test2.cpp

Go to the documentation of this file.
00001 #include "indii/fmri/hemodynamic/FlowBalloonModel.hpp"
00002 #include "indii/fmri/hemodynamic/BOLDCalculator.hpp"
00003 #include "indii/ml/ode/AdaptiveRungeKutta.hpp"
00004 
00005 #include <iostream>
00006 #include <string.h>
00007 #include <math.h>
00008 
00009 using namespace std;
00010 using namespace indii::fmri::hemodynamic;
00011 using namespace indii::ml::ode;
00012 
00013 /**
00014  * @file test2.cpp
00015  *
00016  * Basic test of FlowBalloonModel.
00017  *
00018  * This test configures a FlowBalloonModel with parameters and
00019  * functions set according to the second experiment in Buxton et
00020  * al. (1998). Results are output on stdout, tab delimited, with
00021  * columns representing:
00022  *
00023  * \li \f$t\f$; time
00024  * \li \f$f_{in}(t)\f$
00025  * \li \f$f_{out}(t)\f$
00026  * \li \f$CMRO_2(t) = \frac{E(t)}{E_0}f_{in}(t)\f$ (Buxton et al. 2004).
00027  * \li \f$q\f$
00028  * \li \f$v\f$
00029  * \li \f$y\f$; BOLD response
00030  *
00031  * Results are as follows:
00032  *
00033  * \image html test2.png "Results, c.f. Buxton et al. (1998), Figure 2"
00034  * \image latex test2.eps "Results, c.f. Buxton et al. (1998), Figure 2"
00035  *
00036  * @note The only difference between this test and that in test1.cpp
00037  * is the definition of F_OUT -- linear in the case of test1.cpp and
00038  * nonlinear in the case of test1.cpp.
00039  *
00040  * @note Look out for a double line in the graph for \f$f_{out}(v)\f$
00041  * which may indicate that the error bounds need to be tightened or
00042  * that discontinuities in \f$f_{in}(t)\f$ are not being handled
00043  * well. As the volume increases, peaks and then decreases with time
00044  * in this test, this graph has two lines drawn. They should be
00045  * exactly the same.
00046  */
00047 
00048 /**
00049  * \f$\tau_0\f$
00050  */
00051 static const double TAU_0 = 2.0;
00052 
00053 /**
00054  * \f$E_0\f$
00055  */
00056 static const double E_0 = 0.4;
00057 
00058 /**
00059  * \f$V_0\f$
00060  */
00061 static const double V_0 = 0.01;
00062 
00063 /**
00064  * \f$\alpha\f$
00065  */
00066 static const double ALPHA = 0.5;
00067 
00068 /**
00069  * Duration of simulation (s).
00070  */
00071 static const double END = 20.0;
00072 
00073 /**
00074  * \f$f_{in}(t)\f$; Trapezoidal function with a rise time of 4 s,
00075  * duration of 4 s and fall time of 4 s.
00076  */
00077 double F_IN(double t, const double y[], void* o) {
00078   double f;
00079   if (t < 4) {
00080     f = (0.7/4.0)*t + 1;
00081   } else if (t < 8) {
00082     f = 1.7;
00083   } else if (t < 12) {
00084     f = (-0.7/4.0)*(t - 8) + 1.7;
00085   } else {
00086     f = 1.0;
00087   }
00088   return f;
00089 }
00090 
00091 /**
00092  * @brief \f$f_{out}(t) = \frac{7}{80}\left[\frac{20}{3}(v -
00093  * 1)\right]^{3} + 1\f$;
00094  *
00095  * i.e. nonlinear relative to \f$v\f$. The exact form of the function
00096  * used in Buxton et al. (1998) Figure 2 is unknown, but this seems a
00097  * reasonable approximation.
00098  */
00099 double F_OUT(double t, const double y[], void* o) {
00100   return 0.7/8.0 * pow((y[FlowBalloonModel::V] - 1.0)*2.0/0.3, 3.0) + 1.0;
00101 }
00102 
00103 /**
00104  * Run tests.
00105  */
00106 int main(int argc, const char* argv[]) {
00107   FlowBalloonModel balloonModel;
00108   BOLDCalculator boldCalculator(&balloonModel);
00109   AdaptiveRungeKutta ode(&balloonModel, balloonModel.suggestInitialState());
00110 
00111   /* set up balloon model */
00112   balloonModel.setFunction(FlowBalloonModel::F_IN, F_IN);
00113   balloonModel.setFunction(FlowBalloonModel::F_OUT, F_OUT);
00114   balloonModel.setParameter(FlowBalloonModel::TAU_0, TAU_0);
00115   balloonModel.setParameter(FlowBalloonModel::E_0, E_0);
00116   balloonModel.setParameter(FlowBalloonModel::V_0, V_0);
00117   balloonModel.setParameter(FlowBalloonModel::ALPHA, ALPHA);
00118 
00119   double cmro2;
00120   double t = 0.0;
00121   while (t < END) {
00122     cmro2 = balloonModel.getFunction(FlowBalloonModel::E) /
00123         balloonModel.getParameter(FlowBalloonModel::E_0) *
00124         balloonModel.getFunction(FlowBalloonModel::F_IN);
00125     cout << t << "\t";
00126     cout << balloonModel.getFunction(FlowBalloonModel::F_IN) << "\t";
00127     cout << balloonModel.getFunction(FlowBalloonModel::F_OUT) << "\t";
00128     cout << cmro2 << "\t";
00129     cout << ode.getVariable(FlowBalloonModel::Q) << "\t";
00130     cout << ode.getVariable(FlowBalloonModel::V) << "\t";
00131     cout << boldCalculator.calculate(ode.getState()) * 100.0 << "\t";
00132     cout << endl;
00133     t = ode.step(END);
00134   }
00135 
00136   return 0;
00137 }

Generated on Mon Aug 13 19:51:39 2007 for fmrii Hemodynamic Models Test Suite by  doxygen 1.5.2