Newer
Older
/* MELODIC - Multivariate exploratory linear optimized decomposition into
independent components
melreport.h - report generation
Christian F. Beckmann, FMRIB Image Analysis Group
/* CCOPYRIGHT */
#ifndef __MELODICREPORT_h
#define __MELODICREPORT_h
#include "newimage/newimageall.h"
#include "utils/log.h"
#include "melpca.h"
#include "meloptions.h"
#include "meldata.h"
#include "melgmix.h"
#include "melodic.h"
#include "newmatap.h"
#include "newmatio.h"
#include "libvis/miscplot.h"
#include "libvis/miscpic.h"
#include "utils/options.h"
using namespace Utilities;
using namespace NEWIMAGE;
using namespace MISCPLOT;
using namespace MISCPIC;
namespace Melodic{
public:
MelodicReport(MelodicData &pmelodat, MelodicOptions &popts, Log &plogger):
melodat(pmelodat),
opts(popts),
logger(plogger){
if( bool(opts.genreport.value()) ){
const time_t tmptime = time(NULL);
report.makeDir(logger.appendDir("report"),"00index.html");
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
report << "<HTML><HEAD><link REL=stylesheet TYPE=text/css href=file:" +
(string) getenv("FSLDIR") +"/doc/fsl.css>"
<< "<TITLE>MELODIC report</TITLE></HEAD><BODY>"
<< endl <<endl;
loghtml.setDir(report.getDir(),"log.html");
loghtml << "<HTML><HEAD><link REL=stylesheet TYPE=text/css href=file:" +
(string) getenv("FSLDIR") +"/doc/fsl.css>"
<< "<TITLE>MELODIC report</TITLE></HEAD><BODY>"
<< endl <<endl;
navigator.setDir(report.getDir(),"nav.html");
head.setDir(report.getDir(),"head.html");
navigator << "<link REL=stylesheet TYPE=text/css href=file:"+
(string) getenv("FSLDIR") +"/doc/fsl.css>" << endl;
head << "<link REL=stylesheet TYPE=text/css href=file:"+
(string) getenv("FSLDIR") +"/doc/fsl.css>" << endl;
head <<"<TABLE BORDER=0><TR>" << endl
<<" <TD ALIGN=CENTER WIDTH=100%>"<< endl
<<"<TABLE BORDER=0>"<< endl
<<"<tr><td align=center><font size=+3><b>MELODIC Report</b>"<< endl
<<"</font><tr><td valign=center align=center> <p>"<< endl
<< report.getDir() << "/" << report.getLogFileName() << "<br>"
<< ctime(&tmptime) << "</tr>"<< endl
<<"<tr valign=bottom><td align=center>"<< endl
<< "</tr></table>" << endl
<< "<TD ALIGN=RIGHT>" << endl
<< "<a href=http://www.fmrib.ox.ac.uk/fsl target=_top>" << endl
<< "<IMG BORDER=0 SRC=file:"<< getenv("FSLDIR")
<< "/doc/images/fsl-logo-big.jpg WIDTH=165></a>" << endl
<< "</TD>"<<endl<<"</TR></TABLE> <hr>"<<endl;
if(opts.guireport.value()==""){
report <<"<OBJECT data=head.html></OBJECT>" << endl;
loghtml <<"<OBJECT data=head.html></OBJECT>" << endl;
}else{
report <<"<OBJECT data="<<opts.guireport.value()<< "></OBJECT>"<< endl;
loghtml <<"<OBJECT data="<<opts.guireport.value()<< "></OBJECT>"<< endl;
}
report << "<IFRAME height=80px width=100% src=nav.html frameborder=0></IFRAME><p>"<< endl;
loghtml << "<IFRAME height=100px width=100% src=nav.html frameborder=0></IFRAME><p>"
<<"<pre>../melodic.log</pre>" <<endl;
navigator <<"<CENTER><TABLE BORDER=0><TR>" << endl
<<"<TD ALIGN=CENTER WIDTH=100%><FONT SIZE=-1>"<<endl
<<"<A HREF=\"00index.html\" target=\"_top\">Main</A> - ";
// if(opts.guireport.value()=="")
// navigator << "<A HREF=\"log.html\" target=\"_top\">Log</A> - ";
navigator <<"Components: ";
navigator.flush();
report << "<HR><CENTER><FONT SIZE=1>This page produced automatically by "
<< "<A HREF=\"http://www.fmrib.ox.ac.uk/fsl/melodic/index.html\"> MELODIC</A> Version "
<< version << " - a part of <A HREF=\"http://www.fmrib.ox.ac.uk/fsl\">FSL - "
<< "FMRIB Software Library</A>.</FONT></CENTER>" << endl
<< "</BODY></HTML>" <<endl;
loghtml << "<HR><CENTER><FONT SIZE=1>This page produced automatically by "
<< "<A HREF=\"http://www.fmrib.ox.ac.uk/fsl/melodic/index.html\"> MELODIC</A> Version "
<< version << " - a part of <A HREF=\"http://www.fmrib.ox.ac.uk/fsl\">FSL - "
<< "FMRIB Software Library</A>.</FONT></CENTER>" << endl
<< "</BODY></HTML>" <<endl;
navigator << "</FONT></TD>"<<endl<<"</TR></TABLE></CENTER><hr>" <<endl;
report << "Analysis was carried out using MELODIC (Multivariate Exploratory Linear Decomposition into Independent Components) Version "<< version <<", 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;
if(opts.use_mask.value())
report << " masking of non-brain voxels;";
report << " voxel-wise de-meaning of the data;" << endl;
if(opts.varnorm.value())
report << " normalisation of the voxel-wise variance; ";
report << " Pre-processed data was whitened and projected into a "
<< melodat.get_mix().Ncols()<< "-dimensional subspace using ";
if(melodat.get_PPCA().Storage()>0){
report << "probabilistic Principal Component Analysis where the number of dimensions was estimated using ";
if(opts.pca_est.value() == string("lap"))
report << "the Laplace approximation to the Bayesian evidence of the model order [Minka 2000, Beckmann 2004]. " << endl;
else
if(opts.pca_est.value() == string("bic"))
report << "the <em> Bayesian Information Criterion</em> (BIC) [Kass 1993]. " << endl;
else
if(opts.pca_est.value() == string("mdl"))
report << "<em> Minimum Description Length</em> (MDL) [Rissanen 1978]. " << endl;
else
if(opts.pca_est.value() == string("aic"))
report << "the <em> Akaike Information Criterion</em> (AIC) [Akaike 1969]. " << endl;
else
report << "a committee of approximations to Bayesian the model order [Beckmann 2004]. " << endl;
}
else
report << "Principal Component Analysis. ";
report << " The whitened observations were decomposed into a set of time-courses and spatial maps by optimising for non-Gaussian spatial source distributions using a fixed-point iteration technique [Hyvärinen 1999]. " << endl;
report << "Estimated Component maps were divided by the standard deviation of the residual noise";
if(opts.perf_mm.value())
report << " and thresholded by fitting a mixture model to the histogram of intensity values [Beckmann 2004]. <p>" << endl;
else
report <<".<p>" << endl;
report << "[Hyvärinen 1999] A. Hyvärinen. Fast and Robust Fixed-Point Algorithms for Independent Component Analysis. IEEE Transactions on Neural Networks 10(3):626-634, 1999.<br> " << endl;
report << "[Beckmann 2004] C.F. Beckmann and S.M. Smith. Probabilistic Independent Component Analysis for Functional Magnetic Resonance Imaging. IEEE Transactions on Medical Imaging 23(2):137-152 2004. <br>" << endl;
if(melodat.get_PPCA().Storage()>0){
report << "[Everson 2000] R. Everson and S. Roberts. Inferring the eigenvalues of covariance matrices from limited, noisy data. IEEE Trans Signal Processing, 48(7):2083-2091, 2000<br>"<<endl;
report << "[Tipping 1999] M.E. Tipping and C.M.Bishop. Probabilistic Principal component analysis. J Royal Statistical Society B, 61(3), 1999. <br>" << endl;
/* report << "[Beckmann 2001] C.F. Beckmann, J.A. Noble and S.M. Smith. Investigating the intrinsic dimensionality of FMRI data for ICA. In Seventh Int. Conf. on Functional Mapping of the Human Brain, 2001. <br>" << endl;*/
if(opts.pca_est.value() == string("lap"))
report << "[Minka 2000] T. Minka. Automatic choice of dimensionality for PCA. Technical Report 514, MIT Media Lab Vision and Modeling Group, 2000. <BR>"<< endl;
else
if(opts.pca_est.value() == string("bic"))
report << "[Kass 1995] R.E. Kass and A. E. Raftery. Bayes factors. Journal of the American Statistical Association, 90:733-795, 1995 <br>" << endl;
else
if(opts.pca_est.value() == string("mdl"))
report << "[Rissanen 1978]. J. Rissanen. Modelling by shortest data description. Automatica, 14:465-471, 1978. <br>" << endl;
else
if(opts.pca_est.value() == string("aic"))
report << "[Akaike 1974]. H. Akaike. A new look at statistical model identification. IEEE Transactions on Automatic Control, 19:716-723, 1974. <br>" << endl;
else
report << "[Minka 2000]. T. Minka. Automatic choice of dimensionality for PCA. Technical Report 514, MIT Media Lab Vision and Modeling Group, 2000. <BR>" << endl;
}
}
if( bool(opts.genreport.value()) ){
report << what << endl;
}
if( bool(opts.genreport.value()) ){
report << "<p>" << what << endl;
}
}
inline void addlink(string where, string what){
navigator << "<A HREF=\"" << where << " \"target=\"_top\"> " << what << "</A> ";
navigator.flush();
}
inline void addpic(string what, string link = ""){
if( bool(opts.genreport.value()) ){
if( link.length() > 0)
report << "<A HREF=\"" << link << "\"> ";
report << "<img BORDER=0 SRC=\"" << what<< ".png\"><p>";
if( link.length() > 0)
report << "</A> ";
}
void IC_rep(MelGMix &mmodel, int cnum, int dim, Matrix ICstats);
void IC_simplerep(string prefix, int cnum, int dim);
void PPCA_rep();
private:
MelodicData &melodat;
MelodicOptions &opts;
Log &logger;
Log report;
Log IChtml;
Log IChtml2;
void IC_rep_det(MelGMix &mmodel, int cnum, int dim);
string int2str(int n){
ostrstream os;
// os.fill(' ');
// os.width(width);
os.setf(ios::internal, ios::adjustfield);
os << n << '\0';
return os.str();
}
string float2str(float f, int width, int prec, int scientif){
ostrstream os;
int redw = int(std::abs(std::log10(std::abs(f))))+1;
if(width>0)
os.width(width);
if(scientif>0)
os.setf(ios::scientific);
os.precision(redw+std::abs(prec));
os.setf(ios::internal, ios::adjustfield);
os << f << '\0';
return os.str();
}
};