BOSS 7.1.1
BESIII Offline Software System
Loading...
Searching...
No Matches
ZddReconAlg.cxx
Go to the documentation of this file.
3#include "ZddEvent/ZddBoard.h"
7#include "GaudiKernel/MsgStream.h"
8#include "GaudiKernel/SmartDataPtr.h"
9
10using namespace std;
11
12DECLARE_COMPONENT(ZddReconAlg)
13/////////////////////////////////////////////////////////////////////////////
14
15ZddReconAlg::ZddReconAlg(const std::string& name, ISvcLocator* pSvcLocator) :
16 Algorithm(name, pSvcLocator),
17 m_errStat(false)
18{
19 declareProperty("BreakWithError", m_errQuit = true);
20}
21
22// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
24{
25 MsgStream log(msgSvc(), name());
26 log << MSG::INFO << "in initialize()" << endreq;
27
28 return StatusCode::SUCCESS;
29}
30
31// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
33{
34 MsgStream log(msgSvc(), name());
35 log << MSG::INFO << "in execute()" << endreq;
36
37 // Part 1: Get the event header, print out event and run number
38 SmartDataPtr<Event::EventHeader> eventHeader(eventSvc(),"/Event/EventHeader");
39 if (!eventHeader) {
40 log << MSG::FATAL << "Could not find Event Header" << endreq;
41 return StatusCode::FAILURE;
42 }
43 log << MSG::DEBUG << "Retrieved event: " << eventHeader->eventNumber()
44 << " run: " << eventHeader->runNumber() << endreq;
45
46 // Part 2: Register RecZddChannel to TDS
47 DataObject* aRecEvent = 0;
48 eventSvc()->findObject("/Event/Recon", aRecEvent);
49 if ( aRecEvent == 0 ) {
50 aRecEvent = new ReconEvent();
51 StatusCode sc = eventSvc()->registerObject("/Event/Recon", aRecEvent);
52 if ( sc.isFailure() ) {
53 log << MSG::FATAL << "Could not register ReconEvent" << endreq;
54 return StatusCode::FAILURE;
55 }
56 }
57
58 RecZddChannelCol* recZddCol = new RecZddChannelCol;
59 StatusCode sc = eventSvc()->registerObject(EventModel::Recon::RecZddChannelCol, recZddCol);
60 if ( sc.isFailure() ) {
61 log << MSG::FATAL << "Could not register RecZddChannelCol" << endreq;
62 return StatusCode::FAILURE;
63 }
64
65 // Part 3: check the ZDD data
66 // 3.1: some errors happened before, ignore the rest calculations
67 if ( m_errStat ) return StatusCode::SUCCESS;
68
69 // 3.2: check the status of the current ZDD event
70 SmartDataPtr<Event::ZddEvent> zddEvt(eventSvc(),"/Event/ZddEvent");
71 int zddCheck = zddDataStat(zddEvt.ptr(), eventHeader->eventNumber()+1);
72
73 if ( zddCheck != 0 ) {
74 if ( zddCheck < 0 ) {
75 // serious error happened, ignore all of the rest ZDD data
76 m_errStat = true;
77
78 if ( m_errQuit ) { // whether to break the data processing
79 return StatusCode::FAILURE;
80 }
81 }
82 // else:
83 // problems in the current event, only ignore this event
84 return StatusCode::SUCCESS;
85 }
86
87 // Part 4: Get event T0
88 double bes3_t0 = -10000.0;
89 SmartDataPtr<RecEsTimeCol> evTimeCol(eventSvc(), "/Event/Recon/RecEsTimeCol");
90 if ( !evTimeCol || evTimeCol->size() == 0 ) {
91 log << MSG::WARNING << " Could not find RecEsTimeCol" << endreq;
92 //return StatusCode::SUCCESS;
93 }
94 else {
95 RecEsTimeCol::iterator iter_evt = evTimeCol->begin();
96 if (iter_evt != evTimeCol->end()) {
97 bes3_t0 = (*iter_evt)->getTest();
98 //std::cout << "BESIII t0: " << bes3_t0 << std::endl; //wangyadi
99 bes3_t0 = 6400 - bes3_t0; // T_L1 - T_collision
100 }
101 }
102
103 // Part 5: ZDD data processing
104 const Event::ZddEvent::Channels& chs = zddEvt->channels();
105 //cout << "ZDD has n channel: " << chs.size() << endl;
106 // loop the channels
107 Event::ZddEvent::Channels::const_iterator end_ch = chs.end();
108 for ( Event::ZddEvent::Channels::const_iterator it = chs.begin(); it != end_ch; ++it ) {
109 const ZddChannel* pch = *it;
110 const ZddChannel::Fragments& frags = pch->fragments();
111 //cout << "Channel " << pch->getChId() << " has " << frags.size() << " fragments: " << endl;
112
113 RecZddChannel* recZddCh = new RecZddChannel;
114 recZddCh->setChannelId(pch->getChId());
115 recZddCh->setScanCode(pch->getScanCode());
116 double e_K = getEK(pch->getChId());
117
118 // loop the fragments, rebuild the original channel waveform into one buffer
119 int maxSamples = 800; // This value may change!
120 unsigned char waveform[800];
121 memset(waveform, 0, maxSamples);
122 ZddChannel::Fragments::const_iterator end_fg = frags.end();
123 bool quit_event = false;
124 int start = 0;
125 for ( ZddChannel::Fragments::const_iterator jt = frags.begin(); jt != end_fg; ++jt) {
126 const ZddFragment& frag = *jt;
127 //cout << "\tindex from " << frag.start_index << ",\t length " << frag.length << ":\t ";
128 //for ( int i = 0; i < frag.length; ++i ) {
129 // cout << int(frag.sample[i]) << " ";
130 //}
131 //cout << endl;
132 start = frag.start_index;
133
134 // check for CAEN data corruption ( absent from 2013 onward ?? )
135 if ( start+frag.length > maxSamples ) {
136 recZddCh->setScanCode( 2*10 + pch->getScanCode() );
137 MsgStream log(msgSvc(), name());
138 log << MSG::ERROR << "ZDD BAD DATA: CAEN corruption problem" << endreq;
139 quit_event = true; // abandon this event...
140 break; // ...starting from this channel
141 }
142
143 for ( int i = 0; i < frag.length; ++i ) waveform[start++] = frag.sample[i];
144 }
145
146 // then reclusterize with a slightly higher threshold
147 unsigned char threshold = 20; // threshold for reclustering
148 unsigned char rephaseThreshold = 40; // threshold for waveform rephasing
149 unsigned char minSample = 255, maxSample = -1;
150 int maxTime = -1;
151 bool closed = true; // no cluster is running yet
152 int phases[4] = {-1,-1,-1,-1}; // a 4-channel histogram
153 for ( int pt=0; pt<maxSamples; pt++ ) {
154 bool notZero = waveform[pt]>0;
155 bool smaller = waveform[pt] < minSample;
156 if ( notZero && smaller ) minSample = waveform[pt]; // find baseline for whole channel
157 if ( waveform[pt] > threshold ) {
158 if ( closed ) { // start a new cluster, initialize max and index
159 closed = false;
160 maxSample = waveform[pt];
161 maxTime = pt;
162 } else { // continue the old cluster, update max and index
163 if ( waveform[pt] > maxSample ) {
164 maxSample = waveform[pt];
165 maxTime = pt;
166 }
167 }
168 } else {
169 if ( ! closed ) { // close the old cluster and store it
170 closed = true;
171 double tNsec = 2.*maxTime;
172 recZddCh->addFragment(tNsec, maxSample*e_K); // time relative to start of FADC window
173 // std::cout << " ZDD E & T: " << int(maxSample) << ", " << maxTime << std::endl;
174 if ( maxSample > rephaseThreshold ) { // most peaks are at multiples of 8ns
175 int phase = maxTime%4; // only one of these bins will be most used
176 phases[phase]++; // but we do not know which one yet
177 }
178 }
179 }
180 }
181 if ( ! closed ) { // close and store the last cluster if still running
182 closed = true;
183 double tNsec = 2.*maxTime; // time relative to start of FADC window
184 recZddCh->addFragment(tNsec, maxSample*e_K);
185 // std::cout << " ZDD E & T: " << int(maxSample) << ", " << maxTime << std::endl;
186 if ( maxSample > rephaseThreshold ) {
187 int phase = maxTime%4;
188 phases[phase]++;
189 }
190 }
191
192 // Compute channel phase
193 int mostProb = -1;
194 int chPhase = -1;
195 for (int ph=0; ph<4; ph++) {
196 if ( phases[ph] > mostProb ) {
197 mostProb = phases[ph];
198 chPhase = ph;
199 }
200 }
201
202 if ( chPhase==-1 ) {// mark channel as not rephasable (no samples above rephaseThreshold)
203 recZddCh->setScanCode( 3*10 + pch->getScanCode() );
204 chPhase = -2;
205 }
206
207 recZddCh->setBaseLine(minSample);
208 recZddCh->setPhase(chPhase);
209 recZddCol->push_back(recZddCh);
210
211/* Previous code, left for reference
212 // loop the fragments
213 ZddChannel::Fragments::const_iterator end_fg = frags.end();
214 for ( ZddChannel::Fragments::const_iterator jt = frags.begin(); jt != end_fg; ++jt) {
215 const ZddFragment& frag = *jt;
216 int efrag = -1, tfrag = -1;
217 calFragEandT(frag, efrag, tfrag);
218 recZdd->addFragment(bes3_t0-tfrag, efrag*e_K);
219 }
220*/
221
222 if ( quit_event ) break; // abandon the event entirely after a CAEN data corruption instance
223
224 } // end of loop on channels
225 return StatusCode::SUCCESS;
226}
227
228// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
230{
231 MsgStream log(msgSvc(), name());
232 log << MSG::INFO << "in finalize()" << endreq;
233
234 return StatusCode::SUCCESS;
235}
236
237double ZddReconAlg::getEK(int chId)
238{
239 return 1.0/16.0;
240}
241
242int ZddReconAlg::zddDataStat(const Event::ZddEvent* zddEvt, int evtId)
243{
244 MsgStream log(msgSvc(), name());
245
246 if ( !zddEvt ) {
247 log << MSG::FATAL << "Could not find ZddEvent" << endreq;
248 return 1; /*-1;*/
249 }
250
251 // check the ZDD trigger number
252 const std::vector<ZddBoard*>& boards = zddEvt->boards();
253 if ( boards.size() != 2 ) {
254 log << MSG::FATAL << "incomplete ZDD data, no more ZDD data this run!" << endreq;
255 return -2;
256 }
257
258 if ( boards[0]->getCounter() != evtId || boards[1]->getCounter() != evtId )
259 {
260 log << MSG::FATAL << "missaligned ZDD triggers, no more ZDD data this run!" << endreq;
261 return -3;
262 }
263
264/* This check is not useful anymore
265 // check the Trigger Time Tag
266 static unsigned int bd1_tt = boards[0]->getTimeTag() - 1026;
267 static unsigned int bd2_tt = boards[1]->getTimeTag() - 1026;
268
269 unsigned int tt0 = bd1_tt;
270 unsigned int tt1 = bd2_tt;
271 bd1_tt = boards[0]->getTimeTag();
272 bd2_tt = boards[1]->getTimeTag();
273
274 if ( tt0 > bd1_tt ) tt0 -= 0x80000000;
275 if ( tt1 > bd2_tt ) tt1 -= 0x80000000;
276
277 if ( (bd1_tt-tt0) < 1026 || (bd2_tt-tt1) < 1026 ) {
278 log << MSG::INFO << "overlaped ZDD triggers" << endreq;
279 return 1;
280 }
281*/
282 return 0;
283}
284
285// This code will be needed when we finally have a calibration
286int ZddReconAlg::calFragEandT(const ZddFragment& frag, int& efrag, int& tfrag)
287{
288 int minIndex = 0;
289 unsigned char min = 255, max = 0;
290 for ( int i = 0; i < frag.length; ++i ) {
291 unsigned char& sample = frag.sample[i];
292 if ( sample < min ) {
293 min = sample;
294 minIndex = i;
295 }
296 if ( sample > max ) {
297 max = sample;
298 }
299 }
300
301 efrag = max - min;
302 tfrag = 8160 - 2 * (minIndex + frag.start_index);
303
304 return 0;
305}
ObjectVector< RecZddChannel > RecZddChannelCol
IMessageSvc * msgSvc()
std::vector< ZddChannel * > Channels
Definition ZddEvent.h:19
const Boards & boards() const
Definition ZddEvent.h:29
void setBaseLine(int baseLine)
void setPhase(int phase)
void setScanCode(int scanCode)
void setChannelId(int chId)
void addFragment(int time, float energy)
int getScanCode() const
Definition ZddChannel.h:28
const Fragments & fragments() const
Definition ZddChannel.h:30
int getChId() const
Definition ZddChannel.h:26
std::vector< ZddFragment > Fragments
Definition ZddChannel.h:21
StatusCode execute()
StatusCode finalize()
StatusCode initialize()
_EXTERN_ std::string RecZddChannelCol
Definition EventModel.h:108
int start_index
Definition ZddChannel.h:8
unsigned char * sample
Definition ZddChannel.h:10