Skip to content
Snippets Groups Projects
Commit ea084427 authored by R D Schaffer's avatar R D Schaffer
Browse files

updating map alg to handle job opt setting of currents for online running when...

updating map alg to handle job opt setting of currents for online running when reading the file names from cool, and for offline added check of DCS currents to all reading only sol or tor file. Removing logic in cache to set currents to 0 for online as is not done directly for maps.
parent 34eae6fd
No related merge requests found
......@@ -56,8 +56,15 @@ namespace MagField {
EventIDRange m_mapCondObjOutputRange {EventIDRange()}; // default range covers everything (run/event and timestamp)
};
// get the field map
StatusCode updateFieldMap(const EventContext& ctx, Cache& cache) const;
// get DCS currents to decide which field map file to read
StatusCode checkCurrentFromConditions(const EventContext& ctx,
double& soleCurrent,
double& toroCurrent,
EventIDRange& rangeDCS) const;
/// map file names - if not read from cool
Gaudi::Property<std::string> m_fullMapFilename {this,
"FullMapFile", "MagneticFieldMaps/bfieldmap_7730_20400_14m.root",
......@@ -74,6 +81,12 @@ namespace MagField {
Gaudi::Property<double> m_mapToroCurrent {this,
"MapToroCurrent", 20400., "Nominal toroid current (A)"};
// threshold below which currents are considered zero
Gaudi::Property<double> m_soleMinCurrent {this,
"SoleMinCurrent", 1.0, "Minimum solenoid current (A) for which solenoid is considered ON"};
Gaudi::Property<double> m_toroMinCurrent {this,
"ToroMinCurrent", 1.0, "Minimum toroid current (A) for which toroid is considered ON"};
// flag to load map on start
Gaudi::Property<bool> m_loadMapOnStart {this,
......@@ -94,6 +107,12 @@ namespace MagField {
{this,
"AtlasFieldMapCondObj", "fieldMapCondObj", "Name of key for the Magnetic Field conditions object with the map file names"};
// COOL folder name containing current information
// current input key
SG::ReadCondHandleKey<CondAttrListCollection> m_currInputKey
{this,
"COOLCurrentsFolderName", "/EXT/DCS/MAGNETS/SENSORDATA", "Name of the COOL folder containing magnet currents"};
ServiceHandle<ICondSvc> m_condSvc { this,
"CondSvc", "CondSvc", "conditions service" };
......
......@@ -4,8 +4,11 @@
#
# Testing IOVs and currents: (since LB, solenoid, toroids)
currents = [(0, 7730, 20400),
(5, 0, 0),
# currents = [(0, 7730, 20400),
# (5, 0, 0),
# (10, 7730, 20400)]
currents = [(0, 0, 20400),
(5, 7730, 20400),
(10, 7730, 20400)]
# Folder name
......
......@@ -108,19 +108,6 @@ MagField::AtlasFieldCacheCondAlg::execute(const EventContext& ctx) const {
if (!m_lockMapCurrents) {
scaleField(cache, fieldMap);
}
else {
// For locked currents, we allow the SF to be either 0 or 1, i.e. allow the DCS currents to
// say whether or not the solenoid or toroid is on or not
cache.m_solScaleFactor = (cache.m_solenoidCurrent > 0) ? 1 : 0;
cache.m_torScaleFactor = (cache.m_toroidCurrent > 0) ? 1 : 0;
ATH_MSG_INFO( "execute: map currents locked");
ATH_MSG_INFO( "execute: Solenoid field scale factor " << cache.m_solScaleFactor << ". Desired current and map current: "
<< cache.m_solenoidCurrent << "," << ((fieldMap) ? fieldMap->solenoidCurrent() : 0));
ATH_MSG_INFO( "execute: Toroid field scale factor " << cache.m_torScaleFactor << ". Desired current and map current: "
<< cache.m_toroidCurrent << "," << fieldMap->toroidCurrent());
}
// save current scale factor in conditions object
auto fieldCondObj = std::make_unique<AtlasFieldCacheCondObj>();
......
......@@ -42,7 +42,10 @@ MagField::AtlasFieldMapCondAlg::initialize() {
ATH_CHECK( m_condSvc.retrieve() );
// Read Handle for the map
ATH_CHECK( m_mapsInputKey.initialize() );
ATH_CHECK( m_mapsInputKey.initialize(m_useMapsFromCOOL) );
// Read Handle for the current
ATH_CHECK( m_currInputKey.initialize (!m_loadMapOnStart && m_useMapsFromCOOL) );
// Read Handle for tagInfo
ATH_CHECK( m_tagInfoKey.initialize() );
......@@ -187,6 +190,77 @@ MagField::AtlasFieldMapCondAlg::updateFieldMap(const EventContext& ctx, Cache& c
// (if it contains more than 3 maps, then this logic doesn't work perfectly)
// nominal currents are read from the global map
}
if (m_loadMapOnStart) {
// For loading map on start - online scenario - take the currents from job options
// And set IOV range to current run number to run number + 1
cache.m_mapSoleCurrent = m_mapSoleCurrent;
cache.m_mapToroCurrent = m_mapToroCurrent;
// Create a range for the current run
EventIDBase start, stop;
start.set_run_number(ctx.eventID().run_number());
start.set_lumi_block(0);
stop.set_run_number(ctx.eventID().run_number() + 1);
stop.set_lumi_block(0);
cache.m_mapCondObjOutputRange = EventIDRange(start,stop);
ATH_MSG_INFO("updateFieldMap: loadMapOnStart is set, overriding currents from job options - solCur "
<< cache.m_mapSoleCurrent << ", torCur " << cache.m_mapToroCurrent
<< " and setting IOV range: " << cache.m_mapCondObjOutputRange);
}
else {
// For normal athena jobs, check the currents in DCS to check if one of the two magnets
// is OFF so that the correct map can be used.
// Note: for the nominal maps from COOL, three maps are available:
// - Global with both solenoid and toroid
// - Solenoid - just the currents for the solenoid
// - Toroid - just the currents for the toroid
double soleCurrent;
double toroCurrent;
EventIDRange rangeDCS;
ATH_CHECK( checkCurrentFromConditions(ctx, soleCurrent, toroCurrent, rangeDCS) );
bool useDCSIOVRange = false;
if (soleCurrent < m_soleMinCurrent) {
cache.m_mapSoleCurrent = 0;
useDCSIOVRange = true;
ATH_MSG_INFO("updateFieldMap: set solenoid current to 0 from DCS");
}
if (toroCurrent < m_toroMinCurrent) {
cache.m_mapToroCurrent = 0;
useDCSIOVRange = true;
ATH_MSG_INFO("updateFieldMap: set toroid current to 0 from DCS");
}
if (useDCSIOVRange) {
// Construct range - from DCS range, if not a TimeStamp IOV
EventIDBase start, stop;
if (rangeDCS.start().isTimeStamp()) {
// use ctx run number
start.set_run_number(ctx.eventID().run_number());
start.set_lumi_block(0);
stop.set_run_number(ctx.eventID().run_number() + 1);
stop.set_lumi_block(0);
}
else {
// not just time stamp, use the DCS run number
// - require validity to be at least one full run
start.set_run_number(rangeDCS.start().run_number());
start.set_lumi_block(0);
stop.set_run_number(std::max(rangeDCS.start().run_number() + 1, rangeDCS.stop().run_number()));
stop.set_lumi_block(0);
}
cache.m_mapCondObjOutputRange = EventIDRange(start,stop);
ATH_MSG_INFO("updateFieldMap: map IOV range " << cache.m_mapCondObjOutputRange);
}
else {
ATH_MSG_INFO("updateFieldMap: currents are OK, will use nominal maps");
}
}
}
else {
......@@ -201,7 +275,7 @@ MagField::AtlasFieldMapCondAlg::updateFieldMap(const EventContext& ctx, Cache& c
EventIDBase start, stop;
start.set_run_number(ctx.eventID().run_number());
start.set_lumi_block(0);
stop.set_run_number(ctx.eventID().run_number()+1);
stop.set_run_number(ctx.eventID().run_number() + 1);
stop.set_lumi_block(0);
cache.m_mapCondObjOutputRange = EventIDRange(start,stop);
......@@ -225,13 +299,15 @@ MagField::AtlasFieldMapCondAlg::updateFieldMap(const EventContext& ctx, Cache& c
if (tag.first == "MapSoleCurrent") {
cache.m_mapSoleCurrent = std::stof(tag.second);
resetCurrentsFromTagInfo = true;
ATH_MSG_INFO("updateFieldMap: found MapSoleCurrent in TagInfo, setting the solenoid current " << cache.m_mapSoleCurrent);
ATH_MSG_INFO("updateFieldMap: found MapSoleCurrent in TagInfo, setting the solenoid current "
<< cache.m_mapSoleCurrent);
}
else
if (tag.first == "MapToroCurrent") {
cache.m_mapToroCurrent = std::stof(tag.second);
resetCurrentsFromTagInfo = true;
ATH_MSG_INFO("updateFieldMap: found MapToroCurrent in TagInfo, setting the toroid current " << cache.m_mapToroCurrent);
ATH_MSG_INFO("updateFieldMap: found MapToroCurrent in TagInfo, setting the toroid current "
<< cache.m_mapToroCurrent);
}
}
if (resetCurrentsFromTagInfo) ATH_MSG_INFO("updateFieldMap: reset currents from TagInfo");
......@@ -312,3 +388,98 @@ MagField::AtlasFieldMapCondAlg::updateFieldMap(const EventContext& ctx, Cache& c
return StatusCode::SUCCESS;
}
StatusCode
MagField::AtlasFieldMapCondAlg::checkCurrentFromConditions(const EventContext& ctx,
double& soleCurrent,
double& toroCurrent,
EventIDRange& rangeDCS) const
{
// readin current value
SG::ReadCondHandle<CondAttrListCollection> readHandle {m_currInputKey, ctx};
const CondAttrListCollection* attrListColl{*readHandle};
if (attrListColl == nullptr) {
ATH_MSG_ERROR("checkCurrentFromConditions: Failed to retrieve CondAttributeListCollection with key " << m_currInputKey.key());
return StatusCode::FAILURE;
}
// Get the validitiy range
if (!readHandle.range(rangeDCS)) {
ATH_MSG_FATAL("checkCurrentFromConditions: Failed to retrieve validity range for " << readHandle.key());
return StatusCode::FAILURE;
}
ATH_MSG_INFO("checkCurrentFromConditions: Range of input currents is " << rangeDCS);
// get magnet currents from DCS
double solcur{0.};
double torcur{0.};
bool gotsol{false};
bool gottor{false};
/*
* due to inconsistencies between CONDBR2 and OFLP200/COMP200 (the former includes channel names
* in the /EXT/DCS/MAGNETS/SENSORDATA folder, the latter don't), we try to read currents in
* both ways
*/
bool hasChanNames{false};
ATH_MSG_INFO( "checkCurrentFromConditions: Attempt 1 at reading currents from DCS (using channel name)" );
for ( CondAttrListCollection::const_iterator itr = attrListColl->begin(); itr != attrListColl->end(); ++itr ) {
const std::string& name = attrListColl->chanName(itr->first);
ATH_MSG_INFO( "checkCurrentFromConditions: Trying to read from DCS: [channel name, index, value] "
<< name << " , " << itr->first << " , " << itr->second["value"].data<float>() );
if (name.compare("") != 0) {
hasChanNames = true;
}
if ( name.compare("CentralSol_Current") == 0 ) {
// channel 1 is solenoid current
solcur = itr->second["value"].data<float>();
gotsol = true;
} else if ( name.compare("Toroids_Current") == 0 ) {
// channel 3 is toroid current
torcur = itr->second["value"].data<float>();
gottor = true;
}
}
if ( !hasChanNames ) {
ATH_MSG_INFO( "checkCurrentFromConditions: Attempt 2 at reading currents from DCS (using channel index)" );
// in no channel is named, try again using channel index instead
for ( CondAttrListCollection::const_iterator itr = attrListColl->begin(); itr != attrListColl->end(); ++itr ) {
if ( itr->first == 1 ) {
// channel 1 is solenoid current
solcur = itr->second["value"].data<float>();
gotsol = true;
} else if ( itr->first == 3 ) {
// channel 3 is toroid current
torcur = itr->second["value"].data<float>();
gottor = true;
}
}
}
if ( !gotsol || !gottor ) {
if ( !gotsol ) ATH_MSG_ERROR( "checkCurrentFromConditions: Missing solenoid current in DCS information" );
if ( !gottor ) ATH_MSG_ERROR( "checkCurrentFromConditions: Missing toroid current in DCS information" );
return StatusCode::FAILURE;
}
ATH_MSG_INFO( "checkCurrentFromConditions: Currents read from DCS - solenoid " << solcur << " toroid " << torcur );
// round to zero if close to zero
if ( solcur < m_soleMinCurrent) {
solcur = 0.0;
ATH_MSG_INFO( "checkCurrentFromConditions: Solenoid is off" );
}
if ( torcur < m_toroMinCurrent) {
torcur = 0.0;
ATH_MSG_INFO( "checkCurrentFromConditions: Toroids are off" );
}
soleCurrent = solcur;
toroCurrent = torcur;
return StatusCode::SUCCESS;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment