00001 #ifndef INDII_FMRI_HEMODYNAMIC_BOLDCALCULATOR_HPP 00002 #define INDII_FMRI_HEMODYNAMIC_BOLDCALCULATOR_HPP 00003 00004 #include "indii/ml/aux/vector.hpp" 00005 #include "indii/ml/ode/ParameterCollection.hpp" 00006 00007 namespace indii { 00008 namespace fmri { 00009 namespace hemodynamic { 00010 00011 class BalloonModel; 00012 00013 /** 00014 * Calculates Blood Oxygenation Level Dependent (BOLD) signal from a 00015 * FlowBalloonModel or NeuralBalloonModel. 00016 * 00017 * @author Lawrence Murray <lawrence@indii.org> 00018 * @version $Rev: 285 $ 00019 * @date $Date: 2007-07-20 17:25:40 +0100 (Fri, 20 Jul 2007) $ 00020 * 00021 * @section BOLDCalculator_details Details 00022 * 00023 * The BOLD signal change \f$\frac{\Delta S}{S}\f$ may be calculated 00024 * from the \f$q\f$ and \f$v\f$ state variables of a balloon model 00025 * according to the formula given in @ref Buxton1998 00026 * "Buxton et al. (1998)": 00027 * 00028 * \f[\frac{\Delta S}{S} = V_0\left[ k_1(1-q) + k_2\left(1-\frac{q}{v}\right) 00029 * + k_3(1-v) \right]\f] 00030 * 00031 * where \f$k_1\f$, \f$k_2\f$ and \f$k_3\f$ are constants. 00032 * 00033 * @section usage Usage 00034 * 00035 * The basic usage idiom is to firstly construct a BalloonModel object 00036 * and then create the BOLDCalculator coupled to it: 00037 * 00038 * @code 00039 * FlowBalloonModel bm; // or NeuralBalloonModel bm; 00040 * BOLDCalculator bc(&bm); 00041 * @endcode 00042 * 00043 * The balloon %model may then be simulated as normal and the BOLD 00044 * signal calculated from it at any time by calling calculate(). This 00045 * would usually be done after each step of the balloon %model: 00046 * 00047 * @code 00048 * indii::ml::ode::AdaptiveRungeKutta solver(&bm, bm.suggestInitialState()); 00049 * double end = 60.0; 00050 * double t = 0.0; 00051 * 00052 * while (t < end) { 00053 * t = solver.step(end); 00054 * std::cout << t << '=' << bc.calculate(solver.getState()) << std::endl; 00055 * } 00056 * @endcode 00057 * 00058 * The BalloonModel object itself may be used as normal, the 00059 * BOLDCalculator does not modify it in any way, and simply requires 00060 * it for some parameters. 00061 */ 00062 class BOLDCalculator : public indii::ml::ode::ParameterCollection { 00063 public: 00064 /** 00065 * Biophysical parameters. These are initialised according to the 00066 * values in BOLDCalculatorDefaults, but may be overridden using 00067 * setParameter(). 00068 */ 00069 enum BiophysicalParameter { 00070 /** 00071 * \f$k_1\f$ 00072 */ 00073 K_1, 00074 00075 /** 00076 * \f$k_2\f$ 00077 */ 00078 K_2, 00079 00080 /** 00081 * \f$k_3\f$ 00082 */ 00083 K_3 00084 }; 00085 00086 /** 00087 * Create new BOLD calculator with default biophysical parameters, 00088 * coupled with the given balloon %model. 00089 * 00090 * @param m FlowBalloonModel or NeuralBalloonModel from which to 00091 * calculate BOLD signal. 00092 */ 00093 BOLDCalculator(const BalloonModel* m); 00094 00095 /** 00096 * Destructor. 00097 */ 00098 virtual ~BOLDCalculator(); 00099 00100 /** 00101 * Calculate BOLD signal from coupled balloon %model and given 00102 * state. 00103 * 00104 * @param y State of the balloon %model, usually provided by the 00105 * ordinary differential equation solver being used on the balloon 00106 * %model, such as indii::ml::ode::AdaptiveRungeKutta. 00107 * 00108 * @return The BOLD signal produced by the coupled balloon %model in 00109 * the given state. 00110 */ 00111 double calculate(const indii::ml::aux::vector& y); 00112 00113 private: 00114 /** 00115 * Balloon %model for which to calculate BOLD response. 00116 */ 00117 const BalloonModel* m; 00118 00119 /** 00120 * Number of biophysical parameters. 00121 */ 00122 static const unsigned int NUM_PARAMETERS = 3; 00123 00124 }; 00125 00126 } 00127 } 00128 } 00129 00130 #endif
1.5.2