Skip to content

Commit 1eb27aa

Browse files
authored
Update SpikeSorter.cpp
1 parent 73be460 commit 1eb27aa

1 file changed

Lines changed: 73 additions & 120 deletions

File tree

Source/Plugins/SpikeSorter/SpikeSorter.cpp

Lines changed: 73 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@ SpikeSorter::SpikeSorter()
3434
overflowBufferSize(100), currentElectrode(-1),
3535
numPreSamples(8),numPostSamples(32)
3636
{
37+
setProcessorType (PROCESSOR_TYPE_FILTER);
38+
3739
uniqueID = 0; // for electrode count
3840
uniqueSpikeID = 0;
3941
juce::Time timer;
4042
ticksPerSec = (float) timer.getHighResolutionTicksPerSecond();
4143
electrodeTypes.clear();
4244
electrodeCounter.clear();
43-
spikeBuffer = new uint8_t[MAX_SPIKE_BUFFER_LEN]; // MAX_SPIKE_BUFFER_LEN defined in SpikeObject.h
4445
channelBuffers=nullptr;
4546
PCAbeforeBoxes = true;
4647
autoDACassignment = false;
@@ -137,6 +138,13 @@ int SpikeSorter::getUniqueProbeID(String type)
137138
return 1;
138139
}
139140

141+
void SpikeSorter::setEditAllState(bool val){
142+
editAll = val;
143+
}
144+
145+
bool SpikeSorter::getEditAllState(){
146+
return editAll;
147+
}
140148

141149
void SpikeSorter::increaseUniqueProbeID(String type)
142150
{
@@ -153,9 +161,6 @@ void SpikeSorter::increaseUniqueProbeID(String type)
153161

154162
SpikeSorter::~SpikeSorter()
155163
{
156-
delete spikeBuffer;
157-
spikeBuffer = nullptr;
158-
159164
if (channelBuffers != nullptr)
160165
delete channelBuffers;
161166

@@ -188,13 +193,19 @@ void SpikeSorter::updateSettings()
188193

189194
for (int i = 0; i < electrodes.size(); i++)
190195
{
196+
Electrode* elec = electrodes[i];
197+
unsigned int nChans = elec->numChannels;
198+
Array<const DataChannel*> chans;
199+
for (int c = 0; c < nChans; c++)
200+
{
201+
chans.add(getDataChannel(elec->channels[c]));
202+
}
191203

192-
Channel* ch = new Channel(this,i,ELECTRODE_CHANNEL);
193-
ch->name = generateSpikeElectrodeName(electrodes[i]->numChannels, ch->index);
194-
SpikeChannel* spk = new SpikeChannel(SpikeChannel::Sorted, electrodes[i]->numChannels, electrodes[i], sizeof(Electrode));
195-
ch->extraData = spk;
204+
SpikeChannel* spk = new SpikeChannel(SpikeChannel::typeFromNumChannels(nChans), this, chans);
205+
spk->setNumSamples(elec->prePeakSamples, elec->postPeakSamples);
206+
spk->addEventMetaData(new MetaDataDescriptor(MetaDataDescriptor::UINT8, 3, "Color", "Color of the spike", "graphics.color"));
196207

197-
eventChannels.add(ch);
208+
spikeChannelArray.add(spk);
198209
}
199210

200211
mut.exit();
@@ -212,12 +223,14 @@ Electrode::~Electrode()
212223

213224
}
214225

215-
Electrode::Electrode(int ID, UniqueIDgenerator* uniqueIDgenerator_, PCAcomputingThread* pth, String _name, int _numChannels, int* _channels, float default_threshold, int pre, int post, float samplingRate , int sourceNodeId)
226+
Electrode::Electrode(int ID, UniqueIDgenerator* uniqueIDgenerator_, PCAcomputingThread* pth, String _name, int _numChannels, int* _channels, float default_threshold, int pre, int post, float samplingRate , int sourceId, int subIdx)
216227
{
217228
electrodeID = ID;
218229
computingThread = pth;
219230
uniqueIDgenerator = uniqueIDgenerator_;
220231
name = _name;
232+
sourceNodeId_ = sourceId;
233+
sourceSubIdx = subIdx;
221234

222235
numChannels = _numChannels;
223236
prePeakSamples = pre;
@@ -438,7 +451,7 @@ bool SpikeSorter::addElectrode(int nChans, String name, double Depth)
438451
chans[k] = firstChan + k;
439452

440453
Electrode* newElectrode = new Electrode(++uniqueID, &uniqueIDgenerator, &computingThread, name, nChans, chans, getDefaultThreshold(),
441-
numPreSamples, numPostSamples, getSampleRate(), channels[chans[0]]->sourceNodeId);
454+
numPreSamples, numPostSamples, getSampleRate(), dataChannelArray[chans[0]]->getSourceNodeID(), dataChannelArray[chans[0]]->getSubProcessorIdx());
442455

443456
newElectrode->depthOffsetMM = Depth;
444457
String log = "Added electrode (ID "+ String(uniqueID)+") with " + String(nChans) + " channels." ;
@@ -679,83 +692,41 @@ Electrode* SpikeSorter::getActiveElectrode()
679692
}
680693

