Program Listing for File Common.cpp

Return to documentation for file (src/Common.cpp)

#include "crpropa/Common.h"

#include "kiss/path.h"
#include "kiss/logger.h"

#include <cstdlib>
#include <fstream>
#include <string>
#include <cmath>
#include <algorithm>

#define index(i,j) ((j)+(i)*Y.size())

namespace crpropa {

std::string getDataPath(std::string filename) {
        static std::string dataPath;
        if (dataPath.size())
                return concat_path(dataPath, filename);

        const char *env_path = getenv("CRPROPA_DATA_PATH");
        if (env_path) {
                if (is_directory(env_path)) {
                        dataPath = env_path;
                        KISS_LOG_INFO << "getDataPath: use environment variable, "
                                        << dataPath << std::endl;
                        return concat_path(dataPath, filename);
                }
        }

#ifdef CRPROPA_INSTALL_PREFIX
        {
                std::string _path = CRPROPA_INSTALL_PREFIX "/share/crpropa";
                if (is_directory(_path)) {
                        dataPath = _path;
                        KISS_LOG_INFO
                        << "getDataPath: use install prefix, " << dataPath << std::endl;
                        return concat_path(dataPath, filename);
                }
        }
#endif

        {
                std::string _path = executable_path() + "../data";
                if (is_directory(_path)) {
                        dataPath = _path;
                        KISS_LOG_INFO << "getDataPath: use executable path, " << dataPath
                                        << std::endl;
                        return concat_path(dataPath, filename);
                }
        }

        dataPath = "data";
        KISS_LOG_INFO << "getDataPath: use default, " << dataPath << std::endl;
        return concat_path(dataPath, filename);
}


std::string getInstallPrefix()
{
  std::string _path = "";
  #ifdef CRPROPA_INSTALL_PREFIX
    _path += CRPROPA_INSTALL_PREFIX;
  #endif
  return _path;
};

double interpolate(double x, const std::vector<double> &X,
                const std::vector<double> &Y) {
        std::vector<double>::const_iterator it = std::upper_bound(X.begin(),
                        X.end(), x);
        if (it == X.begin())
                return Y.front();
        if (it == X.end())
                return Y.back();

        size_t i = it - X.begin() - 1;
        return Y[i] + (x - X[i]) * (Y[i + 1] - Y[i]) / (X[i + 1] - X[i]);
}

double interpolate2d(double x, double y, const std::vector<double> &X,
                const std::vector<double> &Y, const std::vector<double> &Z) {

        std::vector<double>::const_iterator itx = std::upper_bound(X.begin(), X.end(), x);
        std::vector<double>::const_iterator ity = std::upper_bound(Y.begin(), Y.end(), y);

        if (x > X.back() || x < X.front())
                return 0;
        if (y > Y.back() || y < Y.front())
                return 0;

        if (itx == X.begin() && ity == Y.begin())
                return Z.front();
        if (itx == X.end() && ity == Y.end())
                return Z.back();

        size_t i = itx - X.begin() - 1;
        size_t j = ity - Y.begin() - 1;

        double Q11 = Z[index(i,j)];
        double Q12 = Z[index(i,j+1)];
        double Q21 = Z[index(i+1,j)];
        double Q22 = Z[index(i+1,j+1)];

        double R1 = ((X[i+1]-x)/(X[i+1]-X[i]))*Q11+((x-X[i])/(X[i+1]-X[i]))*Q21;
        double R2 = ((X[i+1]-x)/(X[i+1]-X[i]))*Q12+((x-X[i])/(X[i+1]-X[i]))*Q22;

        return ((Y[j+1]-y)/(Y[j+1]-Y[j]))*R1+((y-Y[j])/(Y[j+1]-Y[j]))*R2;
}

double interpolateEquidistant(double x, double lo, double hi,
                const std::vector<double> &Y) {
        if (x <= lo)
                return Y.front();
        if (x >= hi)
                return Y.back();

        double dx = (hi - lo) / (Y.size() - 1);
        double p = (x - lo) / dx;
        size_t i = floor(p);
        return Y[i] + (p - i) * (Y[i + 1] - Y[i]);
}

size_t closestIndex(double x, const std::vector<double> &X) {
        size_t i1 = std::lower_bound(X.begin(), X.end(), x) - X.begin();
        if (i1 == 0)
                return i1;
        size_t i0 = i1 - 1;
        if (std::fabs(X[i0] - x) < std::fabs(X[i1] - x))
                return i0;
        else
                return i1;
}

} // namespace crpropa