Skip to content

Commit 4cce939

Browse files
committed
Add gain correction folder functionality and calibration file search
- Added for Neuropixels 1.0 and 2.0 probes
1 parent 4dcf5dd commit 4cce939

File tree

4 files changed

+309
-18
lines changed

4 files changed

+309
-18
lines changed

Source/UI/NeuropixelsV1Interface.cpp

Lines changed: 149 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,37 @@ NeuropixelsV1Interface::NeuropixelsV1Interface(std::shared_ptr<Neuropixels1> d,
7777
infoLabel->setJustificationType(Justification::topLeft);
7878
addAndMakeVisible(infoLabel.get());
7979

80+
searchForCalibrationFilesButton = std::make_unique<ToggleButton>("Search for calibration files automatically");
81+
searchForCalibrationFilesButton->setBounds(infoLabel->getX() + 2, infoLabel->getBottom() + 5, 350, 20);
82+
searchForCalibrationFilesButton->addListener(this);
83+
searchForCalibrationFilesButton->setTooltip("Open a dialog to choose the folder where calibration files exist. This can be a top-level folder which is recursively searched for a matching serial number.");
84+
addAndMakeVisible(searchForCalibrationFilesButton.get());
85+
86+
calibrationFolderLabel = std::make_unique<Label>("calibrationFolderLabel", "Calibration Folder");
87+
calibrationFolderLabel->setBounds(searchForCalibrationFilesButton->getX(), searchForCalibrationFilesButton->getBottom() + 5, 240, 16);
88+
calibrationFolderLabel->setColour(Label::textColourId, Colours::black);
89+
addAndMakeVisible(calibrationFolderLabel.get());
90+
91+
calibrationFolder = std::make_unique<TextEditor>("CALIBRATION FOLDER");
92+
calibrationFolder->setEnabled(false);
93+
calibrationFolder->setBounds(calibrationFolderLabel->getX(), calibrationFolderLabel->getBottom() + 2, calibrationFolderLabel->getWidth(), 20);
94+
calibrationFolder->setColour(Label::textColourId, Colours::black);
95+
calibrationFolder->addListener(this);
96+
addAndMakeVisible(calibrationFolder.get());
97+
98+
calibrationFolderButton = std::make_unique<UtilityButton>("...");
99+
calibrationFolderButton->setBounds(calibrationFolder->getRight() + 3, calibrationFolder->getY(), 26, calibrationFolder->getHeight() + 2);
100+
calibrationFolderButton->setRadius(1.0f);
101+
calibrationFolderButton->addListener(this);
102+
calibrationFolderButton->setTooltip("Open a file dialog to choose the gain calibration folder path to automatically search for probe calibration files.");
103+
addAndMakeVisible(calibrationFolderButton.get());
104+
105+
calibrationFolderChooser = std::make_unique<FileChooser>("Select Gain Calibration Folder.", File());
106+
107+
setCalibrationFolderEnabledState(false);
108+
80109
adcCalibrationFileLabel = std::make_unique<Label>("adcCalibrationFileLabel", "ADC Calibration File");
81-
adcCalibrationFileLabel->setBounds(infoLabel->getX(), infoLabel->getBottom() + 15, 240, 16);
110+
adcCalibrationFileLabel->setBounds(calibrationFolder->getX(), calibrationFolder->getBottom() + 15, calibrationFolderLabel->getWidth(), calibrationFolderLabel->getHeight());
82111
adcCalibrationFileLabel->setColour(Label::textColourId, Colours::black);
83112
addAndMakeVisible(adcCalibrationFileLabel.get());
84113

@@ -96,7 +125,7 @@ NeuropixelsV1Interface::NeuropixelsV1Interface(std::shared_ptr<Neuropixels1> d,
96125
adcCalibrationFileButton->setTooltip("Open a file dialog to choose the ADC calibration file for this probe.");
97126
addAndMakeVisible(adcCalibrationFileButton.get());
98127

99-
adcCalibrationFileChooser = std::make_unique<FileChooser>("Select ADC Calibration file.", File(), "*_ADCCalibration.csv");
128+
adcCalibrationFileChooser = std::make_unique<FileChooser>("Select ADC Calibration file.", File(), std::string("*") + AdcCalibrationFilename);
100129

101130
gainCalibrationFileLabel = std::make_unique<Label>("gainCalibrationFileLabel", "Gain Calibration File");
102131
gainCalibrationFileLabel->setBounds(adcCalibrationFile->getX(), adcCalibrationFile->getBottom() + 3, adcCalibrationFile->getWidth(), adcCalibrationFile->getHeight());
@@ -117,7 +146,7 @@ NeuropixelsV1Interface::NeuropixelsV1Interface(std::shared_ptr<Neuropixels1> d,
117146
gainCalibrationFileButton->setTooltip("Open a file dialog to choose the Gain calibration file for this probe.");
118147
addAndMakeVisible(gainCalibrationFileButton.get());
119148

120-
gainCalibrationFileChooser = std::make_unique<FileChooser>("Select Gain Calibration file.", File(), "*_gainCalValues.csv");
149+
gainCalibrationFileChooser = std::make_unique<FileChooser>("Select Gain Calibration file.", File(), std::string("*") + GainCalibrationFilename);
121150

122151
probeInterfaceRectangle = std::make_unique<DrawableRectangle>();
123152
probeInterfaceRectangle->setFill(Colours::darkgrey);
@@ -534,20 +563,26 @@ void NeuropixelsV1Interface::updateInfoString()
534563
std::string deviceString, infoString;
535564

536565
auto npx = std::static_pointer_cast<Neuropixels1>(device);
566+
auto sn = npx->getProbeSerialNumber();
537567

538568
if (device != nullptr)
539569
{
540570
deviceString = "Neuropixels 1.0 Probe";
541571

542572
infoString += "\n";
543573
infoString += "Probe Number: ";
544-
infoString += std::to_string(npx->getProbeSerialNumber());
574+
infoString += std::to_string(sn);
545575
infoString += "\n";
546576
infoString += "\n";
547577
}
548578

549579
deviceLabel->setText(deviceString, dontSendNotification);
550580
infoLabel->setText(infoString, dontSendNotification);
581+
582+
if (searchForCalibrationFilesButton->getToggleState())
583+
{
584+
searchForCalibrationFiles(calibrationFolder->getText().toStdString(), std::static_pointer_cast<Neuropixels1>(device)->getProbeSerialNumber());
585+
}
551586
}
552587

553588
void NeuropixelsV1Interface::comboBoxChanged(ComboBox* comboBox)
@@ -556,7 +591,6 @@ void NeuropixelsV1Interface::comboBoxChanged(ComboBox* comboBox)
556591

557592
if (!editor->acquisitionIsActive)
558593
{
559-
auto npx = std::static_pointer_cast<Neuropixels1>(device);
560594
auto settings = npx->settings[0].get();
561595

562596
if (comboBox == electrodeConfigurationComboBox.get())
@@ -801,10 +835,6 @@ void NeuropixelsV1Interface::buttonClicked(Button* button)
801835
{
802836
adcCalibrationFile->setText(adcCalibrationFileChooser->getResult().getFullPathName());
803837
}
804-
else
805-
{
806-
adcCalibrationFile->setText("");
807-
}
808838

809839
std::static_pointer_cast<Neuropixels1>(device)->setAdcCalibrationFilePath(adcCalibrationFile->getText().toStdString());
810840
}
@@ -814,15 +844,108 @@ void NeuropixelsV1Interface::buttonClicked(Button* button)
814844
{
815845
gainCalibrationFile->setText(gainCalibrationFileChooser->getResult().getFullPathName());
816846
}
817-
else
847+
848+
std::static_pointer_cast<Neuropixels1>(device)->setGainCalibrationFilePath(gainCalibrationFile->getText().toStdString());
849+
}
850+
else if (button == searchForCalibrationFilesButton.get())
851+
{
852+
setCalibrationFolderEnabledState(button->getToggleState());
853+
854+
if (button->getToggleState())
855+
{
856+
searchForCalibrationFiles(calibrationFolder->getText().toStdString(), std::static_pointer_cast<Neuropixels1>(device)->getProbeSerialNumber());
857+
}
858+
}
859+
else if (button == calibrationFolderButton.get())
860+
{
861+
if (calibrationFolderChooser->browseForDirectory())
818862
{
819-
gainCalibrationFile->setText("");
863+
calibrationFolder->setText(calibrationFolderChooser->getResult().getFullPathName());
864+
searchForCalibrationFiles(calibrationFolder->getText().toStdString(), std::static_pointer_cast<Neuropixels1>(device)->getProbeSerialNumber());
820865
}
866+
}
867+
}
821868

