@@ -273,7 +273,7 @@ void DifferentialExpressionPlugin::init()
273273 layout->addWidget (_buttonProgressBar);
274274 }
275275
276- _totalTableColumns = 8 ;
276+ _totalTableColumns = 10 ;
277277
278278 _tableItemModel->startModelBuilding (_totalTableColumns, 0 );
279279 _tableItemModel->setHorizontalHeader (0 , QString (" ID" ));
@@ -282,8 +282,10 @@ void DifferentialExpressionPlugin::init()
282282 _tableItemModel->setHorizontalHeader (3 , QString (" Mean (Sel. 2)" ));
283283 _tableItemModel->setHorizontalHeader (4 , QString (" Median (Sel. 1)" ));
284284 _tableItemModel->setHorizontalHeader (5 , QString (" Median (Sel. 2)" ));
285- _tableItemModel->setHorizontalHeader (6 , QString (" % Expressed (Sel. 1)" ));
286- _tableItemModel->setHorizontalHeader (7 , QString (" % Expressed (Sel. 2)" ));
285+ _tableItemModel->setHorizontalHeader (6 , QString (" SD (Sel. 1)" ));
286+ _tableItemModel->setHorizontalHeader (7 , QString (" SD (Sel. 2)" ));
287+ _tableItemModel->setHorizontalHeader (8 , QString (" % Expressed (Sel. 1)" ));
288+ _tableItemModel->setHorizontalHeader (9 , QString (" % Expressed (Sel. 2)" ));
287289 _tableItemModel->endModelBuilding ();
288290
289291 // Apply the layout
@@ -620,6 +622,10 @@ void DifferentialExpressionPlugin::computeDE()
620622 std::vector<float > mediansA (numDimensions, 0 );
621623 std::vector<float > mediansB (numDimensions, 0 );
622624
625+ // for SD
626+ std::vector<float > SDA (numDimensions, 0 );
627+ std::vector<float > SDB (numDimensions, 0 );
628+
623629 // for percentage expressed
624630 std::vector<std::size_t > countExpressedA (numDimensions, 0 );
625631 std::vector<std::size_t > countExpressedB (numDimensions, 0 );
@@ -632,7 +638,7 @@ void DifferentialExpressionPlugin::computeDE()
632638 local::visitElements (_points, selectionIDs, [&means, &valCopies, &countExpressed, thr](auto globalRowID, auto localRowID, auto column, auto value)
633639 {
634640 means[column] += value;
635- valCopies[column][localRowID] = value; // for median
641+ valCopies[column][localRowID] = value; // for median and SD
636642
637643 if (value > thr)
638644 countExpressed[column]++;
@@ -644,6 +650,19 @@ void DifferentialExpressionPlugin::computeDE()
644650 return vec[vec.size () / 2 ];
645651 };
646652
653+ auto computeSD = [](const std::vector<float >& vec, float mean) -> float {
654+ if (vec.size () < 2 )
655+ return 0 .0f ;
656+
657+ float sum = 0 .0f ;
658+ for (const float & val : vec)
659+ {
660+ const float diff = val - mean;
661+ sum += diff * diff;
662+ }
663+ return std::sqrt (sum / static_cast <float >(vec.size ()));
664+ };
665+
647666 auto normAvg = [&](const std::vector<float >& avgs, const std::ptrdiff_t dim) -> float {
648667 return (avgs[dim] - _minValues[dim]) * _rescaleValues[dim];
649668 };
@@ -664,12 +683,20 @@ void DifferentialExpressionPlugin::computeDE()
664683 mediansA[d] = computeMedian (valuesA[d]);
665684 mediansB[d] = computeMedian (valuesB[d]);
666685
686+ // compute SD
687+ SDA [d] = computeSD (valuesA[d], meansA[d]);
688+ SDB [d] = computeSD (valuesB[d], meansB[d]);
689+
667690 // then min max - optional by toggle action
668691 if (_norm) {
669692 meansA[d] = normAvg (meansA, d);
670693 meansB[d] = normAvg (meansB, d);
671694 mediansA[d] = normAvg (mediansA, d);
672695 mediansB[d] = normAvg (mediansB, d);
696+
697+ // if norm, rescale SD as well
698+ SDA [d] = SDA [d] * _rescaleValues[d];
699+ SDB [d] = SDB [d] * _rescaleValues[d];
673700 }
674701
675702 // compute percentage expressed
@@ -690,6 +717,8 @@ void DifferentialExpressionPlugin::computeDE()
690717 local::fround (meansB[dimension], 3 ),
691718 local::fround (mediansA[dimension], 3 ),
692719 local::fround (mediansB[dimension], 3 ),
720+ local::fround (SDA [dimension], 3 ),
721+ local::fround (SDB [dimension], 3 ),
693722 local::fround (pctExpressedA[dimension], 3 ),
694723 local::fround (pctExpressedB[dimension], 3 )
695724 };
0 commit comments