QwAnalysis
QwSciFiDetector.cc
Go to the documentation of this file.
1 /**********************************************************\
2  * File: QwSciFiDetector.cc *
3  * *
4  * Author: Jeong Han Lee *
5  * Date: Sunday, January 15 17:22:07 EST 2012 *
6 \**********************************************************/
7 
8 #include "QwSciFiDetector.h"
9 #include "QwParameterFile.h"
10 
11 #include "boost/bind.hpp"
12 
13 // Register this subsystem with the factory
15 
18 
19 
21 : VQwSubsystem(name),
23 {
24  // accept all event types to transfer to ProcessEvBuffer(roc_id .....)
25  // ProcessEvBuffer(eventtype...) is defined in VQwSubsystem.h uses ProcessEvBuffer(roc_id,...)
26  //
27  SetEventTypeMask(0xffff);
28 
30 
31  kRegion = "";
33  fCurrentSlot = 0;
36  fScalerBankIndex = -1;
37 
42 }
43 
45 {
46  fSCAs.clear();
47  delete fF1TDContainer;
48  delete fF1RefContainer;
49 };
50 
51 
52 Int_t
54 {
55 
56  Bool_t local_debug = false;
57 
58  if(local_debug) printf("\n------------- R1 LoadChannelMap %s\n\n", mapfile.Data());
59 
60  TString varname = "";
61  TString varvalue = "";
62  UInt_t value = 0;
63 
64  TString modtype = "";
65  Int_t slot_number = 0; // for SIS3801 scaler. In case of F1TDC, it is a dummy slot number.
66  Int_t chan_number = 0;
67  Int_t fiber_number = 0;
68  TString name = "";
69  Int_t reference_counter = 0;
70 
71  EQwDetectorPackage package = kPackageNull;
72  EQwDirectionID direction = kDirectionNull;
73 
74 
75  QwParameterFile mapstr(mapfile.Data()); //Open the file
76  fDetectorMaps.insert(mapstr.GetParamFileNameContents());
77 
78  while (mapstr.ReadNextLine()){
79 
80  mapstr.TrimComment('!'); // Remove everything after a '!' character.
81  mapstr.TrimWhitespace(); // Get rid of leading and trailing spaces.
82 
83  if (mapstr.LineIsEmpty()) continue;
84 
85  if (mapstr.HasVariablePair("=",varname,varvalue)){
86  // This is a declaration line. Decode it.
87  varname.ToLower();
88  value = QwParameterFile::GetUInt(varvalue);
89  if (value ==0){
90  value = atol(varvalue.Data());
91  }
92  if (varname=="roc") {
93  RegisterROCNumber(value);
94  }
95  else if (varname=="bank"){
96  RegisterSubbank(value);
97  }
98  else if (varname=="pkg") {
99  package=(EQwDetectorPackage)value;
100  }
101  else if (varname=="slot") {
102  RegisterSlotNumber(value);
103  }
104  }
105  else {
106 
107  modtype = mapstr.GetTypedNextToken<TString>();
108  slot_number = mapstr.GetTypedNextToken<Int_t>();
109  chan_number = mapstr.GetTypedNextToken<Int_t>();
110  fiber_number = mapstr.GetTypedNextToken<Int_t>();
111  name = mapstr.GetTypedNextToken<TString>();
112 
113  if(local_debug) {
114  printf("Modtype %8s Slot_Number %4d ChanN %4d, FiberN %4d, FiberName %s\n", modtype.Data(), slot_number, chan_number, fiber_number, name.Data());
115  }
116  if (modtype=="F1TDC") {
117 
118  if (fiber_number==99) {
119 
120  fF1RefContainer -> AddF1TDCReferenceSignal(new F1TDCReferenceSignal(fCurrentBankIndex, slot_number, chan_number, name));
121 
122  if (name=="MasterTrigger" ) {
123  // fReferenceChannels.push_back(std::make_pair(fCurrentModuleIndex, chan_number));
124  // printf("bank index %d Chan %d reference_counter %d\n", fCurrentBankIndex, chan_number, reference_counter);
126  fReferenceChannels.at ( fCurrentBankIndex ).second = chan_number;
127 
128  fDetectorIDs.at(fCurrentModuleIndex).at(chan_number).fElement = fCurrentBankIndex;
129  reference_counter++;
130  }
131  }
132  else {
133  fDetectorIDs.at(fCurrentModuleIndex).at(chan_number).fElement = name.Atoi();
134  }
135 
136  fDetectorIDs.at(fCurrentModuleIndex).at(chan_number).fRegion = kRegionID1;
137  fDetectorIDs.at(fCurrentModuleIndex).at(chan_number).fPackage = package;
138  fDetectorIDs.at(fCurrentModuleIndex).at(chan_number).fPlane = fiber_number;
139  fDetectorIDs.at(fCurrentModuleIndex).at(chan_number).fDirection = direction;
140 
141  }
142  else if (modtype == "SIS3801") {
143 
144  // We have *one* SIS3801 module, and "8" SIS3801 channels,
145  // So, fSCAs size is 8
146 
148  // printf("Scaler bank index %d\n", fScalerBankIndex);
149  QwSIS3801D24_Channel localchannel(name);
150  localchannel.SetNeedsExternalClock(kFALSE);
151  fSCAs.push_back(localchannel);
152  fSCAs_map[name] = fSCAs.size()-1;
153  fSCAs_offset.push_back( QwSIS3801D24_Channel::GetBufferOffset(slot_number,chan_number) );
154 
155  fDetectorIDs.at(fCurrentModuleIndex).at(chan_number).fRegion = kRegionID1;
156  fDetectorIDs.at(fCurrentModuleIndex).at(chan_number).fPackage = package;
157  fDetectorIDs.at(fCurrentModuleIndex).at(chan_number).fPlane = fiber_number;
158  fDetectorIDs.at(fCurrentModuleIndex).at(chan_number).fDirection = direction;
159  fDetectorIDs.at(fCurrentModuleIndex).at(chan_number).fElement = -1;
160 
161  }
162 
163 
164 
165  }
166 
167  }
168 
169  if(local_debug) {
170 
171 
172  Int_t unused_size_counter = 0;
173  std::size_t i = 0;
174 
175 
176 
177  for( i = 0; i < fModuleIndex.size(); i++)
178  {
179  for(size_t slot_size =0; slot_size < fModuleIndex.at(i).size(); slot_size++)
180  {
181  Int_t m_idx = 0;
182  m_idx = fModuleIndex.at(i).at(slot_size);
183  if(m_idx != -1 ) {
184  std::cout << "[" << i <<","<< slot_size << "] "
185  << " module index " << fModuleIndex.at(i).at(slot_size)
186  << std::endl;
187  }
188  else {
189  unused_size_counter++;
190  }
191  }
192  }
193  // why the bank index is always odd number?
194  //
195 
196  printf("Total unused size of fModuleIndex vector %6d\n", unused_size_counter);
197 
198  for(i = 0; i < fReferenceChannels.size(); i++)
199  {
200  std::cout << "[" << i <<"] "
201  << " fRerenceChannel " << fReferenceChannels.at(i).first
202  << " " << fReferenceChannels.at(i).second
203  << std::endl;
204  }
205 
206 
207  // for(i = 0; i < fReferenceData.size(); i++)
208  // {
209  // for(std::size_t j=0; j< fReferenceData.at(i).size(); j++)
210  // {
211  // std::cout << "[" << i << "," << j << "]"
212  // << " fReferenceData " << fReferenceData.at(i).at(j)
213  // << std::endl;
214  // }
215  // }
216  // fReferenceChannels.resize(fCurrentBankIndex+1);
217  // fReferenceData.resize(fCurrentBankIndex+1);
218 
219  printf("\n------------- R1 LoadChannelMap End%s\n\n", mapfile.Data());
220 
221  }
222 
223  mapstr.Close(); // Close the file (ifstream)
224 
225  ReportConfiguration(local_debug);
226  return 0;
227 };
228 
229 Int_t
231 {
232  return 0;
233 };
234 
235 void
237 {
238  SetDataLoaded(kFALSE);
239 
240  fTDCHits.clear();
241  std::size_t i = 0;
242 
244 
245  for (i=0; i<fReferenceData.size(); i++) {
246  fReferenceData.at(i).clear();
247  }
248  for (i=0; i<fSCAs.size(); i++) {
249  fSCAs.at(i).ClearEventData();
250  }
251  return;
252 };
253 
254 void
256 {
257  if (not HasDataLoaded()) return;
258 
259  // F1TDCs
261  UpdateHits();
262 
263 
264  // SIS3801 scaler
265  std::size_t i = 0;
266  for (i=0; i<fSCAs.size(); i++)
267  {
268  fSCAs.at(i).ProcessEvent();
269  }
270  return;
271 };
272 
273 
274 
275 void
277 {
278  return;
279 };
280 
281 void
282 QwSciFiDetector::ConstructHistograms(TDirectory *folder, TString &prefix)
283 {
284 
285  for (std::size_t i=0; i<fSCAs.size(); i++) {
286  fSCAs.at(i).ConstructHistograms(folder, prefix);
287  }
288  return;
289 };
290 
291 void
293 {
294  if (! HasDataLoaded()) return;
295  for (std::size_t i=0; i<fSCAs.size(); i++) {
296  fSCAs.at(i).FillHistograms();
297  }
298 
299  return;
300 };
301 
302 void
304 {
305 
306  return;
307 };
308 
309 
310 
311 void
313  TString& prefix,
314  std::vector<Double_t> &values)
315 {
316  fTreeArrayIndex = values.size();
317 
318  TString basename;
319  if (prefix=="") basename = "scifiber";
320  else basename = prefix;
321 
322  TString list = "";
323 
324  for (std::size_t i=0; i<fSCAs.size(); i++)
325  {
326  if (fSCAs.at(i).GetElementName() != "") {
327  values.push_back(0.0);
328  list += ":" + fSCAs.at(i).GetElementName() + "/D";
329  }
330  }
331 
332  if (list[0]==':') {
333  list = list(1,list.Length()-1);
334  }
335 
336  fTreeArrayNumEntries = values.size() - fTreeArrayIndex;
337  tree->Branch(basename, &values[fTreeArrayIndex], list);
338  return;
339 }
340 
341 void
342 QwSciFiDetector::FillTreeVector(std::vector<Double_t> &values) const
343 {
344  if (! HasDataLoaded()) return;
345 
346  Int_t index = fTreeArrayIndex;
347 
348  for (std::size_t i=0; i<fSCAs.size(); i++)
349  {
350  if (fSCAs.at(i).GetElementName() != "") {
351  values[index] = fSCAs.at(i).GetValue();
352  index++;
353  }
354  }
355  return;
356 }
357 
358 
359 
360 
361 void
363 {
364 
365  // Bank index 1 : ROC4 F1TDC
366  // Bank index 3 : ROC9 F1TDCs
367  // Bank index 5 : ROC11 SIS3801
368 
369 
370  if(verbose) {
371  std::size_t i = 0;
372  std::size_t j = 0;
373 
374  Int_t roc_num = 0;
375  Int_t bank_flag = 0;
376  Int_t bank_index = 0;
377  Int_t module_index = 0;
378 
379  UInt_t slot_id = 0;
380  UInt_t vme_slot_num = 0;
381 
382  std::cout << "QwSciFiDetector Region : "
383  << this->GetSubsystemName()
384  << "::ReportConfiguration fDetectorIDs.size() "
385  << fDetectorIDs.size() << std::endl;
386 
387 
388  for ( i=0; i<fROC_IDs.size(); i++ )
389  {
390 
391  roc_num = fROC_IDs.at(i);
392 
393  for ( j=0; j<fBank_IDs.at(i).size(); j++ )
394  {
395  bank_flag = fBank_IDs.at(i).at(j);
396  if(bank_flag == 0) continue;
397  // must be uncommented if one doesn't define "bank_flag" in a CRL file
398  // but, now we use "bank_flag" in our crl files, thus skip to print
399  // unnecessary things on a screen
400  // Monday, August 30 14:45:34 EDT 2010, jhlee
401 
402  bank_index = GetSubbankIndex(roc_num, bank_flag);
403 
404  std::cout << "ROC [index, Num]["
405  << i
406  << ","
407  << std::setw(2) << roc_num
408  << "]"
409  << " Bank [index,id]["
410  << bank_index
411  << ","
412  << bank_flag
413  << "]"
414  << std::endl;
415 
416  for ( slot_id=2; slot_id<kMaxNumberOfSlotsPerROC; slot_id++ )
417  {
418  // slot id starts from 2, because 0 and 1 are used for CPU and TI.
419  // Tuesday, August 31 10:57:07 EDT 2010, jhlee
420 
421  module_index = GetModuleIndex(bank_index, slot_id);
422 
423  vme_slot_num = slot_id;
424 
425  std::cout << " "
426  << "Slot [id, VME num] ["
427  << std::setw(2) << slot_id
428  << ","
429  << std::setw(2) << vme_slot_num
430  << "]";
431  if ( module_index == -1 ) {
432  std::cout << " "
433  << "Unused in R1 SciFiDetector"
434  << std::endl;
435  }
436  else {
437  std::cout << " "
438  << "Module index "
439  << module_index << std::endl;
440  }
441  }
442  }
443  }
444 
445  for( size_t midx = 0; midx < fDetectorIDs.size(); midx++ )
446  {
447  for (size_t chan = 0 ; chan< fDetectorIDs.at(midx).size(); chan++)
448  {
449  std::cout << "[" << midx <<","<< chan << "] "
450  << " detectorID " << fDetectorIDs.at(midx).at(chan)
451  << std::endl;
452  }
453  }
454  }
455  return;
456 }
457 
458 
459 
460 
461 
462 
463 
464 void
465 QwSciFiDetector::PrintConfigurationBuffer(UInt_t *buffer, UInt_t num_words)
466 {
467  UInt_t ipt = 0;
468  UInt_t j = 0;
469  UInt_t k = 0;
470 
471  for ( j=0; j<(num_words/5); j++ )
472  {
473  printf ( "buffer[%5d] = 0x:", ipt );
474  for ( k=j; k<j+5; k++ )
475  {
476  printf ( "%12x", buffer[ipt++] );
477  }
478  printf ( "\n" );
479  }
480 
481  if ( ipt<num_words ) {
482  printf ( "buffer[%5d] = 0x:", ipt );
483  for ( k=ipt; k<num_words; k++ )
484  {
485  printf ( "%12x", buffer[ipt++] );
486  }
487  printf ( "\n" );
488  }
489  printf ( "\n" );
490 
491  return;
492 }
493 
494 
495 
496 
497 Int_t
499  const UInt_t bank_id,
500  UInt_t* buffer,
501  UInt_t num_words)
502 {
503 
504  TString subsystem_name = "";
505 
506  Int_t bank_index = 0;
507  Int_t tdc_index = 0;
508  UInt_t slot_id = 0;
509  UInt_t vme_slot_num = 0;
510 
511  Bool_t local_debug = false;
512  QwF1TDC *local_f1tdc = NULL;
513 
514  bank_index = GetSubbankIndex(roc_id, bank_id);
515 
516  if(bank_index >=0) {
517  if(local_debug) {
518  std::cout << "fF1TDContainer " << fF1TDContainer
519  <<" local_f1tdc " << local_f1tdc << "\n";
520  }
521  subsystem_name = this->GetSubsystemName();
522  fF1TDContainer -> SetSystemName(subsystem_name);
523 
524  if(local_debug) {
525  std::cout << "-----------------------------------------------------" << std::endl;
526 
527  std::cout << "\nQwSciFiDetector : "
528  << subsystem_name
529  << ", "
530  << "ProcessConfigurationBuffer"
531  << std::endl;
532  std::cout << "ROC "
533  << std::setw(2) << roc_id
534  << " Bank [index,id]["
535  << bank_index
536  << ","
537  << bank_id
538  << "]"
539  << std::endl;
540  }
541  for ( slot_id=0; slot_id<kMaxNumberOfSlotsPerROC; slot_id++ )
542  {
543  // slot id starts from 2, because 0 is one offset (1) difference between QwAnalyzer and VME definition,
544  // and 1 and 2 are used for CPU and TI. Tuesday, August 31 10:57:07 EDT 2010, jhlee
545 
546  tdc_index = GetModuleIndex(bank_index, slot_id);
547  vme_slot_num = slot_id;
548  if(local_debug) {
549  std::cout << " "
550  << "Slot [id, VME num] ["
551  << std::setw(2) << slot_id
552  << ","
553  << std::setw(2) << vme_slot_num
554  << "]";
555  std::cout << " ";
556  }
557  local_f1tdc = NULL;
558 
559  if(slot_id > 2) { // save time
560 
561  if (tdc_index not_eq -1) {
562 
563  if(local_f1tdc) delete local_f1tdc; local_f1tdc = NULL;
564 
565  local_f1tdc = new QwF1TDC(roc_id, vme_slot_num);
566 
567  local_f1tdc->SetF1BankIndex(bank_index);
568  local_f1tdc->SetF1TDCIndex(tdc_index);
569  local_f1tdc->SetF1TDCBuffer(buffer, num_words);
570  local_f1tdc->SetF1SystemName(subsystem_name);
571 
572  fF1TDContainer->AddQwF1TDC(local_f1tdc);
573  if(local_debug) {
574  std::cout << "F1TDC index "
575  << std::setw(2)
576  << tdc_index
577  << std::setw(16)
578  << " local_f1tdc "
579  << *local_f1tdc
580  << " at "
581  << local_f1tdc;
582  }
583  }
584  else {
585  if(local_debug){
586  std::cout << "Unused in "
587  << std::setw(4)
588  << subsystem_name
589  << std::setw(16)
590  << " local_f1tdc at "
591  << local_f1tdc;
592  }
593  }
594 
595  }
596  else { // slot_id == only 0, 1, & 2
597  if(local_debug) {
598  if (slot_id == 0) std::cout << " ";
599  else if (slot_id == 1) std::cout << "MVME CPU ";
600  else std::cout << "Trigger Interface"; // slot_id == 2;
601  }
602  }
603  if(local_debug) {
604  std::cout << std::endl;
605  }
606  }
607 
609 
610  if(local_debug) fF1TDContainer->Print();
611  std::cout << "-----------------------------------------------------" << std::endl;
612 
613 
614  // kMaxNumberOfChannelsPerTDC = fF1TDContainer->GetF1TDCChannelNumber();
615 
616  return 0;
617  }
618  else {
619  if(local_debug) {
620  printf("\nQwSciFiDetector::ProcessConfigurationBuffer: \n");
621  printf("Bank index is not defined with ROC id %d and Bank id %d. Thus, this is not F1TDC data. Skip this bank\n\n", roc_id, bank_id);
622  }
623 
624  return -1;
625  }
626 }
627 
628 
629 
630 // ProcessEvBuffer is called in QwEventBuffer.cc backtrace....
631 // 0 ProcessEvBuffer(event_type, roc_id, bank_id, buffer, num_words) in QwEventBuffer
632 // 1 ProcessEvBuffer(event_type, roc_id, bank_id, buffer, num_words) in QwSubsystemArray
633 // 2 ProcessEvBuffer(event_type, roc_id, bank_id, buffer, num_words) in VQwSubsystem.h
634 // 3 ProcessEvBuffer(roc_id, bank_id, buffer, num_words) in ProcessEvBuffer(event_type,...) in VQwSubsystem.h
635 // * public Constructor of VQwSubsystemTracking.h uses SetEventTypeMask() in order to filter out
636 // 0x1 (parity event, number 1 physics event). So I remove it by using SetEventTypeMask(0xffff)
637 // in the public Constructor of QwSciFiDetector.
638 //
639 // Wednesday, January 18 13:34:29 EST 2012, jhlee
640 
641 
642 Int_t
643 QwSciFiDetector::ProcessEvBuffer(const UInt_t roc_id,
644  const UInt_t bank_id,
645  UInt_t* buffer,
646  UInt_t num_words)
647 {
648 
649  Int_t bank_index = 0;
650  Int_t vme_module_slot_number = 0;
651  Int_t vme_module_chan_number = 0;
652  UInt_t vme_module_data = 0;
653  Int_t module_index = 0;
654 
655  Bool_t data_integrity_flag = false;
656  Bool_t temp_print_flag = false;
657 
658  bank_index = GetSubbankIndex(roc_id, bank_id);
659 
660  if (bank_index>=0 && num_words>0) {
661  // We want to process this ROC. Begin looping through the data.
662  SetDataLoaded(kTRUE);
663 
664  if ( temp_print_flag ) {
665  std::cout << "\nQwSciFiDetector::ProcessEvBuffer: "
666  << "Begin processing ROC"
667  << std::setw(2)
668  << roc_id
669  << " bank id "
670  << bank_id
671  << " Subbbank Index "
672  << bank_index
673  << " Region "
674  << GetSubsystemName()
675  << std::endl;
676  }
677 
678  if( bank_index != fScalerBankIndex) {
679  //
680  // CheckDataIntegrity() do "counter" whatever errors in each F1TDC
681  // and check whether data is OK or not.
682 
683  data_integrity_flag = fF1TDContainer->CheckDataIntegrity(roc_id, buffer, num_words);
684  // if it is false (TFO, EMM, and SYN), the whole buffer is excluded for
685  // the further process, because of multiblock data transfer.
686 
687  if (data_integrity_flag) {
688 
689  // printf("\n");
690  for (UInt_t i=0; i<num_words ; i++) {
691 
692  // Decode this word as a F1TDC word.
693  fF1TDCDecoder.DecodeTDCWord(buffer[i], roc_id);
694 
695  vme_module_slot_number = fF1TDCDecoder.GetTDCSlotNumber();
696  vme_module_chan_number = fF1TDCDecoder.GetTDCChannelNumber();
697  module_index = GetModuleIndex(bank_index, vme_module_slot_number);
698 
699  if ( vme_module_slot_number == 31) {
700  // This is a custom word which is not defined in
701  // the F1TDC, so we can use it as a marker for
702  // other data; it may be useful for something.
703  }
704 
705  // Each subsystem has its own interesting slot(s), thus
706  // here, if this slot isn't in its slot(s) (subsystem map file)
707  // we skip this buffer to do the further process
708 
709  if (not IsSlotRegistered(bank_index, vme_module_slot_number) ) continue;
710 
711  if(temp_print_flag) std::cout << fF1TDCDecoder << std::endl;
712 
713  if ( fF1TDCDecoder.IsValidDataword() ) {//;;
714  // if decoded F1TDC data has a valid slot, resolution locked, data word, no overflow (0xFFFF), and no fake data
715  // try get time and fill it into raw QwHit.. FillRawTDCWord function is in each subsystem.
716 
717  try {
718  vme_module_data = fF1TDCDecoder.GetTDCData();
719  FillRawTDCWord(bank_index, vme_module_slot_number, vme_module_chan_number, vme_module_data);
720 
721  }
722  catch (std::exception& e) {
723  std::cerr << "Standard exception from QwSciFiDetector::FillRawTDCWord: "
724  << e.what() << std::endl;
725  std::cerr << " Parameters: index==" <<bank_index
726  << "; Slot Number==" <<vme_module_slot_number
727  << "; Channel Number=="<<vme_module_chan_number
728  << "; Data==" <<vme_module_data
729  << std::endl;
730 
731  std::cerr << " Module Index=="<<module_index
732  << "; fDetectorIDs.at(module_index).size()=="
733  << fDetectorIDs.at(module_index).size()
734  << "; fDetectorIDs.at(module_index).at(chan).fPlane=="
735  << fDetectorIDs.at(module_index).at(vme_module_chan_number).fPlane
736  << "; fDetectorIDs.at(module_index).at(chan).fElement=="
737  << fDetectorIDs.at(module_index).at(vme_module_chan_number).fElement
738  << std::endl;
739  }
740  }//;;
741  } // for (UInt_t i=0; i<num_words ; i++) {
742  }
743 
744  }
745  else {
746 
747  // printf("Scaler %d\n", (Int_t)fSCAs.size());
748  // Check if scaler buffer contains more than one event, and if so, reject it to decode.
749  //
750  if (buffer[0]/32!=1) {
751  if(temp_print_flag) printf("This buffer contains more than one event, thus, we reject them\n"); // Why? jhlee
752  return 0;
753  }
754 
755  UInt_t words_read = 0;
756  for (std::size_t k=0; k<fSCAs.size(); k++) {
757  words_read += fSCAs.at(k).ProcessEvBuffer(&(buffer[fSCAs_offset.at(k)]), num_words-fSCAs_offset.at(k));
758  if(temp_print_flag) printf("k %d words_read %d\n", (Int_t)k, words_read);
759  }
760 
761  }
762  }
763 
764  // // fF1TDContainer-> PrintErrorSummary();
765  return 0;
766 }
767 
768 
769 
770 void
772  Int_t slot_num,
773  Int_t chan,
774  UInt_t data)
775 {
776  Bool_t local_debug = false;
777  Int_t tdcindex = 0;
778 
779  tdcindex = GetModuleIndex(bank_index,slot_num);
780 
781  // I think, it is not necessary, but is just "safe" double check routine.
782  if (tdcindex not_eq -1) {
783 
784  Int_t hitcnt = 0;
785 
786  EQwDetectorPackage package = kPackageNull;
787  EQwDirectionID direction = kDirectionNull;
788 
789  Int_t octant = 0;
790  Int_t plane = 0; // fiber number (1357, 2,4,6,8) for the fibers, and 99 for the reference channel
791  Int_t element = 0; // fiber orient type (0 (both), 1(a), 2(b)) for the fibers, and the module index for the reference channel
792  TString name = "";
793 
794  // F1TDCReferenceSignal *f1_ref_signal;
795 
796  fF1RefContainer->SetReferenceSignal(bank_index, slot_num, chan, data, local_debug);
797 
798  // if( f1_ref_signal ) {
799  // f1_ref_signal -> SetRefTimeAU (data);
800  // // std::cout << *f1_ref_signal << std::endl;
801  // }
802 
803  plane = fDetectorIDs.at(tdcindex).at(chan).fPlane;
804  element = fDetectorIDs.at(tdcindex).at(chan).fElement;
805  package = fDetectorIDs.at(tdcindex).at(chan).fPackage;
806  octant = fDetectorIDs.at(tdcindex).at(chan).fOctant;
807  if(local_debug) {
808  printf("bank_idx %d, slot %d, plane %d, element %d, package %d\n",
809  bank_index, slot_num, (Int_t) plane, (Int_t) element, (Int_t) package);
810  }
811 
812  if (plane == -1 or element == -1){
813  // This channel is not connected to anything. Do nothing.
814  }
815  else if (plane == kF1ReferenceChannelNumber){
816  fReferenceData.at(element).push_back(data);
817  // we assign the reference time into fReferenceData according the module index
818  // See LocalChannelMap
819 
820  }
821  else {
822  direction = fDetectorIDs.at(tdcindex).at(chan).fDirection;
823 
824  hitcnt = std::count_if(fTDCHits.begin(), fTDCHits.end(),
825  boost::bind(
826  &QwHit::WireMatches, _1, kRegionID1, boost::ref(package), boost::ref(plane), boost::ref(element)
827  )
828  );
829 
830  fTDCHits.push_back(
831  QwHit(
832  bank_index,
833  slot_num,
834  chan,
835  hitcnt,
836  kRegionID1,
837  package,
838  octant,
839  plane,
840  direction,
841  element,
842  data
843  )
844  );
845 
846  if(local_debug) {
847  std::cout << "At QwSciFiDetector::FillRawTDCWord "
848  << " bank index " << bank_index
849  << " slot num " << slot_num
850  << " chan num " << chan
851  << " hitcnt " << hitcnt
852  << " plane " << plane
853  << " wire " << element
854  << " package " << package
855  << " diection " << direction
856  << " fTDCHits.size() " << fTDCHits.size()
857  << std::endl;
858  }
859 
860  }
861 
862  } // (tdcindex not_eq -1) {
863 
864  return;
865 }
866 
867 
868 
869 void
871 {
872  fF1RefContainer-> PrintCounters();
873  fF1TDContainer -> PrintErrorSummary();
874  fF1TDContainer -> WriteErrorSummary();
875  return;
876 };
877 
878 
879 
880 
881 // protected
882 void
884 {
886 
887  std::size_t i = 0;
888 
889  for ( i=0; i<fModuleIndex.size(); i++)
890  {
891  fModuleIndex.at(i).clear();
892  }
893 
894  fModuleIndex.clear();
895  fDetectorIDs.clear();
896  fTDCHits.clear();
898  return;
899 }
900 
901 Int_t
903 {
904  Int_t status = 0;
905  status = VQwSubsystemTracking::RegisterROCNumber(roc_id, 0);
906  std::vector<Int_t> tmpvec(kMaxNumberOfSlotsPerROC,-1);
907  fModuleIndex.push_back(tmpvec);
908  //std::cout<<"Registering ROC "<<roc_id<<std::endl;
909 
910  return status;
911 }
912 
913 
914 Int_t
915 QwSciFiDetector::RegisterSubbank(const UInt_t bank_id)
916 {
917 
918  Int_t status = VQwSubsystem::RegisterSubbank(bank_id);
919  Int_t current_roc_id = VQwSubsystem::fCurrentROC_ID;
920 
921  std::size_t reference_size = fReferenceChannels.size();
922 
923  // from here, just expand some vectors in QwSciFiDetector...
924  //
925  fCurrentBankIndex = GetSubbankIndex(current_roc_id, bank_id);
926  //subbank id is directly related to the ROC
927 
928  if ( (Int_t) reference_size <= fCurrentBankIndex) {
931  }
932 
933  // Why do we need to expand this vector size
934  // even if most of them are empty? --- jhlee
935 
936  std::vector<Int_t> tmpvec(kMaxNumberOfSlotsPerROC,-1);
937 
938  fModuleIndex.push_back(tmpvec);
939 
940  std::cout<< "QwSciFiDetector::RegisterSubbank()"
941  <<" ROC " << current_roc_id
942  <<" Subbank " << bank_id
943  <<" with BankIndex " << fCurrentBankIndex
944  << std::endl;
945 
946  return status;
947 }
948 
949 
950 Int_t
952 {
953  if (slot_id<kMaxNumberOfSlotsPerROC) {
954 
955  if (fCurrentBankIndex <= (Int_t) fModuleIndex.size()) {
956 
959 
960  // reassign kNumberOfVMEModules after resize it
961 
962  kNumberOfVMEModules = (Int_t) fDetectorIDs.size();
964  fCurrentSlot = slot_id;
966  }
967  }
968  else {
969  std::cout << "QwSciFiDetector::RegisterSlotNumber: Slot number "
970  << slot_id << " is larger than the number of slots per ROC, "
971  << kMaxNumberOfSlotsPerROC << std::endl;
972  }
973  return fCurrentModuleIndex;
974 
975 }
976 
977 Int_t
978 QwSciFiDetector::GetModuleIndex(size_t bank_index, size_t slot_num) const
979 {
980  Int_t module_index = -1;
981  if ( bank_index < fModuleIndex.size() ) {
982  if ( slot_num < fModuleIndex.at(bank_index).size() ) {
983  module_index = fModuleIndex.at(bank_index).at(slot_num);
984  }
985  }
986  return module_index;
987 }
988 
989 
990 
991 
992 void
994 {
995 
996  UInt_t bank_index = 0;
997  Double_t raw_time_arb_unit = 0.0;
998  Double_t ref_time_arb_unit = 0.0;
999  Double_t time_arb_unit = 0.0;
1000  // EQwDetectorPackage package = kPackageNull; // Region 1 has only Package 2, so kPackageDown
1001 
1002  Bool_t local_debug = false;
1003  Int_t slot_num = 0;
1004 
1005  TString reference_name1 = "MasterTrigger";
1006  TString reference_name2 = "CopyMasterTrigger";
1007 
1008 
1009  for ( std::vector<QwHit>::iterator hit=fTDCHits.begin(); hit!=fTDCHits.end(); hit++ )
1010  {
1011 
1012  bank_index = hit -> GetSubbankID();
1013  slot_num = hit -> GetModule();
1014  raw_time_arb_unit = (Double_t) hit -> GetRawTime();
1015  ref_time_arb_unit = fF1RefContainer -> GetReferenceTimeAU(bank_index, reference_name1);
1016  //
1017  // if there is no reference time due to a channel error, try to use a copy of mater trigger
1018  //
1019  if(ref_time_arb_unit==0.0) {
1020  ref_time_arb_unit = fF1RefContainer->GetReferenceTimeAU(bank_index, reference_name2);
1021  }
1022  // second time, it returns 0.0, we simply ignore this event ....
1023  // set time zero. ReferenceSignalCorrection() will return zero, and increase RFM counter...
1024  //
1025  time_arb_unit = fF1TDContainer->ReferenceSignalCorrection(raw_time_arb_unit, ref_time_arb_unit, bank_index, slot_num);
1026 
1027  hit -> SetTime(time_arb_unit);
1028  hit -> SetRawRefTime((UInt_t) ref_time_arb_unit);
1029 
1030  if(local_debug) {
1031  QwMessage << this->GetSubsystemName()
1032  << " BankIndex " << std::setw(2) << bank_index
1033  << " Slot " << std::setw(2) << slot_num
1034  << " RawTime : " << std::setw(6) << raw_time_arb_unit
1035  << " RefTime : " << std::setw(6) << ref_time_arb_unit
1036  << " time : " << std::setw(6) << time_arb_unit
1037  << std::endl;
1038 
1039  }
1040  }
1041 
1042  return;
1043 
1044 }
1045 
1046 
1047 // void
1048 // QwSciFiDetector::SubtractReferenceTimes()
1049 // {
1050 
1051 // std::vector<Double_t> reftimes;
1052 // std::vector<Bool_t> refchecked;
1053 // std::vector<Bool_t> refokay;
1054 // Bool_t allrefsokay;
1055 
1056 
1057 // std::size_t ref_size = 0;
1058 // std::size_t i = 0;
1059 // std::size_t j = 0;
1060 
1061 // ref_size = fReferenceData.size();
1062 
1063 // reftimes.resize ( ref_size );
1064 // refchecked.resize( ref_size );
1065 // refokay.resize ( ref_size );
1066 
1067 // for ( i=0; i<ref_size; i++ ) {
1068 // reftimes.at(i) = 0.0;
1069 // refchecked.at(i) = kFALSE;
1070 // refokay.at(i) = kFALSE;
1071 // }
1072 
1073 // allrefsokay = kTRUE;
1074 
1075 
1076 
1077 // UInt_t bank_index = 0;
1078 // Double_t raw_time_arb_unit = 0.0;
1079 // Double_t ref_time_arb_unit = 0.0;
1080 // Double_t time_arb_unit = 0.0;
1081 
1082 // Bool_t local_debug = false;
1083 
1084 // for ( std::vector<QwHit>::iterator hit=fTDCHits.begin(); hit!=fTDCHits.end(); hit++ )
1085 // {
1086 // // Only try to check the reference time for a bank if there is at least one
1087 // // non-reference hit in the bank.
1088 // bank_index = hit->GetSubbankID();
1089 
1090 // // // if(local_debug) printf("QwHit :: bank index %d\n", bank_index);
1091 
1092 // // if ( not refchecked.at(bank_index) ) {
1093 
1094 // // if ( fReferenceData.at(bank_index).empty() ) {
1095 // // std::cout << "QwSciFiDetector::SubtractReferenceTimes: Subbank ID "
1096 // // << bank_index << " is missing a reference time." << std::endl;
1097 // // refokay.at(bank_index) = kFALSE;
1098 // // allrefsokay = kFALSE;
1099 // // }
1100 // // else {
1101 // // if(fReferenceData.at(bank_index).size() not_eq 1) {
1102 // // std::cout << "Multiple hits are recorded in the reference channel, we use the first hit signal as the refererence signal." << std::endl;
1103 // // }
1104 // // reftimes.at(bank_index) = fReferenceData.at(bank_index).at(0);
1105 // // refokay.at(bank_index) = kTRUE;
1106 // // }
1107 
1108 // // if (refokay.at(bank_index)){
1109 // // for ( j=0; j<fReferenceData.at(bank_index).size(); j++ )
1110 // // {
1111 // // // printf("Reference time %f fReferenceData.at(%d).at(%d) %f\n",
1112 // // // reftimes.at(bank_index), (Int_t) bank_index, (Int_t) j, fReferenceData.at(bank_index).at(j));
1113 // // fReferenceData.at(bank_index).at(j) -= reftimes.at(bank_index);
1114 // // // printf("Reference time %f fReferenceData.at(%d).at(%d) %f\n",
1115 // // // reftimes.at(bank_index), (Int_t) bank_index, (Int_t) j, fReferenceData.at(bank_index).at(j));
1116 // // }
1117 // // }
1118 
1119 // // refchecked.at(bank_index) = kTRUE;
1120 // // }
1121 
1122 // // if ( refokay.at(bank_index) ) {
1123 // Int_t slot_num = hit -> GetModule();
1124 // raw_time_arb_unit = (Double_t) hit -> GetRawTime();
1125 // ref_time_arb_unit = (Double_t) reftimes.at(bank_index);
1126 
1127 // time_arb_unit = fF1TDContainer->ReferenceSignalCorrection(raw_time_arb_unit, ref_time_arb_unit, bank_index, slot_num);
1128 
1129 // hit -> SetTime(time_arb_unit);
1130 // hit -> SetRawRefTime((UInt_t) ref_time_arb_unit);
1131 
1132 // if(local_debug) {
1133 // QwMessage << this->GetSubsystemName()
1134 // << " BankIndex " << std::setw(2) << bank_index
1135 // << " Slot " << std::setw(2) << slot_num
1136 // << " RawTime : " << std::setw(6) << raw_time_arb_unit
1137 // << " RefTime : " << std::setw(6) << ref_time_arb_unit
1138 // << " time : " << std::setw(6) << time_arb_unit
1139 // << std::endl;
1140 
1141 // }
1142 // }
1143 
1144 
1145 // // bank_index = 0;
1146 
1147 // // if ( not allrefsokay ) {
1148 // // std::vector<QwHit> tmp_hits;
1149 // // tmp_hits.clear();
1150 // // for ( std::vector<QwHit>::iterator hit=fTDCHits.begin(); hit!=fTDCHits.end(); hit++ )
1151 // // {
1152 // // bank_index = hit->GetSubbankID();
1153 // // if ( refokay.at(bank_index) ) tmp_hits.push_back(*hit);
1154 // // }
1155 // // // std::cout << "FTDC size " << fTDCHits.size() << "tmp hit size " << tmp_hits.size() << std::endl;
1156 // // fTDCHits.clear();
1157 // // fTDCHits = tmp_hits;
1158 // // // std::cout << "FTDC size " << fTDCHits.size() << "tmp hit size " << tmp_hits.size() << std::endl;
1159 // // }
1160 
1161 // return;
1162 // }
1163 
1164 
1165 
1166 void
1168 {
1169 
1170 
1171 
1172  for(std::vector<QwHit>::iterator iter=fTDCHits.begin(); iter!=fTDCHits.end(); ++iter)
1173  {
1174 
1175  iter->ApplyTimeCalibration(fF1TDCResolutionNS); // Fill fTimeRes and fTimeNs in QwHit
1176 
1177  }
1178 
1179  return;
1180 }
1181 
Int_t GetSubbankIndex() const
Definition: VQwSubsystem.h:303
#define QwMessage
Predefined log drain for regular messages.
Definition: QwLog.h:50
void AddQwF1TDC(QwF1TDC *in)
std::map< TString, TString > fDetectorMaps
Definition: VQwSubsystem.h:322
void ReportConfiguration(Bool_t verbose)
Int_t ProcessConfigurationBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
F1TDCs configuration and reference siganls container.
void ClearAllBankRegistrations()
void SetF1TDCBuffer(UInt_t *buffer, UInt_t num_words)
const UInt_t & GetTDCMaxChannels() const
Definition: MQwF1TDC.h:50
F1TDCReferenceContainer * fF1RefContainer
static UInt_t GetUInt(const TString &varvalue)
std::vector< QwHit > fTDCHits
void FillRawTDCWord(Int_t bank_index, Int_t slot_num, Int_t chan, UInt_t data)
std::vector< std::pair< Int_t, Int_t > > fReferenceChannels
void SubtractReferenceTimes()
const UInt_t & GetTDCData() const
Definition: MQwF1TDC.h:49
Bool_t HasDataLoaded() const
Definition: VQwSubsystem.h:94
one F1TDC configuration and reference signal(s) holder
void ConstructBranchAndVector(TTree *tree, TString &prefix, std::vector< Double_t > &values)
Construct the branch and tree vector.
Double_t GetReferenceTimeAU(Int_t bank_index, TString name)
Int_t LoadInputParameters(TString mapfile)
Mandatory parameter file definition.
Int_t GetModuleIndex(size_t bank_index, size_t slot_num) const
static const double e
Definition: QwUnits.h:91
Bool_t CheckDataIntegrity(const UInt_t roc_id, UInt_t *buffer, UInt_t num_words)
EQwDetectorPackage
Definition: QwTypes.h:70
std::vector< Int_t > fSCAs_offset
UInt_t kMaxNumberOfChannelsPerF1TDC
virtual void ConstructHistograms()
Construct the histograms for this subsystem.
Definition: VQwSubsystem.h:209
QwF1TDContainer * fF1TDContainer
Int_t ProcessEvBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
TODO: The non-event-type-aware ProcessEvBuffer routine should be replaced with the event-type-aware v...
const UInt_t & GetTDCSlotNumber() const
Definition: MQwF1TDC.h:44
std::vector< std::vector< Int_t > > fModuleIndex
Bool_t IsSlotRegistered(Int_t bank_index, Int_t slot_num) const
const UInt_t & GetTDCChannelNumber() const
Definition: MQwF1TDC.h:45
void SetEventTypeMask(const UInt_t mask)
Set event type mask.
Definition: VQwSubsystem.h:166
size_t fTreeArrayIndex
Tree indices.
QwSciFiDetector()
Private default constructor (not implemented, will throw linker error on use)
Int_t RegisterROCNumber(const UInt_t roc_id)
void FillTreeVector(std::vector< Double_t > &values) const
Fill the tree vector.
static const Int_t kF1ReferenceChannelNumber
void FillHardwareErrorSummary()
Hardware error summary.
Double_t ReferenceSignalCorrection(Double_t raw_time, Double_t ref_time, Int_t bank_index, Int_t slot)
void FillHistograms()
Fill the histograms for this subsystem.
void FillListOfHits(QwHitContainer &hitlist)
std::vector< std::vector< Double_t > > fReferenceData
void SetReferenceSignal(Int_t bank_index, Int_t slot, Int_t chan, UInt_t data, Bool_t debug=false)
Double_t DoneF1TDCsConfiguration()
Bool_t WireMatches(EQwRegionID region, EQwDetectorPackage package, Int_t plane, Int_t wire)
Definition: QwHit.cc:357
Bool_t IsValidDataword() const
Definition: MQwF1TDC.cc:328
The pure virtual base class of all subsystems.
Definition: VQwSubsystem.h:59
void SetF1BankIndex(const Int_t bank_index)
const MQwF1TDC GetF1TDCDecoder() const
class QwScaler_Channel< 0x00ffffff, 0 > QwSIS3801D24_Channel
void SetF1SystemName(const TString name)
std::vector< std::vector< UInt_t > > fBank_IDs
Vector of Bank IDs per ROC ID associated with this subsystem.
Definition: VQwSubsystem.h:331
Int_t fCurrentROC_ID
ROC ID that is currently being processed.
Definition: VQwSubsystem.h:325
Int_t RegisterSubbank(const UInt_t bank_id)
Tell the object that it will decode data from this sub-bank in the ROC currently open for registratio...
Int_t fCurrentBankIndex
Name of this subsystem (the region).
static const UInt_t kMaxNumberOfSlotsPerROC
virtual Int_t RegisterROCNumber(const UInt_t roc_id, const UInt_t bank_id=0)
Tell the object that it will decode data from this ROC and sub-bank.
void PrintConfigurationBuffer(UInt_t *buffer, UInt_t num_words)
Int_t LoadChannelMap(TString mapfile)
Mandatory map file definition.
std::vector< UInt_t > fROC_IDs
Vector of ROC IDs associated with this subsystem.
Definition: VQwSubsystem.h:329
void SetF1TDCIndex(const Int_t tdc_index)
EQwDirectionID
Definition: QwTypes.h:41
Hit structure uniquely defining each hit.
Definition: QwHit.h:43
MQwF1TDC fF1TDCDecoder
void Print(const Option_t *options=0) const
std::map< TString, size_t > fSCAs_map
Int_t RegisterSubbank(const UInt_t bank_id)
Int_t RegisterSlotNumber(const UInt_t slot_id)
void DecodeTDCWord(UInt_t &word, const UInt_t roc_id)
Definition: MQwF1TDC.cc:84
std::vector< QwSIS3801D24_Channel > fSCAs
std::vector< std::vector< QwDetectorID > > fDetectorIDs
void ClearAllBankRegistrations()
Clear all registration of ROC and Bank IDs for this subsystem.
#define RegisterSubsystemFactory(A)
Definition: QwFactory.h:230
TString GetSubsystemName() const
Definition: VQwSubsystem.h:93
virtual ~QwSciFiDetector()
void SetDataLoaded(Bool_t flag)
Definition: VQwSubsystem.h:305