diff --git a/plugins/processing/signal-processing/src/algorithms/connectivity/connectivityMeasure.cpp b/plugins/processing/signal-processing/src/algorithms/connectivity/connectivityMeasure.cpp
index 3026f7f0324ed13b2e970d857556b1754e838772..7536ec1e4ce330864355eae3c52351faf7d1b04a 100644
--- a/plugins/processing/signal-processing/src/algorithms/connectivity/connectivityMeasure.cpp
+++ b/plugins/processing/signal-processing/src/algorithms/connectivity/connectivityMeasure.cpp
@@ -113,18 +113,19 @@ bool ConnectivityMeasure::initialize(const EConnectMetric metric, uint64_t sampR
 	m_nbChannels = nbChannels;
 	m_fftSize = fftSize;
 	m_dcRemoval = dcRemoval;
+
 	return true;
 }
 
-bool ConnectivityMeasure::process(const std::vector<Eigen::VectorXd>& samples, std::vector<Eigen::MatrixXd>& connectivityMatrix, const EPsdMode mode)
+bool ConnectivityMeasure::process(const std::vector<Eigen::VectorXd>& samples, std::vector<Eigen::MatrixXd>& connectivityMatrix, const EPsdMode mode, const std::vector<size_t>& vLookup)
 {
 	switch(m_psdMode) {
-		case EPsdMode::Welch: return processWelch(samples, connectivityMatrix);
-		case EPsdMode::Burg:  return processBurg(samples, connectivityMatrix);
+		case EPsdMode::Welch: return processWelch(samples, connectivityMatrix, vLookup);
+		case EPsdMode::Burg:  return processBurg(samples, connectivityMatrix, vLookup);
 	}
 }
 
