Skip to content

Commit a441f80

Browse files
committed
Merge branch 'testing' into development
2 parents 4785a20 + 8e39b06 commit a441f80

11 files changed

Lines changed: 125 additions & 49 deletions

File tree

Builds/MacOSX/Plugins/EvntTrigAvg/EvntTrigAvg.xcodeproj/project.pbxproj

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
objectVersion = 48;
77
objects = {
88

9+
/* Begin PBXBuildFile section */
10+
038C244D1FA389C4006EA927 /* EvntTrigAvg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 038981DE1FA2F00200D25D7A /* EvntTrigAvg.cpp */; };
11+
038C244E1FA389C4006EA927 /* EvntTrigAvgCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 038981E31FA2F00300D25D7A /* EvntTrigAvgCanvas.cpp */; };
12+
038C244F1FA389C4006EA927 /* EvntTrigAvgEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 038981E21FA2F00200D25D7A /* EvntTrigAvgEditor.cpp */; };
13+
038C24501FA38A0F006EA927 /* OpenEphysLib.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 038981E11FA2F00200D25D7A /* OpenEphysLib.cpp */; };
14+
/* End PBXBuildFile section */
15+
916
/* Begin PBXFileReference section */
1017
038981D31FA2EFB500D25D7A /* EvntTrigAvg.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EvntTrigAvg.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
1118
038981D61FA2EFB500D25D7A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -146,6 +153,10 @@
146153
isa = PBXSourcesBuildPhase;
147154
buildActionMask = 2147483647;
148155
files = (
156+
038C24501FA38A0F006EA927 /* OpenEphysLib.cpp in Sources */,
157+
038C244D1FA389C4006EA927 /* EvntTrigAvg.cpp in Sources */,
158+
038C244E1FA389C4006EA927 /* EvntTrigAvgCanvas.cpp in Sources */,
159+
038C244F1FA389C4006EA927 /* EvntTrigAvgEditor.cpp in Sources */,
149160
);
150161
runOnlyForDeploymentPostprocessing = 0;
151162
};

Source/Plugins/BasicSpikeDisplay/SpikeDetector/SpikeDetector.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,11 @@ void SpikeDetector::createSpikeChannels()
101101

102102
void SpikeDetector::updateSettings()
103103
{
104-
if (getNumInputs() > 0)
105-
overflowBuffer.setSize (getNumInputs(), overflowBufferSize);
104+
if (getNumInputs() > 0)
105+
{
106+
overflowBuffer.setSize(getNumInputs(), overflowBufferSize);
107+
overflowBuffer.clear();
108+
}
106109

107110
}
108111

@@ -516,7 +519,7 @@ float SpikeDetector::getNextSample (int& chan)
516519
}
517520
else
518521
{
519-
if (sampleIndex < dataBuffer->getNumSamples())
522+
if (sampleIndex < getNumSamples(chan))
520523
return *dataBuffer->getWritePointer (chan, sampleIndex);
521524
else
522525
return 0;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
LIBNAME := $(notdir $(CURDIR))
3+
OBJDIR := $(OBJDIR)/$(LIBNAME)
4+
TARGET := $(LIBNAME).so
5+
6+
7+
SRC_DIR := ${shell find ./ -type d -print}
8+
VPATH := $(SOURCE_DIRS)
9+
10+
SRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.cpp))
11+
OBJ := $(addprefix $(OBJDIR)/,$(notdir $(SRC:.cpp=.o)))
12+
13+
BLDCMD := $(CXX) -shared -o $(OUTDIR)/$(TARGET) $(OBJ) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH)
14+
15+
VPATH = $(SRC_DIR)
16+
17+
.PHONY: objdir
18+
19+
$(OUTDIR)/$(TARGET): objdir $(OBJ)
20+
-@mkdir -p $(BINDIR)
21+
-@mkdir -p $(LIBDIR)
22+
-@mkdir -p $(OUTDIR)
23+
@echo "Building $(TARGET)"
24+
@$(BLDCMD)
25+
26+
$(OBJDIR)/%.o : %.cpp
27+
@echo "Compiling $<"
28+
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
29+
30+
31+
objdir:
32+
-@mkdir -p $(OBJDIR)
33+
34+
clean:
35+
@echo "Cleaning $(LIBNAME)"
36+
-@rm -rf $(OBJDIR)
37+
-@rm -f $(OUTDIR)/$(TARGET)
38+
39+
-include $(OBJ:%.o=%.d)

