Skip to content

File NPCalibrationManager.cxx

File List > core > NPCalibrationManager.cxx

Go to the documentation of this file


#include "NPCalibrationManager.h"
#include "NPApplication.h"
#include "NPFunction.h"
#include "NPOptionManager.h"
//   STL
#include <cmath>
#include <cstdlib>
#include <limits>
#include <sstream>
using namespace nptool;

CalibrationManager::CalibrationManager() {}

void CalibrationManager::InitCalibration() {
  auto app = nptool::Application::GetApplication();
  // Read configuration file
  std::string lineBuffer, dataBuffer;
  std::string configFileName;
  if (app->HasFlag("--calibration")) {
    configFileName = app->GetArg("--calibration");
  }
  else {
    return;
  }
  // Open file
  std::ifstream inputConfigFile;
  inputConfigFile.open(configFileName.c_str());

  if (!inputConfigFile.is_open()) {
    message("yellow", "core", "nptool::CalibrationManager", "file not " + configFileName + " not found");
    return;
  }

  else {
    message("green", "core", "nptool::CalibrationManager", "Reading list of files from " + configFileName);
    while (!inputConfigFile.eof()) {
      getline(inputConfigFile, lineBuffer);
      // search for token giving the list of Root files to treat
      if (lineBuffer.compare(0, 19, "CalibrationFilePath") == 0) {
        while (!inputConfigFile.eof()) {
          inputConfigFile >> dataBuffer;

          // ignore comment Line
          if (dataBuffer.compare(0, 1, "%") == 0) {
            inputConfigFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
          }

          else if (!inputConfigFile.eof()) {
            AddFile(dataBuffer);
            message("green", "core", "nptool::CalibrationManager", "Adding file " + dataBuffer);
          }
        }
      }
    }
  }

  LoadParameterFromFile();
  std::cout << "/////////////////////////////////" << std::endl;
}

CalibrationManager::~CalibrationManager() {}

void CalibrationManager::ClearCalibration() { m_CalibrationCoeff.clear(); }

std::vector<double> CalibrationManager::GetCorrection(const std::string& ParameterPath) const {
  std::vector<double> Coeff;
  std::map<std::string, std::vector<double>>::const_iterator it;
  it = m_CalibrationCoeff.find(ParameterPath);

  if (it == m_CalibrationCoeff.end()) {
    /* std::cout << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX " << std::endl
       ; std::cout << " ERROR: PARAMETER " << ParameterPath << " IS NOT FOUND IN THE CALIBRATION DATA BASE  " <<
       std::endl ;
       std::cout << "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX " << std::endl
       ;*/

    return Coeff;
  }

  Coeff = it->second;

  return (Coeff);
}

void CalibrationManager::LoadParameterFromFile() {
  std::ifstream CalibFile;
  std::string DataBuffer, LineBuffer, token;

  unsigned int sizeF = m_FileList.size();
  if (sizeF) { // If calibration parameter are given, suppress all default calibration
    m_CalibrationCoeff.clear();
  }

  for (unsigned int i = 0; i < sizeF; i++) {
    CalibFile.open(m_FileList[i].c_str());
    std::map<std::string, std::string>::iterator it;

    if (!CalibFile) {
      nptool::message("yellow", "core", "nptool::CalibrationManager", "file " + m_FileList[i] + " is missing");
    }

    else {
      while (!CalibFile.eof()) {
        // Read the file Line by line
        getline(CalibFile, LineBuffer);

        // Create a istd::stringstream to manipulate the line easely
        std::istringstream theLine(LineBuffer, std::istringstream::in);
        theLine >> DataBuffer;

        // Comment support, comment symbole is %
        if (DataBuffer.compare(0, 1, "%") == 0) {
          CalibFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        }
        //   Search word in the token list
        token = DataBuffer;
        //   if the word is find, values are read
        std::vector<double> Coeff;
        while (theLine >> DataBuffer) {
          Coeff.push_back(atof(DataBuffer.c_str()));
        }

        //   Check this parameter is not already define
        if (m_CalibrationCoeff.find(token) != m_CalibrationCoeff.end())
          std::cout << "WARNING: Parameter " << token << " Already found. It will be overwritten. " << std::endl;

        //   Add the list of Coeff to the Coeff std::map using Parameter Path as index
        m_CalibrationCoeff[token] = Coeff;
      }
    }
    CalibFile.close();
  }
}

double CalibrationManager::ApplyCalibration(const std::string& ParameterPath, const double& RawValue,
                                            double random) const {
  std::map<std::string, std::vector<double>>::const_iterator it;
  static std::map<std::string, std::vector<double>>::const_iterator ite = m_CalibrationCoeff.end();

  //   Find the good parameter in the Map
  // Using Find method of stl is the fastest way
  it = m_CalibrationCoeff.find(ParameterPath);
  // If the find methods return the end iterator it's mean the parameter was not found
  if (it == ite) {
    return RawValue;
  }

  double val;
  if (random) {
    val = RawValue /*+ gRandom->Uniform(random)*/;
  }
  else
    val = RawValue;

  // The std::vector size give the degree of calibration
  // We just apply the coeff it->second and returned the calibrated value
  double CalibratedValue = 0;
  unsigned int mysize = it->second.size();
  for (unsigned int i = 0; i < mysize; i++) {
    CalibratedValue += it->second[i] * pow(val, (double)i);
  }

  return CalibratedValue;
}
double CalibrationManager::ApplyCalibrationDebug(const std::string& ParameterPath, const double& RawValue,
                                                 double random) const {
  std::map<std::string, std::vector<double>>::const_iterator it;
  static std::map<std::string, std::vector<double>>::const_iterator ite = m_CalibrationCoeff.end();

  //   Find the good parameter in the Map
  // Using Find method of stl is the fastest way
  it = m_CalibrationCoeff.find(ParameterPath);

  // If the find methods return the end iterator it's mean the parameter was not found
  if (it == ite) {
    std::cout << " PARAMETER " << ParameterPath << " IS NOT FOUND IN THE CALIBRATION DATA BASE  " << std::endl;
    return RawValue;
  }

  double val;
  if (random) {
    val = RawValue /*+ gRandom->Uniform(random)*/;
  }
  else
    val = RawValue;

  // Else we take the second part of the element (first is index, ie: parameter path)
  // Second is the std::vector of Coeff
  std::cout << it->first << " :  raw = " << RawValue << "  randomize = " << val << "  coeff = ";
  std::vector<double> Coeff = it->second;

  // The std::vector size give the degree of calibration
  // We just apply the coeff and returned the calibrated value

  double CalibratedValue = 0;
  for (unsigned int i = 0; i < Coeff.size(); i++) {
    std::cout << Coeff[i] << " ";
    CalibratedValue += Coeff[i] * pow(RawValue, (double)i);
  }
  std::cout << "results = " << CalibratedValue << std::endl;
  return CalibratedValue;
}
double CalibrationManager::ApplyResistivePositionCalibration(const std::string& ParameterPath,
                                                             const double& DeltaRawValue) const {
  std::map<std::string, std::vector<double>>::const_iterator it;
  static std::map<std::string, std::vector<double>>::const_iterator ite = m_CalibrationCoeff.end();

  //   Find the good parameter in the Map
  // Using Find method of stl is the fastest way
  it = m_CalibrationCoeff.find(ParameterPath);

  // If the find methods return the end iterator it's mean the parameter was not found
  if (it == ite) {
    return DeltaRawValue;
  }

  // Check that the number of coeff is ok
  if (it->second.size() != 2)
    return DeltaRawValue;

  double CalibratedValue = (DeltaRawValue - it->second[0]) / (it->second[1]);

  return CalibratedValue;
}

