From d51f6d7f18657a476e4cc9723f4e678ce8f10d9f Mon Sep 17 00:00:00 2001
From: Christian Beckmann <c.beckmann@donders.ru.nl>
Date: Thu, 15 Nov 2012 11:38:44 +0000
Subject: [PATCH] fixed tsplot hangup on linux

---
 meldata.cc    | 79 ++++++++++++++++++++++++++++++++++-----------------
 meldata.h     |  2 +-
 melhlprfns.cc | 26 +++++++++++++----
 melhlprfns.h  | 20 +++++++++++--
 melodic.cc    |  2 +-
 melodic.h     | 21 +++++++++++++-
 melreport.cc  |  9 ++++--
 test.cc       | 58 ++++++++++++++++++++++++++++++++++---
 8 files changed, 174 insertions(+), 43 deletions(-)

diff --git a/meldata.cc b/meldata.cc
index eb72dfb..bc4f70a 100644
--- a/meldata.cc
+++ b/meldata.cc
@@ -24,25 +24,41 @@ using namespace NEWIMAGE;
 namespace Melodic{
 // {{{ Setup
 
-  Matrix MelodicData::process_file(string fname, int numfiles)
+  ReturnMatrix MelodicData::process_file(string fname, int numfiles)
   {
-    volume4D<float> RawData;
+	Matrix tmpData;
+	{
+    	volume4D<float> RawData;
 
-    //read data
-    message("Reading data file " << fname << "  ... ");
-    read_volume4D(RawData,fname);
-    message(" done" << endl);
-    del_vols(RawData,opts.dummy.value());
+		if(opts.debug.value())
+			memmsg(" before reading file "<< fname);
+
+    	//read data
+    	message("Reading data file " << fname << "  ... ");
+    	read_volume4D(RawData,fname);
+    	message(" done" << endl);
+    	if(opts.debug.value())
+			memmsg(" after reading file "<< fname);
+		
+		del_vols(RawData,opts.dummy.value());
     
-    Mean += meanvol(RawData)/numfiles;
+    	Mean += meanvol(RawData)/numfiles;
+
+		//estimate smoothness
+		if(opts.debug.value())
+			memmsg(" before est smoothness ");
+    	if((Resels == 0)&&(!opts.filtermode))
+      		Resels = est_resels(RawData,Mask);
+		if(opts.debug.value())
+			memmsg(" after smoothness ");
 	
-    //reshape
-    Matrix tmpData;
-    tmpData = RawData.matrix(Mask);
-    
-    //estimate smoothness
-    if((Resels == 0)&&(!opts.filtermode))
-      Resels = est_resels(RawData,Mask);
+    	//reshape
+		if(opts.debug.value())
+			memmsg(" before reshape ");
+    	tmpData = RawData.matrix(Mask);
+    	if(opts.debug.value())
+			memmsg(" after reshape ");	  
+	}    
         
     //convert to percent BOLD signal change
     if(opts.pbsc.value()){
@@ -55,16 +71,18 @@ namespace Melodic{
 		if(opts.remove_meanvol.value())
 		{	      
 			message(string("  Removing mean image ..."));
-      		meanR = mean(tmpData);
-      		tmpData = remmean(tmpData);
+      		if(opts.debug.value())
+				memmsg(" before remmean ");
+      		remmean(tmpData,meanR,1);
+      		if(opts.debug.value())
+				memmsg(" after remmean ");
       		message(" done" << endl);
 		}
 		else meanR=ones(1,tmpData.Ncols());
     }
 
 	if(opts.remove_meantc.value()){
-    	meanC = mean(tmpData,2);
-		tmpData = remmean(tmpData,2);
+		remmean(tmpData,meanC,2);
 	}
 	
     //convert to power spectra
@@ -86,6 +104,8 @@ namespace Melodic{
     }
       
     //variance - normalisation
+   	if(opts.debug.value())
+		memmsg(" before VN ");
     if(opts.varnorm.value()){
       message("  Normalising by voxel-wise variance ..."); 
 			if(stdDev.Storage()==0)
@@ -95,9 +115,12 @@ namespace Melodic{
 				stdDev += varnorm(tmpData,std::min(30,tmpData.Nrows()-1),
 					opts.vn_level.value())/numfiles;
       stdDevi = pow(stdDev,-1); 
+	  if(opts.debug.value())
+	    memmsg(" in VN ");
       message(" done" << endl);
     }
 
+	tmpData.Release();
     return tmpData;
   }
 
@@ -152,7 +175,7 @@ namespace Melodic{
 
   	dbgmsg(string("   approach ") << opts.approach.value() << endl);	
 
-	if(opts.approach.value()!=string("concat")){
+	if(opts.approach.value()==string("tica")){
       message("Calculating T- and S-modes " << endl);
       explained_var = krfact(tmp,tmpT,tmpS);
       Tmodes.clear(); Smodes.clear();
@@ -180,6 +203,7 @@ namespace Melodic{
 			add_Tmodes(tmpT3);
 		}
 	}
+	
     if(opts.approach.value()!=string("concat")){
 	  //add GLM OLS fit
 	  dbgmsg(string(" GLM fitting ") << endl);
@@ -213,7 +237,9 @@ namespace Melodic{
   { 
     numfiles = (int)opts.inputfname.value().size();
     setup_misc();
-
+	if(opts.debug.value())
+		memmsg(" after setup_misc ");
+		
 	if(opts.filtermode){ // basic setup for filtering only
 		Data = process_file(opts.inputfname.value().at(0));
 	}
@@ -229,7 +255,9 @@ namespace Melodic{
 			opts.varnorm.set_T(false);
 		}
     	alldat = process_file(opts.inputfname.value().at(0), numfiles) / numfiles;
-
+		if(opts.debug.value())
+			memmsg(" after process_file ");
+			
 		if(opts.pca_dim.value() > alldat.Nrows()-2){
 			cerr << "ERROR:: too many components selected \n\n";
 			exit(2);
@@ -285,11 +313,11 @@ namespace Melodic{
     	RowVector AdjEV, PercEV;
     	Matrix Corr, tmpE;
     	int order;
-		//	cerr << "here1" << endl;
+
     	order = ppca_dim(remmean(alldat,2), RXweight, tmpPPCA, AdjEV, PercEV, Corr, pcaE, pcaD, Resels, opts.pca_est.value());	  
 		if (opts.paradigmfname.value().length()>0)
 			order += param.Ncols();
-		// cerr << "here2" << endl;		
+
 	  	if(opts.pca_dim.value() == 0){
       		opts.pca_dim.set_T(order);
 			PPCA=tmpPPCA;
@@ -332,7 +360,6 @@ namespace Melodic{
       		WM.push_back(tmp);
     	} 
 		else {
-			//cerr << "here" << endl;
       		for(int ctr = 0; ctr < numfiles; ctr++){
 				tmpData = process_file(opts.inputfname.value().at(ctr), numfiles);
 	
@@ -468,7 +495,7 @@ namespace Melodic{
 			Scon &= -1*Scon;
 		}
 	}
-	Tdes = remmean(Tdes,1);
+	remmean(Tdes);
   }
 
   void MelodicData::save()
diff --git a/meldata.h b/meldata.h
index 9021834..12629db 100644
--- a/meldata.h
+++ b/meldata.h
@@ -36,7 +36,7 @@ namespace Melodic{
  
       void save();
 
-      Matrix process_file(string fname, int numfiles = 1);
+      ReturnMatrix process_file(string fname, int numfiles = 1);
 
       inline void save4D(Matrix what, string fname){
 	 			volume4D<float> tempVol;
diff --git a/melhlprfns.cc b/melhlprfns.cc
index 9035a8f..0758bc3 100644
--- a/melhlprfns.cc
+++ b/melhlprfns.cc
@@ -22,7 +22,6 @@ namespace Melodic{
     Matrix DStDev=stdev(Data);
     volume4D<float> tmpMask, RawData;
     tmpMask.setmatrix(DStDev,mask);
-    RawData.setmatrix(Data,mask);
 
     float tMmax;
     volume<float> tmpMask2;
@@ -32,9 +31,23 @@ namespace Melodic{
     double st_mean = DStDev.Sum()/DStDev.Ncols();
     double st_std  = stdev(DStDev.t()).AsScalar();
       
-    mask = binarise(tmpMask2,(float) max((float) st_mean-3*st_std,(float) 0.01*st_mean),tMmax);
+	volume4D<float> newmask;
+    newmask = binarise(tmpMask2,(float) max((float) st_mean-3*st_std,(float) 0.01*st_mean),tMmax);
 
-    Data = RawData.matrix(mask);
+	Matrix newmaskM,newData;
+	newmaskM = newmask.matrix(mask);
+	int N = Data.Nrows();
+	
+	if(int(newmaskM.Row(1).SumAbsoluteValue() + 0.3) < newmaskM.Ncols()){
+		RawData.setmatrix(Data.Row(1),mask);
+		newData = RawData.matrix(newmask[0]);
+		for(int r=2; r <= N; r++){
+			RawData.setmatrix(Data.Row(r),mask);
+			newData &= RawData.matrix(newmask[0]);
+		}
+		Data = newData;
+		mask = newmask[0];  
+	}
   }
 
   void del_vols(volume4D<float>& in, int howmany)
@@ -123,12 +136,14 @@ namespace Melodic{
 
 	void varnorm(Matrix& in, const RowVector& vars)
 	{
-		Matrix tmp = vars;
-		in = SP(in,pow(ones(in.Nrows(),1) * tmp,-1));
+		for(int ctr=1; ctr <=in.Nrows();ctr++){
+			in.Row(ctr) = SD(in.Row(ctr),vars);
+		}
 	}
 	
   RowVector varnorm(Matrix& in, Matrix& Corr, int dim, float level)
   { 
+	
     Matrix tmpE, white, dewhite;
     RowVector tmpD, tmpD2;
 
@@ -147,6 +162,7 @@ namespace Melodic{
 				in.Column(ctr1) = 0.0*in.Column(ctr1);
       }
 	  varnorm(in,tmpD);
+
     return tmpD;
   }  //RowVector varnorm
 
diff --git a/melhlprfns.h b/melhlprfns.h
index 5164451..8e16fd1 100644
--- a/melhlprfns.h
+++ b/melhlprfns.h
@@ -16,6 +16,22 @@
 #include "newmatap.h"
 #include "newmatio.h"
 
+	#ifdef __APPLE__
+	#include <mach/mach.h>
+	#define mmsg(msg) { \
+	  struct task_basic_info t_info; \
+	  mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; \
+	  if (KERN_SUCCESS == task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t) &t_info, &t_info_count)) \
+		{ \
+			cout << " MEM: " << msg << " res: " << t_info.resident_size/1000000 << " virt: " << t_info.virtual_size/1000000 << "\n"; \
+			} \
+	}
+	#else
+	#define mmsg(msg) { \
+	   cout << msg; \
+	}
+	#endif
+
 using namespace NEWIMAGE;
 
 namespace Melodic{
@@ -39,8 +55,8 @@ namespace Melodic{
 
   Matrix corrcoef(const Matrix& in1, const Matrix& in2);
   Matrix corrcoef(const Matrix& in1, const Matrix& in2, const Matrix& part);
-  Matrix calc_corr(const Matrix& in, bool econ = 0);
-  Matrix calc_corr(const Matrix& in, const Matrix& weights, bool econ = 0);
+  Matrix calc_corr(const Matrix& in, bool econ = 1);
+  Matrix calc_corr(const Matrix& in, const Matrix& weights, bool econ = 1);
 
   float calc_white(const Matrix& tmpE, const RowVector& tmpD, const RowVector& PercEV, int dim, Matrix& param, Matrix& paramS, Matrix& white, Matrix& dewhite);
   float calc_white(const Matrix& tmpE, const RowVector& tmpD, const RowVector& PercEV, int dim, Matrix& white, Matrix& dewhite);
diff --git a/melodic.cc b/melodic.cc
index b78b5ff..d111afe 100644
--- a/melodic.cc
+++ b/melodic.cc
@@ -311,7 +311,7 @@ Matrix mmall(Log& logger, MelodicOptions& opts,MelodicData& melodat, MelodicRepo
     if(opts.varnorm.value()&&melodat.get_stdNoisei().Storage()>0){
       ICmap = SP(melodat.get_IC().Row(ctr),diagvals(ctr)*melodat.get_stdNoisei());
     }else{
-    	ICmap = melodat.get_IC().Row(ctr);
+      ICmap = melodat.get_IC().Row(ctr);
 	}
     string wherelog;
     if(opts.genreport.value())
diff --git a/melodic.h b/melodic.h
index 1f6c80a..1260423 100644
--- a/melodic.h
+++ b/melodic.h
@@ -14,6 +14,25 @@
 
 #include <strstream>
 
+#ifdef __APPLE__
+#include <mach/mach.h>
+#define memmsg(msg) { \
+  struct task_basic_info t_info; \
+  mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; \
+  if (KERN_SUCCESS == task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t) &t_info, &t_info_count)) \
+	{ \
+		cout << " MEM: " << msg << " res: " << t_info.resident_size/1000000 << " virt: " << t_info.virtual_size/1000000 << "\n"; \
+		cout.flush(); \
+	} \
+}
+#else
+#define memmsg(msg) { \
+   cout << msg; \
+}
+#endif
+
+
+
 // a simple message macro that takes care of cout and log
 #define message(msg) { \
   MelodicOptions& opt = MelodicOptions::getInstance(); \
@@ -40,7 +59,7 @@
 
 namespace Melodic{
 
-const string version = "3.10";  
+const string version = "3.12";  
 
 // The two strings below specify the title and example usage that is	
 // printed out as the help or usage message
diff --git a/melreport.cc b/melreport.cc
index a1bc2f6..76fe5c6 100644
--- a/melreport.cc
+++ b/melreport.cc
@@ -107,9 +107,11 @@ namespace Melodic{
       }		
 			
       {//plot time course
-    	IChtml << "<H3> Temporal mode </H3><p>" << endl <<endl;
-    	miscplot newplot;
+    	IChtml << "<H3> Temporal mode </H3><p>" << endl <<endl;     	
+		miscplot newplot;
+		
 			Matrix tmptc = melodat.get_Tmodes(cnum-1).Column(1).t();
+
 			newplot.col_replace(0,0xFF0000);
 
 			newplot.add_label(string("IC ")+num2str(cnum)+" time course");
@@ -141,7 +143,8 @@ namespace Melodic{
 				tmptc.Row(1).Minimum()),tmptc.Row(1).Maximum()+
 				0.05*(tmptc.Row(1).Maximum()-tmptc.Row(1).Minimum()));
 			newplot.grid_swapdefault();
-	    newplot.timeseries(tmptc,
+			
+	        newplot.timeseries(tmptc,
 			  report.appendDir(string("t")+num2str(cnum)+".png"),
 			  string("Timecourse No. ")+num2str(cnum), 
 			  opts.tr.value(),150,12,1,false);
diff --git a/test.cc b/test.cc
index 3a13d0e..29e422c 100644
--- a/test.cc
+++ b/test.cc
@@ -13,6 +13,31 @@
 #include "newimage/newimageall.h"
 #include "melhlprfns.h"
 
+#ifdef __APPLE__
+#include <mach/mach.h>
+#define memmsg(msg) { \
+  struct task_basic_info t_info; \
+  mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; \
+  if (KERN_SUCCESS == task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t) &t_info, &t_info_count)) \
+	{ \
+		cout << msg << " res: " << t_info.resident_size/1000000 << " virt: " << t_info.virtual_size/1000000 << "\n"; \
+		cout.flush(); \
+	} \
+}
+#else
+#define memmsg(msg) { \
+   cout << msg; \
+}
+#endif
+
+
+// a simple message macro that takes care of cout
+#define message(msg) { \
+  cout << msg; \
+  cout.flush(); \
+}
+
+
 using namespace MISCPLOT;
 using namespace MISCMATHS;
 using namespace Utilities;
@@ -49,11 +74,36 @@ using namespace std;
 
 int do_work(int argc, char* argv[]) {
     
-	Matrix test;
+	Matrix MatrixData;
+	volume<float> Mean;
+
+   	{
+	volume4D<float> RawData;
+
+    //read data
+    message("Reading data file " << (string)fnin.value() << "  ... ");
+    read_volume4D(RawData,fnin.value());
+    message(" done" << endl);
+  
+	Mean = meanvol(RawData);
+  
+	memmsg(" Before reshape ");
+    MatrixData = RawData.matrix();
+    }
+	memmsg(" after reshape ");
+	message(" Data size " << MatrixData.Nrows() << " x " << MatrixData.Ncols() << endl);
+	
+	memmsg(" before remmean_econ ");
+	remmean_econ(MatrixData);
+	memmsg("after remmean_econ / before remmean")
+	
+	MatrixData = remmean(MatrixData);
+	
+	memmsg(" after remmean ");
+	message(" Mean size " << MatrixData.Nrows() << " x " << MatrixData.Ncols() << endl);
+	
+	message(" Mean size " << MatrixData.Nrows() << " x " << MatrixData.Ncols() << endl);
 	
-	cerr << " X: "<< xdim.value() << ", Y: "<< ydim.value() << endl;
-	test = zeros(xdim.value(),ydim.value());
-	cerr << "Created matrix of size " << test.Nrows() << " x " << test.Ncols() << endl;
 	return 0;
 }
 
-- 
GitLab