Source/Plugins/EvntTrigAvg/OpenEphysLib.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ using namespace Plugin;
3737
extern "C" EXPORT void getLibInfo(Plugin::LibraryInfo* info)
3838
{
3939
info->apiVersion = PLUGIN_API_VER;
40-
info->name = "EvntTrigAvg";
40+
info->name = "Event Trig Avg";
4141
info->libVersion = 1;
4242
info->numPlugins = NUM_PLUGINS;
4343
}
@@ -48,7 +48,7 @@ extern "C" EXPORT int getPluginInfo(int index, Plugin::PluginInfo* info)
4848
{
4949
case 0:
5050
info->type = Plugin::PLUGIN_TYPE_PROCESSOR;
51-
info->processor.name = "EvntTrigAvg";
51+
info->processor.name = "Event Trig Avg";
5252
info->processor.type = Plugin::FilterProcessor;
5353
info->processor.creator = &(Plugin::createProcessor<EvntTrigAvg>);
5454
break;

Source/Plugins/SpikeSorter/SpikeSortBoxes.cpp

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -882,9 +882,10 @@ void SpikeSortBoxes::projectOnPrincipalComponents(SorterSpikePtr so)
882882
if ((spikeBufferIndex == bufferSize -1 && !bPCAcomputed && !bPCAJobSubmitted) || bRePCA)
883883
{
884884
bPCAJobSubmitted = true;
885+
bPCAcomputed = false;
885886
bRePCA = false;
886887
// submit a new job to compute the spike buffer.
887-
PCAjob job(spikeBuffer,pc1,pc2, &pc1min, &pc2min, &pc1max, &pc2max, &bPCAjobFinished);
888+
PCAJobPtr job = new PCAjob(spikeBuffer,pc1,pc2, pc1min, pc2min, pc1max, pc2max, bPCAjobFinished);
888889
computingThread->addPCAjob(job);
889890
}
890891
}
@@ -1706,15 +1707,13 @@ static double sqrarg;
17061707
#define SQR(a) ((sqrarg = (a)) == 0.0 ? 0.0 : sqrarg * sqrarg)
17071708

17081709
PCAjob::PCAjob(SorterSpikeArray& _spikes, float* _pc1, float* _pc2,
1709-
float* pc1Min, float* pc2Min, float* pc1Max, float* pc2Max, bool* _reportDone) : spikes(_spikes), reportDone(_reportDone)
1710+
std::atomic<float>& pc1Min, std::atomic<float>& pc2Min, std::atomic<float>&pc1Max, std::atomic<float>& pc2Max, std::atomic<bool>& _reportDone) : spikes(_spikes),
1711+
pc1min(pc1Min), pc2min(pc2Min), pc1max(pc1Max), pc2max(pc2Max), reportDone(_reportDone)
17101712
{
17111713
cov = nullptr;
17121714
pc1 = _pc1;
17131715
pc2 = _pc2;
1714-
pc1min = pc1Min;
1715-
pc2min = pc2Min;
1716-
pc1max = pc1Max;
1717-
pc2max = pc2Max;
1716+
17181717
dim = spikes[0]->getChannel()->getNumChannels()*spikes[0]->getChannel()->getTotalSamples();
17191718

17201719
};
@@ -2114,10 +2113,10 @@ void PCAjob::computeSVD()
21142113
}
21152114

21162115

2117-
*pc1min = min1 - 1.5 * (max1-min1);
2118-
*pc2min = min2 - 1.5 * (max2-min2);
2119-
*pc1max = max1 + 1.5 * (max1-min1);
2120-
*pc2max = max2 + 1.5 * (max2-min2);
2116+
pc1min = min1 - 1.5 * (max1-min1);
2117+
pc2min = min2 - 1.5 * (max2-min2);
2118+
pc1max = max1 + 1.5 * (max1-min1);
2119+
pc2max = max2 + 1.5 * (max2-min2);
21212120

21222121
// clear memory
21232122
for (int k = 0; k < dim; k++)
@@ -2129,7 +2128,7 @@ void PCAjob::computeSVD()
21292128

21302129
// delete covariances
21312130
for (int k = 0; k < dim; k++)
2132-
delete cov[k];
2131+
delete[] cov[k];
21332132

