37#include "HeartConfig.hpp"
38#include "PostProcessingWriter.hpp"
40#include "OutputFileHandler.hpp"
41#include "DistanceMapCalculator.hpp"
42#include "PseudoEcgCalculator.hpp"
44#include "HeartEventHandler.hpp"
45#include "Hdf5DataWriter.hpp"
49template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
52 const std::string& rHdf5FileName,
53 const std::string& rVoltageName,
54 hsize_t hdf5DataWriterChunkSize)
55 : mDirectory(rDirectory),
56 mHdf5File(rHdf5FileName),
57 mVoltageName(rVoltageName),
59 mHdf5DataWriterChunkSize(hdf5DataWriterChunkSize)
61 mLo =
mrMesh.GetDistributedVectorFactory()->GetLow();
62 mHi =
mrMesh.GetDistributedVectorFactory()->GetHigh();
69template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
79 std::vector<std::pair<double,double> > apd_maps;
81 for (
unsigned i=0; i<apd_maps.size(); i++)
83 WriteApdMapFile(apd_maps[i].first, apd_maps[i].second);
89 std::vector<double> upstroke_time_maps;
91 for (
unsigned i=0; i<upstroke_time_maps.size(); i++)
93 WriteUpstrokeTimeMap(upstroke_time_maps[i]);
99 std::vector<double> upstroke_velocity_maps;
101 for (
unsigned i=0; i<upstroke_velocity_maps.size(); i++)
103 WriteMaxUpstrokeVelocityMap(upstroke_velocity_maps[i]);
109 std::vector<unsigned> conduction_velocity_maps;
115 for (
unsigned i=0; i<conduction_velocity_maps.size(); i++)
117 std::vector<double> distance_map;
118 std::vector<unsigned> origin_surface;
119 origin_surface.push_back(conduction_velocity_maps[i]);
121 WriteConductionVelocityMap(conduction_velocity_maps[i], distance_map);
127 std::vector<unsigned> requested_nodes;
129 WriteVariablesOverTimeAtNodes(requested_nodes);
134 std::vector<ChastePoint<SPACE_DIM> > electrodes;
141 for (
unsigned i=0; i<electrodes.size(); i++)
153 mpCalculator->SetHdf5DataReader(mpDataReader);
157template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
164template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
166 const std::string& rDatasetName,
167 const std::string& rDatasetUnit,
168 const std::string& rUnlimitedVariableName,
169 const std::string& rUnlimitedVariableUnit)
174 mDirectory.GetRelativePath(test_output),
189 if (mHdf5DataWriterChunkSize>0u)
206 unsigned local_max_paces = 0u;
207 for (
unsigned node_index = 0; node_index < rDataPayload.size(); ++node_index)
209 if (rDataPayload[node_index].size() > local_max_paces)
211 local_max_paces = rDataPayload[node_index].size();
215 unsigned max_paces = 0u;
216 MPI_Allreduce(&local_max_paces, &max_paces, 1, MPI_UNSIGNED, MPI_MAX, PETSC_COMM_WORLD);
218 for (
unsigned pace_idx = 0; pace_idx < max_paces; pace_idx++)
223 index!= distributed_vector.
End();
226 unsigned node_idx = index.Local;
228 if (pace_idx < rDataPayload[node_idx].size() )
230 distributed_vector[index] = rDataPayload[node_idx][pace_idx];
234 distributed_vector[index] = -999.0;
245template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
248 std::vector<std::vector<double> > local_output_data = mpCalculator->CalculateAllActionPotentialDurationsForNodeRange(repolarisationPercentage, mLo, mHi, threshold);
251 std::stringstream hdf5_dataset_name;
252 hdf5_dataset_name <<
"Apd_" << repolarisationPercentage;
254 WriteOutputDataToHdf5(local_output_data,
255 hdf5_dataset_name.str() + ConvertToHdf5FriendlyString(threshold) +
"_Map",
259template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
262 std::vector<std::vector<double> > output_data;
264 for (
unsigned node_index = mLo; node_index < mHi; node_index++)
266 std::vector<double> upstroke_times;
269 upstroke_times = mpCalculator->CalculateUpstrokeTimes(node_index, threshold);
270 assert(upstroke_times.size() != 0);
274 upstroke_times.push_back(0);
275 assert(upstroke_times.size() == 1);
277 output_data.push_back(upstroke_times);
280 WriteOutputDataToHdf5(output_data,
281 "UpstrokeTimeMap" + ConvertToHdf5FriendlyString(threshold),
285template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
288 std::vector<std::vector<double> > output_data;
290 for (
unsigned node_index = mLo; node_index < mHi; node_index++)
292 std::vector<double> upstroke_velocities;
295 upstroke_velocities = mpCalculator->CalculateAllMaximumUpstrokeVelocities(node_index, threshold);
296 assert(upstroke_velocities.size() != 0);
300 upstroke_velocities.push_back(0);
301 assert(upstroke_velocities.size() ==1);
303 output_data.push_back(upstroke_velocities);
306 WriteOutputDataToHdf5(output_data,
307 "MaxUpstrokeVelocityMap" + ConvertToHdf5FriendlyString(threshold),
311template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
315 std::vector<std::vector<double> > output_data;
316 for (
unsigned dest_node = mLo; dest_node < mHi; dest_node++)
318 std::vector<double> conduction_velocities;
321 conduction_velocities = mpCalculator->CalculateAllConductionVelocities(originNode, dest_node, distancesFromOriginNode[dest_node]);
322 assert(conduction_velocities.size() != 0);
326 conduction_velocities.push_back(0);
327 assert(conduction_velocities.size() == 1);
329 output_data.push_back(conduction_velocities);
331 std::stringstream filename_stream;
332 filename_stream <<
"ConductionVelocityFromNode" << originNode;
334 WriteOutputDataToHdf5(output_data, filename_stream.str(),
"cm_per_msec");
337template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
340 std::vector<std::vector<double> > output_data;
343 for (
unsigned node_index = mLo; node_index < mHi; node_index++)
345 std::vector<double> upstroke_velocities;
346 std::vector<unsigned> above_threshold_depolarisations;
347 std::vector<double> output_item;
348 bool no_upstroke_occurred =
false;
352 upstroke_velocities = mpCalculator->CalculateAllMaximumUpstrokeVelocities(node_index, threshold);
353 assert(upstroke_velocities.size() != 0);
357 upstroke_velocities.push_back(0);
358 assert(upstroke_velocities.size() == 1);
359 no_upstroke_occurred =
true;
362 above_threshold_depolarisations = mpCalculator->CalculateAllAboveThresholdDepolarisations(node_index, threshold);
365 unsigned total_number_of_above_threshold_depolarisations = 0;
366 for (
unsigned ead_index = 0; ead_index< above_threshold_depolarisations.size();ead_index++)
368 total_number_of_above_threshold_depolarisations = total_number_of_above_threshold_depolarisations + above_threshold_depolarisations[ead_index];
372 if (no_upstroke_occurred)
374 output_item.push_back(0);
378 output_item.push_back((
double)upstroke_velocities.size());
381 output_item.push_back((
double) total_number_of_above_threshold_depolarisations);
383 output_data.push_back(output_item);
387 WriteGenericFileToMeshalyzer(output_data,
"",
"AboveThresholdDepolarisations" + ConvertToHdf5FriendlyString(threshold) +
391template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
394 std::stringstream dataset_stream;
395 std::string extra_message =
"_";
398 extra_message +=
"minus_";
399 threshold = -threshold;
403 if (threshold - floor(threshold) > 1e-8)
406 dataset_stream << extra_message << floor(threshold) <<
"pt" << floor(threshold*100)-(floor(threshold)*100);
410 dataset_stream << extra_message << threshold;
413 return dataset_stream.str();
416template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
419 std::vector<std::string> variable_names = mpDataReader->GetVariableNames();
422 for (
unsigned name_index=0; name_index < variable_names.size(); name_index++)
424 std::vector<std::vector<double> > output_data;
428 output_data.resize( mpDataReader->GetUnlimitedDimensionValues().size() );
429 for (
unsigned j = 0; j < mpDataReader->GetUnlimitedDimensionValues().size(); j++)
431 output_data[j].resize(rNodeIndices.size());
434 for (
unsigned requested_index = 0; requested_index < rNodeIndices.size(); requested_index++)
436 unsigned node_index = rNodeIndices[requested_index];
439 if ((mrMesh.rGetNodePermutation().size() != 0) &&
442 node_index = mrMesh.rGetNodePermutation()[ rNodeIndices[requested_index] ];
446 std::vector<double> time_series = mpDataReader->GetVariableOverTime(variable_names[name_index], node_index);
447 assert ( time_series.size() == mpDataReader->GetUnlimitedDimensionValues().size());
450 for (
unsigned time_step = 0; time_step < time_series.size(); time_step++)
452 output_data[time_step][requested_index] = time_series[time_step];
456 std::stringstream filename_stream;
457 filename_stream <<
"NodalTraces_" << variable_names[name_index] <<
".dat";
459 WriteGenericFileToMeshalyzer(output_data,
"", filename_stream.str());
463template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
469 out_stream p_file=out_stream(NULL);
479 p_file = output_file_handler.
OpenOutputFile(rFileName, std::ios::app);
482 for (
unsigned line_number=0; line_number<rDataPayload.size(); line_number++)
484 for (
unsigned i = 0; i < rDataPayload[line_number].size(); i++)
486 *p_file << rDataPayload[line_number][i] <<
"\t";
488 *p_file << std::endl;
static std::string GetProvenanceString()
void ComputeDistanceMap(const std::vector< unsigned > &rSourceNodeIndices, std::vector< double > &rNodeDistances)
DistributedVector CreateDistributedVector(Vec vec, bool readOnly=false)
unsigned GetNumberOfRows()
void SetTargetChunkSize(hsize_t targetSize)
void DefineUnlimitedDimension(const std::string &rVariableName, const std::string &rVariableUnits, unsigned estimatedLength=1)
void PutUnlimitedVariable(double value)
void AdvanceAlongUnlimitedDimension()
int GetVariableByName(const std::string &rVariableName)
void DefineFixedDimension(long dimensionSize)
int DefineVariable(const std::string &rVariableName, const std::string &rVariableUnits)
virtual void EndDefineMode()
void PutVector(int variableID, Vec petscVector)
bool GetOutputUsingOriginalNodeOrdering()
void GetNodalTimeTraceRequested(std::vector< unsigned > &rRequestedNodes) const
void GetApdMaps(std::vector< std::pair< double, double > > &rApdMaps) const
void GetConductionVelocityMaps(std::vector< unsigned > &rConductionVelocityMaps) const
void GetPseudoEcgElectrodePositions(std::vector< ChastePoint< SPACE_DIM > > &rPseudoEcgElectrodePositions) const
void GetUpstrokeTimeMaps(std::vector< double > &rUpstrokeTimeMaps) const
void GetMaxUpstrokeVelocityMaps(std::vector< double > &rUpstrokeVelocityMaps) const
static HeartConfig * Instance()
out_stream OpenOutputFile(const std::string &rFileName, std::ios_base::openmode mode=std::ios::out|std::ios::trunc) const
void WritePostProcessingFiles()
void WriteMaxUpstrokeVelocityMap(double threshold)
void WriteConductionVelocityMap(unsigned originNode, std::vector< double > distancesFromOriginNode)
void WriteVariablesOverTimeAtNodes(std::vector< unsigned > &rNodeIndices)
void WriteUpstrokeTimeMap(double threshold)
void WriteGenericFileToMeshalyzer(std::vector< std::vector< double > > &rDataPayload, const std::string &rFolder, const std::string &rFileName)
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > & mrMesh
std::string ConvertToHdf5FriendlyString(double threshold)
void WriteApdMapFile(double repolarisationPercentage, double threshold)
void WriteOutputDataToHdf5(const std::vector< std::vector< double > > &rDataPayload, const std::string &rDatasetName, const std::string &rDatasetUnit, const std::string &rUnlimitedVariableName="PaceNumber", const std::string &rUnlimitedVariableUnit="dimensionless")
Hdf5DataReader * mpDataReader
PostProcessingWriter(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, const FileFinder &rDirectory, const std::string &rHdf5FileName, const std::string &rVoltageName="V", hsize_t hdf5DataWriterChunkSize=0)
void WriteAboveThresholdDepolarisationFile(double threshold)
PropagationPropertiesCalculator * mpCalculator