ATLAS Offline Software
HepMCWeightSvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
6 #include "HepMCWeightSvc.h"
8 #include "CoralBase/AttributeListException.h"
10 #include "StoreGate/ReadHandle.h"
12 #include "boost/algorithm/string.hpp"
13 
14 
19 {
21  return StatusCode::SUCCESS;
22 }
23 
24 
33 HepMCWeightSvc::setWeightNames (const WeightMap& weightNames,
34  const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
35 {
36  std::scoped_lock lock (m_mutex);
37 
38  // Ignore any attempt to set 'nothing' for the weight names.
39  if (weightNames.size()==0 ||
40  (weightNames.size()==1 && weightNames.begin()->first=="0") )
41  {
42  return StatusCode::SUCCESS;
43  }
44 
45  if (m_weights[0].m_chanNum != 0 || m_nextWeight != 0) {
46  // We only allow setting of weightNames ONCE! ...
47  // if the weights have ever been loaded, we will not allow
48  // them to be set again!
49  // Effectively means the weights are only set in evgen jobs.
50  return StatusCode::SUCCESS;
51  }
52 
53  unsigned int chanNum = ctx.eventID().run_number();
54 
56  w.m_chanNum = chanNum;
57  w.m_weightNames = weightNames;
58  w.fillVec();
59 
60  // Create and register the metadata containter with these weight names
61  // Use the MetaDataTool to do this
62  ATH_CHECK( m_metaDataTool->registerFolder("/Generation/Parameters","Metadata created during Event Generation") );
63 
64  // Create a new attributelist collection for it ...
65  auto cont = std::make_unique<CondAttrListCollection> (true /* use regular timestamps, not run-lumiblock timestamps */) ;
66 
67  // Create a single attribute list.
69 
70  // Store as strings ... when read back in we use a gaudi parser to parse the list
71  myAttributes.extend("HepMCWeightNames","string");
72  myAttributes.extend("HepMCWeightSvcVersion","int");
73  myAttributes["HepMCWeightSvcVersion"].data<int>() = 2;
74 
75  std::string stringToStore = Gaudi::Utils::toString( weightNames );
76 
77  myAttributes["HepMCWeightNames"].data<std::string>() = stringToStore;
78 
79  // Use the run-number as the 'channel' ... all weightnames should be the same for the same channel
80  bool add_status = cont->add(chanNum, myAttributes);
81  if (!add_status) {
82  ATH_MSG_INFO("Failed to add AttributeList for weight " << stringToStore);
83  }
84 
85  ATH_MSG_INFO("Storing /Generation/Parameters :: WeightNames = " << stringToStore);
86 
87  // And assign it to 'channel 0' .. consistent with other metadata
88  ATH_CHECK( m_metaDataTool->addPayload("/Generation/Parameters", cont.release()) );
89 
90  return StatusCode::SUCCESS;
91 }
92 
93 
97 HepMCWeightSvc::WeightMap
98 HepMCWeightSvc::weightNames (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
99 {
100  std::scoped_lock lock (m_mutex);
101  size_t i = getWeightIndex (ctx);
102  if (i < NWEIGHTS) {
103  return m_weights[i].m_weightNames;
104  }
105 
106  ATH_MSG_WARNING("Unable to load weightnames from metadata ... do not trust the weightnames!");
107  return WeightMap();
108 }
109 
110 
114 std::vector<std::string>
115 HepMCWeightSvc::weightNameVec (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/)
116 {
117  std::scoped_lock lock (m_mutex);
118  size_t i = getWeightIndex (ctx);
119  if (i < NWEIGHTS) {
120  return m_weights[i].m_weightNameVec;
121  }
122 
123  ATH_MSG_WARNING("Unable to load weightnames from metadata ... do not trust the weightnames!");
124  return std::vector<std::string>();
125 }
126 
127 
134 unsigned long HepMCWeightSvc::getChanNum (const EventContext& ctx) const
135 {
136  // Try first to get the MC channel number from EventInfo.
137  SG::ReadHandle ei (m_eventInfoKey, ctx);
138  if (ei.isValid()) {
139  unsigned long chanNum = ei->mcChannelNumber();
140  if (chanNum > 0) return chanNum;
141  }
142  // Fall back to run number.
143  return ctx.eventID().run_number();
144 }
145 
146 
153 unsigned int HepMCWeightSvc::loadWeights (unsigned long chanNum)
154 {
155  // Must be called holding the service mutex.
156 
157  if (!m_enabled) return NWEIGHTS;
158 
159  std::map<std::string, int> in;
160 
161  Athena::ToolLock toolLock (*m_metaDataTool);
162  const IOVMetaDataContainer* cont = m_metaDataTool->findMetaDataContainer ("/Generation/Parameters");
163 
164  // Return quietly if container isn't there.
165  if (cont) {
166  if (cont->payloadContainer()->size() == 0) return NWEIGHTS;
167 
168  unsigned long chanNumRead = chanNum;
169  // If there is only one collection of weights, then we just load that one.
170  if (cont->payloadContainer()->at(0)->size()==1) {
171  chanNumRead = cont->payloadContainer()->at(0)->chanNum(0);
172  }
173 
174  const coral::Attribute& attr = cont->payloadContainer()->at(0)->attributeList(chanNumRead)["HepMCWeightNames"];
175 
176  int version = 1;
177  try {
178  version = cont->payloadContainer()->at(0)->attributeList(chanNumRead)["HepMCWeightSvcVersion"].data<int>();
179  } catch(const coral::AttributeListException&) {
180  version = 1; //no version available so assume version 1
181  }
182 
183  std::string weightNames = attr.data<std::string>();
184 
185  //protect against malformed weightnames - see ATLMCPROD-3103
186  //this actually only came about because the Gaudi::Utils::toString method was not used
187  //in setWeightNames below. I've now corrected that, but now the fear is that these
188  //replacements will interfere with those too!
189  //so use a versioning system now
190  if(version==1) {
191  boost::replace_all(weightNames, "{'", "{\"");
192  boost::replace_all(weightNames, "':", "\":");
193  boost::replace_all(weightNames, ", '", ", \"");
194  }
195 
196  ATH_MSG_DEBUG("Loading weightnames: " << weightNames);
197 
198  if( Gaudi::Parsers::parse(in,weightNames).isFailure() ) return NWEIGHTS;
199  }
200 
201  size_t iweight = m_nextWeight;
202  if (++m_nextWeight >= NWEIGHTS) {
203  m_nextWeight = 0;
204  }
205 
206  WeightInfo& w = m_weights[iweight];
207  w.m_chanNum = chanNum;
208  w.m_weightNames.clear();
209 
210  for(const auto& i : in) {
211  w.m_weightNames[i.first] = i.second;
212  }
213  w.fillVec();
214 
215  return iweight;
216 }
217 
218 
225 unsigned int HepMCWeightSvc::getWeightIndex (const EventContext& ctx)
226 {
227  unsigned long chanNum = getChanNum (ctx);
228  if (chanNum != 0) {
229  for (size_t i = 0; i < NWEIGHTS; i++) {
230  if (m_weights[i].m_chanNum == chanNum) {
231  return i;
232  }
233  }
234  return loadWeights (chanNum);
235  }
236  return NWEIGHTS;
237 }
238 
239 
244 {
245  m_weightNameVec.clear();
246  using WPair = std::pair<std::string, unsigned long int>;
247  std::vector<WPair> sorted;
248  for(const auto& i : m_weightNames) {
249  sorted.emplace_back (i);
250  }
251  std::sort (sorted.begin(), sorted.end(),
252  [](const WPair& a, const WPair& b) {return a.second < b.second; });
253  for (auto& a: sorted) {
254  m_weightNameVec.emplace_back (std::move (a.first));
255  }
256 }
IOVMetaDataContainer::payloadContainer
const IOVPayloadContainer * payloadContainer() const
Access to payload container.
Definition: IOVMetaDataContainer.h:141
IOVPayloadContainer::at
CondAttrListCollection * at(unsigned int i) const
Element access.
Definition: IOVPayloadContainer.h:128
HepMCWeightSvc::m_nextWeight
size_t m_nextWeight
Index of next set of weights to overwrite.
Definition: HepMCWeightSvc.h:123
IOVMetaDataContainer
This class is a container for conditions data. It is intended to be used to store conditions data fro...
Definition: IOVMetaDataContainer.h:37
HepMCWeightSvc::WeightInfo
Cached sets of weights.
Definition: HepMCWeightSvc.h:104
Gaudi::Parsers::parse
StatusCode parse(std::tuple< Tup... > &tup, const Gaudi::Parsers::InputData &input)
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:284
CondAttrListCollection.h
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
HepMCWeightSvc::NWEIGHTS
static const unsigned int NWEIGHTS
Array of weights.
Definition: HepMCWeightSvc.h:119
HepMCWeightSvc.h
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
HepMCWeightSvc::m_enabled
Gaudi::Property< bool > m_enabled
Definition: HepMCWeightSvc.h:97
HepMCWeightSvc::m_metaDataTool
PublicToolHandle< IIOVDbMetaDataTool > m_metaDataTool
Handle to metadata tool.
Definition: HepMCWeightSvc.h:92
HepMCWeightSvc::m_eventInfoKey
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
Used to get MC channel for the current event.
Definition: HepMCWeightSvc.h:127
HepMCWeightSvc::initialize
virtual StatusCode initialize() override
Standard Gaudi initialize.
Definition: HepMCWeightSvc.cxx:18
IOVPayloadContainer::size
size_type size() const
size of payload vector
Definition: IOVPayloadContainer.h:121
HepMCWeightSvc::loadWeights
unsigned int loadWeights(unsigned long chanNum)
Try to load weight names from metadata.
Definition: HepMCWeightSvc.cxx:153
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
checkCoolLatestUpdate.chanNum
chanNum
Definition: checkCoolLatestUpdate.py:27
HepMCWeightSvc::m_weights
WeightInfo m_weights[NWEIGHTS]
Definition: HepMCWeightSvc.h:120
lumiFormat.i
int i
Definition: lumiFormat.py:92
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
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CondAttrListCollection::chanNum
ChanNum chanNum(unsigned int index) const
channel number for index: (index = 0 to size-1)
Definition: CondAttrListCollection.h:384
Athena::ToolLock
RAII helper for acquiring the lock of an ILockableTool.
Definition: ILockableTool.h:43
HepMCWeightSvc::WeightInfo::m_weightNameVec
std::vector< std::string > m_weightNameVec
Sorted vector of weight names.
Definition: HepMCWeightSvc.h:112
CondAttrListCollection::attributeList
const AttributeList & attributeList(ChanNum chanNum) const
attribute list for a given channel number
Definition: CondAttrListCollection.h:401
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
HepMCWeightSvc::getWeightIndex
unsigned int getWeightIndex(const EventContext &ctx)
Return the index in m_weights for the current event.
Definition: HepMCWeightSvc.cxx:225
HepMCWeightSvc::WeightInfo::m_weightNames
WeightMap m_weightNames
Map of weight names.
Definition: HepMCWeightSvc.h:109
HepMCWeightSvc::setWeightNames
virtual StatusCode setWeightNames(const WeightMap &weightNames, const EventContext &ctx=Gaudi::Hive::currentContext()) override
Record weight names to metadata if none have yet been set.
Definition: HepMCWeightSvc.cxx:33
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
IOVMetaDataContainer.h
This class is a container for conditions data. It is intended to be used to store conditions data fro...
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
CondAttrListCollection::size
size_type size() const
number of Chan/AttributeList pairs
Definition: CondAttrListCollection.h:322
EventInfo.h
get_generator_info.version
version
Definition: get_generator_info.py:33
a
TList * a
Definition: liststreamerinfos.cxx:10
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
HepMCWeightSvc::getChanNum
unsigned long getChanNum(const EventContext &ctx) const
Return the ‘channel number’ for the current event.
Definition: HepMCWeightSvc.cxx:134
HepMCWeightSvc::weightNames
virtual WeightMap weightNames(const EventContext &ctx=Gaudi::Hive::currentContext()) override
Return the current weight names.
Definition: HepMCWeightSvc.cxx:98
HepMCWeightSvc::weightNameVec
virtual std::vector< std::string > weightNameVec(const EventContext &ctx=Gaudi::Hive::currentContext()) override
Return the current weight names.
Definition: HepMCWeightSvc.cxx:115
HepMCWeightSvc::m_mutex
std::mutex m_mutex
Serialize access to this service.
Definition: HepMCWeightSvc.h:130
CondAttrListCollection::AttributeList
coral::AttributeList AttributeList
Definition: CondAttrListCollection.h:56
ReadHandle.h
Handle class for reading from StoreGate.
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
HepMCWeightSvc::WeightInfo::fillVec
void fillVec()
Initialize sorted vector from map.
Definition: HepMCWeightSvc.cxx:243