/* MELODIC - Multivariate exploratory linear optimized decomposition into independent components melreport.cc - report generation Christian F. Beckmann, FMRIB Image Analysis Group Copyright (C) 1999-2002 University of Oxford */ /* CCOPYRIGHT */ #include "newimage/newimageall.h" #include "utils/log.h" #include "melreport.h" namespace Melodic{ void MelodicReport::IC_rep(MelGMix &mmodel, int cnum, int dim) { if( bool(opts.genreport.value()) ){ addlink(mmodel.get_prefix()+".html",num2str(cnum)); IChtml.setDir(report.getDir(),mmodel.get_prefix()+".html"); {//start IC page IChtml << "<HTML> " << endl << "<TITLE>MELODIC Component " << num2str(cnum) << "</TITLE>" << endl << "<BODY BACKGROUND=\"file:" << getenv("FSLDIR") << "/doc/images/fsl-bg.jpg\">" << endl << "<hr><CENTER><H1>MELODIC Component " << num2str(cnum) << "</H1>"<< endl; if(cnum>1) IChtml << "<a href=\"" << string("IC_")+num2str(cnum-1) <<".html\">previous</a> - "; IChtml << "<a href=\"00index.html\"> index </a>" ; if(cnum<dim) IChtml << " - <a href=\"" << string("IC_")+num2str(cnum+1) <<".html\">next</a><p>"; IChtml << "<hr><p>" << endl; } volume4D<float> tempVol; if(mmodel.get_threshmaps().Storage()>0&& (mmodel.get_threshmaps().Ncols() == mmodel.get_data().Ncols())) {//Output thresholded IC map tempVol.setmatrix(mmodel.get_threshmaps().Row(1),melodat.get_mask()); volume<float> map1; volume<float> map2; map1 = threshold(tempVol[0],float(0.0), tempVol[0].max()); map2 = threshold(tempVol[0],tempVol[0].min(), float(0.0)); // save_volume(map,report.appendDir(mmodel.get_prefix()+"_thresh") // ,melodat.tempInfo); volume<float> newvol; // for(int ctr=1; ctr<500; ctr++){ // cerr << ctr << " "; miscpic newpic; float map1min = std::max((map1 + binarise(tempVol[0],tempVol[0].min(), float(0.0)) * map1.max()).min(),float(0.01)); float map1max = std::max(map1.max(),float(0.01)); float map2min = std::min(map2.min(),float(-0.01)); float map2max = std::min((map2 + binarise(tempVol[0],float(0.0), tempVol[0].max()) * map2.min()).max(),float(-0.01)); newpic.overlay(newvol, melodat.get_mean(), map1, map2, melodat.get_mean().percentile(0.02), melodat.get_mean().percentile(0.98), map1min, map1max, map2max, map2min, 0, 0, &melodat.tempInfo); char instr[10000]; //save_volume(newvol,report.appendDir(mmodel.get_prefix()+"rendered"), // melodat.tempInfo); sprintf(instr," "); strcat(instr," -s 2"); strcat(instr," -A 950 "); strcat(instr,string(report.appendDir(mmodel.get_prefix()+ "_thresh.png")).c_str()); newpic.set_title(string("Component No. "+num2str(cnum)+ " - thresholded IC map ")+ mmodel.get_infstr(1)); newpic.set_cbar(string("ysb")); //cerr << instr << endl; if(map1.max()-map1.min()>0.01) newpic.slicer(newvol, instr, &melodat.tempInfo); else newpic.slicer(map1, instr, &melodat.tempInfo); } // } // exit(2); IChtml << "<a href=\""+mmodel.get_prefix()+"_MM.html\">"; IChtml << "<img BORDER=0 SRC=\""+mmodel.get_prefix() +"_thresh.png\" ALT=\"MMfit\"></A><p>" << endl; {//plot time course miscplot newplot; if(opts.tr.value()>0.0) newplot.timeseries(melodat.get_mix().Column(cnum).t(), report.appendDir(string("t")+num2str(cnum)+".png"), string("Timecourse (in seconds); TR = ")+ float2str(opts.tr.value(),0,2,0)+" s", opts.tr.value(),150,4,1); else newplot.timeseries(melodat.get_mix().Column(cnum).t(), report.appendDir(string("t")+num2str(cnum)+".png"), string("Timecourse (in TRs)")); write_ascii_matrix(report.appendDir(string("t") +num2str(cnum)+".txt"), melodat.get_mix().Column(cnum)); IChtml << "<A HREF=\"" << string("t") +num2str(cnum)+".txt" << "\"> "; IChtml << "<img BORDER=0 SRC=\"" +string("t")+num2str(cnum)+".png\"></A><p>" << endl; }//time series plot {//plot frequency miscplot newplot; RowVector empty(1); empty = 0.0; int fact = int(std::pow(10.0,int(std::log10(float(melodat.get_mix().Nrows()))))); if(opts.tr.value()>0.0) newplot.timeseries(empty | melodat.get_fmix().Column(cnum).t(), report.appendDir(string("f")+ num2str(cnum)+".png"), string("FFT of timecourse (in Hz / ") +num2str(fact)+")", fact/(opts.tr.value()*melodat.get_mix().Nrows()), 150, 0,2); else newplot.timeseries(empty | melodat.get_fmix().Column(cnum).t(), report.appendDir(string("f")+ num2str(cnum)+".png"), string(string("FFT of timecourse (in cycles); ") +"frequency(Hz)=cycles/(" +num2str(melodat.get_mix().Nrows()) +"* TR); period(s)=(" +num2str(melodat.get_mix().Nrows()) +"* TR)/cycles")); write_ascii_matrix(report.appendDir(string("f") +num2str(cnum)+".txt"), melodat.get_fmix().Column(cnum)); IChtml << "<A HREF=\"" << string("f") +num2str(cnum)+".txt" << "\"> "; IChtml << "<img BORDER=0 SRC=\"" +string("f")+num2str(cnum)+".png\"></A><p>" << endl; }//frequency plot if(mmodel.get_threshmaps().Storage()>0&& (mmodel.get_threshmaps().Ncols() == mmodel.get_data().Ncols())&& (mmodel.get_threshmaps().Nrows()>1)) {//Output other thresholded IC map for(int tctr=2; tctr<=mmodel.get_threshmaps().Nrows(); tctr++){ tempVol.setmatrix(mmodel.get_threshmaps().Row(tctr),melodat.get_mask()); volume<float> map1; volume<float> map2; map1 = threshold(tempVol[0],float(0.0), tempVol[0].max()); map2 = threshold(tempVol[0],tempVol[0].min(), float(0.0)); // save_volume(map,report.appendDir(mmodel.get_prefix()+"_thresh") // ,melodat.tempInfo); volume<float> newvol; miscpic newpic; float map1min = (map1 + binarise(tempVol[0],tempVol[0].min(), float(0.0)) * map1.max()).min(); float map1max = map1.max(); float map2min = map2.min(); float map2max = (map2 + binarise(tempVol[0],float(0.0), tempVol[0].max()) * map2.min()).max(); //cerr << endl << map1min << " " << map1max << endl // << map2min << " " << map2max << endl; // if(map1.max()-map1.min()>0.01) newpic.overlay(newvol, melodat.get_mean(), map1, map2, melodat.get_mean().percentile(0.02), melodat.get_mean().percentile(0.98), map1min, map1max, map2max, map2min, 0, 0, &melodat.tempInfo); char instr[10000]; //save_volume(newvol,report.appendDir(mmodel.get_prefix()+"rendered"), // melodat.tempInfo); sprintf(instr," "); strcat(instr," -s 2"); strcat(instr," -A 950 "); strcat(instr,string(report.appendDir(mmodel.get_prefix()+"_thresh"+ num2str(tctr)+".png")).c_str()); newpic.set_title(string("Component No. "+num2str(cnum)+ " - thresholded IC map ("+ num2str(tctr)+") ")+ mmodel.get_infstr(tctr)); newpic.set_cbar(string("ysb")); //cerr << instr << endl; newpic.slicer(newvol, instr, &melodat.tempInfo); IC_rep_det(mmodel, cnum, dim); IChtml << "<a href=\""+mmodel.get_prefix()+"_MM.html\">"; IChtml << "<img BORDER=0 SRC=\""+mmodel.get_prefix() +"_thresh"+num2str(tctr)+".png\" ALT=\"MMfit\"></A><p>" << endl; } } { //finish IC page IChtml<< "<HR><FONT SIZE=1>This page produced automatically by " << "<A HREF=\"http://www.fmrib.ox.ac.uk/fsl/melodic/index.html\"> MELODIC </A>" << " - a part of <A HREF=\"http://www.fmrib.ox.ac.uk/fsl\">FSL - " << "FMRIB Software Library</A>.</FONT>" << endl << "</BODY></HTML>" << endl; } //finish IC page IC_rep_det(mmodel, cnum, dim); } } void MelodicReport::IC_rep_det(MelGMix &mmodel, int cnum, int dim) { if( bool(opts.genreport.value()) ){ {//start IC2 page IChtml2.setDir(report.getDir(),mmodel.get_prefix()+"_MM.html"); IChtml2 << "<HTML> " << endl << "<TITLE>Component " << num2str(cnum) << " Mixture Model fit </TITLE>" << endl << "<BODY BACKGROUND=\"file:" << getenv("FSLDIR") << "/doc/images/fsl-bg.jpg\">" << endl << "<hr><CENTER><H1>Component " << num2str(cnum) << " Mixture Model fit </H1>"<< endl; if(cnum>1) IChtml2 << "<a href=\"" << string("IC_")+num2str(cnum-1) <<"_MM.html\">previous</a> - "; IChtml2 << "<a href=\""+ mmodel.get_prefix() + ".html\"> up to IC report </a>"; if(cnum<dim) IChtml2 << " - <a href=\"" << string("IC_")+num2str(cnum+1) <<"_MM.html\">next</a><p>"; IChtml2 << "<hr><p>" << endl; } volume4D<float> tempVol; if(melodat.get_IC().Storage()>0) {//Output raw IC map tempVol.setmatrix(melodat.get_IC().Row(cnum), melodat.get_mask()); volume<float> map1; volume<float> map2; map1 = threshold(tempVol[0],float(0.0), tempVol[0].max()); map2 = threshold(tempVol[0],tempVol[0].min(), float(-0.0)); volume<float> newvol; miscpic newpic; // float map1min = (map1 + binarise(tempVol[0],tempVol[0].min(), // float(0.0)) * map1.max()).robustmin(); float map1max = map1.percentile(0.99); float map2min = map2.percentile(0.01); //float map2max = (map2 + binarise(tempVol[0],float(0.0), // tempVol[0].max()) * map2.min()).robustmax(); newpic.overlay(newvol, melodat.get_mean(), map1, map2, float(0.0), float(0.0), float(0.01), map1max, float(-0.01), map2min, 0, 0, &melodat.tempInfo); char instr[10000]; //save_volume(newvol,report.appendDir(mmodel.get_prefix()+"rendered"), // melodat.tempInfo); sprintf(instr," "); strcat(instr," -s 2"); strcat(instr," -A 950 "); strcat(instr,string(report.appendDir(mmodel.get_prefix()+ ".png")).c_str()); newpic.set_title(string("Component No. "+num2str(cnum)+ " - raw Z transformed IC map (1 - 99 percentile)")); newpic.set_cbar(string("ysb")); newpic.slicer(newvol, instr, &melodat.tempInfo); } IChtml2 << "<a href=\""+mmodel.get_prefix()+".html\">"; IChtml2 << "<img BORDER=0 SRC=\""+ mmodel.get_prefix()+ ".png\"><A><p>" << endl; if(mmodel.get_probmap().Storage()>0&& (mmodel.get_probmap().Ncols() == mmodel.get_data().Ncols())&& (mmodel.get_probmap().Nrows() == mmodel.get_data().Nrows())) {//Output probmap tempVol.setmatrix(mmodel.get_probmap(),melodat.get_mask()); volume<float> map; map = tempVol[0]; volume<float> newvol; miscpic newpic; newpic.overlay(newvol, melodat.get_mean(), map, map, melodat.get_mean().percentile(0.02), melodat.get_mean().percentile(0.98), float(0.1), float(1.0), float(0.0), float(0.0), 0, 0, &melodat.tempInfo); //newpic.set_minmax(float(0.0),float(0.0),float(0.0), // float(1.0),float(0.0),float(0.0)); char instr[10000]; sprintf(instr," "); strcat(instr,"-l render1 -s 2"); strcat(instr," -A 950 "); strcat(instr,string(report.appendDir(mmodel.get_prefix()+ "_prob.png")).c_str()); newpic.set_title(string("Component No. "+num2str(cnum)+ " - Mixture Model probability map")); newpic.set_cbar(string("y")); newpic.slicer(newvol, instr, &melodat.tempInfo); // { // Log MMdetails; // MMdetails.setDir(report.getDir(),mmodel.get_prefix()+"_MM.txt"); // MMdetails << mmodel.get_prefix() << " Mixture Model fit " // << endl << endl; // MMdetails << " Means : " << mmodel.get_means() << endl // << " Vars : " << mmodel.get_vars() << endl // << " Prop. : " << mmodel.get_pi() << endl; // // if(mmodel.get_type()=="GGM"){ // // MMdetails << endl << " Gamma offset : " // // << mmodel.get_offset() << endl; // // } // } // IChtml2 << "<A HREF=\"" +mmodel.get_prefix()+"_MM.txt\"> "; IChtml2 << "<a href=\""+mmodel.get_prefix()+".html\">"; IChtml2 << "<img BORDER=0 SRC=\""+ mmodel.get_prefix()+ "_prob.png\">" << endl; // IChtml2 << "</A>"; IChtml2 << "</A><p>" << endl; } {//Output GGM/GMM fit miscplot newplot; // cerr << endl << endl; // cerr << mmodel.get_means() << endl; // cerr << mmodel.get_vars() << endl; // cerr << mmodel.get_pi() << endl; if(mmodel.get_type()=="GGM"){ newplot.add_label("IC map histogram"); newplot.add_label("full GGM fit"); newplot.add_label("background Gaussian"); newplot.add_label("Gamma distributions"); newplot.gmmfit(mmodel.get_data().Row(1), mmodel.get_means(), mmodel.get_vars(), mmodel.get_pi(), report.appendDir(mmodel.get_prefix()+"_MMfit.png"), string(mmodel.get_prefix() + " GGM("+num2str(mmodel.mixtures())+") fit"), true, float(0.0), float(2.0)); // newplot.histogram(mmodel.get_data().Row(1), // report.appendDir(mmodel.get_prefix()+"_MMfit.png"), // string(mmodel.get_prefix() + // " GGM("+num2str(mmodel.mixtures())+") fit")); //, mmodel.get_offset()); } else{ newplot.add_label("IC map histogram"); newplot.add_label("full GMM fit"); newplot.add_label("individual Gaussians"); newplot.gmmfit(mmodel.get_data().Row(1), mmodel.get_means(), mmodel.get_vars(), mmodel.get_pi(), report.appendDir(mmodel.get_prefix()+"_MMfit.png"), string(mmodel.get_prefix() + " GMM("+num2str(mmodel.mixtures())+") fit"), false, float(0.0), float(2.0)); } // cerr << "finish HTML2 " << endl; IChtml2 << "<A HREF=\"" +mmodel.get_prefix()+"_MMfit_detail.png\"> "; IChtml2 << "<img BORDER=0 SRC=\""+ mmodel.get_prefix()+ "_MMfit.png\"></A><p>" << endl; } //GGM/GMM plot { IChtml2 << "<br> " << mmodel.get_prefix() << " Mixture Model fit <br>" << endl << "<br> Means : " << mmodel.get_means() << endl << "<br> Vars : " << mmodel.get_vars() << endl << "<br> Prop. : " << mmodel.get_pi() << endl; // if(mmodel.get_type()=="GGM"){ // IChtml2 << "<br> Gamma offset : " // << mmodel.get_offset() << "<br><p>"<< endl; // } } { //finish IC2 page IChtml2<< "<HR><FONT SIZE=1>This page produced automatically by " << "<A HREF=\"http://www.fmrib.ox.ac.uk/fsl/melodic/index.html\"> MELODIC </A>" << " - a part of <A HREF=\"http://www.fmrib.ox.ac.uk/fsl\">FSL - " << "FMRIB Software Library</A>.</FONT>" << endl << "</BODY></HTML>" << endl; } //finish IC2 page } } void MelodicReport::IC_simplerep(string prefix, int cnum, int dim) { if( bool(opts.genreport.value()) ){ addlink(prefix+".html",num2str(cnum)); IChtml.setDir(report.getDir(),prefix+".html"); {//start IC page IChtml << "<HTML> " << endl << "<TITLE>MELODIC Component " << num2str(cnum) << "</TITLE>" << endl << "<BODY BACKGROUND=\"file:" << getenv("FSLDIR") << "/doc/images/fsl-bg.jpg\">" << endl << "<hr><CENTER><H1>MELODIC Component " << num2str(cnum) << "</H1>"<< endl; if(cnum>1) IChtml << "<a href=\"" << string("IC_")+num2str(cnum-1) <<".html\">previous</a> - "; IChtml << "<a href=\"00index.html\"> index </a>" ; if(cnum<dim) IChtml << " - <a href=\"" << string("IC_")+num2str(cnum+1) <<".html\">next</a><p>"; IChtml << "<hr><p>" << endl; } volume4D<float> tempVol; if(melodat.get_IC().Storage()>0) {//Output raw IC map tempVol.setmatrix(melodat.get_IC().Row(cnum), melodat.get_mask()); volume<float> map1; volume<float> map2; map1 = threshold(tempVol[0],float(0.0), tempVol[0].max()); map2 = threshold(tempVol[0],tempVol[0].min(), float(-0.0)); volume<float> newvol; miscpic newpic; // float map1min = (map1 + binarise(tempVol[0],tempVol[0].min(), // float(0.0)) * map1.max()).robustmin(); float map1max = map1.percentile(0.99); float map2min = map2.percentile(0.01); //float map2max = (map2 + binarise(tempVol[0],float(0.0), // tempVol[0].max()) * map2.min()).robustmax(); newpic.overlay(newvol, melodat.get_mean(), map1, map2, float(0.0), float(0.0), float(0.01), map1max, float(-0.01), map2min, 0, 0, &melodat.tempInfo); char instr[10000]; //save_volume(newvol,report.appendDir(prefix+"rendered"), // melodat.tempInfo); sprintf(instr," "); strcat(instr," -s 2"); strcat(instr," -A 950 "); strcat(instr,string(report.appendDir(prefix+ ".png")).c_str()); newpic.set_title(string("Component No. "+num2str(cnum)+ " - raw Z transformed IC map (1 - 99 percentile)")); newpic.set_cbar(string("ysb")); newpic.slicer(newvol, instr, &melodat.tempInfo); } IChtml << "<img BORDER=0 SRC=\""+ prefix+ ".png\"><p>" << endl; {//plot time course miscplot newplot; if(opts.tr.value()>0.0) newplot.timeseries(melodat.get_mix().Column(cnum).t(), report.appendDir(string("t")+ num2str(cnum)+".png"), string("Timecourse (in seconds); TR = ")+ float2str(opts.tr.value(),0,2,0)+" s", opts.tr.value(),150,4,1); else newplot.timeseries(melodat.get_mix().Column(cnum).t(), report.appendDir(string("t")+ num2str(cnum)+".png"), string("Timecourse (in TRs)")); write_ascii_matrix(report.appendDir(string("t") +num2str(cnum)+".txt"), melodat.get_mix().Column(cnum)); IChtml << "<A HREF=\"" << string("t") +num2str(cnum)+".txt" << "\"> "; IChtml << "<img BORDER=0 SRC=\"" +string("t")+num2str(cnum)+".png\"></A><p>" << endl; }//time series plot {//plot frequency miscplot newplot; int fact = int(std::pow(10.0, int(std::log10(float(melodat.get_mix().Nrows()))))); if(opts.tr.value()>0.0) newplot.timeseries(melodat.get_fmix().Column(cnum).t(), report.appendDir(string("f")+ num2str(cnum)+".png"), string("FFT of timecourse (in Hz / ") + num2str(fact)+")", fact/(opts.tr.value()*melodat.get_mix().Nrows()), 150, 0,2); else newplot.timeseries(melodat.get_fmix().Column(cnum).t(), report.appendDir(string("f")+ num2str(cnum)+".png"), string(string("FFT of timecourse (in cycles); ") +"frequency(Hz)=cycles/(" +num2str(melodat.get_mix().Nrows()) +"* TR); period(s)=(" +num2str(melodat.get_mix().Nrows()) +"* TR)/cycles")); write_ascii_matrix(report.appendDir(string("f") +num2str(cnum)+".txt"), melodat.get_mix().Column(cnum)); IChtml << "<A HREF=\"" << string("f") +num2str(cnum)+".txt" << "\"> "; IChtml << "<img BORDER=0 SRC=\"" +string("f")+num2str(cnum)+".png\"></A><p>" << endl; }//frequency plot { //finish IC page IChtml<< "<HR><FONT SIZE=1>This page produced automatically by " << "<A HREF=\"http://www.fmrib.ox.ac.uk/fsl/melodic/index.html\"> MELODIC </A>" << " - a part of <A HREF=\"http://www.fmrib.ox.ac.uk/fsl\">FSL - " << "FMRIB Software Library</A>.</FONT>" << endl << "</BODY></HTML>" << endl; } //finish IC page } } void MelodicReport::PPCA_rep(){ {//plot time course report << "<p> <H3>PCA estimates </H3> <p>" << endl; Matrix what; miscplot newplot; what = melodat.get_EV(); what &= melodat.get_EVP(); newplot.add_label("ordered Eigenvalues"); newplot.add_label("% of expl. variance"); if(melodat.get_PPCA().Storage()>0){ what = what.Columns(1,melodat.get_PPCA().Nrows()); what &= melodat.get_PPCA().t(); newplot.add_label("dim. estimate"); } newplot.timeseries(what, report.appendDir("EVplot.png"), string("Eigenspectrum Analysis"), 0,450,4,0); report << "<img BORDER=0 SRC=\"EVplot.png\"><p>" << endl; }//time series plot } }