PropagationPropertiesCalculator.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 
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     // We don't own the data reader, so we don't destroy it.
00043 }
00044 
00045 double PropagationPropertiesCalculator::CalculateMaximumUpstrokeVelocity(unsigned globalNodeIndex)
00046 {
00047     std::vector<double> voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00048     std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00049     CellProperties cell_props(voltages, times);
00050     return cell_props.GetLastMaxUpstrokeVelocity();
00051 }
00052 
00053 std::vector<double> PropagationPropertiesCalculator::CalculateAllMaximumUpstrokeVelocities(unsigned globalNodeIndex)
00054 {
00055     std::vector<double> voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00056     std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00057     CellProperties cell_props(voltages, times);
00058     return cell_props.GetMaxUpstrokeVelocities();
00059 }
00060 
00061 double PropagationPropertiesCalculator::CalculateActionPotentialDuration(const double percentage,
00062         unsigned globalNodeIndex)
00063 {
00064     std::vector<double> voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00065     std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00066     CellProperties cell_props(voltages, times);
00067     return cell_props.GetLastActionPotentialDuration(percentage);
00068 }
00069 
00070 std::vector<double> PropagationPropertiesCalculator::CalculateAllActionPotentialDurations(const double percentage,
00071         unsigned globalNodeIndex)
00072 {
00073     std::vector<double> voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00074     std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00075     CellProperties cell_props(voltages, times);
00076     return cell_props.GetAllActionPotentialDurations(percentage);
00077 }
00078 
00079 double PropagationPropertiesCalculator::CalculatePeakMembranePotential(unsigned globalNodeIndex)
00080 {
00081     std::vector<double> voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNodeIndex);
00082     double max = -DBL_MAX;
00083     for(unsigned i=0; i<voltages.size(); i++)
00084     {
00085         if(voltages[i]>max)
00086         {
00087             max = voltages[i];
00088         }
00089     }
00090     return max;
00091 }
00092 
00093 double PropagationPropertiesCalculator::CalculateConductionVelocity(unsigned globalNearNodeIndex,
00094         unsigned globalFarNodeIndex,
00095         const double euclideanDistance)
00096 {
00097     double t_near = 0;
00098     double t_far = 0;
00099     std::vector<double> near_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNearNodeIndex);
00100     std::vector<double> far_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalFarNodeIndex);
00101     std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00102 
00103     CellProperties near_cell_props(near_voltages, times);
00104     CellProperties far_cell_props(far_voltages, times);
00105     
00106     //The size of each vector is the number of APs that reached that node
00107     unsigned aps_near_node = near_cell_props.GetMaxUpstrokeVelocities().size();
00108     unsigned aps_far_node = far_cell_props.GetMaxUpstrokeVelocities().size();
00109     
00110     //If empty, no AP reached the node and no conduction velocity will be calculated
00111     if (aps_near_node == 0 || aps_far_node == 0)
00112     {
00113         EXCEPTION("AP never reached one of the nodes");
00114     }
00115     
00116     //if the same number of APs reached both nodes, get the last one...
00117     if (aps_near_node == aps_far_node)
00118     {
00119         t_near = near_cell_props.GetTimeAtLastMaxUpstrokeVelocity();
00120         t_far = far_cell_props.GetTimeAtLastMaxUpstrokeVelocity();
00121     }
00122     //...otherwise get the one with the smallest value, which is the last AP to reach both nodes
00123     //This prevents possible calculation of negative conduction velocities 
00124     //for repeated stimuli
00125     else if (aps_near_node > aps_far_node)
00126     {
00127         t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_far_node-1];
00128         t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_far_node-1];
00129     }
00130     else
00131     {
00132         t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_near_node-1];
00133         t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity()[aps_near_node-1];
00134     }
00135 
00136     return euclideanDistance / (t_far - t_near);
00137 }
00138 
00139 std::vector<double> PropagationPropertiesCalculator::CalculateAllConductionVelocities(unsigned globalNearNodeIndex,
00140                                                                 unsigned globalFarNodeIndex,
00141                                                                 const double euclideanDistance)
00142 {
00143     std::vector<double> t_near;
00144     std::vector<double> t_far;
00145     std::vector<double> conduction_velocities;
00146     unsigned number_of_aps = 0;
00147     
00148     std::vector<double> near_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalNearNodeIndex);
00149     std::vector<double> far_voltages = mpDataReader->GetVariableOverTime(mVoltageName, globalFarNodeIndex);
00150     std::vector<double> times = mpDataReader->GetUnlimitedDimensionValues();
00151 
00152     CellProperties near_cell_props(near_voltages, times);
00153     CellProperties far_cell_props(far_voltages, times);
00154     
00155     t_near = near_cell_props.GetTimesAtMaxUpstrokeVelocity();
00156     t_far = far_cell_props.GetTimesAtMaxUpstrokeVelocity();
00157     
00158     //If empty, no AP reached the node and no conduction velocity will be calculated
00159     if (t_near.size() == 0 || t_far.size() == 0)
00160     {
00161         EXCEPTION("AP never reached one of the nodes");
00162     }
00163     
00164     //Check the node where the least number of aps is reached. 
00165     //We will calculate only where AP reached both nodes
00166     if (t_near.size() > t_far.size())
00167     {
00168         number_of_aps=t_far.size();
00169     }
00170     else
00171     {
00172        number_of_aps=t_near.size();
00173     }
00174     //now fill the vector
00175     for (unsigned i = 0 ; i < number_of_aps;i++)
00176     {
00177         conduction_velocities.push_back(euclideanDistance / (t_far[i] - t_near[i]));
00178     }
00179     return conduction_velocities;
00180 }

Generated on Wed Mar 18 12:51:52 2009 for Chaste by  doxygen 1.5.5