A C# .NET library for reading and writing neural probe configurations in the probeinterface JSON format. Probeinterface is an open standard describing probe geometry, contact positions, and channel mappings, and is widely used by Open Ephys, SpikeInterface, and related tools.
- Deserializes probeinterface JSON files into strongly-typed .NET objects
- Serializes probe configurations back to compliant JSON
- Validates files against the specification on load (correct version format, required fields, unique channel indices, array length consistency)
- Supports all probe properties: contact positions (2D and 3D), shapes
(
circle,rect,square), plane axes, planar contour, shank IDs, contact sides, and free-form per-contact annotations with typed access
usingNewtonsoft.Json;usingOpenEphys.ProbeInterface.NET;// Load a probeinterface JSON filevarjson=File.ReadAllText("my_probe.json");varprobeGroup=JsonConvert.DeserializeObject<ProbeGroup>(json);// Iterate contacts on each probeforeach(varprobeinprobeGroup.Probes){foreach(varcontactinprobe.Contacts)Console.WriteLine($"Contact {contact.ContactId}: ({contact.PosX}, {contact.PosY})");}// Access per-contact annotations at the contact levelvarprobe0=probeGroup.Probes.First();varcontact0=probe0.Contacts[0];double?impedance=contact0.GetAnnotation<double>("impedance");string?region=contact0.GetAnnotation<string>("brain_area");// Set or remove an annotation on a single contactcontact0.SetAnnotation("brain_area","CA1");contact0.RemoveAnnotation("brain_area");// Bulk access across all contacts on a probe (returns one element per contact)double[]?impedances=probe0.GetContactAnnotation<double>("impedance");probe0.SetContactAnnotation("brain_area",new[]{"CA1","CA3","DG"});probe0.RemoveContactAnnotation("brain_area");// Access probe-level annotations (model, manufacturer, any custom fields)Console.WriteLine(probe0.Annotations.ModelName);probe0.Annotations.SetAnnotation("implant_date","2025-01-01");string?date=probe0.Annotations.GetAnnotation<string>("implant_date");// Wire hardware channels to contacts (channel number → contact index)// Validates uniqueness within and across all probes in the groupChannelWiring.WireChannels(probeGroup,probeIndex:0,newDictionary<int,int>{{0,3},{1,1},{2,2},{3,0}});// Query the resulting channel map (channel number → probe index, contact index)varmap=probeGroup.ChannelMap;if(map!=null){foreach(var(channel,entry)inmap)Console.WriteLine($"Channel {channel} → probe {entry.ProbeIndex}, contact {entry.ContactIndex}");}// Wire a single contact, or clear the mapping when doneChannelWiring.WireChannel(probeGroup,probeIndex:0,contactIndex:4,channel:7);ChannelWiring.UnwireChannel(probeGroup,probeIndex:0,contactIndex:4);ChannelWiring.UnwireChannels(probeGroup,probeIndex:0);// clear one probeChannelWiring.UnwireChannels(probeGroup);// clear all probes// Serialize back to JSONFile.WriteAllText("output.json",JsonConvert.SerializeObject(probeGroup,Formatting.Indented));