-bool ConnectivityMeasure::processWelch(const std::vector<Eigen::VectorXd>& samples, std::vector<Eigen::MatrixXd>& connectivityMatrix)
+bool ConnectivityMeasure::processWelch(const std::vector<Eigen::VectorXd>& samples, std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup)
 {
 	// Windowing
 	const size_t windowShift = m_window.size() - m_windowOverlapSamples;
@@ -152,24 +153,26 @@ bool ConnectivityMeasure::processWelch(const std::vector<Eigen::VectorXd>& sampl
 	}
 
 	// Cross-SPECTRA
-	for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++) {
-		for (size_t chan2 = chan1; chan2 < m_nbChannels; chan2++) { 
-			crossSpectralDensity(m_dft[chan1], m_dft[chan2], m_cpsd[chan1][chan2], nbWindows); 
+	for (size_t chan1 = 0; chan1 < vLookup.size(); chan1++) {
+		for (size_t chan2 = 0; chan2 < m_nbChannels; chan2++) { 
+			if (vLookup[chan1] != chan2) {
+				crossSpectralDensity(m_dft[vLookup[chan1]], m_dft[chan2], m_cpsd[vLookup[chan1]][chan2], nbWindows);
+			}
 		}
 	}
 
 	// Use PSDs & x-spectra to compute the connectivity matrix
 	std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>> placeHolder; // empty vector, to use same fcts...
 	switch (m_metric) {
-		case EConnectMetric::Coherence: return coherence(placeHolder, connectivityMatrix);
-		case EConnectMetric::MagnitudeSquaredCoherence: return magnitudeSquaredCoherence(placeHolder, connectivityMatrix);
-		case EConnectMetric::ImaginaryCoherence: return imaginaryCoherence(placeHolder, connectivityMatrix);
-		case EConnectMetric::AbsImaginaryCoherence: return absImaginaryCoherence(placeHolder, connectivityMatrix);
-		default: return coherence(placeHolder, connectivityMatrix);
+		case EConnectMetric::Coherence: return coherence(placeHolder, connectivityMatrix, vLookup);
+		case EConnectMetric::MagnitudeSquaredCoherence: return magnitudeSquaredCoherence(placeHolder, connectivityMatrix, vLookup);
+		case EConnectMetric::ImaginaryCoherence: return imaginaryCoherence(placeHolder, connectivityMatrix, vLookup);
+		case EConnectMetric::AbsImaginaryCoherence: return absImaginaryCoherence(placeHolder, connectivityMatrix, vLookup);
+		default: return coherence(placeHolder, connectivityMatrix, vLookup);
 	}
 }
 
-bool ConnectivityMeasure::processBurg(const std::vector<Eigen::VectorXd>& samples, std::vector<Eigen::MatrixXd>& connectivityMatrix)
+bool ConnectivityMeasure::processBurg(const std::vector<Eigen::VectorXd>& samples, std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup)
 {
 	// NOT MULTITHREADED VERSION - for reference / debugging purpose
 	/*for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++) {
@@ -181,25 +184,38 @@ bool ConnectivityMeasure::processBurg(const std::vector<Eigen::VectorXd>& sample
 	}*/
 
 	// THREAD POOL (MAX THREADS / STANDALONE without init)
-	for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++) {
-		for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++) {
-			m_threadPoolMax.QueueJob([&, chan1, chan2] {
-				// No need to use mutexes : samples data can be read from multiple threads without issue.
-				// and writing occurs to indices of m_mvarCoeffsMatrix that are independent for every threads
-				mvarSpectralEstimation(samples[chan1], samples[chan2], m_mvarCoeffsMatrix[chan1][chan2], m_autoRegOrder, m_fftSize, m_sampRate, m_dcRemoval, m_expMat);
-			});
+	for (size_t chan1 = 0; chan1 < vLookup.size(); chan1++) {
+		size_t chan1idx = vLookup[chan1];
+		size_t startingIdxChan2 = 0;
+
+		// if we consider all channels, override this channel idx nonsense
+		if (vLookup.size() == m_nbChannels) {
+			startingIdxChan2 = chan1 + 1;
+			chan1idx = chan1;
+		}
+
+		for (size_t chan2 = startingIdxChan2; chan2 < m_nbChannels; chan2++) {
+
+			if (chan1idx != chan2) {
+				m_threadPoolMax.QueueJob([&, chan1idx, chan2] {
+					// No need to use mutexes : samples data can be read from multiple threads without issue.
+					// and writing occurs to indices of m_mvarCoeffsMatrix that are independent for every threads
+					mvarSpectralEstimation(samples[chan1idx], samples[chan2], m_mvarCoeffsMatrix[chan1idx][chan2], m_autoRegOrder, m_fftSize, m_sampRate, m_dcRemoval, m_expMat);
+					});
+			}
 		}
+
 	}
 	// Wait until all jobs have been processed
 	m_threadPoolMax.waitUntilCompleted();
 
 	// Use MVAR results to compute the connectivity matrix
 	switch (m_metric) {
-		case EConnectMetric::Coherence: return coherence(m_mvarCoeffsMatrix, connectivityMatrix);
-		case EConnectMetric::MagnitudeSquaredCoherence: return magnitudeSquaredCoherence(m_mvarCoeffsMatrix, connectivityMatrix); 
-		case EConnectMetric::ImaginaryCoherence: return imaginaryCoherence(m_mvarCoeffsMatrix, connectivityMatrix);
-		case EConnectMetric::AbsImaginaryCoherence: return absImaginaryCoherence(m_mvarCoeffsMatrix, connectivityMatrix);
-		default: return coherence(m_mvarCoeffsMatrix, connectivityMatrix);
+		case EConnectMetric::Coherence: return coherence(m_mvarCoeffsMatrix, connectivityMatrix, vLookup);
+		case EConnectMetric::MagnitudeSquaredCoherence: return magnitudeSquaredCoherence(m_mvarCoeffsMatrix, connectivityMatrix, vLookup);
+		case EConnectMetric::ImaginaryCoherence: return imaginaryCoherence(m_mvarCoeffsMatrix, connectivityMatrix, vLookup);
+		case EConnectMetric::AbsImaginaryCoherence: return absImaginaryCoherence(m_mvarCoeffsMatrix, connectivityMatrix, vLookup);
+		default: return coherence(m_mvarCoeffsMatrix, connectivityMatrix, vLookup);
 	}
 }
 
@@ -251,55 +267,90 @@ bool ConnectivityMeasure::crossSpectralDensity(const Eigen::MatrixXcd& dft1, con
 	return true;
 }
 
-bool ConnectivityMeasure::coherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix)
+bool ConnectivityMeasure::coherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup)
 {
 	// TODO : coherence is a complex matrix. Here we also used MSC... but with sqrt in the denominator.
 
 	if(m_psdMode == EPsdMode::Welch) {
 
 		// PSDs and CPSD are directly available as class members m_psd and m_cpsd
-		for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++) {
-			connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_psd[0].size());
-			for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++) {
-				connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1][chan2].cwiseAbs2().cwiseQuotient(m_psd[chan1].cwiseProduct(m_psd[chan2])).cwiseSqrt();
-				connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
+		for (size_t chan1 = 0; chan1 < vLookup.size(); chan1++) {
+			size_t chan1idx = vLookup[chan1];
+			size_t startingIdxChan2 = 0;
+			if (vLookup.size() == m_nbChannels) {
+				chan1idx = chan1;
+				startingIdxChan2 = chan1 + 1;
 			}
-		}
 
