/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus * * MAUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MAUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MAUS. If not, see . * */ #include "Utils/EMRCalibrationMap.hh" #include "Utils/EMRChannelMap.hh" namespace MAUS { EMRCalibrationMap::EMRCalibrationMap() { pymod_ok = true; if (!this->InitializePyMod()) pymod_ok = false; } EMRCalibrationMap::~EMRCalibrationMap() { _Ckey.clear(); _eps_MA.resize(0); _eps_SA.resize(0); } bool EMRCalibrationMap::InitializeFromCards(Json::Value configJSON) { // Fetch variables _number_of_planes = configJSON["EMRnumberOfPlanes"].asInt(); _number_of_bars = configJSON["EMRnumberOfBars"].asInt(); _fom = configJSON["EMRfom"].asString(); // Fill the vector containing all EMR channel keys. this->MakeEMRChannelKeys(); std::string calibFile; // Get the calibration source and convert it to lower cases std::string source = JsonWrapper::GetProperty(configJSON, "EMR_calib_source", JsonWrapper::stringValue).asString(); std::transform(source.begin(), source.end(), source.begin(), std::ptr_fun(std::tolower)); if (source != "file" && source != "cdb") { Squeak::mout(Squeak::error) << "Invalid EMR_calib_source datacard." << std::endl; return false; } // Load the calibration file or find the right CDB entry char* pMAUS_ROOT_DIR = getenv("MAUS_ROOT_DIR"); if (!pMAUS_ROOT_DIR) { Squeak::mout(Squeak::error) << "Could not find the $MAUS_ROOT_DIR environmental variable." << std::endl; Squeak::mout(Squeak::error) << "Did you try running: source env.sh ?" << std::endl; return false; } bool fromDB = true; if (source == "file") { // Get the calibration text files from the Json document. calibFile = std::string(pMAUS_ROOT_DIR) + configJSON["EMR_calib_file"].asString(); fromDB = false; } else { // Get the CDB calibration validity start date _calibDate = JsonWrapper::GetProperty(configJSON, "EMR_calib_date_from", JsonWrapper::stringValue).asString(); } // Load the calibration constants. bool loaded; if (!fromDB) { loaded = this->Initialize(calibFile); } else { // Get calib from CDB instead of file if (!pymod_ok) return false; loaded = this->InitializeFromCDB(); } if (!loaded) return false; return true; } bool EMRCalibrationMap::InitializeFromCDB() { bool status = LoadFromCDB(); return status; } bool EMRCalibrationMap::Initialize(std::string calibFile) { bool status = Load(calibFile); return status; } int EMRCalibrationMap::MakeEMRChannelKeys() { for (int iPlane = -1; iPlane < _number_of_planes; iPlane++) // NB: global average (-1) for (int iBar = -1; iBar < _number_of_bars; iBar++) // NB: average (-1), test channels (0) _Ckey.push_back(EMRChannelKey(iPlane, iPlane%2, iBar, "emr")); int nChannels = _Ckey.size(); _eps_MA.resize(nChannels); _eps_SA.resize(nChannels); return nChannels; } bool EMRCalibrationMap::LoadFromCDB() { this->GetCalib("EMR", "epsilon", _calibDate); try { while (!epsstr.eof()) { char pmt[10], fom[10]; int plane(-9), bar(-9); double epsilon(-1.0); epsstr >> pmt >> fom >> plane >> bar >> epsilon; int n = FindEMRChannelKey(EMRChannelKey(plane, plane%2, bar, "emr")); if (strcmp(fom, _fom.c_str()) == 0 && n != NOCALIB) { if (strcmp(pmt, "MA") == 0) _eps_MA[n] = epsilon; if (strcmp(pmt, "SA") == 0) _eps_SA[n] = epsilon; } } } catch (MAUS::Exception e) { Squeak::mout(Squeak::error) << "Error in EMRCalibrationMap::LoadFromCDB() : Error during loading. " << std::endl << e.GetMessage() << std::endl; return false; } return true; } void EMRCalibrationMap::GetCalib(std::string devname, std::string caltype, std::string fromdate) { PyObject *py_arg = NULL, *py_value = NULL; // setup the arguments to get_calib_func // the arguments are 3 strings // arg1 = device name (EMR) uppercase // arg2 = calibration type (epsilon) lowercase // arg3 = valid_from_date == either "current" or an actual date 'YYYY-MM-DD HH:MM:SS' // default date argument is "current" // this is set via EMR_calib_date_from card in ConfigurationDefaults py_arg = Py_BuildValue("(sss)", devname.c_str(), caltype.c_str(), fromdate.c_str()); if (py_arg == NULL) { PyErr_Clear(); throw(MAUS::Exception(MAUS::Exception::recoverable, "Failed to resolve arguments to get_calib", "MAUSEvaluator::evaluate")); } if (_get_calib_func != NULL && PyCallable_Check(_get_calib_func)) { py_value = PyObject_CallObject(_get_calib_func, py_arg); // setup the streams to hold the different calibs if (py_value != NULL && strcmp(caltype.c_str(), "epsilon") == 0) epsstr << PyString_AsString(py_value); } if (py_value == NULL) { PyErr_Clear(); Py_XDECREF(py_arg); throw(MAUS::Exception(MAUS::Exception::recoverable, "Failed to parse argument "+devname, "GetCalib::get_calib")); } // clean up Py_XDECREF(py_value); Py_XDECREF(py_arg); } bool EMRCalibrationMap::Load(std::string calibFile) { // Check the calibration file std::ifstream stream(calibFile.c_str()); if (!stream) { Squeak::mout(Squeak::error) << "Error in EMRCalibrationMap::Load : Can't open EMR calibration file." << calibFile << std::endl; return false; } // Fill the arrays of correction factors try { while (!stream.eof()) { char pmt[10], fom[10]; int plane(-9), bar(-9); double epsilon(-1.0); stream >> pmt >> fom >> plane >> bar >> epsilon; int n = FindEMRChannelKey(EMRChannelKey(plane, plane%2, bar, "emr")); if (strcmp(fom, _fom.c_str()) == 0 && n != NOCALIB) { if (strcmp(pmt, "MA") == 0) _eps_MA[n] = epsilon; if (strcmp(pmt, "SA") == 0) _eps_SA[n] = epsilon; } } } catch (MAUS::Exception e) { Squeak::mout(Squeak::error) << "Error in EMRCalibrationMap::Load() : Error during loading. " << std::endl << e.GetMessage() << std::endl; return false; } return true; } int EMRCalibrationMap::FindEMRChannelKey(EMRChannelKey key) const { for (unsigned int i = 0; i < _Ckey.size(); i++ ) if (_Ckey.at(i) == key) return i; return NOCALIB; } double EMRCalibrationMap::Eps(EMRChannelKey key, const char *pmt) const { int n = FindEMRChannelKey(key); double epsilon = 1.0; if (n != NOCALIB) { if (strcmp(pmt, "MA") == 0) epsilon = _eps_MA[n]; else if (strcmp(pmt, "SA") == 0) epsilon = _eps_SA[n]; else Squeak::mout(Squeak::error) << "Wrong PMT ID" << std::endl; if ( epsilon ) return epsilon; } // std::cout << "EMRCalibrationMap -> No " << pmt << " calibration for " << key << std::endl; return NOCALIB; } void EMRCalibrationMap::Print() { std::cout << "====================== EMRCalibrationMap =========================" << std::endl; std::cout << " Number of channels : " << _Ckey.size() << std::endl; for (unsigned int i = 0; i < _Ckey.size(); i++) { std::cout << _Ckey[i] << " MA :" << _eps_MA[i] << std::endl; std::cout << _Ckey[i] << " SA :" << _eps_SA[i] << std::endl; } std::cout<< "===================================================================" << std::endl; } bool EMRCalibrationMap::InitializePyMod() { PyObject* calib_mod = PyImport_ImportModule("calibration.get_emr_calib"); if (calib_mod == NULL) { std::cerr << "Failed to import get_emr_calib module" << std::endl; return false; } PyObject* calib_mod_dict = PyModule_GetDict(calib_mod); PyObject* t_calib = NULL; if (calib_mod_dict != NULL) { PyObject* calib_init = PyDict_GetItemString(calib_mod_dict, "GetCalib"); if (PyCallable_Check(calib_init)) { t_calib = PyObject_Call(calib_init, NULL, NULL); } } if (t_calib == NULL) { std::cerr << "Failed to instantiate get_emr_calib" << std::endl; return false; } // Get the get_calib_func() function _get_calib_func = PyObject_GetAttrString(t_calib, "get_calib"); if (_get_calib_func == NULL) { std::cerr << "Failed to find get_calib function" << std::endl; return false; } return true; } }