822-
std::static_pointer_cast<Neuropixels1>(device)->setGainCalibrationFilePath(gainCalibrationFile->getText().toStdString());
869+
void NeuropixelsV1Interface::textEditorTextChanged(TextEditor& editor)
870+
{
871+
if (editor.getName() == gainCalibrationFile->getName())
872+
{
873+
std::static_pointer_cast<Neuropixels1>(device)->setGainCalibrationFilePath(editor.getText().toStdString());
874+
}
875+
else if (editor.getName() == adcCalibrationFile->getName())
876+
{
877+
std::static_pointer_cast<Neuropixels1>(device)->setAdcCalibrationFilePath(editor.getText().toStdString());
823878
}
824879
}
825880

881+
std::string NeuropixelsV1Interface::searchDirectoryForAdcCalibrationFile(std::string folder, uint64_t sn)
882+
{
883+
return searchDirectoryForCalibrationFile(folder, std::to_string(sn) + AdcCalibrationFilename, sn);
884+
}
885+
886+
std::string NeuropixelsV1Interface::searchDirectoryForGainCalibrationFile(std::string folder, uint64_t sn)
887+
{
888+
return searchDirectoryForCalibrationFile(folder, std::to_string(sn) + GainCalibrationFilename, sn);
889+
}
890+
891+
std::string NeuropixelsV1Interface::searchDirectoryForCalibrationFile(std::string folder, std::string filename, uint64_t sn)
892+
{
893+
if (folder == "" || sn == 0)
894+
return "";
895+
896+
File directory = File(folder);
897+
898+
if (!directory.isDirectory())
899+
{
900+
Onix1::showWarningMessageBoxAsync("Invalid Directory", "The path given for the calibration files directory is invalid. Please try setting it again.");
901+
return "";
902+
}
903+
904+
std::vector<File> calibrationFiles;
905+
906+
for (DirectoryEntry entry : RangedDirectoryIterator(directory, true, filename, File::findFiles, File::FollowSymlinks::no))
907+
{
908+
calibrationFiles.emplace_back(entry.getFile());
909+
LOGD("Discovered file: ", entry.getFile().getFullPathName());
910+
}
911+
912+
if (calibrationFiles.size() != 1)
913+
{
914+
Onix1::showWarningMessageBoxAsync("Wrong Number of Calibration Files", "Expected to find 1 file matching '" + filename +
915+
"', but found " + std::to_string(calibrationFiles.size()) + " instead. Check logs for all files discovered.");
916+
return "";
917+
}
918+
919+
return calibrationFiles[0].getFullPathName().toStdString();
920+
}
921+
922+
void NeuropixelsV1Interface::setCalibrationFolderEnabledState(bool enabledState)
923+
{
924+
if (!enabledState)
925+
{
926+
calibrationFolder->setAlpha(0.25);
927+
calibrationFolderButton->setEnabled(false);
928+
}
929+
else
930+
{
931+
calibrationFolder->setAlpha(1.0);
932+
calibrationFolderButton->setEnabled(true);
933+
}
934+
}
935+
936+
void NeuropixelsV1Interface::searchForCalibrationFiles(std::string folder, uint64_t sn)
937+
{
938+
auto file = searchDirectoryForGainCalibrationFile(folder, sn);
939+
940+
if (file != "")
941+
gainCalibrationFile->setText(file);
942+
943+
file = searchDirectoryForAdcCalibrationFile(folder, sn);
944+
945+
if (file != "")
946+
adcCalibrationFile->setText(file);
947+
}
948+
826949
std::vector<int> NeuropixelsV1Interface::getSelectedElectrodes() const
827950
{
828951
std::vector<int> electrodeIndices;
@@ -898,6 +1021,12 @@ void NeuropixelsV1Interface::setInterfaceEnabledState(bool enabledState)
8981021

8991022
if (loadSettingsButton != nullptr)
9001023
loadSettingsButton->setEnabled(enabledState);
1024+
1025+
if (searchForCalibrationFilesButton != nullptr)
1026+
searchForCalibrationFilesButton->setEnabled(enabledState);
1027+
1028+
if (calibrationFolderButton != nullptr)
1029+
calibrationFolderButton->setEnabled(enabledState);
9011030
}
9021031