-	} else { // m_psdMode == EPsdMode::Burg
+			connectivityMatrix[chan1idx].row(chan1) = Eigen::VectorXd::Zero(m_psd[0].size());
 
-		// For each channel pair : Coh = S(0,1) / sqrt(S(0,0).*S(1,1))
-		// Input matrix dimensions : chan1 x chan2 x nfft x Matrix2cd (S11,S12),(S21,S22))
-		// mvarMatrix[chan1][chan2] is matrix S
-		// mvarMatrix[chan1][chan2][0][0] is psd of chan1
-		// mvarMatrix[chan1][chan2][1][1] is psd of chan2
-		// mvarMatrix[chan1][chan2][0][1] is cpsd of pair of channels
+			for (size_t chan2 = startingIdxChan2; chan2 < m_nbChannels; chan2++) {
+				if (chan1idx != chan2) {
+					connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1idx][chan2].cwiseAbs2().cwiseQuotient(m_psd[chan1idx].cwiseProduct(m_psd[chan2])).cwiseSqrt();
+					if (vLookup.size() == m_nbChannels) {
+						connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2); // diagonal matrix
+					}
+				}
+			}
+		}
+
+	}
+	else { // m_psdMode == EPsdMode::Burg
+
+	 // For each channel pair : Coh = S(0,1) / sqrt(S(0,0).*S(1,1))
+	 // Input matrix dimensions : chan1 x chan2 x nfft x Matrix2cd (S11,S12),(S21,S22))
+	 // mvarMatrix[chan1][chan2] is matrix S
+	 // mvarMatrix[chan1][chan2][0][0] is psd of chan1
+	 // mvarMatrix[chan1][chan2][1][1] is psd of chan2
+	 // mvarMatrix[chan1][chan2][0][1] is cpsd of pair of channels
+
+		for (size_t chan1 = 0; chan1 < vLookup.size(); chan1++) {
+
+			size_t chan1idx = vLookup[chan1];
+			size_t startingIdxChan2 = 0;
+			if (vLookup.size() == m_nbChannels) {
+				chan1idx = chan1;
+				startingIdxChan2 = chan1 + 1;
+			}
 
-		for(size_t chan1 = 0; chan1 < m_nbChannels; chan1++) {
 			connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_fftSize);
-			for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++)
-			{
-				connectivityMatrix[chan1].row(chan2) = mvarMatrix[chan1][chan2][0][1].cwiseAbs2().cwiseQuotient(mvarMatrix[chan1][chan2][0][0].real().cwiseProduct(mvarMatrix[chan1][chan2][1][1].real())).cwiseSqrt();
-				connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
+
+			for (size_t chan2 = startingIdxChan2; chan2 < m_nbChannels; chan2++) {
+				{
+					if (chan1idx != chan2) {
+						connectivityMatrix[chan1].row(chan2) = mvarMatrix[chan1idx][chan2][0][1].cwiseAbs2().cwiseQuotient(mvarMatrix[chan1idx][chan2][0][0].real().cwiseProduct(mvarMatrix[chan1idx][chan2][1][1].real())).cwiseSqrt();
+						if (vLookup.size() == m_nbChannels) {
+							connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2); // diagonal matrix
+						}
+					}
+				}
 			}
 		}
-
 	}
 
 	return true;
 }
 
-
-bool ConnectivityMeasure::magnitudeSquaredCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix)
+bool ConnectivityMeasure::magnitudeSquaredCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup)
 {
 	if(m_psdMode == EPsdMode::Welch) {
 
 		// PSDs and CPSD are directly available as class members m_psd and m_cpsd
-		for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++) {
+		for (size_t chan1 = 0; chan1 < vLookup.size(); chan1++) {
+			size_t chan1idx = vLookup[chan1];
+			size_t startingIdxChan2 = 0;
+			if (vLookup.size() == m_nbChannels) {
+				chan1idx = chan1;
+				startingIdxChan2 = chan1 + 1;
+			}
 			connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_psd[0].size());
-			for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++) {
-				connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1][chan2].cwiseAbs2().cwiseQuotient(m_psd[chan1].cwiseProduct(m_psd[chan2]) );
-				connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
+			for (size_t chan2 = startingIdxChan2; chan2 < m_nbChannels; chan2++) {
+				if (chan1 != chan2) {
+					connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1idx][chan2].cwiseAbs2().cwiseQuotient(m_psd[chan1idx].cwiseProduct(m_psd[chan2]));
+					if (vLookup.size() == m_nbChannels) {
+						connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2); // diagonal matrix
+					}
+				}
 			}
 		}
 
@@ -311,11 +362,22 @@ bool ConnectivityMeasure::magnitudeSquaredCoherence(const std::vector<std::vecto
 		// mvarMatrix[chan1][chan2][0][0] is psd of chan1
 		// mvarMatrix[chan1][chan2][1][1] is psd of chan2
 		// mvarMatrix[chan1][chan2][0][1] is cpsd of pair of channels
-		for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++) {
+		for (size_t chan1 = 0; chan1 < vLookup.size(); chan1++) {
+			size_t chan1idx = vLookup[chan1];
+			size_t startingIdxChan2 = 0;
+			if (vLookup.size() == m_nbChannels) {
+				chan1idx = chan1;
+				startingIdxChan2 = chan1 + 1;
+			}
+
 			connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_fftSize);
-			for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++) {
-				connectivityMatrix[chan1].row(chan2) = mvarMatrix[chan1][chan2][0][1].cwiseAbs2().cwiseQuotient(mvarMatrix[chan1][chan2][0][0].real().cwiseProduct(mvarMatrix[chan1][chan2][1][1].real()));
-				connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
+			for (size_t chan2 = startingIdxChan2; chan2 < m_nbChannels; chan2++) {
+				if (chan1idx != chan2) {
+					connectivityMatrix[chan1].row(chan2) = mvarMatrix[chan1idx][chan2][0][1].cwiseAbs2().cwiseQuotient(mvarMatrix[chan1idx][chan2][0][0].real().cwiseProduct(mvarMatrix[chan1idx][chan2][1][1].real()));
+					if (vLookup.size() == m_nbChannels) {
+						connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2); // diagonal matrix
+					}
+				}
 			}
 		}
 
