35 #define WRITE_FILEATTRIB_STRING(attribute, value) \
37 h5_int64_t h5err = H5WriteFileAttribString(H5file_m, attribute, value); \
38 if (h5err <= H5_ERR) { \
39 std::stringstream ss; \
40 ss << "failed to write string attribute " << attribute << " to file " << fileName_m; \
41 throw GeneralClassicException(std::string(__func__), ss.str()); \
44 #define WRITE_STEPATTRIB_FLOAT64(attribute, value, size) \
46 h5_int64_t h5err = H5WriteStepAttribFloat64(H5file_m, attribute, value, size); \
47 if (h5err <= H5_ERR) { \
48 std::stringstream ss; \
49 ss << "failed to write float64 attribute " << attribute << " to file " << fileName_m; \
50 throw GeneralClassicException(std::string(__func__), ss.str()); \
53 #define WRITE_STEPATTRIB_INT64(attribute, value, size) \
55 h5_int64_t h5err = H5WriteStepAttribInt64(H5file_m, attribute, value, size); \
56 if (h5err <= H5_ERR) { \
57 std::stringstream ss; \
58 ss << "failed to write int64 attribute " << attribute << " to file " << fileName_m; \
59 throw GeneralClassicException(std::string(__func__), ss.str()); \
62 #define WRITE_DATA_FLOAT64(name, value) \
64 h5_int64_t h5err = H5PartWriteDataFloat64(H5file_m, name, value); \
65 if (h5err <= H5_ERR) { \
66 std::stringstream ss; \
67 ss << "failed to write float64 data " << name << " to file " << fileName_m; \
68 throw GeneralClassicException(std::string(__func__), ss.str()); \
71 #define WRITE_DATA_INT64(name, value) \
73 h5_int64_t h5err = H5PartWriteDataInt64(H5file_m, name, value); \
74 if (h5err <= H5_ERR) { \
75 std::stringstream ss; \
76 ss << "failed to write int64 data " << name << " to file " << fileName_m; \
77 throw GeneralClassicException(std::string(__func__), ss.str()); \
82 h5_int64_t h5err = H5SetStep(H5file_m, H5call_m); \
83 if (h5err <= H5_ERR) { \
84 std::stringstream ss; \
85 ss << "failed to set step " << H5call_m << " in file " << fileName_m; \
86 throw GeneralClassicException(std::string(__func__), ss.str()); \
89 #define GET_NUM_STEPS() \
91 H5call_m = H5GetNumSteps(H5file_m); \
92 if (H5call_m <= H5_ERR) { \
93 std::stringstream ss; \
94 ss << "failed to get number of steps of file " << fileName_m; \
95 throw GeneralClassicException(std::string(__func__), ss.str()); \
98 #define SET_NUM_PARTICLES(num) \
100 h5_int64_t h5err = H5PartSetNumParticles(H5file_m, num); \
101 if (h5err <= H5_ERR) { \
102 std::stringstream ss; \
103 ss << "failed to set number of particles to " << num << " in step " << H5call_m \
104 << " in file " << fileName_m; \
105 throw GeneralClassicException(std::string(__func__), ss.str()); \
109 #define OPEN_FILE(fname, mode, props) \
111 H5file_m = H5OpenFile(fname, mode, props); \
112 if (H5file_m == (h5_file_t)H5_ERR) { \
113 std::stringstream ss; \
114 ss << "failed to open file " << fileName_m; \
115 throw GeneralClassicException(std::string(__func__), ss.str()); \
118 #define CLOSE_FILE() \
120 h5_int64_t h5err = H5CloseFile(H5file_m); \
121 if (h5err <= H5_ERR) { \
122 std::stringstream ss; \
123 ss << "failed to close file " << fileName_m; \
124 throw GeneralClassicException(std::string(__func__), ss.str()); \
130 const std::vector<OpalParticle>& particles,
unsigned int startIdx,
131 unsigned int numParticles, h5_float64_t* buffer,
134 particles.begin() + startIdx, particles.begin() + startIdx + numParticles, buffer,
138 const std::vector<OpalParticle>& particles,
unsigned int startIdx,
139 unsigned int numParticles, h5_int64_t* buffer,
142 particles.begin() + startIdx, particles.begin() + startIdx + numParticles, buffer,
146 void cminmax(
double&
min,
double&
max,
double val) {
149 }
else if (val > max) {
181 : h5hut_mode_m(hdf5Save),
185 collectionType_m(collectionType) {
192 "LossDataSink::LossDataSink",
193 "You must select an OPTION to save Loss data files\n"
194 "Please, choose 'ENABLEHDF5=TRUE' or 'ASCIIDUMP=TRUE'");
205 : h5hut_mode_m(rhs.h5hut_mode_m),
206 H5file_m(rhs.H5file_m),
207 outputName_m(rhs.outputName_m),
208 H5call_m(rhs.H5call_m),
209 RefPartR_m(rhs.RefPartR_m),
210 RefPartP_m(rhs.RefPartP_m),
211 globalTrackStep_m(rhs.globalTrackStep_m),
212 refTime_m(rhs.refTime_m),
214 collectionType_m(rhs.collectionType_m) {
228 h5_prop_t props = H5CreateFileProp();
230 H5SetPropFileMPIOCollective(props, &comm);
237 std::stringstream OPAL_version;
297 os_m <<
"# x (m), y (m), z (m), px ( ), py ( ), pz ( ), id";
299 os_m <<
", turn ( ), bunchNumber ( )";
306 const Vector_t& x,
const Vector_t& p,
double time,
double spos,
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 = std::filesystem;
350 for (
unsigned int i = 0; i < numSets; ++i) {
376 spos_m = std::vector<double>();
379 RefPartR_m = std::vector<Vector_t>();
400 allreduce(hasTurnInformation, 1, std::logical_or<bool>());
402 return hasTurnInformation > 0;
407 size_t startIdx = 0, endIdx = nLoc;
411 nLoc = endIdx - startIdx;
418 globN[i] = locN[i] = 0;
431 if (setIdx <
spos_m.size()) {
443 "RMSX", (tmpVector = engine.getStandardDeviationPosition(), &tmpVector[0]), 3);
446 "RMSP", (tmpVector = engine.getStandardDeviationMomentum(), &tmpVector[0]), 3);
448 "#varepsilon", (tmpVector = engine.getNormalizedEmittance(), &tmpVector[0]), 3);
450 "#varepsilon-geom", (tmpVector = engine.getGeometricEmittance(), &tmpVector[0]), 3);
459 "68-percentile", (tmpVector = engine.get68Percentile(), &tmpVector[0]), 3);
461 "95-percentile", (tmpVector = engine.get95Percentile(), &tmpVector[0]), 3);
463 "99-percentile", (tmpVector = engine.get99Percentile(), &tmpVector[0]), 3);
465 "99_99-percentile", (tmpVector = engine.get99_99Percentile(), &tmpVector[0]), 3);
468 "normalizedEps68Percentile",
469 (tmpVector = engine.getNormalizedEmittance68Percentile(), &tmpVector[0]), 3);
471 "normalizedEps95Percentile",
472 (tmpVector = engine.getNormalizedEmittance95Percentile(), &tmpVector[0]), 3);
474 "normalizedEps99Percentile",
475 (tmpVector = engine.getNormalizedEmittance99Percentile(), &tmpVector[0]), 3);
477 "normalizedEps99_99Percentile",
478 (tmpVector = engine.getNormalizedEmittance99_99Percentile(), &tmpVector[0]), 3);
484 std::vector<char> buffer(nLoc *
sizeof(h5_float64_t));
485 h5_float64_t* f64buffer = nLoc > 0 ?
reinterpret_cast<h5_float64_t*
>(&buffer[0]) :
nullptr;
486 h5_int64_t* i64buffer = nLoc > 0 ?
reinterpret_cast<h5_int64_t*
>(&buffer[0]) :
nullptr;
489 return particle.
getId();
493 return particle.
getX();
497 return particle.
getY();
501 return particle.
getZ();
505 return particle.
getPx();
509 return particle.
getPy();
513 return particle.
getPz();
552 for (
unsigned i = 0; i < partCount; i++) {
569 while (notReceived > 0) {
570 unsigned dataBlocks = 0;
574 ERRORMSG(
"LossDataSink: Could not receive from client nodes output." <<
endl);
577 rmsg->
get(&dataBlocks);
579 for (
unsigned i = 0; i < dataBlocks; i++) {
581 size_t bunchNum, turn;
582 double rx, ry, rz, px, py, pz, time;
584 os_m << (rmsg->
get(&rx), rx) <<
" ";
585 os_m << (rmsg->
get(&ry), ry) <<
" ";
586 os_m << (rmsg->
get(&rz), rz) <<
" ";
587 os_m << (rmsg->
get(&px), px) <<
" ";
588 os_m << (rmsg->
get(&py), py) <<
" ";
589 os_m << (rmsg->
get(&pz), pz) <<
" ";
590 os_m << (rmsg->
get(&
id), id) <<
" ";
592 os_m << (rmsg->
get(&turn), turn) <<
" ";
593 os_m << (rmsg->
get(&bunchNum), bunchNum) <<
" ";
604 for (
unsigned i = 0; i < msgsize; i++) {
621 ERRORMSG(
"LossDataSink Ippl::Comm->send(smsg, 0, tag) failed " <<
endl);
650 size_t avgNumPerSet = nLoc / numSets;
651 std::vector<size_t> numPartsInSet(numSets, avgNumPerSet);
652 for (
unsigned int j = 0; j < (nLoc - numSets * avgNumPerSet); ++j) {
657 std::vector<double> data(2 * numSets, 0.0);
658 double* meanT = &data[0];
659 double* numParticles = &data[numSets];
660 std::vector<double> timeRange(numSets, 0.0);
663 for (
unsigned int iteration = 0; iteration < 2; ++iteration) {
665 for (
unsigned int j = 0; j < numSets; ++j) {
666 const size_t& numThisSet = numPartsInSet[j];
667 for (
size_t k = 0; k < numThisSet; ++k, ++partIdx) {
671 numParticles[j] = numThisSet;
674 allreduce(&(data[0]), 2 * numSets, std::plus<double>());
676 for (
unsigned int j = 0; j < numSets; ++j) {
677 meanT[j] /= numParticles[j];
680 for (
unsigned int j = 0; j < numSets - 1; ++j) {
681 timeRange[j] = 0.5 * (meanT[j] + meanT[j + 1]);
683 timeRange[numSets - 1] = maxT;
685 std::fill(numPartsInSet.begin(), numPartsInSet.end(), 0);
689 for (
size_t idx = 0; idx < nLoc; ++idx) {
690 if (
particles_m[idx].getTime() > timeRange[setNum]) {
691 numPartsInSet[setNum] = idx - idxPrior;
696 numPartsInSet[numSets - 1] = nLoc - idxPrior;
699 for (
unsigned int i = 0; i < numSets; ++i) {
708 const unsigned int totalSize = 45;
709 double plainData[totalSize];
710 double rminmax[6] = {};
726 unsigned int idx = startIdx;
727 for (
unsigned long k = 0; k < nLoc; ++k, ++idx) {
730 part[0] = particle.
getX();
731 part[1] = particle.
getPx();
732 part[2] = particle.
getY();
733 part[3] = particle.
getPy();
734 part[4] = particle.
getZ();
735 part[5] = particle.
getPz();
737 for (
int i = 0; i < 6; i++) {
738 localCentroid[i] += part[i];
739 for (
int j = 0; j <= i; j++) {
740 localMoments[i * 6 + j] += part[i] * part[j];
743 localOthers[0] += particle.
getTime();
746 ::cminmax(rminmax[0], rminmax[1], particle.
getX());
747 ::cminmax(rminmax[2], rminmax[3], particle.
getY());
748 ::cminmax(rminmax[4], rminmax[5], particle.
getZ());
751 for (
int i = 0; i < 6; i++) {
752 for (
int j = 0; j < i; j++) {
753 localMoments[j * 6 + i] = localMoments[i * 6 + j];
757 for (
unsigned int i = 0; i < totalSize; ++i) {
758 plainData[i] = data[i].
sum;
761 allreduce(plainData, totalSize, std::plus<double>());
762 allreduce(rminmax, 6, std::greater<double>());
764 if (plainData[0] == 0.0)
767 double* centroid = plainData + 1;
768 double* moments = plainData + 7;
769 double* others = plainData + 43;
776 stat.
nTotal_m = (
unsigned long)std::round(plainData[0]);
778 for (
unsigned int i = 0; i < 3u; i++) {
787 (moments[(2 * i) * 6 + (2 * i) + 1]
799 for (
unsigned int i = 0; i < 3u; i++) {
804 stat.
fac_m(i) = (tmp == 0) ? 0.0 : 1.0 / tmp;
805 stat.
rmin_m(i) = -rminmax[2 * i];
806 stat.
rmax_m(i) = rminmax[2 * i + 1];
void setOpenMode(OpenMode openMode)
static OpalData * getInstance()
Tps< T > sqrt(const Tps< T > &x)
Square root.
double getPx() const
Get horizontal momentum (no dimension).
Message & put(const T &val)
and give any other recipients of the Program a copy of this License along with the Program You may charge a fee for the physical act of transferring a copy
SetStatistics computeSetStatistics(unsigned int setIdx)
std::vector< size_t > bunchNumber_m
bool hasNoParticlesToDump() const
bool enableHDF5
If true HDF5 files are written.
#define OPAL_PROJECT_VERSION
Message * receive_block(int &node, int &tag)
#define WRITE_STEPATTRIB_INT64(attribute, value, size)
static MPI_Comm getComm()
std::string getGitRevision()
#define WRITE_DATA_FLOAT64(name, value)
void addReferenceParticle(const Vector_t &x, const Vector_t &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.
void addParticle(const OpalParticle &, const boost::optional< std::pair< int, short int >> &turnBunchNumPair=boost::none)
int next_tag(int t, int s=1000)
#define OPAL_PROJECT_NAME
std::vector< h5_int64_t > globalTrackStep_m
std::vector< double > refTime_m
Message & get(const T &cval)
void checkAndAddOutputFileName(const std::string &outfn)
checks the output file names of all items to avoid duplicates
double getPy() const
Get vertical momentum (no dimension).
h5_file_t H5file_m
used to write out data in H5hut mode
Inform & endl(Inform &inf)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
#define SET_NUM_PARTICLES(num)
double getTime() const
Get time.
std::vector< Vector_t > RefPartR_m
if write to the Free Software Temple MA USA Also add information on how to contact you by electronic and paper mail If the program is make it output a short notice like this when it starts in an interactive mode
static Communicate * Comm
double getPz() const
Get relative momentum error (no dimension).
#define WRITE_DATA_INT64(name, value)
double getZ() const
Get longitudinal displacement c*t in m.
std::vector< OpalParticle > particles_m
double function(PyOpalObjectNS::PyOpalObject< C > pyobject, double t)
void allreduce(const T *input, T *output, int count, Op op)
void saveH5(unsigned int setIdx)
void splitSets(unsigned int numSets)
OpenMode
Enum for writing to files.
bool send(Message *, int node, int tag, bool delmsg=true)
OpenMode getOpenMode() const
bool hasTurnInformations() const
double getY() const
Get vertical displacement in m.
std::vector< double > spos_m
double getMass() const
Get mass in GeV/c^2.
void openH5(h5_int32_t mode=H5_O_WRONLY)
#define OPEN_FILE(fname, mode, props)
std::vector< size_t > turnNumber_m
int64_t getId() const
Get the id of the particle.
Inform & level2(Inform &inf)
void compute(const std::vector< OpalParticle >::const_iterator &, const std::vector< OpalParticle >::const_iterator &)
std::vector< unsigned long > startSet_m
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
#define WRITE_STEPATTRIB_FLOAT64(attribute, value, size)
std::vector< Vector_t > RefPartP_m
CollectionType collectionType_m
#define WRITE_FILEATTRIB_STRING(attribute, value)
double getX() const
Get horizontal position in m.
~LossDataSink() noexcept(false)
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
double getCharge() const
Get charge in Coulomb.