9031032
void NeuropixelsV1Interface::startAcquisition()
@@ -1020,6 +1149,10 @@ void NeuropixelsV1Interface::saveParameters(XmlElement* xml)
10201149

10211150
xmlNode->setAttribute("isEnabled", bool(device->isEnabled()));
10221151

1152+
xmlNode->setAttribute("searchForCalibrationFiles", searchForCalibrationFilesButton->getToggleState());
1153+
1154+
xmlNode->setAttribute("calibrationFolder", calibrationFolder->getText());
1155+
10231156
xmlNode->setAttribute("adcCalibrationFile", npx->getAdcCalibrationFilePath());
10241157
xmlNode->setAttribute("gainCalibrationFile", npx->getGainCalibrationFilePath());
10251158

@@ -1088,6 +1221,10 @@ void NeuropixelsV1Interface::loadParameters(XmlElement* xml)
10881221

10891222
npx->setEnabled(xmlNode->getBoolAttribute("isEnabled"));
10901223

1224+
searchForCalibrationFilesButton->setToggleState(xmlNode->getBoolAttribute("searchForCalibrationFiles", false), sendNotification);
1225+
1226+
calibrationFolder->setText(xmlNode->getStringAttribute("calibrationFolder", ""));
1227+
10911228
npx->setAdcCalibrationFilePath(xmlNode->getStringAttribute("adcCalibrationFile").toStdString());
10921229
npx->setGainCalibrationFilePath(xmlNode->getStringAttribute("gainCalibrationFile").toStdString());
10931230