@@ -325,16 +387,28 @@ bool ConnectivityMeasure::magnitudeSquaredCoherence(const std::vector<std::vecto
 	return true;
 }
 
-bool ConnectivityMeasure::imaginaryCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix)
+bool ConnectivityMeasure::imaginaryCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup)
 {
 	if(m_psdMode == EPsdMode::Welch) {
 
 		// PSDs and CPSD are directly available as class members m_psd and m_cpsd
-		for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++) {
-			connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_psd[0].size());
-			for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++) {
-				connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1][chan2].imag().cwiseQuotient(m_psd[chan1].cwiseProduct(m_psd[chan2]).cwiseSqrt());
-				connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
+		for (size_t chan1 = 0; chan1 < vLookup.size(); chan1++) {
+			size_t chan1idx = vLookup[chan1];
+			size_t startingIdxChan2 = 0;
+			if (vLookup.size() == m_nbChannels) {
+				chan1idx = chan1;
+				startingIdxChan2 = chan1 + 1;
+			}
+
+			connectivityMatrix[chan1idx].row(chan1) = Eigen::VectorXd::Zero(m_psd[0].size());
+
+			for (size_t chan2 = startingIdxChan2; chan2 < m_nbChannels; chan2++) {
+				if (chan1idx != chan2) {
+					connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1idx][chan2].imag().cwiseQuotient(m_psd[chan1idx].cwiseProduct(m_psd[chan2]).cwiseSqrt());
+					if (vLookup.size() == m_nbChannels) {
+						connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2); // diagonal matrix
+					}
+				}
 			}
 		}
 
@@ -347,11 +421,22 @@ bool ConnectivityMeasure::imaginaryCoherence(const std::vector<std::vector<std::
 		// mvarMatrix[chan1][chan2][1][1] is psd of chan2
 		// mvarMatrix[chan1][chan2][0][1] is cpsd of pair of channels
 
-		for(size_t chan1 = 0; chan1 < m_nbChannels; chan1++) {
+		for (size_t chan1 = 0; chan1 < vLookup.size(); chan1++) {
+			size_t chan1idx = vLookup[chan1];
+			size_t startingIdxChan2 = 0;
+			if (vLookup.size() == m_nbChannels) {
+				chan1idx = chan1;
+				startingIdxChan2 = chan1 + 1;
+			}
+
 			connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_fftSize);
-			for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++) {
-				connectivityMatrix[chan1].row(chan2) = mvarMatrix[chan1][chan2][0][1].imag().cwiseQuotient(mvarMatrix[chan1][chan2][0][0].real().cwiseProduct(mvarMatrix[chan1][chan2][1][1].real()).cwiseSqrt());
-				connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
+			for (size_t chan2 = startingIdxChan2; chan2 < m_nbChannels; chan2++) {
+				if (chan1idx != chan2) {
+					connectivityMatrix[chan1].row(chan2) = mvarMatrix[chan1idx][chan2][0][1].imag().cwiseQuotient(mvarMatrix[chan1idx][chan2][0][0].real().cwiseProduct(mvarMatrix[chan1idx][chan2][1][1].real()).cwiseSqrt());
+					if (vLookup.size() == m_nbChannels) {
+						connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2); // diagonal matrix
+					}
+				}
 			}
 		}
 	}
@@ -359,16 +444,28 @@ bool ConnectivityMeasure::imaginaryCoherence(const std::vector<std::vector<std::
 	return true;
 }
 
-bool ConnectivityMeasure::absImaginaryCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix)
+bool ConnectivityMeasure::absImaginaryCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup)
 {
 	if(m_psdMode == EPsdMode::Welch) {
 
 		// PSDs and CPSD are directly available as class members m_psd and m_cpsd
-		for (size_t chan1 = 0; chan1 < m_nbChannels; chan1++) {
-			connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_psd[0].size());
-			for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++) {
-				connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1][chan2].imag().cwiseAbs().cwiseQuotient(m_psd[chan1].cwiseProduct(m_psd[chan2]).cwiseSqrt());
-				connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
+		for (size_t chan1 = 0; chan1 < vLookup.size(); chan1++) {
+			size_t chan1idx = vLookup[chan1];
+			size_t startingIdxChan2 = 0;
+			if (vLookup.size() == m_nbChannels) {
+				chan1idx = chan1;
+				startingIdxChan2 = chan1 + 1;
+			}
+
+			connectivityMatrix[chan1idx].row(chan1) = Eigen::VectorXd::Zero(m_psd[0].size());
+
+			for (size_t chan2 = startingIdxChan2; chan2 < m_nbChannels; chan2++) {
+				if (chan1idx != chan2) {
+					connectivityMatrix[chan1].row(chan2) = m_cpsd[chan1idx][chan2].imag().cwiseAbs().cwiseQuotient(m_psd[chan1idx].cwiseProduct(m_psd[chan2]).cwiseSqrt());
+					if (vLookup.size() == m_nbChannels) {
+						connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2); // diagonal matrix
+					}
+				}
 			}
 		}
 
