LCOV - code coverage report
Current view: top level - src/module - TextOutput.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 219 249 88.0 %
Date: 2024-04-29 14:43:01 Functions: 9 14 64.3 %

          Line data    Source code
       1             : #include "crpropa/module/TextOutput.h"
       2             : #include "crpropa/module/ParticleCollector.h"
       3             : #include "crpropa/Units.h"
       4             : #include "crpropa/Version.h"
       5             : #include "crpropa/Random.h"
       6             : #include "crpropa/base64.h"
       7             : 
       8             : #include "kiss/string.h"
       9             : 
      10             : #include <cstdio>
      11             : #include <stdexcept>
      12             : #include <iostream>
      13             : 
      14             : #ifdef CRPROPA_HAVE_ZLIB
      15             : #include <izstream.hpp>
      16             : #include <ozstream.hpp>
      17             : #endif
      18             : 
      19             : namespace crpropa {
      20             : 
      21           0 : TextOutput::TextOutput() : Output(), out(&std::cout), storeRandomSeeds(false) {
      22           0 : }
      23             : 
      24           7 : TextOutput::TextOutput(OutputType outputtype) : Output(outputtype), out(&std::cout), storeRandomSeeds(false) {
      25           7 : }
      26             : 
      27           0 : TextOutput::TextOutput(std::ostream &out) : Output(), out(&out), storeRandomSeeds(false) {
      28           0 : }
      29             : 
      30           0 : TextOutput::TextOutput(std::ostream &out,
      31           0 :                 OutputType outputtype) : Output(outputtype), out(&out), storeRandomSeeds(false) {
      32           0 : }
      33             : 
      34           4 : TextOutput::TextOutput(const std::string &filename) :  Output(), outfile(filename.c_str(),
      35           2 :                                 std::ios::binary), out(&outfile),  filename(
      36           4 :                                 filename), storeRandomSeeds(false) {
      37           2 :         if (!outfile.is_open())
      38           2 :                 throw std::runtime_error(std::string("Cannot create file: ") + filename);
      39           3 :         if (kiss::ends_with(filename, ".gz"))
      40           0 :                 gzip();
      41           3 : }
      42             : 
      43           1 : TextOutput::TextOutput(const std::string &filename,
      44           2 :                                 OutputType outputtype) : Output(outputtype), outfile(filename.c_str(),
      45           1 :                                 std::ios::binary), out(&outfile), filename(
      46           2 :                                 filename), storeRandomSeeds(false) {
      47           1 :         if (!outfile.is_open())
      48           0 :                 throw std::runtime_error(std::string("Cannot create file: ") + filename);
      49           2 :         if (kiss::ends_with(filename, ".gz"))
      50           0 :                 gzip();
      51           1 : }
      52             : 
      53           9 : void TextOutput::printHeader() const {
      54           9 :         *out << "#";
      55           9 :         if (fields.test(TrajectoryLengthColumn))
      56           6 :                 *out << "\tD";
      57           9 :         if (fields.test(RedshiftColumn))
      58           2 :                 *out << "\tz";
      59           9 :         if (fields.test(SerialNumberColumn))
      60           3 :                 *out << "\tSN";
      61           9 :         if (fields.test(CurrentIdColumn))
      62           8 :                 *out << "\tID";
      63           9 :         if (fields.test(CurrentEnergyColumn))
      64           8 :                 *out << "\tE";
      65           9 :         if (fields.test(CurrentPositionColumn) && oneDimensional)
      66           2 :                 *out << "\tX";
      67           9 :         if (fields.test(CurrentPositionColumn) && not oneDimensional)
      68           3 :                 *out << "\tX\tY\tZ";
      69           9 :         if (fields.test(CurrentDirectionColumn) && not oneDimensional)
      70           3 :                 *out << "\tPx\tPy\tPz";
      71           9 :         if (fields.test(SerialNumberColumn))
      72           3 :                 *out << "\tSN0";
      73           9 :         if (fields.test(SourceIdColumn))
      74           6 :                 *out << "\tID0";
      75           9 :         if (fields.test(SourceEnergyColumn))
      76           6 :                 *out << "\tE0";
      77           9 :         if (fields.test(SourcePositionColumn) && oneDimensional) 
      78           1 :                 *out << "\tX0";
      79           9 :         if (fields.test(SourcePositionColumn) && not oneDimensional)
      80           2 :                 *out << "\tX0\tY0\tZ0";
      81           9 :         if (fields.test(SourceDirectionColumn) && not oneDimensional)
      82           2 :                 *out << "\tP0x\tP0y\tP0z";
      83           9 :         if (fields.test(SerialNumberColumn))
      84           3 :                 *out << "\tSN1";
      85           9 :         if (fields.test(CreatedIdColumn))
      86           2 :                 *out << "\tID1";
      87           9 :         if (fields.test(CreatedEnergyColumn))
      88           2 :                 *out << "\tE1";
      89           9 :         if (fields.test(CreatedPositionColumn) && oneDimensional)
      90           1 :                 *out << "\tX1";
      91           9 :         if (fields.test(CreatedPositionColumn) && not oneDimensional)
      92           1 :                 *out << "\tX1\tY1\tZ1";
      93           9 :         if (fields.test(CreatedDirectionColumn) && not oneDimensional)
      94           1 :                 *out << "\tP1x\tP1y\tP1z";
      95           9 :         if (fields.test(WeightColumn))
      96           2 :                 *out << "\tW";
      97           9 :         if (fields.test(CandidateTagColumn))
      98           3 :                 *out << "\ttag";
      99           9 :         for(std::vector<Property>::const_iterator iter = properties.begin();
     100          10 :                         iter != properties.end(); ++iter)
     101             :         {
     102           1 :                 *out << "\t" << (*iter).name;
     103             :         }
     104             : 
     105           9 :         *out << "\n#\n";
     106           9 :         if (fields.test(TrajectoryLengthColumn))
     107           6 :                 *out << "# D             Trajectory length [" << lengthScale / Mpc
     108           6 :                                 << " Mpc]\n";
     109           9 :         if (fields.test(RedshiftColumn))
     110           2 :                 *out << "# z             Redshift\n";
     111           9 :         if (fields.test(SerialNumberColumn))
     112           3 :                 *out << "# SN/SN0/SN1    Serial number. Unique (within this run) id of the particle.\n";
     113           1 :         if (fields.test(CurrentIdColumn) || fields.test(CreatedIdColumn)
     114          10 :                         || fields.test(SourceIdColumn))
     115           8 :                 *out << "# ID/ID0/ID1    Particle type (PDG MC numbering scheme)\n";
     116           1 :         if (fields.test(CurrentEnergyColumn) || fields.test(CreatedEnergyColumn)
     117          10 :                         || fields.test(SourceEnergyColumn))
     118           8 :                 *out << "# E/E0/E1       Energy [" << energyScale / EeV << " EeV]\n";
     119           4 :         if (fields.test(CurrentPositionColumn) || fields.test(CreatedPositionColumn)
     120          13 :                         || fields.test(SourcePositionColumn))
     121           5 :                 *out << "# X/X0/X1...    Position [" << lengthScale / Mpc << " Mpc]\n";
     122             :         if (fields.test(CurrentDirectionColumn)
     123           5 :                         || fields.test(CreatedDirectionColumn)
     124          14 :                         || fields.test(SourceDirectionColumn))
     125           4 :                 *out << "# Px/P0x/P1x... Heading (unit vector of momentum)\n";
     126           9 :         if (fields.test(WeightColumn))
     127           2 :                 *out << "# W             Weights" << " \n";
     128           9 :         if (fields.test(CandidateTagColumn)) {
     129           3 :                 *out << "# tag           Candidate tag can be given by the source feature (user defined tag) or by the following interaction process \n";
     130           3 :                 *out << "#\tES  \tElasticScattering \n" << "#\tEPP \tElectronPairProduction \n" << "#\tEMPP\tEMPairProduction\n"
     131             :                         << "#\tEMDP\tEMDoublePairProduction\n" << "#\tEMTP\tEMTripletPairProduction \n" << "#\tEMIC\tEMInverseComptonScattering\n"
     132             :                         << "#\tND  \tNuclearDecay\n" << "#\tPD  \tPhotoDisintegration\n" << "#\tPPP  \tPhotoPionProduction\n" << "#\tSYN \tSynchrotronRadiation\n"
     133           3 :                         << "#\tPRIM/SEC\t primary / secondary particle\n";
     134             :         }
     135           9 :         for(std::vector<Property>::const_iterator iter = properties.begin();
     136          10 :                         iter != properties.end(); ++iter)
     137             :         {
     138           2 :                         *out << "# " << (*iter).name << " " << (*iter).comment << "\n";
     139             :         }
     140             : 
     141           9 :         *out << "# no index = current, 0 = at source, 1 = at point of creation\n#\n";
     142          18 :         *out << "# CRPropa version: " << g_GIT_DESC << "\n#\n";
     143             : 
     144           9 :         if (storeRandomSeeds)
     145             :         {
     146           0 :                 *out << "# Random seeds:\n";
     147           0 :                 std::vector< std::vector<uint32_t> > seeds = Random::getSeedThreads();
     148             : 
     149           0 :                 for (size_t i =0; i < seeds.size(); i++)
     150             :                 {
     151           0 :                         std::string encoded_data = Base64::encode((unsigned char*) &seeds[i][0], sizeof(seeds[i][0]) * seeds[i].size() / sizeof(unsigned char));
     152           0 :                         *out << "#   Thread " << i << ": ";
     153           0 :                         *out << encoded_data;
     154           0 :                         *out << "\n";
     155             :                 }
     156           0 :         }
     157           9 : }
     158             : 
     159          75 : void TextOutput::process(Candidate *c) const {
     160          75 :         if (fields.none() && properties.empty())
     161           0 :                 return;
     162             : 
     163             :         char buffer[1024];
     164             :         size_t p = 0;
     165             : 
     166          75 :         std::locale old_locale = std::locale::global(std::locale::classic());
     167             : 
     168          75 :         if (fields.test(TrajectoryLengthColumn))
     169          72 :                 p += std::sprintf(buffer + p, "%8.5E\t",
     170          72 :                                 c->getTrajectoryLength() / lengthScale);
     171             : 
     172          75 :         if (fields.test(RedshiftColumn))
     173          68 :                 p += std::sprintf(buffer + p, "%1.5E\t", c->getRedshift());
     174             : 
     175          75 :         if (fields.test(SerialNumberColumn))
     176          69 :                 p += std::sprintf(buffer + p, "%10lu\t",
     177             :                                 c->getSerialNumber());
     178          75 :         if (fields.test(CurrentIdColumn))
     179          74 :                 p += std::sprintf(buffer + p, "%10i\t", c->current.getId());
     180          75 :         if (fields.test(CurrentEnergyColumn))
     181          74 :                 p += std::sprintf(buffer + p, "%8.5E\t",
     182          74 :                                 c->current.getEnergy() / energyScale);
     183          75 :         if (fields.test(CurrentPositionColumn)) {
     184          71 :                 if (oneDimensional) {
     185          58 :                         p += std::sprintf(buffer + p, "%8.5E\t",
     186          58 :                                         c->current.getPosition().x / lengthScale);
     187             :                 } else {
     188          13 :                         const Vector3d pos = c->current.getPosition() / lengthScale;
     189          13 :                         p += std::sprintf(buffer + p, "%8.5E\t%8.5E\t%8.5E\t", pos.x, pos.y,
     190             :                                         pos.z);
     191             :                 }
     192             :         }
     193          75 :         if (fields.test(CurrentDirectionColumn)) {
     194          70 :                 if (not oneDimensional) {
     195          13 :                         const Vector3d pos = c->current.getDirection();
     196          13 :                         p += std::sprintf(buffer + p, "%8.5E\t%8.5E\t%8.5E\t", pos.x, pos.y,
     197             :                                         pos.z);
     198             :                 }
     199             :         }
     200             : 
     201          75 :         if (fields.test(SerialNumberColumn))
     202          69 :                 p += std::sprintf(buffer + p, "%10lu\t", c->getSourceSerialNumber());
     203          75 :         if (fields.test(SourceIdColumn))
     204          72 :                 p += std::sprintf(buffer + p, "%10i\t", c->source.getId());
     205          75 :         if (fields.test(SourceEnergyColumn))
     206          72 :                 p += std::sprintf(buffer + p, "%8.5E\t",
     207          72 :                                 c->source.getEnergy() / energyScale);
     208          75 :         if (fields.test(SourcePositionColumn)) {
     209          69 :                 if (oneDimensional) {
     210          57 :                         p += std::sprintf(buffer + p, "%8.5E\t",
     211          57 :                                         c->source.getPosition().x / lengthScale);
     212             :                 } else {
     213          12 :                         const Vector3d pos = c->source.getPosition() / lengthScale;
     214          12 :                         p += std::sprintf(buffer + p, "%8.5E\t%8.5E\t%8.5E\t", pos.x, pos.y,
     215             :                                         pos.z);
     216             :                 }
     217             :         }
     218          75 :         if (fields.test(SourceDirectionColumn)) {
     219          69 :                 if (not oneDimensional) {
     220          12 :                         const Vector3d pos = c->source.getDirection();
     221          12 :                         p += std::sprintf(buffer + p, "%8.5E\t%8.5E\t%8.5E\t", pos.x, pos.y,
     222             :                                         pos.z);
     223             :                 }
     224             : 
     225             :         }
     226             : 
     227          75 :         if (fields.test(SerialNumberColumn))
     228          69 :                 p += std::sprintf(buffer + p, "%10lu\t",
     229             :                                 c->getCreatedSerialNumber());
     230          75 :         if (fields.test(CreatedIdColumn))
     231          68 :                 p += std::sprintf(buffer + p, "%10i\t", c->created.getId());
     232          75 :         if (fields.test(CreatedEnergyColumn))
     233          68 :                 p += std::sprintf(buffer + p, "%8.5E\t",
     234          68 :                                 c->created.getEnergy() / energyScale);
     235          75 :         if (fields.test(CreatedPositionColumn)) {
     236          68 :                 if (oneDimensional) {
     237          57 :                         p += std::sprintf(buffer + p, "%8.5E\t",
     238          57 :                                         c->created.getPosition().x / lengthScale);
     239             :                 } else {
     240          11 :                         const Vector3d pos = c->created.getPosition() / lengthScale;
     241          11 :                         p += std::sprintf(buffer + p, "%8.5E\t%8.5E\t%8.5E\t", pos.x, pos.y,
     242             :                                         pos.z);
     243             :                 }
     244             :         }
     245          75 :         if (fields.test(CreatedDirectionColumn)) {
     246          68 :                 if (not oneDimensional) {
     247          11 :                         const Vector3d pos = c->created.getDirection();
     248          11 :                         p += std::sprintf(buffer + p, "%8.5E\t%8.5E\t%8.5E\t", pos.x, pos.y,
     249             :                                         pos.z);
     250             :                 }
     251             :         }
     252          75 :         if (fields.test(WeightColumn)) {
     253          68 :                 p += std::sprintf(buffer + p, "%8.5E\t", c->getWeight());
     254             :         }
     255          75 :         if (fields.test(CandidateTagColumn)) {
     256          69 :                 p += std::sprintf(buffer + p, "%s\t", c->getTagOrigin().c_str());
     257             :         }
     258             : 
     259          75 :         for(std::vector<Output::Property>::const_iterator iter = properties.begin();
     260          76 :                         iter != properties.end(); ++iter) {
     261           1 :                   Variant v;
     262           1 :                         if (c->hasProperty((*iter).name)) {
     263           0 :                                 v = c->getProperty((*iter).name);
     264             :                         } else {
     265           1 :                                 v = (*iter).defaultValue;
     266             :                         }
     267           1 :                         p += std::sprintf(buffer + p, "%s", v.toString("\t").c_str());
     268           1 :                         p += std::sprintf(buffer + p, "\t");
     269           1 :         }
     270          75 :         buffer[p - 1] = '\n';
     271             : 
     272          75 :         std::locale::global(old_locale);
     273             : 
     274         150 : #pragma omp critical
     275             :         {
     276          75 :                 if (count == 0)
     277           9 :                         printHeader();
     278          75 :                 Output::process(c);
     279          75 :                 out->write(buffer, p);
     280             :         }
     281             : 
     282          75 : }
     283             : 
     284           1 : void TextOutput::load(const std::string &filename, ParticleCollector *collector){
     285             : 
     286             :         std::string line;
     287             :         std::istream *in;
     288           1 :         std::ifstream infile(filename.c_str());
     289             :         
     290             :         double lengthScale = Mpc; // default Mpc
     291             :         double energyScale = EeV; // default EeV
     292             : 
     293           1 :         if (!infile.good())
     294           0 :                 throw std::runtime_error("crpropa::TextOutput: could not open file " + filename);
     295             :         in = &infile;
     296             :         
     297           2 :         if (kiss::ends_with(filename, ".gz")){
     298             : #ifdef CRPROPA_HAVE_ZLIB
     299           0 :                 in = new zstream::igzstream(*in);
     300             : #else
     301             :                 throw std::runtime_error("CRPropa was built without Zlib compression!");
     302             : #endif
     303             :         }
     304             : 
     305          38 :         while (std::getline(*in, line)) {
     306          37 :                 std::stringstream stream(line);
     307          37 :                 if (stream.peek() == '#')
     308             :                         continue;
     309             : 
     310          22 :                 ref_ptr<Candidate> c = new Candidate(); 
     311             :                 double val_d; int val_i;
     312             :                 double x, y, z;
     313             :                 stream >> val_d;
     314          11 :                 c->setTrajectoryLength(val_d*lengthScale); // D
     315             :                 stream >> val_d;
     316          11 :                 c->setRedshift(val_d); // z
     317          11 :                 stream >> val_i;
     318          11 :                 c->setSerialNumber(val_i); // SN
     319          11 :                 stream >> val_i;
     320          11 :                 c->current.setId(val_i); // ID
     321             :                 stream >> val_d;
     322          11 :                 c->current.setEnergy(val_d*energyScale); // E
     323             :                 stream >> x >> y >> z;
     324          11 :                 c->current.setPosition(Vector3d(x, y, z)*lengthScale); // X, Y, Z
     325             :                 stream >> x >> y >> z;
     326          11 :                 c->current.setDirection(Vector3d(x, y, z)*lengthScale); // Px, Py, Pz
     327          11 :                 stream >> val_i; // SN0 (TODO: Reconstruct the parent-child relationship)
     328          11 :                 stream >> val_i;
     329          11 :                 c->source.setId(val_i); // ID0
     330             :                 stream >> val_d;
     331          11 :                 c->source.setEnergy(val_d*energyScale);      // E0
     332             :                 stream >> x >> y >> z;
     333          11 :                 c->source.setPosition(Vector3d(x, y, z)*lengthScale); // X0, Y0, Z0
     334             :                 stream >> x >> y >> z;
     335          11 :                 c->source.setDirection(Vector3d(x, y, z)*lengthScale); // P0x, P0y, P0z
     336          11 :                 stream >> val_i; // SN1
     337          11 :                 stream >> val_i;
     338          11 :                 c->created.setId(val_i); // ID1
     339             :                 stream >> val_d;
     340          11 :                 c->created.setEnergy(val_d*energyScale); // E1
     341             :                 stream >> x >> y >> z;
     342          11 :                 c->created.setPosition(Vector3d(x, y, z)*lengthScale); // X1, Y1, Z1
     343             :                 stream >> x >> y >> z;
     344          11 :                 c->created.setDirection(Vector3d(x, y, z)*lengthScale); // P1x, P1y, P1z
     345             :                 stream >> val_d;
     346          11 :                 c->setWeight(val_d); // W
     347             : 
     348          22 :                 collector->process(c);
     349          37 :         }
     350           1 :         infile.close();
     351           2 : }
     352             : 
     353           0 : std::string TextOutput::getDescription() const {
     354           0 :         return "TextOutput";
     355             : }
     356             : 
     357          10 : void TextOutput::close() {
     358             : #ifdef CRPROPA_HAVE_ZLIB
     359          10 :         zstream::ogzstream *zs = dynamic_cast<zstream::ogzstream *>(out);
     360          10 :         if (zs) {
     361           0 :                 zs->close();
     362           0 :                 delete out;
     363           0 :                 out = 0;
     364             :         }
     365             : #endif
     366          10 :         outfile.flush();
     367          10 : }
     368             : 
     369          10 : TextOutput::~TextOutput() {
     370           9 :         close();
     371          10 : }
     372             : 
     373           0 : void TextOutput::gzip() {
     374             : #ifdef CRPROPA_HAVE_ZLIB
     375           0 :         out = new zstream::ogzstream(*out);
     376             : #else
     377             :         throw std::runtime_error("CRPropa was built without Zlib compression!");
     378             : #endif
     379           0 : }
     380             : 
     381             : } // namespace crpropa

Generated by: LCOV version 1.14