ATLAS Offline Software
VP1BatchOnLatestEvent.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
8 
10 
11 #include "GaudiKernel/ServiceHandle.h"
12 #include "GaudiKernel/IEvtSelector.h"
13 #include "GaudiKernel/IIncidentSvc.h"
14 #include "GaudiKernel/ToolHandle.h"
15 
16 #include <vector>
17 #include <iostream>
18 #include <iomanip>
19 #include <stdexcept>
20 #include <unistd.h>
21 #include <ctime> /* time_t, time, ctime */
22 #include <random> // C++11
23 #include <string>
24 
25 
26 
27 
28 VP1BatchOnLatestEvent::VP1BatchOnLatestEvent(const std::string& name, ISvcLocator* svcLocator)
29  : AthAlgorithm(name, svcLocator)
30  , m_nEvent(0)
31  , m_indexFile(0)
32  , m_lastIndexFile(0)
33 {
34  declareProperty("VP1ConfigFile", m_inputVP1CfgFile="");
35  declareProperty("DestinationDirectory", m_destinationDir=""); // produce files in the run directory by default
36  declareProperty("InputDirectory", m_inputDir=""); // the directory where the input data files (e.g. ESDs) are stored
37  declareProperty("UseRandomVP1ConfigFile", m_isGetRandomFile = false); // get random configuration files if TRUE
38 }
39 
40 // TODO: add DestinationDirectory as argument to the -batch VP1 command option, so we can configure output folder from JobOption
41 
42 
44 {
45  ATH_MSG_INFO(" in initialize() ");
47  ServiceHandle<IIncidentSvc> incSvc("IncidentSvc",name());
48  ATH_CHECK(incSvc.retrieve());
49  incSvc->addListener(this, "BeginEvent", 0);
50  return StatusCode::SUCCESS;
51 }
52 
54 {
55  ATH_MSG_DEBUG(" in execute() ");
57  if(eventInfo.isValid()) {
58  m_eventNumber = eventInfo->eventNumber();
59  m_runNumber = eventInfo->runNumber();
60  m_timeStamp = eventInfo->timeStamp(); // posix time in seconds from 1970, 32 bit unsigned
61 
62  ATH_MSG_DEBUG("run number: "<< m_runNumber
63  << ", event number: "
64  << m_eventNumber << " : timestamp (UNIX): "
65  << m_timeStamp
66  << "] ");
67 
68  if(msgLvl(MSG::DEBUG)) {
69  std::stringstream stream;
70  stream << "Event type: SIMULATION '" << std::boolalpha
72  << "' - ";
73  int i{-1};
74  for(float weight : eventInfo->mcEventWeights()) {
75  stream << " weight " << ++i << ": " << weight;
76  }
77  ATH_MSG_DEBUG(stream.str());
78  }
79  }
80  else {
81  ATH_MSG_ERROR(" Unable to retrieve EventInfo from StoreGate!!!");
82  m_eventNumber = 0;
83  m_runNumber = 0;
84  m_timeStamp = 0;
85  }
86 
87  // get a human-readable timestamp from UNIX time
89 
90  return StatusCode::SUCCESS;
91 }
92 
94 {
95  ATH_MSG_VERBOSE("in finalize() ");
96 
97  // Let VP1FileUtilities handle the output of the last event
98  if(m_nEvent) {
100  }
101 
102  return StatusCode::SUCCESS;
103 }
104 
105 
106 void VP1BatchOnLatestEvent::handle(const Incident& inc)
107 {
108  ATH_MSG_INFO("Handling incident '" << inc.type() << "'");
109 
110  // Let VP1FileUtilities handle the output of the previous event
111  if(m_nEvent) {
113  }
114  m_nEvent++;
115 }
116 
117 
118 
120 
121  // if the user specified empty config file name and declared 'VP1BatchOnLatestEvent.UseRandomVP1ConfigFile=True' in the jobOption
122  if (m_isGetRandomFile) {
123  ATH_MSG_INFO("--> RANDOM MODE: Using a random VP1 configuration file...");
125  }
126 
127  ATH_MSG_INFO("--> Input VP1 Configuration file: " << m_inputVP1CfgFile);
128 
129  // build the command to launch VP1-Batch on the latest-produced ESD file
130  std::string commandStr = "vp1 -batch";
131 
132  // add custom output folder, if user specified it
133  if (m_destinationDir != "") {
134  ATH_MSG_INFO(" --> Using user-defined output folder: " << m_destinationDir);
135  commandStr += " -batch-output-folder=" + m_destinationDir;
136  }
137 
138  commandStr += " `cat latest_vp1event` " + m_inputVP1CfgFile;
139 
140  bool vp1OK = false;
141  ATH_MSG_INFO(" ===> launching VP1-Batch: " << commandStr);
142  try {
143  system(commandStr.c_str());
144  vp1OK = true;
145  } catch (std::runtime_error& err) {
146  ATH_MSG_WARNING("Exception caught: " << err.what());
147  ATH_MSG_WARNING("Unable to launch VP1-Batch on the latest-produced event file");
148  }
149  if (vp1OK) {
150  // Overlay the ATLAS logo to the image
152  // Overlay the event details to the image
154  }
155 }
156 
157 
158 
160 {
161  ATH_MSG_DEBUG(" in getRandomConfigFile() ");
162 
163 
164  std::string configFile;
165 
166  // a list of possible config files, which are stored in the "share/" folder
167  std::vector<std::string> configFiles;
168  configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wTRTGeo.vp1");
169  configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wTRTGeo_IAview.vp1");
170  configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wTRTGeo_wBarrel.vp1");
171  configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wPixel_wSCT_wOpenCalo_wGeo_3D.vp1");
172  configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wPixel_wSCT_wGeo_3D.vp1");
173  configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wPixel_3D.vp1");
174  configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wIDGeo.vp1");
175  configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wGeo_frontView.vp1");
176 
177  int nConfigFiles = configFiles.size();
178  ATH_MSG_DEBUG(" ===> # config files: " << nConfigFiles);
179  int nPositions = nConfigFiles - 1;
180 
181  // setup random generator in [0, nConfigFiles]
182  auto seed = std::random_device{}();
183  auto randomDist = std::bind(std::uniform_int_distribution<int>(0, nPositions ),
184  std::mt19937(seed));
185 
186  // get a random index,
187  // avoiding having the same index in a row
188  while ( m_indexFile == m_lastIndexFile )
189  m_indexFile = randomDist();
191  ATH_MSG_DEBUG(" ===> random index: " << m_indexFile);
192 
193  //std::string configFile = "vp1_conf_ATLASatHOME_truth_event_wTRTGeo.vp1";
194  configFile = configFiles[m_indexFile];
195  ATH_MSG_DEBUG(" ===> random file: " << configFile);
196 
197  return configFile;
198 
199 }
200 
201 // Overlay the ATLAS logo to the image
203 {
204  //std::string commandStr = "convert -composite `cat latest_vp1image` $TestArea/InstallArea/share/ATLAS-Logo-New_300pixels.png -geometry 150x150+0+0 -depth 8 test.png"; // this set the logo size to 150px and it draws it at (0,0)px
205  //std::string commandStr = "convert -composite `cat latest_vp1image` $TestArea/InstallArea/share/ATLAS-Logo-New_300pixels.png -geometry +10+10 -depth 8 test.png"; // this uses the original logo size and it draws it at (10,10)px
206  std::string commandStr = "convert -composite `cat latest_vp1image` $TestArea/InstallArea/share/ATLAS-Logo-New_300pixels.png -geometry +10+10 -depth 8 `cat latest_vp1image`";
207 
208  ATH_MSG_DEBUG( " ===> overlay the ATLAS logo: " << commandStr );
209  try {
210  system(commandStr.c_str());
211  } catch (std::runtime_error& err) {
212  ATH_MSG_WARNING( "Exception caught: " << err.what() );
213  ATH_MSG_WARNING( "Unable to run 'convert'!" );
214  }
215 }
216 
217 // Overlay the event details to the image
218 // it replaces the original image with a version having event details on it
220 {
221 
222 
223 
224  std::string nRun = std::to_string(m_runNumber);
225  std::string nEvent = std::to_string(m_eventNumber);
226 
227  // bash command:
228  // nRun=0; nEvent=4; img=`cat latest_vp1image`; width=$(identify -format %W ${img}); width=$(( ${width} * 3 / 10 )); convert -background '#0008' -gravity west -fill white -size ${width}x80 -font Courier -density 72 -pointsize 18 -interline-spacing 4 caption:'Run number: '${nRun}'\nEvent number: '${nEvent}'\n2015-02-02, 15:10:00' ${img} +swap -gravity SouthEast -composite ${img}-30
229  // nRun=0; nEvent=4; timestamp='ciao'; img=`cat latest_vp1image`; width=$(identify -format %W ${img}); width=$(( ${width} * 3 / 10 )); convert -background '#0008' -gravity west -fill white -size ${width}x80 -font Courier -density 72 -pointsize 18 -interline-spacing 4 caption:'Run number: '${nRun}'\nEvent number: '${nEvent}'\n'${timestamp} ${img} +swap -gravity SouthEast -composite ${img}-31
230  // nRun=0; nEvent=4; timestamp='2015-02-02T10:10:00'; img=`cat latest_vp1image`; width=$(identify -format %W ${img}); width=$(( ${width} * 3 / 10 )); convert -background '#0008' -gravity west -fill white -size ${width}x80 -font Courier -density 72 -pointsize 18 -interline-spacing 4 caption:'Run number: '${nRun}'\nEvent number: '${nEvent}'\n'${timestamp} ${img} +swap -gravity SouthEast -composite ${img}-36
231  std::string commandStr;
232 
233  // setting bash variables
234  commandStr += "nRun="+nRun+"; ";
235  commandStr += "nEvent="+nEvent+"; ";
236  if (m_timeStamp > 0) commandStr += "timestamp='"+m_humanTimestamp+"'; "; // 'timestamp' must not have white spaces
237 
238  // get input image
239  commandStr += "img=`cat latest_vp1image`; "; // get the filename of the latest image produced
240  commandStr += "width=$(identify -format %W ${img}); "; // get the width of the image
241  commandStr += "width=$(( ${width} * 3 / 10 )); "; // set the caption width as a fraction of the image width
242 
243  // ImageMagik 'convert' command settings. (ImageMagik is installed by default on SLC LXPLUS machines)
244  commandStr = commandStr
245  + "convert "
246  + "-background '#0008' " // semi-transparent grey bkg
247  + "-geometry +20+20 " // set an offset to the label position
248  + "-gravity West " // set text position inside the caption space (justification)
249  + "-fill white " // text font color
250  + "-size ${width}x80 " // set text size relative to 'width'
251 
252  + "-font Courier " // text font
253  + "-density 72 " // dots-per-inch resolution
254  + "-pointsize 18 " // text size in points
255  //+ "-interline-spacing 4 " // additional number of pixels between lines of text (only with ImageMagik >= 6.5.5-8!!! Lxplus has 6.7 but not all SLC6 machines...)
256 
257  //+ "caption:'Run number: ${nRun}' " // set the caption text
258  //+ (m_timeStamp > 0 ? "caption:'Run number: '${nRun}'\\nEvent number: '${nEvent}'\\n'${timestamp} " : "caption:'Run number: '${nRun}'\\nEvent number: '${nEvent}'\\n'${timestamp} ") // set the caption text; '\n' needs to be double-escaped while passed to system()
259  + "caption:'Run number: '${nRun}'\\nEvent number: '${nEvent}'\\n'${timestamp} " // set the caption text; '\n' needs to be double-escaped while passed to system()
260 
261  + "${img} " // imput image
262  + "+swap "
263  + "-gravity SouthEast " // set overall caption position
264  + "-composite "
265  + "${img}"; // output image: here we replace the original image
266 
267 
268  ATH_MSG_DEBUG( " ===> overlay the event details: " << commandStr );
269  try {
270  system(commandStr.c_str());
271  } catch (std::runtime_error& err) {
272  ATH_MSG_WARNING( "Exception caught: " << err.what() );
273  ATH_MSG_WARNING( "Unable to run 'convert'!" );
274  }
275 }
276 
277 
279 {
280  time_t t_timestamp = m_timeStamp;
281  struct tm ltm;
282  localtime_r(&t_timestamp, &ltm);
283 
284  // print various components of tm structure.
285  ATH_MSG_DEBUG( "Year: "<< 1900 + ltm.tm_year
286  << " - " << "Month: "<< 1 + ltm.tm_mon<< " - " // tm_mon is in the range [0, 11], so 1 must be added to get real months
287  << "Day: "<< ltm.tm_mday
288  << " - " "Time: "<< ltm.tm_hour << ":" << ltm.tm_min << ":" << ltm.tm_sec); // << "CEST" FIXME: check if time zone is available on data file
289 
290 
291  std::ostringstream ostri;
292  ostri << 1900 + ltm.tm_year
293  << "-" << 1 + ltm.tm_mon // tm_mon is in the range [0, 11], so 1 must be added to get real months
294  << "-" << ltm.tm_mday
295  << "T" << ltm.tm_hour << "-" << ltm.tm_min << "-" << ltm.tm_sec; // << "CEST"; FIXME: check if time zone is available on data file
296 
297  m_humanTimestamp = ostri.str();
298  ATH_MSG_DEBUG( "'human readable' timestamp: " << m_humanTimestamp );
299 }
300 
VP1BatchOnLatestEvent::getRandomConfigFile
std::string getRandomConfigFile()
Definition: VP1BatchOnLatestEvent.cxx:159
taskman.configFile
configFile
Definition: taskman.py:311
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::EventInfo_v1::eventNumber
uint64_t eventNumber() const
The current event's event number.
xAOD::EventInfo_v1::mcEventWeights
const std::vector< float > & mcEventWeights() const
The weights of all the MC events used in the simulation.
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
AthCommonDataStore< AthCommonMsg< Algorithm > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
VP1BatchOnLatestEvent::m_lastIndexFile
int m_lastIndexFile
Definition: VP1BatchOnLatestEvent.h:64
AthCommonMsg< Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
VP1BatchOnLatestEvent::makeEventDisplay
void makeEventDisplay()
Definition: VP1BatchOnLatestEvent.cxx:119
VP1BatchOnLatestEvent::m_runNumber
unsigned long m_runNumber
Definition: VP1BatchOnLatestEvent.h:67
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
xAOD::EventInfo_v1::IS_SIMULATION
@ IS_SIMULATION
true: simulation, false: data
Definition: EventInfo_v1.h:151
VP1BatchOnLatestEvent::m_inputDir
std::string m_inputDir
Definition: VP1BatchOnLatestEvent.h:55
AthenaPoolTestWrite.stream
string stream
Definition: AthenaPoolTestWrite.py:12
VP1BatchOnLatestEvent::overlayATLASlogo
void overlayATLASlogo()
Definition: VP1BatchOnLatestEvent.cxx:202
xAOD::EventInfo_v1::runNumber
uint32_t runNumber() const
The current event's run number.
VP1BatchOnLatestEvent::overlayEventDetails
void overlayEventDetails()
Definition: VP1BatchOnLatestEvent.cxx:219
VP1BatchOnLatestEvent::m_timeStamp
unsigned long m_timeStamp
Definition: VP1BatchOnLatestEvent.h:68
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
VP1BatchOnLatestEvent.h
VP1BatchOnLatestEvent::handle
virtual void handle(const Incident &inc) override
Definition: VP1BatchOnLatestEvent.cxx:106
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
VP1BatchOnLatestEvent::execute
virtual StatusCode execute() override
Definition: VP1BatchOnLatestEvent.cxx:53
VP1BatchOnLatestEvent::m_eventNumber
uint64_t m_eventNumber
Definition: VP1BatchOnLatestEvent.h:66
VP1BatchOnLatestEvent::initialize
virtual StatusCode initialize() override
Definition: VP1BatchOnLatestEvent.cxx:43
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:193
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
VP1BatchOnLatestEvent::VP1BatchOnLatestEvent
VP1BatchOnLatestEvent(const std::string &name, ISvcLocator *pSvcLocator)
Definition: VP1BatchOnLatestEvent.cxx:28
VP1BatchOnLatestEvent::m_destinationDir
std::string m_destinationDir
Definition: VP1BatchOnLatestEvent.h:56
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
VP1BatchOnLatestEvent::m_eventInfoKey
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
Definition: VP1BatchOnLatestEvent.h:59
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
AthAlgorithm
Definition: AthAlgorithm.h:47
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
VP1BatchOnLatestEvent::m_isGetRandomFile
bool m_isGetRandomFile
Definition: VP1BatchOnLatestEvent.h:57
VP1BatchOnLatestEvent::getHumanReadableTimestamp
void getHumanReadableTimestamp()
Definition: VP1BatchOnLatestEvent.cxx:278
VP1BatchOnLatestEvent::m_indexFile
int m_indexFile
Definition: VP1BatchOnLatestEvent.h:63
VP1BatchOnLatestEvent::m_inputVP1CfgFile
std::string m_inputVP1CfgFile
Definition: VP1BatchOnLatestEvent.h:54
VP1BatchOnLatestEvent::m_nEvent
int m_nEvent
Definition: VP1BatchOnLatestEvent.h:62
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
VP1BatchOnLatestEvent::m_humanTimestamp
std::string m_humanTimestamp
Definition: VP1BatchOnLatestEvent.h:69
DEBUG
#define DEBUG
Definition: page_access.h:11
xAOD::EventInfo_v1::timeStamp
uint32_t timeStamp() const
POSIX time in seconds from 1970. January 1st.
VP1FileUtilities.h
xAOD::EventInfo_v1::eventType
bool eventType(EventType type) const
Check for one particular bitmask value.
ServiceHandle< IIncidentSvc >
VP1BatchOnLatestEvent::finalize
virtual StatusCode finalize() override
Definition: VP1BatchOnLatestEvent.cxx:93