681694

682-
void SpikeSorter::addSpikeEvent(SpikeObject* s, MidiBuffer& eventBuffer, int peakIndex)
683-
{
684-
685-
// std::cout << "Adding spike event for index " << peakIndex << std::endl;
686-
687-
s->eventType = SPIKE_EVENT_CODE;
688-
689-
int numBytes = packSpike(s, // SpikeObject
690-
spikeBuffer, // uint8_t*
691-
MAX_SPIKE_BUFFER_LEN); // int
692-
693-
if (numBytes > 0)
694-
eventBuffer.addEvent(spikeBuffer, numBytes, peakIndex);
695-
696-
//std::cout << "Adding spike" << std::endl;
697-
}
698-
699-
void SpikeSorter::addWaveformToSpikeObject(SpikeObject* s,
695+
void SpikeSorter::addWaveformToSpikeObject(SpikeEvent::SpikeBuffer& s,
700696
int& peakIndex,
701697
int& electrodeNumber,
702698
int& currentChannel)
703699
{
704700
mut.enter();
705-
int spikeLength = electrodes[electrodeNumber]->prePeakSamples +
706-
+ electrodes[electrodeNumber]->postPeakSamples;
707-
708-
s->timestamp = getTimestamp(currentChannel) + peakIndex;
709-
710-
// convert sample offset to software ticks
711-
float samplesPerSec = getSampleRate();
712-
s->timestamp_software = software_timestamp + int64(ticksPerSec*float(peakIndex)/samplesPerSec);
713-
s->nSamples = spikeLength;
714-
715-
int chan = *(electrodes[electrodeNumber]->channels+currentChannel);
716-
717-
s->gain[currentChannel] = (1.0f / channels[chan]->bitVolts)*1000;
718-
s->threshold[currentChannel] = (int) electrodes[electrodeNumber]->thresholds[currentChannel];
719-
720-
// cycle through buffer
721-
722-
if (isChannelActive(electrodeNumber, currentChannel))
723-
{
724-
725-
for (int sample = 0; sample < spikeLength; sample++)
726-
{
727-
728-
// warning -- be careful of bitvolts conversion
729-
// do not flip signal (!).
730-
float value = getNextSample(electrodes[electrodeNumber]->channels[currentChannel]);
731-
s->data[currentIndex] = uint16(jmin(65535,jmax(0, int(value / channels[chan]->bitVolts) + 32768)));
732-
// recovered data
733-
//float value2 = (s->data[currentIndex]-32768) /float(s->gain[currentChannel])*1000.0f;
734-
735-
currentIndex++;
736-
sampleIndex++;
737-
738-
//std::cout << currentIndex << std::endl;
701+
int spikeLength = electrodes[electrodeNumber]->prePeakSamples
702+
+ electrodes[electrodeNumber]->postPeakSamples;
739703

740-
}
741-
}
742-
else
743-
{
744-
for (int sample = 0; sample < spikeLength; sample++)
745-
{
746704

747-
// insert a blank spike if the
748-
s->data[currentIndex] = 0;
749-
currentIndex++;
750-
sampleIndex++;
705+
const int chan = *(electrodes[electrodeNumber]->channels + currentChannel);
751706

752-
//std::cout << currentIndex << std::endl;
707+
if (isChannelActive(electrodeNumber, currentChannel))
708+
{
753709

754-
}
755-
}
710+
for (int sample = 0; sample < spikeLength; ++sample)
711+
{
712+
s.set(currentChannel, sample, getNextSample(*(electrodes[electrodeNumber]->channels + currentChannel)));
713+
++sampleIndex;
756714

715+
//std::cout << currentIndex << std::endl;
716+
}
717+
}
718+
else
719+
{
720+
for (int sample = 0; sample < spikeLength; ++sample)
721+
{
722+
// insert a blank spike if the
723+
s.set(currentChannel, sample, 0);
724+
++sampleIndex;
725+
//std::cout << currentIndex << std::endl;
726+
}
727+
}
757728

758-
sampleIndex -= spikeLength; // reset sample index
729+
sampleIndex -= spikeLength; // reset sample index
759730
mut.exit();
760731

761732
}
@@ -825,16 +796,6 @@ void SpikeSorter::startRecording()
825796
// delete msg_with_ts;
826797
// }
827798

828-
void SpikeSorter::handleEvent(int eventType, MidiMessage& event, int sampleNum)
829-
{
830-
if (eventType == TIMESTAMP)
831-
{
832-
const uint8* dataptr = event.getRawData();
833-
memcpy(&hardware_timestamp, dataptr + 4, 8); // remember to skip first four bytes
834-
software_timestamp = timer.getHighResolutionTicks(); // software timestamp for start of buffer
835-
}
836-
}
837-
838799
// void SpikeSorter::addNetworkEventToQueue(StringTS S)
839800
// {
840801
// StringTS copy(S);
@@ -872,8 +833,7 @@ void SpikeSorter::clearRunningStatForSelectedElectrode()
872833
electrodes[currentElectrode]->runningStats[0].Clear();
873834
}
874835

