29#include <boost/filesystem.hpp>
35#define WRITE_FILEATTRIB_STRING( attribute, value ) { \
36 h5_int64_t h5err = H5WriteFileAttribString (H5file_m, attribute, value); \
37 if (h5err <= H5_ERR) { \
38 std::stringstream ss; \
39 ss << "failed to write string attribute " << attribute << " to file " << fileName_m; \
40 throw GeneralClassicException(std::string(__func__), ss.str()); \
43#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 ) { \
52 h5_int64_t h5err = H5WriteStepAttribInt64 (H5file_m, attribute, value, size); \
53 if (h5err <= H5_ERR) { \
54 std::stringstream ss; \
55 ss << "failed to write int64 attribute " << attribute << " to file " << fileName_m; \
56 throw GeneralClassicException(std::string(__func__), ss.str()); \
59#define WRITE_DATA_FLOAT64( name, value ) { \
60 h5_int64_t h5err = H5PartWriteDataFloat64 (H5file_m, name, value); \
61 if (h5err <= H5_ERR) { \
62 std::stringstream ss; \
63 ss << "failed to write float64 data " << name << " to file " << fileName_m; \
64 throw GeneralClassicException(std::string(__func__), ss.str()); \
67#define WRITE_DATA_INT64( name, value ) { \
68 h5_int64_t h5err = H5PartWriteDataInt64 (H5file_m, name, value); \
69 if (h5err <= H5_ERR) { \
70 std::stringstream ss; \
71 ss << "failed to write int64 data " << name << " to file " << fileName_m; \
72 throw GeneralClassicException(std::string(__func__), ss.str()); \
76 h5_int64_t h5err = H5SetStep (H5file_m, H5call_m); \
77 if (h5err <= H5_ERR) { \
78 std::stringstream ss; \
79 ss << "failed to set step " << H5call_m << " in file " << fileName_m; \
80 throw GeneralClassicException(std::string(__func__), ss.str()); \
83#define GET_NUM_STEPS() { \
84 H5call_m = H5GetNumSteps( H5file_m ); \
85 if (H5call_m <= H5_ERR) { \
86 std::stringstream ss; \
87 ss << "failed to get number of steps of file " << fileName_m; \
88 throw GeneralClassicException(std::string(__func__), ss.str()); \
91#define SET_NUM_PARTICLES( num ) { \
92 h5_int64_t h5err = H5PartSetNumParticles (H5file_m, num); \
93 if (h5err <= H5_ERR) { \
94 std::stringstream ss; \
95 ss << "failed to set number of particles to " << num << " in step " << H5call_m << " in file " << fileName_m; \
96 throw GeneralClassicException(std::string(__func__), ss.str()); \
100#define OPEN_FILE( fname, mode, props ) { \
101 H5file_m = H5OpenFile (fname, mode, props); \
102 if (H5file_m == (h5_file_t)H5_ERR) { \
103 std::stringstream ss; \
104 ss << "failed to open file " << fileName_m; \
105 throw GeneralClassicException(std::string(__func__), ss.str()); \
108#define CLOSE_FILE() { \
109 h5_int64_t h5err = H5CloseFile (H5file_m); \
110 if (h5err <= H5_ERR) { \
111 std::stringstream ss; \
112 ss << "failed to close file " << fileName_m; \
113 throw GeneralClassicException(std::string(__func__), ss.str()); \
118 void f64transform(
const std::vector<OpalParticle> &particles,
119 unsigned int startIdx,
120 unsigned int numParticles,
121 h5_float64_t *buffer,
123 std::transform(particles.begin() + startIdx,
124 particles.begin() + startIdx + numParticles,
127 void i64transform(
const std::vector<OpalParticle> &particles,
128 unsigned int startIdx,
129 unsigned int numParticles,
132 std::transform(particles.begin() + startIdx,
133 particles.begin() + startIdx + numParticles,
137 void cminmax(
double &
min,
double &
max,
double val) {
140 }
else if (val >
max) {
172 h5hut_mode_m(hdf5Save),
176 collectionType_m(collectionType)
184 "LossDataSink::LossDataSink",
185 "You must select an OPTION to save Loss data files\n"
186 "Please, choose 'ENABLEHDF5=TRUE' or 'ASCIIDUMP=TRUE'");
197 h5hut_mode_m(rhs.h5hut_mode_m),
198 H5file_m(rhs.H5file_m),
199 outputName_m(rhs.outputName_m),
200 H5call_m(rhs.H5call_m),
201 RefPartR_m(rhs.RefPartR_m),
202 RefPartP_m(rhs.RefPartP_m),
203 globalTrackStep_m(rhs.globalTrackStep_m),
204 refTime_m(rhs.refTime_m),
206 collectionType_m(rhs.collectionType_m)
221 h5_prop_t props = H5CreateFileProp ();
223 H5SetPropFileMPIOCollective (props, &comm);
232 std::stringstream OPAL_version;
292 os_m <<
"# x (m), y (m), z (m), px ( ), py ( ), pz ( ), id";
294 os_m <<
", turn ( ), bunchNumber ( )";
304 long long globalTrackStep
314 if (turnBunchNumPair) {
317 "Either no particle or all have turn number and bunch number");
335 namespace fs = boost::filesystem;
346 for (
unsigned int i = 0; i < numSets; ++ i) {
396 allreduce(hasTurnInformation, 1, std::logical_or<bool>());
398 return hasTurnInformation > 0;
403 size_t startIdx = 0, endIdx = nLoc;
407 nLoc = endIdx - startIdx;
414 globN[i] = locN[i] = 0;
427 if (setIdx <
spos_m.size()) {
468 std::vector<char> buffer(nLoc *
sizeof(h5_float64_t));
469 h5_float64_t *f64buffer = nLoc > 0?
reinterpret_cast<h5_float64_t*
>(&buffer[0]) :
nullptr;
470 h5_int64_t *i64buffer = nLoc > 0?
reinterpret_cast<h5_int64_t*
>(&buffer[0]) :
nullptr;
472 ::i64transform(
particles_m, startIdx, nLoc, i64buffer,
475 ::f64transform(
particles_m, startIdx, nLoc, f64buffer,
478 ::f64transform(
particles_m, startIdx, nLoc, f64buffer,
481 ::f64transform(
particles_m, startIdx, nLoc, f64buffer,
484 ::f64transform(
particles_m, startIdx, nLoc, f64buffer,
487 ::f64transform(
particles_m, startIdx, nLoc, f64buffer,
490 ::f64transform(
particles_m, startIdx, nLoc, f64buffer,
493 ::f64transform(
particles_m, startIdx, nLoc, f64buffer,
496 ::f64transform(
particles_m, startIdx, nLoc, f64buffer,
512 ::f64transform(
particles_m, startIdx, nLoc, f64buffer,
529 for (
unsigned i = 0; i < partCount; i++) {
547 while (notReceived > 0) {
548 unsigned dataBlocks = 0;
552 ERRORMSG(
"LossDataSink: Could not receive from client nodes output." <<
endl);
555 rmsg->
get(&dataBlocks);
557 for (
unsigned i = 0; i < dataBlocks; i++) {
559 size_t bunchNum, turn;
560 double rx, ry, rz, px, py, pz, time;
562 os_m << (rmsg->
get(&rx), rx) <<
" ";
563 os_m << (rmsg->
get(&ry), ry) <<
" ";
564 os_m << (rmsg->
get(&rz), rz) <<
" ";
565 os_m << (rmsg->
get(&px), px) <<
" ";
566 os_m << (rmsg->
get(&py), py) <<
" ";
567 os_m << (rmsg->
get(&pz), pz) <<
" ";
568 os_m << (rmsg->
get(&
id), id) <<
" ";
570 os_m << (rmsg->
get(&turn), turn) <<
" ";
571 os_m << (rmsg->
get(&bunchNum), bunchNum) <<
" ";
573 os_m << (rmsg->
get(&time), time)
583 for (
unsigned i = 0; i < msgsize; i++) {
600 ERRORMSG(
"LossDataSink Ippl::Comm->send(smsg, 0, tag) failed " <<
endl);
629 size_t avgNumPerSet = nLoc / numSets;
630 std::vector<size_t> numPartsInSet(numSets, avgNumPerSet);
631 for (
unsigned int j = 0; j < (nLoc - numSets * avgNumPerSet); ++ j) {
636 std::vector<double> data(2 * numSets, 0.0);
637 double* meanT = &data[0];
638 double* numParticles = &data[numSets];
639 std::vector<double> timeRange(numSets, 0.0);
642 for (
unsigned int iteration = 0; iteration < 2; ++ iteration) {
644 for (
unsigned int j = 0; j < numSets; ++ j) {
646 const size_t &numThisSet = numPartsInSet[j];
647 for (
size_t k = 0; k < numThisSet; ++ k, ++ partIdx) {
651 numParticles[j] = numThisSet;
654 allreduce(&(data[0]), 2 * numSets, std::plus<double>());
656 for (
unsigned int j = 0; j < numSets; ++ j) {
657 meanT[j] /= numParticles[j];
660 for (
unsigned int j = 0; j < numSets - 1; ++ j) {
661 timeRange[j] = 0.5 * (meanT[j] + meanT[j + 1]);
663 timeRange[numSets - 1] = maxT;
665 std::fill(numPartsInSet.begin(),
671 for (
size_t idx = 0; idx < nLoc; ++ idx) {
672 if (
particles_m[idx].getTime() > timeRange[setNum]) {
673 numPartsInSet[setNum] = idx - idxPrior;
678 numPartsInSet[numSets - 1] = nLoc - idxPrior;
681 for (
unsigned int i = 0; i < numSets; ++ i) {
690 const unsigned int totalSize = 45;
691 double plainData[totalSize];
692 double rminmax[6] = {};
708 unsigned int idx = startIdx;
709 for (
unsigned long k = 0; k < nLoc; ++ k, ++ idx) {
712 part[0] = particle.
getX();
713 part[1] = particle.
getPx();
714 part[2] = particle.
getY();
715 part[3] = particle.
getPy();
716 part[4] = particle.
getZ();
717 part[5] = particle.
getPz();
719 for (
int i = 0; i < 6; i++) {
720 localCentroid[i] += part[i];
721 for (
int j = 0; j <= i; j++) {
722 localMoments[i * 6 + j] += part[i] * part[j];
725 localOthers[0] += particle.
getTime();
728 ::cminmax(rminmax[0], rminmax[1], particle.
getX());
729 ::cminmax(rminmax[2], rminmax[3], particle.
getY());
730 ::cminmax(rminmax[4], rminmax[5], particle.
getZ());
733 for (
int i = 0; i < 6; i++) {
734 for (
int j = 0; j < i; j++) {
735 localMoments[j * 6 + i] = localMoments[i * 6 + j];
739 for (
unsigned int i = 0; i < totalSize; ++ i) {
740 plainData[i] = data[i].
sum;
743 allreduce(plainData, totalSize, std::plus<double>());
744 allreduce(rminmax, 6, std::greater<double>());
746 if (plainData[0] == 0.0)
return stat;
748 double *centroid = plainData + 1;
749 double *moments = plainData + 7;
750 double *others = plainData + 43;
757 stat.
nTotal_m = (
unsigned long)std::round(plainData[0]);
759 for (
unsigned int i = 0 ; i < 3u; i++) {
762 stat.
rsqsum_m(i) = (moments[2 * i * 6 + 2 * i] -
765 moments[(2 * i + 1) * 6 + (2 * i) + 1] -
767 stat.
rpsum_m(i) = (moments[(2 * i) * 6 + (2 * i) + 1] -
778 for (
unsigned int i = 0 ; i < 3u; i++) {
783 stat.
fac_m(i) = (tmp == 0) ? 0.0 : 1.0 / tmp;
784 stat.
rmin_m(i) = -rminmax[2 * i];
785 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)
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Tps< T > sqrt(const Tps< T > &x)
Square root.
void allreduce(const T *input, T *output, int count, Op op)
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Inform & level2(Inform &inf)
Inform & endl(Inform &inf)
py::list function(PolynomialPatch *patch, py::list point)
bool enableHDF5
If true HDF5 files are written.
std::string getGitRevision()
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)
Vector_t getStandardDeviationMomentum() const
Vector_t get99Percentile() const
double getMeanKineticEnergy() const
Vector_t getStandardDeviationPosition() const
Vector_t getNormalizedEmittance95Percentile() const
Vector_t getNormalizedEmittance68Percentile() const
double getTotalCharge() const
Vector_t getNormalizedEmittance99_99Percentile() const
Vector_t getNormalizedEmittance99Percentile() const
Vector_t getMeanPosition() const
Vector_t get99_99Percentile() const
void compute(const std::vector< OpalParticle >::const_iterator &, const std::vector< OpalParticle >::const_iterator &)
double getStdKineticEnergy() const
Vector_t getNormalizedEmittance() const
double getStdTime() const
double getTotalMass() const
Vector_t getMeanMomentum() const
Vector_t get95Percentile() const
Vector_t get68Percentile() const
double getMeanTime() const
Vector_t getGeometricEmittance() const
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.
std::vector< size_t > turnNumber_m
std::vector< Vector_t > RefPartR_m
void addReferenceParticle(const Vector_t &x, const Vector_t &p, double time, double spos, long long globalTrackStep)
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 save(unsigned int numSets=1, OpalData::OpenMode openMode=OpalData::OpenMode::UNDEFINED)
std::vector< Vector_t > RefPartP_m
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)
std::vector< OpalParticle > particles_m
bool hasTurnInformations() const
void saveH5(unsigned int setIdx)
std::vector< h5_int64_t > globalTrackStep_m
bool hasNoParticlesToDump() const
std::vector< unsigned long > startSet_m
bool send(Message *, int node, int tag, bool delmsg=true)
Message * receive_block(int &node, int &tag)
Message & put(const T &val)
Message & get(const T &cval)
int next_tag(int t, int s=1000)
static MPI_Comm getComm()
static Communicate * Comm