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