875-
void SpikeSorter::process(AudioSampleBuffer& buffer,
876-
MidiBuffer& events)
836+
void SpikeSorter::process(AudioSampleBuffer& buffer)
877837
{
878838

879839
//printf("Entering Spike Detector::process\n");
@@ -882,8 +842,7 @@ void SpikeSorter::process(AudioSampleBuffer& buffer,
882842
// cycle through electrodes
883843
Electrode* electrode;
884844
dataBuffer = &buffer;
885-
886-
checkForEvents(events); // find latest's packet timestamps
845+
const SpikeChannel* spikeChan;
887846

888847
//channelBuffers->update(buffer, hardware_timestamp,software_timestamp, nSamples);
889848

@@ -893,6 +852,7 @@ void SpikeSorter::process(AudioSampleBuffer& buffer,
893852
// std::cout << "ELECTRODE " << i << std::endl;
894853

895854
electrode = electrodes[i];
855+
spikeChan = spikeChannelArray[i];
896856

897857
// refresh buffer index for this electrode
898858
sampleIndex = electrode->lastBufferIndex - 1; // subtract 1 to account for
@@ -958,28 +918,20 @@ void SpikeSorter::process(AudioSampleBuffer& buffer,
958918
peakIndex = sampleIndex;
959919
sampleIndex -= (electrode->prePeakSamples+1);
960920

961-
SpikeObject newSpike;
962-
newSpike.sortedId = 0; // unsorted.
963-
newSpike.timestamp = getTimestamp(currentChannel) + peakIndex;
964-
newSpike.electrodeID = electrode->electrodeID;
965-
newSpike.channel = chan;
966-
newSpike.source = i;
967-
newSpike.nChannels = electrode->numChannels;
968-
newSpike.samplingFrequencyHz = samplingFrequencyHz;
969-
newSpike.color[0] = newSpike.color[1] = newSpike.color[2] = 127;
970-
currentIndex = 0;
971-
972-
// package spikes;
973-
for (int channel = 0; channel < electrode->numChannels; channel++)
974-
{
975-
976-
addWaveformToSpikeObject(&newSpike,
977-
peakIndex,
978-
i,
979-
channel);
980-
981-
//std::cout << "adding waveform" << std::endl;
982-
}
921+
const SpikeChannel* spikeChan = getSpikeChannel(i);
922+
SpikeEvent::SpikeBuffer spikeData(spikeChan);
923+
Array<float> thresholds;
924+
for (int channel = 0; channel < electrode->numChannels; ++channel)
925+
{
926+
addWaveformToSpikeObject(spikeData,
927+
peakIndex,
928+
i,
929+
channel);
930+
thresholds.add((int)*(electrode->thresholds + channel));
931+
}
932+
int64 timestamp = getTimestamp(electrode->channels[0]) + peakIndex;
933+
934+
SorterSpikePtr sorterSpike = new SorterSpikeContainer(spikeChan, spikeData, timestamp);
983935

984936
/*
985937
bool perfectMatch = true;
@@ -994,10 +946,10 @@ void SpikeSorter::process(AudioSampleBuffer& buffer,
994946
*/
995947

996948
//for (int xxx = 0; xxx < 1000; xxx++) // overload with spikes for testing purposes
997-
electrode->spikeSort->projectOnPrincipalComponents(&newSpike);
949+
electrode->spikeSort->projectOnPrincipalComponents(sorterSpike);
998950

999951
// Add spike to drawing buffer....
1000-
electrode->spikeSort->sortSpike(&newSpike, PCAbeforeBoxes);
952+
electrode->spikeSort->sortSpike(sorterSpike, PCAbeforeBoxes);
1001953

1002954

1003955
// transfer buffered spikes to spike plot
@@ -1012,11 +964,14 @@ void SpikeSorter::process(AudioSampleBuffer& buffer,
1012964
}
1013965

1014966

1015-
electrode->spikePlot->processSpikeObject(newSpike);
967+
electrode->spikePlot->processSpikeObject(sorterSpike);
1016968
}
1017969

970+
MetaDataValueArray md;
971+
md.add(new MetaDataValue(MetaDataDescriptor::UINT8, 3, sorterSpike->color));
972+
SpikeEventPtr newSpike = SpikeEvent::createSpikeEvent(spikeChan, timestamp, thresholds, spikeData, sorterSpike->sortedId, md);
1018973

1019-
addSpikeEvent(&newSpike, events, peakIndex);
974+
addSpike(spikeChan, newSpike, peakIndex);
1020975
//prevSpike = newSpike;
1021976
// advance the sample index
1022977
sampleIndex = peakIndex + electrode->postPeakSamples;
@@ -1337,7 +1292,7 @@ void SpikeSorter::loadCustomParametersFromXml()
13371292
int sourceNodeId = 102010; // some number
13381293

13391294
Electrode* newElectrode = new Electrode(electrodeID, &uniqueIDgenerator,&computingThread, electrodeName, channelsPerElectrode, channels,getDefaultThreshold(),
1340-
numPreSamples,numPostSamples, getSampleRate(), sourceNodeId);
1295+
numPreSamples,numPostSamples, getSampleRate(), sourceNodeId,0);
13411296
for (int k=0; k<channelsPerElectrode; k++)
13421297
{
13431298
newElectrode->thresholds[k] = thres[k];
@@ -1963,5 +1918,3 @@ int ContinuousCircularBuffer::GetPtr()
19631918

19641919
/************************************************************/
19651920

1966-
1967-

0 commit comments

Comments
 (0)