Skip to content
Snippets Groups Projects
Commit ee6d2dba authored by Riccardo Maria Bianchi's avatar Riccardo Maria Bianchi :sunny: Committed by Graeme Stewart
Browse files

adding missing CMake 'atlas_install_runtime' declaration to install VP1 config...

adding missing CMake 'atlas_install_runtime' declaration to install VP1 config file in share/ (VP1AlgsBatch-00-00-03)
parent a6fa2ef9
No related branches found
No related tags found
No related merge requests found
Showing
with 545 additions and 0 deletions
################################################################################
# Package: VP1AlgsBatch
################################################################################
# Declare the package name:
atlas_subdir( VP1AlgsBatch )
# Declare the package's dependencies:
atlas_depends_on_subdirs( PUBLIC
Control/AthenaBaseComps
Database/AthenaPOOL/PoolSvc
GaudiKernel
PRIVATE
Database/APR/CollectionBase
Database/APR/CollectionUtilities
Database/APR/POOLCore
Database/APR/PersistencySvc
Database/APR/StorageSvc
Event/EventInfo
Tools/PathResolver
graphics/VP1/VP1UtilsBase )
# External dependencies:
find_package( Qt4 COMPONENTS QtCore QtOpenGL QtGui )
include_directories( /usr/X11R6/include )
# Component(s) in the package:
atlas_add_component( VP1AlgsBatch
src/*.cxx
src/components/*.cxx
INCLUDE_DIRS ${QT4_INCLUDE_DIRS}
LINK_LIBRARIES ${QT4_LIBRARIES} GL AthenaBaseComps GaudiKernel CollectionBase CollectionUtilities POOLCore PersistencySvc StorageSvc EventInfo PathResolver VP1UtilsBase )
# Install files from the package:
atlas_install_headers( VP1AlgsBatch )
atlas_install_runtime( share/*.vp1 )
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
/////////////////////////////////////////////////////////////
// //
// Header file for class VP1BatchOnLatestEvent //
// //
// Riccardo-Maria BIANCHI <rbianchi@cern.ch> //
// 11 Mar 2015 //
// //
// This is the Athena algorithm to launch VP1 in //
// batch-mode, to automatically create 3D event //
// displays on-the-fly. //
// //
/////////////////////////////////////////////////////////////
#ifndef VP1ALGS_VP1BatchOnLatestEvent
#define VP1ALGS_VP1BatchOnLatestEvent
#include "AthenaBaseComps/AthAlgorithm.h"
#include "GaudiKernel/IIncidentListener.h"
#include "PoolSvc/IPoolSvc.h"
#include <string>
// FWD
class StoreGateSvc;
class EventInfo;
class VP1BatchOnLatestEvent: public AthAlgorithm,
public IIncidentListener
{
public:
VP1BatchOnLatestEvent(const std::string& name, ISvcLocator* pSvcLocator);
~VP1BatchOnLatestEvent();
StatusCode initialize();
StatusCode execute();
StatusCode finalize();
void handle(const Incident& inc);
private:
std::string getRandomConfigFile();
void overlayATLASlogo();
void overlayEventDetails();
void getEventDetails();
void getHumanReadableTimestamp();
void makeEventDisplay();
// run/event number to be used in the vp1 event file name
// int m_runNumber;
// int m_eventNumber;
// unsigned int m_timeStamp;
// std::string m_humanTimestamp;
// properties
std::string m_inputVP1CfgFile;
std::string m_inputDir;
std::string m_destinationDir;
bool m_isGetRandomFile;
bool m_evtInfoDone;
const EventInfo* eventInfo;
// int m_maxProducedFiles;
int m_nEvent; // Internal counter for the number of processed events
int m_indexFile;
int m_lastIndexFile;
unsigned long m_eventNumber = 0;
unsigned long m_runNumber = 0;
unsigned long m_timeStamp = 0;
std::string m_humanTimestamp;
// service handle
ServiceHandle<IPoolSvc> m_poolSvc;
};
#endif
package VP1AlgsBatch
author Riccardo Maria BIANCHI <rbianchi@cern.ch>
manager Riccardo Maria BIANCHI <rbianchi@cern.ch>
use AtlasPolicy AtlasPolicy-*
use AthenaBaseComps AthenaBaseComps-* Control
use GaudiInterface GaudiInterface-* External
use PoolSvc PoolSvc-* Database/AthenaPOOL
library VP1AlgsBatch *.cxx components/*.cxx
apply_pattern component_library
apply_pattern declare_joboptions files="*.py"
apply_pattern declare_python_modules files="*.py"
# install to InstallArea the *.vp1 configuration files stored in share/
apply_pattern declare_runtime_extras extras="*.vp1" ;
#For genconfs sake we get the LD_LIBRARY_PATH to include external libs:
#private
#use VP1Qt VP1Qt-* graphics/VP1
#use AtlasCoinInventor AtlasCoinInventor-* External
#use AtlasSoQt AtlasSoQt-* External
#path_remove LD_LIBRARY_PATH "/CoinInventor/"
#path_append LD_LIBRARY_PATH "$(AtlasCoinInventor_home)/lib"
#path_remove LD_LIBRARY_PATH "/SoQt/"
#path_append LD_LIBRARY_PATH "$(AtlasSoQt_home)/lib"
private
use VP1Qt VP1Qt-* graphics/VP1 -no_auto_imports # Needed for linker. The flag '-no_auto_imports' avoids CHECKREQ errors.
use VP1UtilsBase VP1UtilsBase-* graphics/VP1
use EventInfo EventInfo-* Event
use PathResolver PathResolver-* Tools
use AtlasPOOL AtlasPOOL-* External
File added
File added
File added
File added
File added
File added
File added
File added
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#include "VP1AlgsBatch/VP1BatchOnLatestEvent.h"
#include "VP1UtilsBase/VP1FileUtilities.h"
#include "StorageSvc/DbType.h"
#include "EventInfo/EventInfo.h"
#include "EventInfo/EventID.h"
#include "EventInfo/EventType.h"
#include "EventInfo/EventIncident.h"
#include "PathResolver/PathResolver.h"
#include "GaudiKernel/FileIncident.h"
#include "GaudiKernel/ServiceHandle.h"
#include "GaudiKernel/IEvtSelector.h"
#include "GaudiKernel/IIncidentSvc.h"
#include "GaudiKernel/ToolHandle.h"
#include <vector>
#include <iostream>
#include <iomanip>
#include <stdexcept>
#include <unistd.h>
#include <ctime> /* time_t, time, ctime */
#include <random> // C++11
#include <string>
VP1BatchOnLatestEvent::VP1BatchOnLatestEvent(const std::string& name, ISvcLocator* svcLocator):
AthAlgorithm(name, svcLocator),
// m_runNumber(0),
// m_eventNumber(0),
// m_timeStamp(0),
// m_humanTimestamp(""),
m_evtInfoDone(false),
m_nEvent(0),
m_indexFile(0),
m_lastIndexFile(0),
m_poolSvc("PoolSvc", name)
{
declareProperty("VP1ConfigFile", m_inputVP1CfgFile="");
declareProperty("DestinationDirectory", m_destinationDir=""); // produce files in the run directory by default
declareProperty("InputDirectory", m_inputDir=""); // the directory where the input data files (e.g. ESDs) are stored
declareProperty("UseRandomVP1ConfigFile", m_isGetRandomFile = false); // get random configuration files if TRUE
// declareProperty("MaxNumberOfFiles", m_maxProducedFiles=5); // keep 5 event files in the run directory
}
// TODO: add DestinationDirectory as argument to the -batch VP1 command option, so we can configure output folder from JobOption
VP1BatchOnLatestEvent::~VP1BatchOnLatestEvent()
{
}
StatusCode VP1BatchOnLatestEvent::initialize()
{
msg(MSG::INFO) << " in initialize() " << endreq;
StatusCode result = StatusCode::SUCCESS;
// use the incident service to register a handle
IIncidentSvc* incsvc = 0;
StatusCode status = service("IncidentSvc", incsvc, true);
if(status.isFailure() || incsvc==0)
msg(MSG::WARNING) << "Unable to get IncidentSvc!" << endreq;
else
incsvc->addListener(this, "BeginEvent", 0);
// get hold of the PoolSvc
status = m_poolSvc.retrieve();
if(status.isFailure())
msg(MSG::WARNING) << "Unable to get PoolSvc" << endreq;
return result;
}
StatusCode VP1BatchOnLatestEvent::execute()
{
msg(MSG::DEBUG) <<" in execute() " << endreq;
//----------------------------
// Event information
//---------------------------
eventInfo = 0; //NOTE: Everything that comes from the storegate direct from the input files is const!
// ask the event store to retrieve the xAOD EventInfo container
//CHECK( evtStore()->retrieve( eventInfo, "EventInfo") ); // the second argument ("EventInfo") is the key name
//CHECK( evtStore()->retrieve( eventInfo, "McEventInfo") ); // the second argument ("McEventInfo") is the key name
// CHECK( evtStore()->retrieve( eventInfo) );
StatusCode status = evtStore()->retrieve( eventInfo);
// if there is only one container of that type in the xAOD (as with the EventInfo container), you do not need to pass
// the key name, the default will be taken as the only key name in the xAOD
if(status.isSuccess() && eventInfo!=0) {
m_evtInfoDone = true;
}
getEventDetails();
return StatusCode::SUCCESS;
}
StatusCode VP1BatchOnLatestEvent::finalize()
{
msg(MSG::INFO) <<"in finalize() " << endreq;
// Let VP1FileUtilities handle the output of the last event
if(m_nEvent) {
makeEventDisplay();
}
return StatusCode::SUCCESS;
}
void VP1BatchOnLatestEvent::handle(const Incident& inc)
{
msg(MSG::INFO) << "Handling incident '" << inc.type() << "'" << endreq;
const EventIncident* eventInc = dynamic_cast<const EventIncident*>(&inc);
if(eventInc == 0) {
msg(MSG::WARNING) << " Unable to cast incident type" << endreq;
return;
} else {
msg(MSG::DEBUG) << " Event incident casting successful" << endreq;
}
// Let VP1FileUtilities handle the output of the previous event
if(m_nEvent) {
makeEventDisplay();
}
m_nEvent++;
}
void VP1BatchOnLatestEvent::makeEventDisplay() {
// if the user specified empty config file name and declared 'VP1BatchOnLatestEvent.UseRandomVP1ConfigFile=True' in the jobOption
if (m_isGetRandomFile) {
msg(MSG::INFO)
<< "--> RANDOM MODE: Using a random VP1 configuration file..."
<< endreq;
m_inputVP1CfgFile = getRandomConfigFile();
}
msg(MSG::INFO) << "--> Input VP1 Configuration file: " << m_inputVP1CfgFile
<< endreq;
// LAUNCH VP1-Batch on the latest-produced ESD file
std::string commandStr = "vp1 -batch";
// add custom output folder, if user specified it
if (m_destinationDir != "") {
msg(MSG::INFO) << " --> Using user-defined output folder: "
<< m_destinationDir << endreq;
commandStr += " -batch-output-folder=" + m_destinationDir;
}
commandStr += " `cat latest_vp1event` " + m_inputVP1CfgFile;
bool vp1OK = false;
msg(MSG::INFO) << " ===> launching VP1-Batch: " << commandStr << endreq;
try {
system(commandStr.c_str());
vp1OK = true;
} catch (std::runtime_error& err) {
msg(MSG::WARNING) << "Exception caught: " << err.what() << endreq;
msg(MSG::WARNING)
<< "Unable to launch VP1-Batch on the latest-produced event file"
<< endreq;
}
if (vp1OK) {
// Overlay the ATLAS logo to the image
overlayATLASlogo();
// Overlay the event details to the image
overlayEventDetails();
}
}
std::string VP1BatchOnLatestEvent::getRandomConfigFile()
{
msg(MSG::DEBUG) <<" in getRandomConfigFile() " << endreq;
std::string configFile;
// a list of possible config files, which are stored in the "share/" folder
std::vector<std::string> configFiles;
configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wTRTGeo.vp1");
configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wTRTGeo_IAview.vp1");
configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wTRTGeo_wBarrel.vp1");
configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wPixel_wSCT_wOpenCalo_wGeo_3D.vp1");
configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wPixel_wSCT_wGeo_3D.vp1");
configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wPixel_3D.vp1");
configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wIDGeo.vp1");
configFiles.push_back("vp1_conf_ATLASatHOME_truth_event_wGeo_frontView.vp1");
int nConfigFiles = configFiles.size();
msg(MSG::DEBUG) << " ===> # config files: " << nConfigFiles << endreq;
int nPositions = nConfigFiles - 1;
// setup random generator in [0, nConfigFiles]
auto seed = std::random_device{}();
auto randomDist = std::bind(std::uniform_int_distribution<int>(0, nPositions ),
std::mt19937(seed));
// get a random index,
// avoiding having the same index in a row
while ( m_indexFile == m_lastIndexFile )
m_indexFile = randomDist();
m_lastIndexFile = m_indexFile;
msg(MSG::DEBUG) << " ===> random index: " << m_indexFile << endreq;
//std::string configFile = "vp1_conf_ATLASatHOME_truth_event_wTRTGeo.vp1";
configFile = configFiles[m_indexFile];
msg(MSG::DEBUG) << " ===> random file: " << configFile << endreq;
return configFile;
}
// Overlay the ATLAS logo to the image
void VP1BatchOnLatestEvent::overlayATLASlogo()
{
//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
//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
std::string commandStr = "convert -composite `cat latest_vp1image` $TestArea/InstallArea/share/ATLAS-Logo-New_300pixels.png -geometry +10+10 -depth 8 `cat latest_vp1image`";
msg(MSG::DEBUG) << " ===> overlay the ATLAS logo: " << commandStr << endreq;
try {
system(commandStr.c_str());
} catch (std::runtime_error& err) {
msg(MSG::WARNING) << "Exception caught: " << err.what() << endreq;
msg(MSG::WARNING) << "Unable to run 'convert'!" << endreq;
}
}
// Overlay the event details to the image
// it replaces the original image with a version having event details on it
void VP1BatchOnLatestEvent::overlayEventDetails()
{
std::string nRun = std::to_string(m_runNumber);
std::string nEvent = std::to_string(m_eventNumber);
// bash command:
// 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
// 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
// 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
std::string commandStr;
// setting bash variables
commandStr += "nRun="+nRun+"; ";
commandStr += "nEvent="+nEvent+"; ";
if (m_timeStamp > 0) commandStr += "timestamp='"+m_humanTimestamp+"'; "; // 'timestamp' must not have white spaces
// get input image
commandStr += "img=`cat latest_vp1image`; "; // get the filename of the latest image produced
commandStr += "width=$(identify -format %W ${img}); "; // get the width of the image
commandStr += "width=$(( ${width} * 3 / 10 )); "; // set the caption width as a fraction of the image width
// ImageMagik 'convert' command settings. (ImageMagik is installed by default on SLC LXPLUS machines)
commandStr = commandStr
+ "convert "
+ "-background '#0008' " // semi-transparent grey bkg
+ "-geometry +20+20 " // set an offset to the label position
+ "-gravity West " // set text position inside the caption space (justification)
+ "-fill white " // text font color
+ "-size ${width}x80 " // set text size relative to 'width'
+ "-font Courier " // text font
+ "-density 72 " // dots-per-inch resolution
+ "-pointsize 18 " // text size in points
//+ "-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...)
//+ "caption:'Run number: ${nRun}' " // set the caption text
+ (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()
+ "${img} " // imput image
+ "+swap "
+ "-gravity SouthEast " // set overall caption position
+ "-composite "
+ "${img}"; // output image: here we replace the original image
msg(MSG::DEBUG) << " ===> overlay the event details: " << commandStr << endreq;
try {
system(commandStr.c_str());
} catch (std::runtime_error& err) {
msg(MSG::WARNING) << "Exception caught: " << err.what() << endreq;
msg(MSG::WARNING) << "Unable to run 'convert'!" << endreq;
}
}
void VP1BatchOnLatestEvent::getEventDetails()
{
// Update run_number/event_number/time_stamp
msg(MSG::DEBUG) << "getEventDetails()" << endreq;
if(m_evtInfoDone) {
ATH_MSG_DEBUG(*(eventInfo->event_ID()));
m_eventNumber = eventInfo->event_ID()->event_number();
m_runNumber = eventInfo->event_ID()->run_number();
m_timeStamp = eventInfo->event_ID()->time_stamp(); // posix time in seconds from 1970, 32 bit unsigned
ATH_MSG_DEBUG("run number: "<< m_runNumber
<< ", event number: "
<< m_eventNumber << " : timestamp (UNIX): "
<< m_timeStamp
<< "] ");
std::stringstream stream;
stream << "Event type: user type '"
<< eventInfo->event_type()->user_type()
<< "' - ";
for (unsigned int i = 0; i < eventInfo->event_type()->n_mc_event_weights (); ++i) {
stream << " weight " << i << ": " << eventInfo->event_type()->mc_event_weight(i);
}
ATH_MSG_DEBUG(stream.str());
}
if (!m_evtInfoDone) {
msg(MSG::ERROR) << " Unable to retrieve EventInfo (or McEventInfo) from StoreGate!!!" << endreq;
m_eventNumber = 0;
m_runNumber = 0;
m_timeStamp = 0;
}
// get a human-readable timestamp from UNIX time
getHumanReadableTimestamp();
}
void VP1BatchOnLatestEvent::getHumanReadableTimestamp()
{
time_t t_timestamp = m_timeStamp;
tm *ltm = localtime(&t_timestamp);
// print various components of tm structure.
msg(MSG::DEBUG) << "Year: "<< 1900 + ltm->tm_year
<< " - " << "Month: "<< 1 + ltm->tm_mon<< " - " // tm_mon is in the range [0, 11], so 1 must be added to get real months
<< "Day: "<< ltm->tm_mday
<< " - " "Time: "<< ltm->tm_hour << ":" << ltm->tm_min << ":" << ltm->tm_sec // << "CEST" FIXME: check if time zone is available on data file
<< endreq;
std::ostringstream ostri;
ostri << 1900 + ltm->tm_year
<< "-" << 1 + ltm->tm_mon // tm_mon is in the range [0, 11], so 1 must be added to get real months
<< "-" << ltm->tm_mday
<< "T" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec; // << "CEST"; FIXME: check if time zone is available on data file
m_humanTimestamp = ostri.str();
msg(MSG::DEBUG) << "'human readable' timestamp: " << m_humanTimestamp << endreq;
}
#include "GaudiKernel/DeclareFactoryEntries.h"
#include "VP1AlgsBatch/VP1BatchOnLatestEvent.h"
DECLARE_ALGORITHM_FACTORY(VP1BatchOnLatestEvent)
DECLARE_FACTORY_ENTRIES(VP1AlgsBatch) {
DECLARE_ALGORITHM( VP1BatchOnLatestEvent );
}
#include "GaudiKernel/LoadFactoryEntries.h"
LOAD_FACTORY_ENTRIES(VP1AlgsBatch)
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