QwAnalysis
QwDriftChamber.cc
Go to the documentation of this file.
1 /**********************************************************\
2  * File: QwDriftChamber.C *
3  * *
4  * Author: P. M. King, Rakitha Beminiwattha *
5  * J. H. Lee *
6  * Time-stamp: Wednesday, July 28 15:52:26 EDT 2010 *
7 \**********************************************************/
8 
9 #include "QwDriftChamber.h"
10 
11 #include "QwLog.h"
12 #include "QwColor.h"
13 #include "QwOptions.h"
14 #include "QwParameterFile.h"
15 
16 //const UInt_t QwDriftChamber::kMaxNumberOfTDCsPerROC = 21;
17 // VME 21 slots - 2 VMEs (CPU, TI)
18 // in priniciple, the maximum number is 19,
19 // but, Qweak only uses 9 F1TDCs at ROC 9 and ROC 10.
23 
24 // kMaxNumberOfChannelsPerTDC is used in RegisterSlotNumber() function
25 // before one can access the real F1TDC configuration from CODA buffer.
26 // Thus, it is a constant value and is independent upon the real
27 // F1TDC configuration generally. However, Qweak uses only the Normal
28 // Resolution configuration. Thus, it is always 64 channels we uses.
29 // If someone wants to use the High Resolution Mode of F1TDC,
30 // it would be better to change this number to 32 by hand.
31 // Friday, September 3 13:31:06 EDT 2010, jhlee
32 
33 
35 
36 #define OK 0
37 
38 
39 QwDriftChamber::QwDriftChamber(const TString& name)
40  :VQwSubsystem(name),
42  fWireHits(fTDCHits)
43 {
44  fNumberOfTDCs = 0;
47 
52 }
53 
54 QwDriftChamber::QwDriftChamber(const TString& name, std::vector< QwHit > &fWireHits_TEMP)
55  :VQwSubsystem(name),
57  fWireHits(fWireHits_TEMP)
58 {
59  fNumberOfTDCs = 0;
62 
67 }
68 
70 {
71  delete fF1TDContainer;
72  delete fF1RefContainer;
73 }
74 
76 {
77 //Currently This routine is not in use the drift distance calculation is done at ProcessEvent() on each sub-class
78 // std::cout << "size: " << fWireHits.size() << std::endl;
79 
80  for (std::vector<QwHit>::iterator hit1=fWireHits.begin(); hit1!=fWireHits.end(); hit1++)
81  {
82  hit1->SetDriftDistance(
83  CalculateDriftDistance( hit1->GetTimeNs(), hit1->GetDetectorID() )
84  );
85  }
86  return;
87 }
88 
89 
90 Int_t QwDriftChamber::ProcessEvBuffer(const UInt_t roc_id,
91  const UInt_t bank_id,
92  UInt_t* buffer,
93  UInt_t num_words)
94 {
95 
96  Int_t bank_index = 0;
97  UInt_t tdc_data = 0;
98 
99  Bool_t data_integrity_flag = false;
100  Bool_t temp_print_flag = false;
101  // Int_t tdcindex = 0;
102 
103  bank_index = GetSubbankIndex(roc_id, bank_id);
104 
105 
106 
107 
108  if (bank_index>=0 && num_words>0) {
109  // We want to process this ROC. Begin looping through the data.
110  SetDataLoaded(kTRUE);
111 
112 
113  if (temp_print_flag ) {
114  std::cout << "QwDriftChamber::ProcessEvBuffer: "
115  << "Begin processing ROC"
116  << std::setw(2)
117  << roc_id
118  << " bank id "
119  << bank_id
120  << " Subbbank Index "
121  << bank_index
122  << " Region "
123  << GetSubsystemName()
124  << std::endl;
125  }
126 
127  //
128  // CheckDataIntegrity() do "counter" whatever errors in each F1TDC
129  // and check whether data is OK or not.
130 
131  data_integrity_flag = fF1TDContainer->CheckDataIntegrity(roc_id, buffer, num_words);
132  // if it is false (TFO, EMM, and SYN), the whole buffer is excluded for
133  // the further process, because of multiblock data transfer.
134 
135  if (data_integrity_flag) {
136 
137  for (UInt_t i=0; i<num_words ; i++) {
138 
139  // Decode this word as a F1TDC word.
140  fF1TDCDecoder.DecodeTDCWord(buffer[i], roc_id); // MQwF1TDC or MQwV775TDC
141 
142  // For MQwF1TDC, roc_id is needed to print out some warning messages.
143  // For MQwV775TDC, roc_id isn't necessary, thus I set roc_id=0 in
144  // MQwV775TDC.h (Mon May 3 12:32:06 EDT 2010 jhlee)
145 
146  Int_t tdc_slot_number = fF1TDCDecoder.GetTDCSlotNumber();
147  Int_t tdc_chan_number = fF1TDCDecoder.GetTDCChannelNumber();
148  Int_t tdcindex = GetTDCIndex(bank_index, tdc_slot_number);
149 
150  if ( tdc_slot_number == 31) {
151  // This is a custom word which is not defined in
152  // the F1TDC, so we can use it as a marker for
153  // other data; it may be useful for something.
154  }
155 
156  // Each subsystem has its own interesting slot(s), thus
157  // here, if this slot isn't in its slot(s) (subsystem map file)
158  // we skip this buffer to do the further process
159 
160  if (not IsSlotRegistered(bank_index, tdc_slot_number) ) continue;
161 
162  if(temp_print_flag) std::cout << fF1TDCDecoder << std::endl;
163 
164  if ( fF1TDCDecoder.IsValidDataword() ) {//;;
165  // if decoded F1TDC data has a valid slot, resolution locked, data word, no overflow (0xFFFF), and no fake data
166  // try get time and fill it into raw QwHit.. FillRawTDCWord function is in each subsystem.
167 
168  try {
169  tdc_data = fF1TDCDecoder.GetTDCData();
170  FillRawTDCWord(bank_index, tdc_slot_number, tdc_chan_number, tdc_data);
171  }
172  catch (std::exception& e) {
173  std::cerr << "Standard exception from QwDriftChamber::FillRawTDCWord: "
174  << e.what() << std::endl;
175  std::cerr << " Parameters: index==" <<bank_index
176  << "; GetF1SlotNumber()==" <<tdc_slot_number
177  << "; GetF1ChannelNumber()=="<<tdc_chan_number
178  << "; GetF1Data()==" <<tdc_data
179  << std::endl;
180  // Int_t tdcindex = GetTDCIndex(bank_index, tdc_slot_number);
181  std::cerr << " GetTDCIndex()=="<<tdcindex
182  << "; fTDCPtrs.at(tdcindex).size()=="
183  << fTDCPtrs.at(tdcindex).size()
184  << "; fTDCPtrs.at(tdcindex).at(chan).fPlane=="
185  << fTDCPtrs.at(tdcindex).at(tdc_chan_number).fPlane
186  << "; fTDCPtrs.at(tdcindex).at(chan).fElement=="
187  << fTDCPtrs.at(tdcindex).at(tdc_chan_number).fElement
188  << std::endl;
189  }
190  }//;;
191  } // for (UInt_t i=0; i<num_words ; i++) {
192  }
193 
194  }
195 
196  // fF1TDContainer-> PrintErrorSummary();
197  return OK;
198 }
199 
200 
201 
203 {
205  std::size_t i = 0;
206  for ( i=0; i<fTDC_Index.size(); i++){
207  fTDC_Index.at(i).clear();
208  }
209  fTDC_Index.clear();
210 
211  fTDCPtrs.clear();
212  fWireData.clear();
213  fNumberOfTDCs = 0;
214  return;
215 }
216 
217 Int_t QwDriftChamber::RegisterROCNumber(const UInt_t roc_id, const UInt_t bank_id)
218 {
219  Int_t status = 0;
220  status = VQwSubsystemTracking::RegisterROCNumber(roc_id, bank_id);
221  std::vector<Int_t> tmpvec(kMaxNumberOfSlotsPerROC,-1);
222  fTDC_Index.push_back(tmpvec);
223  // std::cout<<"Registering ROC "<<roc_id<<std::endl;
224 
225  return status;
226 }
227 
228 
229 Int_t QwDriftChamber::RegisterSubbank(const UInt_t bank_id)
230 {
231  Int_t stat = VQwSubsystem::RegisterSubbank(bank_id);
232  fCurrentBankIndex = GetSubbankIndex(VQwSubsystem::fCurrentROC_ID, bank_id);//subbank id is directly related to the ROC
237  }
238  std::vector<Int_t> tmpvec(kMaxNumberOfSlotsPerROC,-1);
239  fTDC_Index.push_back(tmpvec);
240  std::cout<< "RegisterSubbank()"
241  <<" ROC " << (VQwSubsystem::fCurrentROC_ID)
242  <<" Subbank "<<bank_id
243  <<" with BankIndex "<<fCurrentBankIndex<<std::endl;
244  return stat;
245 }
246 
247 
249 {
250  if (slot_id<kMaxNumberOfSlotsPerROC) {
251  // fCurrentBankIndex is unsigned int and always positive
252  if (/* fCurrentBankIndex >= 0 && */ fCurrentBankIndex <= fTDC_Index.size()) {
253  fTDCPtrs.resize(fNumberOfTDCs+1);
255  fNumberOfTDCs = fTDCPtrs.size();
256  fTDC_Index.at(fCurrentBankIndex).at(slot_id) = fNumberOfTDCs-1;
257  fCurrentSlot = slot_id;
259  }
260  }
261  else {
262  std::cerr << "QwDriftChamber::RegisterSlotNumber: Slot number "
263  << slot_id << " is larger than the number of slots per ROC, "
264  << kMaxNumberOfSlotsPerROC << std::endl;
265  }
266  return fCurrentTDCIndex;
267 
268 }
269 
270 Int_t QwDriftChamber::GetTDCIndex(size_t bank_index, size_t slot_num) const
271 {
272  Int_t tdcindex = -1;
273  // bank_index and slot_num are unsigned int and always positive
274  if (/* bank_index >= 0 && */ bank_index < fTDC_Index.size()) {
275  if (/* slot_num >= 0 && */ slot_num < fTDC_Index.at(bank_index).size()) {
276  tdcindex = fTDC_Index.at(bank_index).at(slot_num);
277  }
278  }
279  return tdcindex;
280 }
281 
282 
283 Int_t QwDriftChamber::LinkReferenceChannel (const UInt_t chan,const Int_t plane, const Int_t wire )
284 {
286  fReferenceChannels.at ( fCurrentBankIndex ).second = chan;
287  // Register a reference channel with the wire equal to the bank index.
288  fTDCPtrs.at ( fCurrentTDCIndex ).at ( chan ).fPackage = kPackageNull; //Should be OK?
289  fTDCPtrs.at ( fCurrentTDCIndex ).at ( chan ).fPlane = plane;
290  fTDCPtrs.at ( fCurrentTDCIndex ).at ( chan ).fElement = fCurrentBankIndex;
291  return OK;
292 }
293 
294 
295 
296 
298 {
299  std::size_t i = 0;
300  std::size_t j = 0;
301 
302  Int_t roc_num = 0;
303  Int_t bank_flag = 0;
304  Int_t bank_index = 0;
305  Int_t tdc_index = 0;
306 
307  UInt_t slot_id = 0;
308  UInt_t vme_slot_num = 0;
309 
310  std::cout << "QwDriftChamber Region : "
311  << this->GetSubsystemName()
312  << "::ReportConfiguration fTDCPtrs.size() "
313  << fTDCPtrs.size() << std::endl;
314 
315 
316  for ( i=0; i<fROC_IDs.size(); i++ )
317  {
318 
319  roc_num = fROC_IDs.at(i);
320 
321  for ( j=0; j<fBank_IDs.at(i).size(); j++ )
322  {
323 
324  bank_flag = fBank_IDs.at(i).at(j);
325  if(bank_flag == 0) continue;
326  // must be uncommented if one doesn't define "bank_flag" in a CRL file
327  // but, now we use "bank_flag" in our crl files, thus skip to print
328  // unnecessary things on a screen
329  // Monday, August 30 14:45:34 EDT 2010, jhlee
330 
331  bank_index = GetSubbankIndex(roc_num, bank_flag);
332 
333  std::cout << "ROC [index, Num]["
334  << i
335  << ","
336  << std::setw(2) << roc_num
337  << "]"
338  << " Bank [index,id]["
339  << bank_index
340  << ","
341  << bank_flag
342  << "]"
343  << std::endl;
344 
345  for ( slot_id=2; slot_id<kMaxNumberOfSlotsPerROC; slot_id++ )
346  {
347  // slot id starts from 2, because 0 and 1 are used for CPU and TI.
348  // Tuesday, August 31 10:57:07 EDT 2010, jhlee
349 
350  tdc_index = GetTDCIndex(bank_index, slot_id);
351 
352  vme_slot_num = slot_id;
353 
354  std::cout << " "
355  << "Slot [id, VME num] ["
356  << std::setw(2) << slot_id
357  << ","
358  << std::setw(2) << vme_slot_num
359  << "]";
360  if ( tdc_index == -1 ) {
361  std::cout << " "
362  << "Unused in VDC"
363  << std::endl;
364  }
365  else {
366  std::cout << " "
367  << "F1TDC index "
368  << tdc_index << std::endl;
369  }
370  }
371  }
372  }
373 
374  return;
375 }
376 
377 
378 
379 
380 
381 
382 
383 void QwDriftChamber::PrintConfigurationBuffer(UInt_t *buffer,UInt_t num_words)
384 {
385  UInt_t ipt = 0;
386  UInt_t j = 0;
387  UInt_t k = 0;
388 
389  for ( j=0; j<(num_words/5); j++ )
390  {
391  printf ( "buffer[%5d] = 0x:", ipt );
392  for ( k=j; k<j+5; k++ ) {
393  printf ( "%12x", buffer[ipt++] );
394  }
395  printf ( "\n" );
396  }
397 
398  if ( ipt<num_words ) {
399  printf ( "buffer[%5d] = 0x:", ipt );
400  for ( k=ipt; k<num_words; k++ )
401  {
402  printf ( "%12x", buffer[ipt++] );
403  }
404  printf ( "\n" );
405  }
406  printf ( "\n" );
407 
408  return;
409 }
410 
411 
412 
413 Int_t QwDriftChamber::ProcessConfigurationBuffer (const UInt_t roc_id,
414  const UInt_t bank_id,
415  UInt_t* buffer,
416  UInt_t num_words)
417 {
418 
419  TString subsystem_name;
420 
421  Int_t bank_index = 0;
422  Int_t tdc_index = 0;
423  UInt_t slot_id = 0;
424  UInt_t vme_slot_num = 0;
425 
426  QwF1TDC *local_f1tdc = NULL;
427 
428  bank_index = GetSubbankIndex(roc_id, bank_id);
429 
430  if(bank_index >=0) {
432  std::cout << "fF1TDContainer " << fF1TDContainer
433  <<" local_f1tdc " << local_f1tdc << "\n";
434  }
435  subsystem_name = this->GetSubsystemName();
436  fF1TDContainer -> SetSystemName(subsystem_name);
437  fF1RefContainer-> SetSystemName(subsystem_name);
438 
440  std::cout << "-----------------------------------------------------" << std::endl;
441 
442  std::cout << "\nQwDriftChamber : "
443  << subsystem_name
444  << ", "
445  << "ProcessConfigurationBuffer"
446  << std::endl;
447  std::cout << "ROC "
448  << std::setw(2) << roc_id
449  << " Bank [index,id]["
450  << bank_index
451  << ","
452  << bank_id
453  << "]"
454  << std::endl;
455  }
456  for ( slot_id=0; slot_id<kMaxNumberOfSlotsPerROC; slot_id++ )
457  {
458  // slot id starts from 2, because 0 is one offset (1) difference between QwAnalyzer and VME definition,
459  // and 1 and 2 are used for CPU and TI. Tuesday, August 31 10:57:07 EDT 2010, jhlee
460 
461  tdc_index = GetTDCIndex(bank_index, slot_id);
462  vme_slot_num = slot_id;
464  std::cout << " "
465  << "Slot [id, VME num] ["
466  << std::setw(2) << slot_id
467  << ","
468  << std::setw(2) << vme_slot_num
469  << "]";
470  std::cout << " ";
471  }
472  local_f1tdc = NULL;
473 
474  if(slot_id > 2) { // save time
475 
476  if (tdc_index not_eq -1) {
477 
478  if(local_f1tdc) delete local_f1tdc; local_f1tdc = NULL;
479 
480  local_f1tdc = new QwF1TDC(roc_id, vme_slot_num);
481 
482  local_f1tdc->SetF1BankIndex(bank_index);
483  local_f1tdc->SetF1TDCIndex(tdc_index);
484  local_f1tdc->SetF1TDCBuffer(buffer, num_words);
485  local_f1tdc->SetF1SystemName(subsystem_name);
486 
487  fF1TDContainer->AddQwF1TDC(local_f1tdc);
489  std::cout << "F1TDC index "
490  << std::setw(2)
491  << tdc_index
492  << std::setw(16)
493  << " local_f1tdc "
494  << *local_f1tdc
495  << " at "
496  << local_f1tdc;
497  }
498  }
499  else {
501  std::cout << "Unused in "
502  << std::setw(4)
503  << subsystem_name
504  << std::setw(16)
505  << " local_f1tdc at "
506  << local_f1tdc;
507  }
508  }
509 
510  }
511  else { // slot_id == only 0, 1, & 2
513  if (slot_id == 0) std::cout << " ";
514  else if (slot_id == 1) std::cout << "MVME CPU ";
515  else std::cout << "Trigger Interface"; // slot_id == 2;
516  }
517  }
519  std::cout << std::endl;
520  }
521  }
522 
524 
526  std::cout << "-----------------------------------------------------" << std::endl;
527 
528 
529  // kMaxNumberOfChannelsPerTDC = fF1TDContainer->GetF1TDCChannelNumber();
530 
531  return OK;
532  }
533  else {
534  /// local_f1tdc = 0;
535  return -1;
536  }
537 }
538 
539 
540 void
542 {
543  fF1RefContainer -> PrintCounters();
544  fF1TDContainer -> PrintErrorSummary();
545  fF1TDContainer -> WriteErrorSummary();
546  return;
547 };
Int_t GetSubbankIndex() const
Definition: VQwSubsystem.h:303
std::vector< std::vector< Int_t > > fTDC_Index
void AddQwF1TDC(QwF1TDC *in)
std::vector< std::vector< Double_t > > fReferenceMaster
size_t fCurrentBankIndex
Name of this subsystem (the region).
F1TDCs configuration and reference siganls container.
void SetF1TDCBuffer(UInt_t *buffer, UInt_t num_words)
const UInt_t & GetTDCMaxChannels() const
Definition: MQwF1TDC.h:50
void PrintConfigurationBuffer(UInt_t *buffer, UInt_t num_words)
void InitHistogramPointers()
void ClearAllBankRegistrations()
static const UInt_t kMaxNumberOfSlotsPerROC
const UInt_t & GetTDCData() const
Definition: MQwF1TDC.h:49
one F1TDC configuration and reference signal(s) holder
static const double e
Definition: QwUnits.h:91
static const Int_t kCodaMasterPlaneNumber
Bool_t CheckDataIntegrity(const UInt_t roc_id, UInt_t *buffer, UInt_t num_words)
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...
Int_t ProcessConfigurationBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
static bool fPrintF1TDCConfiguration
const UInt_t & GetTDCSlotNumber() const
Definition: MQwF1TDC.h:44
const UInt_t & GetTDCChannelNumber() const
Definition: MQwF1TDC.h:45
A logfile class, based on an identical class in the Hermes analyzer.
Int_t LinkReferenceChannel(const UInt_t chan, const Int_t plane, const Int_t wire)
std::vector< std::vector< QwDetectorID > > fTDCPtrs
std::vector< std::pair< Int_t, Int_t > > fReferenceChannels
QwDriftChamber()
Private default constructor (not implemented, will throw linker error on use)
Double_t DoneF1TDCsConfiguration()
UInt_t kMaxNumberOfChannelsPerTDC
QwF1TDContainer * fF1TDContainer
Bool_t IsValidDataword() const
Definition: MQwF1TDC.cc:328
The pure virtual base class of all subsystems.
Definition: VQwSubsystem.h:59
#define OK
void SetF1BankIndex(const Int_t bank_index)
const MQwF1TDC GetF1TDCDecoder() const
virtual Double_t CalculateDriftDistance(Double_t drifttime, QwDetectorID detector)=0
void SetF1SystemName(const TString name)
std::vector< std::vector< Double_t > > fReferenceData
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 RegisterSubbank(const UInt_t bank_id)
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 ReportConfiguration()
Int_t GetTDCIndex(size_t bank_index, size_t slot_num) const
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)
Int_t RegisterSlotNumber(const UInt_t slot_id)
static const Int_t kReferenceChannelPlaneNumber
An options class which parses command line, config file and environment.
virtual ~QwDriftChamber()
Virtual destructor.
Bool_t IsSlotRegistered(Int_t bank_index, Int_t slot_num) const
std::vector< QwHit > & fWireHits
MQwF1TDC fF1TDCDecoder
void Print(const Option_t *options=0) const
void DecodeTDCWord(UInt_t &word, const UInt_t roc_id)
Definition: MQwF1TDC.cc:84
void FillDriftDistanceToHits()
virtual void FillRawTDCWord(Int_t bank_index, Int_t slot_num, Int_t chan, UInt_t data)=0
void ClearAllBankRegistrations()
Clear all registration of ROC and Bank IDs for this subsystem.
void FillHardwareErrorSummary()
Hardware error summary.
TString GetSubsystemName() const
Definition: VQwSubsystem.h:93
Int_t RegisterROCNumber(const UInt_t roc_id, const UInt_t bank_id)
Tell the object that it will decode data from this ROC and sub-bank.
F1TDCReferenceContainer * fF1RefContainer
std::vector< std::vector< QwDetectorInfo > > fWireData
void SetDataLoaded(Bool_t flag)
Definition: VQwSubsystem.h:305