00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "UblasIncludes.hpp"
00030 #include "PropagationPropertiesCalculator.hpp"
00031 #include "CellProperties.hpp"
00032 #include "Exception.hpp"
00033 #include <sstream>
00034
00035 PropagationPropertiesCalculator::PropagationPropertiesCalculator(Hdf5DataReader* pDataReader,
00036 const std::string voltageName)
00037 : mpDataReader(pDataReader),
00038 mVoltageName(voltageName),
00039 mTimes(mpDataReader->GetUnlimitedDimensionValues()),
00040 mCachedNodeGlobalIndex(UNSIGNED_UNSET)
00041 {}
00042
00043 PropagationPropertiesCalculator::~PropagationPropertiesCalculator()
00044 {
00045
00046 }
00047
00048 double PropagationPropertiesCalculator::CalculateMaximumUpstrokeVelocity(unsigned globalNodeIndex)
00049 {
00050 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00051 CellProperties cell_props(r_voltages, mTimes);
00052 return cell_props.GetLastMaxUpstrokeVelocity();
00053 }
00054
00055 std::vector<double> PropagationPropertiesCalculator::CalculateAllMaximumUpstrokeVelocities(unsigned globalNodeIndex, double threshold)
00056 {
00057 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00058 CellProperties cell_props(r_voltages, mTimes, threshold);
00059 return cell_props.GetMaxUpstrokeVelocities();
00060 }
00061
00062 std::vector<double> PropagationPropertiesCalculator::CalculateUpstrokeTimes(unsigned globalNodeIndex, double threshold)
00063 {
00064 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00065 CellProperties cell_props(r_voltages, mTimes, threshold);
00066 return cell_props.GetTimesAtMaxUpstrokeVelocity();
00067 }
00068
00069 double PropagationPropertiesCalculator::CalculateActionPotentialDuration(const double percentage,
00070 unsigned globalNodeIndex)
00071 {
00072 if (percentage < 1.0 || percentage >= 100.0)
00073 {
00074 EXCEPTION("First argument of CalculateActionPotentialDuration() is expected to be a percentage");
00075 }
00076 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00077 CellProperties cell_props(r_voltages, mTimes);
00078 return cell_props.GetLastActionPotentialDuration(percentage);
00079 }
00080
00081 std::vector<double> PropagationPropertiesCalculator::CalculateAllActionPotentialDurations(const double percentage,
00082 unsigned globalNodeIndex,
00083 double threshold)
00084 {
00085 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00086 CellProperties cell_props(r_voltages, mTimes, threshold);
00087 return cell_props.GetAllActionPotentialDurations(percentage);
00088 }
00089
00090 double PropagationPropertiesCalculator::CalculatePeakMembranePotential(unsigned globalNodeIndex)
00091 {
00092 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00093 double max = -DBL_MAX;
00094 for (unsigned i=0; i<r_voltages.size(); i++)
00095 {
00096 if (r_voltages[i]>max)
00097 {
00098 max = r_voltages[i];
00099 }
00100 }
00101 return max;
00102 }
00103
00104 double PropagationPropertiesCalculator::CalculateConductionVelocity(unsigned globalNearNodeIndex,
00105 unsigned globalFarNodeIndex,
00106 const double euclideanDistance)
00107 {
00108 double t_near = 0;
00109 double t_far = 0;
00110 std::vector<double>& r_near_voltages = rCacheVoltages(globalNearNodeIndex);
00111 std::vector<double> far_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalFarNodeIndex);
00112
00113 CellProperties near_cell_props(r_near_voltages, mTimes);
00114 CellProperties far_cell_props(far_voltages, mTimes);
00115
00116
00117 unsigned aps_near_node = near_cell_props.GetMaxUpstrokeVelocities().size();
00118 unsigned aps_far_node = far_cell_props.GetMaxUpstrokeVelocities().size();
00119
00120
00121 assert(aps_near_node > 0);
00122 assert(aps_far_node > 0);
00123
00124
00125 if (aps_near_node == aps_far_node)
00126 {
00127 t_near = near_cell_props.GetTimeAtLastMaxUpstrokeVelocity();
00128 t_far = far_cell_props.GetTimeAtLastMaxUpstrokeVelocity();
00129 }
00130
00131
00132
00133 else if (aps_near_node > aps_far_node)
00134 {
00135 t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_far_node-1];
00136 t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_far_node-1];
00137 }
00138 else
00139 {
00140 t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_near_node-1];
00141 t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_near_node-1];
00142 }
00143
00144 if ((globalNearNodeIndex == globalFarNodeIndex) || ( fabs(t_far - t_near) < 1e-8))
00145 {
00146
00147
00148
00149 return 0.0;
00150 }
00151 else
00152 {
00153 return euclideanDistance / (t_far - t_near);
00154 }
00155
00156
00157 }
00158
00159 std::vector<double> PropagationPropertiesCalculator::CalculateAllConductionVelocities(unsigned globalNearNodeIndex,
00160 unsigned globalFarNodeIndex,
00161 const double euclideanDistance)
00162 {
00163 std::vector<double> conduction_velocities;
00164
00165 std::vector<double> t_near;
00166 std::vector<double> t_far;
00167 unsigned number_of_aps = 0;
00168
00169 std::vector<double>& r_near_voltages = rCacheVoltages(globalNearNodeIndex);
00170 std::vector<double> far_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalFarNodeIndex);
00171
00172 CellProperties near_cell_props(r_near_voltages, mTimes);
00173 CellProperties far_cell_props(far_voltages, mTimes);
00174
00175 t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity();
00176 t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity();
00177
00178
00179
00180 assert(t_near.size() !=0);
00181 assert(t_far.size() !=0);
00182
00183
00184
00185 if (t_near.size() > t_far.size())
00186 {
00187 number_of_aps = t_far.size();
00188 }
00189 else
00190 {
00191 number_of_aps = t_near.size();
00192 }
00193
00194
00195 if (globalNearNodeIndex == globalFarNodeIndex)
00196 {
00197
00198 for (unsigned i = 0 ; i < number_of_aps;i++)
00199 {
00200 conduction_velocities.push_back(0.0);
00201 }
00202 }
00203 else
00204 {
00205 for (unsigned i = 0 ; i < number_of_aps;i++)
00206 {
00207 if ( fabs(t_far[i] - t_near[i]) < 1e-8)
00208 {
00209
00210 conduction_velocities.push_back(0.0);
00211 }
00212 else
00213 {
00214 conduction_velocities.push_back(euclideanDistance / (t_far[i] - t_near[i]));
00215 }
00216 }
00217 }
00218
00219 return conduction_velocities;
00220 }
00221
00222
00223 std::vector<unsigned> PropagationPropertiesCalculator::CalculateAllAboveThresholdDepolarisations(unsigned globalNodeIndex, double threshold)
00224 {
00225 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00226 CellProperties cell_props(r_voltages, mTimes, threshold);
00227 return cell_props.GetNumberOfAboveThresholdDepolarisationsForAllAps();
00228 }
00229
00230
00231 unsigned PropagationPropertiesCalculator::CalculateAboveThresholdDepolarisationsForLastAp(unsigned globalNodeIndex, double threshold)
00232 {
00233 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00234 CellProperties cell_props(r_voltages, mTimes, threshold);
00235 return cell_props.GetNumberOfAboveThresholdDepolarisationsForLastAp();
00236 }
00237
00238
00239 std::vector<double>& PropagationPropertiesCalculator::rCacheVoltages(unsigned globalNodeIndex)
00240 {
00241 if (globalNodeIndex != mCachedNodeGlobalIndex)
00242 {
00243 mCachedVoltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00244 mCachedNodeGlobalIndex = globalNodeIndex;
00245 }
00246 return mCachedVoltages;
00247 }