ATLAS Offline Software
Loading...
Searching...
No Matches
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
28VP1BatchOnLatestEvent::VP1BatchOnLatestEvent(const std::string& name, ISvcLocator* svcLocator)
29 : AthAlgorithm(name, svcLocator)
30 , m_nEvent(0)
31 , m_indexFile(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() ");
46 ATH_CHECK(m_eventInfoKey.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): "
66 << "] ");
67
68 if(msgLvl(MSG::DEBUG)) {
69 std::stringstream stream;
70 stream << "Event type: SIMULATION '" << std::boolalpha
71 << eventInfo->eventType (xAOD::EventInfo::IS_SIMULATION)
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
106void 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
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool msgLvl(const MSG::Level lvl) const
virtual bool isValid() override final
Can the handle be successfully dereferenced?
virtual StatusCode execute() override
VP1BatchOnLatestEvent(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
virtual StatusCode initialize() override
virtual void handle(const Incident &inc) override
virtual StatusCode finalize() override
@ IS_SIMULATION
true: simulation, false: data