Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 58 additions & 43 deletions Source/Devices/Neuropixels1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Neuropixels1::Neuropixels1 (std::string name, std::string hubName, OnixDeviceTyp
{
}

void Neuropixels1::setSettings (ProbeSettings<NeuropixelsV1Values::numberOfChannels, NeuropixelsV1Values::numberOfElectrodes>* settings_, int index)
void Neuropixels1::setSettings (ProbeSettings* settings_, int index)
{
if (index >= settings.size())
{
Expand All @@ -58,47 +58,55 @@ void Neuropixels1::setSettings (ProbeSettings<NeuropixelsV1Values::numberOfChann
settings[index]->updateProbeSettings (settings_);
}

std::vector<int> Neuropixels1::selectElectrodeConfiguration (int electrodeConfigurationIndex)
std::vector<int> Neuropixels1::selectElectrodeConfiguration (int electrodeConfigurationIndex, ProbeType probeType)
{
std::vector<int> selection;

if (electrodeConfigurationIndex == (int32_t) ElectrodeConfiguration::BankA)
if (probeType == ProbeType::NPX_V1)
{
for (int i = 0; i < 384; i++)
selection.emplace_back (i);
}
else if (electrodeConfigurationIndex == (int32_t) ElectrodeConfiguration::BankB)
{
for (int i = 384; i < 768; i++)
selection.emplace_back (i);
}
else if (electrodeConfigurationIndex == (int32_t) ElectrodeConfiguration::BankC)
{
for (int i = 576; i < 960; i++)
selection.emplace_back (i);
}
else if (electrodeConfigurationIndex == (int32_t) ElectrodeConfiguration::SingleColumn)
{
for (int i = 0; i < 384; i += 2)
selection.emplace_back (i);

for (int i = 385; i < 768; i += 2)
selection.emplace_back (i);
}
else if (electrodeConfigurationIndex == (int32_t) ElectrodeConfiguration::Tetrodes)
{
for (int i = 0; i < 384; i += 8)
if (electrodeConfigurationIndex == (int32_t) ElectrodeConfiguration::BankA)
{
for (int j = 0; j < 4; j++)
selection.emplace_back (i + j);
for (int i = 0; i < 384; i++)
selection.emplace_back (i);
}
else if (electrodeConfigurationIndex == (int32_t) ElectrodeConfiguration::BankB)
{
for (int i = 384; i < 768; i++)
selection.emplace_back (i);
}
else if (electrodeConfigurationIndex == (int32_t) ElectrodeConfiguration::BankC)
{
for (int i = 576; i < 960; i++)
selection.emplace_back (i);
}
else if (electrodeConfigurationIndex == (int32_t) ElectrodeConfiguration::SingleColumn)
{
for (int i = 0; i < 384; i += 2)
selection.emplace_back (i);

for (int i = 388; i < 768; i += 8)
for (int i = 385; i < 768; i += 2)
selection.emplace_back (i);
}
else if (electrodeConfigurationIndex == (int32_t) ElectrodeConfiguration::Tetrodes)
{
for (int j = 0; j < 4; j++)
selection.emplace_back (i + j);
for (int i = 0; i < 384; i += 8)
{
for (int j = 0; j < 4; j++)
selection.emplace_back (i + j);
}

for (int i = 388; i < 768; i += 8)
{
for (int j = 0; j < 4; j++)
selection.emplace_back (i + j);
}
}
}
else
{
LOGE ("Invalid probe type given for a Neuropixels 2.0 device: ", ProbeTypeString.at (probeType));
return selection;
}

assert (selection.size() == numberOfChannels && "Invalid number of selected channels.");

Expand Down Expand Up @@ -169,9 +177,9 @@ void Neuropixels1::updateLfpOffsets (std::array<float, numLfpSamples>& samples,
}
}

void Neuropixels1::defineMetadata (ProbeSettings<numberOfChannels, numberOfElectrodes>* settings)
void Neuropixels1::defineMetadata (ProbeSettings* settings, ProbeType probeType)
{
settings->probeType = ProbeType::NPX_V1;
settings->probeType = probeType;
settings->probeMetadata.name = "Neuropixels 1.0";

std::vector<std::array<float, 2>> shankOutline {
Expand Down Expand Up @@ -200,13 +208,6 @@ void Neuropixels1::defineMetadata (ProbeSettings<numberOfChannels, numberOfElect
settings->probeMetadata.num_adcs = 32; // NB: Is this right for 1.0e?
settings->probeMetadata.adc_bits = 10; // NB: Is this right for 1.0e?

settings->availableBanks = {
Bank::A,
Bank::B,
Bank::C,
Bank::NONE // disconnected
};

Array<float> xpositions = { 27.0f, 59.0f, 11.0f, 43.0f };

for (int i = 0; i < numberOfElectrodes; i++)
Expand Down Expand Up @@ -296,8 +297,6 @@ void Neuropixels1::defineMetadata (ProbeSettings<numberOfChannels, numberOfElect
settings->electrodeConfigurationIndex = (int32_t) ElectrodeConfiguration::BankA;
auto selection = selectElectrodeConfiguration (settings->electrodeConfigurationIndex);
settings->selectElectrodes (selection);

settings->isValid = true;
}

uint64_t Neuropixels1::getProbeSerialNumber (int index)
Expand Down Expand Up @@ -529,3 +528,19 @@ void Neuropixels1::setGainCalibrationFilePath (std::string filepath)
{
gainCalibrationFilePath = filepath;
}

bool Neuropixels1::validateProbeTypeAndPartNumber()
{
if (! NeuropixelsProbeMetadata::validateProbeTypeAndPartNumber (settings[0]->probeType, probeMetadata))
{
Onix1::showWarningMessageBoxAsync ("Probe Type / Number Mismatch",
"The selected probe type is " + ProbeTypeString.at (settings[0]->probeType)
+ "', but the connected probe is '" + NeuropixelsProbeMetadata::getProbeTypeString (probeMetadata.getProbePartNumber())
+ "'. Please select the correct probe type to match the connected probe."
+ ".\n\nProbe serial number: " + std::to_string (probeMetadata.getProbeSerialNumber()));
return false;
}

return true;
}

8 changes: 5 additions & 3 deletions Source/Devices/Neuropixels1.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,12 @@ class Neuropixels1 : public INeuropixel<NeuropixelsV1Values::numberOfChannels, N
void setGainCalibrationFilePath (std::string filepath);

// INeuropixels methods
void defineMetadata (ProbeSettings<numberOfChannels, numberOfElectrodes>* settings) override;
void defineMetadata (ProbeSettings* settings, ProbeType probeType) override;

/** Select a preset electrode configuration, based on the index of the given enum */
std::vector<int> selectElectrodeConfiguration (int electrodeConfigurationIndex) override;
std::vector<int> selectElectrodeConfiguration (int electrodeConfigurationIndex, ProbeType probeType = ProbeType::NPX_V1) override;

void setSettings (ProbeSettings<numberOfChannels, numberOfElectrodes>* settings_, int index = 0) override;
void setSettings (ProbeSettings* settings_, int index = 0) override;

uint64_t getProbeSerialNumber (int index = 0) override;
std::string getProbePartNumber (int index = 0) override;
Expand Down Expand Up @@ -133,6 +133,8 @@ class Neuropixels1 : public INeuropixel<NeuropixelsV1Values::numberOfChannels, N
void updateLfpOffsets (std::array<float, numLfpSamples>&, int64);
void updateApOffsets (std::array<float, numApSamples>&, int64);

bool validateProbeTypeAndPartNumber ();

enum class ElectrodeConfiguration : int32_t
{
BankA = 0,
Expand Down
5 changes: 4 additions & 1 deletion Source/Devices/Neuropixels1e.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Neuropixels1e::Neuropixels1e (std::string name, std::string hubName, const oni_d
"lfp");
streamInfos.add (lfpStream);

defineMetadata (settings[0].get());
defineMetadata (settings[0].get(), ProbeType::NPX_V1);

adcCalibrationFilePath = "None";
gainCalibrationFilePath = "None";
Expand Down Expand Up @@ -197,6 +197,9 @@ void Neuropixels1e::resetProbe()

bool Neuropixels1e::updateSettings()
{
if (! validateProbeTypeAndPartNumber())
return false;

auto updater = NeuropixelsV1eBackgroundUpdater (this);

return updater.updateSettings() && adcValues.size() == NeuropixelsV1Values::AdcCount;
Expand Down
5 changes: 4 additions & 1 deletion Source/Devices/Neuropixels1f.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Neuropixels1f::Neuropixels1f (std::string name, std::string hubName, const oni_d
"lfp");
streamInfos.add (lfpStream);

defineMetadata (settings[0].get());
defineMetadata (settings[0].get(), ProbeType::NPX_V1);

adcCalibrationFilePath = "None";
gainCalibrationFilePath = "None";
Expand Down Expand Up @@ -153,6 +153,9 @@ int Neuropixels1f::configureDevice()

bool Neuropixels1f::updateSettings()
{
if (! validateProbeTypeAndPartNumber())
return false;

auto updater = NeuropixelsV1fBackgroundUpdater (this);

return updater.updateSettings() && adcValues.size() == NeuropixelsV1Values::AdcCount;
Expand Down
61 changes: 36 additions & 25 deletions Source/Devices/Neuropixels2e.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ using namespace OnixSourcePlugin;
Neuropixels2e::Neuropixels2e (std::string name, std::string hubName, const oni_dev_idx_t deviceIdx_, std::shared_ptr<Onix1> ctx_)
: OnixDevice (name, hubName, Neuropixels2e::getDeviceType(), deviceIdx_, ctx_, true),
I2CRegisterContext (ProbeI2CAddress, deviceIdx_, ctx_),
INeuropixel (NeuropixelsV2eValues::numberOfSettings, NeuropixelsV2eValues::numberOfShanks)
INeuropixel (NeuropixelsV2eValues::numberOfSettings, NeuropixelsV2eValues::quadShankCount)
{
frameCount.fill (0);
sampleNumber.fill (0);

for (int i = 0; i < NeuropixelsV2eValues::numberOfSettings; i++)
{
defineMetadata (settings[i].get());
defineMetadata (settings[i].get(), ProbeType::NPX_V2_QUAD_SHANK);
}

for (int i = 0; i < NumberOfProbes; i++)
Expand Down Expand Up @@ -98,13 +98,11 @@ void Neuropixels2e::selectElectrodesAcrossShanks (std::vector<int>& selection, i
}
}

std::vector<int> Neuropixels2e::selectElectrodeConfiguration (int electrodeConfigurationIndex)
std::vector<int> Neuropixels2e::selectElectrodeConfiguration (int electrodeConfigurationIndex, ProbeType probeType)
{
static int numberOfElectrodesAcrossShanks = 96;

std::vector<int> selection;

if (numberOfShanks == 1)
if (probeType == ProbeType::NPX_V2_SINGLE_SHANK)
{
if (electrodeConfigurationIndex == (int32_t) ElectrodeConfigurationSingleShank::BankA)
{
Expand All @@ -124,8 +122,10 @@ std::vector<int> Neuropixels2e::selectElectrodeConfiguration (int electrodeConfi
selectElectrodesInRange (selection, bankDOffset, numberOfChannels);
}
}
else if (numberOfShanks == 4)
else if (probeType == ProbeType::NPX_V2_QUAD_SHANK)
{
static int numberOfElectrodesAcrossShanks = 96;

if (electrodeConfigurationIndex == (int32_t) ElectrodeConfigurationQuadShank::Shank1BankA)
{
selectElectrodesInRange (selection, 0, numberOfChannels);
Expand Down Expand Up @@ -227,6 +227,10 @@ std::vector<int> Neuropixels2e::selectElectrodeConfiguration (int electrodeConfi
selectElectrodesAcrossShanks (selection, numberOfElectrodesAcrossShanks * 12, numberOfElectrodesAcrossShanks);
}
}
else
{
LOGE ("Invalid probe type given for a Neuropixels 2.0 device: ", ProbeTypeString.at (probeType));
}

return selection;
}
Expand Down Expand Up @@ -342,6 +346,16 @@ bool Neuropixels2e::updateSettings()
{
if (probeMetadata[i].getProbeSerialNumber() != 0)
{
if (! NeuropixelsProbeMetadata::validateProbeTypeAndPartNumber (settings[i]->probeType, probeMetadata[i]))
{
Onix1::showWarningMessageBoxAsync ("Probe Type Mismatch",
"The selected probe type is '" + ProbeTypeString.at (settings[i]->probeType)
+ "', but the connected probe is '" + NeuropixelsProbeMetadata::getProbeTypeString (probeMetadata[i].getProbePartNumber())
+ "'. Please select the correct probe type to match the connected probe."
+ ".\n\nProbe serial number: " + std::to_string (probeMetadata[i].getProbeSerialNumber()));
return false;
}

if (gainCorrectionFilePath[i] == "None" || gainCorrectionFilePath[i] == "")
{
Onix1::showWarningMessageBoxAsync ("Missing File", "Missing gain correction file for probe " + std::to_string (probeMetadata[i].getProbeSerialNumber()));
Expand Down Expand Up @@ -598,7 +612,7 @@ void Neuropixels2e::processFrames()
}
}

void Neuropixels2e::writeConfiguration (ProbeSettings<numberOfChannels, numberOfElectrodes>* settings)
void Neuropixels2e::writeConfiguration (ProbeSettings* settings)
{
auto baseBits = makeBaseBits (getReference (settings->referenceIndex));
writeShiftRegister (SR_CHAIN5, baseBits[0]);
Expand Down Expand Up @@ -716,7 +730,7 @@ Neuropixels2e::BaseBitsArray Neuropixels2e::makeBaseBits (NeuropixelsV2Reference
return baseBits;
}

Neuropixels2e::ShankBitsArray Neuropixels2e::makeShankBits (NeuropixelsV2Reference reference, std::array<ElectrodeMetadata, numberOfElectrodes> channelMap)
Neuropixels2e::ShankBitsArray Neuropixels2e::makeShankBits (NeuropixelsV2Reference reference, std::vector<ElectrodeMetadata> channelMap)
{
ShankBitsArray shankBits;

Expand Down Expand Up @@ -766,7 +780,7 @@ Neuropixels2e::ShankBitsArray Neuropixels2e::makeShankBits (NeuropixelsV2Referen
return shankBits;
}

void Neuropixels2e::setSettings (ProbeSettings<NeuropixelsV2eValues::numberOfChannels, NeuropixelsV2eValues::numberOfElectrodes>* settings_, int index)
void Neuropixels2e::setSettings (ProbeSettings* settings_, int index)
{
if (index >= settings.size())
{
Expand All @@ -777,12 +791,13 @@ void Neuropixels2e::setSettings (ProbeSettings<NeuropixelsV2eValues::numberOfCha
settings[index]->updateProbeSettings (settings_);
}

void Neuropixels2e::defineMetadata (ProbeSettings<numberOfChannels, numberOfElectrodes>* settings)
void Neuropixels2e::defineMetadata (ProbeSettings* settings, ProbeType probeType)
{
auto shankCount = NeuropixelsV2eValues::numberOfShanks;
settings->probeType = probeType;

settings->probeType = ProbeType::NPX_V2;
settings->probeMetadata.name = "Neuropixels 2.0e" + (shankCount == 1) ? " - Single Shank" : " - Quad Shank";
auto shankCount = probeType == ProbeType::NPX_V2_QUAD_SHANK ? NeuropixelsV2eValues::quadShankCount : NeuropixelsV2eValues::singleShankCount;

settings->probeMetadata.name = "Neuropixels 2.0e" + (probeType == ProbeType::NPX_V2_QUAD_SHANK) ? " - Single Shank" : " - Quad Shank";

constexpr float shankTipY = 0.0f;
constexpr float shankBaseY = 155.0f;
Expand Down Expand Up @@ -827,14 +842,6 @@ void Neuropixels2e::defineMetadata (ProbeSettings<numberOfChannels, numberOfElec
settings->probeMetadata.num_adcs = 24;
settings->probeMetadata.adc_bits = 12;

settings->availableBanks = {
Bank::A,
Bank::B,
Bank::C,
Bank::D,
Bank::NONE // disconnected
};

for (int i = 0; i < settings->probeMetadata.electrodes_per_shank * settings->probeMetadata.shank_count; i++)
{
ElectrodeMetadata metadata;
Expand Down Expand Up @@ -1099,14 +1106,18 @@ void Neuropixels2e::defineMetadata (ProbeSettings<numberOfChannels, numberOfElec
settings->apFilterState = false;

settings->electrodeConfigurationIndex = (int32_t) ElectrodeConfigurationSingleShank::BankA;
auto selection = selectElectrodeConfiguration (settings->electrodeConfigurationIndex);
auto selection = selectElectrodeConfiguration (settings->electrodeConfigurationIndex, probeType);
settings->selectElectrodes (selection);

settings->availableReferences.add ("Ext");
settings->availableReferences.add ("Tip1");

if (shankCount == 4)
if (probeType == ProbeType::NPX_V2_SINGLE_SHANK)
{
settings->availableReferences.add ("Tip");
}
else if (probeType == ProbeType::NPX_V2_QUAD_SHANK)
{
settings->availableReferences.add ("Tip1");
settings->availableReferences.add ("Tip2");
settings->availableReferences.add ("Tip3");
settings->availableReferences.add ("Tip4");
Expand Down
Loading