21342133
delete[] cov;
21352134
cov = nullptr;
@@ -2140,11 +2139,11 @@ void PCAjob::computeSVD()
21402139
/**********************/
21412140

21422141

2143-
void PCAcomputingThread::addPCAjob(PCAjob job)
2142+
void PCAcomputingThread::addPCAjob(PCAJobPtr job)
21442143
{
21452144
{
21462145
ScopedLock critical(lock);
2147-
jobs.push(job);
2146+
jobs.add(job);
21482147
}
21492148

21502149
if (!isThreadRunning())
@@ -2158,19 +2157,19 @@ void PCAcomputingThread::run()
21582157
while (jobs.size() > 0)
21592158
{
21602159
lock.enter();
2161-
PCAjob J = jobs.front();
2162-
jobs.pop();
2160+
PCAJobPtr J = jobs.removeAndReturn(0);
2161+
if (J == nullptr) continue;
21632162
lock.exit();
21642163
// compute PCA
21652164
// 1. Compute Covariance matrix
21662165
// 2. Apply SVD on covariance matrix
21672166
// 3. Extract the two principal components corresponding to the largest singular values
21682167

2169-
J.computeCov();
2170-
J.computeSVD();
2168+
J->computeCov();
2169+
J->computeSVD();
21712170

21722171
// 4. Report to the spike sorting electrode that PCA is finished
2173-
*(J.reportDone) = true;
2172+
J->reportDone = true;
21742173
}
21752174
}
21762175

@@ -2239,4 +2238,4 @@ const SpikeChannel* SorterSpikeContainer::getChannel() const
22392238
int64 SorterSpikeContainer::getTimestamp() const
22402239
{
22412240
return timestamp;
2242-
}
2241+
}

Source/Plugins/SpikeSorter/SpikeSortBoxes.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2828
#include <algorithm> // std::sort
2929
#include <list>
3030
#include <queue>
31+
#include <atomic>
3132

3233
class SorterSpikeContainer : public ReferenceCountedObject
3334
{
@@ -176,26 +177,28 @@ class PCAjob
176177
public:
177178
PCAjob();
178179
};*/
179-
class PCAjob
180+
class PCAjob : public ReferenceCountedObject
180181
{
181182
public:
182183
PCAjob(SorterSpikeArray& _spikes, float* _pc1, float* _pc2,
183-
float*, float*, float*, float*, bool* _reportDone);
184+
std::atomic<float>&, std::atomic<float>&, std::atomic<float>&, std::atomic<float>&, std::atomic<bool>& _reportDone);
184185
~PCAjob();
185186
void computeCov();
186187
void computeSVD();
187188

188189
float** cov;
189190
SorterSpikeArray spikes;
190191
float* pc1, *pc2;
191-
float* pc1min, *pc2min, *pc1max, *pc2max;
192-
bool* reportDone;
192+
std::atomic<float>& pc1min, &pc2min, &pc1max, &pc2max;
193+
std::atomic<bool>& reportDone;
193194
private:
194195
int svdcmp(float** a, int nRows, int nCols, float* w, float** v);
195196
float pythag(float a, float b);
196197
int dim;
197198
};
198199

200+
typedef ReferenceCountedObjectPtr<PCAjob> PCAJobPtr;
201+
typedef ReferenceCountedArray<PCAjob, CriticalSection> PCAJobArray;
199202

200203
class cPolygon
201204
{
@@ -213,10 +216,10 @@ class PCAcomputingThread : juce::Thread
213216
public:
214217
PCAcomputingThread();
215218
void run(); // computes PCA on waveforms
216-
void addPCAjob(PCAjob job);
219+
void addPCAjob(PCAJobPtr job);
217220

218221
private:
219-
std::queue<PCAjob> jobs;
222+
PCAJobArray jobs;
220223
CriticalSection lock;
221224
};
222225

@@ -299,11 +302,12 @@ class SpikeSortBoxes
299302
std::vector<BoxUnit> boxUnits;
300303
std::vector<PCAUnit> pcaUnits;
301304
float* pc1, *pc2;
302-
float pc1min, pc2min, pc1max, pc2max;
305+
std::atomic<float> pc1min, pc2min, pc1max, pc2max;
303306
SorterSpikeArray spikeBuffer;
304307
int bufferSize,spikeBufferIndex;
305308
PCAcomputingThread* computingThread;
306-
bool bPCAJobSubmitted,bPCAcomputed,bRePCA,bPCAjobFinished ;
309+
bool bPCAJobSubmitted,bPCAcomputed,bRePCA;
310+
std::atomic<bool> bPCAjobFinished ;
307311

