AlcapDAQ  1
TWFDBankReader.cpp
Go to the documentation of this file.
1 #include "TWFDBankReader.h"
2 #include <stdlib.h>
3 using std::string;
4 #include <iostream>
5 using std::cerr; using std::cout; using std::endl;
6 
7 extern TPC_PARAM tpc_parameters;
8 
9 // There's no point in making an empty reader.
11 {
12  cerr << "TWFDBankReader: Error! Do not use default constructor." << endl;
13  exit(1);
14 }
15 
17  Int_t personality,
18  string bankname)
19  : fDBC(dbc), fPersonality(personality), fBankName(bankname),
20  fBankPtr(NULL), fEventPtr(NULL), fSize(0), fNRequestedWords(0),
21  fNReceivedWords(0), fStatus(0), fIsOK(true), fNBlocks(0)
22 {}
23 
24 Int_t TWFDBankReader::GetDBC() { return fDBC; }
27 Int_t TWFDBankReader::GetNIslands() { return fData.size(); }
29 
31 inline Int_t TWFDBankReader::GetBlockLength_Words() { return 2*fDBC + 2; }
32 
34 inline Int_t TWFDBankReader::GetNBlockSamples() { return 8*fDBC; }
35 
39 
43 TWFDRawIsland& TWFDBankReader::at(int index){ return fData.at(index); }
44 
45 void TWFDBankReader::ProcessEvent(EVENT_HEADER* pheader, void *pevent)
46 {
47  ClearEvent(); // reset everything to zero at the beginning of each event
48  fEventPtr = pevent;
49 
50  if(fPersonality != 2) { //MuCap mode is 2
51  cerr << "TWFDBankReader::ProcessEvent() Error! WFD personalities other"
52  << " than 2 (MuCap mode) have not been implemented. Skipping bank:\n"
53  << "\t" << fBankName
54  << endl;
55  fIsOK = false;
56  return;
57  }
58  fSize = bk_locate(fEventPtr, fBankName.c_str(), &fBankPtr);
59  if(fBankPtr == NULL) {
60  cerr << "TWFDBankReader::ProcessEvent() Error! Bank not found:"
61  << "\t" << fBankName
62  << endl;
63  fIsOK = false;
64  return;
65  }
66 
67  //Read status words
68  if(fSize < 3) { // There are 3 status words
69  cerr << "TWFDBankReader::ProcessEvent() Error? Bank size < 3 words"
70  << "\tfor bank: " << fBankName
71  << endl;
72  fIsOK = false; return;
73  }
74  fNRequestedWords = Int_t(fBankPtr[0]); // unsigned to signed cast.
75  fNReceivedWords = Int_t(fBankPtr[1]);
76  fStatus = Int_t(fBankPtr[2]);
77 
78  if( !CheckStatus() ) return; // CheckStatus returns false if bank is corrupt
79 
81 
82  if( !ReadIslandsLoop() ) return; // ReadIslandsLoop returns false on failure
83 
84  //And we're done!
85 }
86 
91 {
92  if( fNRequestedWords == 0 ) {
93  cerr << "TWFDBankReader::ProcessEvent() Error? WFD Requested words = 0"
94  << "\tfor bank: " << fBankName << "\n"
95  << "\tSkipping bank."
96  << endl;
97  fIsOK = false; return false;
98  }
99  if( fNRequestedWords >= 0x00100000 ) {
100  cerr << "TWFDBankReader::ProcessEvent() Error? WFD Requested words "
101  << " > 0x00100000."
102  << "\tfor bank: " << fBankName << "\n"
103  << "\tSkipping bank."
104  << endl;
105  fIsOK = false; return false;
106  }
107  if( fNRequestedWords != fNReceivedWords || fStatus!=0 ) {
108  cerr << "TWFDBankReader::ProcessEvent() Error! WFD Requested words != "
109  << "WFD received words for bank: " << fBankName << "\n"
110  << "Requested: " << fNRequestedWords << " Received: "
111  << fNReceivedWords << " Status: " << fStatus << "\n"
112  << "\tSkipping bank."
113  << endl;
114  fIsOK = false; return false;
115  }
116  // Check that the size of the bank is a multiple of the block size
117  // (plus 4 status words).
118  if( (fSize-4) % GetBlockLength_Words() !=0 ) {
119  cerr << "TWFDBankReader::ProcessEvent() Error! Bank size ("
120  << fSize-4 << ") is not a multiple "
121  << "of WFD block length (" << GetBlockLength_Words() << ") "
122  << "\tfor bank: " << fBankName << "\n"
123  << "\tSkipping bank."
124  << endl;
125  fIsOK=false; return false;
126  }
127  return true;
128 }
129 
134 {
135  //pointer to beginning of wfd block data
136  DWORD* pDataPtr = fBankPtr+3;
137  int nBlocksRead = 0;
138  int blockoffset = 0; // offset to pDataPtr for the current block
139  int blocktime = 0; // time of current block
140  int conttime = -1; // GetNBlockSamples after the last island's time
141  while( nBlocksRead<fNBlocks ){
142  // offset for pDataPtr
143  blockoffset = nBlocksRead*GetBlockLength_Words();
144  // time is at the end of the adc samples
145  blocktime = pDataPtr[blockoffset+GetBlockLength_Words()-1] & 0xEFFFFFFF;
146  // conttime is the time of a potential continuation island
147  conttime = fData.empty() ? -1 : fData.back().fTime+fData.back().fADC.size();
148  // New island for first guy or if it's a new trigger
149  if(nBlocksRead==0 || blocktime > conttime) {
150  fData.push_back( TWFDRawIsland() ); // make a new island
151  fData.back().fTime = blocktime; // set the new island's time
152  } else if( blocktime < conttime ){
153  cerr << "TWFDBankReader::ReadIslandsLoop() Error! Block has time: "
154  << blocktime << " which is less than " << fData.back().fADC.size()
155  << " clock ticks after the last block at "
156  << fData.back().fTime << "\n"
157  << "Skipping Bank " << fBankName
158  << endl;
159  fIsOK=false; return false;
160  } // Otherwise, it must be a continuation, so don't append to fData
161 
162  // At this point, the last island in fData is the one we should add too.
163  std::vector<UChar_t>& rVec = fData.back().fADC; // local reference
164  // Set a 1-byte pointer at the beginning of the new block's samples
165  UChar_t* adc = (UChar_t*)&pDataPtr[blockoffset];
166  for(int iadc=0; iadc<GetNBlockSamples(); iadc++) {
167  /* WFD banks store samples non-sequentially. The samples within
168  * each word are reversed:
169  * |DWORD |DWORD |DWORD
170  * Bank: |3|2|1|0|7|6|5|4|11|10|...
171  *
172  * where |0| is the first sample, |1| is the second, etc.
173  * the function (3-iadc%4) + 4*(iadc/4) reproduces this encoding.
174  */
175  rVec.push_back( adc[ (3-iadc%4) + 4*(iadc/4) ] );
176  /* cout << "Set sample " << rVec.size() << " to "
177  << "adc[" << (3-iadc%4) + 4*(iadc/4) << "] = "
178  << int(adc[ (3-iadc%4) + 4*(iadc/4) ])
179  << endl; */ // In case you want to look at what's happening
180  }
181 
182  // update loop variable
183  nBlocksRead++;
184  } // end while
185 }
186 
192 {
193  fData.clear();
194  fSize = 0;
195  fBankPtr = NULL;
196  fEventPtr = NULL;
197  fNRequestedWords = 0;
198  fNReceivedWords = 0;
199  fStatus = 0;
200  fIsOK = true;
201  fNBlocks = 0;
202 }