Program Listing for File InteractionRates.cpp
↰ Return to documentation for file (src/InteractionRates.cpp)
#include "crpropa/InteractionRates.h"
#include "crpropa/Units.h"
#include "crpropa/Random.h"
#include "kiss/path.h"
#include <vector>
#include <string>
#include <unordered_map>
#include <fstream>
namespace crpropa {
InteractionRatesHomogeneous::InteractionRatesHomogeneous(std::string rateFile, std::string cumulativeRateFile) {
this->ratesName = "interactionRatesHomogeneous";
this->isPositionDependent = false;
if (rateFile != "")
initRate(rateFile);
if (cumulativeRateFile != "")
initCumulativeRate(cumulativeRateFile);
}
double InteractionRatesHomogeneous::getProcessRate(const double E, const Vector3d &position) const {
return interpolate(E, this->tabEnergy, this->tabRate);
}
void InteractionRatesHomogeneous::loadPerformInteractionTabs(const Vector3d &position, std::vector<double> &tabE, std::vector<double> &tabs, std::vector<std::vector<double>> &tabCDF) const {
tabE = this->getTabulatedE();
tabs = this->getTabulateds();
tabCDF = this->getTabulatedCDF();
}
void InteractionRatesHomogeneous::setTabulatedEnergy(std::vector<double>& tabEnergy) {
this->tabEnergy = tabEnergy;
}
void InteractionRatesHomogeneous::setTabulatedRate(std::vector<double>& tabRate) {
this->tabRate = tabRate;
}
void InteractionRatesHomogeneous::setTabulatedE(std::vector<double>& tabE) {
this->tabE = tabE;
}
void InteractionRatesHomogeneous::setTabulateds(std::vector<double>& tabs) {
this->tabs = tabs;
}
void InteractionRatesHomogeneous::setTabulatedCDF(std::vector<std::vector<double>>& tabCDF) {
this->tabCDF = tabCDF;
}
void InteractionRatesHomogeneous::initRate(std::string filename){
if(is_directory(filename))
throw std::runtime_error("InteractionRatesHomogeneous: The given filename " + filename + " is a directory!\
If you wanted to use position dependent photon fields instead, set the correct InteractionRates class first!");
std::ifstream infile(filename.c_str());
if (!infile.good())
throw std::runtime_error("InteractionRatesHomogeneous: could not open file " + filename);
std::vector<double> tabEnergy;
std::vector<double> tabRate;
while (infile.good()) {
if (infile.peek() != '#') {
double a, b;
infile >> a >> b;
if (infile) {
tabEnergy.push_back(pow(10, a) * eV);
tabRate.push_back(b / Mpc);
}
}
infile.ignore(std::numeric_limits < std::streamsize > ::max(), '\n');
}
infile.close();
setTabulatedEnergy(tabEnergy);
setTabulatedRate(tabRate);
}
void InteractionRatesHomogeneous::initCumulativeRate(std::string filename){
if(is_directory(filename))
throw std::runtime_error("InteractionRatesHomogeneous: The given filename " + filename + " is a directory!\
If you wanted to use position dependent photon fields instead, set the correct InteractionRates class first!");
std::ifstream infile(filename.c_str());
if (!infile.good())
throw std::runtime_error("InteractionRatesHomogeneous: could not open file " + filename);
std::vector<double> tabE;
std::vector<double> tabs;
std::vector<std::vector<double>> tabCDF;
// skip header
while (infile.peek() == '#')
infile.ignore(std::numeric_limits < std::streamsize > ::max(), '\n');
// read s values in first line
double a;
infile >> a; // skip first value
while (infile.good() and (infile.peek() != '\n')) {
infile >> a;
tabs.push_back(pow(10, a) * eV * eV);
}
// read all following lines: E, cdf values
while (infile.good()) {
infile >> a;
if (!infile)
break; // end of file
tabE.push_back(pow(10, a) * eV);
std::vector<double> cdf;
for (int i = 0; i < tabs.size(); i++) {
infile >> a;
cdf.push_back(a / Mpc);
}
tabCDF.push_back(cdf);
}
infile.close();
setTabulatedE(tabE);
setTabulateds(tabs);
setTabulatedCDF(tabCDF);
}
InteractionRatesPositionDependent::InteractionRatesPositionDependent(
std::string rateFilePath, std::string cumulativeRateFilePath, ref_ptr<Surface> surface) {
this->ratesName = "interactionRatesPositionDependent";
this->isPositionDependent = true;
this->surface = surface;
if (rateFilePath != "")
initRate(rateFilePath);
if (cumulativeRateFilePath != "")
initCumulativeRate(cumulativeRateFilePath);
}
int InteractionRatesPositionDependent::findClosestGridPoint(const Vector3d &position) const {
if (!tree) {
throw std::runtime_error("KD-Tree not initialized!");
}
unsigned int closestIndex;
double closestDistSquared;
double queryPoint[3] = { position.x, position.y, position.z };
this->tree->knnSearch(queryPoint, 1, &closestIndex, &closestDistSquared);
return this->cloud.ids[closestIndex];
}
std::vector<double> InteractionRatesPositionDependent::getClosestRate(const Vector3d &position) const {
int iMin = findClosestGridPoint(position);
return tabRate[iMin];
}
std::vector<double> InteractionRatesPositionDependent::getClosests(const Vector3d &position) const {
int iMin = findClosestGridPoint(position);
return tabs[iMin];
}
std::vector<std::vector<double>> InteractionRatesPositionDependent::getClosestCDF(const Vector3d &position) const {
int iMin = findClosestGridPoint(position);
return tabCDF[iMin];
}
double InteractionRatesPositionDependent::getProcessRate(const double E, const Vector3d &position) const {
std::vector<double> tabRate = this->getClosestRate(position);
// compute the interaction rate for the given candidate energy, E
return interpolate(E, this->tabEnergy, tabRate);
}
void InteractionRatesPositionDependent::loadPerformInteractionTabs(const Vector3d &position, std::vector<double> &tabE, std::vector<double> &tabs, std::vector<std::vector<double>> &tabCDF) const {
std::vector<double> E = this->getTabulatedE();
std::vector<double> s = this->getClosests(position);
std::vector<std::vector<double>> CDF = this->getClosestCDF(position);
tabE = E;
tabs = s;
tabCDF = CDF;
}
void InteractionRatesPositionDependent::setTabulatedEnergy(std::vector<double>& tabEnergy) {
this->tabEnergy = tabEnergy;
}
void InteractionRatesPositionDependent::setTabulatedRate(std::vector<std::vector<double>>& tabRate) {
this->tabRate = tabRate;
}
void InteractionRatesPositionDependent::setTabulatedE(std::vector<double>& tabE) {
this->tabE = tabE;
}
void InteractionRatesPositionDependent::setTabulateds(std::vector<std::vector<double>>& tabs) {
this->tabs = tabs;
}
void InteractionRatesPositionDependent::setTabulatedCDF(std::vector<std::vector<std::vector<double>>>& tabCDF) {
this->tabCDF = tabCDF;
}
void InteractionRatesPositionDependent::setPhotonDict(std::unordered_map<int, Vector3d>& photonDict) {
this->photonDict = photonDict;
// delete old clouds
this->cloud.points.clear();
this->cloud.ids.clear();
for (const auto& el : this->photonDict) {
this->cloud.ids.push_back(el.first);
this->cloud.points.push_back(el.second);
}
// delete old tree
if (this->tree) {
delete this->tree;
}
int maxLeafTree = 20;
int nThreads = 4;
nanoflann::KDTreeSingleIndexAdaptorFlags flag;
this->tree = new KDTree(3, cloud, nanoflann::KDTreeSingleIndexAdaptorParams(maxLeafTree, flag, nThreads));
this->tree->buildIndex();
}
void InteractionRatesPositionDependent::setSurface(ref_ptr<Surface> surface) {
this->surface = surface;
}
void InteractionRatesPositionDependent::initRate(std::string filepath){
if(!is_directory(filepath))
throw std::runtime_error("InteractionRatesPositionDependent: The given path " + filepath + " is not a directory or does not exist!\
If you wanted to use homogeneous photon fields instead, set the correct InteractionRates class first!");
std::vector<std::vector<double>> tabRate;
std::unordered_map<int, Vector3d> photonDict;
int iFile = 0;
std::vector<std::string> dirs;
if(!list_directory(filepath, dirs))
throw std::runtime_error("Could not find any files in " + filepath + "!\n");
for (auto const& filename : dirs) {
// the input filename here should be a string
//check if it is correct, i.e. a proper filename string
std::ifstream infile(concat_path(filepath, filename).c_str());
if (!infile.good())
throw std::runtime_error("InteractionRatesPositionDependent: could not open file " + concat_path(filepath, filename));
std::vector<double> vecEnergy;
std::vector<double> vecRate;
double x, y, z;
std::string str;
std::stringstream ss;
std::string filename_split = splitFilename(filename);
ss << filename_split;
int iLine = 0;
std::locale::global(std::locale("C"));
while (getline(ss, str, '_')) {
if (iLine == 3) {
x = std::stod(str) * kpc;
}
if (iLine == 4) {
y = std::stod(str) * kpc;
}
if (iLine == 5) {
z = std::stod(str) * kpc;
}
iLine = iLine + 1;
}
Vector3d vPos(x, y, z);
// continue when not "inside" surface
if (getSurface() && getSurface()->distance(vPos)>=0)
continue;
photonDict[iFile] = vPos;
while (infile.good()) {
if (infile.peek() != '#') {
double a, b;
infile >> a >> b;
if (infile) {
if (iFile == 0) {
vecEnergy.push_back(pow(10, a) * eV);
setTabulatedEnergy(vecEnergy);
}
vecRate.push_back(b / Mpc);
}
}
infile.ignore(std::numeric_limits< std::streamsize >::max(), '\n');
}
tabRate.push_back(vecRate);
iFile = iFile + 1;
infile.close();
}
if (tabRate.empty())
throw std::runtime_error("Rate's table empty! Check if the surface is properly set.");
setTabulatedRate(tabRate);
setPhotonDict(photonDict);
}
void InteractionRatesPositionDependent::initCumulativeRate(std::string filepath){
if(!is_directory(filepath))
throw std::runtime_error("InteractionRatesPositionDependent: The given path " + filepath + " is not a directory or does not exist!\
If you wanted to use homogeneous photon fields instead, set the correct InteractionRates class first!");
std::vector<std::vector<double>> tabs;
std::vector<std::vector<std::vector<double>>> tabCDF;
int iFile = 0;
std::vector<std::string> dirs;
if(!list_directory(filepath, dirs))
throw std::runtime_error("Could not find any files in " + filepath + "!\n");
for (auto const& filename : dirs) {
std::vector<double> vecE;
std::vector<double> vecs;
std::vector<std::vector<double>> vecCDF;
std::ifstream infile(concat_path(filepath, filename).c_str());
if (!infile.good())
throw std::runtime_error("InteractionRatesPositionDependent: could not open file " + concat_path(filepath, filename));
double x, y, z;
std::string str;
std::stringstream ss;
std::string filename_split = splitFilename(filename);
ss << filename_split;
int iLine = 0;
std::locale::global(std::locale("C"));
while (getline(ss, str, '_')) {
if (iLine == 3) {
x = -std::stod(str) * kpc;
}
if (iLine == 4) {
y = std::stod(str) * kpc;
}
if (iLine == 5) {
z = std::stod(str) * kpc;
}
iLine = iLine + 1;
}
Vector3d vPos(x, y, z);
// continue when not "inside" surface
if (getSurface() && getSurface()->distance(vPos)>=0)
continue;
// skip header
while (infile.peek() == '#')
infile.ignore(std::numeric_limits < std::streamsize > ::max(), '\n');
// read s values in first line
double a;
infile >> a; // skip first value
while (infile.good() and (infile.peek() != '\n')) {
infile >> a;
vecs.push_back(pow(10, a) * eV * eV);
}
// read all following lines: E, cdf values
while (infile.good()) {
infile >> a;
if (!infile)
break; // end of file
if (iFile == 0) {
vecE.push_back(pow(10, a) * eV);
setTabulatedE(vecE);
}
std::vector<double> cdf;
for (int i = 0; i < tabs.size(); i++) {
infile >> a;
cdf.push_back(a / Mpc);
}
vecCDF.push_back(cdf);
}
iFile = iFile + 1;
tabs.push_back(vecs);
tabCDF.push_back(vecCDF);
infile.close();
}
setTabulateds(tabs);
setTabulatedCDF(tabCDF);
}
} //namespace crpropa