ATLAS Offline Software
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 
13 // ISF_Services include
14 #include "AtlasFieldCacheCondAlg.h"
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  : AthReentrantAlgorithm(name, pSvcLocator)
30 {}
31 
33 
36 {
37  // Read Handle for the current
38  ATH_CHECK(m_currInputKey.initialize(m_useDCS));
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 
61 MagField::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
68  SG::WriteCondHandle<AtlasFieldCacheCondObj> writeHandle{ m_condObjOutputKey,
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) {
82  ATH_CHECK(updateCurrentFromConditions(ctx, cache));
83  } else {
84  ATH_CHECK(updateCurrentFromParameters(ctx, cache));
85  }
86 
87  // Must read map cond object to get previously created map
88  SG::ReadCondHandle<AtlasFieldMapCondObj> mapReadHandle{ m_mapCondObjInputKey,
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 
125  ATH_MSG_INFO(
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 
140  const EventContext& ctx,
141  Cache& cache) const
142 {
143 
144  // readin current value
145  SG::ReadCondHandle<CondAttrListCollection> readHandle{ m_currInputKey, ctx };
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 
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 
285 void
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) {
351  cache.m_solScaleFactor = cache.m_torScaleFactor;
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) {
356  cache.m_torScaleFactor = cache.m_solScaleFactor;
357  }
358 }
MagField::AtlasFieldCacheCondAlg::scaleField
void scaleField(Cache &cache, const MagField::AtlasFieldMap *fieldMap) const
Definition: AtlasFieldCacheCondAlg.cxx:286
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
AtlasFieldMapCondObj
Definition: AtlasFieldMapCondObj.h:12
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
AtlasFieldCacheCondAlg.h
PixelModuleFeMask_create_db.stop
int stop
Definition: PixelModuleFeMask_create_db.py:76
CondAttrListCollection
This class is a collection of AttributeLists where each one is associated with a channel number....
Definition: CondAttrListCollection.h:52
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
MagField::AtlasFieldMap::toroidCurrent
float toroidCurrent() const
Definition: AtlasFieldMap.h:61
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MagField::AtlasFieldCacheCondAlg::Cache::m_solenoidCurrent
float m_solenoidCurrent
Definition: AtlasFieldCacheCondAlg.h:39
MagField::AtlasFieldCacheCondAlg::execute
StatusCode execute(const EventContext &ctx) const override final
Definition: AtlasFieldCacheCondAlg.cxx:61
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
MagField::AtlasFieldMap
Map for magnetic field.
Definition: AtlasFieldMap.h:39
MagField::AtlasFieldCacheCondAlg::initialize
StatusCode initialize() override final
Definition: AtlasFieldCacheCondAlg.cxx:35
MagField::AtlasFieldCacheCondAlg::updateCurrentFromParameters
StatusCode updateCurrentFromParameters(const EventContext &ctx, Cache &cache) const
Definition: AtlasFieldCacheCondAlg.cxx:250
CondAttrListCollection::const_iterator
ChanAttrListMap::const_iterator const_iterator
Definition: CondAttrListCollection.h:63
MagField::AtlasFieldMap::solenoidZoneId
int solenoidZoneId() const
Definition: AtlasFieldMap.h:62
MagField::AtlasFieldCacheCondAlg::~AtlasFieldCacheCondAlg
virtual ~AtlasFieldCacheCondAlg()
MagField::AtlasFieldCacheCondAlg::AtlasFieldCacheCondAlg
AtlasFieldCacheCondAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: AtlasFieldCacheCondAlg.cxx:26
MagField::AtlasFieldCacheCondAlg::Cache::m_condObjOutputRange
EventIDRange m_condObjOutputRange
Definition: AtlasFieldCacheCondAlg.h:45
MagField::AtlasFieldCacheCondAlg::Cache
Definition: AtlasFieldCacheCondAlg.h:38
MagField::AtlasFieldCacheCondAlg::updateCurrentFromConditions
StatusCode updateCurrentFromConditions(const EventContext &ctx, Cache &cache) const
Definition: AtlasFieldCacheCondAlg.cxx:139
SG::WriteCondHandle
Definition: WriteCondHandle.h:26
MagField::AtlasFieldMap::solenoidCurrent
float solenoidCurrent() const
Definition: AtlasFieldMap.h:60
MagField::AtlasFieldCacheCondAlg::Cache::m_torScaleFactor
double m_torScaleFactor
Definition: AtlasFieldCacheCondAlg.h:42
MagField::AtlasFieldCacheCondAlg::Cache::m_solScaleFactor
double m_solScaleFactor
Definition: AtlasFieldCacheCondAlg.h:41
MagField::AtlasFieldCacheCondAlg::Cache::m_toroidCurrent
float m_toroidCurrent
Definition: AtlasFieldCacheCondAlg.h:40