ATLAS Offline Software
Loading...
Searching...
No Matches
AlgoJiveXML.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
11
13
14#include "GaudiKernel/ServiceHandle.h"
15
17
18#include <algorithm>
19
20namespace JiveXML{
21
22 AlgoJiveXML::AlgoJiveXML(const std::string& name, ISvcLocator* pSvcLocator) :
23 AthAlgorithm(name, pSvcLocator) {}
24
33
34 //be verbose
35 ATH_MSG_VERBOSE("Initialize()");
36
41
42 ATH_MSG_DEBUG("Writing geometry to file");
43
45 std::vector<std::string>::iterator GeoWriterNameItr = m_GeoWriterNames.begin();
46 for ( ; GeoWriterNameItr != m_GeoWriterNames.end(); ++GeoWriterNameItr){
47
49
50 ToolHandle<IGeometryWriter> GeometryWriter(*GeoWriterNameItr);
51 if ( GeometryWriter.retrieve().isFailure() ){
52 ATH_MSG_WARNING("Unable to locate "<<GeometryWriter.name()<<" tool");
53 } else {
55 if ( GeometryWriter->writeGeometry().isFailure() ){
56 ATH_MSG_WARNING("Unable to write geometry");
57 }
59 if ( GeometryWriter.release().isFailure() ){
60 ATH_MSG_WARNING("Unable to release tool GeometryWriter");
61 }
62 }
63 }
64 }
65
69 ATH_MSG_DEBUG("Retrieving XML format tool");
70
71 //Retrieve the format tool
72 ATH_CHECK(m_FormatTool.retrieve());
73
74 //Setting the tags
75 if ( m_FormatTool->SetTag( TagType("Release",m_AtlasRelease)).isFailure() ){
76 ATH_MSG_WARNING( "Couldn't set Release version" );
77 }
78
82 ATH_MSG_DEBUG("Retrieving streaming tools");
83 if (m_writeToFile){
84 ATH_MSG_INFO("Retrieving default file streaming tool");
85 ATH_CHECK(m_StreamToFileTool.retrieve());
86 }
87 ATH_MSG_INFO("online " << m_onlineMode);
89 if (m_onlineMode){
90 ATH_MSG_INFO("Retrieving default server streaming tool");
92 }
93
94
95 ATH_MSG_INFO("Retrieving data from " << m_DataRetrieverTools.size() << " tools" );
96
97 ATH_MSG_INFO("List property settings: ");
98 ATH_MSG_INFO("AtlasRelease: " << m_AtlasRelease);
99 ATH_MSG_INFO("WriteToFile: " << m_writeToFile);
100 ATH_MSG_INFO("OnlineMode: " << m_onlineMode);
101 ATH_MSG_INFO("WriteGeometry: " << m_writeGeometry);
102 ATH_MSG_INFO("GeometryVersion: " << m_geometryVersionIn);
103 ATH_MSG_INFO("GeoWriterNames: " << m_GeoWriterNames );
104
105 return StatusCode::SUCCESS;
106 }
107
114 StatusCode AlgoJiveXML::execute() {
115
116 if(m_onlineMode){
117 bool isR4PinThisEvent = false;
118 // Get the ready4physics bool at the start of this job and for the current time, during the job ATLAS might have become ready for physics, if this is the case we need to stop the jobs and let the partition restart them
119
120 // Acquire the Global Interpreter Lock (GIL) to ensure thread safety when interacting with Python objects
122
123 // Import the EventDisplaysOnlineHelpers Python module
124 PyObject* pHelper = PyImport_ImportModule("EventDisplaysOnline.EventDisplaysOnlineHelpers");
125 if (!pHelper) {
126 // Error handling: Print Python exception if import fails
127 PyErr_Print();
128 ATH_MSG_WARNING("Failed to import EventDisplaysOnline.EventDisplaysOnlineHelpers module");
129 return StatusCode::FAILURE;
130 } else {
131 ATH_MSG_INFO("ready4Physics at start of job: " << m_ready4PhysicsAtStart);
132 // Get the "Ready4Physics" function from the module
133 PyObject* Ready4Physics = PyObject_GetAttrString(pHelper, "Ready4Physics");
134 if (!Ready4Physics || !PyCallable_Check(Ready4Physics)) {
135 // Error handling: Print warning if function not found or not callable
136 ATH_MSG_WARNING("Could not find or call Ready4Physics function in EventDisplaysOnline.EventDisplaysOnlineHelpers module");
137 } else {
138 // Call the "Ready4Physics" function
139 PyObject* r4p = PyObject_CallFunctionObjArgs(Ready4Physics, NULL);
140 if (!r4p) {
141 PyErr_Print();
142 ATH_MSG_WARNING("Failed to call Ready4Physics function");
143 } else {
144 // Convert the result to a boolean value
145 isR4PinThisEvent = PyObject_IsTrue(r4p);
146 ATH_MSG_INFO("isR4PinThisEvent: " << isR4PinThisEvent);
147 if(!m_ready4PhysicsAtStart && isR4PinThisEvent){
148 ATH_MSG_INFO("ATLAS was not ready for physics at the start of this job, but is now, so stopping job so that the partition can restart the jobs with any new configuration, i.e. after a warm start to pick back up pixel hits");
149 return StatusCode::FAILURE;
150 }
151 Py_DECREF(r4p); // Decrement reference count of the r4p object
152 }
153 }
154 Py_XDECREF(Ready4Physics);
155 }
156 Py_DECREF(pHelper);
157 }// End of if online
158
162 //The run and event number of the current event
163 unsigned int runNo = 0, lumiBlock = 0;
164 uint64_t eventNo=0;
165 //Date and time string of the current event
166 char dateTime[32];
167 //general event property, unused yet
168 std::string eventProperty = "default";
169
170 // geometry-version/geometry-tag from Athena (sourced via jOs)
171 std::string geometryVersion = "default";
172 geometryVersion = DataType(m_geometryVersionIn).toString();
173
174 //Retrieve eventInfo from StoreGate
175 const xAOD::EventInfo* eventInfo = nullptr;
176 if (evtStore()->retrieve(eventInfo).isFailure()){
177 ATH_MSG_FATAL("Could not find xAODEventInfo" );
178 return StatusCode::FAILURE;
179 }else{
180 ATH_MSG_DEBUG(" xAODEventInfo: runNumber: " << eventInfo->runNumber()
181 << ", eventNumber: " << eventInfo->eventNumber()
182 << ", mcChannelNumber: " << eventInfo->mcChannelNumber()
183 << ", mcEventNumber: " << eventInfo->mcEventNumber() // MC: use this instead of runNumber
184 << ", lumiBlock: " << eventInfo->lumiBlock()
185 << ", timeStamp: " << eventInfo->timeStamp()
186 << ", bcid: " << eventInfo->bcid()
187 << ", eventTypeBitmask: " << eventInfo->eventTypeBitmask()
188 << ", actualInteractionsPerCrossing: " << eventInfo->actualInteractionsPerCrossing()
189 << ", averageInteractionsPerCrossing: " << eventInfo->averageInteractionsPerCrossing()
190 );
191 }
192
193 //when running online, if a new run has started stop the jobs and let the partition restart the jobs to pick up any new configuration for the run
194 if(m_onlineMode){
195 ATH_MSG_INFO("m_previousRunNumber: " << m_previousRunNumber);
196 ATH_MSG_INFO("eventInfo->runNumber(): " << eventInfo->runNumber());
197 //don't check for first event
198 if(m_previousRunNumber!=0){
199 if(m_previousRunNumber != eventInfo->runNumber()){
200 ATH_MSG_INFO("Got a new run number, a new run has started whilst this job was running, stopping now to let the partition restart the jobs and pick up any new configuration");
201 return StatusCode::FAILURE;
202 }
203 }
204 //store run number to look at in the next event
205 m_previousRunNumber = eventInfo->runNumber();
206 }
207 // new treatment of mc_channel_number for mc12
208 // from: https://twiki.cern.ch/twiki/bin/viewauth/Atlas/PileupDigitization#Contents_of_Pileup_RDO
209 unsigned int mcChannelNo = 0;
210 bool firstEv = true;
211
212 //+++ Get sub-event info object
213 ATH_MSG_DEBUG( "Sub Event Infos: " );
214 for (const xAOD::EventInfo::SubEvent& subevt : eventInfo->subEvents()) {
215 const xAOD::EventInfo* sevt = subevt.ptr();
216 if (sevt) {
217 if (firstEv){
218 mcChannelNo = sevt->mcChannelNumber(); // the 'real' mc-channel
219 ATH_MSG_DEBUG( " mc_channel from SubEvent : " << sevt->mcChannelNumber() );
220 firstEv = false;
221 }
222 ATH_MSG_VERBOSE("Sub Event Info:\n Time : " << subevt.time()
223 << " Index : " << subevt.index()
224 << " Provenance : " << subevt.type() // This is the provenance stuff: signal, minbias, cavern, etc
225 << " Run Number : " << sevt->runNumber()
226 << " Event Number : " << sevt->eventNumber()
227 << " ns Offset : " << sevt->timeStampNSOffset()
228 << " Lumi Block : " << sevt->lumiBlock()
229 << " mc_channel : " << sevt->mcChannelNumber()
230 << " BCID : " << sevt->bcid()
231 << " Geo version : " << m_geometryVersionIn
232 );
233 }
234 else ATH_MSG_VERBOSE("Subevent is null ptr ");
235 }
236
237 //Get run and event numbers
238 runNo = eventInfo->runNumber();
239 eventNo = eventInfo->eventNumber();
240
241// Note: 4294967293 is the maximum value for a unsigned long
242
243 if ( mcChannelNo != 0 ){ runNo = mcChannelNo + 140000000; } // indicating 'mc14'
244 ATH_MSG_DEBUG( " runNumber for filename: " << runNo << ", eventNumber: " << eventNo);
245
246 if ( eventInfo->lumiBlock() ){
247 lumiBlock = eventInfo->lumiBlock();
248 }else{
249 lumiBlock = -1; // placeholder
250 }
251 if ( mcChannelNo != 0 ) lumiBlock = -1; // mask for mc11a
252
253 // lumiBlock from mc can be just huge number, ignore then
254 if ( lumiBlock > 1000000 ) { lumiBlock = 0; }
255
256 //Get timestamp of the event
257 //If Grid job not running in CEST or CET, change to UTC
258 //Only option to avoid odd timezones. jpt 29Mar11
259 size_t found1;
260 size_t found2;
261 if (eventInfo->timeStamp() > 0) {
262 time_t unixtime = (time_t) eventInfo->timeStamp();
263 struct tm time;
264 localtime_r(&unixtime, &time);
265 strftime(dateTime, 32, "%Y-%m-%d %H:%M:%S %Z", &time);
266 struct tm utctime;
267 gmtime_r(&unixtime, &utctime);
268 found1 = (DataType(dateTime).toString().find("CEST"));
269 found2 = (DataType(dateTime).toString().find("CET"));
270 if ( int(found1)<0 && int(found2)<0 ){ // not found is -1
271 strftime(dateTime, 32, "%Y-%m-%d %H:%M:%S UTC", &utctime);
272 ATH_MSG_DEBUG( " TIME NOT CET/CEST. Adjusted to:" << dateTime );
273 }
274 } else {
275 dateTime[0] = '\0'; // empty string
276 }
277 if ( mcChannelNo != 0 ){ dateTime[0] = '\0'; } // mask for mc11a
278
282 if ( m_FormatTool->StartEvent(eventNo, runNo, dateTime, lumiBlock, eventProperty, geometryVersion).isFailure() ){
283 ATH_MSG_FATAL("Couldn't start event in FormatTool");
284 return StatusCode::FAILURE;
285 }
286
291 ATH_MSG_DEBUG("Starting loop over data retrievers" );
292 //Loop over data retrievers
293 ToolHandleArray<IDataRetriever>::iterator DataRetrieverItr = m_DataRetrieverTools.begin();
294 for(; DataRetrieverItr != m_DataRetrieverTools.end(); ++DataRetrieverItr) {
295 //Add try-catch to avoid retrieval to fail on single retriever
296 try {
297 //Retrieve information and pass it to formatting tool object
298 if ((*DataRetrieverItr)->retrieve(m_FormatTool).isFailure()) {
299 ATH_MSG_WARNING( "Failed to fill " << (*DataRetrieverItr)->dataTypeName() );
300 } else {
301 ATH_MSG_DEBUG("Filled: " << (*DataRetrieverItr)->dataTypeName() );
302 }
303 //Only catch std::exception
304 } catch ( std::exception& ex ){
305 //Now show some message
306 ATH_MSG_FATAL("Caught exception in " << (*DataRetrieverItr)->name()
307 << " while retrieving data for " << (*DataRetrieverItr)->dataTypeName()
308 << " : " << ex.what() );
309 //and return with an error
310 return StatusCode::FAILURE;
311 }
312 }
313 ATH_MSG_DEBUG( "Finished loop over data retrievers" );
314
318 if ( m_FormatTool->EndEvent().isFailure() ){
319 ATH_MSG_WARNING( "Couldn't end event in FormatTool" );
320 return StatusCode::FAILURE;
321 }
322
326 if(m_writeToFile){
327 ATH_MSG_DEBUG("Streaming event to file");
328 if ( (m_StreamToFileTool->StreamEvent(eventNo, runNo, m_FormatTool->getFormattedEvent()).isFailure() )){
329 ATH_MSG_WARNING( "Could not stream event to file" );
330 }
331 }
332 if(m_onlineMode){
333 ATH_MSG_DEBUG("Streaming event to server");
334 if ( (m_StreamToServerTool->StreamEvent(eventNo, runNo, m_FormatTool->getFormattedEvent()).isFailure() )){
335 ATH_MSG_WARNING( "Could not stream event to server" );
336 }
337 }
338
339 return StatusCode::SUCCESS;
340 }
341
347
348 ATH_MSG_VERBOSE( "finalize()" );
349
351 m_DataRetrieverTools.release().ignore();
352 m_FormatTool.release().ignore();
353 m_StreamToFileTool.release().ignore();
354 m_StreamToServerTool.release().ignore();
355
356 return StatusCode::SUCCESS;
357 }
358} //namespace
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
OFFLINE_FRAGMENTS_NAMESPACE::PointerType DataType
_object PyObject
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
ToolHandle< JiveXML::IStreamTool > m_StreamToServerTool
Definition AlgoJiveXML.h:68
AlgoJiveXML(const std::string &name, ISvcLocator *pSvcLocator)
ToolHandle< JiveXML::IStreamTool > m_StreamToFileTool
Streaming tools that pass the formatted XML text into a file, to a server, etc.
Definition AlgoJiveXML.h:67
ToolHandle< JiveXML::IFormatTool > m_FormatTool
Handle to the formatting tool, which is passed on to the data retrievers and converts the data into X...
Definition AlgoJiveXML.h:61
StatusCode execute()
Execute - called for every event.
Gaudi::Property< bool > m_writeToFile
Definition AlgoJiveXML.h:44
StatusCode initialize()
Initialize - called once in the beginning.
uint32_t m_previousRunNumber
Definition AlgoJiveXML.h:70
Gaudi::Property< bool > m_onlineMode
Definition AlgoJiveXML.h:45
StatusCode finalize()
Finalize called once in the end.
Gaudi::Property< bool > m_writeGeometry
Definition AlgoJiveXML.h:46
Gaudi::Property< bool > m_ready4PhysicsAtStart
Definition AlgoJiveXML.h:49
Gaudi::Property< std::vector< std::string > > m_GeoWriterNames
Definition AlgoJiveXML.h:48
Gaudi::Property< std::string > m_geometryVersionIn
Definition AlgoJiveXML.h:47
ToolHandleArray< JiveXML::IDataRetriever > m_DataRetrieverTools
The list of DataRetrievers.
Definition AlgoJiveXML.h:55
Gaudi::Property< std::string > m_AtlasRelease
Definition AlgoJiveXML.h:43
Writes the inner detector and calorimeter geometry to an XML file for use with Atlantis.
virtual StatusCode writeGeometry() override
Writes the inner detector and calorimeter geometry to an XML file.
Class describing the properties of one pileup sub-event.
uint64_t mcEventNumber() const
The MC generator's event number.
uint32_t lumiBlock() const
The current event's luminosity block number.
uint32_t eventTypeBitmask() const
The event type bitmask.
uint32_t bcid() const
The bunch crossing ID of the event.
float averageInteractionsPerCrossing() const
Average interactions per crossing for all BCIDs - for out-of-time pile-up.
float actualInteractionsPerCrossing() const
Average interactions per crossing for the current BCID - for in-time pile-up.
uint32_t timeStamp() const
POSIX time in seconds from 1970. January 1st.
const std::vector< SubEvent > & subEvents() const
Get the pileup events that were used in the simulation.
uint32_t runNumber() const
The current event's run number.
uint32_t mcChannelNumber() const
The MC generator's channel number.
uint32_t timeStampNSOffset() const
Nanosecond time offset wrt. the time stamp.
uint64_t eventNumber() const
The current event's event number.
This header is shared inbetween the C-style server thread and the C++ Athena ServerSvc.
std::pair< std::string, std::string > TagType
Defines a tag as a pair of strings.
Definition DataType.h:62
EventInfo_v1 EventInfo
Definition of the latest event info version.