CMS 3D CMS Logo

HcalTBTDCUnpacker.cc
Go to the documentation of this file.
3 #include <cmath>
4 
5 // Timing channels
6 static const int lcTriggerTime = 1;
7 static const int lcTTCL1ATime = 2;
8 static const int lcBeamCoincidence = 3;
9 static const int lcLaserFlash = 4;
10 static const int lcQIEPhase = 5;
11 
12 static const int lcMuon1 = 90;
13 static const int lcMuon2 = 91;
14 static const int lcMuon3 = 92;
15 static const int lcScint1 = 93;
16 static const int lcScint2 = 94;
17 static const int lcScint3 = 95;
18 static const int lcScint4 = 96;
19 static const int lcBeamHalo1 = 50;
20 static const int lcBeamHalo2 = 51;
21 static const int lcBeamHalo3 = 55;
22 static const int lcBeamHalo4 = 63;
23 static const int lcTOF1S = 129;
24 static const int lcTOF1J = 130;
25 static const int lcTOF2S = 131;
26 static const int lcTOF2J = 132;
27 
28 namespace hcaltb {
29 
30  HcalTBTDCUnpacker::HcalTBTDCUnpacker(bool include_unmatched_hits)
31  : includeUnmatchedHits_(include_unmatched_hits), dumpObs_(nullptr) {
32  // setupWC(); reads it from configuration file
33  // dumpObs_=fopen("dump_obs.csv","w");
34  }
35  void HcalTBTDCUnpacker::setCalib(const std::vector<std::vector<std::string> >& calibLines_) {
36  for (int i = 0; i < 161; i++) {
37  tdc_ped[i] = 0.;
38  tdc_convers[i] = 1.;
39  }
40  for (unsigned int ii = 0; ii < calibLines_.size(); ii++) {
41  // TDC configuration
42  if (calibLines_[ii][0] == "TDC") {
43  if (calibLines_[ii].size() == 4) {
44  int channel = atoi(calibLines_[ii][1].c_str());
45  tdc_ped[channel] = atof(calibLines_[ii][2].c_str());
46  tdc_convers[channel] = atof(calibLines_[ii][3].c_str());
47  // printf("Got TDC %i ped %f , conversion %f\n",channel, tdc_ped[channel],tdc_convers[channel]);
48  } else {
49  throw cms::Exception("Incomplete configuration")
50  << "Wrong TDC configuration format : expected 3 parameters, got " << calibLines_[ii].size() - 1;
51  }
52  } // End of the TDCs
53 
54  // Wire chambers calibration
55  if (calibLines_[ii][0] == "WC") {
56  if (calibLines_[ii].size() == 6) {
57  int plane = atoi(calibLines_[ii][1].c_str());
58  wc_[plane].b0 = atof(calibLines_[ii][2].c_str());
59  wc_[plane].b1 = atof(calibLines_[ii][3].c_str());
60  wc_[plane].mean = atof(calibLines_[ii][4].c_str());
61  wc_[plane].sigma = atof(calibLines_[ii][5].c_str());
62  // printf("Got WC plane %i b0 %f, b1 %f, mean %f, sigma %f\n",plane,
63  // wc_[plane].b0,wc_[plane].b1,wc_[plane].mean,wc_[plane].sigma);
64  } else {
65  throw cms::Exception("Incomplete configuration")
66  << "Wrong Wire Chamber configuration format : expected 5 parameters, got " << calibLines_[ii].size() - 1;
67  }
68  } // End of the Wire Chambers
69 
70  } // End of the CalibLines
71  }
72 
74  std::vector<Hit> hits;
75 
76  unpackHits(raw, hits, timing);
77 
80  }
81 
84  unsigned int n_max_hits; // maximum number of hits possible in the block
85  unsigned int n_hits;
86  unsigned int hits[2];
87  };
88 
91  unsigned int n_qdc_hits; // Count of QDC channels
92  unsigned int n_tdc_hits; // upper/lower TDC counts
93  unsigned short qdc_values[4];
94  };
95 
96  //static const double CONVERSION_FACTOR=25.0/32.0;
97 
98  void HcalTBTDCUnpacker::unpackHits(const FEDRawData& raw, std::vector<Hit>& hits, HcalTBTiming& timing) const {
99  const ClassicTDCDataFormat* tdc = (const ClassicTDCDataFormat*)raw.data();
100 
101  if (raw.size() < 3 * 8) {
102  throw cms::Exception("Missing Data") << "No data in the TDC block";
103  }
104 
105  const unsigned int* hitbase = nullptr;
106  unsigned int totalhits = 0;
107 
108  // old TDC (767)
109  if (tdc->n_max_hits != 192) {
110  const CombinedTDCQDCDataFormat* qdctdc = (const CombinedTDCQDCDataFormat*)raw.data();
111  hitbase = (const unsigned int*)(qdctdc);
112  hitbase += 6; // header
113  hitbase += qdctdc->n_qdc_hits / 2; // two unsigned short per unsigned long
114  totalhits = qdctdc->n_tdc_hits & 0xFFFF; // mask off high bits
115 
116  // for (unsigned int i=0; i<qdctdc->n_qdc_hits; i++)
117  // printf("QADC: %02d %d\n",i,qdctdc->qdc_values[i]&0xFFF);
118 
119  } else {
120  hitbase = &(tdc->hits[0]);
121  totalhits = tdc->n_hits;
122  }
123 
124  for (unsigned int i = 0; i < totalhits; i++) {
125  Hit h;
126  h.channel = (hitbase[i] & 0x7FC00000) >> 22; // hardcode channel assignment
127  h.time = (hitbase[i] & 0xFFFFF) * tdc_convers[h.channel];
128  hits.push_back(h);
129  // printf("V767: %d %f\n",h.channel,h.time);
130  }
131 
132  // new TDC (V775)
133  int v775[32];
134  for (int i = 0; i < 32; i++)
135  v775[i] = -1;
136  if (tdc->n_max_hits != 192) {
137  const CombinedTDCQDCDataFormat* qdctdc = (const CombinedTDCQDCDataFormat*)raw.data();
138  hitbase = (const unsigned int*)(qdctdc);
139  hitbase += 6; // header
140  hitbase += qdctdc->n_qdc_hits / 2; // two unsigned short per unsigned long
141  hitbase += (qdctdc->n_tdc_hits & 0xFFFF); // same length
142  totalhits = (qdctdc->n_tdc_hits & 0xFFFF0000) >> 16; // mask off high bits
143  for (unsigned int i = 0; i < totalhits; i++) {
144  Hit h;
145  // h.channel=129+i;
146  h.channel = 129 + ((hitbase[i] & 0x3F0000) >> 16);
147  h.time = (hitbase[i] & 0xFFF) * tdc_convers[h.channel];
148  hits.push_back(h);
149  if ((h.channel - 129) < 32)
150  v775[(h.channel - 129)] = (hitbase[i] & 0xFFF);
151  // printf("V775: %d %f\n",h.channel,h.time);
152  }
153  }
154  timing.setV775(v775);
155  }
156 
157  void HcalTBTDCUnpacker::reconstructTiming(const std::vector<Hit>& hits, HcalTBTiming& timing) const {
158  std::vector<Hit>::const_iterator j;
159  double trigger_time = 0;
160  double ttc_l1a_time = 0;
161  double laser_flash = 0;
162  double qie_phase = 0;
163  double TOF1S_time = 0;
164  double TOF1J_time = 0;
165  double TOF2S_time = 0;
166  double TOF2J_time = 0;
167 
168  std::vector<double> m1hits, m2hits, m3hits, s1hits, s2hits, s3hits, s4hits, bh1hits, bh2hits, bh3hits, bh4hits,
169  beam_coinc;
170 
171  for (j = hits.begin(); j != hits.end(); j++) {
172  switch (j->channel) {
173  case lcTriggerTime:
174  trigger_time = j->time - tdc_ped[lcTriggerTime];
175  break;
176  case lcTTCL1ATime:
177  ttc_l1a_time = j->time - tdc_ped[lcTTCL1ATime];
178  break;
179  case lcBeamCoincidence:
180  beam_coinc.push_back(j->time - tdc_ped[lcBeamCoincidence]);
181  break;
182  case lcLaserFlash:
183  laser_flash = j->time - tdc_ped[lcLaserFlash];
184  break;
185  case lcQIEPhase:
186  qie_phase = j->time - tdc_ped[lcQIEPhase];
187  break;
188  case lcMuon1:
189  m1hits.push_back(j->time - tdc_ped[lcMuon1]);
190  break;
191  case lcMuon2:
192  m2hits.push_back(j->time - tdc_ped[lcMuon2]);
193  break;
194  case lcMuon3:
195  m3hits.push_back(j->time - tdc_ped[lcMuon3]);
196  break;
197  case lcScint1:
198  s1hits.push_back(j->time - tdc_ped[lcScint1]);
199  break;
200  case lcScint2:
201  s2hits.push_back(j->time - tdc_ped[lcScint2]);
202  break;
203  case lcScint3:
204  s3hits.push_back(j->time - tdc_ped[lcScint3]);
205  break;
206  case lcScint4:
207  s4hits.push_back(j->time - tdc_ped[lcScint4]);
208  break;
209  case lcTOF1S:
210  TOF1S_time = j->time - tdc_ped[lcTOF1S];
211  break;
212  case lcTOF1J:
213  TOF1J_time = j->time - tdc_ped[lcTOF1J];
214  break;
215  case lcTOF2S:
216  TOF2S_time = j->time - tdc_ped[lcTOF2S];
217  break;
218  case lcTOF2J:
219  TOF2J_time = j->time - tdc_ped[lcTOF2J];
220  break;
221  case lcBeamHalo1:
222  bh1hits.push_back(j->time - tdc_ped[lcBeamHalo1]);
223  break;
224  case lcBeamHalo2:
225  bh2hits.push_back(j->time - tdc_ped[lcBeamHalo2]);
226  break;
227  case lcBeamHalo3:
228  bh3hits.push_back(j->time - tdc_ped[lcBeamHalo3]);
229  break;
230  case lcBeamHalo4:
231  bh4hits.push_back(j->time - tdc_ped[lcBeamHalo4]);
232  break;
233  default:
234  break;
235  }
236  }
237 
238  timing.setTimes(trigger_time, ttc_l1a_time, laser_flash, qie_phase, TOF1S_time, TOF1J_time, TOF2S_time, TOF2J_time);
239  timing.setHits(
240  m1hits, m2hits, m3hits, s1hits, s2hits, s3hits, s4hits, bh1hits, bh2hits, bh3hits, bh4hits, beam_coinc);
241  }
242 
243  const int HcalTBTDCUnpacker::WC_CHANNELIDS[PLANECOUNT * 3] = {
244  12, 13, 14, // WCA LR plane
245  10, 11, 14, // WCA UD plane
246  22, 23, 24, // WCB LR plane
247  20, 21, 24, // WCB UD plane
248  32, 33, 34, // WCC LR plane
249  30, 31, 34, // WCC UD plane
250  101, 102, 104, // WCD LR plane
251  107, 108, 110, // WCD UD plane
252  113, 114, 116, // WCE LR plane
253  97, 98, 99, // WCE UD plane
254  42, 43, -1, // WCF LR plane (was WC1)
255  44, 60, -1, // WCF UD plane (was WC1)
256  40, 41, -1, // WCG LR plane (was WC2)
257  45, 61, -1, // WCG UD plane (was WC2)
258  52, 53, -1, // WCH LR plane (was WC3)
259  54, 62, -1 // WCH UD plane (was WC3)
260  };
261 
262  static const double TDC_OFFSET_CONSTANT = 12000;
263  static const double N_SIGMA = 2.5;
264 
265  /* Obsolated - reads it from the configuration file
266 void HcalTBTDCUnpacker::setupWC() {
267 
268  wc_[0].b0 = -0.0870056; wc_[0].b1 = -0.193263; // WCA planes
269  wc_[1].b0 = -0.0288171; wc_[1].b1 = -0.191231;
270 
271  wc_[2].b0 = -0.2214840; wc_[2].b1 = -0.191683; // WCB planes
272  wc_[3].b0 = -1.0847300; wc_[3].b1 = -0.187691;
273 
274  wc_[4].b0 = -0.1981440; wc_[4].b1 = -0.192760; // WCC planes
275  wc_[5].b0 = 0.4230690; wc_[5].b1 = -0.192278;
276 
277  wc_[6].b0 = -0.6039130; wc_[6].b1 = -0.185674; // WCD planes
278  wc_[7].b0 = -0.4366590; wc_[7].b1 = -0.184992;
279 
280  wc_[8].b0 = 1.7016400; wc_[8].b1 = -0.185575; // WCE planes
281  wc_[9].b0 = -0.2324480; wc_[9].b1 = -0.185367;
282 
283  wc_[0].mean=225.2; wc_[0].sigma=5.704;
284  wc_[1].mean=223.5; wc_[1].sigma=5.862;
285  wc_[2].mean=227.2; wc_[2].sigma=5.070;
286  wc_[3].mean=235.7; wc_[3].sigma=6.090;
287  wc_[4].mean=243.3; wc_[4].sigma=7.804;
288  wc_[5].mean=230.3; wc_[5].sigma=28.91;
289 
290  wc_[6].mean=225.0; wc_[6].sigma=6.000;
291  wc_[7].mean=225.0; wc_[7].sigma=6.000;
292  wc_[8].mean=225.0; wc_[8].sigma=6.000;
293  wc_[9].mean=225.0; wc_[9].sigma=6.000;
294 }
295 */
296 
297  void HcalTBTDCUnpacker::reconstructWC(const std::vector<Hit>& hits, HcalTBEventPosition& ep) const {
298  // process all planes, looping over all hits...
299  const int MAX_HITS = 100;
300  float hits1[MAX_HITS], hits2[MAX_HITS], hitsA[MAX_HITS];
301  int n1, n2, nA, chan1, chan2, chanA;
302 
303  std::vector<double> x;
304 
305  for (int plane = 0; plane < PLANECOUNT; plane++) {
306  n1 = 0;
307  n2 = 0;
308  nA = 0;
309 
310  std::vector<double> plane_hits;
311  double hit_time;
312  hits1[0] = -1000;
313  hits2[0] = -1000;
314  hitsA[0] = -1000;
315  hitsA[1] = -1000;
316 
317  chan1 = WC_CHANNELIDS[plane * 3];
318  chan2 = WC_CHANNELIDS[plane * 3 + 1];
319  chanA = WC_CHANNELIDS[plane * 3 + 2];
320 
321  for (std::vector<Hit>::const_iterator j = hits.begin(); j != hits.end(); j++) {
322  if (j->channel == chan1 && n1 < MAX_HITS) {
323  hits1[n1] = j->time - TDC_OFFSET_CONSTANT;
324  n1++;
325  }
326  if (j->channel == chan2 && n2 < MAX_HITS) {
327  hits2[n2] = j->time - TDC_OFFSET_CONSTANT;
328  n2++;
329  }
330  if (j->channel == chanA && nA < MAX_HITS) {
331  hitsA[nA] = j->time - TDC_OFFSET_CONSTANT;
332  nA++;
333  }
334  }
335 
336  if (n1 != 0 && n2 != 0 && dumpObs_ != nullptr) {
337  fprintf(dumpObs_, "%d,%f,%f,%f,%f\n", plane, hits1[0], hits2[0], hitsA[0], hitsA[1]);
338  fflush(dumpObs_);
339  }
340 
341  // anode-matched hits
342  for (int ii = 0; ii < n1; ii++) {
343  int jmin = -1, lmin = -1;
344  float dsumMin = 99999;
345  for (int jj = 0; jj < n2; jj++) {
346  for (int ll = 0; ll < nA; ll++) {
347  float dsum = fabs(wc_[plane].mean - hits1[ii] - hits2[jj] + 2.0 * hitsA[ll]);
348  if (dsum < (N_SIGMA * wc_[plane].sigma) && dsum < dsumMin) {
349  jmin = jj;
350  lmin = ll;
351  dsumMin = dsum;
352  }
353  }
354  }
355  if (jmin >= 0) {
356  hit_time = wc_[plane].b0 + wc_[plane].b1 * (hits1[ii] - hits2[jmin]);
357  if ((plane % 2) == 0) {
358  plane_hits.push_back(-hit_time);
359  } else {
360  plane_hits.push_back(hit_time);
361  }
362  hits1[ii] = -99999;
363  hits2[jmin] = -99999;
364  hitsA[lmin] = 99999;
365  }
366  }
367 
368  if (includeUnmatchedHits_ || plane > 9) // unmatched hits (all pairs get in here)
369  for (int ii = 0; ii < n1; ii++) {
370  if (hits1[ii] < -99990)
371  continue;
372  for (int jj = 0; jj < n2; jj++) {
373  if (hits2[jj] < -99990)
374  continue;
375  hit_time = wc_[plane].b0 + wc_[plane].b1 * (hits1[ii] - hits2[jj]);
376  if ((plane % 2) == 0) {
377  plane_hits.push_back(-hit_time);
378  } else {
379  plane_hits.push_back(hit_time);
380  }
381  }
382  }
383 
384  if ((plane % 2) == 0)
385  x = plane_hits;
386  else {
387  char chamber = 'A' + plane / 2;
388  ep.setChamberHits(chamber, x, plane_hits);
389  }
390  }
391  }
392 
393 } // namespace hcaltb
static const int lcBeamCoincidence
static const int lcTOF2S
static const int lcBeamHalo4
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:48
static const int lcTOF1S
static const int lcTTCL1ATime
static const int lcScint4
static const int lcScint3
static const int lcBeamHalo2
static const int lcLaserFlash
void reconstructWC(const std::vector< Hit > &hits, HcalTBEventPosition &pos) const
static const int lcScint1
static const int lcMuon3
void setCalib(const std::vector< std::vector< std::string > > &calibLines_)
static const int lcBeamHalo1
ii
Definition: cuy.py:589
static const int lcTriggerTime
static const int lcTOF1J
static const int lcQIEPhase
static const double N_SIGMA
static const int lcBeamHalo3
static const int lcMuon1
float x
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
void unpackHits(const FEDRawData &raw, std::vector< Hit > &hits, HcalTBTiming &timing) const
static const double TDC_OFFSET_CONSTANT
static const int lcMuon2
void unpack(const FEDRawData &raw, HcalTBEventPosition &pos, HcalTBTiming &timing) const
static const int lcTOF2J
static const int WC_CHANNELIDS[PLANECOUNT *3]
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
struct hcaltb::HcalTBTDCUnpacker::WireChamberRecoData wc_[PLANECOUNT]
static const int lcScint2
void reconstructTiming(const std::vector< Hit > &hits, HcalTBTiming &timing) const