27#include <boost/filesystem.hpp>
33#define WRITE_FILEATTRIB_STRING(attribute, value) \
35 h5_int64_t h5err = H5WriteFileAttribString(H5file_m, attribute, value); \
36 if (h5err <= H5_ERR) { \
37 std::stringstream ss; \
38 ss << "failed to write string attribute " << attribute << " to file " << fileName_m; \
39 throw GeneralClassicException(std::string(__func__), ss.str()); \
42#define WRITE_STEPATTRIB_FLOAT64(attribute, value, size) \
44 h5_int64_t h5err = H5WriteStepAttribFloat64(H5file_m, attribute, value, size); \
45 if (h5err <= H5_ERR) { \
46 std::stringstream ss; \
47 ss << "failed to write float64 attribute " << attribute << " to file " << fileName_m; \
48 throw GeneralClassicException(std::string(__func__), ss.str()); \
51#define WRITE_STEPATTRIB_INT64(attribute, value, size) \
53 h5_int64_t h5err = H5WriteStepAttribInt64(H5file_m, attribute, value, size); \
54 if (h5err <= H5_ERR) { \
55 std::stringstream ss; \
56 ss << "failed to write int64 attribute " << attribute << " to file " << fileName_m; \
57 throw GeneralClassicException(std::string(__func__), ss.str()); \
60#define WRITE_DATA_FLOAT64(name, value) \
62 h5_int64_t h5err = H5PartWriteDataFloat64(H5file_m, name, value); \
63 if (h5err <= H5_ERR) { \
64 std::stringstream ss; \
65 ss << "failed to write float64 data " << name << " to file " << fileName_m; \
66 throw GeneralClassicException(std::string(__func__), ss.str()); \
69#define WRITE_DATA_INT64(name, value) \
71 h5_int64_t h5err = H5PartWriteDataInt64(H5file_m, name, value); \
72 if (h5err <= H5_ERR) { \
73 std::stringstream ss; \
74 ss << "failed to write int64 data " << name << " to file " << fileName_m; \
75 throw GeneralClassicException(std::string(__func__), ss.str()); \
80 h5_int64_t h5err = H5SetStep(H5file_m, H5call_m); \
81 if (h5err <= H5_ERR) { \
82 std::stringstream ss; \
83 ss << "failed to set step " << H5call_m << " in file " << fileName_m; \
84 throw GeneralClassicException(std::string(__func__), ss.str()); \
87#define GET_NUM_STEPS() \
89 H5call_m = H5GetNumSteps(H5file_m); \
90 if (H5call_m <= H5_ERR) { \
91 std::stringstream ss; \
92 ss << "failed to get number of steps of file " << fileName_m; \
93 throw GeneralClassicException(std::string(__func__), ss.str()); \
96#define SET_NUM_PARTICLES(num) \
98 h5_int64_t h5err = H5PartSetNumParticles(H5file_m, num); \
99 if (h5err <= H5_ERR) { \
100 std::stringstream ss; \
101 ss << "failed to set number of particles to " << num << " in step " << H5call_m \
102 << " in file " << fileName_m; \
103 throw GeneralClassicException(std::string(__func__), ss.str()); \
107#define OPEN_FILE(fname, mode, props) \
109 H5file_m = H5OpenFile(fname, mode, props); \
110 if (H5file_m == (h5_file_t)H5_ERR) { \
111 std::stringstream ss; \
112 ss << "failed to open file " << fileName_m; \
113 throw GeneralClassicException(std::string(__func__), ss.str()); \
116#define CLOSE_FILE() \
118 h5_int64_t h5err = H5CloseFile(H5file_m); \
119 if (h5err <= H5_ERR) { \
120 std::stringstream ss; \
121 ss << "failed to close file " << fileName_m; \
122 throw GeneralClassicException(std::string(__func__), ss.str()); \
128 const std::vector<OpalParticle>& particles,
unsigned int startIdx,
129 unsigned int numParticles, h5_float64_t* buffer,
130 std::function<h5_float64_t(
const OpalParticle&)> select) {
132 particles.begin() + startIdx, particles.begin() + startIdx + numParticles, buffer,
136 const std::vector<OpalParticle>& particles,
unsigned int startIdx,
137 unsigned int numParticles, h5_int64_t* buffer,
138 std::function<h5_int64_t(
const OpalParticle&)> select) {
140 particles.begin() + startIdx, particles.begin() + startIdx + numParticles, buffer,
144 void cminmax(
double&
min,
double&
max,
double val) {
147 }
else if (val >
max) {
179 : h5hut_mode_m(hdf5Save),
183 collectionType_m(collectionType) {
190 "LossDataSink::LossDataSink",
191 "You must select an OPTION to save Loss data files\n"
192 "Please, choose 'ENABLEHDF5=TRUE' or 'ASCIIDUMP=TRUE'");
203 : h5hut_mode_m(rhs.h5hut_mode_m),
204 H5file_m(rhs.H5file_m),
205 outputName_m(rhs.outputName_m),
206 H5call_m(rhs.H5call_m),
207 RefPartR_m(rhs.RefPartR_m),
208 RefPartP_m(rhs.RefPartP_m),
209 globalTrackStep_m(rhs.globalTrackStep_m),
210 refTime_m(rhs.refTime_m),
212 collectionType_m(rhs.collectionType_m) {
227 h5_prop_t props = H5CreateFileProp();
228 MPI_Comm comm =
ippl::Comm->getCommunicator();
229 H5SetPropFileMPIOCollective(props, &comm);
236 std::stringstream OPAL_version;
296 os_m <<
"# x (m), y (m), z (m), px ( ), py ( ), pz ( ), id";
298 os_m <<
", turn ( ), bunchNumber ( )";
306 long long globalTrackStep) {
315 const OpalParticle& particle,
const boost::optional<std::pair<int, short>>& turnBunchNumPair) {
316 if (turnBunchNumPair) {
319 "LossDataSink::addParticle",
320 "Either no particle or all have turn number and bunch number");
339 namespace fs = boost::filesystem;
350 for (
unsigned int i = 0; i < numSets; ++i) {
389 ippl::Comm->reduce(nLoc, nLoc, 1, std::plus<size_t>());
396 ippl::Comm->allreduce(hasTurnInformation, 1, std::logical_or<bool>());
398 return hasTurnInformation > 0;
403 size_t startIdx = 0, endIdx = nLoc;
407 nLoc = endIdx - startIdx;
413 for (
int i = 0; i <
ippl::Comm->size(); i++) {
414 globN[i] = locN[i] = 0;
419 reduce(locN.get(), globN.get(),
ippl::Comm->size(), std::plus<size_t>());
428 if (setIdx <
spos_m.size()) {
456 "68-percentile", (tmpVector = engine.
get68Percentile(), &tmpVector[0]), 3);
458 "95-percentile", (tmpVector = engine.
get95Percentile(), &tmpVector[0]), 3);
460 "99-percentile", (tmpVector = engine.
get99Percentile(), &tmpVector[0]), 3);
465 "normalizedEps68Percentile",
468 "normalizedEps95Percentile",
471 "normalizedEps99Percentile",
474 "normalizedEps99_99Percentile",
481 std::vector<char> buffer(nLoc *
sizeof(h5_float64_t));
482 h5_float64_t* f64buffer = nLoc > 0 ?
reinterpret_cast<h5_float64_t*
>(&buffer[0]) :
nullptr;
483 h5_int64_t* i64buffer = nLoc > 0 ?
reinterpret_cast<h5_int64_t*
>(&buffer[0]) :
nullptr;
486 return particle.
getId();
490 return particle.
getX();
494 return particle.
getY();
498 return particle.
getZ();
502 return particle.
getPx();
506 return particle.
getPy();
510 return particle.
getPz();
648 size_t avgNumPerSet = nLoc / numSets;
649 std::vector<size_t> numPartsInSet(numSets, avgNumPerSet);
650 for (
unsigned int j = 0; j < (nLoc - numSets * avgNumPerSet); ++j) {
655 std::vector<double> data(2 * numSets, 0.0);
656 double* meanT = &data[0];
657 double* numParticles = &data[numSets];
658 std::vector<double> timeRange(numSets, 0.0);
661 for (
unsigned int iteration = 0; iteration < 2; ++iteration) {
663 for (
unsigned int j = 0; j < numSets; ++j) {
664 const size_t& numThisSet = numPartsInSet[j];
665 for (
size_t k = 0; k < numThisSet; ++k, ++partIdx) {
669 numParticles[j] = numThisSet;
672 ippl::Comm->allreduce(&(data[0]), 2 * numSets, std::plus<double>());
674 for (
unsigned int j = 0; j < numSets; ++j) {
675 meanT[j] /= numParticles[j];
678 for (
unsigned int j = 0; j < numSets - 1; ++j) {
679 timeRange[j] = 0.5 * (meanT[j] + meanT[j + 1]);
681 timeRange[numSets - 1] = maxT;
683 std::fill(numPartsInSet.begin(), numPartsInSet.end(), 0);
687 for (
size_t idx = 0; idx < nLoc; ++idx) {
688 if (
particles_m[idx].getTime() > timeRange[setNum]) {
689 numPartsInSet[setNum] = idx - idxPrior;
694 numPartsInSet[numSets - 1] = nLoc - idxPrior;
697 for (
unsigned int i = 0; i < numSets; ++i) {
706 const unsigned int totalSize = 45;
707 double plainData[totalSize];
708 double rminmax[6] = {};
724 unsigned int idx = startIdx;
725 for (
unsigned long k = 0; k < nLoc; ++k, ++idx) {
728 part[0] = particle.
getX();
729 part[1] = particle.
getPx();
730 part[2] = particle.
getY();
731 part[3] = particle.
getPy();
732 part[4] = particle.
getZ();
733 part[5] = particle.
getPz();
735 for (
int i = 0; i < 6; i++) {
736 localCentroid[i] += part[i];
737 for (
int j = 0; j <= i; j++) {
738 localMoments[i * 6 + j] += part[i] * part[j];
741 localOthers[0] += particle.
getTime();
742 localOthers[1] += std::pow(particle.
getTime(), 2);
744 ::cminmax(rminmax[0], rminmax[1], particle.
getX());
745 ::cminmax(rminmax[2], rminmax[3], particle.
getY());
746 ::cminmax(rminmax[4], rminmax[5], particle.
getZ());
749 for (
int i = 0; i < 6; i++) {
750 for (
int j = 0; j < i; j++) {
751 localMoments[j * 6 + i] = localMoments[i * 6 + j];
755 for (
unsigned int i = 0; i < totalSize; ++i) {
756 plainData[i] = data[i].
sum;
759 ippl::Comm->allreduce(plainData, totalSize, std::plus<double>());
760 ippl::Comm->allreduce(rminmax, 6, std::greater<double>());
762 if (plainData[0] == 0.0)
765 double* centroid = plainData + 1;
766 double* moments = plainData + 7;
767 double* others = plainData + 43;
774 stat.
nTotal_m = (
unsigned long)std::round(plainData[0]);
776 for (
unsigned int i = 0; i < 3u; i++) {
780 (moments[2 * i * 6 + 2 * i] - stat.
nTotal_m * std::pow(stat.
rmean_m(i), 2));
783 moments[(2 * i + 1) * 6 + (2 * i) + 1] - stat.
nTotal_m * std::pow(stat.
pmean_m(i), 2));
785 (moments[(2 * i) * 6 + (2 * i) + 1]
797 for (
unsigned int i = 0; i < 3u; i++) {
802 stat.
fac_m(i) = (tmp == 0) ? 0.0 : 1.0 / tmp;
803 stat.
rmin_m(i) = -rminmax[2 * i];
804 stat.
rmax_m(i) = rminmax[2 * i + 1];
#define OPAL_PROJECT_VERSION
#define OPAL_PROJECT_NAME
#define OPEN_FILE(fname, mode, props)
#define WRITE_DATA_FLOAT64(name, value)
#define WRITE_STEPATTRIB_INT64(attribute, value, size)
#define WRITE_FILEATTRIB_STRING(attribute, value)
#define SET_NUM_PARTICLES(num)
#define WRITE_STEPATTRIB_FLOAT64(attribute, value, size)
#define WRITE_DATA_INT64(name, value)
Inform & level2(Inform &inf)
Inform & endl(Inform &inf)
bool enableHDF5
If true HDF5 files are written.
std::string getGitRevision()
KOKKOS_INLINE_FUNCTION Vector< T, Dim > max(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
KOKKOS_INLINE_FUNCTION Vector< T, Dim > min(const Vector< T, Dim > &a, const Vector< T, Dim > &b)
std::unique_ptr< mpi::Communicator > Comm
void checkAndAddOutputFileName(const std::string &outfn)
checks the output file names of all items to avoid duplicates
OpenMode getOpenMode() const
static OpalData * getInstance()
OpenMode
Enum for writing to files.
void setOpenMode(OpenMode openMode)
double getPy() const
Get vertical momentum (no dimension).
double getPz() const
Get relative momentum error (no dimension).
double getY() const
Get vertical displacement in m.
double getCharge() const
Get charge in Coulomb.
double getZ() const
Get longitudinal displacement c*t in m.
double getMass() const
Get mass in GeV/c^2.
double getTime() const
Get time.
int64_t getId() const
Get the id of the particle.
double getPx() const
Get horizontal momentum (no dimension).
double getX() const
Get horizontal position in m.
double getMeanKineticEnergy() const
Vector_t< double, 3 > get68Percentile() const
Vector_t< double, 3 > getMeanMomentum() const
Vector_t< double, 3 > getStandardDeviationPosition() const
Vector_t< double, 3 > getNormalizedEmittance() const
Vector_t< double, 3 > get99_99Percentile() const
double getTotalCharge() const
void compute(const std::vector< OpalParticle >::const_iterator &, const std::vector< OpalParticle >::const_iterator &)
double getStdKineticEnergy() const
Vector_t< double, 3 > getNormalizedEmittance99Percentile() const
Vector_t< double, 3 > getStandardDeviationMomentum() const
Vector_t< double, 3 > getMeanPosition() const
double getStdTime() const
double getTotalMass() const
Vector_t< double, 3 > getNormalizedEmittance99_99Percentile() const
Vector_t< double, 3 > getNormalizedEmittance95Percentile() const
Vector_t< double, 3 > getGeometricEmittance() const
Vector_t< double, 3 > get95Percentile() const
Vector_t< double, 3 > getNormalizedEmittance68Percentile() const
Vector_t< double, 3 > get99Percentile() const
double getMeanTime() const
Vector_t< double, 3 > getMaxR() const
Vector_t< double, 3 > rprms_m
Vector_t< double, 3 > eps2_m
Vector_t< double, 3 > rsqsum_m
Vector_t< double, 3 > RefPartR_m
Vector_t< double, 3 > RefPartP_m
Vector_t< double, 3 > rrms_m
Vector_t< double, 3 > eps_norm_m
Vector_t< double, 3 > rmax_m
Vector_t< double, 3 > prms_m
Vector_t< double, 3 > pmean_m
Vector_t< double, 3 > fac_m
Vector_t< double, 3 > psqsum_m
Vector_t< double, 3 > rpsum_m
Vector_t< double, 3 > rmin_m
Vector_t< double, 3 > rmean_m
std::vector< Vector_t< double, 3 > > RefPartR_m
std::vector< size_t > turnNumber_m
h5_file_t H5file_m
used to write out data in H5hut mode
~LossDataSink() noexcept(false)
std::vector< double > refTime_m
CollectionType collectionType_m
void addReferenceParticle(const Vector_t< double, 3 > &x, const Vector_t< double, 3 > &p, double time, double spos, long long globalTrackStep)
void save(unsigned int numSets=1, OpalData::OpenMode openMode=OpalData::OpenMode::UNDEFINED)
h5_int64_t H5call_m
Current record, or time step, of H5 file.
std::vector< size_t > bunchNumber_m
std::vector< double > spos_m
void addParticle(const OpalParticle &, const boost::optional< std::pair< int, short int > > &turnBunchNumPair=boost::none)
void openH5(h5_int32_t mode=H5_O_WRONLY)
SetStatistics computeSetStatistics(unsigned int setIdx)
void splitSets(unsigned int numSets)
In Opal-T monitors can be traversed several times.
std::vector< OpalParticle > particles_m
bool hasTurnInformations() const
std::vector< Vector_t< double, 3 > > RefPartP_m
void saveH5(unsigned int setIdx)
std::vector< h5_int64_t > globalTrackStep_m
bool hasNoParticlesToDump() const
std::vector< unsigned long > startSet_m