File indexing completed on 2025-10-31 09:22:25
0001 
0002 
0003 
0004 
0005 
0006 #pragma once
0007 #include <JANA/Calibrations/JCalibration.h>
0008 #include <JANA/Calibrations/JCalibrationFile.h>
0009 #include <JANA/Calibrations/JCalibrationGenerator.h>
0010 
0011 #include <JANA/JService.h>
0012 
0013 #include <algorithm>
0014 #include "JANA/Services/JParameterManager.h"
0015 #include "JResource.h"
0016 
0017 class JCalibrationManager : public JService {
0018 
0019     vector<JCalibration *> m_calibrations;
0020     vector<JResource *> m_resource_managers;
0021     vector<JCalibrationGenerator *> m_calibration_generators;
0022 
0023     pthread_mutex_t m_calibration_mutex;
0024     pthread_mutex_t m_resource_manager_mutex;
0025 
0026     std::shared_ptr<JParameterManager> m_params;
0027 
0028     std::string m_url = "file://./";
0029     std::string m_context = "default";
0030 
0031 public:
0032 
0033     JCalibrationManager() { 
0034         pthread_mutex_init(&m_calibration_mutex, nullptr);
0035         pthread_mutex_init(&m_resource_manager_mutex, nullptr);
0036 
0037         SetPrefix("jana"); 
0038     }
0039 
0040     void Init() {
0041 
0042         
0043         
0044 
0045         if (getenv("JANA_CALIB_URL") != nullptr) m_url = getenv("JANA_CALIB_URL");
0046         if (getenv("JANA_CALIB_CONTEXT") != nullptr) m_context = getenv("JANA_CALIB_CONTEXT");
0047 
0048         m_params = GetApplication()->GetService<JParameterManager>();
0049         m_params->SetDefaultParameter("JANA:CALIB_URL", m_url, "URL used to access calibration constants");
0050         m_params->SetDefaultParameter("JANA:CALIB_CONTEXT", m_context,
0051                                     "Calibration context to pass on to concrete JCalibration derived class");
0052         m_params->RegisterParameter("ccdb:cache", true, "Enable CCDB Caching");
0053 
0054         for(auto generator:m_calibration_generators) {
0055             generator->SetApplication(GetApplication());
0056         }
0057     }
0058 
0059     void AddCalibrationGenerator(JCalibrationGenerator *generator) {
0060         m_calibration_generators.push_back(generator);
0061     };
0062 
0063     void RemoveCalibrationGenerator(JCalibrationGenerator *generator) {
0064 
0065         vector<JCalibrationGenerator *> &f = m_calibration_generators;
0066         vector<JCalibrationGenerator *>::iterator iter = std::find(f.begin(), f.end(), generator);
0067         if (iter != f.end())f.erase(iter);
0068     }
0069 
0070     vector<JCalibrationGenerator *> GetCalibrationGenerators() { return m_calibration_generators; }
0071 
0072     void GetJCalibrations(vector<JCalibration *> &calibs) { calibs = m_calibrations; }
0073 
0074     JCalibration *GetJCalibration(unsigned int run_number) {
0075         
0076         
0077         
0078         
0079         
0080         
0081         
0082         
0083 
0084 
0085         
0086         pthread_mutex_lock(&m_calibration_mutex);
0087 
0088         vector<JCalibration *>::iterator iter = m_calibrations.begin();
0089         for (; iter != m_calibrations.end(); iter++) {
0090             if ((*iter)->GetRun() != (int) run_number)continue;
0091             if ((*iter)->GetURL() != m_url)continue;                    
0092             if ((*iter)->GetContext() != m_context)continue;        
0093             
0094             JCalibration *g = *iter;
0095             pthread_mutex_unlock(&m_calibration_mutex);
0096             return g;
0097         }
0098 
0099         
0100         
0101         
0102         
0103         
0104         
0105 
0106         JCalibrationGenerator *gen = nullptr;
0107         double liklihood = 0.0;
0108         for (unsigned int i = 0; i < m_calibration_generators.size(); i++) {
0109             double my_liklihood = m_calibration_generators[i]->CheckOpenable(m_url, run_number, m_context);
0110             if (my_liklihood > liklihood) {
0111                 liklihood = my_liklihood;
0112                 gen = m_calibration_generators[i];
0113             }
0114         }
0115 
0116         
0117         JCalibration *g = nullptr;
0118         if (gen) {
0119             g = gen->MakeJCalibration(m_url, run_number, m_context);
0120         }
0121         if (gen == nullptr && (m_url.find("file://") == 0)) {
0122             g = new JCalibrationFile(m_url, run_number, m_context);
0123         }
0124         if (g) {
0125             m_calibrations.push_back(g);
0126             LOG_INFO(m_logger)
0127                 << "Created JCalibration object of type: " << g->className() << "\n"
0128                 << "  Generated via: "
0129                 << (gen == nullptr ? "fallback creation of JCalibrationFile" : gen->Description())
0130                 << "\n"
0131                 << "  Run: " << g->GetRun() << "\n"
0132                 << "  URL: " << g->GetURL() << "\n"
0133                 << "  context: " << g->GetContext()
0134                 << LOG_END;
0135         } else {
0136             JLogMessage m(m_logger, JLogger::Level::ERROR);
0137             m << "Unable to create JCalibration object!\n"
0138               << "  Run: " << run_number << "\n"
0139               << "  URL: " << m_url << "\n"
0140               << "  context: " << m_context << "\n";
0141 
0142             if (gen) {
0143                 m << "  Attempted to use generator: " << gen->Description();
0144             } else {
0145                 m << "  No appropriate generators found. Attempted JCalibrationFile";
0146             }
0147             std::move(m) << LOG_END;
0148         }
0149 
0150         
0151         pthread_mutex_unlock(&m_calibration_mutex);
0152         return g;
0153     }
0154 
0155     template<class T>
0156     bool GetCalib(unsigned int run_number, unsigned int event_number, string namepath, map<string, T> &vals) {
0157         
0158         
0159 
0160         
0161         
0162         
0163 
0164         vals.clear();
0165         JCalibration *calib = GetJCalibration(run_number);
0166         if (!calib) {
0167             LOG_ERROR(m_logger) << "Unable to get JCalibration object for run " << run_number << LOG_END;
0168             return true;
0169         }
0170         return calib->Get(namepath, vals, event_number);
0171     }
0172 
0173     template<class T>
0174     bool GetCalib(unsigned int run_number, unsigned int event_number, string namepath, vector<T> &vals) {
0175         
0176         
0177 
0178         vals.clear();
0179         JCalibration *calib = GetJCalibration(run_number);
0180         if (!calib) {
0181             LOG_ERROR(m_logger) << "Unable to get JCalibration object for run " << run_number << LOG_END;
0182             return true;
0183         }
0184         return calib->Get(namepath, vals, event_number);
0185     }
0186 
0187     JResource* GetResource(unsigned int run_number = 0) {
0188 
0189         
0190         
0191         
0192         
0193         
0194         
0195         
0196         
0197         
0198         
0199 
0200         
0201         if (run_number == 0) {
0202             pthread_mutex_lock(&m_resource_manager_mutex);
0203             if (m_resource_managers.empty()) {
0204                 if (m_calibrations.empty()) {
0205                     m_resource_managers.push_back(new JResource(m_params, nullptr));
0206                 } else {
0207                     m_resource_managers.push_back(new JResource(m_params, m_calibrations[0]));
0208                 }
0209             }
0210             pthread_mutex_unlock(&m_resource_manager_mutex);
0211 
0212             return m_resource_managers[0];
0213         }
0214 
0215         
0216         JCalibration *jcalib = GetJCalibration(run_number);
0217         for (unsigned int i = 0; i < m_resource_managers.size(); i++) {
0218             if (m_resource_managers[i]->GetJCalibration() == jcalib)return m_resource_managers[i];
0219         }
0220 
0221         
0222         JResource *resource_manager = new JResource(m_params, jcalib);
0223         pthread_mutex_lock(&m_resource_manager_mutex);
0224         m_resource_managers.push_back(resource_manager);
0225         pthread_mutex_unlock(&m_resource_manager_mutex);
0226 
0227         return resource_manager;
0228 
0229     }
0230 
0231 };
0232 
0233