From d80f75561830cf35220694a425ba18d92e02d2fc Mon Sep 17 00:00:00 2001 From: Christian Beckmann <c.beckmann@donders.ru.nl> Date: Mon, 23 Aug 2004 14:10:14 +0000 Subject: [PATCH] updated to ln(11) --- meldata.cc | 20 ++++--- meldata.h | 7 ++- melgmix.cc | 2 +- melgmix.h | 12 +++- melodic.cc | 35 ++++++----- melodic.h | 2 +- meloptions.cc | 1 + meloptions.h | 5 ++ melreport.h | 2 +- test.cc | 163 +++++++++++++++++++++++++++++++++++++++++++++++--- 10 files changed, 213 insertions(+), 36 deletions(-) diff --git a/meldata.cc b/meldata.cc index cdcae29..c8c3b93 100644 --- a/meldata.cc +++ b/meldata.cc @@ -196,12 +196,12 @@ namespace Melodic{ message("Writing results to : " << endl); //Output IC - if((IC.Storage()>0)&&(opts.output_origIC.value()) ){ + if((IC.Storage()>0)&&(opts.output_origIC.value())&&(after_mm==false)){ volume4D<float> tempVol; tempVol.setmatrix(IC,Mask); //strncpy(tempInfo.header.hist.aux_file,"render3",24); save_volume4D(tempVol,logger.appendDir(opts.outputfname.value() - + "_origIC"),tempInfo); + + "_oIC"),tempInfo); message(" " << logger.appendDir(opts.outputfname.value() + "_oIC") <<endl); } @@ -214,13 +214,17 @@ namespace Melodic{ //Matrix ICadjust = IC; Matrix ICadjust; - stdNoisei = pow(stdev(Data - mixMatrix * IC)*std::sqrt((float)(Data.Nrows()-1))/ - std::sqrt((float)(Data.Nrows()-IC.Nrows())),-1); + if(after_mm) + ICadjust = IC; + else{ + stdNoisei = pow(stdev(Data - mixMatrix * IC)*std::sqrt((float)(Data.Nrows()-1))/ + std::sqrt((float)(Data.Nrows()-IC.Nrows())),-1); + + ColumnVector diagvals; + diagvals=pow(diag(unmixMatrix*unmixMatrix.t()),-0.5); + ICadjust = SP(IC,diagvals*stdNoisei); + } - ColumnVector diagvals; - diagvals=pow(diag(unmixMatrix*unmixMatrix.t()),-0.5); - ICadjust = SP(IC,diagvals*stdNoisei); - tempVol.setmatrix(ICadjust,Mask); //strncpy(tempInfo.header.hist.aux_file,"render3",24); save_volume4D(tempVol,logger.appendDir(opts.outputfname.value() diff --git a/meldata.h b/meldata.h index f3cd6e0..491cfa9 100644 --- a/meldata.h +++ b/meldata.h @@ -30,7 +30,8 @@ namespace Melodic{ MelodicData(MelodicOptions &popts, Log &plogger): opts(popts), logger(plogger) - { + { + after_mm = false; } void save(); @@ -118,6 +119,8 @@ namespace Melodic{ inline float get_resels() {return Resels;} inline void set_resels(float& Arg) {Resels = Arg;} + inline void set_after_mm(bool val) {after_mm = val;} + Matrix smoothColumns(const Matrix &inp); inline void flipres(int num){ @@ -162,6 +165,8 @@ namespace Melodic{ Matrix DataVN; Matrix PPCA; + bool after_mm; + float Resels; char Mean_fname[1000]; diff --git a/melgmix.cc b/melgmix.cc index 9b142cd..cab5e93 100644 --- a/melgmix.cc +++ b/melgmix.cc @@ -730,7 +730,7 @@ namespace Melodic{ // probmap << normcdf(data,means(1),vars(1)); // }|| std::abs(mean(data,2).AsScalar()) > 1.0 - if(props(1)<0.6 ){ + if(props(1)<0.4 ){ //set up GMM message(" try Gaussian Mixture Model " << endl); props=zeros(1,nummix); diff --git a/melgmix.h b/melgmix.h index 71891ac..b6fffae 100644 --- a/melgmix.h +++ b/melgmix.h @@ -53,7 +53,6 @@ namespace Melodic{ volume<float> themean, int num_mix = 3, float eps = 0.0, bool fixdim = false); - void gmmfit(); void ggmfit(); @@ -123,7 +122,7 @@ namespace Melodic{ threshmaps = -threshmaps; if(mmtype=="GGM"){ float tmp; - tmp= means(2);means(2)= means(3);means(3)=tmp; + tmp= means(2);means(2)=means(3);means(3)=tmp; tmp=vars(2);vars(2)=vars(3);vars(3)=tmp; tmp=props(2);props(2)=props(3);props(3)=tmp; } @@ -150,6 +149,15 @@ namespace Melodic{ threshinfo.clear(); } + inline void smooth_probs(float howmuch){ + volume4D<float> tempVol; + tempVol.setmatrix(probmap,Mask); + tempVol[0]= smooth(tempVol[0],howmuch); + probmap = tempVol.matrix(Mask); + } + + + double datamean; double datastdev; diff --git a/melodic.cc b/melodic.cc index f59a633..c428ab0 100644 --- a/melodic.cc +++ b/melodic.cc @@ -327,12 +327,6 @@ Matrix mmall(Log& logger, MelodicOptions& opts, melodat.save4D(mixmod.get_probmap(), string("stats/probmap_")+num2str(ctr)); } - // save probability map - //if((mixmod.get_probmap().Storage()>0)&& - // (mixmod.get_probmap().Ncols() == pmaps.Ncols())) - // pmaps.Row(ctr) = mixmod.get_probmap(); - //else - // pmaps.Row(ctr) = zeros(1,pmaps.Ncols()); //re-scale spatial maps to mean 0 for nht @@ -358,6 +352,17 @@ Matrix mmall(Log& logger, MelodicOptions& opts, melodat.set_IC(ctr,tmp); } + if(opts.smooth_probmap.value()<0.0){ + message(" smoothing probability map ... "<< endl); + mixmod.smooth_probs(0.5*(std::min(std::min(std::abs(melodat.get_mean().xdim()),std::abs(melodat.get_mean().ydim())),std::abs(melodat.get_mean().zdim())))); + } + + if(opts.smooth_probmap.value()>0.0){ + message(" smoothing probability map ... "<< endl); + mixmod.smooth_probs(opts.smooth_probmap.value()); + } + + message(" thresholding ... "<< endl); mixmod.threshold(opts.mmthresh.value()); @@ -418,16 +423,18 @@ Matrix mmall(Log& logger, MelodicOptions& opts, //now safe new data // bool what = opts.verbose.value(); //opts.verbose.set_T(false); - // melodat.save(); + + melodat.set_after_mm(TRUE); + melodat.save(); //opts.verbose.set_T(what); - if(melodat.get_IC().Storage()>0){ - volume4D<float> tempVol; - tempVol.setmatrix(melodat.get_IC(),melodat.get_mask()); - save_volume4D(tempVol,logger.appendDir(opts.outputfname.value() - + "_IC"),melodat.tempInfo); - message(endl<< endl << " Saving " << logger.appendDir(opts.outputfname.value() + "_IC") <<endl); - } + //if(melodat.get_IC().Storage()>0){ + // volume4D<float> tempVol; + // tempVol.setmatrix(melodat.get_IC(),melodat.get_mask()); + // save_volume4D(tempVol,logger.appendDir(opts.outputfname.value() + // + "_IC"),melodat.tempInfo); + // message(endl<< endl << " Saving " << logger.appendDir(opts.outputfname.value() + "_IC") <<endl); + //} if( bool(opts.genreport.value()) ){ message(endl << endl << diff --git a/melodic.h b/melodic.h index afc7e77..78822d5 100644 --- a/melodic.h +++ b/melodic.h @@ -32,7 +32,7 @@ namespace Melodic{ -const string version = "ln(10)"; +const string version = "ln(11)"; } diff --git a/meloptions.cc b/meloptions.cc index 7087b46..eb9eb40 100644 --- a/meloptions.cc +++ b/meloptions.cc @@ -234,6 +234,7 @@ void MelodicOptions::status() cout << " repeats = " << repeats.value() << endl; cout << " nlconst1 = " << nlconst1.value() << endl; cout << " nlconst2 = " << nlconst2.value() << endl; + cout << " smooth_probmap = " << smooth_probmap.value() << endl; cout << " epsilon = " << epsilon.value() << endl; cout << " threshold = " << threshold.value() << endl; diff --git a/meloptions.h b/meloptions.h index ecd3482..140f802 100644 --- a/meloptions.h +++ b/meloptions.h @@ -93,6 +93,7 @@ class MelodicOptions { Option<int> repeats; Option<float> nlconst1; Option<float> nlconst2; + Option<float> smooth_probmap; Option<bool> remove_meanvol; @@ -258,6 +259,9 @@ class MelodicOptions { nlconst2(string("--nl2,--nlconst2"), 1.0, string("nonlinear constant 2"), false, requires_argument, false), + smooth_probmap(string("--smooth_pm"), 0.0, + string("width of smoothing kernel for probability maps"), + false, requires_argument, false), remove_meanvol(string("--keepmeanvol"), true, string("do not subtract mean volume"), false, no_argument, false), @@ -331,6 +335,7 @@ class MelodicOptions { options.add(repeats); options.add(nlconst1); options.add(nlconst2); + options.add(smooth_probmap); options.add(remove_meanvol); options.add(remove_endslices); options.add(rescale_nht); diff --git a/melreport.h b/melreport.h index acb987b..2ab3a79 100644 --- a/melreport.h +++ b/melreport.h @@ -84,7 +84,7 @@ namespace Melodic{ if( bool(opts.genreport.value()) ){ report << "<hr><h2>Analysis methods</h2> <p>"<<endl; - report << "Analysis was carried out using MELODIC (Multivariate Exploratory Linear Decomposition into Independent Components) Version 2.00, part of FSL (FMRIB's Software Library, <A HREF=\"http://www.fmrib.ox.ac.uk/fsl/\">www.fmrib.ox.ac.uk/fsl</A>), an implementation for the estimation of a Probabilistic Independent Component Analysis model [Beckmann 2004]."<<endl; + report << "Analysis was carried out using MELODIC (Multivariate Exploratory Linear Decomposition into Independent Components) Version ln(11), part of FSL (FMRIB's Software Library, <A HREF=\"http://www.fmrib.ox.ac.uk/fsl/\">www.fmrib.ox.ac.uk/fsl</A>), an implementation for the estimation of a Probabilistic Independent Component Analysis model [Beckmann 2004]."<<endl; report << "The following melodic pre-processing was applied to the input data file: "<< endl; diff --git a/test.cc b/test.cc index 3c8339f..bc2c81a 100644 --- a/test.cc +++ b/test.cc @@ -10,6 +10,8 @@ #include "miscmaths/miscprob.h" #include <string> #include "utils/log.h" +#include "melgmix.h" +#include "meloptions.h" using namespace std; @@ -17,7 +19,7 @@ using namespace Utilities; using namespace NEWIMAGE; using namespace MISCPLOT; using namespace MISCPIC; - +using namespace Melodic; Matrix calcFFT(const Matrix& Mat) @@ -56,12 +58,153 @@ string float2str(float f, int width, int prec, int scientif) return os.str(); } +void usage(void) +{ + cout << "Usage: test infile ICfile [mixfile]" << endl; + exit(1); +} + int main(int argc, char *argv[]) { - Matrix data; + if (argc<3) + usage(); + + Matrix ICs; + Matrix mixMatrix; + Matrix fmixMatrix; + volumeinfo ICvolInfo; + volume<float> Mask; + volume<float> Mean; + + string RAWfname; + RAWfname = string(argv[1]); + string ICfname; + ICfname = string(argv[2]); + + string MIXfname; + if (argc>3) + MIXfname = string(argv[3]); + + cerr << argc << " " << RAWfname << " " <<ICfname << " " << MIXfname << endl; + + { + volume4D<float> RawData; + cout << " Reading orig. data " << RAWfname << " ... "; + read_volume4D(RawData,RAWfname,ICvolInfo); + Mean = meanvol(RawData); + + float howmuch = 0.5*(std::min(std::min(std::abs(Mean.xdim()),std::abs(Mean.ydim())),std::abs(Mean.zdim()))); + + cout << " Smoothing by " << howmuch << endl; + volume<float> tmpvol = smooth(Mean,howmuch); + miscpic newpic; + char instr[10000]; + + sprintf(instr," "); + strcat(instr,"-s 2"); + strcat(instr," -A 950 "); + strcat(instr,string("./res/m1.png").c_str()); + newpic.slicer(Mean, instr, &ICvolInfo); + + char instr2[10000]; + + sprintf(instr2," "); + strcat(instr2,"-s 2"); + strcat(instr2," -A 950 "); + strcat(instr2,string("./res/m2.png").c_str()); + newpic.slicer(tmpvol, instr2, &ICvolInfo); + + + + cout << " done! " << endl; + } + { + volume4D<float> RawIC; + cout << "Reading components " << ICfname << " ... "; + read_volume4D(RawIC,ICfname); + cout << " done" << endl; + + cout << "Creating mask ... "; + Mask = binarise(RawIC[0],float(RawIC[0].min()),float(RawIC[0].max())); + + ICs = RawIC.matrix(Mask); + if(ICs.Nrows()>1){ + Matrix DStDev=stdev(ICs); + + volume4D<float> tmpMask; + tmpMask.setmatrix(DStDev,Mask); + + float tMmax; + volume<float> tmpMask2; + tmpMask2 = tmpMask[0]; + tMmax = tmpMask2.max(); + 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); + ICs = RawIC.matrix(Mask); + } + else{ + Mask = binarise(RawIC[0],float(0.001),float(RawIC[0].max())) + + binarise(RawIC[0],float(RawIC[0].min()),float(-0.001)); + ICs = RawIC.matrix(Mask); + } + + //cerr << "ICs : " << ICs.Ncols() << ICs.Nrows() << endl; + cout << " done" << endl; + } + + if(MIXfname.length()>0){ + cout << "Reading mixing matrix " << MIXfname << " ... "; + mixMatrix = read_ascii_matrix(MIXfname); + if (mixMatrix.Storage()<=0) { + cerr <<" Please specify the mixing matrix correctly" << endl; + exit(2); + cout << " done " << endl; + } + } + + cout << " ICs: " << ICs.Nrows() << " x " << ICs.Ncols() << endl; + if(ICs.Nrows()>0){ + cout << " Plotting histogram for map 1" << endl; + + miscplot newplot; + // newplot.add_label("legend1"); + //newplot.add_label("legend2"); + //newplot.add_ylabel(string("yll1")); + + //newplot.add_xlabel(string("xl1")); + // newplot.set_xysize(600,600); + + Matrix mu(1,3); + Matrix pi(1,3); + Matrix std(1,3); + mu(1,1)=0;mu(1,2)=2.10;mu(1,3)=-1.99388; + pi(1,1)=0.911806;pi(1,2)=0.066722;pi(1,3)=0.021472; + std(1,1)=1;std(1,2)=0.831590;std(1,3)=0.639299; + newplot.gmmfit(ICs.Row(1),mu,std,pi,string("./res/g1.png"),string("Title")); + + mu(1,1)=0;mu(1,2)=2.209024;mu(1,3)=-2.016637; + pi(1,1)=0.873335;pi(1,2)=0.086185;pi(1,3)=0.040480; + std(1,1)=1;std(1,2)=1.012970;std(1,3)=0.616374; + newplot.gmmfit(ICs.Row(2),mu,std,pi,string("./res/g2.png"),string("Title")); + + mu(1,1)=0;mu(1,2)=2.694458;mu(1,3)=-3.418763; + pi(1,1)=0.9779397;pi(1,2)=0.017768;pi(1,3)=0.004293; + std(1,1)=1;std(1,2)=2.848577;std(1,3)=0.385187; + newplot.gmmfit(ICs.Row(3),mu,std,pi,string("./res/g3.png"),string("Title")); + + // newplot.histogram(ICs.Row(1),string("./res/h1.png"),string("Title")); + } + + cout << endl << endl; + /* + Matrix data; + cerr<< "Reading mixing matrix "; data = read_ascii_matrix(string("mixmat")); if (data.Storage()<=0) { @@ -77,7 +220,7 @@ int main(int argc, char *argv[]) cerr << " create new data " << M_PI <<endl; - ColumnVector X(200); + ColumnVector X(1000); for(int i=1; i<=X.Nrows(); i++){ X(i) = (float((i-1))/(X.Nrows()-1))*M_PI; @@ -113,19 +256,23 @@ mmat.setDir(string("./res/"),string("mix.txt")); << "</H1>"<< endl; - float tr = 0.0; + float tr = 5.0; Matrix data2; data2 = calcFFT(data); - for (int i=1; i<=data.Ncols(); i++) { - cerr << i << " " ; {//plot time course miscplot newplot; - + //newplot.add_label("legend1"); + //newplot.add_label("legend2"); + // newplot.add_ylabel(string("yll1")); + //newplot.add_ylabel(string("ylabel2guiygyiasyugfuyigfuigasgfuiguiyasgfuigasuigfagifgiuygasisgfuigasgfgasgfigiagfgaggfigaif")); + //newplot.add_xlabel(string("xl1")); + //newplot.add_xlabel(string("xlabel2")); + //newplot.set_xysize(600,200); if(tr>0.0) newplot.timeseries(data.Column(i).t(), string("./res/t")+num2str(i)+".png", @@ -183,6 +330,6 @@ mmat.setDir(string("./res/"),string("mix.txt")); IChtml<< "<HR><FONT SIZE=1>This page produced automatically by " << "FMRIB Software Library</A>.</FONT>" << endl << "</BODY></HTML>" << endl; - cerr << endl; + cerr << endl; */ return 0; } -- GitLab