@@ -77,8 +77,35 @@ 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 file dialog to choose a folder that contains all calibration files. The calibration file(s) that matches your probe will automatically be selected if it exists in this folder.");
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 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+
80107 adcCalibrationFileLabel = std::make_unique<Label>("adcCalibrationFileLabel", "ADC Calibration File");
81- adcCalibrationFileLabel->setBounds(infoLabel ->getX(), infoLabel ->getBottom() + 15, 240, 16 );
108+ adcCalibrationFileLabel->setBounds(calibrationFolder ->getX(), calibrationFolder ->getBottom() + 15, calibrationFolderLabel->getWidth(), calibrationFolderLabel->getHeight() );
82109 adcCalibrationFileLabel->setColour(Label::textColourId, Colours::black);
83110 addAndMakeVisible(adcCalibrationFileLabel.get());
84111
@@ -96,7 +123,7 @@ NeuropixelsV1Interface::NeuropixelsV1Interface(std::shared_ptr<Neuropixels1> d,
96123 adcCalibrationFileButton->setTooltip("Open a file dialog to choose the ADC calibration file for this probe.");
97124 addAndMakeVisible(adcCalibrationFileButton.get());
98125
99- adcCalibrationFileChooser = std::make_unique<FileChooser>("Select ADC Calibration file.", File(), "*_ADCCalibration.csv" );
126+ adcCalibrationFileChooser = std::make_unique<FileChooser>("Select ADC Calibration file.", File(), std::string("*") + AdcCalibrationFilename );
100127
101128 gainCalibrationFileLabel = std::make_unique<Label>("gainCalibrationFileLabel", "Gain Calibration File");
102129 gainCalibrationFileLabel->setBounds(adcCalibrationFile->getX(), adcCalibrationFile->getBottom() + 3, adcCalibrationFile->getWidth(), adcCalibrationFile->getHeight());
@@ -117,7 +144,7 @@ NeuropixelsV1Interface::NeuropixelsV1Interface(std::shared_ptr<Neuropixels1> d,
117144 gainCalibrationFileButton->setTooltip("Open a file dialog to choose the Gain calibration file for this probe.");
118145 addAndMakeVisible(gainCalibrationFileButton.get());
119146
120- gainCalibrationFileChooser = std::make_unique<FileChooser>("Select Gain Calibration file.", File(), "*_gainCalValues.csv" );
147+ gainCalibrationFileChooser = std::make_unique<FileChooser>("Select Gain Calibration file.", File(), std::string("*") + GainCalibrationFilename );
121148
122149 probeInterfaceRectangle = std::make_unique<DrawableRectangle>();
123150 probeInterfaceRectangle->setFill(Colours::darkgrey);
@@ -507,6 +534,8 @@ NeuropixelsV1Interface::NeuropixelsV1Interface(std::shared_ptr<Neuropixels1> d,
507534 addAndMakeVisible(activityViewComponent.get());
508535
509536 updateSettings();
537+
538+ setCalibrationFolderEnabledState(false);
510539 }
511540
512541 drawLegend();
@@ -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(), sn);
585+ }
551586}
552587
553588void 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())
@@ -686,7 +720,6 @@ void NeuropixelsV1Interface::buttonClicked(Button* button)
686720 deviceEnableButton->setLabel(disabledButtonText);
687721 }
688722
689- updateInfoString();
690723 repaint();
691724
692725 CoreServices::updateSignalChain(editor);
@@ -801,10 +834,6 @@ void NeuropixelsV1Interface::buttonClicked(Button* button)
801834 {
802835 adcCalibrationFile->setText(adcCalibrationFileChooser->getResult().getFullPathName());
803836 }
804- else
805- {
806- adcCalibrationFile->setText("");
807- }
808837
809838 std::static_pointer_cast<Neuropixels1>(device)->setAdcCalibrationFilePath(adcCalibrationFile->getText().toStdString());
810839 }
@@ -814,15 +843,128 @@ void NeuropixelsV1Interface::buttonClicked(Button* button)
814843 {
815844 gainCalibrationFile->setText(gainCalibrationFileChooser->getResult().getFullPathName());
816845 }
817- else
846+
847+ std::static_pointer_cast<Neuropixels1>(device)->setGainCalibrationFilePath(gainCalibrationFile->getText().toStdString());
848+ }
849+ else if (button == searchForCalibrationFilesButton.get())
850+ {
851+ setCalibrationFolderEnabledState(button->getToggleState());
852+
853+ if (button->getToggleState())
818854 {
819- gainCalibrationFile->setText("" );
855+ searchForCalibrationFiles(calibrationFolder->getText().toStdString(), std::static_pointer_cast<Neuropixels1>(device)->getProbeSerialNumber() );
820856 }
857+ }
858+ else if (button == calibrationFolderButton.get())
859+ {
860+ if (calibrationFolderChooser->browseForDirectory())
861+ {
862+ calibrationFolder->setText(calibrationFolderChooser->getResult().getFullPathName());
863+ searchForCalibrationFiles(calibrationFolder->getText().toStdString(), std::static_pointer_cast<Neuropixels1>(device)->getProbeSerialNumber());
864+ }
865+ }
866+ }
821867
822- std::static_pointer_cast<Neuropixels1>(device)->setGainCalibrationFilePath(gainCalibrationFile->getText().toStdString());
868+ void NeuropixelsV1Interface::textEditorTextChanged(TextEditor& editor)
869+ {
870+ if (editor.getName() == gainCalibrationFile->getName())
871+ {
872+ std::static_pointer_cast<Neuropixels1>(device)->setGainCalibrationFilePath(editor.getText().toStdString());
873+ }
874+ else if (editor.getName() == adcCalibrationFile->getName())
875+ {
876+ std::static_pointer_cast<Neuropixels1>(device)->setAdcCalibrationFilePath(editor.getText().toStdString());
877+ }
878+ }
879+
880+ std::string NeuropixelsV1Interface::searchDirectoryForAdcCalibrationFile(std::string folder, uint64_t sn)
881+ {
882+ return searchDirectoryForCalibrationFile(folder, std::to_string(sn) + AdcCalibrationFilename, sn);
883+ }
884+
885+ std::string NeuropixelsV1Interface::searchDirectoryForGainCalibrationFile(std::string folder, uint64_t sn)
886+ {
887+ return searchDirectoryForCalibrationFile(folder, std::to_string(sn) + GainCalibrationFilename, sn);
888+ }
889+
890+ std::string NeuropixelsV1Interface::searchDirectoryForCalibrationFile(std::string folder, std::string filename, uint64_t sn)
891+ {
892+ if (folder == "" || sn == 0)
893+ return "";
894+
895+ File rootDirectory = File(folder);
896+
897+ if (!rootDirectory.isDirectory())
898+ {
899+ Onix1::showWarningMessageBoxAsync("Invalid Directory", "The path given for the calibration files directory is invalid. Please try setting it again.");
900+ return "";
901+ }
902+
903+ auto calibrationFiles = searchDirectoryForFile(rootDirectory, filename, NeuropixelsCalibrationFileRecursiveLevels);
904+
905+ if (calibrationFiles.size() != 1)
906+ {
907+ std::string msg = "Expected to find 1 file matching '" + filename +
908+ "', but found " + std::to_string(calibrationFiles.size()) + " instead.";
909+
910+ if (calibrationFiles.size() > 1)
911+ {
912+ msg += " Check console for all files discovered.";
913+ }
914+
915+ Onix1::showWarningMessageBoxAsync("Wrong Number of Calibration Files", msg);
916+ return "";
917+ }
918+
919+ return calibrationFiles[0].getFullPathName().toStdString();
920+ }
921+
922+ void NeuropixelsV1Interface::setCalibrationFolderEnabledState(bool enabledState)
923+ {
924+ float alphaEnabled = 1.0, alphaDisabled = 0.25;
925+
926+ if (!enabledState)
927+ {
928+ calibrationFolder->setAlpha(alphaDisabled);
929+ calibrationFolderButton->setEnabled(false);
930+
931+ adcCalibrationFile->setAlpha(alphaEnabled);
932+ adcCalibrationFileButton->setEnabled(true);
933+
934+ gainCalibrationFile->setAlpha(alphaEnabled);
935+ gainCalibrationFileButton->setEnabled(true);
936+ }
937+ else
938+ {
939+ calibrationFolder->setAlpha(alphaEnabled);
940+ calibrationFolderButton->setEnabled(true);
941+
942+ adcCalibrationFile->setAlpha(alphaDisabled);
943+ adcCalibrationFileButton->setEnabled(false);
944+
945+ gainCalibrationFile->setAlpha(alphaDisabled);
946+ gainCalibrationFileButton->setEnabled(false);
823947 }
824948}
825949
950+ void NeuropixelsV1Interface::searchForCalibrationFiles(std::string folder, uint64_t sn)
951+ {
952+ if (!device->isEnabled())
953+ return;
954+
955+ auto file = searchDirectoryForGainCalibrationFile(folder, sn);
956+
957+ if (file != "")
958+ gainCalibrationFile->setText(file);
959+ else
960+ return;
961+
962+ file = searchDirectoryForAdcCalibrationFile(folder, sn);
963+
964+ if (file != "")
965+ adcCalibrationFile->setText(file);
966+ }
967+
826968std::vector<int> NeuropixelsV1Interface::getSelectedElectrodes() const
827969{
828970 std::vector<int> electrodeIndices;
@@ -898,6 +1040,12 @@ void NeuropixelsV1Interface::setInterfaceEnabledState(bool enabledState)
8981040
8991041 if (loadSettingsButton != nullptr)
9001042 loadSettingsButton->setEnabled(enabledState);
1043+
1044+ if (searchForCalibrationFilesButton != nullptr)
1045+ searchForCalibrationFilesButton->setEnabled(enabledState);
1046+
1047+ if (calibrationFolderButton != nullptr)
1048+ calibrationFolderButton->setEnabled(enabledState);
9011049}
9021050
9031051void NeuropixelsV1Interface::startAcquisition()
@@ -1020,6 +1168,10 @@ void NeuropixelsV1Interface::saveParameters(XmlElement* xml)
10201168
10211169 xmlNode->setAttribute("isEnabled", bool(device->isEnabled()));
10221170
1171+ xmlNode->setAttribute("searchForCalibrationFiles", searchForCalibrationFilesButton->getToggleState());
1172+
1173+ xmlNode->setAttribute("calibrationFolder", calibrationFolder->getText());
1174+
10231175 xmlNode->setAttribute("adcCalibrationFile", npx->getAdcCalibrationFilePath());
10241176 xmlNode->setAttribute("gainCalibrationFile", npx->getGainCalibrationFilePath());
10251177
@@ -1088,6 +1240,10 @@ void NeuropixelsV1Interface::loadParameters(XmlElement* xml)
10881240
10891241 npx->setEnabled(xmlNode->getBoolAttribute("isEnabled"));
10901242
1243+ searchForCalibrationFilesButton->setToggleState(xmlNode->getBoolAttribute("searchForCalibrationFiles", false), sendNotification);
1244+
1245+ calibrationFolder->setText(xmlNode->getStringAttribute("calibrationFolder", ""));
1246+
10911247 npx->setAdcCalibrationFilePath(xmlNode->getStringAttribute("adcCalibrationFile").toStdString());
10921248 npx->setGainCalibrationFilePath(xmlNode->getStringAttribute("gainCalibrationFile").toStdString());
10931249
0 commit comments