@@ -381,11 +478,22 @@ bool ConnectivityMeasure::absImaginaryCoherence(const std::vector<std::vector<st
 		// mvarMatrix[chan1][chan2][1][1] is psd of chan2
 		// mvarMatrix[chan1][chan2][0][1] is cpsd of pair of channels
 
-		for(size_t chan1 = 0; chan1 < m_nbChannels; chan1++) {
+		for (size_t chan1 = 0; chan1 < vLookup.size(); chan1++) {
+			size_t chan1idx = vLookup[chan1];
+			size_t startingIdxChan2 = 0;
+			if (vLookup.size() == m_nbChannels) {
+				chan1idx = chan1;
+				startingIdxChan2 = chan1 + 1;
+			}
+
 			connectivityMatrix[chan1].row(chan1) = Eigen::VectorXd::Zero(m_fftSize);
-			for (size_t chan2 = chan1 + 1; chan2 < m_nbChannels; chan2++) {
-				connectivityMatrix[chan1].row(chan2) = mvarMatrix[chan1][chan2][0][1].imag().cwiseAbs().cwiseQuotient(mvarMatrix[chan1][chan2][0][0].real().cwiseProduct(mvarMatrix[chan1][chan2][1][1].real()).cwiseSqrt());
-				connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2);
+			for (size_t chan2 = startingIdxChan2; chan2 < m_nbChannels; chan2++) {
+				if (chan1idx != chan2) {
+					connectivityMatrix[chan1].row(chan2) = mvarMatrix[chan1idx][chan2][0][1].imag().cwiseAbs().cwiseQuotient(mvarMatrix[chan1idx][chan2][0][0].real().cwiseProduct(mvarMatrix[chan1idx][chan2][1][1].real()).cwiseSqrt());
+					if (vLookup.size() == m_nbChannels) {
+						connectivityMatrix[chan2].row(chan1) = connectivityMatrix[chan1].row(chan2); // diagonal matrix
+					}
+				}
 			}
 		}
 	}
diff --git a/plugins/processing/signal-processing/src/algorithms/connectivity/connectivityMeasure.hpp b/plugins/processing/signal-processing/src/algorithms/connectivity/connectivityMeasure.hpp
index 14f9a23ab18600367aba8326441fa8484dbc81a2..ce709b628cfdad6bff66f5b55522c955204bbd50 100644
--- a/plugins/processing/signal-processing/src/algorithms/connectivity/connectivityMeasure.hpp
+++ b/plugins/processing/signal-processing/src/algorithms/connectivity/connectivityMeasure.hpp
@@ -108,7 +108,9 @@ inline std::string toString(const EConnectWindowMethod method)
 class ConnectivityMeasure
 {
 public:
-	ConnectivityMeasure(){m_threadPoolMax.Start( std::thread::hardware_concurrency());}
+	EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
+	ConnectivityMeasure() {m_threadPoolMax.Start(std::thread::hardware_concurrency()); }
 	~ConnectivityMeasure(){m_threadPoolMax.Stop();}
 
 	/// \brief Initialize the connectivity measurement class, Welch specific parameters
@@ -136,11 +138,11 @@ public:
 	/// \brief Select the function to call for the connectivity measurement.
 	/// \param samples The input data set \f$x\f$. With \f$ nChan \f$ channels and \f$ nSamp \f$ samples per channel
 	/// \param connectivityMatrix The connectivity matrix
-	bool process(const std::vector<Eigen::VectorXd>& samples, std::vector<Eigen::MatrixXd>& connectivityMatrix, const EPsdMode mode);
+	bool process(const std::vector<Eigen::VectorXd>& samples, std::vector<Eigen::MatrixXd>& connectivityMatrix, const EPsdMode mode, const std::vector<size_t>& vLookup);
 
 protected:
-	bool processWelch(const std::vector<Eigen::VectorXd>& samples,	std::vector<Eigen::MatrixXd>& connectivityMatrix);
-	bool processBurg(const std::vector<Eigen::VectorXd>& samples, std::vector<Eigen::MatrixXd>& connectivityMatrix);
+	bool processWelch(const std::vector<Eigen::VectorXd>& samples,	std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup);
+	bool processBurg(const std::vector<Eigen::VectorXd>& samples, std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup);
 
 private:
 	/// \brief Initialize the connectivity measurement class, with common parameters
@@ -166,7 +168,7 @@ private:
 	/// \param connectivityMatrix The connectivity matrix as a vector of 2D Matrices of size nbChannels x (nbChannels x frequency_taps)
 	/// \return	True if it succeeds, false if it fails.
 	/// \todo don't recompute the whole table, because connectivity measures overlap !
-	bool coherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix);
+	bool coherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup);
 
 	/// \brief Calculation of the Magnitude Squared Coherence
 	/// \f$ Pxx = PSD of x \f$ // \f$ Pyy = PSD of y \f$ // \f$ Sxy = cross spectral density of x and y \f$
