Jpp  15.0.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Functions
JTriggerEfficiency.cc File Reference

Auxiliary program to trigger Monte Carlo events. More...

#include <string>
#include <iostream>
#include <iomanip>
#include <vector>
#include <set>
#include "TH1D.h"
#include "TRandom3.h"
#include "km3net-dataformat/offline/Head.hh"
#include "km3net-dataformat/offline/Evt.hh"
#include "km3net-dataformat/offline/Hit.hh"
#include "JDAQ/JDAQTimesliceIO.hh"
#include "JDAQ/JDAQEventIO.hh"
#include "JDAQ/JDAQSummarysliceIO.hh"
#include "JDAQ/JDAQToolkit.hh"
#include "JTimeslice/JEventTimeslice.hh"
#include "JSummaryslice/JSummaryslice.hh"
#include "JAAnet/JHead.hh"
#include "JAAnet/JHeadToolkit.hh"
#include "JAAnet/JAAnetToolkit.hh"
#include "JPhysics/JK40Rates.hh"
#include "JDetector/JDetector.hh"
#include "JDetector/JDetectorToolkit.hh"
#include "JDetector/JDetectorSimulator.hh"
#include "JDetector/JModuleMapper.hh"
#include "JDetector/JPMTRouter.hh"
#include "JDetector/JTimeRange.hh"
#include "JDetector/JPMTParametersMap.hh"
#include "JDetector/JK40DefaultSimulator.hh"
#include "JDetector/JPMTDefaultSimulator.hh"
#include "JDetector/JCLBDefaultSimulator.hh"
#include "JTrigger/JHit.hh"
#include "JTrigger/JHitToolkit.hh"
#include "JTrigger/JTimeslice.hh"
#include "JTrigger/JSuperFrame1D.hh"
#include "JTrigger/JSuperFrame2D.hh"
#include "JTrigger/JHitL0.hh"
#include "JTrigger/JHitL1.hh"
#include "JTrigger/JBuildL1.hh"
#include "JTrigger/JBuildL2.hh"
#include "JTrigger/JTrigger3DShower.hh"
#include "JTrigger/JTriggerMXShower.hh"
#include "JTrigger/JTrigger3DMuon.hh"
#include "JTrigger/JTriggerBits.hh"
#include "JTrigger/JEventOverlap.hh"
#include "JTrigger/JTimesliceRouter.hh"
#include "JTrigger/JTriggeredEvent.hh"
#include "JTrigger/JTimesliceL1.hh"
#include "JTrigger/JTriggerParameters.hh"
#include "JTrigger/JEventToolkit.hh"
#include "JTrigger/JSummaryRouter.hh"
#include "JTrigger/JTriggerToolkit.hh"
#include "JTrigger/JK40RunByRunSimulator.hh"
#include "JTrigger/JPMTRunByRunSimulator.hh"
#include "JTrigger/JCLBRunByRunSimulator.hh"
#include "JSupport/JMultipleFileScanner.hh"
#include "JSupport/JFileRecorder.hh"
#include "JSupport/JMonteCarloFileSupportkit.hh"
#include "JSupport/JTriggerParametersSupportkit.hh"
#include "JSupport/JSupport.hh"
#include "JSupport/JRunByRun.hh"
#include "JSupport/JMeta.hh"
#include "Jeep/JPrint.hh"
#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Detailed Description

Auxiliary program to trigger Monte Carlo events.

The options

The event counter of the triggered events, as returned by KM3NETDAQ::JDAQEvent::getCounter(), is set to the corresponding index of the Monte Carlo event in the output.
This allows for correlating the DAQ event to the Monte Carlo event.
The time of the DAQ hits can be correlated to the time of the Monte Carlo hits using the frame index and the time of the Monte Carlo event (Evt::mc_t), respectively (see also time_converter).
The universal time of the DAQ event is set to the universal time of the Monte Carlo event with a correction for the time of the event (read hits) within the time slice.
In run-by-run mode, the trigger parameters as well as the singles rates and status of the PMTs are read from the given raw data file.
The two-fold (and higher) coincidence rates should still be provided on the command line.

