PropagationPropertiesCalculator.cpp
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 #include "HeartEventHandler.hpp"
00035
00036 PropagationPropertiesCalculator::PropagationPropertiesCalculator(Hdf5DataReader* pDataReader,
00037 const std::string voltageName)
00038 : mpDataReader(pDataReader),
00039 mVoltageName(voltageName),
00040 mTimes(mpDataReader->GetUnlimitedDimensionValues()),
00041 mCachedNodeGlobalIndex(UNSIGNED_UNSET)
00042 {}
00043
00044 PropagationPropertiesCalculator::~PropagationPropertiesCalculator()
00045 {
00046
00047 }
00048
00049 double PropagationPropertiesCalculator::CalculateMaximumUpstrokeVelocity(unsigned globalNodeIndex)
00050 {
00051 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00052 CellProperties cell_props(r_voltages, mTimes);
00053 return cell_props.GetLastMaxUpstrokeVelocity();
00054 }
00055
00056 std::vector<double> PropagationPropertiesCalculator::CalculateAllMaximumUpstrokeVelocities(unsigned globalNodeIndex, double threshold)
00057 {
00058 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00059 CellProperties cell_props(r_voltages, mTimes, threshold);
00060 return cell_props.GetMaxUpstrokeVelocities();
00061 }
00062
00063 std::vector<double> PropagationPropertiesCalculator::CalculateUpstrokeTimes(unsigned globalNodeIndex, double threshold)
00064 {
00065 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00066 CellProperties cell_props(r_voltages, mTimes, threshold);
00067 return cell_props.GetTimesAtMaxUpstrokeVelocity();
00068 }
00069
00070 double PropagationPropertiesCalculator::CalculateActionPotentialDuration(const double percentage,
00071 unsigned globalNodeIndex)
00072 {
00073 if (percentage < 1.0 || percentage >= 100.0)
00074 {
00075 EXCEPTION("First argument of CalculateActionPotentialDuration() is expected to be a percentage");
00076 }
00077 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00078 CellProperties cell_props(r_voltages, mTimes);
00079 return cell_props.GetLastActionPotentialDuration(percentage);
00080 }
00081
00082 std::vector<double> PropagationPropertiesCalculator::CalculateAllActionPotentialDurations(const double percentage,
00083 unsigned globalNodeIndex,
00084 double threshold)
00085 {
00086 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00087 CellProperties cell_props(r_voltages, mTimes, threshold);
00088 return cell_props.GetAllActionPotentialDurations(percentage);
00089 }
00090
00091 std::vector<std::vector<double> > PropagationPropertiesCalculator::CalculateAllActionPotentialDurationsForNodeRange(
00092 const double percentage,
00093 unsigned lowerNodeIndex,
00094 unsigned upperNodeIndex,
00095 double threshold)
00096 {
00097 std::vector<std::vector<double> > output_data;
00098 output_data.reserve(upperNodeIndex-lowerNodeIndex+1);
00099 unsigned num_nodes_per_data_block = 100;
00100 unsigned num_complete_blocks = (upperNodeIndex-lowerNodeIndex) / num_nodes_per_data_block;
00101 unsigned size_last_block = (upperNodeIndex-lowerNodeIndex) % num_nodes_per_data_block;
00102
00103 for (unsigned block_num=0;
00104 block_num<num_complete_blocks+1;
00105 block_num++)
00106 {
00107 unsigned num_nodes_to_read;
00108 if (block_num != num_complete_blocks)
00109 {
00110 num_nodes_to_read = num_nodes_per_data_block;
00111 }
00112 else
00113 {
00114 num_nodes_to_read = size_last_block;
00115 }
00116
00117 if (num_nodes_to_read > 0)
00118 {
00119
00120 unsigned low_node = lowerNodeIndex + block_num*num_nodes_per_data_block;
00121 unsigned high_node = low_node + num_nodes_to_read;
00122 std::vector<std::vector<double> > voltages = mpDataReader->GetVariableOverTimeOverMultipleNodes(mVoltageName, low_node, high_node);
00123
00124 for (unsigned node_within_block=0;
00125 node_within_block < num_nodes_to_read;
00126 node_within_block++)
00127 {
00128 std::vector<double>& r_voltages = voltages[node_within_block];
00129 CellProperties cell_props(r_voltages, mTimes, threshold);
00130 std::vector<double> apds;
00131 try
00132 {
00133 apds = cell_props.GetAllActionPotentialDurations(percentage);
00134 assert(apds.size() != 0);
00135 }
00136 catch (Exception& e)
00137 {
00138 assert(e.GetShortMessage()=="No full action potential was recorded" ||
00139 e.GetShortMessage()=="AP did not occur, never exceeded threshold voltage.");
00140 apds.push_back(0);
00141 assert(apds.size() == 1);
00142 }
00143 output_data.push_back(apds);
00144 }
00145 }
00146 }
00147 return output_data;
00148 }
00149
00150 double PropagationPropertiesCalculator::CalculatePeakMembranePotential(unsigned globalNodeIndex)
00151 {
00152 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00153 double max = -DBL_MAX;
00154 for (unsigned i=0; i<r_voltages.size(); i++)
00155 {
00156 if (r_voltages[i]>max)
00157 {
00158 max = r_voltages[i];
00159 }
00160 }
00161 return max;
00162 }
00163
00164 double PropagationPropertiesCalculator::CalculateConductionVelocity(unsigned globalNearNodeIndex,
00165 unsigned globalFarNodeIndex,
00166 const double euclideanDistance)
00167 {
00168 double t_near = 0;
00169 double t_far = 0;
00170 std::vector<double>& r_near_voltages = rCacheVoltages(globalNearNodeIndex);
00171 std::vector<double> far_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalFarNodeIndex);
00172
00173 CellProperties near_cell_props(r_near_voltages, mTimes);
00174 CellProperties far_cell_props(far_voltages, mTimes);
00175
00176
00177 unsigned aps_near_node = near_cell_props.GetMaxUpstrokeVelocities().size();
00178 unsigned aps_far_node = far_cell_props.GetMaxUpstrokeVelocities().size();
00179
00180
00181 assert(aps_near_node > 0);
00182 assert(aps_far_node > 0);
00183
00184
00185 if (aps_near_node == aps_far_node)
00186 {
00187 t_near = near_cell_props.GetTimeAtLastMaxUpstrokeVelocity();
00188 t_far = far_cell_props.GetTimeAtLastMaxUpstrokeVelocity();
00189 }
00190
00191
00192
00193 else if (aps_near_node > aps_far_node)
00194 {
00195 t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_far_node-1];
00196 t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_far_node-1];
00197 }
00198 else
00199 {
00200 t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_near_node-1];
00201 t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_near_node-1];
00202 }
00203
00205 if ((globalNearNodeIndex == globalFarNodeIndex) || ( fabs(t_far - t_near) < 1e-8))
00206 {
00207
00208
00209
00210 return 0.0;
00211 }
00212 else
00213 {
00214 return euclideanDistance / (t_far - t_near);
00215 }
00216
00217
00218 }
00219
00220 std::vector<double> PropagationPropertiesCalculator::CalculateAllConductionVelocities(unsigned globalNearNodeIndex,
00221 unsigned globalFarNodeIndex,
00222 const double euclideanDistance)
00223 {
00224 std::vector<double> conduction_velocities;
00225
00226 std::vector<double> t_near;
00227 std::vector<double> t_far;
00228 unsigned number_of_aps = 0;
00229
00230 std::vector<double>& r_near_voltages = rCacheVoltages(globalNearNodeIndex);
00231 std::vector<double> far_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalFarNodeIndex);
00232
00233 CellProperties near_cell_props(r_near_voltages, mTimes);
00234 CellProperties far_cell_props(far_voltages, mTimes);
00235
00236 t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity();
00237 t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity();
00238
00239
00240
00241 assert(t_near.size() !=0);
00242 assert(t_far.size() !=0);
00243
00244
00245
00246 if (t_near.size() > t_far.size())
00247 {
00248 number_of_aps = t_far.size();
00249 }
00250 else
00251 {
00252 number_of_aps = t_near.size();
00253 }
00254
00255
00256 if (globalNearNodeIndex == globalFarNodeIndex)
00257 {
00258
00259 for (unsigned i = 0 ; i < number_of_aps;i++)
00260 {
00261 conduction_velocities.push_back(0.0);
00262 }
00263 }
00264 else
00265 {
00266 for (unsigned i = 0 ; i < number_of_aps;i++)
00267 {
00269 if ( fabs(t_far[i] - t_near[i]) < 1e-8)
00270 {
00271
00272 conduction_velocities.push_back(0.0);
00273 }
00274 else
00275 {
00276 conduction_velocities.push_back(euclideanDistance / (t_far[i] - t_near[i]));
00277 }
00278 }
00279 }
00280
00281 return conduction_velocities;
00282 }
00283
00284
00285 std::vector<unsigned> PropagationPropertiesCalculator::CalculateAllAboveThresholdDepolarisations(unsigned globalNodeIndex, double threshold)
00286 {
00287 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00288 CellProperties cell_props(r_voltages, mTimes, threshold);
00289 return cell_props.GetNumberOfAboveThresholdDepolarisationsForAllAps();
00290 }
00291
00292
00293 unsigned PropagationPropertiesCalculator::CalculateAboveThresholdDepolarisationsForLastAp(unsigned globalNodeIndex, double threshold)
00294 {
00295 std::vector<double>& r_voltages = rCacheVoltages(globalNodeIndex);
00296 CellProperties cell_props(r_voltages, mTimes, threshold);
00297 return cell_props.GetNumberOfAboveThresholdDepolarisationsForLastAp();
00298 }
00299
00300
00301 std::vector<double>& PropagationPropertiesCalculator::rCacheVoltages(unsigned globalNodeIndex)
00302 {
00303 if (globalNodeIndex != mCachedNodeGlobalIndex)
00304 {
00305 mCachedVoltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00306 mCachedNodeGlobalIndex = globalNodeIndex;
00307 }
00308 return mCachedVoltages;
00309 }