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