ATLAS Offline Software
Loading...
Searching...
No Matches
ZdcInjPulserAmpMap.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
7#include <fstream>
8
9// Get singleton instance
10//
12{
13 static const ZdcInjPulserAmpMap pulser_map;
14 return &pulser_map;
15}
16
17
18//constructor
20{
21 msg().setLevel(MSG::INFO);
22
23 // std::string filePath = PathResolverFindCalibFile("ZdcConditions/ZDC_InjectPulseSteps.json"); // change back file name after other changes get merged + ready for T0 reprocessing
24 std::string filePath = PathResolverFindCalibFile("ZdcConditions/INJpulser_combined_2024.json");
25
26 if (!filePath.empty())
27 {
28 ATH_MSG_INFO( "ZdcInjPulserAmpMap::found ZDC JSON at " << filePath );
29 }
30 else
31 {
32 ATH_MSG_WARNING( "ZdcInjPulserAmpMap constructor, JSON file not found in search path, trying local file" ) ;
33 filePath = "./ZDC_InjectPulseSteps.json";
34 }
35
36
37 std::ifstream ifs(filePath);
38 if (!ifs.is_open()) {
39 ATH_MSG_FATAL("ZdcInjPulserAmpMap constructor, JSON file cannot be opened!" ) ;
40 }
41
42 m_filePath = std::move(filePath);
43 if (parseJsonFile(ifs)) m_validJSon = true;;
44}
45
46bool ZdcInjPulserAmpMap::parseJsonFile(std::ifstream& ifs)
47{
48 try {
49 nlohmann::json j = nlohmann::json::parse(ifs);
50
51 // Check for the existence of the run range section of the json file
52 //
53 auto rangeIter = j.find("RunRanges");
54 if (rangeIter == j.end()) return false;
55
56 //
57 // We loop over all the defined run ranges and save
58 //
59 for (json range : *rangeIter) {
60 unsigned int first = range.at("First");
61 unsigned int last = range.at("Last");
62 std::string name = range.at("StepsConfig");
63 float scale = range.at("ScaleFactor");
64
65 m_runRangeDescrs.push_back(std::make_tuple(first, last, name, scale));
66
67 ATH_MSG_DEBUG( "ZdcInjPulserAmpMap::found run range: first, last = " << first << ", " << last
68 << ", config name = " << name << ", scale factor = " << scale );
69 }
70
71 auto stepConfigIter = j.find("StepConfigurations");
72 if (stepConfigIter == j.end()) return false;
73
74 // Now loop over the configurations and save
75 //
76 for (json::iterator configIt = stepConfigIter->begin(); configIt != stepConfigIter->end(); ++configIt) {
77 std::string confName = configIt.key();
78
79 // First we make a spot in the map
80 //
81 auto [insertIter, insertResult] = m_stepsConfigs.insert(std::make_pair(confName, StepsDescr()));
82 if (!insertResult) return false;
83
84 // And now we fill it
85 //
86 json steps = configIt.value();
87 if (!steps.is_array()) {
88 return false;
89 }
90
91 // Unpack the elements of the step confg array
92 //
93 StepsDescr& stepsDesc = insertIter->second;
94 readPulserSteps(stepsDesc, steps);
95
96 ATH_MSG_DEBUG( "ZdcInjPulserAmpMap::found steps configuration with name " << confName << ", starting LB = "
97 << stepsDesc.first << ", number of LBs = " << stepsDesc.second.size());
98 }
99 }
100 catch (...) {
101 return false;
102 }
103
104 return true;
105}
106
108{
109 // Loop over all entries in the json array
110 //
111 for (unsigned int index = 0; index < stepsJson.size(); index++) {
112 const json& elem = stepsJson[index];
113
114 // Get the starting LB entry in the json if it exists
115 //
116 if (index ==0 && elem.size() == 1) {
117 if (elem.find("startLB") != elem.end()) {
118 steps.first = elem["startLB"];
119 }
120 }
121 else {
122 // Fill out the pulser amplitudes for this step
123 //
124 fillVVector(steps.second, elem);
125 }
126 }
127}
128
129void ZdcInjPulserAmpMap::fillVVector(StepsVector& stepVec, const nlohmann::json& entry)
130{
131 unsigned int nStep = entry.at("nStep");
132 float vStart = entry.at("vStart");
133 float vStep = entry.at("vStep");
134
135 float voltage = vStart;
136 for (size_t step = 0; step < nStep; step++) {
137 stepVec.push_back(voltage);
138 voltage += vStep;
139 }
140}
141
142ZdcInjPulserAmpMap::Token ZdcInjPulserAmpMap::lookupRun(unsigned int runNumber, bool allowDefault)
143{
144 std::string configName = (allowDefault ? "Default" : "_none_");
145 float scaleFactor = 1;
146
147 for ( auto rangeDescr : m_runRangeDescrs) {
148 if (runNumber >= std::get<0>(rangeDescr) && runNumber < std::get<1>(rangeDescr)) {
149 configName = std::get<2>(rangeDescr);
150 scaleFactor = std::get<3>(rangeDescr);
151
152 ATH_MSG_INFO( "ZdcInjPulserAmpMap::lookupRun(): found config name " << configName << " for run number "
153 << runNumber);
154 }
155 }
156
157 if (configName == "Default") {
158 ATH_MSG_WARNING("ZdcInjPulserAmpMap::lookupRun(): no valid configuration found for run number " << runNumber
159 << ". Using Default configuration.");
160 }
161
162 if (configName == "_none_") {
163 ATH_MSG_ERROR("ZdcInjPulserAmpMap::lookupRun(): no valid configuration found for run number " << runNumber
164 << "; Default configuration is NOT allowed. Will return an invalid (empty) token.");
165 }
166
167 // Find the corresponding configuration -- we hope
168 //
169 auto findIter = m_stepsConfigs.find(configName);
170 if (findIter == m_stepsConfigs.end()) return Token(); // config name doesn't match to any step configuration: return an invalid token
171
172 // Now we make a new active configuration -- the only thing that needs to be thread-protected
173 //
174 const std::lock_guard<std::mutex> lock(m_lock);
175
176 // Put a new entry in the active configuration vector
177 //
178 int newIndex = m_activeConfigs.size();
179 m_activeConfigs.push_back(&findIter->second);
180
181 ATH_MSG_DEBUG( "ZdcInjPulserAmpMap::lookupRun(): creating token for run number " << runNumber
182 << " with index " << newIndex << ", and scaleFactor " << scaleFactor);
183
184 return Token(newIndex, scaleFactor);
185}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
std::map< std::string, StepsDescr > m_stepsConfigs
std::vector< const StepsDescr * > m_activeConfigs
bool parseJsonFile(std::ifstream &ifs)
std::pair< unsigned int, StepsVector > StepsDescr
void readPulserSteps(StepsDescr &steps, const json &stepsJson)
static const ZdcInjPulserAmpMap * getInstance()
std::vector< float > StepsVector
std::vector< RunRangeDescr > m_runRangeDescrs
Token lookupRun(unsigned int runNumber, bool allowDefault=false)
void fillVVector(StepsVector &stepVec, const nlohmann::json &entry)
MsgStream & msg() const
The standard message stream.
AsgMessaging(const std::string &name)
Constructor with a name.
Definition index.py:1