double CalibrationManager::ApplyResistivePositionCalibrationDebug(const std::string& ParameterPath,
                                                                  const double& DeltaRawValue) const {
  std::map<std::string, std::vector<double>>::const_iterator it;
  static std::map<std::string, std::vector<double>>::const_iterator ite = m_CalibrationCoeff.end();

  //   Find the good parameter in the Map
  // Using Find method of stl is the fastest way
  it = m_CalibrationCoeff.find(ParameterPath);

  // If the find methods return the end iterator it's mean the parameter was not found
  if (it == ite) {
    std::cout << " PARAMETER " << ParameterPath << " IS NOT FOUND IN THE CALIBRATION DATA BASE  " << std::endl;
    return DeltaRawValue;
  }

  std::vector<double> Coeff = it->second;

  // Check that the number of coeff is ok
  if (Coeff.size() != 2) {
    std::cout << " NUMBER OF COEFF " << Coeff.size() << " IS DIFFERENT THAN TWO " << std::endl;
    return DeltaRawValue;
  }

  double CalibratedValue = (DeltaRawValue - Coeff[0]) / (Coeff[1]);
  std::cout << it->first << " :  raw = " << DeltaRawValue << " coeff = ";
  std::cout << Coeff[0] << " " << Coeff[1] << std::endl;
  std::cout << "results = " << CalibratedValue << std::endl;

  return CalibratedValue;
}

bool CalibrationManager::ApplyThreshold(const std::string& ParameterPath, const double& RawValue) const {
  std::map<std::string, std::vector<double>>::const_iterator it;
  static std::map<std::string, std::vector<double>>::const_iterator ite = m_CalibrationCoeff.end();

  //   Find the good parameter in the Map
  // Using Find method of stl is the fastest way
  it = m_CalibrationCoeff.find(ParameterPath);

  // If the find methods return the end iterator it's mean the parameter was not found
  if (it == ite) {
    return false;
  }

  // The std::vector size give the degree of calibration
  // We just apply the coeff and returned the calibrated value

  double ThresholdValue;

  if (it->second.size() == 2) { // CATS style
    ThresholdValue = it->second[0] + 3 * it->second[1];
  }
  else { // Standard Threshold
    ThresholdValue = it->second[0];
  }

  if (RawValue > ThresholdValue)
    return true;
  else
    return false;
}

double CalibrationManager::ApplySigmoid(const std::string& ParameterPath, const double& RawValue) const {
  std::map<std::string, std::vector<double>>::const_iterator it;
  static std::map<std::string, std::vector<double>>::const_iterator ite = m_CalibrationCoeff.end();
  //   Find the good parameter in the Map
  // Using Find method of stl is the fastest way
  it = m_CalibrationCoeff.find(ParameterPath);
  // If the find methods return the end iterator it's mean the parameter was not found
  if (it == ite) {
    return RawValue;
  }

  std::vector<double> Coeff = it->second;
  // Check that the number of coeff is ok
  if (Coeff.size() != 3) {
    return RawValue;
  }

  return (Coeff[0] / (exp(Coeff[1] * (Coeff[2] - (RawValue /*+gRandom->Uniform(1)*/))) + 1));
}
double CalibrationManager::GetPedestal(const std::string& ParameterPath) const { return GetValue(ParameterPath, 0); }

double CalibrationManager::GetValue(const std::string& ParameterPath, const unsigned int& order) const {
  std::map<std::string, std::vector<double>>::const_iterator it;
  static std::map<std::string, std::vector<double>>::const_iterator ite = m_CalibrationCoeff.end();

  //   Find the good parameter in the Map
  // Using Find method of stl is the fastest way
  it = m_CalibrationCoeff.find(ParameterPath);

  // If the find methods return the end iterator it's mean the parameter was not found
  if (it == ite) {
    return 0;
  }

  // The std::vector size give the degree of calibration
  double Value = 0;
  if (it->second.size() > order) {
    Value = it->second[order];
  }

  return Value;
}

void CalibrationManager::Dump() const {
  std::map<std::string, std::vector<double>>::const_iterator it;

  for (it = m_CalibrationCoeff.begin(); it != m_CalibrationCoeff.end(); it++) {
    std::cout << it->first << std::endl;
    std::cout << it->second[0] << std::endl;
  }
}