LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
EventDisplay.cc
Go to the documentation of this file.
9 // ROOT includes
10 #include "TROOT.h"
11 #include "TApplication.h"
12 #include "TText.h"
13 #include "TCanvas.h"
14 // ART includes framework includes
15 #include "art_root_io/RootInput.h"
18 #include "cetlib_except/exception.h"
19 // Local includes
26 
27 #include <wordexp.h>
28 
29 namespace evdb
30 {
31  //
32  // Build this as soon as the library is loaded to ensure that our
33  // interactive session is started before other services that might use
34  // ROOT get a chance to make their own.
35  //
36  static evdb::RootEnv gsRootEnv(0,0);
37 
38  //......................................................................
39 
40  class testCanvas1 : public evdb::Canvas
41  {
42  public:
43  testCanvas1(TGMainFrame* mf) : evdb::Canvas(mf) {
45  }
48  }
49  const char* Description() const { return "Test Canvas 1"; }
50  const char* PrintTag() const { return "Test1"; }
51  void Draw(const char* /* opt */) {
52  static TText* t = new TText(0.5,0.5,"-");
53  static int count = 0;
54  char buff[256];
55  sprintf(buff,"%d",count);
56  mf::LogWarning("EventDisplayBase") << buff;
57  t->SetText(0.5,0.5,buff);
58  t->Draw();
59  ++count;
60  fCanvas->Update();
61  }
62  };
63 
64  //......................................................................
65  // Uncomment this static method for testing purposes
66  // static evdb::Canvas* mk_canvas1(TGMainFrame* mf) {
67  // return new testCanvas1(mf);
68  // }
69 
70  //......................................................................
71 
73  art::ActivityRegistry& reg) :
74  fAutoPrintCount(0)
75  {
76  // evdb::DisplayWindow::Register("Test1","Test display #1",600,900,mk_canvas1);
77  // evdb::DisplayWindow::OpenWindow(0);
78 
79  this->reconfigure(pset);
80 
81  reg.sPostBeginJob.watch (this, &EventDisplay::postBeginJob);
85  }
86 
87  //......................................................................
88 
90  {
91  fAutoAdvanceInterval = pset.get<unsigned int>("AutoAdvanceInterval" );
92  fAutoPrintMax = pset.get<int >("AutoPrintMax", 0 );
93  fAutoPrintPattern = pset.get<std::string >("AutoPrintPattern", "");
94  fEchoPrint = pset.get<bool >("EchoPrint", false);
95  fEchoPrintFile = pset.get<std::string >("EchoPrintFile", "$HOME/evt_echo.gif");
96  // Sanitize filename: root's OK with env variables, straight system
97  // calls are not. So, force a substitution of env. variables in the
98  // filename so we can do atomic-write "renames" later using a tmp file
99  if (fEchoPrint) {
100  wordexp_t p;
101  char** w;
102  wordexp( fEchoPrintFile.c_str(), &p, 0 );
103  w = p.we_wordv;
104  fEchoPrintFile = std::string(*w);
105  // the tempfile has to end with the same extension (eg, ".gif") as
106  // the specified filename. root's printing takes the format of the file
107  // from that extension. So, we have to construct a name with the same
108  // path, and extension: need to insert a "tmp" before the final .gif
109  // Sp, simply grab the file extension and stick it back on the end
110  std::string::size_type idx;
111  std::string extension;
112  idx = fEchoPrintFile.rfind('.');
113  if(idx != std::string::npos) {
114  extension = fEchoPrintFile.substr(idx);
115  fEchoPrintTempFile = std::string(*w) + ".tmp" + extension;
116  } else {
117  // No extension found, can't do this
118  fEchoPrint = false;
119  fEchoPrintTempFile = "";
120  mf::LogWarning("EventDisplayBase")
121  << "No file extension given to EchoPrintFile "
122  << fEchoPrintFile
123  << " so cannot determine file format, disabling EchoPrint\n";
124  }
125  wordfree(&p);
126  } else {
127  fEchoPrintTempFile = "";
128  }
129  }
130 
131  //......................................................................
132 
134  std::vector<art::Worker*> const&)
135  {
136  fInputSource = input_source;
137  }
138 
139  //......................................................................
140 
142  {
144  }
145 
146  //......................................................................
147 
149  {
151  }
152 
153  //......................................................................
154 
156  {
157  // stuff the event into the holder
159  holder->SetEvent(&evt);
160 
162 
163  if(fAutoPrintMax == 0){
164  TApplication* app = gROOT->GetApplication();
165 
166  // Hold here for user input from the GUI...
167  app->Run(kTRUE);
168  }
169 
170  //
171  // Apply edits to any services that may have been reconfigured
172  //
174 
175  if(fAutoPrintMax > 0){
176  ++fAutoPrintCount;
177  std::map<std::string, Printable*>& ps = Printable::GetPrintables();
178  for(std::map<std::string,Printable*>::iterator it = ps.begin(); it != ps.end(); ++it){
179  Printable* p = it->second;
180  // Ensure the format string is well-formed
181  if(fAutoPrintPattern.find("%s") == std::string::npos)
182  throw cet::exception("EventDisplay") << "Cannot find AutoPrintPattern"
183  << " format for %s";
184  if(fAutoPrintPattern.find("%d") == std::string::npos)
185  throw cet::exception("EventDisplay") << "Cannot find AutoPrintPattern"
186  << " format for %d";
187  // png doesn't seem to work for some reason
188  p->Print(TString::Format(fAutoPrintPattern.c_str(), p->PrintTag(), evt.event()));
189  }
190  if(fAutoPrintCount >= fAutoPrintMax) exit(0);
191  }
192 
193  // if fEchoPrint is set, do so
194  if (fEchoPrint){
195  std::map<std::string, Printable*>& ps = Printable::GetPrintables();
196  for(std::map<std::string,Printable*>::iterator it = ps.begin(); it != ps.end(); ++it){
197  Printable* p = it->second;
198  // lack of more parameters to Print() call means use the file format
199  // that's specified by the file name extension
200  p->Print(fEchoPrintTempFile.c_str());
201  }
202  // move temporary file to final file. This makes the creation of the
203  // newly printed file close to atomic
204  int result;
205  result=rename(fEchoPrintTempFile.c_str(),fEchoPrintFile.c_str());
206  if (result==0)
207  MF_LOG_DEBUG("EventDisplayBase") << fEchoPrintTempFile
208  << " tempfile successfully renamed to "
209  << fEchoPrintFile;
210  else
211  mf::LogWarning("EventDisplayBase") << "Error renaming file "
213  << " to " << fEchoPrintFile
214  << " " << strerror(errno) <<"\n";
215  }
216 
217  art::RootInput* rootInput = dynamic_cast<art::RootInput*>(fInputSource);
218 
219  if(!rootInput && NavState::Which() != kSEQUENTIAL_ONLY){
221  mf::LogWarning("EventDisplayBase")
222  << "Random access for the EventDisplay requires a RootInput source for proper operation.\n"
223  << "You do not have a RootInput source so only sequential access works.\n";
224  }
225 
226 
227  // Figure out where to go in the input stream from here
228  switch (NavState::Which()) {
229  case kSEQUENTIAL_ONLY: break;
230  case kNEXT_EVENT: {
231  // Contrary to appearances, this is *not* a NOP: it ensures run and
232  // subRun are (re-)read as necessary if we've been doing random
233  // access. Come the revolution ...
234  //
235  // 2011/04/10 CG.
236  if(rootInput) rootInput->seekToEvent(0);
237  break;
238  }
239  case kPREV_EVENT: {
240  if(rootInput) rootInput->seekToEvent(-2);
241  break;
242  }
243  case kRELOAD_EVENT: {
244  if(rootInput) rootInput->seekToEvent(evt.id());
245  break;
246  }
247  case kGOTO_EVENT: {
249  if(rootInput){
250  if (!rootInput->seekToEvent(id)) { // Couldn't find event
251  mf::LogWarning("EventDisplayBase") << "Unable to find "
252  << id
253  << " -- reloading current event.";
254  // Reload current event.
255  rootInput->seekToEvent(evt.id());
256  }
257  }// end if not a RootInput
258  break;
259  }
260  default: {
262  << "EvengtDisplay in unhandled state "
263  << NavState::Which()
264  << ".\n";
265  }
266  } // end switch statement
267 
268  }
269 
270 }//namespace
271 
272 
EventDisplay(fhicl::ParameterSet const &pset, art::ActivityRegistry &reg)
Definition: EventDisplay.cc:72
intermediate_table::iterator iterator
static void RemoveFromListOfPrintables(evdb::Printable *p)
Definition: Printable.cxx:47
testCanvas1(TGMainFrame *mf)
Definition: EventDisplay.cc:43
static void Set(int which)
Definition: NavState.cxx:24
static int TargetEvent()
Definition: NavState.cxx:51
GlobalSignal< detail::SignalResponseType::FIFO, void()> sPostBeginJob
int fAutoPrintMax
How many events to print (zero = disable printing).
Definition: EventDisplay.h:47
static ServiceTable & Instance()
const char * Description() const
Definition: EventDisplay.cc:49
Base class for printable objects.
Definition: Printable.h:15
std::string fEchoPrintFile
The file to dump that .gif to. Only one file, if you want a different file for each event...
Definition: EventDisplay.h:50
Interface to services and their configurations.
unsigned int fAutoAdvanceInterval
Wait time in milliseconds.
Definition: EventDisplay.h:45
bool fEchoPrint
Copy what you see in X to a .gif for each event.
Definition: EventDisplay.h:49
static void SetServicesAll()
void postBeginJobWorkers(art::InputSource *inputs, std::vector< art::Worker * > const &workers)
TCanvas * fCanvas
The ROOT drawing canvas.
Definition: Canvas.h:42
virtual const char * PrintTag() const =0
std::string fEchoPrintTempFile
a temporary file to enable atomic writes
Definition: EventDisplay.h:51
void preProcessEvent(art::Event const &, art::ScheduleContext)
void Draw(const char *)
Definition: EventDisplay.cc:51
Manage all things related to colors for the event display.
Configure the ROOT environment.
Definition: RootEnv.h:14
Singleton to hold the current art::Event for the event display.
static int TargetRun()
Definition: NavState.cxx:47
RunNumber_t run() const
Definition: EventID.h:98
GlobalSignal< detail::SignalResponseType::LIFO, void(InputSource *, std::vector< Worker * > const &)> sPostBeginJobWorkers
The interactive event display.
Base class for define a detector display.
Setup the root environment.
static std::map< std::string, evdb::Printable * > & GetPrintables()
Definition: Printable.cxx:61
static void SetRunEventAll(int run, int event)
void postProcessEvent(art::Event const &, art::ScheduleContext)
static EventHolder * Instance()
Definition: EventHolder.cxx:15
T get(std::string const &key) const
Definition: ParameterSet.h:314
EventNumber_t event() const
Definition: Event.cc:41
const char * PrintTag() const
Definition: EventDisplay.cc:50
static evdb::RootEnv gsRootEnv(0, 0)
GlobalSignal< detail::SignalResponseType::FIFO, void(Event const &, ScheduleContext)> sPreProcessEvent
GlobalSignal< detail::SignalResponseType::LIFO, void(Event const &, ScheduleContext)> sPostProcessEvent
static void DrawAll(const char *opt=0)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
static int Which()
Definition: NavState.cxx:20
#define MF_LOG_DEBUG(id)
static SubRunID invalidSubRun(RunID const &rID)
Definition: SubRunID.h:165
EventNumber_t event() const
Definition: EventID.h:116
A window containing a display of the detector or one of its components.
TCEvent evt
Definition: DataStructs.cxx:8
void reconfigure(fhicl::ParameterSet const &pset)
Definition: EventDisplay.cc:89
static void AddToListOfPrintables(const char *name, evdb::Printable *p)
Definition: Printable.cxx:29
int fAutoPrintCount
Number of events printed so far.
Definition: EventDisplay.h:46
std::string fAutoPrintPattern
Pattern for printing output filenames. Must contain "%s" and "%d", in that order. ...
Definition: EventDisplay.h:48
void SetEvent(art::Event const *evt)
Definition: EventHolder.cxx:32
Float_t w
Definition: plot.C:20
EventID id() const
Definition: Event.cc:23
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
art::InputSource * fInputSource
Input source of events.
Definition: EventDisplay.h:42
virtual void Print(const char *filename)=0