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