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 <sstream>
00033
00034 PropagationPropertiesCalculator::PropagationPropertiesCalculator(Hdf5DataReader *pDataReader,
00035 const std::string voltageName)
00036 : mpDataReader(pDataReader),
00037 mVoltageName(voltageName)
00038 {}
00039
00040 PropagationPropertiesCalculator::~PropagationPropertiesCalculator()
00041 {
00042
00043 }
00044
00047
00048
00049
00050
00051
00052
00053
00054
00055 double PropagationPropertiesCalculator::CalculateMaximumUpstrokeVelocity(unsigned globalNodeIndex)
00056 {
00057 std::vector<double> voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00058 std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00059 CellProperties cell_props(voltages, times);
00060 return cell_props.GetLastMaxUpstrokeVelocity();
00061 }
00062
00063 std::vector<double> PropagationPropertiesCalculator::CalculateAllMaximumUpstrokeVelocities(unsigned globalNodeIndex, double threshold)
00064 {
00065 std::vector<double> voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00066 std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00067 CellProperties cell_props(voltages, times, threshold);
00068 return cell_props.GetMaxUpstrokeVelocities();
00069 }
00070
00071 std::vector<double> PropagationPropertiesCalculator::CalculateUpstrokeTimes(unsigned globalNodeIndex, double threshold)
00072 {
00073 std::vector<double> voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00074 std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00075 CellProperties cell_props(voltages, times, threshold);
00076 return cell_props.GetTimesAtMaxUpstrokeVelocity();
00077 }
00078
00079 double PropagationPropertiesCalculator::CalculateActionPotentialDuration(const double percentage,
00080 unsigned globalNodeIndex)
00081 {
00082 if (percentage < 1.0 || percentage >= 100.0)
00083 {
00084 EXCEPTION("First argument of CalculateActionPotentialDuration() is expected to be a percentage");
00085 }
00086 std::vector<double> voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00087 std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00088 CellProperties cell_props(voltages, times);
00089 return cell_props.GetLastActionPotentialDuration(percentage);
00090 }
00091
00092 std::vector<double> PropagationPropertiesCalculator::CalculateAllActionPotentialDurations(const double percentage,
00093 unsigned globalNodeIndex, double threshold)
00094 {
00095 std::vector<double> voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00096 std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00097 CellProperties cell_props(voltages, times, threshold);
00098 return cell_props.GetAllActionPotentialDurations(percentage);
00099 }
00100
00101 double PropagationPropertiesCalculator::CalculatePeakMembranePotential(unsigned globalNodeIndex)
00102 {
00103 std::vector<double> voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00104 double max = -DBL_MAX;
00105 for(unsigned i=0; i<voltages.size(); i++)
00106 {
00107 if(voltages[i]>max)
00108 {
00109 max = voltages[i];
00110 }
00111 }
00112 return max;
00113 }
00114
00115 double PropagationPropertiesCalculator::CalculateConductionVelocity(unsigned globalNearNodeIndex,
00116 unsigned globalFarNodeIndex,
00117 const double euclideanDistance)
00118 {
00119 double t_near = 0;
00120 double t_far = 0;
00121 std::vector<double> near_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNearNodeIndex);
00122 std::vector<double> far_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalFarNodeIndex);
00123 std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00124
00125 CellProperties near_cell_props(near_voltages, times);
00126 CellProperties far_cell_props(far_voltages, times);
00127
00128
00129 unsigned aps_near_node = near_cell_props.GetMaxUpstrokeVelocities().size();
00130 unsigned aps_far_node = far_cell_props.GetMaxUpstrokeVelocities().size();
00131
00132
00133 if (aps_near_node == 0 || aps_far_node == 0)
00134 {
00135 EXCEPTION("AP never reached one of the nodes");
00136 }
00137
00138
00139 if (aps_near_node == aps_far_node)
00140 {
00141 t_near = near_cell_props.GetTimeAtLastMaxUpstrokeVelocity();
00142 t_far = far_cell_props.GetTimeAtLastMaxUpstrokeVelocity();
00143 }
00144
00145
00146
00147 else if (aps_near_node > aps_far_node)
00148 {
00149 t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_far_node-1];
00150 t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_far_node-1];
00151 }
00152 else
00153 {
00154 t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_near_node-1];
00155 t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_near_node-1];
00156 }
00157
00158 if ((globalNearNodeIndex == globalFarNodeIndex) || ( fabs(t_far - t_near) < 1e-8))
00159 {
00160
00161
00162
00163 return 0.0;
00164 }
00165 else
00166 {
00167 return euclideanDistance / (t_far - t_near);
00168 }
00169
00170
00171 }
00172
00173 std::vector<double> PropagationPropertiesCalculator::CalculateAllConductionVelocities(unsigned globalNearNodeIndex,
00174 unsigned globalFarNodeIndex,
00175 const double euclideanDistance)
00176 {
00177 std::vector<double> conduction_velocities;
00178
00179 std::vector<double> t_near;
00180 std::vector<double> t_far;
00181 unsigned number_of_aps = 0;
00182
00183 std::vector<double> near_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNearNodeIndex);
00184 std::vector<double> far_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalFarNodeIndex);
00185 std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00186
00187 CellProperties near_cell_props(near_voltages, times);
00188 CellProperties far_cell_props(far_voltages, times);
00189
00190 t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity();
00191 t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity();
00192
00193
00194 if (t_near.size() == 0 || t_far.size() == 0)
00195 {
00196 EXCEPTION("AP never reached one of the nodes");
00197 }
00198
00199
00200
00201 if (t_near.size() > t_far.size())
00202 {
00203 number_of_aps=t_far.size();
00204 }
00205 else
00206 {
00207 number_of_aps=t_near.size();
00208 }
00209
00210
00211 if (globalNearNodeIndex == globalFarNodeIndex)
00212 {
00213
00214 for (unsigned i = 0 ; i < number_of_aps;i++)
00215 {
00216 conduction_velocities.push_back(0.0);
00217 }
00218 }
00219 else
00220 {
00221 for (unsigned i = 0 ; i < number_of_aps;i++)
00222 {
00223 if ( fabs(t_far[i] - t_near[i]) < 1e-8)
00224 {
00225
00226 conduction_velocities.push_back(0.0);
00227 }
00228 else
00229 {
00230 conduction_velocities.push_back(euclideanDistance / (t_far[i] - t_near[i]));
00231 }
00232 }
00233 }
00234
00235 return conduction_velocities;
00236 }