37 #include "HeartConfig.hpp"
38 #include "PostProcessingWriter.hpp"
40 #include "OutputFileHandler.hpp"
41 #include "DistanceMapCalculator.hpp"
42 #include "PseudoEcgCalculator.hpp"
43 #include "Version.hpp"
44 #include "HeartEventHandler.hpp"
45 #include "Hdf5DataWriter.hpp"
46 #include "Hdf5ToMeshalyzerConverter.hpp"
47 #include "Hdf5ToVtkConverter.hpp"
51 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
54 const std::string& rHdf5FileName,
55 const std::string& rVoltageName)
56 : mDirectory(rDirectory),
57 mHdf5File(rHdf5FileName),
58 mVoltageName(rVoltageName),
61 mLo =
mrMesh.GetDistributedVectorFactory()->GetLow();
62 mHi =
mrMesh.GetDistributedVectorFactory()->GetHigh();
69 template<
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);
158 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
165 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
167 const std::string& rDatasetName,
168 const std::string& rDatasetUnit,
169 const std::string& rUnlimitedVariableName,
170 const std::string& rUnlimitedVariableUnit)
175 mDirectory.GetRelativePath(test_output),
185 if ( writer.IsInDefineMode() )
188 writer.DefineFixedDimension(mrMesh.GetNumNodes());
189 writer.DefineUnlimitedDimension(rUnlimitedVariableName, rUnlimitedVariableUnit);
190 writer.EndDefineMode();
194 apd_id = writer.GetVariableByName(rDatasetName);
195 writer.EmptyDataset();
199 unsigned local_max_paces = 0u;
200 for (
unsigned node_index = 0; node_index < rDataPayload.size(); ++node_index)
202 if (rDataPayload[node_index].size() > local_max_paces)
204 local_max_paces = rDataPayload[node_index].size();
208 unsigned max_paces = 0u;
209 MPI_Allreduce(&local_max_paces, &max_paces, 1, MPI_UNSIGNED, MPI_MAX, PETSC_COMM_WORLD);
211 for (
unsigned pace_idx = 0; pace_idx < max_paces; pace_idx++)
216 index!= distributed_vector.
End();
219 unsigned node_idx = index.Local;
221 if (pace_idx < rDataPayload[node_idx].size() )
223 distributed_vector[index] = rDataPayload[node_idx][pace_idx];
227 distributed_vector[index] = -999.0;
230 writer.PutVector(apd_id, apd_vec);
232 writer.PutUnlimitedVariable(pace_idx);
233 writer.AdvanceAlongUnlimitedDimension();
238 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
241 std::vector<std::vector<double> > local_output_data = mpCalculator->CalculateAllActionPotentialDurationsForNodeRange(repolarisationPercentage, mLo, mHi, threshold);
244 std::stringstream hdf5_dataset_name;
245 hdf5_dataset_name <<
"Apd_" << repolarisationPercentage;
247 WriteOutputDataToHdf5(local_output_data,
248 hdf5_dataset_name.str() + ConvertToHdf5FriendlyString(threshold) +
"_Map",
252 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
255 std::vector<std::vector<double> > output_data;
257 for (
unsigned node_index = mLo; node_index < mHi; node_index++)
259 std::vector<double> upstroke_times;
262 upstroke_times = mpCalculator->CalculateUpstrokeTimes(node_index, threshold);
263 assert(upstroke_times.size() != 0);
267 upstroke_times.push_back(0);
268 assert(upstroke_times.size() == 1);
270 output_data.push_back(upstroke_times);
273 WriteOutputDataToHdf5(output_data,
274 "UpstrokeTimeMap" + ConvertToHdf5FriendlyString(threshold),
278 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
281 std::vector<std::vector<double> > output_data;
283 for (
unsigned node_index = mLo; node_index < mHi; node_index++)
285 std::vector<double> upstroke_velocities;
288 upstroke_velocities = mpCalculator->CalculateAllMaximumUpstrokeVelocities(node_index, threshold);
289 assert(upstroke_velocities.size() != 0);
293 upstroke_velocities.push_back(0);
294 assert(upstroke_velocities.size() ==1);
296 output_data.push_back(upstroke_velocities);
299 WriteOutputDataToHdf5(output_data,
300 "MaxUpstrokeVelocityMap" + ConvertToHdf5FriendlyString(threshold),
304 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
308 std::vector<std::vector<double> > output_data;
309 for (
unsigned dest_node = mLo; dest_node < mHi; dest_node++)
311 std::vector<double> conduction_velocities;
314 conduction_velocities = mpCalculator->CalculateAllConductionVelocities(originNode, dest_node, distancesFromOriginNode[dest_node]);
315 assert(conduction_velocities.size() != 0);
319 conduction_velocities.push_back(0);
320 assert(conduction_velocities.size() == 1);
322 output_data.push_back(conduction_velocities);
324 std::stringstream filename_stream;
325 filename_stream <<
"ConductionVelocityFromNode" << originNode;
327 WriteOutputDataToHdf5(output_data, filename_stream.str(),
"cm_per_msec");
330 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
333 std::vector<std::vector<double> > output_data;
336 for (
unsigned node_index = mLo; node_index < mHi; node_index++)
338 std::vector<double> upstroke_velocities;
339 std::vector<unsigned> above_threshold_depolarisations;
340 std::vector<double> output_item;
341 bool no_upstroke_occurred =
false;
345 upstroke_velocities = mpCalculator->CalculateAllMaximumUpstrokeVelocities(node_index, threshold);
346 assert(upstroke_velocities.size() != 0);
350 upstroke_velocities.push_back(0);
351 assert(upstroke_velocities.size() == 1);
352 no_upstroke_occurred =
true;
355 above_threshold_depolarisations = mpCalculator->CalculateAllAboveThresholdDepolarisations(node_index, threshold);
358 unsigned total_number_of_above_threshold_depolarisations = 0;
359 for (
unsigned ead_index = 0; ead_index< above_threshold_depolarisations.size();ead_index++)
361 total_number_of_above_threshold_depolarisations = total_number_of_above_threshold_depolarisations + above_threshold_depolarisations[ead_index];
365 if (no_upstroke_occurred)
367 output_item.push_back(0);
371 output_item.push_back((
double)upstroke_velocities.size());
374 output_item.push_back((
double) total_number_of_above_threshold_depolarisations);
376 output_data.push_back(output_item);
380 WriteGenericFileToMeshalyzer(output_data,
"",
"AboveThresholdDepolarisations" + ConvertToHdf5FriendlyString(threshold) +
384 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
387 std::stringstream dataset_stream;
388 std::string extra_message =
"_";
391 extra_message +=
"minus_";
392 threshold = -threshold;
396 if (threshold - floor(threshold) > 1e-8)
399 dataset_stream << extra_message << floor(threshold) <<
"pt" << floor(threshold*100)-(floor(threshold)*100);
403 dataset_stream << extra_message << threshold;
406 return dataset_stream.str();
409 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
412 std::vector<std::string> variable_names = mpDataReader->GetVariableNames();
415 for (
unsigned name_index=0; name_index < variable_names.size(); name_index++)
417 std::vector<std::vector<double> > output_data;
421 output_data.resize( mpDataReader->GetUnlimitedDimensionValues().size() );
422 for (
unsigned j = 0; j < mpDataReader->GetUnlimitedDimensionValues().size(); j++)
424 output_data[j].resize(rNodeIndices.size());
427 for (
unsigned requested_index = 0; requested_index < rNodeIndices.size(); requested_index++)
429 unsigned node_index = rNodeIndices[requested_index];
432 if ( (mrMesh.rGetNodePermutation().size() != 0) &&
435 node_index = mrMesh.rGetNodePermutation()[ rNodeIndices[requested_index] ];
439 std::vector<double> time_series = mpDataReader->GetVariableOverTime(variable_names[name_index], node_index);
440 assert ( time_series.size() == mpDataReader->GetUnlimitedDimensionValues().size());
443 for (
unsigned time_step = 0; time_step < time_series.size(); time_step++)
445 output_data[time_step][requested_index] = time_series[time_step];
449 std::stringstream filename_stream;
450 filename_stream <<
"NodalTraces_" << variable_names[name_index] <<
".dat";
452 WriteGenericFileToMeshalyzer(output_data,
"", filename_stream.str());
456 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
462 out_stream p_file=out_stream(NULL);
472 p_file = output_file_handler.
OpenOutputFile(rFileName, std::ios::app);
475 for (
unsigned line_number=0; line_number<rDataPayload.size(); line_number++)
477 for (
unsigned i = 0; i < rDataPayload[line_number].size(); i++)
479 *p_file << rDataPayload[line_number][i] <<
"\t";
481 *p_file << std::endl;
void WritePostProcessingFiles()
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > & mrMesh
void WriteVariablesOverTimeAtNodes(std::vector< unsigned > &rNodeIndices)
unsigned GetNumberOfRows()
DistributedVector CreateDistributedVector(Vec vec, bool readOnly=false)
void GetConductionVelocityMaps(std::vector< unsigned > &rConductionVelocityMaps) const
bool GetOutputUsingOriginalNodeOrdering()
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")
std::string ConvertToHdf5FriendlyString(double threshold)
void GetUpstrokeTimeMaps(std::vector< double > &rUpstrokeTimeMaps) const
void WriteMaxUpstrokeVelocityMap(double threshold)
out_stream OpenOutputFile(const std::string &rFileName, std::ios_base::openmode mode=std::ios::out|std::ios::trunc) const
void GetNodalTimeTraceRequested(std::vector< unsigned > &rRequestedNodes) const
void WriteConductionVelocityMap(unsigned originNode, std::vector< double > distancesFromOriginNode)
void WriteUpstrokeTimeMap(double threshold)
PostProcessingWriter(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, const FileFinder &rDirectory, const std::string &rHdf5FileName, const std::string &rVoltageName="V")
void WriteGenericFileToMeshalyzer(std::vector< std::vector< double > > &rDataPayload, const std::string &rFolder, const std::string &rFileName)
void GetPseudoEcgElectrodePositions(std::vector< ChastePoint< SPACE_DIM > > &rPseudoEcgElectrodePositions) const
int DefineVariable(const std::string &rVariableName, const std::string &rVariableUnits)
PropagationPropertiesCalculator * mpCalculator
void GetApdMaps(std::vector< std::pair< double, double > > &rApdMaps) const
void WriteApdMapFile(double repolarisationPercentage, double threshold)
static std::string GetProvenanceString()
void GetMaxUpstrokeVelocityMaps(std::vector< double > &rUpstrokeVelocityMaps) const
void ComputeDistanceMap(const std::vector< unsigned > &rSourceNodeIndices, std::vector< double > &rNodeDistances)
Hdf5DataReader * mpDataReader
static HeartConfig * Instance()
void WriteAboveThresholdDepolarisationFile(double threshold)