ATLAS Offline Software
Loading...
Searching...
No Matches
OnlineEventDisplaysSvc Class Reference

#include <OnlineEventDisplaysSvc.h>

Inheritance diagram for OnlineEventDisplaysSvc:
Collaboration diagram for OnlineEventDisplaysSvc:

Public Member Functions

 OnlineEventDisplaysSvc (const std::string &name, ISvcLocator *pSvcLocator)
StatusCode initialize () override
StatusCode finalize () override
void beginEvent ()
void endEvent ()
void handle (const Incident &incident) override
void createWriteableDir (const std::string &directory, gid_t zpgid)
gid_t setOwnershipToZpGrpOrDefault ()
std::string getFileNamePrefix () override
std::string getEntireOutputStr () override
std::string getStreamName () override

Private Member Functions

 OnlineEventDisplaysSvc ()

Private Attributes

SG::ReadHandleKey< xAOD::EventInfom_evt {this, "EventInfo", "EventInfo", "Input event information"}
Gaudi::Property< std::string > m_outputDirectory {this, "OutputDirectory", "/atlas/EventDisplayEvents", "Output Directory"}
Gaudi::Property< std::vector< std::string > > m_streamsWanted {this, "StreamsWanted", {}, "Desired trigger streams"}
Gaudi::Property< std::vector< std::string > > m_publicStreams {this, "PublicStreams", {}, "Streams that can be seen by the public"}
Gaudi::Property< std::string > m_projectTag {this, "ProjectTag", "", "Is needed to add streams to the Public trigger streams"}
Gaudi::Property< bool > m_BeamSplash {this, "BeamSplash", false, "Is a beam splash event"}
Gaudi::Property< bool > m_CheckPair {this, "CheckPair", false, "Check for matching ESD and JiveXML files"}
Gaudi::Property< int > m_maxEvents {this, "MaxEvents", 200, "Number of events to keep per stream"}
std::string m_FileNamePrefix = "JiveXML"
std::string m_outputStreamDir = ".Unknown"
std::string m_entireOutputStr = "."
int m_runNumber {}
long m_eventNumber {}

Detailed Description

Definition at line 16 of file OnlineEventDisplaysSvc.h.

Constructor & Destructor Documentation

◆ OnlineEventDisplaysSvc() [1/2]

OnlineEventDisplaysSvc::OnlineEventDisplaysSvc ( const std::string & name,
ISvcLocator * pSvcLocator )

Definition at line 30 of file OnlineEventDisplaysSvc.cxx.

31 :
32 base_class(name, pSvcLocator){}

◆ OnlineEventDisplaysSvc() [2/2]

OnlineEventDisplaysSvc::OnlineEventDisplaysSvc ( )
private

Member Function Documentation

◆ beginEvent()

void OnlineEventDisplaysSvc::beginEvent ( )

Definition at line 34 of file OnlineEventDisplaysSvc.cxx.