@@ -183,7 +185,7 @@ private:
 	/// \param connectivityMatrix The connectivity matrix as a vector of 2D Matrices of size nbChannels x (nbChannels x frequency_taps)
 	/// \return	True if it succeeds, false if it fails.
 	/// \todo don't recompute the whole table, because connectivity measures overlap !
-	bool magnitudeSquaredCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix);
+	bool magnitudeSquaredCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup);
 
 	/// \brief Calculation of the Imaginary part of the coherence
 	/// \f$ Pxx = PSD of x \f$ // \f$ Pyy = PSD of y \f$ // \f$ Sxy = cross spectral density of x and y \f$
@@ -199,7 +201,7 @@ private:
 	/// \param connectivityMatrix The connectivity matrix as a vector of 2D Matrices of size nbChannels x (nbChannels x frequency_taps)
 	/// \return	True if it succeeds, false if it fails.
 	/// \todo don't recompute the whole table, because connectivity measures overlap !
-	bool imaginaryCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix);
+	bool imaginaryCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup);
 
 	/// \brief Calculation of the absolute value of the Imaginary part of the coherence
 	/// \f$ Pxx = PSD of x \f$ // \f$ Pyy = PSD of y \f$ // \f$ Sxy = cross spectral density of x and y \f$
@@ -215,7 +217,7 @@ private:
 	/// \param connectivityMatrix The connectivity matrix as a vector of 2D Matrices of size nbChannels x (nbChannels x frequency_taps)
 	/// \return	True if it succeeds, false if it fails.
 	/// \todo don't recompute the whole table, because connectivity measures overlap !
-	bool absImaginaryCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix);
+	bool absImaginaryCoherence(const std::vector<std::vector<std::vector<std::vector<Eigen::VectorXcd>>>>& mvarMatrix, std::vector<Eigen::MatrixXd>& connectivityMatrix, const std::vector<size_t>& vLookup);
 
 	/// \brief Generates periodigram of signal
 	/// \param input The signal
diff --git a/plugins/processing/signal-processing/src/box-algorithms/connectivity/CBoxAlgorithmConnectivityMeasure.cpp b/plugins/processing/signal-processing/src/box-algorithms/connectivity/CBoxAlgorithmConnectivityMeasure.cpp
index f1e863187b5ed27be3f53ba9ea63a7364131ed5b..1b2ce73df2a17fbadabc70d148f0da6bfe5f1c1d 100644
--- a/plugins/processing/signal-processing/src/box-algorithms/connectivity/CBoxAlgorithmConnectivityMeasure.cpp
+++ b/plugins/processing/signal-processing/src/box-algorithms/connectivity/CBoxAlgorithmConnectivityMeasure.cpp
@@ -25,6 +25,7 @@
 #include "CBoxAlgorithmConnectivityMeasure.hpp"
 #include "eigen/convert.hpp"
 #include <cmath>
+#include <chrono>
 
 namespace OpenViBE {
 namespace Plugins {
@@ -39,26 +40,28 @@ bool CBoxAlgorithmConnectivityMeasure::initialize()
 	m_oMatrix = m_matrixEncoder.getInputMatrix();
 
 	// Settings
-	m_metric               = EConnectMetric(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0)));
-	m_connectLengthSeconds = double(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1));
-	m_connectOverlap       = int(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2));
-	m_dcRemoval            = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3);
-	m_fftSize              = size_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 4));
-	m_psdMode		       = EPsdMode(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 5)));
-
+	m_selectedChannels	   = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
+	m_metric               = EConnectMetric(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1)));
+	m_connectLengthSeconds = double(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2));
+	m_connectOverlap       = int(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3));
+	m_dcRemoval            = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 4);
+	m_fftSize              = size_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 5));
+	m_psdMode		       = EPsdMode(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 6)));
+	
 	OV_ERROR_UNLESS_KRF(m_psdMode == EPsdMode::Welch || m_psdMode == EPsdMode::Burg, "Invalid PSD mode", Kernel::ErrorType::BadSetting);
 
 	switch(m_psdMode) {
 		case EPsdMode::Welch:
-			m_windowMethod         = EConnectWindowMethod(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 6)));
-			m_windowLengthSeconds  = double(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 7));
-			m_windowOverlap        = int(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 8));
+			m_windowMethod         = EConnectWindowMethod(uint64_t(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 7)));
+			m_windowLengthSeconds  = double(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 8));
+			m_windowOverlap        = int(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 9));
 			break;
 
 		case EPsdMode::Burg:
-			m_autoRegOrder	= int(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 6));
+			m_autoRegOrder	= int(FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 7));
 			break;
 	}
+
 	return true;
 }
 
@@ -101,13 +104,54 @@ bool CBoxAlgorithmConnectivityMeasure::process()
 			m_windowOverlapSamples  = int(std::floor(double(m_windowLength * m_windowOverlap / 100.0)));
 			m_connectShiftSamples = m_connectLength - m_connectOverlapSamples;
 