Source/UI/NeuropixelsV1Interface.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ namespace OnixSourcePlugin
5151

5252
void buttonClicked(Button*) override;
5353
void comboBoxChanged(ComboBox*) override;
54+
void textEditorTextChanged(TextEditor&) override;
5455

5556
void startAcquisition() override;
5657

@@ -77,6 +78,9 @@ namespace OnixSourcePlugin
7778

7879
bool acquisitionIsActive = false;
7980

81+
static constexpr char* GainCalibrationFilename = "_gainCalValues.csv";
82+
static constexpr char* AdcCalibrationFilename = "_ADCCalibration.csv";
83+
8084
std::unique_ptr<ComboBox> electrodeConfigurationComboBox;
8185
std::unique_ptr<ComboBox> lfpGainComboBox;
8286
std::unique_ptr<ComboBox> apGainComboBox;
@@ -94,6 +98,20 @@ namespace OnixSourcePlugin
9498
std::unique_ptr<Label> filterLabel;
9599
std::unique_ptr<Label> activityViewLabel;
96100

101+
std::unique_ptr<Label> calibrationFolderLabel;
102+
std::unique_ptr<ToggleButton> searchForCalibrationFilesButton;
103+
std::unique_ptr<FileChooser> calibrationFolderChooser;
104+
std::unique_ptr<TextEditor> calibrationFolder;
105+
std::unique_ptr<UtilityButton> calibrationFolderButton;
106+
107+
void setCalibrationFolderEnabledState(bool enabledState);
108+
109+
static std::string searchDirectoryForGainCalibrationFile(std::string folder, uint64_t sn);
110+
static std::string searchDirectoryForAdcCalibrationFile(std::string folder, uint64_t sn);
111+
static std::string searchDirectoryForCalibrationFile(std::string folder, std::string filename, uint64_t sn);
112+
113+
void searchForCalibrationFiles(std::string, uint64_t);
114+
97115
std::unique_ptr<Label> adcCalibrationFileLabel;
98116
std::unique_ptr<Label> gainCalibrationFileLabel;
99117

0 commit comments

Comments
 (0)