diff --git a/Source/Processors/Editors/SpikeSorterEditor.cpp b/Source/Processors/Editors/SpikeSorterEditor.cpp
index fc286491a21271086d24fdf91c9cbd0b50208886..fc7340e4a73795bdd69d14d4ae94df87ab03aa23 100644
--- a/Source/Processors/Editors/SpikeSorterEditor.cpp
+++ b/Source/Processors/Editors/SpikeSorterEditor.cpp
@@ -431,6 +431,8 @@ void SpikeSorterEditor::buttonEvent(Button* button)
 
 	 	processor->addProbes(ProbeType,numProbes, nElectrodes,nChansPerElectrode, firstElectrodeOffset,interelectrodeDistance);
 		refreshElectrodeList();
+
+        getEditorViewport()->makeEditorVisible(this, true, true);
 		
         return;
 
diff --git a/Source/Processors/SpikeSortBoxes.cpp b/Source/Processors/SpikeSortBoxes.cpp
index 8c972882a6a5bc317930d5e19d2034154c8b51f7..d399221d3c44ee497f09df699ef418d0061d1990 100644
--- a/Source/Processors/SpikeSortBoxes.cpp
+++ b/Source/Processors/SpikeSortBoxes.cpp
@@ -1743,8 +1743,9 @@ float PCAjob::pythag(float a, float b) {
   V (not V transpose) is output as the matrix V[nCols][nCols].
 */
 int PCAjob::svdcmp(float **a, int nRows, int nCols, float *w, float **v) {
-  int flag,i,its,j,jj,k,l,nm;
-  float anorm,c,f,g,h,s,scale,x,y,z,*rv1;
+ 
+  int flag, i, its, j, jj, k, l, nm;
+  float anorm, c, f, g, h, s, scale, x, y, z, *rv1;
 
   rv1 = new float[nCols];
   if(rv1 == NULL) {
@@ -1753,14 +1754,14 @@ int PCAjob::svdcmp(float **a, int nRows, int nCols, float *w, float **v) {
   }
 
   g = scale = anorm = 0.0;
-  for(i=0;i<nCols;i++) {
+  for(i = 0; i < nCols; i++) {
     l = i+1;
     rv1[i] = scale*g;
     g = s = scale = 0.0;
     if(i < nRows) {
-      for(k=i;k<nRows;k++) scale += fabs(a[k][i]);
+      for(k = i; k < nRows; k++) scale += fabs(a[k][i]);
       if(scale) {
-	for(k=i;k<nRows;k++) {
+	for(k = i; k < nRows; k++) {
 	  a[k][i] /= scale;
 	  s += a[k][i] * a[k][i];
 	}
@@ -1768,20 +1769,21 @@ int PCAjob::svdcmp(float **a, int nRows, int nCols, float *w, float **v) {
 	g = -SIGN(sqrt(s),f);
 	h = f * g - s;
 	a[i][i] = f - g;
-	for(j=l;j<nCols;j++) {
-	  for(s=0.0,k=i;k<nRows;k++) s += a[k][i] * a[k][j];
+	for(j = l; j < nCols; j++) {
+	  for(s = 0.0, k = i; k < nRows; k++) s += a[k][i] * a[k][j];
 	  f = s / h;
-	  for(k=i;k<nRows;k++) a[k][j] += f * a[k][i];
+	  for(k = i; k < nRows; k++) a[k][j] += f * a[k][i];
 	}
-	for(k=i;k<nRows;k++) a[k][i] *= scale;
+	for(k = i; k < nRows; k++) a[k][i] *= scale;
       }
     }
     w[i] = scale * g;
     g = s = scale = 0.0;
     if(i < nRows && i != nCols-1) {
-      for(k=l;k<nCols;k++) scale += fabs(a[i][k]);
+      for(k = l; k < nCols; k++) scale += fabs(a[i][k]);
       if(scale)  {
-	for(k=l;k<nCols;k++) {
+	for(k = l; k < nCols; k++)
+	{
 	  a[i][k] /= scale;
 	  s += a[i][k] * a[i][k];
 	}
@@ -1939,8 +1941,8 @@ void PCAjob::computeCov()
 {
 	// allocate and zero
 	cov = new float*[dim];
-	float *mean  = new float[dim];
-	for (int k=0;k<dim;k++) {
+	float* mean  = new float[dim];
+	for (int k = 0;k < dim; k++) {
 		cov[k] = new float[dim];
 		for (int j=0;j<dim;j++)
 		{
@@ -1981,6 +1983,13 @@ void PCAjob::computeCov()
 	}
 	delete mean;
 
+	// delete covariances
+	for (int k = 0; k < dim; k++)
+	 	delete cov[k];
+
+	delete(cov);
+	cov = nullptr;
+
 }
 
 std::vector<int> sort_indexes( std::vector<float> v) 
@@ -1993,16 +2002,15 @@ std::vector<int> sort_indexes( std::vector<float> v)
 		idx[i] = i;
 	}
 
-	//// NEED TO FIX THIS:::: -- Linux compiler doesn't understand syntax!
-	// sort indexes based on comparing values in v
-	// sort(
-	// 	idx.begin(), 
-	// 	idx.end(), 
-	// 	[&v](size_t i1, size_t i2) 
-	// 	{
-	// 		return v[i1] > v[i2];
-	// 	}
-	// );
+	//sort indexes based on comparing values in v
+	sort(
+		idx.begin(), 
+		idx.end()//, 
+		//[&v](size_t i1, size_t i2) 
+		//{
+		//	return v[i1] > v[i2];
+		//}
+	);
 
 	return idx;
 }
@@ -2015,30 +2023,23 @@ void PCAjob::computeSVD()
 	sigvalues = new float[dim];
 
 	eigvec = new float*[dim];
-	for (int k=0;k<dim;k++) {
+	for (int k = 0; k < dim; k++) {
 		eigvec[k] = new float[dim];
 		for (int j=0;j<dim;j++)
 		{
 			eigvec[k][j] = 0;
 		}
 	}
-	
-	svdcmp(cov, dim, dim, sigvalues,eigvec );
-	// find the two largest eigen values
-	for (int k=0;k<dim;k++)
-		delete cov[k];
 
-	delete(cov);
-	cov=nullptr;
+	svdcmp(cov, dim, dim, sigvalues, eigvec);
+	
 
-	  std::vector<float> sig;
-	  sig.resize(dim);
-	  for (int k=0;k<dim;k++)
-		  sig[k] = sigvalues[k];
 
-		
+	std::vector<float> sig;
+	sig.resize(dim);
+	for (int k = 0; k < dim; k++)
+	    sig[k] = sigvalues[k];
 
-	
 	std::vector<int> sortind = sort_indexes(sig);
 
 	//
@@ -2076,7 +2077,7 @@ void PCAjob::computeSVD()
 	 *pc2max = max2 + 1.5 * (max2-min2);
 
 	// clear memory
-	for (int k=0;k<dim;k++)
+	for (int k = 0; k < dim; k++)
 	{
 		delete eigvec[k];
 	}
diff --git a/Source/Processors/SpikeSorter.cpp b/Source/Processors/SpikeSorter.cpp
index 12b317ed4df9408b435919f83f25f281b1b61461..7eb8cf1a08e7d63b89b551305706d2f3a0890f09 100644
--- a/Source/Processors/SpikeSorter.cpp
+++ b/Source/Processors/SpikeSorter.cpp
@@ -188,13 +188,19 @@ void SpikeSorter::updateSettings()
 	double ContinuousBufferLengthSec = 5;
 	channelBuffers = new ContinuousCircularBuffer(numChannels,SamplingRate,1, ContinuousBufferLengthSec);
 	 
-	// instead, we pass things now in this new form:
-	for (int k = 0; k < electrodes.size(); k++)
+	for (int i = 0; i < electrodes.size(); i++)
 	{
-		String eventlog = "NewElectrode "+String(electrodes[k]->electrodeID) + " "+String(electrodes[k]->numChannels)+" ";
-		for (int j=0;j<electrodes[k]->numChannels;j++)
-			eventlog += String(electrodes[k]->channels[j])+ " "+electrodes[k]->name;
-		//addNetworkEventToQueue(StringTS(eventlog));
+
+		Channel* ch = new Channel(this, i);
+        //ch->isEventChannel = true;
+        ch->eventType = SPIKE_BASE_CODE + electrodes[i]->numChannels;
+        ch->name = electrodes[i]->name;
+
+        eventChannels.add(ch);
+		// String eventlog = "NewElectrode "+String(electrodes[k]->electrodeID) + " "+String(electrodes[k]->numChannels)+" ";
+		// for (int j=0;j<electrodes[k]->numChannels;j++)
+		// 	eventlog += String(electrodes[k]->channels[j])+ " "+electrodes[k]->name;
+		// //addNetworkEventToQueue(StringTS(eventlog));
 	}
 	
 	mut.exit();
@@ -319,14 +325,14 @@ void SpikeSorter::addNewUnit(int electrodeID, int newUnitID, uint8 r, uint8 g, u
 {
 	String eventlog = "NewUnit "+String(electrodeID) + " "+String(newUnitID)+" "+String(r)+" "+String(g)+" "+String(b);
 	//addNetworkEventToQueue(StringTS(eventlog));
-	updateSinks( electrodeID,  newUnitID, r,g,b,true);
+	//updateSinks( electrodeID,  newUnitID, r,g,b,true);
 }
 
 void SpikeSorter::removeUnit(int electrodeID, int unitID)
 {
 	String eventlog = "RemoveUnit "+String(electrodeID) + " "+String(unitID);
 	//addNetworkEventToQueue(StringTS(eventlog));
-	updateSinks( electrodeID,  unitID, 0,0,0,false);
+	//updateSinks( electrodeID,  unitID, 0,0,0,false);
 	
 }
 
@@ -335,7 +341,7 @@ void SpikeSorter::removeAllUnits(int electrodeID)
 {
 	String eventlog = "RemoveAllUnits "+String(electrodeID);
 	//addNetworkEventToQueue(StringTS(eventlog));
-	updateSinks( electrodeID,true);
+	//updateSinks( electrodeID,true);
 }
 
 RHD2000Thread* SpikeSorter::getRhythmAccess()
@@ -397,171 +403,13 @@ void SpikeSorter::assignDACtoChannel(int dacOutput, int channel)
 	}
 }
 
-
-void SpikeSorter::updateSinks(int electrodeID, int unitID, uint8 r, uint8 g, uint8 b, bool addRemove)
-{
-	// inform sinks about a new unit
-	ProcessorGraph *gr = getProcessorGraph();
-	Array<GenericProcessor*> p = gr->getListOfProcessors();
-	// for (int k=0;k<p.size();k++)
-	// {
-	// 	if (p[k]->getName() == "PSTH")
-	// 	{
-	// 		PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k];
-	// 		if (node->trialCircularBuffer != nullptr)
-	// 		{
-	// 			if (addRemove) 
-	// 			{
-	// 				// add electrode
-	// 				node->trialCircularBuffer->addNewUnit(electrodeID,unitID,r,g,b);
-	// 			} else
-	// 			{
-	// 				// remove electrode
-	// 				node->trialCircularBuffer->removeUnit(electrodeID,unitID);
-	// 			}
-	// 			((PeriStimulusTimeHistogramEditor *) node->getEditor())->updateCanvas();
-	// 		}
-	// 	}
-	// }
-}
-
-void SpikeSorter::updateSinks(int electrodeID, bool rem)
-{
-	// inform sinks about a removal of all units
-	ProcessorGraph *g = getProcessorGraph();
-	Array<GenericProcessor*> p = g->getListOfProcessors();
-	// for (int k=0;k<p.size();k++)
-	// {
-	// 	if (p[k]->getName() == "PSTH")
-	// 	{
-	// 		PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k];
-	// 		if (node->trialCircularBuffer != nullptr)
-	// 		{
-	// 			if (rem)
-	// 			{
-	// 				node->trialCircularBuffer->removeAllUnits(electrodeID);
-	// 			}
-	// 			(((PeriStimulusTimeHistogramEditor *) node->getEditor()))->updateCanvas();
-	// 		}
-	// 	}
-	// 	if (p[k]->getName() == "Spike Viewer")
-	// 	{
-	// 		SpikeDisplayNode* node = (SpikeDisplayNode*)p[k];
-	// 		node->syncWithSpikeSorter();
-	// 	}
-	// }
-}
-
-void SpikeSorter::updateSinks(int electrodeID, int channelindex, int newchannel)
-{
-	// inform sinks about a channel change
-	ProcessorGraph *g = getProcessorGraph();
-	Array<GenericProcessor*> p = g->getListOfProcessors();
-	// for (int k=0;k<p.size();k++)
-	// {
-	// 	if (p[k]->getName() == "PSTH")
-	// 	{
-	// 		PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k];
-	// 		if (node->trialCircularBuffer != nullptr)
-	// 		{
-	// 			node->trialCircularBuffer->channelChange(electrodeID, channelindex,newchannel);
-	// 		}
-	// 	}
-	// 	if (p[k]->getName() == "Spike Viewer")
-	// 	{
-	// 		SpikeDisplayNode* node = (SpikeDisplayNode*)p[k];
-	// 		node->syncWithSpikeSorter();
-	// 	}
-	// }
-}
-
-
-void SpikeSorter::updateSinks(Electrode* electrode)
-{
-	// inform sinks about an electrode add 
-	ProcessorGraph *g = getProcessorGraph();
-	Array<GenericProcessor*> p = g->getListOfProcessors();
-	// for (int k=0;k<p.size();k++)
-	// {
-	// 	String s = p[k]->getName();
-	// 	if (p[k]->getName() == "PSTH")
-	// 	{
-	// 		PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k];
-	// 		if (node->trialCircularBuffer != nullptr)
-	// 		{
-	// 				// add electrode
-	// 				node->trialCircularBuffer->addNewElectrode(electrode);
-	// 				(((PeriStimulusTimeHistogramEditor *) node->getEditor()))->updateCanvas();
-	// 		}
-	// 	}
-	// 	if (p[k]->getName() == "Spike Viewer")
-	// 	{
-	// 		SpikeDisplayNode* node = (SpikeDisplayNode*)p[k];
-	// 		node->syncWithSpikeSorter();
-	// 	}
-	// }
-}
-
-void SpikeSorter::updateSinks(int electrodeID, String NewName)
-{
-	// inform sinks about an electrode name change
-	ProcessorGraph *g = getProcessorGraph();
-	Array<GenericProcessor*> p = g->getListOfProcessors();
-	// for (int k=0;k<p.size();k++)
-	// {
-	// 	String s = p[k]->getName();
-	// 	if (p[k]->getName() == "PSTH")
-	// 	{
-	// 		PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k];
-	// 		if (node->trialCircularBuffer != nullptr)
-	// 		{
-	// 				// add electrode
-	// 				node->trialCircularBuffer->updateElectrodeName(electrodeID, NewName);
-	// 				(((PeriStimulusTimeHistogramEditor *) node->getEditor()))->updateCanvas();
-	// 		}
-	// 	}
-	// 	if (p[k]->getName() == "Spike Viewer")
-	// 	{
-	// 		SpikeDisplayNode* node = (SpikeDisplayNode*)p[k];
-	// 		node->syncWithSpikeSorter();
-	// 	}
-	// }
-}
-
-
-void SpikeSorter::updateSinks(int electrodeID)
-{
-	// inform sinks about an electrode removal
-	ProcessorGraph *g = getProcessorGraph();
-	Array<GenericProcessor*> p = g->getListOfProcessors();
-	// for (int k=0;k<p.size();k++)
-	// {
-	// 	String s = p[k]->getName();
-	// 	if (p[k]->getName() == "PSTH")
-	// 	{
-	// 		PeriStimulusTimeHistogramNode *node = (PeriStimulusTimeHistogramNode*)p[k];
-	// 		if (node->trialCircularBuffer != nullptr)
-	// 		{
-	// 			// remove electrode
-	// 			node->trialCircularBuffer->removeElectrode(electrodeID);
-	// 			((PeriStimulusTimeHistogramEditor *) node->getEditor())->updateCanvas();
-	// 		}
-	// 	}
-	// 	if (p[k]->getName() == "Spike Viewer")
-	// 	{
-	// 		SpikeDisplayNode* node = (SpikeDisplayNode*)p[k];
-	// 		node->syncWithSpikeSorter();
-	// 	}
-	// }
-}
-
 void SpikeSorter::addElectrode(Electrode* newElectrode)
 {
 	mut.enter();
     resetElectrode(newElectrode);
     electrodes.add(newElectrode);
 	// inform PSTH sink, if it exists, about this new electrode.
-	updateSinks(newElectrode);
+	//updateSinks(newElectrode);
 	mut.exit();
 }
 
@@ -605,7 +453,7 @@ bool SpikeSorter::addElectrode(int nChans, String name, double Depth)
 
     resetElectrode(newElectrode);
     electrodes.add(newElectrode);
-	updateSinks(newElectrode);
+	//updateSinks(newElectrode);
 	setCurrentElectrodeIndex(electrodes.size()-1);
 	mut.exit();
     return true;
@@ -654,7 +502,7 @@ bool SpikeSorter::removeElectrode(int index)
 	int idToRemove = electrodes[index]->electrodeID;
     electrodes.remove(index);
 
-	updateSinks(idToRemove);
+	//(idToRemove);
 
 	if (electrodes.size() > 0)
 		currentElectrode = electrodes.size()-1;
@@ -669,7 +517,7 @@ void SpikeSorter::setElectrodeName(int index, String newName)
 {
 	mut.enter();
     electrodes[index-1]->name = newName;
-	updateSinks(electrodes[index-1]->electrodeID, newName);
+	//updateSinks(electrodes[index-1]->electrodeID, newName);
 	mut.exit();
 }
 
@@ -685,7 +533,7 @@ void SpikeSorter::setChannel(int electrodeIndex, int channelNum, int newChannel)
 	String eventlog = "ChanelElectrodeChannel " + String(electrodes[electrodeIndex]->electrodeID) + " " + String(channelNum) + " " + String(newChannel);
 	//addNetworkEventToQueue(StringTS(eventlog));
 	
-	updateSinks(electrodes[electrodeIndex]->electrodeID, channelNum,newChannel);
+	//updateSinks(electrodes[electrodeIndex]->electrodeID, channelNum,newChannel);
 
     *(electrodes[electrodeIndex]->channels+channelNum) = newChannel;
 	mut.exit();
diff --git a/Source/Processors/SpikeSorter.h b/Source/Processors/SpikeSorter.h
index 3df7bddc4edd1ad6c744948e66a2b7ab2185074b..82136225e4c17963071dd4a8f89c6f84d5d0697c 100644
--- a/Source/Processors/SpikeSorter.h
+++ b/Source/Processors/SpikeSorter.h
@@ -238,19 +238,6 @@ public:
 
 	/** returns a channel's detection threshold */
     double getChannelThreshold(int electrodeNum, int channelNum);
-	
-	/** sync PSTH : inform of a new electrode added  */
-	void updateSinks(Electrode* newElectrode); 
-	/** sync PSTH : inform of an electrode removal */
-	void updateSinks(int electrodeID); 
-	/** sync PSTH : inform of a channel swap */
-	void updateSinks(int electrodeID, int channelindex, int newchannel);
-	/** sync PSTH: inform of a new unit added / removed */
-	void updateSinks(int electrodeID, int unitID, uint8 r, uint8 g, uint8 b, bool addRemove);
-	/** sync PSTH: inform of a name change*/
-	void updateSinks(int electrodeID, String NewName);
-	/** sync PSTH: remove all units*/
-	void updateSinks(int electrodeID, bool b);
 
 	/** used to generate messages over the network and to inform PSTH sink */
 	void addNewUnit(int electrodeID, int newUnitID, uint8 r, uint8 g, uint8 b);
diff --git a/Source/Processors/Visualization/SpikeDisplayCanvas.cpp b/Source/Processors/Visualization/SpikeDisplayCanvas.cpp
index 7145dca563b4775c91d34def9e2cfcc2d91a21f0..67db2c80ca9c6f5740705461a04ce4d9134fa496 100755
--- a/Source/Processors/Visualization/SpikeDisplayCanvas.cpp
+++ b/Source/Processors/Visualization/SpikeDisplayCanvas.cpp
@@ -486,12 +486,14 @@ float SpikeDisplay::getRangeForWaveAxis(int plotNum, int axisNum)
 
 void SpikeDisplay::setThresholdForWaveAxis(int plotNum, int axisNum, float range)
 {
-    return spikePlots[plotNum]->setDisplayThresholdForChannel(axisNum, range);
+    if (spikePlots.size() > plotNum)
+        return spikePlots[plotNum]->setDisplayThresholdForChannel(axisNum, range);
 }
 
 void SpikeDisplay::setRangeForWaveAxis(int plotNum, int axisNum, float range)
 {
-    return spikePlots[plotNum]->setRangeForChannel(axisNum, range);
+    if (spikePlots.size() > plotNum)
+        return spikePlots[plotNum]->setRangeForChannel(axisNum, range);
 }
 
 // ----------------------------------------------------------------
diff --git a/Source/Processors/Visualization/SpikeSorterCanvas.cpp b/Source/Processors/Visualization/SpikeSorterCanvas.cpp
index cccddfbff3f9edca6eae7e2cce022ab2dc70219a..170f41189b2c4af5a86e0e85eed5ac063076f1aa 100644
--- a/Source/Processors/Visualization/SpikeSorterCanvas.cpp
+++ b/Source/Processors/Visualization/SpikeSorterCanvas.cpp
@@ -108,14 +108,14 @@ void SpikeSorterCanvas::beginAnimation()
 {
     std::cout << "SpikeSorterCanvas beginning animation." << std::endl;
 
-    //startCallbacks();
+    startCallbacks();
 }
 
 void SpikeSorterCanvas::endAnimation()
 {
     std::cout << "SpikeSorterCanvas ending animation." << std::endl;
 
-   // stopCallbacks();
+    stopCallbacks();
 }
 
 void SpikeSorterCanvas::update()
@@ -380,7 +380,7 @@ void SpikeSorterCanvas::buttonClicked(Button* button)
 		// generate new IDs
 		processor->getActiveElectrode()->spikeSort->generateNewIDs();
 		electrode->spikePlot->updateUnitsFromProcessor();
-		processor->updateSinks(electrode->electrodeID,false);
+		//processor->updateSinks(electrode->electrodeID,false);
 	} else if (button == deleteAllUnits)
 	{
 		// delete unit
@@ -1853,20 +1853,20 @@ void PCAProjectionAxes::drawProjectedSpike(SpikeObject s)
 
 void PCAProjectionAxes::redraw(bool subsample)
 {
-//	Graphics g(projectionImage);
-//
-//	// recompute image
-//	int w = getWidth();
-//	int h = getHeight();
-//	projectionImage.clear(juce::Rectangle<int>(0, 0, projectionImage.getWidth(), projectionImage.getHeight()),
-//                          Colours::black);
-//
-//	int dk = (subsample) ? 5 : 1;
-//
-//	for (int k=0;k<bufferSize;k+=dk)
-//	{
-//		drawProjectedSpike(spikeBuffer[k]);
-//	}
+	Graphics g(projectionImage);
+
+	// recompute image
+	int w = getWidth();
+	int h = getHeight();
+	projectionImage.clear(juce::Rectangle<int>(0, 0, projectionImage.getWidth(), projectionImage.getHeight()),
+                         Colours::black);
+
+	int dk = (subsample) ? 5 : 1;
+
+	for (int k=0;k<bufferSize;k+=dk)
+	{
+		drawProjectedSpike(spikeBuffer[k]);
+	}
 	
 }