ATLAS Offline Software
Loading...
Searching...
No Matches
AtlasFieldCacheCondAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
12
13// ISF_Services include
15
16// Concurrency
17#include "GaudiKernel/ConcurrencyFlags.h"
18
19// PathResolver
21
22// ROOT
23#include "TFile.h"
24#include "TTree.h"
25
27 const std::string& name,
28 ISvcLocator* pSvcLocator)
29 : AthCondAlgorithm(name, pSvcLocator)
30{}
31
33
34StatusCode
36{
37 // Read Handle for the current
39
40 // Read handle for the field map cond object
41 ATH_CHECK(m_mapCondObjInputKey.initialize());
42
43 // Output handle for scale factors/cache
44 ATH_CHECK(m_condObjOutputKey.initialize());
45
46 ATH_MSG_DEBUG("Initialize: Key " << m_condObjOutputKey.fullKey()
47 << " has been succesfully registered ");
48
49 ATH_MSG_INFO("Initialize: Will update current from " <<
50 (m_useDCS ? "conditions" : "parameters"));
51
52 ATH_MSG_INFO("Initialize: useDCS, useSoleCurrent, useToroCurrent. "
53 << (int)m_useDCS << ", " << m_useSoleCurrent << ", "
54 << m_useToroCurrent << " LockMapCurrents "
55 << (int)m_lockMapCurrents);
56
57 return StatusCode::SUCCESS;
58}
59
60StatusCode
61MagField::AtlasFieldCacheCondAlg::execute(const EventContext& ctx) const
62{
63
64 ATH_MSG_DEBUG("execute: entering");
65
66 // Check if output conditions object with field cache object is still valid,
67 // if not replace it with new current scale factors
69 ctx };
70 if (writeHandle.isValid()) {
71 ATH_MSG_DEBUG("execute: CondHandle "
72 << writeHandle.fullKey() << " is already valid. "
73 << " May happen if multiple concurrent events are being "
74 "processed out of order.");
75 return StatusCode::SUCCESS;
76 }
77
78 // This will need to be filled before we construct the condition object
79 Cache cache{};
80
81 if (m_useDCS) {
83 } else {
85 }
86
87 // Must read map cond object to get previously created map
89 ctx };
90 const AtlasFieldMapCondObj* mapCondObj{ *mapReadHandle };
91 if (mapCondObj == nullptr) {
92 ATH_MSG_ERROR("execute: Could not access conditions map for key: "
93 << m_mapCondObjInputKey.fullKey());
94 return StatusCode::FAILURE;
95 }
96
97 // simple pointer to the map, to be give to the AtlasFieldCacheCondObj, used
98 // for the cache field map access
99 const MagField::AtlasFieldMap* fieldMap = mapCondObj->fieldMap();
100
101 // calculate the scale factors
102 if (!m_lockMapCurrents) {
103 scaleField(cache, fieldMap);
104 }
105
106 // save current scale factor in conditions object
107 auto fieldCondObj = std::make_unique<AtlasFieldCacheCondObj>();
108
109 // initialize cond obj with current scale factors and the field svc (needed to
110 // setup cache)
111 fieldCondObj->initialize(
112 cache.m_solScaleFactor, cache.m_torScaleFactor, fieldMap);
113
114 // Record in conditions store the conditions object with scale factors and map
115 // pointer for cache
116 if (writeHandle.record(cache.m_condObjOutputRange, std::move(fieldCondObj))
117 .isFailure()) {
119 "execute: Could not record AtlasFieldCacheCondObj object with "
120 << writeHandle.key() << " with EventRange " << cache.m_condObjOutputRange
121 << " into Conditions Store");
122 return StatusCode::FAILURE;
123 }
124
126 "execute: initialized AtlasFieldCacheCondObj and cache with SFs - sol/tor "
127 << cache.m_solScaleFactor << "/" << cache.m_torScaleFactor
128 << ", EventRange " << cache.m_condObjOutputRange);
129 if (fieldMap) {
130 ATH_MSG_INFO("execute: solenoid zone id " << fieldMap->solenoidZoneId());
131 } else {
132 ATH_MSG_INFO("execute: no map read (currents == 0");
133 }
134
135 return StatusCode::SUCCESS;
136}
137
138StatusCode
140 const EventContext& ctx,
141 Cache& cache) const
142{
143
144 // readin current value
146 const CondAttrListCollection* attrListColl{ *readHandle };
147 if (attrListColl == nullptr) {
148 ATH_MSG_ERROR("updateCurrentFromConditions: Failed to retrieve "
149 "CondAttributeListCollection with key "
150 << m_currInputKey.key());
151 return StatusCode::FAILURE;
152 }
153
154 // Get the validitiy range
155 EventIDRange rangeW;
156 if (!readHandle.range(rangeW)) {
158 "updateCurrentFromConditions: Failed to retrieve validity range for "
159 << readHandle.key());
160 return StatusCode::FAILURE;
161 }
162 cache.m_condObjOutputRange = rangeW;
163 ATH_MSG_INFO("UpdateCurrentFromConditions: Range of input/output is "
164 << cache.m_condObjOutputRange);
165
166 // get magnet currents from DCS
167 double solcur{ 0. };
168 double torcur{ 0. };
169 bool gotsol{ false };
170 bool gottor{ false };
171
172 /*
173 * due to inconsistencies between CONDBR2 and OFLP200/COMP200 (the former
174 * includes channel names in the /EXT/DCS/MAGNETS/SENSORDATA folder, the
175 * latter don't), we try to read currents in both ways
176 */
177 bool hasChanNames{ false };
178 ATH_MSG_INFO("UpdateCurrentFromConditions: Attempt 1 at reading currents "
179 "from DCS (using channel name)");
180 for (CondAttrListCollection::const_iterator itr = attrListColl->begin();
181 itr != attrListColl->end();
182 ++itr) {
183 const std::string& name = attrListColl->chanName(itr->first);
184 ATH_MSG_INFO("UpdateCurrentFromConditions: Trying to read from DCS: "
185 "[channel name, index, value] "
186 << name << " , " << itr->first << " , "
187 << itr->second["value"].data<float>());
188 if (name.compare("") != 0) {
189 hasChanNames = true;
190 }
191 if (name.compare("CentralSol_Current") == 0) {
192 // channel 1 is solenoid current
193 solcur = itr->second["value"].data<float>();
194 gotsol = true;
195 } else if (name.compare("Toroids_Current") == 0) {
196 // channel 3 is toroid current
197 torcur = itr->second["value"].data<float>();
198 gottor = true;
199 }
200 }
201 if (!hasChanNames) {
202 ATH_MSG_INFO("UpdateCurrentFromConditions: Attempt 2 at reading currents "
203 "from DCS (using channel index)");
204 // in no channel is named, try again using channel index instead
205 for (CondAttrListCollection::const_iterator itr = attrListColl->begin();
206 itr != attrListColl->end();
207 ++itr) {
208
209 if (itr->first == 1) {
210 // channel 1 is solenoid current
211 solcur = itr->second["value"].data<float>();
212 gotsol = true;
213 } else if (itr->first == 3) {
214 // channel 3 is toroid current
215 torcur = itr->second["value"].data<float>();
216 gottor = true;
217 }
218 }
219 }
220 if (!gotsol || !gottor) {
221 if (!gotsol)
222 ATH_MSG_ERROR("UpdateCurrentFromConditions: Missing solenoid current in "
223 "DCS information");
224 if (!gottor)
225 ATH_MSG_ERROR("UpdateCurrentFromConditions: Missing toroid current in "
226 "DCS information");
227 return StatusCode::FAILURE;
228 }
229
230 ATH_MSG_INFO("UpdateCurrentFromConditions: Currents read from DCS - solenoid "
231 << solcur << " toroid " << torcur);
232
233 // round to zero if close to zero
234 if (solcur < m_soleMinCurrent) {
235 solcur = 0.0;
236 ATH_MSG_INFO("UpdateCurrentFromConditions: Solenoid is off");
237 }
238 if (torcur < m_toroMinCurrent) {
239 torcur = 0.0;
240 ATH_MSG_INFO("UpdateCurrentFromConditions: Toroids are off");
241 }
242
243 cache.m_solenoidCurrent = solcur;
244 cache.m_toroidCurrent = torcur;
245
246 return StatusCode::SUCCESS;
247}
248
249StatusCode
251 const EventContext& ctx,
252 Cache& cache) const
253{
254
255 // take the current values from JobOptions
256 double solcur{ m_useSoleCurrent };
257 double torcur{ m_useToroCurrent };
258 if (solcur < m_soleMinCurrent) {
259 solcur = 0.0;
260 ATH_MSG_INFO("updateCurrentFromParameters: Solenoid is off");
261 }
262 if (torcur < m_toroMinCurrent) {
263 torcur = 0.0;
264 ATH_MSG_INFO("updateCurrentFromParameters: Toroids are off");
265 }
266 cache.m_solenoidCurrent = solcur;
267 cache.m_toroidCurrent = torcur;
268
269 // in case of reading from DB or from FILE, the EventID range is always the
270 // current run
271 EventIDBase start, stop;
272 start.set_run_number(ctx.eventID().run_number());
273 start.set_lumi_block(0);
274 stop.set_run_number(ctx.eventID().run_number() + 1);
275 stop.set_lumi_block(0);
276 cache.m_condObjOutputRange = EventIDRange(start, stop);
277
278 ATH_MSG_INFO("updateCurrentFromParameters: Update from job options: Range of "
279 "input/output is "
280 << cache.m_condObjOutputRange);
281
282 return StatusCode::SUCCESS;
283}
284
285void
287 Cache& cache,
288 const MagField::AtlasFieldMap* fieldMap) const
289{
290 // Calculate the scale factor for solenoid and toroid.
291
292 // We have one piece of information coming from the map.
293 // Do we have a map including both Toroid/Solenoid or only one.
294 // The values are typically the nominal value for the map
295 // or 0.
296 bool mapHasToroid = fieldMap && (fieldMap->toroidCurrent()>0);
297 bool mapHasSolenoid = fieldMap && (fieldMap->solenoidCurrent()>0);
298
299 // Then we have the info we get on the actual current we have
300 // So we might need to scale the map with it.
301 // Set the SF for the solenoid
302 if (cache.m_solenoidCurrent > 0.0) {
303 if (mapHasSolenoid &&
304 std::abs(cache.m_solenoidCurrent / fieldMap->solenoidCurrent() - 1.0) >
305 0.001) {
306 cache.m_solScaleFactor =
307 cache.m_solenoidCurrent / fieldMap->solenoidCurrent();
308 }
309 ATH_MSG_INFO("scaleField: Solenoid field scale factor "
310 << cache.m_solScaleFactor
311 << ". Desired current and map current: "
312 << cache.m_solenoidCurrent << ","
313 << (fieldMap ? fieldMap->solenoidCurrent() : 0));
314 } else {
315 // No SF set, set it to 0 - current was set to zero either here or for the
316 // map, or the map was not read in
317 cache.m_solScaleFactor = 0;
318 ATH_MSG_INFO("scaleField: Solenoid field scale factor "
319 << cache.m_solScaleFactor
320 << ". Desired current and map current: "
321 << cache.m_solenoidCurrent << ","
322 << ((fieldMap) ? fieldMap->solenoidCurrent() : 0));
323 }
324
325
326 // Set the SF for the toroid
327 if (cache.m_toroidCurrent > 0.0) {
328 if (mapHasToroid &&
329 std::abs(cache.m_toroidCurrent / fieldMap->toroidCurrent() - 1.0) >
330 0.001) {
331 // scale the field in all zones except for the solenoid zone
332 cache.m_torScaleFactor =
333 cache.m_toroidCurrent / fieldMap->toroidCurrent();
334 }
335 ATH_MSG_INFO("scaleField: Toroid field scale factor "
336 << cache.m_torScaleFactor
337 << ". Desired current and map current: "
338 << cache.m_toroidCurrent << ","
339 << (fieldMap ? fieldMap->toroidCurrent() : 0));
340 } else {
341 cache.m_torScaleFactor = 0;
342 ATH_MSG_INFO("scaleField: Toroid field scale factor "
343 << cache.m_torScaleFactor
344 << ". Desired current and map current: "
345 << cache.m_toroidCurrent << ","
346 << ((fieldMap) ? fieldMap->toroidCurrent() : 0));
347 }
348 // If the map was toroid only set both to the toroid
349 // the 0s in the solenoid should be covered by the map
350 if (mapHasToroid && !mapHasSolenoid) {
352 }
353 // if the map is solenoid only set both to the solenoid
354 // the 0s in the toroid should be covered by the map
355 if (!mapHasToroid && mapHasSolenoid) {
357 }
358}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
Base class for conditions algorithms.
const MagField::AtlasFieldMap * fieldMap() const
This class is a collection of AttributeLists where each one is associated with a channel number.
const_iterator end() const
const_iterator begin() const
Access to Chan/AttributeList pairs via iterators.
const std::string & chanName(ChanNum chanNum) const
find name for particular channel
ChanAttrListMap::const_iterator const_iterator
void scaleField(Cache &cache, const MagField::AtlasFieldMap *fieldMap) const
Gaudi::Property< double > m_useSoleCurrent
Gaudi::Property< double > m_useToroCurrent
SG::WriteCondHandleKey< AtlasFieldCacheCondObj > m_condObjOutputKey
Gaudi::Property< double > m_soleMinCurrent
StatusCode updateCurrentFromConditions(const EventContext &ctx, Cache &cache) const
StatusCode updateCurrentFromParameters(const EventContext &ctx, Cache &cache) const
SG::ReadCondHandleKey< CondAttrListCollection > m_currInputKey
Gaudi::Property< double > m_toroMinCurrent
StatusCode initialize() override final
AtlasFieldCacheCondAlg(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< bool > m_lockMapCurrents
SG::ReadCondHandleKey< AtlasFieldMapCondObj > m_mapCondObjInputKey
StatusCode execute(const EventContext &ctx) const override final
Map for magnetic field.
float toroidCurrent() const
float solenoidCurrent() const
bool range(EventIDRange &r)
const std::string & key() const
const std::string & key() const
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
const DataObjID & fullKey() const