+			if (m_selectedChannels == CString("")) {
+				// Keep all channels
+				for (size_t j = 0; j < m_iMatrix->getDimensionSize(0); ++j) {
+					m_vLookup.push_back(j);
+				}
+			} else {
+				std::vector<CString> token;
+				const size_t nToken = split(m_selectedChannels, Toolkit::String::TSplitCallback<std::vector<CString>>(token), OV_Value_EnumeratedStringSeparator);
+
+				for (size_t j = 0; j < m_iMatrix->getDimensionSize(0); ++j) {
+					for (size_t k = 0; k < nToken; ++k) {
+						if (Toolkit::String::isAlmostEqual(m_iMatrix->getDimensionLabel(0, j), token[k], false)) {m_vLookup.push_back(j); }
+					}
+				}
+
+				if (nToken != m_vLookup.size()) {
+					this->getLogManager() << Kernel::LogLevel_Warning << "Some channels in the subselection were not found in the signal stream.\n";
+					for (size_t k = 0; k < nToken; ++k) {
+						bool found = false;
+						for (size_t j = 0; j < m_vLookup.size(); j++) {
+							if (Toolkit::String::isAlmostEqual(m_iMatrix->getDimensionLabel(0, m_vLookup[j]), token[k], false)) { 
+								found = true; break;
+							}
+						}
+
+						if (!found) {
+							this->getLogManager() << Kernel::LogLevel_Warning << token[k] << " was not found in the signal stream.\n";
+						}
+					}
+				}
+
+			}
+
+			m_nbChanOutput = m_vLookup.size();
+			OV_ERROR_UNLESS_KRF(m_nbChanOutput > 0, "Connectivity channel subselection error. Mismatch between the subselection and the channel names? ",
+				Kernel::ErrorType::BadArgument);
+
+
+						
+			this->getLogManager() << Kernel::LogLevel_Info << "NB CHANNELS FOR CONNECTIVITY OUTPUT: " << m_nbChanOutput << ")\n";
+
 			m_timeIncrement = uint64_t(m_connectLengthSeconds * std::pow(2, 32));
 			this->getLogManager() << Kernel::LogLevel_Debug << "TIME INCREMENT: " << m_timeIncrement << " (" << (double)(m_timeIncrement)*std::pow(2,-32) << ")\n";
 
 			m_nbChannels           = matrix->getDimensionSize(0);
 			const auto sampPerChan = matrix->getDimensionSize(1);
 
-			this->getLogManager() << Kernel::LogLevel_Debug << "HEADER : nChannels " << m_nbChannels << ", " << sampPerChan << " samples, sampling rate " << sampling << "\n";
+			this->getLogManager() << Kernel::LogLevel_Info << "HEADER : nChannels " << m_nbChannels << ", " << sampPerChan << " samples, sampling rate " << sampling << "\n";
 			this->getLogManager() << Kernel::LogLevel_Debug << "Connectivity segments overlap percent/samples : " << m_connectOverlap << " " << m_connectOverlapSamples << "\n";
 			this->getLogManager() << Kernel::LogLevel_Debug << "Connectivity segment shift (samples): " << m_connectShiftSamples << "\n";
 			this->getLogManager() << Kernel::LogLevel_Debug << "Welch Windows overlap percent/samples : " << m_windowOverlap << " " << m_windowOverlapSamples << "\n";
@@ -127,15 +171,18 @@ bool CBoxAlgorithmConnectivityMeasure::process()
 
 			}
 
-			m_oMatrix->resize({ m_fftSize, m_nbChannels, m_nbChannels }); // nbFreqs x nbChan x nbChan
+			m_oMatrix->resize({ m_fftSize, m_nbChannels, m_nbChanOutput }); // nbFreqs x nbChan x nbChanOutput
 			this->getLogManager() << Kernel::LogLevel_Debug << "output Matrix dimensions: " << m_oMatrix->getDimensionSize(0) << " x " <<  m_oMatrix->getDimensionSize(1) << "\n";
 			for (size_t aa = 0; aa < m_fftSize; aa++) {
 				m_oMatrix->setDimensionLabel(0, aa, std::to_string(aa));
 			}
 			for (size_t aa = 0; aa < m_nbChannels; aa++) {
 				m_oMatrix->setDimensionLabel(1, aa, matrix->getDimensionLabel(0, aa));
-				m_oMatrix->setDimensionLabel(2, aa, matrix->getDimensionLabel(0, aa));
-				this->getLogManager() << Kernel::LogLevel_Debug << "Channel " << aa << " : " << m_oMatrix->getDimensionLabel(1, aa) << "/" << m_oMatrix->getDimensionLabel(2, aa) << "\n";
+				//this->getLogManager() << Kernel::LogLevel_Debug << "Channel " << aa << " : " << m_oMatrix->getDimensionLabel(1, aa) << "/" << m_oMatrix->getDimensionLabel(2, aa) << "\n";
+			}
+			for (size_t aa = 0; aa < m_nbChanOutput; aa++) {
+				m_oMatrix->setDimensionLabel(2, aa, matrix->getDimensionLabel(0, m_vLookup[aa]));
+				this->getLogManager() << Kernel::LogLevel_Info << "Output matrix: Channel " << aa << " : " << m_oMatrix->getDimensionLabel(2, aa) << "\n";
 			}
 
 			m_matrixEncoder.encodeHeader(); // Pass the header to the next boxes