308312

309313
};

Source/Plugins/SpikeSorter/SpikeSorter.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,13 @@ void SpikeSorter::updateSettings()
172172
{
173173

174174
mut.enter();
175+
sorterReady = false;
175176
int numChannels = getNumInputs();
176-
if (numChannels > 0)
177-
overflowBuffer.setSize(getNumInputs(), overflowBufferSize);
177+
if (numChannels > 0)
178+
{
179+
overflowBuffer.setSize(getNumInputs(), overflowBufferSize);
180+
overflowBuffer.clear();
181+
}
178182

179183
if (channelBuffers != nullptr)
180184
delete channelBuffers;
@@ -191,7 +195,13 @@ void SpikeSorter::updateSettings()
191195
Array<const DataChannel*> chans;
192196
for (int c = 0; c < nChans; c++)
193197
{
194-
chans.add(getDataChannel(elec->channels[c]));
198+
const DataChannel* ch = getDataChannel(elec->channels[c]);
199+
if (!ch)
200+
{
201+
//not enough channels for the electrodes
202+
return;
203+
}
204+
chans.add(ch);
195205
}
196206

197207
SpikeChannel* spk = new SpikeChannel(SpikeChannel::typeFromNumChannels(nChans), this, chans);
@@ -200,7 +210,7 @@ void SpikeSorter::updateSettings()
200210

201211
spikeChannelArray.add(spk);
202212
}
203-
213+
sorterReady = true;
204214
mut.exit();
205215
}
206216

@@ -212,9 +222,6 @@ Electrode::~Electrode()
212222
delete[] voltageScale;
213223
delete[] channels;
214224
delete[] runningStats;
215-
216-
delete spikeSort;
217-
218225
}
219226

220227
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)
@@ -459,6 +466,7 @@ bool SpikeSorter::addElectrode(int nChans, String name, double Depth)
459466
eventlog += String(chans[k])+ " " + name;
460467

461468
//addNetworkEventToQueue(StringTS(eventlog));
469+
delete[] chans;
462470

463471
resetElectrode(newElectrode);
464472
electrodes.add(newElectrode);
@@ -647,6 +655,12 @@ bool SpikeSorter::enable()
647655
{
648656

649657
useOverflowBuffer.clear();
658+
if (!sorterReady)
659+
{
660+
CoreServices::sendStatusMessage("Not enough channels for the configured electrodes");
661+
std::cout << "SpikeSorter: Not enough channels for the configured electrodes" << std::endl;
662+
return false;
663+
}
650664

651665
for (int i = 0; i < electrodes.size(); i++)
652666
useOverflowBuffer.add(false);
@@ -1036,7 +1050,7 @@ float SpikeSorter::getNextSample(int& chan)
10361050
// useOverflowBuffer = false;
10371051
// std::cout << " sample index " << sampleIndex << "from regular buffer" << std::endl;
10381052

1039-
if (sampleIndex < dataBuffer->getNumSamples())
1053+
if (sampleIndex < getNumSamples(chan))
10401054
return (*dataBuffer->getReadPointer(chan, sampleIndex));
10411055
else
10421056
return 0;
@@ -1112,7 +1126,7 @@ void SpikeSorter::addProbes(String probeType,int numProbes, int nElectrodesPerPr
11121126
increaseUniqueProbeID(probeType);
11131127
}
11141128
}
1115-
Array<Electrode*> SpikeSorter::getElectrodes()
1129+
const OwnedArray<Electrode>& SpikeSorter::getElectrodes()
11161130
{
11171131
return electrodes;
11181132
}
@@ -1292,6 +1306,9 @@ void SpikeSorter::loadCustomParametersFromXml()
12921306
newElectrode->thresholds[k] = thres[k];
12931307
newElectrode->isActive[k] = isActive[k];
12941308
}
1309+
delete[] channels;
1310+
delete[] thres;
1311+
delete[] isActive;
12951312

12961313
newElectrode->advancerID = advancerID;
12971314
newElectrode->depthOffsetMM = depthOffsetMM;

0 commit comments

Comments
 (0)