Author
mdejong

Definition in file JTriggerEfficiency.cc.

Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 97 of file JTriggerEfficiency.cc.

98 {
99  using namespace std;
100  using namespace JPP;
101  using namespace KM3NETDAQ;
102 
104 
105  JMultipleFileScanner<> inputFile;
107  JLimit_t& numberOfEvents = inputFile.getLimit();
108  string detectorFileA;
109  string detectorFileB;
110  int run;
112  bool triggeredEventsOnly;
113  JPMTParametersMap pmtParameters;
114  JK40Rates rates_Hz;
115  JRunByRun runbyrun;
116  UInt_t seed;
117  int debug;
118 
119  try {
120 
121  JParser<> zap("Auxiliary program to trigger Monte Carlo events.");
122 
123  zap['f'] = make_field(inputFile, "input file (output of detector simulation)");
124  zap['o'] = make_field(outputFile, "output file") = "trigger_efficieny.root";
125  zap['n'] = make_field(numberOfEvents) = JLimit::max();
126  zap['a'] = make_field(detectorFileA, "detector used for conversion from Monte Carlo truth to raw data.");
127  zap['b'] = make_field(detectorFileB, "detector used for conversion of raw data to calibrated data.") = "";
128  zap['R'] = make_field(run, "run number") = -1;
129  zap['r'] = make_field(runbyrun, "option for run-by-run mode") = JPARSER::initialised();
130  zap['@'] = make_field(parameters, "Trigger parameters (or corresponding file name)") = JPARSER::initialised();
131  zap['O'] = make_field(triggeredEventsOnly, "optionally write only triggered events.");
132  zap['P'] = make_field(pmtParameters, "PMT simulation data (or corresponding file name)") = JPARSER::initialised();
133  zap['B'] = make_field(rates_Hz, "background rates [Hz]") = JPARSER::initialised();
134  zap['S'] = make_field(seed, "seed") = 0;
135  zap['d'] = make_field(debug, "debug") = 0;
136 
137  zap(argc, argv);
138  }
139  catch(const exception &error) {
140  FATAL(error.what() << endl);
141  }
142 
143  gRandom->SetSeed(seed);
144 
145  cout.tie(&cerr);
146 
148 
149  if (detectorFileB == "") {
150  detectorFileB = detectorFileA;
151  }
152 
153 
154  JDetector detectorA;
155  JDetector detectorB;
156 
157  try {
158  load(detectorFileA, detectorA);
159  load(detectorFileB, detectorB);
160  }
161  catch(const JException& error) {
162  FATAL(error);
163  }
164 
165  JPMTParametersMap::Throw(true);
166 
167  if (!pmtParameters.is_valid()) {
168  FATAL("Invalid PMT parameters " << pmtParameters << endl);
169  }
170 
171  if (pmtParameters.getQE() != 1.0) {
172 
173  WARNING("Correct background rates with global efficiency " << pmtParameters.getQE() << endl);
174 
175  rates_Hz.correct(pmtParameters.getQE());
176  }
177 
178  const JModuleRouter moduleRouter(detectorB);
179  JDetectorSimulator simbad (detectorA);
180  JSummaryRouter summaryRouter;
181 
182  if (runbyrun.is_valid()) {
183 
184  NOTICE("Using run-by-run:" << endl << runbyrun << endl);
185 
186  if (!runbyrun.hasNext()) {
187  FATAL("Run-by-run simulation yields no input." << endl);
188  }
189 
190  if (rates_Hz.getSinglesRate() != 0.0) {
191  WARNING("Run-by-run simulation discards singles rate [Hz] " << rates_Hz.getSinglesRate() << endl);
192  }
193 
194  try {
195  simbad.reset(new JK40RunByRunSimulator(summaryRouter, rates_Hz));
196  simbad.reset(new JPMTRunByRunSimulator(summaryRouter, pmtParameters, detectorA));
197  simbad.reset(new JCLBRunByRunSimulator(summaryRouter));
198  }
199  catch(const JException& error) {
200  FATAL(error.what() << endl);
201  }
202 
203  try {
204 
206 
207  NOTICE("Set trigger parameters from run-by-run input." << endl);
208  }
209  catch(const JException& error) {
210  WARNING("No trigger parameters from run-by-run input;\nrun with default/user input." << endl);
211  }
212 
213  } else {
214 
215  NOTICE("Using fixed rates [Hz]: " << rates_Hz << endl);
216 
217  try {
218  simbad.reset(new JK40DefaultSimulator(rates_Hz));
219  simbad.reset(new JPMTDefaultSimulator(pmtParameters, detectorA));
220  simbad.reset(new JCLBDefaultSimulator());
221  }
222  catch(const JException& error) {
223  FATAL(error.what() << endl);
224  }
225  }
226 
227  parameters.set(getMaximalDistance(detectorB));
228 
229  DEBUG("Trigger:" << endl << parameters << endl);
230  DEBUG("PMT parameters:" << endl << pmtParameters << endl);
231 
232  const double Tmax = max(getMaximalTime(detectorA),
233  getMaximalTime(detectorB));
234 
235  const JTimeRange period(-(Tmax + parameters.TMaxLocal_ns),
236  +(Tmax + parameters.TMaxLocal_ns));
237 
238  typedef double hit_type;
239 
240  typedef JSuperFrame1D<hit_type> JSuperFrame1D_t;
241  typedef JSuperFrame2D<hit_type> JSuperFrame2D_t;
242  typedef JTimeslice <hit_type> JTimeslice_t;
243  typedef JBuildL1 <hit_type> JBuildL1_t;
244  typedef JBuildL2 <hit_type> JBuildL2_t;
245 
246  const JBuildL1_t buildL1(parameters);
247  const JBuildL2_t buildL2(parameters.L2);
248  const JBuildL2_t buildSN(parameters.SN);
249 
250  JTimesliceRouter timesliceRouter(parameters.numberOfBins);
251 
252  const JTrigger3DMuon trigger3DMuon (parameters);
253  const JTrigger3DShower trigger3DShower(parameters);
254  const JTriggerMXShower triggerMXShower(parameters, detectorB);
255 
256 
257  Head header;
258 
259  try {
260  header = getHeader(inputFile);
261  }
262  catch(const JException& error) {
263  FATAL(error);
264  }
265 
266  const JPosition3D center = get<JPosition3D>(header);
267 
268  NOTICE("Apply detector offset from Monte Carlo run header (" << center << ")" << endl);
269 
270  detectorA -= center;
271  detectorB -= center;
272 
273  TH1D h1("Trigger bits", NULL, NUMBER_OF_TRIGGER_BITS, -0.5, NUMBER_OF_TRIGGER_BITS - 0.5);
274 
275 
276  outputFile.open();
277 
278  if (!outputFile.is_open()) {
279  FATAL("Error opening file " << outputFile << endl);
280  }
281 
282  outputFile.put(*gRandom);
283  outputFile.put(JMeta(argc, argv));
284  outputFile.put(header);
285  outputFile.put(parameters);
286 
287  JLimit_t limit = inputFile.getLimit();
288  counter_type number_of_events = 0;
289  int trigger_counter = 0;
290 
291  for (JMultipleFileScanner<>::const_iterator file = inputFile.begin(); file != inputFile.end(); ++file) {
292 
293  int mc_run_id = 0;
294 
295  try {
296 
297  const JHead head(getHeader(*file));
298 
299  mc_run_id = head.start_run.run_id;
300  }
301  catch(const JException& error) {
302  FATAL(error);
303  }
304 
306 
307  limit.setLowerLimit(limit.getLowerLimit() - in.skip(limit.getLowerLimit()));
308 
309  for ( ; in.hasNext() && number_of_events != limit; ++number_of_events) {
310 
311  STATUS("event: " << setw(10) << number_of_events << '\r'); DEBUG(endl);
312 
313  Evt* event = in.next();
314 
315  event->mc_run_id = mc_run_id;
316 
317  DEBUG(*event << endl);
318 
319  bool trigger = false;
320 
321  if (!event->mc_hits.empty()) {
322 
323  int frame_index = (int) in.getCounter() + 1; // 1 event / slice
324 
325  if (runbyrun.is_valid() && runbyrun.hasNext()) {
326 
327  summaryRouter.update(runbyrun.next());
328 
329  summaryRouter.correct(dynamic_cast<const JPMTDefaultSimulatorInterface&>(simbad.getPMTSimulator()));
330 
331  frame_index = summaryRouter.getFrameIndex();
332  run = summaryRouter.getRunNumber();
333  }
334 
335  // set the event time!
336 
337  JTimeRange timeRange = getTimeRange(*event, period);
338 
339  if (!timeRange.is_valid()) {
340  timeRange.setRange(0.0,0.0);
341  }
342 
343  const double t0 = 0.5 * (timeRange.getLowerLimit() + timeRange.getUpperLimit());
344  const double t1 = gRandom->Rndm() * getFrameTime();
345 
346  event->mc_t = getTimeOfFrame(frame_index) + t1 - t0; // time since start of data taking run
347 
348  timeRange.add(event->mc_t);
349  timeRange.add(period);
350 
351  JDAQUTCExtended utc(getTimeOfFrame(trigger_counter + 1)); // ensure incremental UTC times (e.g. for JDAQSplit.cc)
352 
353  if (event->mc_event_time != TTimeStamp(0)) {
354  utc = getDAQUTCExtended(event->mc_event_time, t1); // set UTC time according Monte Carlo event
355  }
356 
357  const JDAQChronometer chronometer(detectorB.getID(), (run != -1 ? run : mc_run_id), frame_index, utc);
358 
359  const JEventTimeslice timeslice(chronometer, simbad, *event, period);
360 
361  DEBUG(timeslice << endl);
362 
363 
364  timesliceRouter.configure(timeslice);
365 
366  JTimeslice_t timesliceL0(timeslice.getDAQChronometer());
367  JTimeslice_t timesliceL1(timeslice.getDAQChronometer());
368  JTimeslice_t timesliceL2(timeslice.getDAQChronometer());
369  JTimeslice_t timesliceSN(timeslice.getDAQChronometer());
370 
371  for (JDAQTimeslice::const_iterator super_frame = timeslice.begin(); super_frame != timeslice.end(); ++super_frame) {
372 
373  if (moduleRouter.hasModule(super_frame->getModuleID())) {
374 
375  // calibration
376 
377  const JModule& module = moduleRouter.getModule(super_frame->getModuleID());
378  const JSuperFrame2D_t& buffer = JSuperFrame2D_t::demultiplex(*super_frame, module);
379 
380  // L0
381 
382  timesliceL0.push_back(JSuperFrame1D_t(buffer));
383 
384  // L1
385 
386  timesliceL1.push_back(JSuperFrame1D_t(super_frame->getDAQChronometer(),
387  super_frame->getModuleIdentifier(),
388  module.getPosition()));
389 
390  buildL1(*timesliceL0.rbegin(), back_inserter(*timesliceL1.rbegin()));
391 
392  // L2
393 
394  timesliceL2.push_back(JSuperFrame1D_t(super_frame->getDAQChronometer(),
395  super_frame->getModuleIdentifier(),
396  module.getPosition()));
397 
398  buildL2(buffer, *timesliceL1.rbegin(), back_inserter(*timesliceL2.rbegin()));
399 
400  // SN
401 
402  timesliceSN.push_back(JSuperFrame1D_t(super_frame->getDAQChronometer(),
403  super_frame->getModuleIdentifier(),
404  module.getPosition()));
405 
406  buildSN(buffer, *timesliceL1.rbegin(), back_inserter(*timesliceSN.rbegin()));
407 
408  DEBUG("L0 " << setw(8) << timesliceL0.rbegin()->getModuleID() << ' ' << setw(8) << timesliceL0.rbegin()->size() << endl);
409  DEBUG("L1 " << setw(8) << timesliceL1.rbegin()->getModuleID() << ' ' << setw(8) << timesliceL1.rbegin()->size() << endl);
410  DEBUG("L2 " << setw(8) << timesliceL2.rbegin()->getModuleID() << ' ' << setw(8) << timesliceL2.rbegin()->size() << endl);
411  DEBUG("SN " << setw(8) << timesliceSN.rbegin()->getModuleID() << ' ' << setw(8) << timesliceSN.rbegin()->size() << endl);
412  }
413  }
414 
415 
416  // Trigger
417 
418  JTriggerInput trigger_input(timesliceL2);
419  JTriggerOutput trigger_output;
420 
421  trigger3DMuon (trigger_input, back_inserter(trigger_output));
422  trigger3DShower(trigger_input, back_inserter(trigger_output));
423  triggerMXShower(trigger_input, timesliceL0, back_inserter(trigger_output));
424 
425  trigger_output.merge(JEventOverlap(parameters.TMaxEvent_ns));
426 
427  for (JTriggerOutput::const_iterator to = trigger_output.begin(); to != trigger_output.end(); ++to) {
428 
429  for (int i = 0; i != h1.GetNbinsX(); ++i) {
430  if (to->hasTriggerBit(i)) {
431  h1.Fill((double) i);
432  }
433  }
434 
435  JTimeRange eventTime = getTimeRange(*to).add(getTimeOfRTS(*to));
436 
437  DEBUG("Event time: "
438  << to->getFrameIndex() << ' '
439  << eventTime << ' '
440  << timeRange << endl);
441 
442  if (timeRange.overlap(eventTime)) {
443 
444  JTriggeredEvent tev(*to,
445  timesliceRouter,
446  moduleRouter,
447  parameters.TMaxLocal_ns,
449 
450  // Set the event counter to the index of the Monte Carlo event in the output.
451 
452  tev.setCounter(trigger_counter);
453 
454  outputFile.put(tev);
455 
456  trigger = true;
457  }
458  }
459 
460 
461  if (!triggeredEventsOnly || trigger) {
462 
463  if (parameters.writeL0()) {
464  outputFile.put(timeslice);
465  }
466 
467  if (parameters.writeL1()) {
468  outputFile.put(JTimesliceL1<JDAQTimesliceL1>(timesliceL1, timesliceRouter, moduleRouter, parameters.TMaxLocal_ns));
469  }
470 
471  if (parameters.writeL2()) {
472  outputFile.put(JTimesliceL1<JDAQTimesliceL2>(timesliceL2, timesliceRouter, moduleRouter, parameters.L2.TMaxLocal_ns));
473  }
474 
475  if (parameters.writeSN()) {
476  outputFile.put(JTimesliceL1<JDAQTimesliceSN>(timesliceSN, timesliceRouter, moduleRouter, parameters.SN.TMaxLocal_ns));
477  }
478 
479  if (parameters.writeSummary()) {
480  outputFile.put(JSummaryslice(chronometer,simbad));
481  }
482  }
483  }
484 
485  if (!triggeredEventsOnly || trigger) {
486 
487  outputFile.put(*event);
488 
489  ++trigger_counter;
490  }
491  }
492  }
493  STATUS(endl);
494 
495 
497 
498  io >> outputFile;
499 
500  outputFile.put(h1);
501  outputFile.put(*gRandom);
502  outputFile.close();
503 }
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:70
Auxiliary class to select summary data (KM3NETDAQ::JDAQSummaryslice) from the specified raw data file...
Definition: JRunByRun.hh:32
Object writing to file.
Utility class to parse command line options.
Definition: JParser.hh:1500
General exception.
Definition: JException.hh:23
#define WARNING(A)
Definition: JMessage.hh:65
debug
Definition: JMessage.hh:29
T getLowerLimit() const
Get lower limit.
Definition: JRange.hh:202
static const unsigned int NUMBER_OF_TRIGGER_BITS
Number of trigger bits.
Default implementation of the simulation of K40 background.
Data structure for a composite optical module.
Definition: JModule.hh:68
Router for fast addressing of hits in KM3NETDAQ::JDAQTimeslice data structure as a function of the op...
#define STATUS(A)
Definition: JMessage.hh:63
Detector data structure.
Definition: JDetector.hh:89
Router for direct addressing of module data in detector data structure.
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
Definition: diff-Tuna.sh:38
then for HISTOGRAM in h0 h1
Definition: JMatrixNZ.sh:71
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:66
Long64_t counter_type
Type definition for counter.
double getTimeOfRTS(const JDAQChronometer &chronometer)
Get time of last RTS in ns since start of run for a given chronometer.
string outputFile
Data structure for UTC time.
double getTimeOfFrame(const int frame_index)
Get start time of frame in ns since start of run for a given frame index.
Definition: JDAQClock.hh:185
1-dimensional frame with time calibrated data from one optical module.
JTimeRange getTimeRange(const Evt &event)
Get time range (i.e. time between earliest and latest hit) of Monte Carlo event.
K40 simulation based on run-by-run information.
Head getHeader(const JMultipleFileScanner_t &file_list)
Get Monte Carlo header.
Type list.
Definition: JTypeList.hh:22
void setDAQLongprint(const bool option)
Set DAQ print option.
Definition: JDAQPrint.hh:28
Auxiliary class for defining the range of iterations of objects.
Definition: JLimit.hh:41
Template L2 builder.
Definition: JBuildL2.hh:45
double getMaximalDistance(const JDetector &detector)
Get maximal distance between modules in detector.
void merge(const JMatch_t &match)
Merge events.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1961
CLB simulation based on run-by-run information.
range_type & add(argument_type x)
Add offset.
Definition: JRange.hh:447
double getFrameTime()
Get frame time duration.
Definition: JDAQClock.hh:162
void setRange(const range_type &range)
Set range.
Definition: JRange.hh:146
T getUpperLimit() const
Get upper limit.
Definition: JRange.hh:213
#define NOTICE(A)
Definition: JMessage.hh:64
Auxiliary class to create summary data.
Auxiliary class to build JDAQEvent for a triggered event.
Auxiliary class for map of PMT parameters.
int debug
debug level
Definition: JSirene.cc:63
const JPosition3D & getPosition() const
Get position.
Definition: JPosition3D.hh:130
double getMaximalTime(const double R_Hz)
Get maximal time for given rate.
Router for fast addressing of summary data in JDAQSummaryslice data structure as a function of the op...
Monte Carlo run header.
Definition: JHead.hh:1113
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
Definition: Head.hh:67
Template L1 hit builder.
Definition: JBuildL1.hh:85
#define FATAL(A)
Definition: JMessage.hh:67
PMT simulation based on run-by-run information.
bool is_valid() const
Check validity of range.
Definition: JRange.hh:311
virtual const char * what() const override
Get error message.
Definition: JException.hh:48
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
Auxiliary class to build JDAQTimeslice for L1 timeslice.
Definition: JTimesliceL1.hh:36
then usage $script< input_file >< detector_file > fi set_variable OUTPUT_DIR set_variable SELECTOR JDAQTimesliceL1 set_variable DEBUG case set_variable DEBUG
2-dimensional frame with time calibrated data from one optical module.
Data structure for input to trigger algorithm.
Data structure for position in three dimensions.
Definition: JPosition3D.hh:36
const JLimit & getLimit() const
Get limit.
Definition: JLimit.hh:73
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY source JAcoustics sh $DETECTOR_ID CHECK_EXIT_CODE typeset A TRIPODS get_tripods $WORKDIR tripod txt TRIPODS for EMITTER in
Definition: JCanberra.sh:41
JDAQUTCExtended getDAQUTCExtended(const TTimeStamp &t0, const double t1=0.0)
Get DAQ UTC time.
Definition: JDAQToolkit.hh:26
Match of two events considering overlap in time.
bool overlap(const range_type &range) const
Test overlap with given range.
Definition: JRange.hh:383
Timeslice with Monte Carlo event.
JTriggerParameters getTriggerParameters(const JMultipleFileScanner_t &file_list)
Get trigger parameters.
Auxiliary class for K40 rates.
Definition: JK40Rates.hh:41
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Definition: Evt.hh:19
Time slice with calibrated data.
Definition: JTimeslice.hh:26
then usage $script< string identifier >< detectorfile > event file(toashort file)+" "\nNote that the event files and toashort files should be one-to-one related." fi if (( $