@@ -185,16 +232,16 @@ bool CBoxAlgorithmConnectivityMeasure::process()
 					m_signalChannelBuffers[aa].erase(m_signalChannelBuffers[aa].begin(), m_signalChannelBuffers[aa].begin() + m_connectShiftSamples);
 				}
 
-				// 3D Matrix init, vector of size (chan) of Matrices (chan x fftsize)
-				std::vector<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>> connectivityMatrix(m_nbChannels, Eigen::MatrixXd::Zero(m_nbChannels, m_fftSize));
+				// 3D Matrix init, vector of size (m_nbChanOutput) of Matrices (chan x fftsize)
+				std::vector<Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>> connectivityMatrix(m_nbChanOutput, Eigen::MatrixXd::Zero(m_nbChannels, m_fftSize));
 
-				OV_ERROR_UNLESS_KRF(connectivityMeasure.process(m_vectorXdBuffer, connectivityMatrix, m_psdMode), "Connectivity measurement error",
+				OV_ERROR_UNLESS_KRF(connectivityMeasure.process(m_vectorXdBuffer, connectivityMatrix, m_psdMode, m_vLookup), "Connectivity measurement error",
 									Kernel::ErrorType::BadProcessing);
-
+				
 				this->getLogManager() << Kernel::LogLevel_Debug << "Exited connectivityMeasure.process() : connect size "
 						<< (size_t)connectivityMatrix.size() << " x " << (size_t)connectivityMatrix[0].rows() << " x " << (size_t)connectivityMatrix[0].cols() << "\n";
 
-				// Convert output matrix (nchan x nchan x fftsize) to matrix (fftsize x nchan x nchan)
+				// Convert output matrix (nchanoutput x nchan x fftsize) to matrix (fftsize x nchan x nchanoutput)
 				MatrixConvert(connectivityMatrix, *m_oMatrix, 5);
 
 				m_matrixEncoder.encodeBuffer();
diff --git a/plugins/processing/signal-processing/src/box-algorithms/connectivity/CBoxAlgorithmConnectivityMeasure.hpp b/plugins/processing/signal-processing/src/box-algorithms/connectivity/CBoxAlgorithmConnectivityMeasure.hpp
index 2896ec199db5f67cde559fe718d8961539ef4b67..d33f094aada99dcfb597e53b12f2afd4296fa18d 100644
--- a/plugins/processing/signal-processing/src/box-algorithms/connectivity/CBoxAlgorithmConnectivityMeasure.hpp
+++ b/plugins/processing/signal-processing/src/box-algorithms/connectivity/CBoxAlgorithmConnectivityMeasure.hpp
@@ -31,7 +31,6 @@
 #include <toolkit/ovtk_all.h>
 #include "connectivityMeasure.hpp"
 
-
 #define OV_AttributeId_Box_FlagIsUnstable                OpenViBE::CIdentifier(0x666FFFFF, 0x666FFFFF)
 
 namespace OpenViBE {
@@ -44,6 +43,9 @@ namespace SignalProcessing {
 class CBoxAlgorithmConnectivityMeasure final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
 {
 public:
+
+	EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
 	void release() override { delete this; }
 
 	bool initialize() override;
@@ -87,6 +89,11 @@ protected:
 	int m_autoRegOrder = 11; // auto-regressive model order, in samples
 
 	// Common
+	std::vector<size_t> m_vLookup;
+	size_t m_nbChanOutput = 0;
+	//uint64_t totalDuration = 0; //for measuring performance
+
+	CString m_selectedChannels;  // subselection of channels, separated with ";". Blank = select all
 	int m_connectLength = 256; // size of one full connectivity estimation occurrence (samples)
 	double m_connectLengthSeconds = 0.5; // size of one full connectivity estimation occurrence (sec)
 	int m_connectOverlap = 50;  // overlap btw connectivity measurements (%)
@@ -99,7 +106,7 @@ protected:
 	uint64_t m_timeIncrement = 0;
 
 	std::vector<uint64_t> m_startTimes;
-	
+
 };
 
 ///
@@ -187,6 +194,8 @@ public:
 		prototype.addInput("Input signal", OV_TypeId_Signal);
 		prototype.addOutput("Connectivity Matrix", OV_TypeId_StreamedMatrix);
 
+		prototype.addSetting("Channel subselection", OV_TypeId_String, "");
+
 		prototype.addSetting("Metric", OVP_TypeId_Connectivity_Metric, toString(EConnectMetric::Coherence).c_str());
 
 		prototype.addSetting("Connectivity Measure Length (in sec)", OV_TypeId_Float, "0.5"); //s