BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
MdcMergeDups.cxx
Go to the documentation of this file.
1//--------------------------------------------------------------------------
2// File and Version Information:
3// $Id: MdcMergeDups.cxx,v 1.4 2022/06/28 01:30:15 zhangy Exp $
4//
5// Description:
6// Class MdcMergeDups is to be merge duplicated track in MDC.
7//
8// Environment:
9// Software developed for the BESIII Detector at the BEPCII.
10//
11// Author List:
12// Zhang Yao(zhangyao@ihep.ac.cn) Migrate to BESIII
13// Yoshi Iwasaki(yoshihito.iwasaki@kek.jp) Overlap method
14// Jia Lukui(jialk@ihep.ac.cn) Optimized overlap
15//
16// Copyright Information:
17// Copyright (C) 2009 IHEP
18//
19// History:
20// Zhang Yao 2009-10-30
21// Migration BELLE TTrackManager::merge() for BESIII MDC
22//
23//------------------------------------------------------------------------
24
25//-----------------------
26// This Class's Header --
27//-----------------------
28#include "MdcMergeDups.h"
29#include "EvTimeEvent/RecEsTime.h"
30#include "EventModel/EventHeader.h"
31// #include "GaudiKernel/AlgFactory.h"
32#include "GaudiKernel/DataSvc.h"
33#include "GaudiKernel/IDataManagerSvc.h"
34#include "GaudiKernel/IDataProviderSvc.h"
35#include "GaudiKernel/ISvcLocator.h"
36#include "GaudiKernel/MsgStream.h"
37#include "GaudiKernel/PropertyMgr.h"
38#include "GaudiKernel/SmartDataPtr.h"
39#include "Identifier/Identifier.h"
40#include "Identifier/MdcID.h"
41#include "MagneticFieldSvc/IBesMagFieldSvc.h"
42#include "MdcCalibFunSvc/IMdcCalibFunSvc.h"
43#include "MdcData/MdcHitMap.h"
44#include "MdcData/MdcHitOnTrack.h"
45#include "MdcData/MdcHitUse.h"
46#include "MdcData/MdcRecoHitOnTrack.h"
47#include "MdcGeom/Constants.h"
48#include "MdcRecEvent/RecMdcHit.h"
49#include "MdcTrkRecon/MdcTrack.h"
50#include "TrkBase/TrkErrCode.h"
51#include "TrkBase/TrkExchangePar.h"
52#include "TrkBase/TrkFit.h"
53#include "TrkBase/TrkHitList.h"
54#include "TrkBase/TrkRecoTrk.h"
55#include "TrkFitter/TrkContextEv.h"
56#include "TrkFitter/TrkHelixMaker.h"
57
59MdcMergeDups::MdcMergeDups( const std::string& name, ISvcLocator* pSvcLocator )
60 : Algorithm( name, pSvcLocator ) {
61 declareProperty( "debug", m_debug = 0 );
62 // cuts for mergeDups()
63 declareProperty( "maxDd0InMerge", m_maxDd0InMerge = 2.7 );
64 declareProperty( "maxDphi0InMerge", m_maxDphi0InMerge = 0.15 );
65 declareProperty( "maxDPdradInMerge", m_maxPdradInMerge = 0.22 );
66 declareProperty( "maxRcsInMerge", m_maxRcsInMerge = 18. );
67 // cuts for mergeCurl()
68 declareProperty( "mergePt", m_mergePt = 0.13 );
69 declareProperty( "mergeLoadAx", m_mergeLoadAx = 3. );
70 declareProperty( "mergeLoadSt", m_mergeLoadSt = 4. );
71 declareProperty( "mergeOverlapRatio", m_mergeOverlapRatio = 0.7 );
72}
73
74//--------------
75// Destructor --
76//--------------
77MdcMergeDups::~MdcMergeDups() { delete m_bfield; }
78
80 // Detector geometry
81 m_gm = MdcDetector::instance();
82 if ( NULL == m_gm ) return StatusCode::FAILURE;
83 return StatusCode::SUCCESS;
84}
85
86//--------------
87// Operations --
88//--------------
90 MsgStream log( msgSvc(), name() );
91 log << MSG::INFO << "in initialize()" << endmsg;
92 StatusCode sc;
93
94 // Initailize magnetic filed
95 IBesMagFieldSvc* m_pIMF;
96 sc = service( "MagneticFieldSvc", m_pIMF );
97 if ( sc != StatusCode::SUCCESS )
98 {
99 log << MSG::ERROR << "Unable to open Magnetic field service" << endmsg;
100 return StatusCode::FAILURE;
101 }
102 m_bfield = new BField( m_pIMF );
103
104 return StatusCode::SUCCESS;
105}
106
108 if ( !m_beginRun )
109 {
110 StatusCode sc = beginRun();
111 if ( sc.isFailure() )
112 {
113 error() << "beginRun failed" << endmsg;
114 return StatusCode::FAILURE;
115 }
116 m_beginRun = true;
117 }
118
119 MsgStream log( msgSvc(), name() );
120 log << MSG::INFO << "in execute()" << endmsg;
121 setFilterPassed( false );
122
123 m_bunchT0 = -999.;
124 SmartDataPtr<RecEsTimeCol> aevtimeCol( eventSvc(), "/Event/Recon/RecEsTimeCol" );
125 if ( !aevtimeCol || aevtimeCol->size() == 0 )
126 {
127 log << MSG::WARNING << " Could not find RecEsTimeCol" << endmsg;
128 return StatusCode::SUCCESS;
129 }
130
131 RecEsTimeCol::iterator iter_evt = aevtimeCol->begin();
132 for ( ; iter_evt != aevtimeCol->end(); iter_evt++ ) { m_bunchT0 = ( *iter_evt )->getTest(); }
133
134 int nMerged = mergeCurl();
135
136 if ( m_debug > 0 )
137 {
138 std::cout << name() << ": Merged " << nMerged << " track " << std::endl;
140 }
141
142 return StatusCode::SUCCESS;
143}
144
146 MsgStream log( msgSvc(), name() );
147 log << MSG::INFO << "in finalize()" << endmsg;
148
149 return StatusCode::SUCCESS;
150}
151
152//-------------------------------------------------------------------
154 //-------------------------------------------------------------------
155
156 SmartDataPtr<RecMdcTrackCol> trackList( eventSvc(), EventModel::Recon::RecMdcTrackCol );
157 if ( !trackList ) return -1;
158
159 int needMerge = 0;
160
161 //...Merging. Search a track to be merged...
162 RecMdcTrackCol::iterator iterRefTk = trackList->begin();
163 for ( ; iterRefTk != trackList->end(); iterRefTk++ )
164 {
165 RecMdcTrack* refTk = *iterRefTk;
166 if ( refTk->stat() < 0 ) continue;
167 std::vector<RecMdcTrack*> mergeTkList;
168 mergeTkList.push_back( refTk );
169
170 bool curl = false;
171 int sameParm = 0;
172 RecMdcTrackCol::iterator iterTestTk = trackList->begin();
173 for ( ; iterTestTk != trackList->end(); iterTestTk++ )
174 {
175 RecMdcTrack* testTk = *iterTestTk;
176 if ( iterRefTk == iterTestTk || ( testTk->stat() < 0 ) ) continue;
177
178 //-- overlapRatio cut 0.7 by jialk, original is 0.8
179 if ( testByOverlapHit( refTk, testTk ) )
180 {
181 if ( m_debug > 0 )
182 std::cout << __FILE__ << " overlape tk:" << refTk->trackId() << " with "
183 << testTk->trackId() << std::endl;
184 mergeTkList.push_back( testTk );
185 curl = true;
186 }
187 sameParm = testByParam( refTk, testTk );
188 if ( sameParm > 0 )
189 {
190 if ( m_debug > 0 )
191 std::cout << __FILE__ << " same param tk:" << refTk->trackId() << " with "
192 << testTk->trackId() << std::endl;
193 mergeTkList.push_back( testTk );
194 }
195 }
196 if ( mergeTkList.size() > 1 && curl ) needMerge = doMergeCurl( mergeTkList );
197 if ( ( needMerge < 999 ) && mergeTkList.size() > 1 )
198 needMerge = doMergeLong( mergeTkList );
199 // if ((needMerge <999) && mergeTkList.size()==2 && (sameParm==2) ) needMerge =
200 // doMergeOdd(mergeTkList); //FIXME
201 }
202
203 // return 0 if No track need merged
204 if ( needMerge <= 0 ) return 0;
205
206 // reset track Id
207 iterRefTk = trackList->begin();
208 int iTk = 0;
209 int nDeleted = 0;
210 for ( ; iterRefTk != trackList->end(); )
211 {
212 if ( ( *iterRefTk )->stat() >= 0 )
213 {
214 ( *iterRefTk )->setTrackId( iTk );
215 iterRefTk++;
216 iTk++;
217 }
218 else
219 {
220 int id = ( *iterRefTk )->trackId();
221 bool erased = eraseTdsTrack( iterRefTk );
222 if ( erased )
223 {
224 nDeleted++;
225 if ( m_debug > 0 ) std::cout << __FILE__ << " erase track No." << id << std::endl;
226 }
227 else
228 {
229 if ( m_debug > 0 ) std::cout << __FILE__ << " erase failed !" << std::endl;
230 }
231 }
232 }
233 if ( m_debug > 0 )
234 std::cout << __FILE__ << " After merge save " << iTk << " tracks" << std::endl;
235
236 return nDeleted;
237}
238
239//-------------------------------------------------------------------
240// Test by track parameters of 2 track, if overlaped return true
241// return 0: not duplicates, 1: same charge, 2: odd charge
243 //-------------------------------------------------------------------
244 int overlaped = 0;
245
246 // Convert to Babar track convension
247 double Bz = m_bfield->bFieldZ();
248 double omega1 = ( Constants::c * Bz * refTk->helix( 2 ) ) / 10000.;
249 double omega2 = ( Constants::c * Bz * testTk->helix( 2 ) ) / 10000.;
250 // phi0_babar = phi0_belle + pi/2 [0,2pi)
251 double phi01 = refTk->helix( 1 ) + Constants::pi / 2.;
252 double phi02 = testTk->helix( 1 ) + Constants::pi / 2.;
253 while ( phi01 > Constants::twoPi ) phi01 -= Constants::twoPi;
254 while ( phi02 > Constants::twoPi ) phi02 -= Constants::twoPi;
255 double d01 = -refTk->helix( 0 );
256 double d02 = -testTk->helix( 0 );
257 double dphi0 = fabs( phi01 - phi02 );
258 double dd0 = fabs( d01 - d02 );
259 double prodo = omega1 * omega2;
260 double r1 = 100000.;
261 double r2 = 100000.;
262 if ( fabs( omega1 ) > 0.00001 ) r1 = 1.0 / fabs( omega1 );
263 if ( fabs( omega2 ) > 0.00001 ) r2 = 1.0 / fabs( omega2 ); // FIXME
264 double pdrad = fabs( ( r1 - r2 ) / ( r1 + r2 ) );
265
266 if ( 2 == m_debug )
267 {
268 std::cout << " fabs(d01 - d02) " << fabs( d01 - d02 ) << std::endl;
269 std::cout << " fabs(phi01-phi02) " << fabs( phi01 - phi02 ) << std::endl;
270 }
271 // Try to merge pair that looks like duplicates (same charge)
272 if ( ( prodo > 0. ) && ( dd0 < m_maxDd0InMerge ) && ( dphi0 < m_maxDphi0InMerge ) &&
273 ( pdrad < m_maxPdradInMerge ) )
274 { overlaped = 1; }
275
276 // Try to merge pair that looks like albedo (opp charge, large d0)
277 if ( ( prodo < 0. ) && ( fabs( d01 + d02 ) < 4.0 ) && ( dd0 > 47.0 ) &&
278 ( fabs( dphi0 - Constants::pi ) < m_maxDphi0InMerge ) && ( pdrad < m_maxPdradInMerge ) )
279 { overlaped = 2; }
280
281 return overlaped;
282}
283
284//-------------------------------------------------------------------
285// return best tk id
286// if failed return 999
287int MdcMergeDups::doMergeLong( std::vector<RecMdcTrack*> mergeTkList ) {
288 //-------------------------------------------------------------------
289 // merge hitlist
290 double minRcs = 999.;
291 int bestTkId = 999;
292 RecMdcTrack* bestTk = NULL;
293 std::vector<RecMdcTrack*>::iterator itTk = mergeTkList.begin();
294 for ( int iTk = 0; itTk != mergeTkList.end(); itTk++, iTk++ )
295 {
296 RecMdcTrack* tk = ( *itTk );
297 double chi2 = tk->chi2();
298 double ndf = tk->ndof();
299 if ( chi2 / ndf < minRcs )
300 {
301 bestTkId = tk->trackId();
302 bestTk = tk;
303 }
304 }
305 if ( minRcs < m_maxRcsInMerge ) return bestTkId;
306 bestTk->setStat( -1 );
307
308 return 999;
309 // FIXME
310 /*
311 //fit with track parameter respectively
312 MdcxFittedHel fit1(dcxhlist, *iptr);
313 MdcxFittedHel fit2(dcxhlist, *trkl[j]);
314 int uf = 0;
315 //get a best fit
316 if ( !fit1.Fail() && (fit1.Rcs()<m_maxRcsInMerge) ) uf = 1;
317 if ( !fit2.Fail() && (fit2.Rcs()<fit1.Rcs()) ) uf = 2;
318
319 if (uf) {//two fit all ok
320 //delete bad track
321 MdcxHel fitme = (uf == 1) ? fit1 : fit2;
322 }
323 */
324}
325
326//-------------------------------------------------------------------
327// int MdcMergeDups::doMergeOdd(std::vector<RecMdcTrack*> mergeTkList){
328//-------------------------------------------------------------------
329/*
330//odd charged track
331if (2==m_debug)
332cout << "MdcxMD i j sum " << i << " " << j << " " << d01+d02 << " "
333<< deltap << " " << r1 << " " << r2 << " " << pdrad << endl;
334//merge list
335//fit
336MdcxFittedHel fit1(dcxhlist, temp1); // fit1.FitPrint(); fit1.print();
337MdcxFittedHel fit2(dcxhlist, temp2); // fit2.FitPrint(); fit2.print();
338int uf = 0;
339if ( !fit1.Fail() && (fit1.Rcs()<m_maxRcsInMerge) ) uf = 1;
340if ( !fit2.Fail() && (fit2.Rcs()<fit1.Rcs()) ) uf = 2;
341if (uf) {
342MdcxHel fitme = (1 == uf) ? fit1 : fit2;
343MdcxFittedHel* finehel = new MdcxFittedHel(dcxhlist, fitme);
344if (!finehel->Fail()) {
345if (already_merged) {
346NewTrklist.replace(iptr, finehel);
347delete iptr;
348iptr = finehel;
349trkl[j]->SetUsedOnHel(already_merged);
350} else {
351NewTrklist.append(finehel);
352already_merged = NewTrklist.length();
353iptr->SetUsedOnHel(already_merged);
354iptr = finehel;
355trkl[j]->SetUsedOnHel(already_merged);
356}
357} else {
358delete finehel;
359}
360}
361*/
362//}
363
364//-------------------------------------------------------------------
365// Test by overlap hit rate of 2 track, if overlaped return 1, else return 0
367 //-------------------------------------------------------------------
368 int overlaped = 0;
369 if ( ( testTk->pxy() >= m_mergePt ) || ( refTk->pxy() >= m_mergePt ) ) return overlaped;
370
371 HitRefVec testHits = testTk->getVecHits();
372 int nHit = testHits.size();
373 int nOverlap = 0;
374
375 HitRefVec::iterator iterHit = testHits.begin();
376 for ( ; iterHit != testHits.end(); iterHit++ )
377 {
378 RecMdcHit* hit = *iterHit;
379
380 //-- load for Axial and Stereo layer are 3,4 by jialk, original is 2,3
381 double load = m_mergeLoadAx;
382 bool isStLayer = ( m_gm->Layer( MdcID::layer( hit->getMdcId() ) )->view() != 0 );
383 if ( isStLayer ) load = m_mergeLoadSt;
384
385 // helix parameters
386 double vx0 = refTk->getVX0();
387 double vy0 = refTk->getVY0();
388 double vz0 = refTk->getVZ0();
389 double dr = refTk->helix( 0 );
390 double phi0 = refTk->helix( 1 );
391 double Bz = m_bfield->bFieldZ();
392 double r = 10000. / ( Constants::c * Bz * refTk->helix( 2 ) );
393 double dz = refTk->helix( 3 );
394 double tanl = refTk->helix( 4 );
395
396 // center of circle
397 double xc = vx0 + ( dr + r ) * cos( phi0 );
398 double yc = vy0 + ( dr + r ) * sin( phi0 );
399
400 // position of hit
401 double zHit = hit->getZhit();
402 double phi = ( vz0 + dz - zHit ) / ( r * tanl );
403 double xHit = vx0 + dr * cos( phi0 ) + r * ( cos( phi0 ) - cos( phi0 + phi ) );
404 double yHit = vy0 + dr * sin( phi0 ) + r * ( sin( phi0 ) - sin( phi0 + phi ) );
405
406 // distance from center of circle to hit
407 double dx = xc - xHit;
408 double dy = yc - yHit;
409 double dHit2Center = sqrt( dx * dx + dy * dy );
410 double rTk = fabs( r );
411
412 // is this hit overlaped ?
413 if ( ( dHit2Center > ( rTk - load ) ) && ( dHit2Center < ( rTk + load ) ) ) nOverlap++;
414 }
415
416 if ( nOverlap <= 0 ) return overlaped;
417
418 double overlapRatio = double( nOverlap ) / double( nHit );
419
420 if ( overlapRatio > m_mergeOverlapRatio ) overlaped = 1;
421
422 return overlaped;
423}
424
425//-------------------------------------------------------------------
426int MdcMergeDups::doMergeCurl( std::vector<RecMdcTrack*> mergeTkList ) {
427 //-------------------------------------------------------------------
428 int innerMostTkId = 999;
429 RecMdcTrack* innerMostTk = NULL;
430 unsigned innerMostLayerOfTk = 999;
431 std::vector<RecMdcTrack*>::iterator itTk = mergeTkList.begin();
432 for ( int iTk = 0; itTk != mergeTkList.end(); itTk++, iTk++ )
433 {
434 RecMdcTrack* tk = ( *itTk );
435 unsigned innerMostLayer = 999;
436 for ( unsigned iHit = 0; iHit < tk->getVecHits().size(); iHit++ )
437 {
438 unsigned layer = MdcID::layer( tk->getVecHits()[iHit]->getMdcId() );
439 if ( layer < innerMostLayer ) innerMostLayer = layer;
440 }
441
442 if ( m_debug > 0 )
443 std::cout << __FILE__ << " to be merged track id=" << tk->trackId() << std::endl;
444 // test inner most layer id; if same, test dz
445 if ( innerMostLayer < innerMostLayerOfTk )
446 {
447 innerMostTkId = iTk;
448 innerMostTk = tk;
449 }
450 else if ( innerMostLayer == innerMostLayerOfTk )
451 {
452 // test by dz
453 if ( tk->helix( 3 ) < innerMostTk->helix( 3 ) )
454 {
455 innerMostTkId = iTk;
456 innerMostTk = tk;
457 }
458 }
459 } // end of for mergeTkList
460 innerMostTk->setStat( -1 );
461
462 return innerMostTkId;
463}
464
466 SmartDataPtr<RecMdcTrackCol> trackList( eventSvc(), EventModel::Recon::RecMdcTrackCol );
467 if ( !trackList ) return;
468 SmartDataPtr<RecMdcHitCol> hitList( eventSvc(), EventModel::Recon::RecMdcHitCol );
469 if ( !hitList ) return;
470
471 assert( aTrack != NULL );
472 TrkExchangePar helix = aTrack->fitResult()->helix( 0. );
473
474 if ( m_debug > 1 ) std::cout << __FILE__ << " STORED" << std::endl;
475 MdcTrack mdcTrack( aTrack ); // aTrack have been deleted in ~MdcTrack()
476 // tkStat: 0,Tsf 1,CurlFinder 2,PatRec 3,MdcxReco 4,MergeCurl
477 int tkStat = 4;
478 mdcTrack.storeTrack( -1, trackList, hitList, tkStat );
479}
480
481bool MdcMergeDups::eraseTdsTrack( RecMdcTrackCol::iterator tk ) {
482 SmartDataPtr<RecMdcTrackCol> trackList( eventSvc(), EventModel::Recon::RecMdcTrackCol );
483 if ( !trackList ) return false;
484 SmartDataPtr<RecMdcHitCol> hitList( eventSvc(), EventModel::Recon::RecMdcHitCol );
485 if ( !hitList ) return false;
486 HitRefVec hits = ( *tk )->getVecHits();
487 HitRefVec::iterator iterHit = hits.begin();
488 for ( ; iterHit != hits.end(); iterHit++ )
489 {
490 // hitList->erase(iterHit);
491 }
492 trackList->erase( tk );
493 return true;
494}
495
497 SmartDataPtr<RecMdcTrackCol> trackList( eventSvc(), EventModel::Recon::RecMdcTrackCol );
498 if ( !trackList ) return;
499 if ( trackList->size() != 4 ) setFilterPassed( true );
500 std::cout << "N track after Merged = " << trackList->size() << std::endl;
501 if ( m_debug <= 1 ) return;
502 RecMdcTrackCol::iterator it = trackList->begin();
503 for ( ; it != trackList->end(); it++ )
504 {
505 RecMdcTrack* tk = *it;
506 std::cout << "//====RecMdcTrack " << tk->trackId() << "====:" << std::endl;
507 cout << " d0 " << tk->helix( 0 ) << " phi0 " << tk->helix( 1 ) << " cpa " << tk->helix( 2 )
508 << " z0 " << tk->helix( 3 ) << " tanl " << tk->helix( 4 ) << endl;
509 std::cout << " q " << tk->charge() << " theta " << tk->theta() << " phi " << tk->phi()
510 << " x0 " << tk->x() << " y0 " << tk->y() << " z0 " << tk->z() << " r0 "
511 << tk->r() << endl;
512 std::cout << " p " << tk->p() << " pt " << tk->pxy() << " px " << tk->px() << " py "
513 << tk->py() << " pz " << tk->pz() << endl;
514 std::cout << " tkStat " << tk->stat() << " chi2 " << tk->chi2() << " ndof " << tk->ndof()
515 << " nhit " << tk->getNhits() << " nst " << tk->nster() << endl;
516 // std::cout<< "errmat " << std::endl;
517 // for (int i=0; i<15; i++){ std::cout<< " "<<tk->err(i); }
518 // std::cout<< " " << std::endl;
519
520 int nhits = tk->getVecHits().size();
521 std::cout << nhits << " Hits: " << std::endl;
522 for ( int ii = 0; ii < nhits; ii++ )
523 {
524 Identifier id( tk->getVecHits()[ii]->getMdcId() );
525 int layer = MdcID::layer( id );
526 int wire = MdcID::wire( id );
527 cout << "(" << layer << "," << wire << "," << tk->getVecHits()[ii]->getStat()
528 << ",lr:" << tk->getVecHits()[ii]->getFlagLR() << ") ";
529 } // end of hit list
530 std::cout << " " << std::endl;
531 } // end of tk list
532 std::cout << " " << std::endl;
533}
DECLARE_COMPONENT(BesBdkRc)
IMessageSvc * msgSvc()
const HepVector helix() const
......
static MdcDetector * instance()
static int layer(const Identifier &id)
Values of different levels (failure returns 0).
Definition MdcID.cxx:47
static int wire(const Identifier &id)
Definition MdcID.cxx:52
virtual ~MdcMergeDups()
StatusCode execute()
int doMergeLong(std::vector< RecMdcTrack * > mergeTkList)
int testByParam(RecMdcTrack *refTk, RecMdcTrack *testTk)
StatusCode finalize()
StatusCode initialize()
void store(TrkRecoTrk *aTrack)
void dumpRecMdcTrack()
bool eraseTdsTrack(RecMdcTrackCol::iterator tk)
int testByOverlapHit(RecMdcTrack *refTk, RecMdcTrack *testTk)
StatusCode beginRun()
int doMergeCurl(std::vector< RecMdcTrack * > mergeTkList)
int mergeCurl(void)
MdcMergeDups(const std::string &name, ISvcLocator *pSvcLocator)
void storeTrack(int trackId, RecMdcTrackCol *trackList, RecMdcHitCol *hitList, int tkStat)
Definition MdcTrack.cxx:145
virtual TrkExchangePar helix(double fltL) const =0
const TrkFit * fitResult() const