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