34 {
35
36 SG::ReadHandle<xAOD::EventInfo> evt (m_evt);
37 if (!evt.isValid()) {
38 ATH_MSG_FATAL("Could not find event info");
39 }
40 std::vector<std::string> streams;
41
42 m_eventNumber = evt->eventNumber();
43 m_runNumber = evt->runNumber();
44
45 //Check what trigger streams were fired, if in list of desired
46 //streams to be reconstructed pick one randomly
47 for (const xAOD::EventInfo::StreamTag& tag : evt->streamTags()){
48 ATH_MSG_DEBUG("A trigger in stream " << tag.type() << "_" << tag.name() << " was fired in this event.");
49 std::string stream_fullname = tag.type() + "_" + tag.name();
50
51 if (m_streamsWanted.empty()) {
52 ATH_MSG_WARNING("You have not requested any specific streams, going to allow all streams");
53 streams.emplace_back(stream_fullname);
54 }
55
56 else{
57 //If the stream is in the list of streams requested, add it
58 if(std::find(m_streamsWanted.begin(), m_streamsWanted.end(), tag.name()) != m_streamsWanted.end()){
59 streams.emplace_back(stream_fullname);
60 }
61 bool isPublic = false;
62 //if the stream is not in the list of public streams wanted, continue
63 if(std::find(m_publicStreams.begin(), m_publicStreams.end(), tag.name()) == m_publicStreams.end()) continue;
64 // Acquire the Global Interpreter Lock (GIL) to ensure thread safety when interacting with Python objects
65 RootUtils::PyGILStateEnsure ensure;
66 // Convert the project tag string to a Python Unicode object
67 std::string tag = m_projectTag;
68 PyObject* pProjectTag = PyUnicode_FromString(tag.c_str());
69 if (!pProjectTag) {
70 // Error handling: Print Python exception if conversion fails
71 PyErr_Print();
72 ATH_MSG_WARNING("Failed to create Python Unicode object from project tag");
73 } else {
74 // Import the Python module
75 PyObject* pHelper = PyImport_ImportModule("EventDisplaysOnline.EventDisplaysOnlineHelpers");
76 if (!pHelper) {
77 // Error handling: Print Python exception if import fails
78 PyErr_Print();
79 ATH_MSG_WARNING("Failed to import EventDisplaysOnline.EventDisplaysOnlineHelpers module");
80 } else {
81 // Get the "EventCanBeSeenByPublic" function from the module
82 PyObject* EventCanBeSeenByPublic = PyObject_GetAttrString(pHelper, "EventCanBeSeenByPublic");
83 if (!EventCanBeSeenByPublic || !PyCallable_Check(EventCanBeSeenByPublic)) {
84 // Error handling: Print warning if function not found or not callable
85 ATH_MSG_WARNING("Could not find or call EventCanBeSeenByPublic function in EventDisplaysOnline.EventDisplaysOnlineHelpers module");
86 } else {
87 // Call the "EventCanBeSeenByPublic" function with the project tag as argument
88 PyObject* result = PyObject_CallFunctionObjArgs(EventCanBeSeenByPublic, pProjectTag, NULL);
89 if (!result) {
90 PyErr_Print();
91 ATH_MSG_WARNING("Failed to call EventCanBeSeenByPublic function");
92 } else {
93 // Convert the result to a boolean value
94 isPublic = PyObject_IsTrue(result);
95 Py_DECREF(result); // Decrement reference count of the result object
96 }
97 }
98 Py_XDECREF(EventCanBeSeenByPublic);
99 Py_DECREF(pHelper);
100 }
101 Py_DECREF(pProjectTag);
102 }
103 if(isPublic){
104 streams.emplace_back("Public");
105 ATH_MSG_DEBUG("Can send event to public stream");
106 }
107 }
108 }
109 for (const std::string& stream : streams){
110 ATH_MSG_DEBUG("streams where a trigger fired and in your desired streams list: " << stream);
111 }
112 std::random_shuffle(streams.begin(), streams.end());
113 //Pick the first stream as the output directory
114 if(!streams.empty()){
116 }
117 else{
118 ATH_MSG_WARNING("Cannot find a stream adding to .Unknown directory");
119 m_outputStreamDir = ".Unknown";
120 }
121
123 m_FileNamePrefix = m_entireOutputStr + "/JiveXML";;
124
125 gid_t zpgid = setOwnershipToZpGrpOrDefault();
128}
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
_object PyObject
Gaudi::Property< std::vector< std::string > > m_streamsWanted
void createWriteableDir(const std::string &directory, gid_t zpgid)
Gaudi::Property< std::string > m_outputDirectory
SG::ReadHandleKey< xAOD::EventInfo > m_evt
Gaudi::Property< std::vector< std::string > > m_publicStreams
Gaudi::Property< std::string > m_projectTag

◆ createWriteableDir()

void OnlineEventDisplaysSvc::createWriteableDir ( const std::string & directory,
gid_t zpgid )

