Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DDIRCPmtHit_factory.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DDIRCPmtHit_factory.cc
4 //
5 
6 #include <iostream>
7 #include <iomanip>
8 using namespace std;
9 
10 #include "DIRC/DDIRCGeometry.h"
12 #include "TTAB/DTTabUtilities.h"
13 #include "DAQ/DDIRCTriggerTime.h"
14 using namespace jana;
15 
16 //------------------
17 // init
18 //------------------
20 {
21  // initialize calibration tables
22  vector<double> new_t0s(DIRC_MAX_CHANNELS);
23  vector<int> new_status(DIRC_MAX_CHANNELS);
24 
25  time_offsets.push_back(new_t0s); time_offsets.push_back(new_t0s);
26  channel_status.push_back(new_status); channel_status.push_back(new_status);
27 
28  return NOERROR;
29 }
30 
31 //------------------
32 // brun
33 //------------------
34 jerror_t DDIRCPmtHit_factory::brun(jana::JEventLoop *eventLoop, int32_t runnumber)
35 {
36  // Only print messages for one thread whenever run number change
37  static pthread_mutex_t print_mutex = PTHREAD_MUTEX_INITIALIZER;
38  static set<int> runs_announced;
39  pthread_mutex_lock(&print_mutex);
40  bool print_messages = false;
41  if(runs_announced.find(runnumber) == runs_announced.end()){
42  print_messages = true;
43  runs_announced.insert(runnumber);
44  }
45  pthread_mutex_unlock(&print_mutex);
46 
47  if(print_messages) jout << "In DDIRCPmtHit_factory, loading constants..." << endl;
48 
49  // load base time offset
50  map<string,double> base_time_offset;
51  if (eventLoop->GetCalib("/DIRC/base_time_offset",base_time_offset))
52  jout << "Error loading /DIRC/base_time_offset !" << endl;
53  else if (base_time_offset.find("t0_North") != base_time_offset.end() && base_time_offset.find("t0_South") != base_time_offset.end()) {
54  t_base[0] = base_time_offset["t0_North"];
55  t_base[1] = base_time_offset["t0_South"];
56  }
57  else
58  jerr << "Unable to get t0s from /DIRC/base_time_offset !" << endl;
59 
60  // load constant tables
61  if (eventLoop->GetCalib("/DIRC/North/timing_offsets", time_offsets[0]))
62  jout << "Error loading /DIRC/North/timing_offsets !" << endl;
63  if (eventLoop->GetCalib("/DIRC/North/channel_status", channel_status[0]))
64  jout << "Error loading /DIRC/North/channel_status !" << endl;
65  if (eventLoop->GetCalib("/DIRC/South/timing_offsets", time_offsets[1]))
66  jout << "Error loading /DIRC/South/timing_offsets !" << endl;
67  if (eventLoop->GetCalib("/DIRC/South/channel_status", channel_status[1]))
68  jout << "Error loading /DIRC/South/channel_status !" << endl;
69 
70  return NOERROR;
71 }
72 
73 //------------------
74 // evnt
75 //------------------
76 jerror_t DDIRCPmtHit_factory::evnt(JEventLoop *loop, uint64_t eventnumber)
77 {
78  /// Generate DDIRCPmtHit object for each DDIRCDigiHit object.
79  /// This is where the first set of calibration constants
80  /// is applied to convert from digitzed units into natural
81  /// units.
82  ///
83  /// Note that this code does NOT get called for simulated
84  /// data in HDDM format. The HDDM event source will copy
85  /// the precalibrated values directly into the _data vector.
86 
87  // check that SSP board timestamps match for all modules
88  vector<const DDIRCTriggerTime*> timestamps;
89  loop->Get(timestamps);
90  if(timestamps.size() > 0) {
91  for (unsigned int i=0; i < timestamps.size()-1; i++) {
92  if(timestamps[i]->time != timestamps[i+1]->time)
93  return NOERROR;
94  }
95  }
96 
97  vector<const DCODAROCInfo*> locCODAROCInfos;
98  eventLoop->Get(locCODAROCInfos);
99  uint64_t locReferenceClockTime = 0;
100  for (const auto& locCODAROCInfo : locCODAROCInfos) {
101  if(locCODAROCInfo->rocid == 92) {
102  locReferenceClockTime = locCODAROCInfo->timestamp;
103  }
104  }
105 
106  vector<const DDIRCTDCDigiHit*> digihits;
107  loop->Get(digihits);
108 
109  // loop over leading edges
110  for (unsigned int i=0; i < digihits.size(); i++) {
111  const DDIRCTDCDigiHit *digihit_lead = digihits[i];
112  if(digihit_lead->edge == 0) continue; // remove trailing edges
113  // Note this doesn't match SSP data format document, but appears correct for data...
114 
115  double timeOverThreshold = 0.;
116 
117  // loop over trailing edges
118  const DDIRCTDCDigiHit *digihit_trail = NULL;
119  for (unsigned int j=0; j < digihits.size(); j++) {
120  digihit_trail = digihits[j];
121  if(i==j || digihit_trail->edge == 1) continue; // remove leading edges
122  // Note this doesn't match SSP data format document, but appears correct for data...
123 
124  // discard hits from different channels
125  if(digihit_lead->channel != digihit_trail->channel) continue;
126  int channel = digihit_lead->channel;
127  int box = (channel < DIRC_MAX_CHANNELS) ? 1 : 0; // North=0 and South=1
128 
129  // get time-over-threshold
130  timeOverThreshold = (double)digihit_trail->time - (double)digihit_lead->time;
131 
132  // discard bad time-over-threshold (negative or too long > 100 ns)
133  if(timeOverThreshold < 0 || timeOverThreshold > 100) continue;
134 
135  // throw away hits from bad or noisy channels
136  dirc_status_state status = static_cast<dirc_status_state>(channel_status[box][channel]);
137  if ( (status==BAD) || (status==NOISY) ) continue;
138 
139  // Build hit object
140  DDIRCPmtHit *hit = new DDIRCPmtHit;
141  hit->ch = digihit_lead->channel;
142  hit->tot = timeOverThreshold;
143 
144  // Apply calibration constants
145  double T = (double)digihit_lead->time;
146  hit->t = T;
147  if(locReferenceClockTime%2 == 0)
148  hit->t += 4;
149 
150  applyTimeOffset = true;
151  applyTimewalk = true;
152  double slope = 0.3;
153  double timeOverThresholdPeak = 50;
154  if(applyTimeOffset) {
155  hit->t = hit->t - time_offsets[box][channel] + t_base[box];
156  }
157  if(applyTimewalk) {
158  hit->t += slope*(timeOverThreshold - timeOverThresholdPeak);
159  }
160 
161  hit->AddAssociatedObject(digihit_lead);
162  hit->AddAssociatedObject(digihit_trail);
163  _data.push_back(hit);
164  }
165  }
166 
167  return NOERROR;
168 }
169 
170 //------------------
171 // erun
172 //------------------
174 {
175  return NOERROR;
176 }
177 
178 //------------------
179 // fini
180 //------------------
182 {
183  return NOERROR;
184 }
uint32_t edge
0=leading edge 1=trailing edge
uint32_t time
16 bit relative to beginning of defined readout window
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.
jerror_t fini(void)
Called after last event of last event source has been processed.
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
jerror_t init(void)
Called once at program start.2.
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.