LCOV - code coverage report
Current view: top level - src - InteractionRates.cpp (source / functions) Coverage Total Hit
Test: coverage.info.cleaned Lines: 29.8 % 215 64
Test Date: 2026-07-13 06:03:10 Functions: 38.5 % 26 10

            Line data    Source code
       1              : #include "crpropa/InteractionRates.h"
       2              : #include "crpropa/Units.h"
       3              : #include "crpropa/Random.h"
       4              : 
       5              : #include "kiss/path.h"
       6              : 
       7              : #include <vector>
       8              : #include <string>
       9              : #include <unordered_map>
      10              : #include <fstream>
      11              : 
      12              : namespace crpropa {
      13              : 
      14           80 : InteractionRatesHomogeneous::InteractionRatesHomogeneous(std::string rateFile, std::string cumulativeRateFile) {
      15           80 :         this->ratesName = "interactionRatesHomogeneous";
      16           80 :         this->isPositionDependent = false;
      17              : 
      18           80 :         if (rateFile != "")
      19          160 :                 initRate(rateFile);
      20           80 :         if (cumulativeRateFile != "")
      21          130 :                 initCumulativeRate(cumulativeRateFile);
      22           80 : }
      23              : 
      24          844 : double InteractionRatesHomogeneous::getProcessRate(const double E, const Vector3d &position) const {
      25          844 :         return interpolate(E, this->tabEnergy, this->tabRate);
      26              : }
      27              : 
      28          500 : void InteractionRatesHomogeneous::loadPerformInteractionTabs(const Vector3d &position, std::vector<double> &tabE, std::vector<double> &tabs, std::vector<std::vector<double>> &tabCDF) const {
      29          500 :         tabE = this->getTabulatedE();
      30          500 :         tabs = this->getTabulateds();
      31          500 :         tabCDF = this->getTabulatedCDF();
      32          500 : }
      33              : 
      34           80 : void InteractionRatesHomogeneous::setTabulatedEnergy(std::vector<double>& tabEnergy) {
      35           80 :         this->tabEnergy = tabEnergy;
      36           80 : }
      37              : 
      38           80 : void InteractionRatesHomogeneous::setTabulatedRate(std::vector<double>& tabRate) {
      39           80 :         this->tabRate = tabRate;
      40           80 : }
      41              : 
      42           65 : void InteractionRatesHomogeneous::setTabulatedE(std::vector<double>& tabE) {
      43           65 :         this->tabE = tabE;
      44           65 : }
      45              : 
      46           65 : void InteractionRatesHomogeneous::setTabulateds(std::vector<double>& tabs) {
      47           65 :         this->tabs = tabs;
      48           65 : }
      49              : 
      50           65 : void InteractionRatesHomogeneous::setTabulatedCDF(std::vector<std::vector<double>>& tabCDF) {
      51           65 :         this->tabCDF = tabCDF;
      52           65 : }
      53              : 
      54           80 : void InteractionRatesHomogeneous::initRate(std::string filename){
      55           80 :         if(is_directory(filename))
      56            0 :                 throw std::runtime_error("InteractionRatesHomogeneous: The given filename " + filename + " is a directory!\
      57            0 :                         If you wanted to use position dependent photon fields instead, set the correct InteractionRates class first!");
      58              :         
      59           80 :         std::ifstream infile(filename.c_str());
      60           80 :         if (!infile.good())
      61            0 :                 throw std::runtime_error("InteractionRatesHomogeneous: could not open file " + filename);
      62              : 
      63              :         std::vector<double> tabEnergy;
      64              :         std::vector<double> tabRate;
      65              : 
      66        19035 :         while (infile.good()) {
      67              :                 
      68        18955 :                 if (infile.peek() != '#') {     
      69              :                         double a, b;
      70              :                         infile >> a >> b;
      71        18635 :                         if (infile) {
      72        18555 :                                 tabEnergy.push_back(pow(10, a) * eV);
      73        18555 :                                 tabRate.push_back(b / Mpc);
      74              :                         }
      75              :                 }
      76        18955 :                 infile.ignore(std::numeric_limits < std::streamsize > ::max(), '\n');
      77              :                 
      78              :         }
      79              :         
      80           80 :         infile.close();
      81              :                 
      82           80 :         setTabulatedEnergy(tabEnergy);
      83           80 :         setTabulatedRate(tabRate);
      84           80 : }
      85              : 
      86           65 : void InteractionRatesHomogeneous::initCumulativeRate(std::string filename){
      87           65 :         if(is_directory(filename))
      88            0 :                 throw std::runtime_error("InteractionRatesHomogeneous: The given filename " + filename + " is a directory!\
      89            0 :                         If you wanted to use position dependent photon fields instead, set the correct InteractionRates class first!");
      90              : 
      91           65 :         std::ifstream infile(filename.c_str());
      92              :         
      93           65 :         if (!infile.good())
      94            0 :                 throw std::runtime_error("InteractionRatesHomogeneous: could not open file " + filename);
      95              :         
      96              :         std::vector<double> tabE;
      97              :         std::vector<double> tabs;
      98              :         std::vector<std::vector<double>> tabCDF;
      99              :         
     100              :         // skip header
     101          325 :         while (infile.peek() == '#')
     102          260 :                 infile.ignore(std::numeric_limits < std::streamsize > ::max(), '\n');
     103              :         
     104              :         // read s values in first line
     105              :         double a;
     106              :         infile >> a; // skip first value
     107         8253 :         while (infile.good() and (infile.peek() != '\n')) {
     108              :                 infile >> a;
     109         8188 :                 tabs.push_back(pow(10, a) * eV * eV);
     110              :         }
     111              :         
     112              :         // read all following lines: E, cdf values
     113        15404 :         while (infile.good()) {
     114              :                 infile >> a;
     115        15404 :                 if (!infile)
     116              :                         break;  // end of file
     117        15339 :                 tabE.push_back(pow(10, a) * eV);
     118              :                 std::vector<double> cdf;
     119      1999132 :                 for (int i = 0; i < tabs.size(); i++) {
     120              :                         infile >> a;
     121      1983793 :                         cdf.push_back(a / Mpc);
     122              :                 }
     123        15339 :                 tabCDF.push_back(cdf);
     124        15339 :         }
     125           65 :         infile.close();
     126              :         
     127           65 :         setTabulatedE(tabE);
     128           65 :         setTabulateds(tabs);
     129           65 :         setTabulatedCDF(tabCDF);
     130           65 : }
     131              : 
     132              : 
     133            0 : InteractionRatesPositionDependent::InteractionRatesPositionDependent(
     134            0 :         std::string rateFilePath, std::string cumulativeRateFilePath, ref_ptr<Surface> surface) {
     135              :         
     136            0 :         this->ratesName = "interactionRatesPositionDependent";
     137            0 :         this->isPositionDependent = true;
     138            0 :         this->surface = surface;
     139              : 
     140            0 :         if (rateFilePath != "")
     141            0 :                 initRate(rateFilePath);
     142            0 :         if (cumulativeRateFilePath != "")
     143            0 :                 initCumulativeRate(cumulativeRateFilePath);
     144            0 : }
     145              : 
     146            0 : int InteractionRatesPositionDependent::findClosestGridPoint(const Vector3d &position) const {
     147            0 :         if (!tree) {
     148            0 :                 throw std::runtime_error("KD-Tree not initialized!");
     149              :         }
     150              :         
     151              :         unsigned int closestIndex;
     152              :         double closestDistSquared;
     153            0 :         double queryPoint[3] = { position.x, position.y, position.z };
     154              :         
     155              :         this->tree->knnSearch(queryPoint, 1, &closestIndex, &closestDistSquared);
     156            0 :         return this->cloud.ids[closestIndex];
     157              :         
     158              : }
     159              : 
     160            0 : std::vector<double> InteractionRatesPositionDependent::getClosestRate(const Vector3d &position) const {
     161            0 :         int iMin = findClosestGridPoint(position);
     162            0 :         return tabRate[iMin];
     163              : }
     164              : 
     165            0 : std::vector<double> InteractionRatesPositionDependent::getClosests(const Vector3d &position) const {
     166            0 :         int iMin = findClosestGridPoint(position);
     167            0 :         return tabs[iMin];
     168              : }
     169              : 
     170            0 : std::vector<std::vector<double>> InteractionRatesPositionDependent::getClosestCDF(const Vector3d &position) const {
     171            0 :         int iMin = findClosestGridPoint(position);
     172            0 :         return tabCDF[iMin];
     173              : }
     174              : 
     175            0 : double InteractionRatesPositionDependent::getProcessRate(const double E, const Vector3d &position) const {
     176            0 :         std::vector<double> tabRate = this->getClosestRate(position);
     177              :         // compute the interaction rate for the given candidate energy, E
     178            0 :         return interpolate(E, this->tabEnergy, tabRate);
     179            0 : }
     180              : 
     181            0 : void InteractionRatesPositionDependent::loadPerformInteractionTabs(const Vector3d &position, std::vector<double> &tabE, std::vector<double> &tabs, std::vector<std::vector<double>> &tabCDF) const {
     182              :         
     183              :         std::vector<double> E = this->getTabulatedE();
     184            0 :         std::vector<double> s = this->getClosests(position);
     185            0 :         std::vector<std::vector<double>> CDF = this->getClosestCDF(position);
     186              :         
     187            0 :         tabE = E;
     188            0 :         tabs = s;
     189            0 :         tabCDF = CDF;
     190            0 : }
     191              : 
     192            0 : void InteractionRatesPositionDependent::setTabulatedEnergy(std::vector<double>& tabEnergy) {
     193            0 :         this->tabEnergy = tabEnergy;
     194            0 : }
     195              : 
     196            0 : void InteractionRatesPositionDependent::setTabulatedRate(std::vector<std::vector<double>>& tabRate) {
     197            0 :         this->tabRate = tabRate;
     198            0 : }
     199              : 
     200            0 : void InteractionRatesPositionDependent::setTabulatedE(std::vector<double>& tabE) {
     201            0 :         this->tabE = tabE;
     202            0 : }
     203              : 
     204            0 : void InteractionRatesPositionDependent::setTabulateds(std::vector<std::vector<double>>& tabs) {
     205            0 :         this->tabs = tabs;
     206            0 : }
     207              : 
     208            0 : void InteractionRatesPositionDependent::setTabulatedCDF(std::vector<std::vector<std::vector<double>>>& tabCDF) {
     209            0 :         this->tabCDF = tabCDF;
     210            0 : }
     211              : 
     212            0 : void InteractionRatesPositionDependent::setPhotonDict(std::unordered_map<int, Vector3d>& photonDict) {
     213              :         this->photonDict = photonDict;
     214              :         
     215              :         // delete old clouds
     216              :         this->cloud.points.clear();
     217              :         this->cloud.ids.clear();
     218              :         
     219            0 :         for (const auto& el : this->photonDict) {
     220            0 :                 this->cloud.ids.push_back(el.first);
     221            0 :                 this->cloud.points.push_back(el.second);
     222              :         }
     223              :         
     224              :         // delete old tree
     225            0 :         if (this->tree) {
     226            0 :                 delete this->tree;
     227              :         }
     228              :         
     229              :         int maxLeafTree = 20;
     230              :         int nThreads = 4;
     231              :         nanoflann::KDTreeSingleIndexAdaptorFlags flag;
     232              : 
     233            0 :         this->tree = new KDTree(3, cloud, nanoflann::KDTreeSingleIndexAdaptorParams(maxLeafTree, flag, nThreads));
     234            0 :         this->tree->buildIndex();
     235            0 : }
     236              : 
     237            0 : void InteractionRatesPositionDependent::setSurface(ref_ptr<Surface> surface) {
     238            0 :         this->surface = surface;
     239            0 : }
     240              : 
     241            0 : void InteractionRatesPositionDependent::initRate(std::string filepath){
     242            0 :         if(!is_directory(filepath))
     243            0 :                 throw std::runtime_error("InteractionRatesPositionDependent: The given path " + filepath + " is not a directory or does not exist!\
     244            0 :                         If you wanted to use homogeneous photon fields instead, set the correct InteractionRates class first!");
     245              : 
     246              :         std::vector<std::vector<double>> tabRate;
     247              :                 
     248              :         std::unordered_map<int, Vector3d> photonDict;
     249            0 :         int iFile = 0;
     250              :         
     251              :         std::vector<std::string> dirs;
     252            0 :         if(!list_directory(filepath, dirs))
     253            0 :                 throw std::runtime_error("Could not find any files in " + filepath + "!\n");
     254              : 
     255            0 :         for (auto const& filename : dirs) {
     256              :                 
     257              :                 // the input filename here should be a string
     258              :                 //check if it is correct, i.e. a proper filename string
     259            0 :                 std::ifstream infile(concat_path(filepath, filename).c_str());
     260            0 :                 if (!infile.good())
     261            0 :                         throw std::runtime_error("InteractionRatesPositionDependent: could not open file " + concat_path(filepath, filename));
     262              :                 
     263              :                 std::vector<double> vecEnergy;
     264              :                 std::vector<double> vecRate;
     265              :                 
     266              :                 double x, y, z;
     267              :                 std::string str;
     268            0 :                 std::stringstream ss;
     269              :                 
     270            0 :                 std::string filename_split = splitFilename(filename);
     271              :                 ss << filename_split;
     272              :                 
     273              :                 int iLine = 0;
     274              :                 
     275            0 :                 std::locale::global(std::locale("C"));
     276              :                 
     277            0 :                 while (getline(ss, str, '_')) {
     278            0 :                         if (iLine == 3) {
     279            0 :                                 x = std::stod(str) * kpc;
     280              :                         }
     281            0 :                         if (iLine == 4) {
     282            0 :                                 y = std::stod(str) * kpc;
     283              :                         }
     284            0 :                         if (iLine == 5) {
     285            0 :                                 z = std::stod(str) * kpc;
     286              :                         }
     287            0 :                         iLine = iLine + 1;
     288              :                 }
     289              :                 
     290              :                 Vector3d vPos(x, y, z);
     291              :                 
     292              :                 // continue when not "inside" surface
     293            0 :                 if (getSurface() && getSurface()->distance(vPos)>=0)
     294              :                         continue;
     295              :                 
     296              :                 photonDict[iFile] = vPos;
     297              :                 
     298            0 :                 while (infile.good()) {
     299            0 :                         if (infile.peek() != '#') {
     300              :                                 double a, b;
     301              :                                 infile >> a >> b;
     302            0 :                                 if (infile) {
     303            0 :                                         if (iFile == 0) {
     304            0 :                                                 vecEnergy.push_back(pow(10, a) * eV);
     305            0 :                                                 setTabulatedEnergy(vecEnergy);
     306              :                                         }
     307            0 :                                         vecRate.push_back(b / Mpc);
     308              :                                 }
     309              :                         }
     310            0 :                         infile.ignore(std::numeric_limits< std::streamsize >::max(), '\n');
     311              :                 }
     312              :                 
     313            0 :                 tabRate.push_back(vecRate);
     314              :                 
     315            0 :                 iFile = iFile + 1;
     316            0 :                 infile.close();
     317            0 :         }
     318              :                 
     319            0 :         if (tabRate.empty())
     320            0 :                 throw std::runtime_error("Rate's table empty! Check if the surface is properly set.");
     321              :                 
     322            0 :         setTabulatedRate(tabRate);
     323            0 :         setPhotonDict(photonDict);
     324            0 : }
     325              : 
     326            0 : void InteractionRatesPositionDependent::initCumulativeRate(std::string filepath){
     327            0 :         if(!is_directory(filepath))
     328            0 :                 throw std::runtime_error("InteractionRatesPositionDependent: The given path " + filepath + " is not a directory or does not exist!\
     329            0 :                         If you wanted to use homogeneous photon fields instead, set the correct InteractionRates class first!");
     330              : 
     331              :         std::vector<std::vector<double>> tabs;
     332              :         std::vector<std::vector<std::vector<double>>> tabCDF;
     333              :         
     334              :         int iFile = 0;
     335              :         std::vector<std::string> dirs;
     336            0 :         if(!list_directory(filepath, dirs))
     337            0 :                 throw std::runtime_error("Could not find any files in " + filepath + "!\n");
     338              : 
     339            0 :         for (auto const& filename : dirs) {
     340              :                 
     341              :                 std::vector<double> vecE;
     342              :                 std::vector<double> vecs;
     343              :                 std::vector<std::vector<double>> vecCDF;
     344              :                 
     345            0 :                 std::ifstream infile(concat_path(filepath, filename).c_str());
     346              : 
     347            0 :                 if (!infile.good())
     348            0 :                         throw std::runtime_error("InteractionRatesPositionDependent: could not open file " + concat_path(filepath, filename));
     349              :                 
     350              :                 double x, y, z;
     351              :                 std::string str;
     352            0 :                 std::stringstream ss;
     353              :                 
     354            0 :                 std::string filename_split = splitFilename(filename);
     355              :                 ss << filename_split;
     356              :                 
     357              :                 int iLine = 0;
     358              :                 
     359            0 :                 std::locale::global(std::locale("C"));
     360              :                 
     361            0 :                 while (getline(ss, str, '_')) {
     362            0 :                         if (iLine == 3) {
     363            0 :                                 x = -std::stod(str) * kpc;
     364              :                         }
     365            0 :                         if (iLine == 4) {
     366            0 :                                 y = std::stod(str) * kpc;
     367              :                         }
     368            0 :                         if (iLine == 5) {
     369            0 :                                 z = std::stod(str) * kpc;
     370              :                         }
     371            0 :                         iLine = iLine + 1;
     372              :                 }
     373              :                 
     374              :                 Vector3d vPos(x, y, z);
     375              :                 
     376              :                 // continue when not "inside" surface
     377            0 :                 if (getSurface() && getSurface()->distance(vPos)>=0)
     378              :                         continue;
     379              :                 
     380              :                 // skip header
     381            0 :                 while (infile.peek() == '#')
     382            0 :                         infile.ignore(std::numeric_limits < std::streamsize > ::max(), '\n');
     383              :                 
     384              :                 // read s values in first line
     385              :                 double a;
     386              :                 infile >> a; // skip first value
     387            0 :                 while (infile.good() and (infile.peek() != '\n')) {
     388              :                         infile >> a;
     389            0 :                         vecs.push_back(pow(10, a) * eV * eV);
     390              :                 }
     391              :                 
     392              :                 // read all following lines: E, cdf values
     393            0 :                 while (infile.good()) {
     394              :                         infile >> a;
     395            0 :                         if (!infile)
     396              :                                 break;  // end of file
     397            0 :                         if (iFile == 0) {
     398            0 :                                 vecE.push_back(pow(10, a) * eV);
     399            0 :                                 setTabulatedE(vecE);
     400              :                         }
     401              :                         std::vector<double> cdf;
     402            0 :                         for (int i = 0; i < tabs.size(); i++) {
     403              :                                 infile >> a;
     404            0 :                                 cdf.push_back(a / Mpc);
     405              :                         }
     406            0 :                         vecCDF.push_back(cdf);
     407            0 :                 }
     408              :                 
     409            0 :                 iFile = iFile + 1;
     410              :                 
     411            0 :                 tabs.push_back(vecs);
     412            0 :                 tabCDF.push_back(vecCDF);
     413            0 :                 infile.close();
     414            0 :         }
     415              :         
     416            0 :         setTabulateds(tabs);
     417            0 :         setTabulatedCDF(tabCDF);
     418            0 : }
     419              : 
     420              : } //namespace crpropa
        

Generated by: LCOV version 2.0-1