Definition at line 188 of file OnlineEventDisplaysSvc.cxx.

188 {
189
190 const char* char_dir = directory.c_str();
191 //Time of Check, Time of Use
192 //coverity[TOCTOU]
193 if (access(char_dir, F_OK) == 0) {
194 struct stat directoryStat;
195 //Time of Check, Time of Use
196 //coverity[TOCTOU]
197 if (stat(char_dir, &directoryStat) == 0 && S_ISDIR(directoryStat.st_mode) &&
198 access(char_dir, W_OK) == 0) {
199 ATH_MSG_DEBUG("Going to write file to existing directory: " << directory);
200 if (directoryStat.st_gid != zpgid) {
201 ATH_MSG_DEBUG("Setting group to 'zp' for directory: " << directory);
202 chown(char_dir, -1, zpgid);
203 }
204 } else {
205 ATH_MSG_WARNING("Directory '" << directory << "' is not usable, trying next alternative");
206 }
207 } else {
208 try {
209 auto rc = mkdir(char_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
210 if (rc !=0){
211 ATH_MSG_ERROR("mkdir failed for directory: " << directory);
212 }
213 rc = chown(char_dir, -1, zpgid);
214 if (rc !=0){
215 ATH_MSG_ERROR( "chown failed for directory: " << directory);
216 }
217 ATH_MSG_DEBUG("Created output directory " << directory);
218 } catch (const std::system_error& err) {
219 ATH_MSG_ERROR( "Failed to create output directory " << directory << err.what());
220 }
221 }
222}
#define ATH_MSG_ERROR(x)
static Double_t rc
str directory
Definition DeMoScan.py:78
mkdir(path, recursive=True)
access(filename, mode)

◆ endEvent()

void OnlineEventDisplaysSvc::endEvent ( )

Definition at line 130 of file OnlineEventDisplaysSvc.cxx.

130 {
131 RootUtils::PyGILStateEnsure ensure;
132 PyObject* pCheckPair = PyBool_FromLong(m_CheckPair);
133 PyObject* pBeamSplash = PyBool_FromLong(m_BeamSplash);
134 PyObject* pMaxEvents = PyLong_FromLong(m_maxEvents);
135 const char* cString = m_entireOutputStr.c_str();
136 PyObject* pDirectory = PyUnicode_FromString(cString);
137 PyObject* pArgs = PyTuple_Pack(4, pDirectory, pMaxEvents, pCheckPair,pBeamSplash);
138 PyObject* pModule = PyImport_ImportModule(const_cast< char* >("EventDisplaysOnline.EventUtils"));
139 if(!pCheckPair || !pBeamSplash || !pMaxEvents || !pDirectory || !pArgs){
140 PyErr_Print();
141 ATH_MSG_WARNING("Failed to create Python Unicode object");}
142 if (!pModule) {
143 PyErr_Print();
144 ATH_MSG_WARNING("Failed to import EventDisplaysOnline.EventUtils module");
145 } else {
146 ATH_MSG_DEBUG("Successfully imported EventDisplaysOnline.EventUtils module");
147
148 // Get the "cleanDirectory" function from the module
149 PyObject* cleanDirectory = PyObject_GetAttrString(pModule, "cleanDirectory");
150 if (!cleanDirectory || !PyCallable_Check(cleanDirectory)) {
151 ATH_MSG_WARNING("Could not find or call cleanDirectory function in EventDisplaysOnline.EventUtils module");
152 } else {
153 ATH_MSG_DEBUG("Found cleanDirectory function in EventDisplaysOnline.EventUtils module");
154
155 // Call the "cleanDirectory" function with the provided arguments
156 PyObject_CallObject(cleanDirectory, pArgs);
157 if (PyErr_Occurred()) {
158 PyErr_Print();
159 }
160 }
161 if (anyNullPtr(cleanDirectory)){
162 throw std::runtime_error("OnlineEventDisplaysSvc::endEvent: Py_DECREF on nullptr argument");
163 }
164 Py_DECREF(cleanDirectory);
165 }
166
167 if (anyNullPtr(pModule, pArgs, pCheckPair, pMaxEvents, pDirectory)){
168 throw std::runtime_error("OnlineEventDisplaysSvc::endEvent: Py_DECREF on nullptr argument");
169 }
170 Py_DECREF(pModule);
171 Py_DECREF(pArgs);
172 Py_DECREF(pCheckPair);
173 Py_DECREF(pMaxEvents);
174 Py_DECREF(pDirectory);
175}
Gaudi::Property< bool > m_CheckPair
Gaudi::Property< int > m_maxEvents
Gaudi::Property< bool > m_BeamSplash
cleanDirectory(directory, max_pairs, check_pair, is_beam_splash_mode)
Definition EventUtils.py:17

◆ finalize()

StatusCode OnlineEventDisplaysSvc::finalize ( )
override

Definition at line 259 of file OnlineEventDisplaysSvc.cxx.

259 {
260
261 ATH_MSG_DEBUG("Finalizing " << name());
262 return StatusCode::SUCCESS;
263}

◆ getEntireOutputStr()

std::string OnlineEventDisplaysSvc::getEntireOutputStr ( )
override

Definition at line 181 of file OnlineEventDisplaysSvc.cxx.

181 {
182 return m_entireOutputStr;
183}

◆ getFileNamePrefix()

std::string OnlineEventDisplaysSvc::getFileNamePrefix ( )
override

Definition at line 177 of file OnlineEventDisplaysSvc.cxx.

177 {
178 return m_FileNamePrefix;
179}

◆ getStreamName()

std::string OnlineEventDisplaysSvc::getStreamName ( )
override

Definition at line 185 of file OnlineEventDisplaysSvc.cxx.

185 {
186 return m_outputStreamDir;
187}

◆ handle()

void OnlineEventDisplaysSvc::handle ( const Incident & incident)
override

Definition at line 265 of file OnlineEventDisplaysSvc.cxx.

265 {
266 ATH_MSG_DEBUG("Received incident " << incident.type() << " from " << incident.source() );
267 if ( incident.type() == IncidentType::BeginEvent && incident.source() == "BeginIncFiringAlg" ){
268 beginEvent();
269 }
270 if (incident.type() == "EndEvent" && incident.source() == "EndIncFiringAlg"){
271 endEvent();
272 }
273}

◆ initialize()

StatusCode OnlineEventDisplaysSvc::initialize ( )
override

Definition at line 239 of file OnlineEventDisplaysSvc.cxx.

239 {
240
241 ATH_MSG_DEBUG("Initializing " << name());
242 ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", name());
243 ATH_CHECK( incSvc.retrieve() );
244 ATH_MSG_DEBUG("You have requested to only output JiveXML and ESD files when a trigger in the following streams was fired: ");
245 for (const std::string& stream : m_streamsWanted){
246 ATH_MSG_DEBUG(stream);
247 }
248 if(m_BeamSplash){
249 m_CheckPair = false;
250 }
251 incSvc->addListener( this, "BeginEvent");
252 incSvc->addListener( this, "EndEvent");
253
254 ATH_CHECK( m_evt.initialize() );
255
256 return StatusCode::SUCCESS;
257}
#define ATH_CHECK
Evaluate an expression and check for errors.

◆ setOwnershipToZpGrpOrDefault()

gid_t OnlineEventDisplaysSvc::setOwnershipToZpGrpOrDefault ( )

Definition at line 224 of file OnlineEventDisplaysSvc.cxx.

224 {
225 gid_t zpgid;
226 struct group grp;
227 struct group* grp_result;
228 char buf[1024]; // sysconf(_SC_GETGR_R_SIZE_MAX)
229 (void)getgrnam_r("zp", &grp, buf, sizeof(buf), &grp_result);
230 if (grp_result != nullptr) {
231 zpgid = grp.gr_gid;
232 } else {
233 ATH_MSG_DEBUG("If running on private machine, zp group might not exist. Just set to the likely value 1307.");
234 zpgid = 1307;
235 }
236 return zpgid;
237}

Member Data Documentation

◆ m_BeamSplash

Gaudi::Property<bool> OnlineEventDisplaysSvc::m_BeamSplash {this, "BeamSplash", false, "Is a beam splash event"}
private

Definition at line 41 of file OnlineEventDisplaysSvc.h.

41{this, "BeamSplash", false, "Is a beam splash event"};

◆ m_CheckPair

Gaudi::Property<bool> OnlineEventDisplaysSvc::m_CheckPair {this, "CheckPair", false, "Check for matching ESD and JiveXML files"}
private

Definition at line 42 of file OnlineEventDisplaysSvc.h.

42{this, "CheckPair", false, "Check for matching ESD and JiveXML files"};

◆ m_entireOutputStr

std::string OnlineEventDisplaysSvc::m_entireOutputStr = "."
private

Definition at line 46 of file OnlineEventDisplaysSvc.h.

◆ m_eventNumber

long OnlineEventDisplaysSvc::m_eventNumber {}
private

Definition at line 48 of file OnlineEventDisplaysSvc.h.

48{};

◆ m_evt

SG::ReadHandleKey<xAOD::EventInfo> OnlineEventDisplaysSvc::m_evt {this, "EventInfo", "EventInfo", "Input event information"}
private

Definition at line 36 of file OnlineEventDisplaysSvc.h.

36{this, "EventInfo", "EventInfo", "Input event information"};

◆ m_FileNamePrefix

std::string OnlineEventDisplaysSvc::m_FileNamePrefix = "JiveXML"
private

Definition at line 44 of file OnlineEventDisplaysSvc.h.

◆ m_maxEvents

Gaudi::Property<int> OnlineEventDisplaysSvc::m_maxEvents {this, "MaxEvents", 200, "Number of events to keep per stream"}
private

Definition at line 43 of file OnlineEventDisplaysSvc.h.

43{this, "MaxEvents", 200, "Number of events to keep per stream"};

◆ m_outputDirectory

Gaudi::Property<std::string> OnlineEventDisplaysSvc::m_outputDirectory {this, "OutputDirectory", "/atlas/EventDisplayEvents", "Output Directory"}
private

Definition at line 37 of file OnlineEventDisplaysSvc.h.

37{this, "OutputDirectory", "/atlas/EventDisplayEvents", "Output Directory"};

◆ m_outputStreamDir

std::string OnlineEventDisplaysSvc::m_outputStreamDir = ".Unknown"
private

Definition at line 45 of file OnlineEventDisplaysSvc.h.

◆ m_projectTag

Gaudi::Property<std::string> OnlineEventDisplaysSvc::m_projectTag {this, "ProjectTag", "", "Is needed to add streams to the Public trigger streams"}
private

Definition at line 40 of file OnlineEventDisplaysSvc.h.

40{this, "ProjectTag", "", "Is needed to add streams to the Public trigger streams"};

◆ m_publicStreams

Gaudi::Property<std::vector<std::string> > OnlineEventDisplaysSvc::m_publicStreams {this, "PublicStreams", {}, "Streams that can be seen by the public"}
private

Definition at line 39 of file OnlineEventDisplaysSvc.h.

39{this, "PublicStreams", {}, "Streams that can be seen by the public"};

◆ m_runNumber

int OnlineEventDisplaysSvc::m_runNumber {}
private

Definition at line 47 of file OnlineEventDisplaysSvc.h.

47{};

◆ m_streamsWanted

Gaudi::Property<std::vector<std::string> > OnlineEventDisplaysSvc::m_streamsWanted {this, "StreamsWanted", {}, "Desired trigger streams"}
private

Definition at line 38 of file OnlineEventDisplaysSvc.h.

38{this, "StreamsWanted", {}, "Desired trigger streams"};

The documentation for this class was generated from the following files: