CGEM BOSS 6.6.5.h
BESIII Offline Software System
Loading...
Searching...
No Matches
DotsConnection.cxx
Go to the documentation of this file.
1
3
4#include "GaudiKernel/MsgStream.h"
5//#include "GaudiKernel/ISvcLocator.h"
6#include "GaudiKernel/SmartDataPtr.h"
7#include "GaudiKernel/IPartPropSvc.h"
8#include "GaudiKernel/INTupleSvc.h"
9//#include "GaudiKernel/IDataManagerSvc.h"
10//#include "GaudiKernel/IDataProviderSvc.h"
11#include "HepPDT/ParticleDataTable.hh"
12#include "McTruth/McParticle.h"
13#include "McTruth/MdcMcHit.h"
16#include "Identifier/MdcID.h"
18#include "MdcGeom/Constants.h"
19// #include "MdcCalibFunSvc/IMdcCalibFunSvc.h"
20#define Epsilon 1e-8
21
22using namespace Event; // for McParticleCol
23//using namespace EventModel; // for EventHeader
24
26
27DotsConnection::DotsConnection(const std::string& name, ISvcLocator* pSvcLocator) :
28 Algorithm(name, pSvcLocator)
29{
30 myMdcCalibFunSvc=NULL;
31
32 // Part 1: Declare the properties
33 //declareProperty("MyInt", m_myInt);
34 declareProperty("Ntuple", myNtProd=0);
35 declareProperty("driftTimeUpLimit", myDriftTimeUpLimit = 400);
36 declareProperty("MdcHitChi2Cut", myMdcHitChi2Cut = 100);
37 declareProperty("ChiCut_circle", myChiCut_circle=5);
38 declareProperty("NmaxDeact_circle", myNmaxDeact_circle=1);
39 declareProperty("ChiCut_helix", myChiCut_helix=5);
40 declareProperty("NmaxDeact_helix", myNmaxDeact_helix=1);
41 declareProperty("Debug", myDebug=0);
42 declareProperty("DebugNb", myDebugNb=0);
43 declareProperty("Chi2CutDiverge", myChi2CutDiverge=99999999);
44 //declareProperty("MCparID", myMCparID=1);//1: e, 2: mu, 3: pi, 4: K, 5: p
45 declareProperty("IniHelix", myIniHelix=1);
46 declareProperty("nBinTanl", myNBinTanl= 100);
47 declareProperty("nBinDz", myNBinDz = 100);
48 declareProperty("tanlRange", myTanlRange = 3.0);
49 declareProperty("dzRange", myDzRange = 50);
50 declareProperty("useWireCrossPoint", myUseWireCrossPoint = false);
51 declareProperty("wireCrossPointAvgMode", myWireCrossPointAvgMode = false);
52 declareProperty("WireCrossPointPersistent",myWireCrossPointPersistent = false);
53 declareProperty("IdealTracking",myRunIdealTracking= false);
54 declareProperty("UseInTrkerHits",myUseInTrkerHits = true);
55 declareProperty("TrkFollow",myRunTrkFollow= true);
56}
57
58// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
59
61
62 //bool debug=false; //debug=true;
63
64 // Part 1: Get the messaging service, print where you are
65 MsgStream log(msgSvc(), name());
66 log << MSG::INFO << " DotsConnection initialize()" << endreq;
67
68 // Part 2: Print out the property values
69 // log << MSG::INFO << " MyInt = " << m_myInt << endreq;
70
71 // --- Get MdcGeomSvc ---
72 IMdcGeomSvc* imdcGeomSvc;
73 //StatusCode sc1 =Gaudi::svcLocator()->service("MdcGeomSvc", imdcGeomSvc);
74 StatusCode sc = service ("MdcGeomSvc", imdcGeomSvc);
75 myMdcGeomSvc = dynamic_cast<MdcGeomSvc*> (imdcGeomSvc);
76 if (sc.isFailure()) {
77 return( StatusCode::FAILURE);
78 }
79 int nWire = myMdcGeomSvc->getWireSize();
80 int nLayer= myMdcGeomSvc->getLayerSize();
81 int nSuperLayer= myMdcGeomSvc->getSuperLayerSize();
82 int nSeg= myMdcGeomSvc->getSegmentNo();
83 /*cout<<"nWire = "<<nWire
84 <<" nLayer="<<nLayer
85 <<" nSuperLayer="<<nSuperLayer
86 <<" nSeg="<<nSeg
87 <<endl;*/
88 int nCellTot=0;
89 int lastWireFlag=-1;
90 int iArea=0;
91 for(int i=0; i<nLayer; i++)
92 {
93 const MdcGeoLayer* aLayer = myMdcGeomSvc->Layer(i);
94 myNWire[i]=aLayer->NCell();
95 myRLayer[i]=aLayer->Radius();
96 //cout<<"layer "<<i<<", "<<aLayer->NCell()<<" cells, slant "<<aLayer->Slant()<<", R="<<aLayer->Radius()<<endl;
97
98 double nomShift = aLayer->nomShift();
99 if(nomShift>0) myWireFlag[i]=1;
100 else if(nomShift<0) myWireFlag[i]=-1;
101 else myWireFlag[i]=0;
102 if(i>0&&myWireFlag[i]!=lastWireFlag) {
103 iArea++;
104 }
105 myAreaLayer[i]=iArea;
106 lastWireFlag=myWireFlag[i];
107 //cout<<"layer "<<i<<" in area "<<iArea<<endl;
108
109 //nCellTot+=aLayer->NCell();
110 nCellTot+=myNWire[i];
111 for(int j=0; j<myNWire[i]; j++)
112 {
113 const MdcGeoWire* aWire = myMdcGeomSvc->Wire(i,j);
114 //cout<<" wire "<<j<<", BWpos ="<<aWire->Backward()
115 // <<", "<<aWire->BWirePos()
116 // <<", FWpos ="<<aWire->Forward()
117 // <<", "<<aWire->FWirePos()
118 // <<endl;
119 int wireidx = aWire->Id();
120 myMdcDigiGroup[wireidx].SetWire(aWire);// set wire pointer
121 //myMdcDigiGroupPnt[i][j]=&(myMdcDigiGroup[wireidx]);
122 myWirePhi[i][j]=aWire->Forward().phi();
123 //cout<<"Mdc layer "<<i<<", wire "<<j<<", phi="<<myWirePhi[i][j]<<endl;
124 //int layer = aWire->Layer();
125 //int cell = aWire->Cell();
126 //cout<<"wire idx "<<wireidx<<", WireLayer "<<layer<<", cell "<<cell<<", previous idx:"<<aWire->GetNeighborIDType1()<<endl;
127 int iInnerLayer = i-1;
128 if(iInnerLayer>=0) {
129 for(int k=0; k<myNWire[iInnerLayer]; k++)
130 {
131 int k_last = k-1;
132 if(k_last<0) k_last=myNWire[iInnerLayer]-1;
133 double dphi_last = dPhi(myWirePhi[iInnerLayer][k_last], myWirePhi[i][j]);
134 double dphi = dPhi(myWirePhi[iInnerLayer][k], myWirePhi[i][j]);
135 if(dphi_last<0&&dphi>0) {
136 myInnerWire[i][j][0]=k_last;
137 myInnerWire[i][j][1]=k;
138 //cout<<"k_last, k ="<<k_last<<", "<<k<<endl;
139 break;
140 }
141 }
142 }
143 }
144 }
145
146 //cout<<"test "<<endl;
147 //myMdcDigiGroup[503].GetWire()->GetNeighborIDType1();
148 //cout<<"test done "<<endl;
149
150 for(int i=0; i<nLayer; i++)
151 {
152 for(int j=0; j<myNWire[i]; j++)
153 {
154 int iOuterLayer = i+1;
155 if(iOuterLayer<nLayer) {
156 for(int k=0; k<myNWire[iOuterLayer]; k++)
157 {
158 int k_last = k-1;// index of previous wire
159 if(k_last<0) k_last=myNWire[iOuterLayer]-1;
160 double dphi_last = dPhi(myWirePhi[iOuterLayer][k_last], myWirePhi[i][j]);
161 double dphi = dPhi(myWirePhi[iOuterLayer][k], myWirePhi[i][j]);
162 if(dphi_last<0&&dphi>0) {
163 myOuterWire[i][j][0]=k_last;
164 myOuterWire[i][j][1]=k;
165 //cout<<"k_last, k ="<<k_last<<", "<<k<<endl;
166 //cout<<"phi="<<myWirePhi[i][j]<<", outer phi = "<<myWirePhi[iOuterLayer][k_last]<<", "<<myWirePhi[iOuterLayer][k]<<endl;
167 break;
168 }
169 }
170 }
171 }
172 }
173 cout<<"Total "<<nCellTot<<" cells"<<endl;
174 // ----------------------
175
176 // --- some specific tests
177 int layer=14;
178 int wire=50;
179 vector<int> innerWires_tem = myMdcGeomSvc->Wire(layer,wire)->GetNeighborIDType3();
180 int n_wire = innerWires_tem.size();
181 cout<<" Layer "<<layer<<", wire "<<wire<<", inner neighbours: "<<endl;
182 for(int i=0; i<n_wire; i++) {
183 int wireIdx = innerWires_tem[i];
184 layer=myMdcGeomSvc->Wire(wireIdx)->Layer();
185 wire=myMdcGeomSvc->Wire(wireIdx)->Cell();
186 cout<<"(L"<<layer<<", W"<<wire<<") ";
187 }
188 cout<<endl;
189
190
191 ICgemGeomSvc* ISvc;
192 StatusCode Cgem_sc = service ("CgemGeomSvc", ISvc);
193 if(Cgem_sc.isSuccess()) myCgemGeomSvc=dynamic_cast<CgemGeomSvc *>(ISvc);
194 else cout<<"DotsConnection::initialize(): can not get CgemGeomSvc"<<endl;
195
196 // --- Initialize RawDataProviderSvc ---
197 IRawDataProviderSvc* irawDataProviderSvc;
198 sc = service ("RawDataProviderSvc", irawDataProviderSvc);
199 myRawDataProviderSvc = dynamic_cast<RawDataProviderSvc*> (irawDataProviderSvc);
200 if ( sc.isFailure() ){
201 log << MSG::FATAL << name()<<" Could not load RawDataProviderSvc!" << endreq;
202 return StatusCode::FAILURE;
203 }
204
205 // --- MdcCalibFunSvc ---
206 IMdcCalibFunSvc* imdcCalibSvc;
207 sc = service("MdcCalibFunSvc", imdcCalibSvc);
208 if ( sc.isSuccess() ){
209 myMdcCalibFunSvc = dynamic_cast<MdcCalibFunSvc*>(imdcCalibSvc);
210 }
211 else {
212 cout<<"DotsConnection::initialize(): can not get MdcCalibFunSvc"<<endl;
213 }
214 // --- initialize DotsHelixFitter ---
215 myDotsHelixFitter.initialize();
216 myDotsHelixFitter.setChi2Diverge(myChi2CutDiverge);
217 myDotsHelixFitter.setModeWireCrossPointPersistent(myWireCrossPointPersistent);
218 if(myNtProd&1)
219 {
220 NTuplePtr nt_ptr(ntupleSvc(),"TestDotsHelixFitter/trkPar");
221 if( nt_ptr ) myNtHelixFitter = nt_ptr;
222 else
223 {
224 myNtHelixFitter = ntupleSvc()->book("TestDotsHelixFitter/trkPar",CLID_ColumnWiseTuple,"trkPar");
225 if( myNtHelixFitter ) {
226 myNtHelixFitter->addItem ("run", myRUN);
227 myNtHelixFitter->addItem ("evt", myEVT);
228 myNtHelixFitter->addItem ("pid", myPID);
229 myNtHelixFitter->addItem ("Npar", myNPar, 0,5);
230 myNtHelixFitter->addIndexedItem("HelixMC", myNPar, myArrayHelixMC);
231 myNtHelixFitter->addIndexedItem("HelixFitted", myNPar, myArrayHelixFitted);
232 myNtHelixFitter->addItem ("NhitCircle", myNHitsCircle, 0,100);
233 myNtHelixFitter->addIndexedItem("LayerHitsCircle", myNHitsCircle, myLayerHitsCircle);
234 myNtHelixFitter->addIndexedItem("ChiHitsCircle", myNHitsCircle, myChiHitsCircle);
235 myNtHelixFitter->addItem ("Nhit", myNHits, 0,100);
236 myNtHelixFitter->addIndexedItem("LayerHits", myNHits, myLayerHits);
237 myNtHelixFitter->addIndexedItem("ChiHits", myNHits, myChiHits);
238 myNtHelixFitter->addItem ("NXhit", myNXHits, 0,100);
239 myNtHelixFitter->addItem ("NVhit", myNVHits, 0,100);
240 myNtHelixFitter->addItem ("NXCluster", myNXCluster, 0,100);
241 myNtHelixFitter->addItem ("NVCluster", myNVCluster, 0,100);
242 myNtHelixFitter->addItem ("TrkIdBest", myTrkIdBest);
243 myNtHelixFitter->addItem ("NHitsBestTrk", myNHitsBestTrk);
244 myNtHelixFitter->addItem ("NSameHitsBestTrk", myNSameHitsBestTrk);
245 //cout<<"myNtHelixFitter added !"<<endl;
246 }
247 }
248 }
249
250 if(myNtProd&2 || myNtProd&4) {
251 NTuplePtr nt_ptr(ntupleSvc(),"TestDotsHelixFitter/lineTrkSegHough");
252 if( nt_ptr ) myNtTrkSeg = nt_ptr;
253 else
254 {
255 myNtTrkSeg = ntupleSvc()->book("TestDotsHelixFitter/lineTrkSegHough",CLID_ColumnWiseTuple,"hough");
256 if( myNtTrkSeg ) {
257 myNtTrkSeg->addItem ("run", myRUN);
258 myNtTrkSeg->addItem ("evt", myEVT);
259 myNtTrkSeg->addItem ("nhits", myNt_nhits, 0,100);
260 myNtTrkSeg->addIndexedItem("layer", myNt_nhits, myNt_layer);
261 myNtTrkSeg->addIndexedItem("wire", myNt_nhits, myNt_wire);
262 myNtTrkSeg->addIndexedItem("xhit", myNt_nhits, myNt_Xhit);
263 myNtTrkSeg->addIndexedItem("yhit", myNt_nhits, myNt_Yhit);
264 myNtTrkSeg->addIndexedItem("DDhit", myNt_nhits, myNt_DDhit);
265 myNtTrkSeg->addItem ("rho", myNt_rho);
266 myNtTrkSeg->addItem ("theta", myNt_theta);
267 }
268 }
269 }
270
271 // --- get MdcUtilitySvc
272 /*
273 sc = service("MdcUtilitySvc", myMdcUtilitySvc);
274 if( sc != StatusCode::SUCCESS ){
275 log << MSG::FATAL << "can not use MdcUtilitySvc" << endreq;
276 }*/
277
278 //myWatch_reset=kTRUE;
279
280 cout<<"DotsConnection::initialize() myIniHelix = "<<myIniHelix<<endl;
281
282 // --- Hough maps
283 myRoughTanlDzMap = TH2D("roughTanlDzMap","roughTanlDzMap",myNBinTanl,-1.*myTanlRange,myTanlRange,myNBinDz,-1.*myDzRange,myDzRange);
284
285 myRhoRange=78;// in cm
286 myThetaRange=acos(-1); // pi
287 myRoughRhoThetaMap=TH2D("roughRhoThetaMap","roughRhoThetaMap",100,0,myThetaRange,100,-1.*myRhoRange,myRhoRange);
288
289 return StatusCode::SUCCESS;
290}
291
292// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
294 cout.precision(4);
295
296 // Part 1: Get the messaging service, print where you are
297 MsgStream log(msgSvc(), name());
298 log << MSG::INFO << "DotsConnection execute()" << endreq;
299
300 // Part 2: Print out the different levels of messages
301 /*log << MSG::DEBUG << "A DEBUG message" << endreq;
302 log << MSG::INFO << "An INFO message" << endreq;
303 log << MSG::WARNING << "A WARNING message" << endreq;
304 log << MSG::ERROR << "An ERROR message" << endreq;
305 log << MSG::FATAL << "A FATAL error message" << endreq;
306 */
307
308 SmartDataPtr<Event::EventHeader> eventHeader(eventSvc(),"/Event/EventHeader");
309 if (!eventHeader) {
310 log << MSG::WARNING << "Could not find Event Header" << endreq;
311 return StatusCode::FAILURE;
312 }
313 myRun = eventHeader->runNumber();
314 myEvt = eventHeader->eventNumber();
315 if(myDebug) {
316 cout<<endl<<"------------------------------ "<<endl;
317 cout<<"run:"<<myRun<<" , event: "<<myEvt<<endl;
318 }
319 if(myDebugNb==2) {
320 cout<<endl<<"------------------------------ "<<endl;
321 cout<<"DotsConnection: run:"<<myRun<<" , event: "<<myEvt<<endl;
322 }
323
324
325 //if(!(myEvt==240|| myEvt==1374 || myEvt==5084 || myEvt==9015) )
326 //if(myEvt!=6746)
327 // return StatusCode::SUCCESS;
328 //if(myRun==763)
329 //if(myEvt!=3946) return StatusCode::SUCCESS;// run for specific events
330 //if(myEvt!=3946) return StatusCode::SUCCESS;// run for specific events
331
332 //testDotsHelixFitterAllHits();
333 //testDotsHelixFitterPartHits();
334
335 // --- event start time
336 getEventStartTime();
337
338 // --- register RecMdcTrack/HitCol if not there
339 bool bookTrkCol = registerRecMdcTrack();
340 if(!bookTrkCol)
341 {
342 cout<<"DotsConnection::execute(): failed to register RecMdcTrackCol!"<<endl;
343 return StatusCode::FAILURE;
344 }
345
346 //if(myEvt!=2376) return StatusCode::SUCCESS;// run for specific events
347
348 // --- tracking starting with grouping neighboured digis
349 if(myRunTrkFollow) {
350 myVecTrkCandidates.clear();
351 //cout<<"test 3"<<endl;
352 //myMdcDigiGroup[503].GetWire()->GetNeighborIDType1();
353 //cout<<"test 3 done "<<endl;
354 vector<const MdcDigi*> vecDigi = getMdcDigiVec();
355 if(vecDigi.size()<2000) {
356 // fillMdcDigiBuildNeighbors(vecDigi,1,1); // expired
357 fillMdcDigiMap(vecDigi);
358 buildMdcDigiNeighbors(myMapMdcDigi, 3, 3);
359 findOuterEnds();
360 getMdcHitCluster();
361 getCgemClusters();
362 //matchCgemClusterMdcDigi();
363 processTrkCandi();
364 //processMdcHitCluter();
365 findCgemTrkSeg();
366 saveGoodTrkCandi();
367 }
368 else log << MSG::WARNING << "Too Many MDC digis: "<<vecDigi.size() << endreq;
369 }
370
371 // --- ideal tracking
372 if(myRunIdealTracking) {
373 getMcFinalChargedStates();
374 //myWatch_tot.Start(myWatch_reset);
375 associateDigisToMcParticles();
376 //myWatch_reset=kFALSE;
377 //myWatch_tot.Stop();
378 //cout<<"associateDigisToMcParticles used CPU time: "<<myWatch_tot.CpuTime()<<" s"<<endl;
379 //cout<<" finding "<<myWatch_finding.CpuTime()<<" s"<<endl;
380 //cout<<" fitting "<<myWatch_fitting.CpuTime()<<" s"<<endl;
381 }
382
383 return StatusCode::SUCCESS;
384}
385
386// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
387
389
390 // Part 1: Get the messaging service, print where you are
391 MsgStream log(msgSvc(), name());
392 log << MSG::INFO << "DotsConnection finalize()" << endreq;
393
394 if(myDebugNb==2) {
395 cout<<"DotsConnection finalize(): " << endl;
396 //cout<<" associateDigisToMcParticles used CPU time: "<<myWatch_tot.CpuTime()<<" s"<<endl;
397 //cout<<" finding "<<myWatch_finding.CpuTime()<<" s"<<endl;
398 //cout<<" fitting "<<myWatch_fitting.CpuTime()<<" s"<<endl;
399 }
400
401 return StatusCode::SUCCESS;
402}
403
404
405double DotsConnection::dPhi(double phi1, double phi2)
406{
407 double dphi=phi1-phi2;
408 //while(dphi>M_PI) dphi-=M_PI*2.0;
409 //while(dphi<-M_PI) dphi+=M_PI*2.0;
410 if(dphi<-M_PI||dphi> M_PI) dphi=atan2(sin(dphi),cos(dphi));// into [-pi, pi]
411 return dphi;
412}
413
414KalmanFit::Helix DotsConnection::getMCHelix()
415{
416
417 // particle information
418 std::string name;
419 double charge = 0;
420 double pos_x, pos_y, pos_z;
421 double px, py, pz;
422
423
424 // get PartPropSvc
425 IPartPropSvc* p_PartPropSvc;
426 static const bool CREATEIFNOTTHERE(true);
427 StatusCode PartPropStatus = service("PartPropSvc", p_PartPropSvc, CREATEIFNOTTHERE);
428 if (!PartPropStatus.isSuccess() || 0 == p_PartPropSvc) {
429 cout<< " Could not initialize Particle Properties Service" << endl;
430 }
431 HepPDT::ParticleDataTable* p_particleTable = p_PartPropSvc->PDT();
432
433 // get MC particle collection
434 SmartDataPtr<McParticleCol> mcParticleCol(eventSvc(),"/Event/MC/McParticleCol");
435 if (mcParticleCol) {
436 McParticleCol::iterator iter_mc = mcParticleCol->begin();
437 for (;iter_mc != mcParticleCol->end(); iter_mc++ ) {
438 if(!(*iter_mc)->primaryParticle()) continue;
439 int pid = (*iter_mc)->particleProperty();
440 int pid_abs = abs(pid);
441 if( p_particleTable->particle(pid) ){
442 name = p_particleTable->particle(pid)->name();
443 charge= p_particleTable->particle(pid)->charge();
444 }else if( p_particleTable->particle(-pid) ){
445 name = "anti " + p_particleTable->particle(-pid)->name();
446 charge = (-1.)*p_particleTable->particle(-pid)->charge();
447 }
448 pos_x = (*iter_mc)->initialPosition().x();
449 pos_y = (*iter_mc)->initialPosition().y();
450 pos_z = (*iter_mc)->initialPosition().z();
451 px = (*iter_mc)->initialFourMomentum().px();
452 py = (*iter_mc)->initialFourMomentum().py();
453 pz = (*iter_mc)->initialFourMomentum().pz();
454 if(pid_abs==11||pid_abs==13||pid_abs==211||pid_abs==321||pid_abs==2212) break;
455 }
456 }
457
458 // --- get Helix ---
459 HepPoint3D posTruth(pos_x, pos_y, pos_z);
460 Hep3Vector p3Truth(px, py, pz);
461 KalmanFit::Helix helix_truth(posTruth,p3Truth,charge);
462 HepPoint3D origin(0, 0, 0);
463 helix_truth.pivot(origin);
464 if(myDebug) {
465 cout<<"DotsConnection::getMCHelix() finds a valid MC particle "<<name<<" at "<<posTruth<<" with p3="<<p3Truth<<endl;
466 cout<<"DotsConnection::getMCHelix() Helix = "<<helix_truth.a()<<endl;
467 }
468
469 return helix_truth;
470}
471
472void DotsConnection::getMcFinalChargedStates()
473{
474 resetFCSVec();
475
476 // particle information
477 std::string name;
478 double charge = 0;
479 double pos_x, pos_y, pos_z;
480 double px, py, pz;
481 HepPoint3D origin(0, 0, 0);
482
483
484 // get PartPropSvc
485 IPartPropSvc* p_PartPropSvc;
486 static const bool CREATEIFNOTTHERE(true);
487 StatusCode PartPropStatus = service("PartPropSvc", p_PartPropSvc, CREATEIFNOTTHERE);
488 if (!PartPropStatus.isSuccess() || 0 == p_PartPropSvc) {
489 cout<< " Could not initialize Particle Properties Service" << endl;
490 }
491 HepPDT::ParticleDataTable* p_particleTable = p_PartPropSvc->PDT();
492
493 // get MC particle collection
494 SmartDataPtr<McParticleCol> mcParticleCol(eventSvc(),"/Event/MC/McParticleCol");
495 if (mcParticleCol) {
496 McParticleCol::iterator iter_mc = mcParticleCol->begin();
497 if(myDebug) cout<<"MC charged particles: "<<endl;
498 for (;iter_mc != mcParticleCol->end(); iter_mc++ )
499 {
500 int pdgid = (*iter_mc)->particleProperty();
501 if(myDebug) cout<<"idx, pdg, from "<<(*iter_mc)->trackIndex()<<", "<<pdgid<<", "<<((*iter_mc)->mother()).trackIndex()<<endl;
502 if( !( (*iter_mc)->primaryParticle() || (*iter_mc)->decayFromGenerator() || (*iter_mc)->decayInFlight() ) ) continue;
503 int pid = (*iter_mc)->particleProperty();
504 int mpid = ((*iter_mc)->mother()).particleProperty(); // xiaogy add!
505 int pid_abs = abs(pid);
506 // --- e, mu, pi, K, p
507 if(pid_abs==11||pid_abs==13||pid_abs==211||pid_abs==321||pid_abs==2212)
508 {
509 if( p_particleTable->particle(pid) )
510 {
511 name = p_particleTable->particle(pid)->name();
512 charge= p_particleTable->particle(pid)->charge();
513 }
514 else if( p_particleTable->particle(-pid) )
515 {
516 name = "anti " + p_particleTable->particle(-pid)->name();
517 charge = (-1.)*p_particleTable->particle(-pid)->charge();
518 }
519 pos_x = (*iter_mc)->initialPosition().x();
520 pos_y = (*iter_mc)->initialPosition().y();
521 pos_z = (*iter_mc)->initialPosition().z();
522 px = (*iter_mc)->initialFourMomentum().px();
523 py = (*iter_mc)->initialFourMomentum().py();
524 pz = (*iter_mc)->initialFourMomentum().pz();
525 // --- get Helix ---
526 HepPoint3D posTruth(pos_x, pos_y, pos_z);
527 Hep3Vector p3Truth(px, py, pz);
528 KalmanFit::Helix helix_truth(posTruth,p3Truth,charge);
529 helix_truth.pivot(origin);
530 // --- get the flight length of the first half in MDC --
531 double dphi=helix_truth.IntersectCylinder(myRLayer[42]/10.);// mm -> cm
532 if(dphi==0) dphi=M_PI*charge;
533 HepPoint3D posOuter = helix_truth.x(dphi);
534 double lenOuter = helix_truth.flightLength(posOuter);
535 double lenInner = helix_truth.flightLength(posTruth);
536 double lenInMdc = lenOuter-lenInner;
537 myVecTrkLenFirstHalf.push_back(lenInMdc);
538 // --- fill charged final states
539 int trkIdx = (*iter_mc)->trackIndex();
540 int mtrkIdx = ((*iter_mc)->mother()).trackIndex(); // xiaogy add!
541 myVecMCTrkId.push_back(trkIdx);
542 myVecPDG.push_back(pid);
543 vector<double> helix;
544 helix.push_back(helix_truth.dr());
545 helix.push_back(helix_truth.phi0());
546 helix.push_back(helix_truth.kappa());
547 helix.push_back(helix_truth.dz());
548 helix.push_back(helix_truth.tanl());
549 myVecHelix.push_back(helix);
550 if(myDebug)
551 {
552 cout<<Form("trk idx %d, pdg code %d, mother %d", trkIdx, pid, mpid)<<endl;
553 cout<<Form("p3 = (%.6f, %.6f, %.6f)", px, py, pz)<<endl;
554 cout<<Form("pos = (%.6f, %.6f, %.6f)", pos_x, pos_y, pos_z)<<endl;
555 cout<<Form("dphi = %.6f", dphi)<<endl;
556 cout<<Form("lenOuter = %.6f, lenInner = %.6f", lenOuter,lenInner)<<endl;
557 cout<<"******************************************************"<<endl;
558 //cout<<" trk idx "<<trkIdx<<", pdg code "<<pid
559 // <<", p3=("<<px<<", "<<py<<", "<<pz<<")"
560 // <<", pos=("<<pos_x<<","<<pos_y<<","<<pos_z<<")"
561 // <<", dphi="<<dphi<<", lenOuter="<<lenOuter<<", lenInner="<<lenInner
562 // <<", lenInMdc = "<<lenInMdc
563 // //<<", lenInMdc = "<<lenOuter
564 // <<endl;
565 }
566 }
567 }
568 }
569}
570
571
572void DotsConnection::resetFCSVec()
573{
574 myVecMCTrkId.clear();
575 myVecPDG.clear();
576 myVecTrkLenFirstHalf.clear();
577 myVecHelix.clear();
578 myVecCgemMcHit.clear();
579 myVecCgemXcluster.clear();
580 myVecCgemVcluster.clear();
581}
582
583void DotsConnection::associateDigisToMcParticles()
584{
585 //myWatch_finding.Start(myWatch_reset);
586
587 // --- get event T0 ---
588 double T0 = getEventStartTime();// in ns
589
590 // --- get CGEM MC hits
591 SmartDataPtr<Event::CgemMcHitCol> cgemMcHitCol(eventSvc(),"/Event/MC/CgemMcHitCol");
592 if(!cgemMcHitCol) cout<<"DotsConnection::associateDigisToMcParticles() does not find CgemMcHitCol!"<<endl;
593 //cout<<"CGEM MC hits obtained"<<endl;
594
595 // --- get CGEM cluster
596 RecCgemClusterCol::iterator iter_cluster_begin;
597 RecCgemClusterCol::iterator iter_cluster;
598 SmartDataPtr<RecCgemClusterCol> aCgemClusterCol(eventSvc(),"/Event/Recon/RecCgemClusterCol");
599 if(!aCgemClusterCol) cout<<"DotsConnection::associateDigisToMcParticles() does not find RecCgemClusterCol!"<<endl;
600 else iter_cluster_begin=aCgemClusterCol->begin();
601 //cout<<"CGEM clusters obtained"<<endl;
602
603 // --- get MDC MC hits
604 SmartDataPtr<Event::MdcMcHitCol> mdcMcHitCol(eventSvc(),"/Event/MC/MdcMcHitCol");
605 if(!mdcMcHitCol) cout<<"DotsConnection::associateDigisToMcParticles() does not find MdcMcHitCol!"<<endl;
606 if(myDebug)
607 {
608 cout<<"MDC MC hits obtained, n="<<mdcMcHitCol->size()<<endl;
609 Event::MdcMcHitCol::iterator iter_mdcMcHit = mdcMcHitCol->begin();
610 for(; iter_mdcMcHit!=mdcMcHitCol->end(); iter_mdcMcHit++ )
611 {
612 string creatorProcess = (*iter_mdcMcHit)->getCreatorProcess();
613 int trkId = (*iter_mdcMcHit)->getTrackIndex();
614 int isSec = (*iter_mdcMcHit)->getIsSecondary();
615 double trkLen = (*iter_mdcMcHit)->getFlightLength();
616 double px=(*iter_mdcMcHit)->getMomentumX();
617 double py=(*iter_mdcMcHit)->getMomentumY();
618 double pz=(*iter_mdcMcHit)->getMomentumZ();
619 double posx=(*iter_mdcMcHit)->getPositionX();
620 double posy=(*iter_mdcMcHit)->getPositionY();
621 double posz=(*iter_mdcMcHit)->getPositionZ();
622 int pdgCode = (*iter_mdcMcHit)->getCurrentTrackPID();
623 int digiIdx = (*iter_mdcMcHit)->getDigiIdx();
624 Identifier id = (*iter_mdcMcHit)->identify();
625 int layer = MdcID::layer(id);
626 int wire = MdcID::wire(id);
627 Hep3Vector pos(posx,posy,0);
628 Hep3Vector p3(px,py,0);
629 double dotProd = pos*p3;
630
631 //if(myDebug)
632 cout<<" MDC MC hit from "<<creatorProcess
633 <<", trk "<<trkId
634 <<", isSec="<<isSec
635 <<", len="<<trkLen/10 // mm -> cm
636 <<", p3=("<<px<<", "<<py<<", "<<pz<<")"
637 <<", pos=("<<posx<<", "<<posy<<", "<<posz<<")"
638 <<", layer "<<layer<<" wire "<<wire
639 <<", dotProd="<<dotProd
640 <<", pdg code = "<<pdgCode
641 <<", digi index = "<<digiIdx
642 <<endl;
643 }
644 }
645
646 // --- get MDC digi vector
647 uint32_t getDigiFlag = 0;
648 MdcDigiVec mdcDigiVec = myRawDataProviderSvc->getMdcDigiVec(getDigiFlag);
649 if(myDebug)
650 cout<<"DotsConnection::associateDigisToMcParticles() get "<<mdcDigiVec.size()<<" MDC digis from RawDataProviderSvc"<<endl;
651 //vector<const MdcDigi*> aMdcDigiVec;
652 clearMdcDigiPointer();
653 vector<MdcDigi*>::iterator iter_mdcDigi = mdcDigiVec.begin();
654 for(; iter_mdcDigi!=mdcDigiVec.end(); iter_mdcDigi++)
655 {
656 // --- get id, layer, wire ---
657 Identifier id = (*iter_mdcDigi)->identify();
658 int layer = MdcID::layer(id);
659 //if( (layer>=8&&layer<=19) || (layer>=36&&layer<=42) ) // --- only axial hits kept
660 int wire = MdcID::wire(id);
661
662 double rawTime = RawDataUtil::MdcTime((*iter_mdcDigi)->getTimeChannel());
663 double tprop = myMdcCalibFunSvc->getTprop(layer, 0);
664 double charge = (*iter_mdcDigi)->getChargeChannel();
665 double T0Walk = myMdcCalibFunSvc->getT0(layer,wire) + myMdcCalibFunSvc->getTimeWalk(layer, charge);
666 double TOF = 0.;
667 double driftT = rawTime - T0 - TOF - T0Walk - tprop;
668 if(driftT>myDriftTimeUpLimit) continue;
669
670 myMdcDigiPointer[layer][wire]=*iter_mdcDigi;
671 }
672
673 // --- loop MC tracks to get the proper digits (CGEM clusters and MDC hits)
674 HepPoint3D origin(0, 0, 0);
675 int nMcTrk = myVecMCTrkId.size();
676 for(int i=0; i<nMcTrk; i++)
677 {
678 // --- get track index in mc particle collection
679 int trkIdx = myVecMCTrkId[i];
680 double trkLenInMdc = myVecTrkLenFirstHalf[i];
681 if(myDebug)
682 cout<<endl<<"* MC particle "<<trkIdx<<", pdg code "<<myVecPDG[i]<<endl;
683
684 // --- for helix at nearest hit in MDC
685 double trkLenMcHit_min=9999.;
686 double pos_innermost[3],p3_innermost[3];
687
688 // --- associate CGEM clusters through CGEM MC hits
689 if(myUseInTrkerHits&&aCgemClusterCol) {
690 int CgemCluster[3][2]={0,0,0,0,0,0};// [layer][x/v]
691 myVecCgemXcluster.clear();
692 myVecCgemVcluster.clear();
693 myVecCgem1DCluster.clear();
694 clearVecCgemClu();
695 Event::CgemMcHitCol::iterator iter_CgemMcHit = cgemMcHitCol->begin();
696 for(; iter_CgemMcHit!=cgemMcHitCol->end(); iter_CgemMcHit++ )
697 {
698 string creatorProcess = (*iter_CgemMcHit)->GetCreatorProcess();
699 if(myDebug)
700 cout<<" CGEM MC hit from process "<<creatorProcess;
701 if(creatorProcess=="Generator"||creatorProcess=="Decay")// only from generator or decay
702 {
703 //cout<<", trk id "<<(*iter_CgemMcHit)->GetTrackID()<<endl;
704 if((*iter_CgemMcHit)->GetTrackID()!=trkIdx) {
705 if(myDebug) cout <<" trkIdx diff "<<endl;
706 continue; // keep only matched MC hits
707 }
708 //cout<<" is secondary "<<(*iter_CgemMcHit)->GetIsSecondary()<<endl;
709 if((*iter_CgemMcHit)->GetIsSecondary()) {
710 if(myDebug) cout <<" is secondary "<<endl;
711 continue;
712 }
713 double px=(*iter_CgemMcHit)->GetMomentumXOfPrePoint();
714 double py=(*iter_CgemMcHit)->GetMomentumYOfPrePoint();
715 double pz=(*iter_CgemMcHit)->GetMomentumZOfPrePoint();
716 double posx=(*iter_CgemMcHit)->GetPositionXOfPrePoint();
717 double posy=(*iter_CgemMcHit)->GetPositionYOfPrePoint();
718 double posz=(*iter_CgemMcHit)->GetPositionZOfPrePoint();
719 Hep3Vector pos(posx,posy,0);
720 Hep3Vector p3(px,py,0);
721 double dotProd = pos*p3;
722 if(dotProd<0) {
723 //cout<<" pos="<<pos<<", p3="<<p3<<endl;
724 //cout<<" CGEM MC hit coming back"<<endl;
725 if(myDebug) cout <<" coming back "<<endl;
726 continue;// reject hits from track coming back
727 }
728 double trkLenMcHit = ((*iter_CgemMcHit)->GetFlightLengthPrePoint())/10.;
729 if(myDebug) cout <<" trkLenMcHit, trkLenInMdc ="<<trkLenMcHit<<", "<<trkLenInMdc<<endl;
730 if(trkLenMcHit>1.5*trkLenInMdc) {
731 if(myDebug) cout <<" trkLenMcHit>1.5*trkLenInMdc "<<endl;
732 continue;
733 }
734 //cout<<"trkLenMcHit, pos.perp(), trkLenMcHit_min="<<trkLenMcHit<<", "<<pos.perp()<<", "<<trkLenMcHit_min<<endl;
735 if((pos.perp()/10.)<trkLenMcHit_min) {
736 trkLenMcHit_min=pos.perp()/10.;
737 pos_innermost[0]=posx;
738 pos_innermost[1]=posy;
739 pos_innermost[2]=posz;
740 p3_innermost[0]=px;
741 p3_innermost[1]=py;
742 p3_innermost[2]=pz;
743 }
744 // --- print the helix at each hit
745 HepPoint3D aPivot(posx/10., posy/10., posz/10.);
746 Hep3Vector aP3(px/1000., py/1000., pz/1000.);
747 double charge=myVecHelix[i][2]/fabs(myVecHelix[i][2]);
748 KalmanFit::Helix aHelix(aPivot,aP3,charge);
749 aHelix.pivot(origin);
750 if(myDebugNb==2)
751 cout<<"R="<<pos.perp()/10.<<", z="<<posz/10.<<", helix = ("<<aHelix.dr()<<", "<<aHelix.phi0()<<", "<<aHelix.kappa()<<", "<<aHelix.dz()<<", "<<aHelix.tanl()<<")"<<endl;
752 // --- end --- print the helix at each hit
753
754 const vector<int> & vec_xCluster = (*iter_CgemMcHit)->GetXclusterIdxVec();// find the X-clusters
755 int nXCluster=vec_xCluster.size();
756 for(int j=0; j<nXCluster; j++)
757 {
758 iter_cluster=iter_cluster_begin+vec_xCluster[j];
759 int clusterId = (*iter_cluster)->getclusterid();
760 int layer=(*iter_cluster)->getlayerid();
761 int sheet=(*iter_cluster)->getsheetid();
762 if(myDebug)
763 cout<<" find one X-cluster on layer "<<layer<<" (phi="<<(*iter_cluster)->getrecphi()<<") ";
764 if(CgemCluster[layer][0]==0)
765 {
766 myVecCgemXcluster.push_back(*iter_cluster);
767 myVecCgem1DCluster.push_back(*iter_cluster);
768 myVecCgemXCluIdx[layer][sheet].push_back(clusterId);
769 //vector<const RecCgemCluster*> vecCgemClu = myDotsHelixFitter.getVecCgemCluster();
770 CgemCluster[layer][0]++;
771 if(myDebug)
772 cout<<", associated. ";
773 }
774 }
775 //cout<<" X-clusters done "<<endl;
776 const vector<int> & vec_vCluster = (*iter_CgemMcHit)->GetVclusterIdxVec();// find the V-clusters
777 int nVCluster=vec_vCluster.size();
778 for(int j=0; j<nVCluster; j++)
779 {
780 iter_cluster=iter_cluster_begin+vec_vCluster[j];
781 int clusterId = (*iter_cluster)->getclusterid();
782 int layer=(*iter_cluster)->getlayerid();
783 int sheet=(*iter_cluster)->getsheetid();
784 if(myDebug)
785 cout<<" find one V-cluster on layer "<<layer;
786 if(CgemCluster[layer][1]==0)
787 {
788 myVecCgemVcluster.push_back(*iter_cluster);
789 myVecCgem1DCluster.push_back(*iter_cluster);
790 myVecCgemVCluIdx[layer][sheet].push_back(clusterId);
791 CgemCluster[layer][1]++;
792 if(myDebug)
793 cout<<", associated. ";
794 }
795 }
796 }
797 if(myDebug) cout<<endl;
798 }// end of looping CGEM MC hits
799 }
800
801 myVecMdcDigi.clear();
802 int nMdcXHits(0), nMdcVHits(0);
803
804 // --- associate MDC hits through MC track index
805 /*
806 vector<MdcDigi*>::iterator iter_mdcDigi = mdcDigiVec.begin();
807 for(; iter_mdcDigi!=mdcDigiVec.end(); iter_mdcDigi++)
808 {
809 int mcTrkIdx = (*iter_mdcDigi)->getTrackIndex();
810 if(mcTrkIdx==trkIdx)
811 {
812 //myVecMdcDigi.push_back((*iter_mdcDigi));
813 Identifier id = (*iter_mdcDigi)->identify();
814 int layer = MdcID::layer(id);
815 int wire = MdcID::wire(id);
816 //cout<<" MDC digi on layer "<<layer<<" wire "<<wire<<" associated"<<endl;
817 //cout<<" MDC digi on layer "<<layer<<" wire "<<wire<<" matched"<<endl;
818 }
819 }*/
820
821 // --- associate MDC hits through MdcMcHits
822 Event::MdcMcHitCol::iterator iter_mdcMcHit = mdcMcHitCol->begin();
823 //int nXhits(0), nVhits(0);
824 for(; iter_mdcMcHit!=mdcMcHitCol->end(); iter_mdcMcHit++ )
825 {
826 int trkId = (*iter_mdcMcHit)->getTrackIndex();
827 if(trkId!=trkIdx) continue;
828 if((*iter_mdcMcHit)->getDigiIdx()==-9999) continue;
829 Identifier id = (*iter_mdcMcHit)->identify();
830 int layer = MdcID::layer(id);
831 if(!myUseInTrkerHits&&layer<8) continue;
832 int wire = MdcID::wire(id);
833 int isSec = (*iter_mdcMcHit)->getIsSecondary();
834 if(isSec!=0) {
835 /*cout<<" MDC digi on layer "<<layer<<" wire "<<wire<<" isSec"
836 <<", pid = "<<(*iter_mdcMcHit)->getCurrentTrackPID()
837 <<endl;*/
838 continue;
839 }
840 double trkLenMcHit = ((*iter_mdcMcHit)->getFlightLength())/10.;
841 if(trkLenMcHit>1.5*trkLenInMdc) {
842 //cout<<" MDC digi on layer "<<layer<<" wire "<<wire<<" trkLenMcHit>1.5*trkLenInMdc"<<endl;
843 continue;
844 }
845 double px=(*iter_mdcMcHit)->getMomentumX();
846 double py=(*iter_mdcMcHit)->getMomentumY();
847 double pz=(*iter_mdcMcHit)->getMomentumZ();
848 double posx=(*iter_mdcMcHit)->getPositionX();
849 double posy=(*iter_mdcMcHit)->getPositionY();
850 double posz=(*iter_mdcMcHit)->getPositionZ();
851 Hep3Vector pos(posx,posy,0);
852 Hep3Vector p3(px,py,0);
853 double dotProd = pos*p3;
854 if(dotProd<0) {
855 //cout<<" pos="<<pos<<", p3="<<p3<<endl;
856 //cout<<" MDC digi on layer "<<layer<<" wire "<<wire<<" coming back"<<endl;
857 continue;// reject hits from track coming back
858 }
859 //cout<<"trkLenMcHit, trkLenMcHit_min="<<trkLenMcHit<<", "<<trkLenMcHit_min<<endl;
860 if(trkLenMcHit<trkLenMcHit_min) {
861 trkLenMcHit_min=trkLenMcHit;
862 pos_innermost[0]=posx;
863 pos_innermost[1]=posy;
864 pos_innermost[2]=posz;
865 p3_innermost[0]=px;
866 p3_innermost[1]=py;
867 p3_innermost[2]=pz;
868 }
869 // --- print the helix at each hit
870 HepPoint3D aPivot(posx/10., posy/10., posz/10.);
871 Hep3Vector aP3(px/1000., py/1000., pz/1000.);
872 double charge=myVecHelix[i][2]/fabs(myVecHelix[i][2]);
873 KalmanFit::Helix aHelix(aPivot,aP3,charge);
874 aHelix.pivot(origin);
875 if(myDebugNb==2)
876 cout<<"R="<<pos.perp()/10.<<", z="<<posz/10.<<", helix = ("<<aHelix.dr()<<", "<<aHelix.phi0()<<", "<<aHelix.kappa()<<", "<<aHelix.dz()<<", "<<aHelix.tanl()<<") layer "<<layer<<endl;
877 // --- end --- print the helix at each hit
878 //Identifier id = (*iter_mdcMcHit)->identify();
879 //int layer = MdcID::layer(id);
880 //int wire = MdcID::wire(id);
881 const MdcDigi* aMdcDigiPt = myMdcDigiPointer[layer][wire];
882 if(aMdcDigiPt!=NULL)
883 {
884 myVecMdcDigi.push_back(aMdcDigiPt);
885 myMdcDigiPointer[layer][wire]=NULL;
886 if(myDebug)
887 cout<<" MDC digi on layer "<<layer<<" wire "<<wire<<" associated"<<endl;
888 if(layer<8||(layer>19&&layer<36)) nMdcVHits++;
889 else nMdcXHits++;
890 }
891 }
892 if(myDebug) cout<<" digi association finished"<<endl;
893 //myWatch_finding.Stop();
894
895 //myWatch_fitting.Start(myWatch_reset);
896 // --- fit to Helix
897 //cout<<" start to fit "<<endl;
898 int fitFlag=99;
899 if((myVecCgemVcluster.size()+nMdcVHits)>=2&&(myVecCgemXcluster.size()+nMdcXHits+myVecCgemVcluster.size()+nMdcVHits)>5)
900 {
901 myDotsHelixFitter.setCgemClusters(myVecCgem1DCluster);
902 //cout<<" set CGEM cluster vector "<<endl;
903 myDotsHelixFitter.setDChits(myVecMdcDigi,T0);
904 //cout<<" set MDC digi vector "<<endl;
905
906 HepVector a_helix(5,0);
907 if(myIniHelix==1) // --- helix at IP
908 {
909 a_helix(1)=myVecHelix[i][0];
910 a_helix(2)=myVecHelix[i][1];
911 a_helix(3)=myVecHelix[i][2];
912 a_helix(4)=myVecHelix[i][3];
913 a_helix(5)=myVecHelix[i][4];
914 }
915 else if(myIniHelix==2) // --- helix at innermost hit in CGEM/MDC
916 {
917 HepPoint3D posTruth_mdc(pos_innermost[0]/10., pos_innermost[1]/10., pos_innermost[2]/10.);//mm->cm
918 Hep3Vector p3Truth(p3_innermost[0]/1000., p3_innermost[1]/1000., p3_innermost[2]/1000.);//MeV->GeV
919 double charge=myVecHelix[i][2]/fabs(myVecHelix[i][2]);
920 KalmanFit::Helix ini_helix(posTruth_mdc,p3Truth,charge);
921 ini_helix.pivot(origin);
922 a_helix(1)=ini_helix.dr();
923 a_helix(2)=ini_helix.phi0();
924 a_helix(3)=ini_helix.kappa();
925 a_helix(4)=ini_helix.dz();
926 a_helix(5)=ini_helix.tanl();
927 if(myDebugNb==2){
928 cout<<"helix at IP: "<<myVecHelix[i][0]<<", "<<myVecHelix[i][1]<<", "<<myVecHelix[i][2]<<", "<<myVecHelix[i][3]<<", "<<myVecHelix[i][4]<<endl;
929 cout<<"helix at innermost hit: "<<a_helix(1)<<", "<<a_helix(2)<<", "<<a_helix(3)<<", "<<a_helix(4)<<", "<<a_helix(5)<<endl;
930 cout<<"innermost hit position: r="<<posTruth_mdc.perp()<<", phi="<<posTruth_mdc.phi()<<endl;
931 }
932 }
933 else if(myIniHelix==3) // --- helix at innermost hit in CGEM/MDC
934 {
935 //helix Taubin_circle_fit();
936 //Hough_dz_tanL();
937 //helix
938
939 HepPoint3D posTruth_mdc(pos_innermost[0]/10., pos_innermost[1]/10., pos_innermost[2]/10.);//mm->cm
940 Hep3Vector p3Truth(p3_innermost[0]/1000., p3_innermost[1]/1000., p3_innermost[2]/1000.);//MeV->GeV
941 double charge=myVecHelix[i][2]/fabs(myVecHelix[i][2]);
942 KalmanFit::Helix ini_helix(posTruth_mdc,p3Truth,charge);
943 ini_helix.pivot(origin);
944 if(myVecCgemXcluster.size()+nMdcXHits>=3) {
945 vector<double> circleParVec = myDotsHelixFitter.calculateCirclePar_Taubin();
946 a_helix(1)=circleParVec[0];
947 a_helix(2)=circleParVec[1];
948 a_helix(3)=circleParVec[2];
949 }
950 else {
951 a_helix(1)=ini_helix.dr();
952 a_helix(2)=ini_helix.phi0();
953 a_helix(3)=ini_helix.kappa();
954 }
955 a_helix(4)=ini_helix.dz();
956 a_helix(5)=ini_helix.tanl();
957 }
958 //cout<<" ini helix "<<endl;
959 KalmanFit::Helix ini_helix(origin,a_helix);
960 //cout<<" after ini helix "<<endl;
961 myDotsHelixFitter.setInitialHelix(ini_helix);
962 //cout<<" set ini helix "<<endl;
963
964 myDotsHelixFitter.fitCircleOnly();
965 //myDotsHelixFitter.useAxialHitsOnly();
966 //cout<<" set fit circle only "<<endl;
967 int nIter=0;
968 while(1)
969 {
970 //cout<<" circle fit iter "<<nIter<<endl;
971 fitFlag = myDotsHelixFitter.calculateNewHelix();
972 //cout<<" finish one circle fit "<<endl;
973 nIter++;
974 //if(fitFlag!=0) break;
975 if(fitFlag==0)
976 {
977 if(myNtProd&1 && nIter==1) {
978 myNHitsCircle=0;
979 // --- fill CGEM clusters
980 vector<double> vecChiCgem = myDotsHelixFitter.getVecChiCgemCluster();
981 vector<const RecCgemCluster*>::iterator it_cluster=myVecCgem1DCluster.begin();
982 int i_cluster=0;
983 for(; it_cluster!=myVecCgem1DCluster.end(); it_cluster++, i_cluster++)
984 {
985 int flag=(*it_cluster)->getflag();
986 if(flag!=0) continue;
987 int layer=(*it_cluster)->getlayerid();
988 //if(flag==1) layer=-1*(layer+1);// for V-cluster
989 if(myNHitsCircle<100)
990 {
991 myLayerHitsCircle[myNHitsCircle]=layer;
992 myChiHitsCircle[myNHitsCircle] =vecChiCgem[i_cluster];
993 myNHitsCircle++;
994 }
995 }
996
997 // --- fill MDC hits
998 vector<const MdcDigi*>::iterator it_digi=myVecMdcDigi.begin();
999 vector<double> vecChiMdc = myDotsHelixFitter.getVecChiMdcDigi();
1000 vector<int> vecIsActMdc = myDotsHelixFitter.getVecMdcDigiIsAct();
1001 int i_digi=0;
1002 for(; it_digi!=myVecMdcDigi.end(); it_digi++, i_digi++)
1003 {
1004 //if(vecIsActMdc[i_digi]==0) continue;
1005 Identifier id = (*it_digi)->identify();
1006 int layer = MdcID::layer(id);
1007 if(myWireFlag[layer]!=0) continue;
1008 if(myNHitsCircle<100)
1009 {
1010 myLayerHitsCircle[myNHitsCircle]=layer;
1011 myChiHitsCircle[myNHitsCircle] =vecChiMdc[i_digi];
1012 myNHitsCircle++;
1013 }
1014 }
1015 }
1016 }
1017 else break;
1018 if(myDotsHelixFitter.deactiveHits(myChiCut_circle,myNmaxDeact_circle)==0) break;
1019 if(nIter>100) break;
1020 }// iterations
1021 if(myDebug) {
1022 cout<<"initial helix "<<ini_helix.a()<<endl;
1023 cout<<"fitFlag="<<fitFlag<<endl;
1024 cout<<"nIter="<<nIter<<endl;
1025 cout<<"fitted circle "<<myDotsHelixFitter.getHelix()<<endl;
1026 cout<<"circle chi2="<<myDotsHelixFitter.getChi2()<<endl;
1027 cout<<"circle error="<<myDotsHelixFitter.getEa()<<endl<<endl;
1028 }
1029 //cout<<"circle fitting nIter="<<nIter<<endl;
1030 if(fitFlag==0) {
1031 myDotsHelixFitter.fitModeHelix();
1032 nIter=0;
1033 while(1)
1034 {
1035 fitFlag = myDotsHelixFitter.calculateNewHelix();
1036 nIter++;
1037 if(fitFlag!=0) break;
1038 if(myDotsHelixFitter.deactiveHits(myChiCut_helix,myNmaxDeact_helix)==0) break;
1039 //if(nIter>100) break;
1040 }
1041 while(1)
1042 {
1043 if(fitFlag!=0) break;
1044 if(myDotsHelixFitter.activeHits(myChiCut_helix)==0) break;
1045 fitFlag = myDotsHelixFitter.calculateNewHelix();
1046 nIter++;
1047 //if(nIter>100) break;
1048 }
1049 if(myDebug) {
1050 cout<<"fitFlag="<<fitFlag<<endl;
1051 cout<<"fitted helix "<<myDotsHelixFitter.getHelix()<<endl;
1052 cout<<"helix chi2="<<myDotsHelixFitter.getChi2()<<endl;
1053 cout<<"helix error="<<myDotsHelixFitter.getEa()<<endl;
1054 }
1055 //cout<<"helix fitting nIter="<<nIter<<endl;
1056 }
1057 }
1058 else if(myDebug){
1059 cout<<" Didn't found enough hits!!!!"<<endl;
1060 }
1061
1062 //myWatch_fitting.Stop();
1063
1064 // --- save good track to RecMdcTrackCol and fill ntuple
1065 //cout<<"before fill myArrayHelixMC"<<endl;
1066 if(myNtProd&1) {
1067 myNHits=0;
1068 myRUN=myRun;
1069 myEVT=myEvt;
1070 //cout<<"fill 1"<<endl;
1071 myPID=myVecPDG[i];
1072 //cout<<"fill 2"<<endl;
1073 myNPar=5;
1074 myNXHits=nMdcXHits;
1075 myNVHits=nMdcVHits;
1076 myNXCluster=myVecCgemXcluster.size();
1077 myNVCluster=myVecCgemVcluster.size();
1078 //cout<<"fill 3"<<endl;
1079 myArrayHelixMC[0]=myVecHelix[i][0];
1080 //cout<<"fill 4"<<endl;
1081 myArrayHelixMC[1]=myVecHelix[i][1];
1082 myArrayHelixMC[2]=myVecHelix[i][2];
1083 myArrayHelixMC[3]=myVecHelix[i][3];
1084 myArrayHelixMC[4]=myVecHelix[i][4];
1085 myTrkIdBest=-1;
1086 myNHitsBestTrk=0;
1087 myNSameHitsBestTrk=0;
1088 }
1089 //cout<<"after fill myArrayHelixMC"<<endl;
1090 if(fitFlag==0)
1091 {
1092 saveARecMdcTrack(i);
1093
1094 if(myNtProd&1) {
1095 // --- fill CGEM clusters
1096 vector<double> vecChiCgem = myDotsHelixFitter.getVecChiCgemCluster();
1097 vector<const RecCgemCluster*>::iterator it_cluster=myVecCgem1DCluster.begin();
1098 int i_cluster=0;
1099 for(; it_cluster!=myVecCgem1DCluster.end(); it_cluster++, i_cluster++)
1100 {
1101 int flag=(*it_cluster)->getflag();
1102 int layer=(*it_cluster)->getlayerid();
1103 if(flag==1) layer=-1*(layer+1);// for V-cluster
1104 if(myNHits<100)
1105 {
1106 myLayerHits[myNHits]=layer;
1107 myChiHits[myNHits] =vecChiCgem[i_cluster];
1108 myNHits++;
1109 }
1110 }
1111
1112 // --- fill MDC hits
1113 vector<const MdcDigi*>::iterator it_digi=myVecMdcDigi.begin();
1114 vector<double> vecChiMdc = myDotsHelixFitter.getVecChiMdcDigi();
1115 vector<int> vecIsActMdc = myDotsHelixFitter.getVecMdcDigiIsAct();
1116 int i_digi=0;
1117 for(; it_digi!=myVecMdcDigi.end(); it_digi++, i_digi++)
1118 {
1119 if(vecIsActMdc[i_digi]==0) continue;
1120 Identifier id = (*it_digi)->identify();
1121 int layer = MdcID::layer(id);
1122 if(myNHits<100)
1123 {
1124 myLayerHits[myNHits]=layer;
1125 myChiHits[myNHits] =vecChiMdc[i_digi];
1126 myNHits++;
1127 }
1128
1129 }
1130 }// if myNtProd&1
1131 }
1132
1133 // --- write out ntuple
1134 if(myNtProd&1) myNtHelixFitter->write();
1135
1136 }// loop MC tracks
1137
1138 return;
1139}
1140
1141/**
1142 * @brief calls myRawDataProviderSvc->getMdcDigiVec()
1143 *
1144 * @return vector<const MdcDigi*>
1145 */
1146vector<const MdcDigi*> DotsConnection::getMdcDigiVec()
1147{
1148 uint32_t getDigiFlag = 0;
1149 /*
1150 getDigiFlag += m_maxMdcDigi;
1151 if(m_dropHot) getDigiFlag |= MdcRawDataProvider::b_dropHot;
1152 if(m_keepBadTdc) getDigiFlag |= MdcRawDataProvider::b_keepBadTdc;
1153 if(m_keepUnmatch) getDigiFlag |= MdcRawDataProvider::b_keepUnmatch;
1154 */
1155 MdcDigiVec mdcDigiVec = myRawDataProviderSvc->getMdcDigiVec(getDigiFlag);
1156 if(myDebug)
1157 cout<<"DotsConnection::getMdcDigiVec() get "<<mdcDigiVec.size()<<" MDC digis from RawDataProviderSvc"<<endl;
1158 ///*
1159 // MdcDigiVec aMdcDigiVec;
1160 vector<const MdcDigi*> aMdcDigiVec;
1161 vector<MdcDigi*>::iterator iter_mdcDigi = mdcDigiVec.begin();
1162 for(; iter_mdcDigi!=mdcDigiVec.end(); iter_mdcDigi++) {
1163 // --- get id, layer, wire ---
1164 //Identifier id = (*iter_mdcDigi)->identify();
1165 //int layer = MdcID::layer(id);
1166
1167 // --- only axial hits kept
1168 //if( (layer>=8&&layer<=19) || (layer>=36&&layer<=42) )
1169
1170 aMdcDigiVec.push_back(*iter_mdcDigi);
1171
1172 }
1173 return aMdcDigiVec;
1174 //*/
1175 //return mdcDigiVec;
1176}
1177
1178/**
1179 * @brief get time from last element of RecEsTimeCol with getTest()
1180 * and save results to myEvtT0
1181 *
1182 * @return double, the time
1183 */
1184double DotsConnection::getEventStartTime()
1185{
1186 double T0=0;
1187
1188 // --- get event start time ---
1189 SmartDataPtr<RecEsTimeCol> evTimeCol(eventSvc(),"/Event/Recon/RecEsTimeCol");
1190 if(evTimeCol){
1191 RecEsTimeCol::iterator iter_evt = evTimeCol->begin();
1192 if(iter_evt != evTimeCol->end()){
1193 //T0 = (*iter_evt)->getTest()*1.e-9;//m_bunchT0-s, getTest-ns
1194 T0 = (*iter_evt)->getTest();// getTest-ns
1195 }
1196 }
1197 else cout<<"error: DotsConnection::getEventStartTime() failed to access event start time"<<endl;
1198 myEvtT0=T0;
1199
1200 return T0;
1201}
1202
1203double DotsConnection::getRoughDD(const MdcDigi* aMdcDigi)
1204{
1205 Identifier id = aMdcDigi->identify();
1206 int layer = MdcID::layer(id);
1207 //if( (layer>=8&&layer<=19) || (layer>=36&&layer<=42) ) // --- only axial hits kept
1208 int wire = MdcID::wire(id);
1209
1210 double rawTime = RawDataUtil::MdcTime(aMdcDigi->getTimeChannel());
1211 double tprop = myMdcCalibFunSvc->getTprop(layer, 0);
1212 double charge = aMdcDigi->getChargeChannel();
1213 double T0Walk = myMdcCalibFunSvc->getT0(layer,wire) + myMdcCalibFunSvc->getTimeWalk(layer, charge);
1214 double TOF = myRLayer[layer]/Constants::c*1.0e9*1.28;// in ns
1215 double driftT = rawTime - myEvtT0 - TOF - T0Walk - tprop;
1216
1217 int lrCalib=2;
1218 double entranceAngle = 0;
1219 double driftDist = 0.1 * myMdcCalibFunSvc->driftTimeToDist(driftT,layer,wire,lrCalib,entranceAngle);// in cm
1220
1221 return driftDist;
1222
1223}
1224
1225void DotsConnection::testDotsHelixFitterAllHits()
1226{
1227 // --- set MC helix
1228 KalmanFit::Helix ini_helix = getMCHelix();
1229 myDotsHelixFitter.setInitialHelix(ini_helix);
1230
1231 // --- get all MDC digi
1232 vector<const MdcDigi*> vecDigi = getMdcDigiVec();
1233
1234 // --- get event start time
1235 double T0 = getEventStartTime();// in ns
1236 //cout<<"DotsConnection::testDotsHelixFitterAllHits() T0 = "<<T0<<endl;
1237 //myDotsHelixFitter.setT0(T0);
1238
1239 // --- set DC digi to DotsHelixFitter
1240 myDotsHelixFitter.setDChits(vecDigi,T0);
1241
1242 // --- get DC digi ordered with the fligth length
1243 vector<const MdcDigi*>::iterator iter_mdcDigi = vecDigi.begin();
1244 map<double, const MdcDigi*> aMapDcDigi;
1245 for(; iter_mdcDigi!=vecDigi.end(); iter_mdcDigi++)
1246 {
1247 aMapDcDigi[myDotsHelixFitter.getFlightLength(*iter_mdcDigi)] = *iter_mdcDigi;
1248 }
1249
1250 vector<const RecCgemCluster*> vecCgemCluster = getCgemClusterVec();
1251 myDotsHelixFitter.setCgemClusters(vecCgemCluster);
1252
1253 myDotsHelixFitter.fitCircleOnly();
1254 myDotsHelixFitter.calculateNewHelix();
1255
1256 // --- fill a NTuple ---
1257 myNPar=5;
1258 HepVector a = ini_helix.a();
1259 HepVector a_new = myDotsHelixFitter.getHelix();
1260 for(int i=0; i<5; i++)
1261 {
1262 myArrayHelixMC[i]=a[i];
1263 myArrayHelixFitted[i]=a_new[i];
1264 }
1265 myNtHelixFitter->write();
1266}
1267
1268bool DotsConnection::getCgemClusterIntersection(int idx_Xclu, int idx_Vclu, double& z)
1269{
1270 RecCgemClusterCol::iterator iter_Xclu = myIterCgemClusterBegin+idx_Xclu;
1271 int flag = (*iter_Xclu)->getflag();
1272 if(flag!=0) return false;
1273 int layer = (*iter_Xclu)->getlayerid();
1274 int sheet = (*iter_Xclu)->getsheetid();
1275
1276 RecCgemClusterCol::iterator iter_Vclu = myIterCgemClusterBegin+idx_Vclu;
1277 int flagV = (*iter_Vclu)->getflag();
1278 if(flagV!=1||(*iter_Vclu)->getlayerid()!=layer||(*iter_Vclu)->getsheetid()!=sheet) return false;
1279
1280 double phi = (*iter_Xclu)->getrecphi();
1281 double V_loc = (*iter_Vclu)->getrecv();
1282 CgemGeoReadoutPlane* readoutPlane= myCgemGeomSvc->getReadoutPlane(layer,sheet);
1283 z = readoutPlane->getZFromPhiV(phi,V_loc); // in mm
1284
1285 if(readoutPlane->OnThePlane(phi,z)) {
1286 z*=0.1;// in cm
1287 return true;
1288 }
1289 else return false;
1290}
1291
1292vector<const RecCgemCluster*> DotsConnection::getCgemClusterVec(int view)
1293{
1294 vector<const RecCgemCluster*> aVecCgemCluster;
1295 SmartDataPtr<RecCgemClusterCol> aCgemClusterCol(eventSvc(),"/Event/Recon/RecCgemClusterCol");
1296 if(aCgemClusterCol)
1297 {
1298 RecCgemClusterCol::iterator iter_cluster=aCgemClusterCol->begin();
1299 int nCluster = aCgemClusterCol->size();
1300 //cout<<"DotsConnection::getCgemClusterVec() finds a RecCgemClusterCol with "<<nCluster<<" clusters!"<<endl;
1301 // cout<<"~~~~~~~~~~~~~~~~~~~~~~~~ check RecCgemClusterCol:"<<endl;
1302 // cout <<setw(10)<<"idx"
1303 // <<setw(10)<<"layer"
1304 // <<setw(10)<<"sheet"
1305 // <<setw(10)<<"XVFlag"
1306 // <<setw(10)<<"id1 ~"
1307 // <<setw(10)<<"id2"
1308 // <<setw(15)<<"phi"
1309 // <<setw(15)<<"V"
1310 // <<setw(15)<<"z"
1311 // <<endl;
1312 for(; iter_cluster!=aCgemClusterCol->end(); iter_cluster++)
1313 {
1314 // cout <<setw(10)<<(*iter_cluster)->getclusterid()
1315 // <<setw(10)<<(*iter_cluster)->getlayerid()
1316 // <<setw(10)<<(*iter_cluster)->getsheetid()
1317 // <<setw(10)<<(*iter_cluster)->getflag()
1318 // <<setw(10)<<(*iter_cluster)->getclusterflagb()
1319 // <<setw(10)<<(*iter_cluster)->getclusterflage()
1320 // <<setw(15)<<setprecision(10)<<(*iter_cluster)->getrecphi()
1321 // <<setw(15)<<setprecision(10)<<(*iter_cluster)->getrecv()
1322 // <<setw(15)<<setprecision(10)<<(*iter_cluster)->getRecZ()
1323 // <<endl;
1324 int flag = (*iter_cluster)->getflag();
1325 if(view==0||view==1)
1326 {
1327 if(flag==view) aVecCgemCluster.push_back(*iter_cluster);
1328 }else if(view=2)
1329 {
1330 if(flag==0||flag==1) aVecCgemCluster.push_back(*iter_cluster);
1331 }
1332 }
1333 // cout<<"~~~~~~~~~~~~~~~~~~~~~~~~"<<endl;
1334 }
1335 else cout<<"DotsConnection::getCgemClusterVec() does not find RecCgemClusterCol!"<<endl;
1336 return aVecCgemCluster;
1337}
1338
1339/**
1340 * @brief got myVecCgem{X,V}ClusterIdx from RecCgemClusterCol;
1341 * and set myVecCgemVClusterTrkIdx same size but valued -1.
1342 *
1343 * @return true
1344 * @return false
1345 */
1346bool DotsConnection::getCgemClusters()
1347{
1348 for(int i=0; i<3; i++)
1349 {
1350 myVecCgemXClusterIdx[i].clear();
1351 myVecCgemVClusterIdx[i].clear();
1352 myVecCgemXClusterTrkIdx[i].clear();
1353 myVecCgemVClusterTrkIdx[i].clear();
1354 }
1355
1356 SmartDataPtr<RecCgemClusterCol> aCgemClusterCol(eventSvc(),"/Event/Recon/RecCgemClusterCol");
1357 if(aCgemClusterCol)
1358 {
1359 //myPntRecCgemClusterCol=aCgemClusterCol;
1360 myIterCgemClusterBegin=aCgemClusterCol->begin();
1361 myIterCgemClusterEnd=aCgemClusterCol->end();
1362 myIterClu=myIterCgemClusterBegin;
1363 int nCluster = aCgemClusterCol->size();
1364 for(int i=0; i<nCluster; i++, myIterClu++)
1365 {
1366 int flag = (*myIterClu)->getflag();
1367 int layer= (*myIterClu)->getlayerid();
1368 if(flag==0) myVecCgemXClusterIdx[layer].push_back(i);
1369 else if(flag==1) myVecCgemVClusterIdx[layer].push_back(i);
1370 }
1371 for(int i=0; i<3; i++) {
1372 int size = myVecCgemXClusterIdx[i].size();
1373 myVecCgemXClusterTrkIdx[i].resize(size, -1);
1374 size = myVecCgemVClusterIdx[i].size();
1375 myVecCgemVClusterTrkIdx[i].resize(size, -1);
1376 }
1377 return true;
1378 }
1379 else return false;
1380}
1381
1382void DotsConnection::testDotsHelixFitterPartHits()
1383{
1384 // --- set MC helix
1385 KalmanFit::Helix ini_helix = getMCHelix();
1386 myDotsHelixFitter.setInitialHelix(ini_helix);
1387
1388 // --- get all MDC digi
1389 vector<const MdcDigi*> vecDigi = getMdcDigiVec();
1390
1391 // --- get event start time
1392 double T0 = getEventStartTime();// in ns
1393 //cout<<"DotsConnection::testDotsHelixFitterPartHits() T0 = "<<T0<<endl;
1394 myDotsHelixFitter.setT0(T0);
1395
1396 // --- set DC digi to DotsHelixFitter
1397 //myDotsHelixFitter.setDChits(vecDigi,T0);
1398
1399 // --- get DC digi ordered with the fligth length
1400 vector<const MdcDigi*>::iterator iter_mdcDigi = vecDigi.begin();
1401 map<double, const MdcDigi*> aMapDcDigi;
1402 for(; iter_mdcDigi!=vecDigi.end(); iter_mdcDigi++)
1403 {
1404 aMapDcDigi[myDotsHelixFitter.getFlightLength(*iter_mdcDigi)] = *iter_mdcDigi;
1405 }
1406
1407 int layerUdStudy=8;
1408 int layerUsed=6;
1409 vector<const MdcDigi*> smallVecDigi;
1410 map<double, const MdcDigi*>::iterator iter_digi = aMapDcDigi.begin();
1411 int nLayerCount=-1;
1412 const MdcDigi* digiUdStudy=NULL;
1413 for(; iter_digi!=aMapDcDigi.end(); iter_digi++)
1414 {
1415 const MdcDigi* aDigi = iter_digi->second;
1416 int layer = myDotsHelixFitter.getLayer(aDigi);
1417 if(layer==layerUdStudy)
1418 {
1419 digiUdStudy=aDigi;
1420 nLayerCount=0;
1421 }
1422 if(layer>layerUdStudy&&nLayerCount>=0&&nLayerCount<layerUsed)
1423 {
1424 smallVecDigi.push_back(aDigi);
1425 nLayerCount++;
1426 }
1427 if(nLayerCount==layerUsed) break;
1428 }
1429 if( digiUdStudy!=NULL && nLayerCount==layerUsed )
1430 {
1431 myDotsHelixFitter.setDChits(smallVecDigi,T0);
1432 myDotsHelixFitter.fitCircleOnly();
1433 myDotsHelixFitter.calculateNewHelix();
1434 double doca = myDotsHelixFitter.getDocaFromTrk(digiUdStudy);
1435 //cout<<"layer "<<layerUdStudy<<" doca prediction from outer "<<layerUsed<<" digis : "<<doca<<endl;
1436 }
1437
1438
1439 // --- fill a NTuple ---
1440 /*
1441 myNPar=5;
1442 HepVector a = ini_helix.a();
1443 HepVector a_new = myDotsHelixFitter.getHelix();
1444 for(int i=0; i<5; i++)
1445 {
1446 myArrayHelixMC[i]=a[i];
1447 myArrayHelixFitted[i]=a_new[i];
1448 }
1449 myNtHelixFitter->write();
1450 */
1451}
1452
1453
1454void DotsConnection::clearMdcDigiPointer()
1455{
1456 for(int i=0; i<43; i++)
1457 for(int j=0; j<288; j++)
1458 myMdcDigiPointer[i][j]=NULL;
1459}
1460
1461/**
1462 * @brief register eventSvc, myRecMdcTrackCol, myRecMdcHitCol
1463 *
1464 * @return true successful in register.
1465 * @return false
1466 */
1467bool DotsConnection::registerRecMdcTrack()
1468{
1469 MsgStream log(msgSvc(), name());
1470 StatusCode sc;
1471 IDataProviderSvc* eventSvc = NULL;
1472 service("EventDataSvc", eventSvc);
1473 if (eventSvc) {
1474 log << MSG::INFO << "makeTds:event Svc has been found" << endreq;
1475 } else {
1476 log << MSG::FATAL << "makeTds:Could not find eventSvc" << endreq;
1477 return false;
1478 }
1479 IDataManagerSvc *dataManSvc = dynamic_cast<IDataManagerSvc*>(eventSvc);;
1480
1481 // --- register RecMdcTrackCol
1482 myRecMdcTrackCol = NULL; // new RecMdcTrackCol;
1483 DataObject *aRecMdcTrackCol;
1484 eventSvc->findObject("/Event/Recon/RecMdcTrackCol",aRecMdcTrackCol);
1485 if(aRecMdcTrackCol != NULL)
1486 {
1487 myRecMdcTrackCol = dynamic_cast<RecMdcTrackCol*> (aRecMdcTrackCol);
1488 //dataManSvc->clearSubTree("/Event/Recon/RecMdcTrackCol");
1489 //eventSvc->unregisterObject("/Event/Recon/RecMdcTrackCol");
1490 }
1491 else {
1492 myRecMdcTrackCol = new RecMdcTrackCol;
1493 sc = eventSvc->registerObject("/Event/Recon/RecMdcTrackCol", myRecMdcTrackCol);
1494 if(sc.isFailure()) {
1495 log << MSG::FATAL << " Could not register RecMdcTrack collection" <<endreq;
1496 return false;
1497 }
1498 log << MSG::INFO << "RecMdcTrackCol registered successfully!" <<endreq;
1499 }
1500
1501 DataObject *aRecMdcHitCol;
1502 eventSvc->findObject("/Event/Recon/RecMdcHitCol",aRecMdcHitCol);
1503 if(aRecMdcHitCol != NULL) {
1504 //dataManSvc->clearSubTree("/Event/Recon/RecMdcHitCol");
1505 //eventSvc->unregisterObject("/Event/Recon/RecMdcHitCol");
1506 myRecMdcHitCol=dynamic_cast<RecMdcHitCol*> (aRecMdcHitCol);
1507 }
1508 else {
1509 myRecMdcHitCol= new RecMdcHitCol;
1510
1511 sc = eventSvc->registerObject("/Event/Recon/RecMdcHitCol", myRecMdcHitCol);
1512 if(sc.isFailure()) {
1513 log << MSG::FATAL << " Could not register RecMdcHit collection" <<endreq;
1514 return false;
1515 }
1516 log << MSG::INFO << "RecMdcHitCol registered successfully!" <<endreq;
1517 }
1518
1519 return true;
1520}
1521
1522bool sortCluster(const RecCgemCluster* clusterA , const RecCgemCluster* clusterB){
1523 return clusterA->getlayerid()<clusterB->getlayerid();
1524}
1525
1526bool DotsConnection::saveARecMdcTrack(int iTrk)
1527{
1528 int tkStat =4;
1529
1530 RecMdcTrack* recMdcTrack = new RecMdcTrack();
1531
1532 int trackId = myRecMdcTrackCol->size();
1533 recMdcTrack->setTrackId(trackId);
1534
1535 double helixPar[5];
1536 HepVector aHelixVec = myDotsHelixFitter.getHelix();
1537 helixPar[0]=aHelixVec[0];
1538 helixPar[1]=aHelixVec[1];
1539 helixPar[2]=aHelixVec[2];
1540 helixPar[3]=aHelixVec[3];
1541 helixPar[4]=aHelixVec[4];//helixPar[4]+=0.1;
1542 recMdcTrack->setHelix(helixPar);
1543
1544 // --- for ntuple
1545 if(myNtProd&1) {
1546 myArrayHelixFitted[0]=aHelixVec[0];
1547 myArrayHelixFitted[1]=aHelixVec[1];
1548 myArrayHelixFitted[2]=aHelixVec[2];
1549 myArrayHelixFitted[3]=aHelixVec[3];
1550 myArrayHelixFitted[4]=aHelixVec[4];
1551 }
1552
1553 int q = helixPar[2]>0? 1:-1;
1554 KalmanFit::Helix aHelix = myDotsHelixFitter.getClassHelix();
1555 double pxy = aHelix.pt();
1556 double px = aHelix.momentum(0).x();
1557 double py = aHelix.momentum(0).y();
1558 double pz = aHelix.momentum(0).z();
1559 double p = aHelix.momentum(0).mag();
1560 double theta = aHelix.direction(0).theta();
1561 double phi = aHelix.direction(0).phi();
1562 HepPoint3D poca = aHelix.x(0);
1563 HepPoint3D pivot = aHelix.pivot();
1564 double r = poca.perp();
1565 HepSymMatrix Ea = aHelix.Ea();
1566 //cout<<"Ea="<<Ea<<endl;
1567 double errorMat[15];
1568 int k = 0;
1569 for (int ie = 0 ; ie < 5 ; ie ++){
1570 for (int je = ie ; je < 5 ; je ++){
1571 errorMat[k] = Ea[ie][je];
1572 k++;
1573 }
1574 }
1575 double chisq = myDotsHelixFitter.getChi2();
1576 recMdcTrack->setCharge(q);
1577 recMdcTrack->setPxy(pxy);
1578 recMdcTrack->setPx(px);
1579 recMdcTrack->setPy(py);
1580 recMdcTrack->setPz(pz);
1581 recMdcTrack->setP(p);
1582 recMdcTrack->setTheta(theta);
1583 recMdcTrack->setPhi(phi);
1584 recMdcTrack->setPoca(poca);
1585 recMdcTrack->setX(poca.x());//poca
1586 recMdcTrack->setY(poca.y());
1587 recMdcTrack->setZ(poca.z());
1588 recMdcTrack->setR(sqrt(poca.x()*poca.x() + poca.y()*poca.y()));
1589 HepPoint3D apivot(0.,0.,0.);
1590 recMdcTrack->setPivot(apivot);
1591 recMdcTrack->setVX0(0.);//pivot
1592 recMdcTrack->setVY0(0.);
1593 recMdcTrack->setVZ0(0.);
1594 recMdcTrack->setError(errorMat);
1595 recMdcTrack->setError(Ea);
1596 recMdcTrack->setChi2(chisq);
1597 //recMdcTrack->setStat(tkStat);
1598 recMdcTrack->setStat(myVecPDG[iTrk]);
1599
1600 int maxLayerId = -1;
1601 int minLayerId = 43;
1602 double fiTerm = 0.;
1603 double fltLen = -0.00001;
1604 int layerMaxFltLen=-1;
1605
1606 // --- CGEM clusters
1607 vector<double> vecChiCgem = myDotsHelixFitter.getVecChiCgemCluster();
1608 //vector<const RecCgemCluster*> vecCgemClu = myDotsHelixFitter.getVecCgemCluster();
1609 vector<const RecCgemCluster*>::iterator it_cluster=myVecCgem1DCluster.begin();
1610 int i_cluster=0;
1611 for(; it_cluster!=myVecCgem1DCluster.end(); it_cluster++, i_cluster++)
1612 {
1613 int flag=(*it_cluster)->getflag();
1614 int layer=(*it_cluster)->getlayerid();
1615 int sheet=(*it_cluster)->getsheetid();
1616 if(fabs(vecChiCgem[i_cluster]+9999)<1e-10)
1617 cout<<"vecChiCgem="<<vecChiCgem[i_cluster]<<endl;
1618 if(flag==0) myVecCgemXCluChi[layer][sheet].push_back(vecChiCgem[i_cluster]);
1619 else if(flag==1) myVecCgemVCluChi[layer][sheet].push_back(vecChiCgem[i_cluster]);
1620 }
1621 ClusterRefVec clusterRefVec;
1622 map<int,int> clusterFitStat;
1623 SmartDataPtr<RecCgemClusterCol> aCgemClusterCol(eventSvc(),"/Event/Recon/RecCgemClusterCol");
1624 if(!aCgemClusterCol) cout<<"DotsConnection::saveARecMdcTrack() does not find RecCgemClusterCol!"<<endl;
1625 else {
1626 RecCgemClusterCol::iterator iter_cluster_begin=aCgemClusterCol->begin();
1627 RecCgemClusterCol::iterator iter_cluster=iter_cluster_begin;
1628 for(; iter_cluster!=aCgemClusterCol->end(); iter_cluster++)
1629 {
1630 int flag = (*iter_cluster)->getflag();
1631 if(flag!=2) continue;// skip 1D clusters
1632 int layer=(*iter_cluster)->getlayerid();
1633 int sheet=(*iter_cluster)->getsheetid();
1634 int idXClu = (*iter_cluster)->getclusterflagb();
1635 bool matchX=false;
1636 vector<int>::iterator iter=myVecCgemXCluIdx[layer][sheet].begin();
1637 i_cluster=0;
1638 for(; iter!=myVecCgemXCluIdx[layer][sheet].end(); iter++, i_cluster++)
1639 if((*iter)==idXClu && fabs(myVecCgemXCluChi[layer][sheet][i_cluster]+9999)>1e-10)
1640 matchX=true;
1641 if(!matchX) continue;
1642 int idVClu = (*iter_cluster)->getclusterflage();
1643 bool matchV=false;
1644 iter=myVecCgemVCluIdx[layer][sheet].begin();
1645 for(; iter!=myVecCgemVCluIdx[layer][sheet].end(); iter++)
1646 if((*iter)==idVClu) matchV=true;
1647 if(matchV)
1648 {
1649 const RecCgemCluster* recCgemCluster = (*iter_cluster);
1650 int clusterid = recCgemCluster->getclusterid();
1651 clusterRefVec.push_back(recCgemCluster);
1652 clusterFitStat[clusterid] = 1;
1653 if(maxLayerId<layer)
1654 {
1655 maxLayerId=layer;
1656 }
1657 }
1658 }
1659 }
1660
1661
1662 // --- MDC hits
1663 set<int> setMdcIdt;
1664 int hitId = 0;
1665 HitRefVec hitRefVec;
1666 vector<RecMdcHit> aRecMdcHitVec=myDotsHelixFitter.makeRecMdcHitVec(1);
1667 int nMdcHits=aRecMdcHitVec.size();
1668 int nMdcHitsKept=0;
1669 vector<RecMdcHit>::iterator iter_recMdcHit = aRecMdcHitVec.begin();
1670 for(; iter_recMdcHit!=aRecMdcHitVec.end(); iter_recMdcHit++)
1671 {
1672 if(iter_recMdcHit->getChisqAdd()>myMdcHitChi2Cut) // skip hit with chi2>myMdcHitChi2Cut
1673 continue;
1674
1675 RecMdcHit* recMdcHit = new RecMdcHit(*iter_recMdcHit);
1676 recMdcHit->setId(hitId);
1677 recMdcHit->setTrkId(trackId);
1678 recMdcHit->setStat(1);
1679 myRecMdcHitCol->push_back(recMdcHit);
1680 SmartRef<RecMdcHit> refHit(recMdcHit);
1681 hitRefVec.push_back(refHit);
1682 nMdcHitsKept++;
1683
1684 Identifier mdcid = recMdcHit->getMdcId();
1685 int layer = MdcID::layer(mdcid);
1686 int wire = MdcID::wire(mdcid);
1687 setMdcIdt.insert(layer*1000+wire);
1688 if(layer>maxLayerId)
1689 {
1690 maxLayerId = layer;
1691 }
1692 if(layer<minLayerId)
1693 {
1694 minLayerId = layer;
1695 }
1696 if(fltLen<recMdcHit->getFltLen()) {
1697 fltLen=recMdcHit->getFltLen();
1698 layerMaxFltLen=layer;
1699 }
1700 hitId++;
1701 }
1702 //if(myDebug)
1703 cout<<"track "<<trackId<<", "<<nMdcHitsKept<<"/"<<nMdcHits<<" MDC hits kept, "<<clusterRefVec.size()<<" 2D-clusters kept"<<endl;
1704
1705 // --- phi term (phi for the outmost hit/cluster)
1706 if(maxLayerId>=0&&maxLayerId<3) {
1707 double rmax=myDotsHelixFitter.getRmidGapCgem(maxLayerId);
1708 fltLen=aHelix.flightLength(rmax);
1709 }
1710 if(fltLen>0) fiTerm=-fltLen*sin(theta)/aHelix.radius();
1711 else {
1712 cout<<"fltLen<0!: maxLayerId="<<maxLayerId<<", n_cluster="<<clusterRefVec.size()<<", nMdcHitsKept="<<nMdcHitsKept<<endl;
1713 cout<<"myVecCgem1DCluster.size="<<myVecCgem1DCluster.size()<<endl;
1714 }
1715 recMdcTrack->setFiTerm(fiTerm);
1716
1717 // --- check fiTerm
1718 HepPoint3D posOut = aHelix.x(fiTerm);
1719 if(myDebug)
1720 cout<<"fiTerm, layer, fltLen, pos= "<<fiTerm<<", "<<layerMaxFltLen<<", "<<fltLen<<", "<<posOut<<endl;
1721
1722 // --- setN* functions called in setVec* functions
1723 recMdcTrack->setVecHits(hitRefVec);
1724 std::sort(clusterRefVec.begin(),clusterRefVec.end(),sortCluster);
1725 recMdcTrack->setVecClusters(clusterRefVec,clusterFitStat);
1726
1727 // --- check if any track share the same hits
1728 int n_CgemCluster(0), n_MdcHits(0), n_hits_tot(0);
1729 int n_sameCgemCluster(0), n_sameMdcHits(0), n_sameHit_tot(0);
1730 int bestTrkId(-1);
1731 RecMdcTrackCol::iterator iter_bestTrk;
1732 RecMdcTrackCol::iterator iter_trk = myRecMdcTrackCol->begin();
1733 for(; iter_trk!=myRecMdcTrackCol->end(); iter_trk++)
1734 {
1735 int stat =(*iter_trk)->stat();
1736 //if(stat!=4) break;
1737 //if(stat!=5) continue;
1738 n_sameCgemCluster=0;
1739 ClusterRefVec aClusterRefVec=(*iter_trk)->getVecClusters();
1740 n_CgemCluster=aClusterRefVec.size();
1741 ClusterRefVec::iterator itCluster=aClusterRefVec.begin();
1742 for(; itCluster!=aClusterRefVec.end(); itCluster++) {
1743 int clusterid = (*itCluster)->getclusterid();
1744 if(clusterFitStat.count(clusterid)) n_sameCgemCluster++;
1745 }
1746
1747 n_sameMdcHits=0;
1748 HitRefVec aHitRefVec = (*iter_trk)->getVecHits();
1749 n_MdcHits=aHitRefVec.size();
1750 HitRefVec::iterator it_hit = aHitRefVec.begin();
1751 for(; it_hit!=aHitRefVec.end(); it_hit++) {
1752 Identifier mdcid = (*it_hit)->getMdcId();
1753 int layid = MdcID::layer(mdcid);
1754 int localwid = MdcID::wire(mdcid);
1755 if(setMdcIdt.find(layid*1000+localwid)!=setMdcIdt.end()) n_sameMdcHits++;
1756 }
1757 if((n_sameMdcHits+2*n_sameCgemCluster)>n_sameHit_tot) {
1758 n_sameHit_tot=n_sameMdcHits+2*n_sameCgemCluster;
1759 n_hits_tot=n_MdcHits+2*n_CgemCluster;
1760 iter_bestTrk=iter_trk;
1761 bestTrkId=(*iter_trk)->trackId();
1762 }
1763 }
1764 if(myNtProd&1) {
1765 myTrkIdBest=bestTrkId;
1766 myNHitsBestTrk=n_hits_tot;
1767 myNSameHitsBestTrk=n_sameHit_tot;
1768 }
1769 if(bestTrkId!=-1) {
1770 int stat = (*iter_bestTrk)->stat();
1771 (*iter_bestTrk)->setStat(stat*100000*myVecPDG[iTrk]/abs(myVecPDG[iTrk])+myVecPDG[iTrk]);
1772 }
1773
1774 // --- put a new track into RecMdcTrackCol
1775 myRecMdcTrackCol->push_back(recMdcTrack);
1776
1777 return true;
1778}
1779
1780void DotsConnection::clearMdcNeighbours()
1781{
1782 //map<int, const MdcDigi*>::iterator iter_mapDigi = myMapMdcDigi.begin();
1783 //for(; iter_mapDigi!=myMapMdcDigi.end(); iter_mapDigi++)
1784 //{
1785 // int wireIdx=iter_mapDigi->first;
1786 // myMdcDigiGroup[wireIdx].Reset();
1787 //}
1788 for(int i=0; i<6796; i++) if(myMdcDigiGroup[i].GetNoNeiborHits()||myMdcDigiGroup[i].HasHit()) myMdcDigiGroup[i].Reset();
1789 //myMapMdcDigi.clear();
1790 //myOuterEnds.clear();
1791}
1792
1793/**
1794 * @brief save input into a std::map myMapMdcDigi with key=wireid
1795 *
1796 * @param vecMdcDigiPnt
1797 */
1798void DotsConnection::fillMdcDigiMap(vector<const MdcDigi*>& vecMdcDigiPnt)
1799{
1800 myMapMdcDigi.clear();
1801 vector<const MdcDigi*>::iterator iter_mdcDigi = vecMdcDigiPnt.begin();
1802 for(; iter_mdcDigi!=vecMdcDigiPnt.end(); iter_mdcDigi++)
1803 {
1804 // --- fill MDC digis
1805 Identifier id = (*iter_mdcDigi)->identify();
1806 int layer_id = MdcID::layer(id);
1807 int wire_id = MdcID::wire(id);
1808 int wireid = myMdcGeomSvc->Wire(layer_id,wire_id)->Id();
1809 //cout<<" layer, cell, wireidx = "<<layer_id<<", "<<wire_id<<", "<<wireid<<endl;
1810 //myMdcDigiGroup[wireid].AddHit((*iter_mdcDigi));// set MDC digi
1811 myMapMdcDigi[wireid]=*iter_mdcDigi;
1812 double dd = getRoughDD(*iter_mdcDigi);
1813 myMapMdcDigiDd[wireid]=dd;
1814 }
1815}
1816
1817/**
1818 * @brief anyway, added neighbour of digis, intra- and inter- layer, into myMdcDigiGroup
1819 *
1820 * @param aMapMdcDigi is not modified
1821 * @param SameLRange intra-layer range of neighbour, bi-directional
1822 * @param DiffLRange inter-layer range of neighbour, bi-directional
1823 */
1824void DotsConnection::buildMdcDigiNeighbors(map<int, const MdcDigi*>& aMapMdcDigi, int SameLRange, int DiffLRange)
1825{
1826 clearMdcNeighbours();
1827
1828 map<int, const MdcDigi*>::iterator iter_mapDigi = aMapMdcDigi.begin();
1829 for(; iter_mapDigi!=aMapMdcDigi.end(); iter_mapDigi++)
1830 {
1831 int wireid=iter_mapDigi->first;
1832 myMdcDigiGroup[wireid].AddHit(iter_mapDigi->second);// set MDC digi
1833
1834 // --- to fill neighbours at the same layer
1835 //cout<<" wireid "<<wireid<<endl;
1836 int wirePrev_tem=myMdcGeomSvc->Wire(wireid)->GetNeighborIDType1();
1837 //cout<<" previous idx "<<wirePrev_tem<<endl;
1838 //int wireNext_tem=myMdcDigiGroup[wireid].GetWire()->GetNeighborIDType2();
1839 int wireNext_tem=myMdcGeomSvc->Wire(wireid)->GetNeighborIDType2();
1840 for(int range=0;range<SameLRange;range++)
1841 {
1842 int prevWire = wirePrev_tem;
1843 if(aMapMdcDigi.find(prevWire)!=aMapMdcDigi.end()) myMdcDigiGroup[prevWire].AddNext(wireid, range);// add the current digi as the previous neighbor's next neighbor
1844 //cout<<" prevWire "<<prevWire<<endl;
1845 //wirePrev_tem=myMdcDigiGroup[prevWire].GetWire()->GetNeighborIDType1();// for the next range
1846 wirePrev_tem=myMdcGeomSvc->Wire(prevWire)->GetNeighborIDType1();// for the next range
1847 //cout<<" previous idx "<<wirePrev_tem<<endl;
1848 int nextWire = wireNext_tem;
1849 if(aMapMdcDigi.find(nextWire)!=aMapMdcDigi.end()) myMdcDigiGroup[nextWire].AddPrev(wireid, range);// add the current digi as right neighbour's left neighbour
1850 //wireNext_tem = myMdcDigiGroup[nextWire].GetWire()->GetNeighborIDType2();// for the next range
1851 wireNext_tem = myMdcGeomSvc->Wire(nextWire)->GetNeighborIDType2();// for the next range
1852 }
1853
1854 // --- to fill neighbours on inner and outer layers
1855 //vector<int> innerWires_tem=myMdcDigiGroup[wireid].GetWire()->GetNeighborIDType3();// inner wires
1856 //vector<int> outerWires_tem=myMdcDigiGroup[wireid].GetWire()->GetNeighborIDType4();// outer wires
1857 vector<int> innerWires_tem=myMdcGeomSvc->Wire(wireid)->GetNeighborIDType3();// inner wires
1858 vector<int> outerWires_tem=myMdcGeomSvc->Wire(wireid)->GetNeighborIDType4();// outer wires
1859 for(int range=0;range<DiffLRange;range++)
1860 {
1861 int flag = 0;// 1: if the same inner inner (or outer outer) wire found
1862 vector<int> innerWires = innerWires_tem;
1863 //cout<<" inner wires: ";
1864 for(unsigned int i=0;i<innerWires.size();i++){
1865 //cout<<innerWires[i]<<" ";
1866 if(aMapMdcDigi.find(innerWires[i])!=aMapMdcDigi.end()) myMdcDigiGroup[innerWires[i]].AddOuter(wireid, range);// add the current digi as inner wire's outer neighbour
1867 //vector<int> tem1 = myMdcDigiGroup[innerWires[i]].GetWire()->GetNeighborIDType3();// inner wire's inner wires
1868 vector<int> tem1 = myMdcGeomSvc->Wire(innerWires[i])->GetNeighborIDType3();// inner wire's inner wires
1869 vector<int> tem2 = innerWires_tem;// inner wires
1870 if(i==0){
1871 //innerWires_tem = myMdcDigiGroup[innerWires[i]].GetWire()->GetNeighborIDType3();//the 1st inner wire's inner wires
1872 innerWires_tem = myMdcGeomSvc->Wire(innerWires[i])->GetNeighborIDType3();//the 1st inner wire's inner wires
1873 }
1874 else{
1875 for(unsigned int k=0;k<tem1.size();k++){
1876 for(unsigned int j=0;j<tem2.size();j++){
1877 if(tem1.at(k)==tem2.at(j)){
1878 flag = 1;
1879 break;
1880 }
1881 }
1882 if(flag==0){
1883 innerWires_tem.push_back(tem1.at(k));// add new inner inner wires
1884 }
1885 flag = 0;
1886 }
1887 }
1888 }
1889 //cout<<endl;
1890
1891 vector<int> outerWires = outerWires_tem;
1892 //cout<<" N_outer ="<<outerWires.size()<<endl;
1893 //cout<<" outer wires: ";
1894 for(unsigned int i=0;i<outerWires.size();i++){
1895 //cout<<outerWires[i]<<" ";
1896 if(aMapMdcDigi.find(outerWires[i])!=aMapMdcDigi.end()) myMdcDigiGroup[outerWires[i]].AddInner(wireid, range);// add the current digi as the outer wire's inner neighbour
1897 //cout<<"wire "<<outerWires[i]<<" add digi at wire "<<wireid<<endl;
1898 //vector<int> tem1 = myMdcDigiGroup[outerWires[i]].GetWire()->GetNeighborIDType4();
1899 vector<int> tem1 = myMdcGeomSvc->Wire(outerWires[i])->GetNeighborIDType4();
1900 vector<int> tem2 = outerWires_tem;
1901 if(i==0){
1902 //outerWires_tem = myMdcDigiGroup[outerWires[i]].GetWire()->GetNeighborIDType4();
1903 outerWires_tem = myMdcGeomSvc->Wire(outerWires[i])->GetNeighborIDType4();
1904 }
1905 else{
1906 for(unsigned int k=0;k<tem1.size();k++){
1907 for(unsigned int j=0;j<tem2.size();j++){
1908 if(tem1.at(k)==tem2.at(j)){
1909 flag = 1;
1910 break;
1911 }
1912 }
1913 if(flag==0){
1914 outerWires_tem.push_back(tem1.at(k));// fill new outer outer wires
1915 }
1916 flag = 0;
1917 }
1918 }
1919 }// loop outter wires
1920 //cout<<endl;
1921 }// loop DiffLRange
1922 }// loop digi
1923}
1924
1925// modified from MdcUtilitySvc::ConnectionHitsGroup(...) which was developped by Zhou Hang
1926void DotsConnection::fillMdcDigiBuildNeighbors(vector<const MdcDigi*> vecMdcDigiPnt, int SameLRange, int DiffLRange)
1927{
1928 clearMdcNeighbours();
1929 //cout<<"test 2"<<endl;
1930 //myMdcDigiGroup[503].GetWire()->GetNeighborIDType1();
1931 //cout<<"test 2 done "<<endl;
1932
1933 vector<const MdcDigi*>::iterator iter_mdcDigi = vecMdcDigiPnt.begin();
1934 for(; iter_mdcDigi!=vecMdcDigiPnt.end(); iter_mdcDigi++)
1935 {
1936 // --- fill MDC digis
1937 Identifier id = (*iter_mdcDigi)->identify();
1938 int layer_id = MdcID::layer(id);
1939 int wire_id = MdcID::wire(id);
1940 int wireid = myMdcGeomSvc->Wire(layer_id,wire_id)->Id();
1941 //cout<<" layer, cell, wireidx = "<<layer_id<<", "<<wire_id<<", "<<wireid<<endl;
1942 myMdcDigiGroup[wireid].AddHit((*iter_mdcDigi));// set MDC digi
1943 myMapMdcDigi[wireid]=*iter_mdcDigi;
1944
1945 // --- to fill neighbours at the same layer
1946 //cout<<" wireid "<<wireid<<endl;
1947 //int wirePrev_tem=myMdcDigiGroup[wireid].GetWire()->GetNeighborIDType1();
1948 int wirePrev_tem=myMdcGeomSvc->Wire(wireid)->GetNeighborIDType1();
1949 //cout<<" previous idx "<<wirePrev_tem<<endl;
1950 //int wireNext_tem=myMdcDigiGroup[wireid].GetWire()->GetNeighborIDType2();
1951 int wireNext_tem=myMdcGeomSvc->Wire(wireid)->GetNeighborIDType2();
1952 for(int range=0;range<SameLRange;range++)
1953 {
1954 int prevWire = wirePrev_tem;
1955 myMdcDigiGroup[prevWire].AddNext(wireid);// add the current digi as the previous neighbor's next neighbor
1956 //cout<<" prevWire "<<prevWire<<endl;
1957 //wirePrev_tem=myMdcDigiGroup[prevWire].GetWire()->GetNeighborIDType1();// for the next range
1958 wirePrev_tem=myMdcGeomSvc->Wire(prevWire)->GetNeighborIDType1();// for the next range
1959 //cout<<" previous idx "<<wirePrev_tem<<endl;
1960 int nextWire = wireNext_tem;
1961 myMdcDigiGroup[nextWire].AddPrev(wireid);// add the current digi as right neighbour's left neighbour
1962 //wireNext_tem = myMdcDigiGroup[nextWire].GetWire()->GetNeighborIDType2();// for the next range
1963 wireNext_tem = myMdcGeomSvc->Wire(nextWire)->GetNeighborIDType2();// for the next range
1964 }
1965
1966 // --- to fill neighbours on inner and outer layers
1967 //vector<int> innerWires_tem=myMdcDigiGroup[wireid].GetWire()->GetNeighborIDType3();// inner wires
1968 //vector<int> outerWires_tem=myMdcDigiGroup[wireid].GetWire()->GetNeighborIDType4();// outer wires
1969 vector<int> innerWires_tem=myMdcGeomSvc->Wire(wireid)->GetNeighborIDType3();// inner wires
1970 vector<int> outerWires_tem=myMdcGeomSvc->Wire(wireid)->GetNeighborIDType4();// outer wires
1971 for(int range=0;range<DiffLRange;range++)
1972 {
1973 int flag = 0;// if the same inner inner (or outer outer) wire found
1974 vector<int> innerWires = innerWires_tem;
1975 //cout<<" inner wires: ";
1976 for(unsigned int i=0;i<innerWires.size();i++){
1977 //cout<<innerWires[i]<<" ";
1978 myMdcDigiGroup[innerWires[i]].AddOuter(wireid);// add the current digi as inner wire's outer neighbour
1979 //vector<int> tem1 = myMdcDigiGroup[innerWires[i]].GetWire()->GetNeighborIDType3();// inner wire's inner wires
1980 vector<int> tem1 = myMdcGeomSvc->Wire(innerWires[i])->GetNeighborIDType3();// inner wire's inner wires
1981 vector<int> tem2 = innerWires_tem;// inner wires
1982 if(i==0){
1983 //innerWires_tem = myMdcDigiGroup[innerWires[i]].GetWire()->GetNeighborIDType3();//the 1st inner wire's inner wires
1984 innerWires_tem = myMdcGeomSvc->Wire(innerWires[i])->GetNeighborIDType3();//the 1st inner wire's inner wires
1985 }
1986 else{
1987 for(unsigned int k=0;k<tem1.size();k++){
1988 for(unsigned int j=0;j<tem2.size();j++){
1989 if(tem1.at(k)==tem2.at(j)){
1990 flag = 1;
1991 break;
1992 }
1993 }
1994 if(flag==0){
1995 innerWires_tem.push_back(tem1.at(k));// add new inner inner wires
1996 }
1997 flag = 0;
1998 }
1999 }
2000 }
2001 //cout<<endl;
2002
2003 vector<int> outerWires = outerWires_tem;
2004 //cout<<" N_outer ="<<outerWires.size()<<endl;
2005 //cout<<" outer wires: ";
2006 for(unsigned int i=0;i<outerWires.size();i++){
2007 //cout<<outerWires[i]<<" ";
2008 myMdcDigiGroup[outerWires[i]].AddInner(wireid);// add the current digi as the outer wire's inner neighbour
2009 //cout<<"wire "<<outerWires[i]<<" add digi at wire "<<wireid<<endl;
2010 //vector<int> tem1 = myMdcDigiGroup[outerWires[i]].GetWire()->GetNeighborIDType4();
2011 vector<int> tem1 = myMdcGeomSvc->Wire(outerWires[i])->GetNeighborIDType4();
2012 vector<int> tem2 = outerWires_tem;
2013 if(i==0){
2014 //outerWires_tem = myMdcDigiGroup[outerWires[i]].GetWire()->GetNeighborIDType4();
2015 outerWires_tem = myMdcGeomSvc->Wire(outerWires[i])->GetNeighborIDType4();
2016 }
2017 else{
2018 for(unsigned int k=0;k<tem1.size();k++){
2019 for(unsigned int j=0;j<tem2.size();j++){
2020 if(tem1.at(k)==tem2.at(j)){
2021 flag = 1;
2022 break;
2023 }
2024 }
2025 if(flag==0){
2026 outerWires_tem.push_back(tem1.at(k));// fill new outer outer wires
2027 }
2028 flag = 0;
2029 }
2030 }
2031 }// loop outter wires
2032 //cout<<endl;
2033 }// loop DiffLRange
2034
2035 }// loop digi
2036
2037 // --- filter digis
2038 //cout <<setw(10)<<"wireIdx"
2039 // <<setw(10)<<"layer"
2040 // <<setw(10)<<"cell"
2041 // <<setw(10)<<"inner"
2042 // <<setw(10)<<"outer"
2043 // <<setw(10)<<"prev"
2044 // <<setw(10)<<"next"
2045 // <<endl;
2046 map<int, const MdcDigi*>::iterator iter_mapDigi = myMapMdcDigi.begin();
2047 for(; iter_mapDigi!=myMapMdcDigi.end(); iter_mapDigi++)
2048 {
2049 int wireIdx=iter_mapDigi->first;
2050 //cout //<<"wireIdx, inner, outer, prev. next "<<wireIdx
2051 // //<<", "<<myMdcDigiGroup[wireIdx].GetInner().size()
2052 // //<<", "<<myMdcDigiGroup[wireIdx].GetOuter().size()
2053 // //<<", "<<myMdcDigiGroup[wireIdx].GetPrev()
2054 // //<<", "<<myMdcDigiGroup[wireIdx].GetNext()
2055 // <<setw(10)<<wireIdx
2056 // <<setw(10)<<myMdcGeomSvc->Wire(wireIdx)->Layer()
2057 // <<setw(10)<<myMdcGeomSvc->Wire(wireIdx)->Cell()
2058 // <<setw(10)<<myMdcDigiGroup[wireIdx].GetInner().size()
2059 // <<setw(10)<<myMdcDigiGroup[wireIdx].GetOuter().size()
2060 // <<setw(10)<<myMdcDigiGroup[wireIdx].GetPrev()
2061 // <<setw(10)<<myMdcDigiGroup[wireIdx].GetNext()
2062 // <<endl;
2063 if(myMdcDigiGroup[wireIdx].IsOuterEnd()) myOuterEnds.push_back(wireIdx);
2064 }
2065 //cout<<"myOuterEnds.size = "<<myOuterEnds.size()<<endl;
2066}// expired
2067
2068/**
2069 * @brief findOuterEnds
2070 * filter through myMapMdcDigi, outer ends =>myOuterEnds[wireIdx] =>myNeighbourSeeds[]
2071 * myNeighbourSeeds also includes in the front
2072 * iwireIdxds where (GetNTypesNeighborHits()==0&&GetNhitsNearby()!=0)||isCircuEnd())
2073 */
2074void DotsConnection::findOuterEnds()
2075{
2076 myOuterEnds.clear();
2077 myNeighbourSeeds.clear();
2078
2079 vector<int> wireIdxVec_noNbLayer;
2080 // --- filter digis
2081 //cout <<setw(10)<<"wireIdx"
2082 // <<setw(10)<<"layer"
2083 // <<setw(10)<<"cell"
2084 // <<setw(10)<<"inner"
2085 // <<setw(10)<<"outer"
2086 // <<setw(10)<<"prev"
2087 // <<setw(10)<<"next"
2088 // <<endl;
2089
2090 //map<int, const MdcDigi*>::iterator iter_mapDigi = myMapMdcDigi.begin();
2091 //for(; iter_mapDigi!=myMapMdcDigi.end(); iter_mapDigi++)
2092
2093 //map<int, const MdcDigi*>::reverse_iterator iter_mapDigi = myMapMdcDigi.rbegin();
2094 //for(; iter_mapDigi!=myMapMdcDigi.rend(); iter_mapDigi++)
2095 map<int, const MdcDigi*>::iterator iter_mapDigi = myMapMdcDigi.begin();
2096 for(; iter_mapDigi!=myMapMdcDigi.end(); iter_mapDigi++)
2097 {
2098 int wireIdx=iter_mapDigi->first;
2099 //cout //<<"wireIdx, inner, outer, prev. next "<<wireIdx
2100 // //<<", "<<myMdcDigiGroup[wireIdx].GetInner().size()
2101 // //<<", "<<myMdcDigiGroup[wireIdx].GetOuter().size()
2102 // //<<", "<<myMdcDigiGroup[wireIdx].GetPrev()
2103 // //<<", "<<myMdcDigiGroup[wireIdx].GetNext()
2104 // <<setw(10)<<wireIdx
2105 // <<setw(10)<<myMdcGeomSvc->Wire(wireIdx)->Layer()
2106 // <<setw(10)<<myMdcGeomSvc->Wire(wireIdx)->Cell()
2107 // <<setw(10)<<myMdcDigiGroup[wireIdx].GetInner().size()
2108 // <<setw(10)<<myMdcDigiGroup[wireIdx].GetOuter().size()
2109 // <<setw(10)<<myMdcDigiGroup[wireIdx].GetPrev()
2110 // <<setw(10)<<myMdcDigiGroup[wireIdx].GetNext()
2111 // <<endl;
2112 if(myMdcDigiGroup[wireIdx].IsOuterEnd()) myOuterEnds.push_back(wireIdx);
2113 //if(myMdcDigiGroup[wireIdx].isGoodSeed()) myNeighbourSeeds.push_back(wireIdx);
2114 if((myMdcDigiGroup[wireIdx].GetNTypesNeighborHits()==0&&myMdcDigiGroup[wireIdx].GetNhitsNearby()!=0)||myMdcDigiGroup[wireIdx].isCircuEnd()) wireIdxVec_noNbLayer.push_back(wireIdx);
2115
2116 }// loop digi
2117
2118 myNeighbourSeeds=myOuterEnds;
2119 //myNeighbourSeeds.insert(myNeighbourSeeds.end(), wireIdxVec_noNbLayer.begin(), wireIdxVec_noNbLayer.end());
2120 myNeighbourSeeds.insert(myNeighbourSeeds.begin(), wireIdxVec_noNbLayer.begin(), wireIdxVec_noNbLayer.end());
2121 //cout<<"myOuterEnds.size = "<<myOuterEnds.size()<<endl;
2122}
2123
2124//vector<vector<const MdcDigi*> > DotsConnection::getMdcHitCluster()
2125/**
2126 * @brief update myVecTrkCandidates holding trkCandi
2127 *
2128 */
2129void DotsConnection::getMdcHitCluster()
2130{
2131 int method=0;
2132
2133 int layer, nAxial, nStereo, nStereo1, nStereo2;
2134 vector<vector<const MdcDigi*> > MdcHitClusters;
2135 vector<int> vecWireId_tmp;
2136 //for(int i=0; i<myOuterEnds.size(); i++)
2137 //for(int i=0; i<myNeighbourSeeds.size(); i++)
2138 while(!myNeighbourSeeds.empty())
2139 {
2140 nAxial=0;
2141 nStereo=0;
2142 nStereo1=0;
2143 nStereo2=0;
2144
2145 struct trkCandi aTrkCandi;
2146 vector<const MdcDigi*> aMdcHitCluster;
2147 vector<int> vecMdcXDigiIdx;
2148 vector<int> vecMdcV1DigiIdx;
2149 vector<int> vecMdcV2DigiIdx;
2150 vector<int> vecMdcVDigiIdx;
2151
2152 //int wireIdx = myOuterEnds[i];
2153 //int wireIdx = myNeighbourSeeds[i];
2154 int wireIdx = myNeighbourSeeds.back();
2155 myNeighbourSeeds.pop_back();
2156
2157 int xlayer_min=99;
2158 int xlayer_max=-1;
2159 int layer_min=99;
2160 int layer_max=-1;
2161 int nextNbType=3;// inner ???
2162
2163 if(method==0) {
2164 // --- simple neighbour connection
2165 vecWireId_tmp.push_back(wireIdx);
2166 while(!vecWireId_tmp.empty())
2167 {
2168 wireIdx=vecWireId_tmp.back();
2169 vecWireId_tmp.pop_back();
2170 if(!myMdcDigiGroup[wireIdx].Used())
2171 {
2172 layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
2173 if(layer<layer_min) layer_min=layer;
2174 if(layer>layer_max) layer_max=layer;
2175 if(myWireFlag[layer]==0) {
2176 aTrkCandi.mdcHitIdx[layer].push_back(nAxial);
2177 nAxial++;// axial
2178 vecMdcXDigiIdx.push_back(wireIdx);
2179 if(layer<xlayer_min) xlayer_min=layer;
2180 if(layer>xlayer_max) xlayer_max=layer;
2181 }
2182 else {
2183 aTrkCandi.mdcHitIdx[layer].push_back(nStereo);
2184 vecMdcVDigiIdx.push_back(wireIdx);
2185 nStereo++;
2186 if(myWireFlag[layer]==1) {
2187 nStereo1++; // stereo 1
2188 vecMdcV1DigiIdx.push_back(wireIdx);
2189 }
2190 else if(myWireFlag[layer]==-1) {
2191 nStereo2++; // stereo 2
2192 vecMdcV2DigiIdx.push_back(wireIdx);
2193 }
2194 }
2195 aMdcHitCluster.push_back(myMapMdcDigi[wireIdx]);
2196 myMdcDigiGroup[wireIdx].SetUsedFlag();
2197
2198 // --- vector of all neighbours
2199 vector<int> neighbours = myMdcDigiGroup[wireIdx].GetNeiborHits();
2200 for(int j=0; j<neighbours.size(); j++) {
2201 //if(!myMdcDigiGroup[neighbours[j]].Used() && myMdcDigiGroup[neighbours[j]].GetNTypesNeighborHits()<=2) vecWireId_tmp.push_back(neighbours[j]);
2202 if(!myMdcDigiGroup[neighbours[j]].Used()) vecWireId_tmp.push_back(neighbours[j]);
2203 }
2204 }
2205 }
2206 }
2207 else if(method==1) { // --- new path finding
2208 layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
2209 // --- vector of neighbours in the same layer
2210 vector<int> nbSameLayer;
2211 nbSameLayer.push_back(wireIdx);
2212 int nbWireId=myMdcDigiGroup[wireIdx].GetPrev();
2213 while(nbWireId>=0) {
2214 if(!myMdcDigiGroup[nbWireId].Used()) nbSameLayer.push_back(nbWireId);
2215 nbWireId=myMdcDigiGroup[nbWireId].GetPrev();
2216 }
2217 nbWireId=myMdcDigiGroup[wireIdx].GetNext();
2218 while(nbWireId>=0) {
2219 if(!myMdcDigiGroup[nbWireId].Used()) nbSameLayer.push_back(nbWireId);
2220 nbWireId=myMdcDigiGroup[nbWireId].GetNext();
2221 }
2222 //vector<int> neighbours = nbSameLayer;
2223 while(layer>=8) {
2224 int nSame=nbSameLayer.size();
2225 //while(!nbSameLayer.empty())
2226 for(int i=0; i<nSame; i++)
2227 {
2228 //wireIdx=nbSameLayer.back(); nbSameLayer.pop_back();
2229 wireIdx=nbSameLayer[i];
2230 if(!myMdcDigiGroup[wireIdx].Used())
2231 {
2232 //layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
2233 if(layer<layer_min) layer_min=layer;
2234 if(layer>layer_max) layer_max=layer;
2235 if(myWireFlag[layer]==0) {
2236 aTrkCandi.mdcHitIdx[layer].push_back(nAxial);
2237 nAxial++;// axial
2238 vecMdcXDigiIdx.push_back(wireIdx);
2239 if(layer<xlayer_min) xlayer_min=layer;
2240 if(layer>xlayer_max) xlayer_max=layer;
2241 }
2242 else {
2243 aTrkCandi.mdcHitIdx[layer].push_back(nStereo);
2244 vecMdcVDigiIdx.push_back(wireIdx);
2245 nStereo++;
2246 if(myWireFlag[layer]==1) {
2247 nStereo1++; // stereo 1
2248 vecMdcV1DigiIdx.push_back(wireIdx);
2249 }
2250 else if(myWireFlag[layer]==-1) {
2251 nStereo2++; // stereo 2
2252 vecMdcV2DigiIdx.push_back(wireIdx);
2253 }
2254 }
2255 aMdcHitCluster.push_back(myMapMdcDigi[wireIdx]);
2256 myMdcDigiGroup[wireIdx].SetUsedFlag();
2257 }
2258 }
2259 // --- vector of neighbours in the inner layer
2260 layer--;
2261 int nGap(0);
2262 if(layer>=8&&layer<=42) {
2263 int nHits=0;
2264 set<int> idxSetInnerLayer;
2265 //vector<int> nbInnerLayer;
2266 vector<int> seedsInnerLayer;
2267 for(int j=0; j<nbSameLayer.size(); j++) {
2268 const vector<int>& InnerNbs=myMdcDigiGroup[nbSameLayer[j]].GetInner();
2269 for(int k=0; k<InnerNbs.size(); k++) {
2270 wireIdx=InnerNbs[k];
2271 if(myMdcDigiGroup[wireIdx].Used()) continue;
2272 idxSetInnerLayer.insert(wireIdx);
2273 //nbInnerLayer.push_back(InnerNbs[k]);
2274 //nHits++;
2275 int nbWireId=myMdcDigiGroup[wireIdx].GetPrev();
2276 while(nbWireId>=0) {
2277 if(!myMdcDigiGroup[nbWireId].Used()) idxSetInnerLayer.insert(nbWireId);
2278 nbWireId=myMdcDigiGroup[nbWireId].GetPrev();
2279 }
2280 nbWireId=myMdcDigiGroup[wireIdx].GetNext();
2281 while(nbWireId>=0) {
2282 if(!myMdcDigiGroup[nbWireId].Used()) idxSetInnerLayer.insert(nbWireId);
2283 nbWireId=myMdcDigiGroup[nbWireId].GetNext();
2284 }
2285 }
2286 }
2287 nHits=idxSetInnerLayer.size();
2288 set<int>::iterator it=idxSetInnerLayer.begin();
2289 int first(-100), last(-100), prev(-100);
2290 for(int iHit=0; iHit<nHits; iHit++, it++) {
2291 if(iHit==0) first=*it;
2292 if(iHit==nHits-1) last =*it;
2293 if(iHit>0) {
2294 if((*it-prev)>1) {
2295 nGap++;
2296 seedsInnerLayer.push_back(prev);
2297 }
2298 }
2299 //cout<<" "<<*it;
2300 prev=*it;
2301 }
2302 if(first==0&&last+1==myNWire[layer]) nGap--;
2303 else seedsInnerLayer.push_back(last);
2304 if(nGap==0) {
2305 nbSameLayer.clear();
2306 nbSameLayer.insert(nbSameLayer.end(), idxSetInnerLayer.begin(), idxSetInnerLayer.end());
2307 }
2308 else {
2309 myNeighbourSeeds.insert(myNeighbourSeeds.end(), seedsInnerLayer.begin(), seedsInnerLayer.end());
2310 }
2311 if(myDebugNb==2)
2312 cout<<" layer "<<layer<<", "<<nHits<<" hits, "<<nGap<<" gaps, "<<endl;
2313 if(nHits==0) break;
2314 }// if 8=<layer<=42
2315 if(nGap>0) break;
2316 }// while layer 8-42
2317 }//method==1
2318
2319 // if a track candidate found
2320 if(!aMdcHitCluster.empty()) {
2321 MdcHitClusters.push_back(aMdcHitCluster);
2322 aTrkCandi.mdcXDigiWireIdx=vecMdcXDigiIdx;
2323 int nXMdcDigi = vecMdcXDigiIdx.size();
2324 aTrkCandi.mdcXDigiChi.clear();
2325 aTrkCandi.mdcXDigiChi.resize(nXMdcDigi, 9999.0);
2326 aTrkCandi.mdcXDigiFitted.clear();
2327 aTrkCandi.mdcXDigiFitted.resize(nXMdcDigi, 1);
2328 aTrkCandi.mdcV1DigiWireIdx=vecMdcV1DigiIdx;
2329 aTrkCandi.mdcV2DigiWireIdx=vecMdcV2DigiIdx;
2330 aTrkCandi.mdcVDigiWireIdx=vecMdcVDigiIdx;
2331 int nVMdcDigi = vecMdcVDigiIdx.size();
2332 aTrkCandi.mdcVDigiChi.clear();
2333 aTrkCandi.mdcVDigiChi.resize(nVMdcDigi, 9999.0);
2334 aTrkCandi.mdcVDigiFitted.clear();
2335 aTrkCandi.mdcVDigiFitted.resize(nVMdcDigi, 1);
2336 aTrkCandi.xLayerMin=xlayer_min;
2337 aTrkCandi.xLayerMax=xlayer_max;
2338 aTrkCandi.layerMin=layer_min;
2339 aTrkCandi.layerMax=layer_max;
2340 if((nAxial+nStereo1+nStereo2)<3) aTrkCandi.isGood=0;
2341 else aTrkCandi.isGood=1;
2342 int trkIdx = myVecTrkCandidates.size();
2343 aTrkCandi.trkIdx = trkIdx;
2344 myVecTrkCandidates.push_back(aTrkCandi);
2345 //printTrkCandi(aTrkCandi);
2346 /*if(nAxial>=3) {
2347 myDotsHelixFitter.setDChits(aMdcHitCluster, myEvtT0);
2348 vector<double> circleParVec = myDotsHelixFitter.calculateCirclePar_Taubin();
2349 cout<<"Circle par from Taubin fit: "<<circleParVec[0]
2350 <<", "<<circleParVec[1]
2351 <<", "<<circleParVec[2]
2352 <<", chi2 = "<<myDotsHelixFitter.getChi2()
2353 <<", nHitFit = "<<myDotsHelixFitter.getNActiveHits()
2354 <<endl;
2355 }*/
2356 }// find a path
2357 }// loop outer ends to get trk candidates
2358
2359 // --- print MdcHitClusters
2360 if(myDebugNb==2) {
2361 vector<vector<const MdcDigi*> >::iterator iter = MdcHitClusters.begin();
2362 int ipath=0;
2363 for(; iter!=MdcHitClusters.end(); iter++, ipath++) {
2364 cout<<endl<<" --------> hit-cluster "<<ipath<<":" <<endl;
2365 vector<const MdcDigi*> vecDigi = *iter;
2366 vector<const MdcDigi*>::iterator iter_digi = vecDigi.begin();
2367 int iHit=1;
2368 for(; iter_digi!=vecDigi.end(); iter_digi++, iHit++) {
2369 Identifier id = (*iter_digi)->identify();
2370 int layer = MdcID::layer(id);
2371 int wire = MdcID::wire(id);
2372 //if(myDebugNb==2) {
2373 cout<<" (layer "<<layer<<", wire "<<wire<<", view "<<myWireFlag[layer]<<") ";
2374 if(iHit%5==0) cout<<endl;
2375 //}
2376 }
2377 //if(myDebugNb==2)
2378 cout<<endl;
2379 }
2380 }
2381
2382 //return MdcHitClusters;
2383}
2384
2385void DotsConnection::mdcHitClustering(const vector<int>& vecWireIdx, vector<vector<int> >& vecHitClu)
2386{
2387 int nHit=vecWireIdx.size();
2388 vector<int> vecUseFlag;
2389 for(int i=0; i<nHit; i++) {
2390 int wireIdx = vecWireIdx.at(i);
2391 vecUseFlag.push_back(myMdcDigiGroup[wireIdx].getUseFlag());
2392 myMdcDigiGroup[wireIdx].SetUsedFlag(2);
2393 }
2394
2395 vector<int> vecWireId_tmp;
2396 for(int i=0; i<nHit; i++)
2397 {
2398 int wireIdx = vecWireIdx.at(i);// seed
2399 if(myMdcDigiGroup[wireIdx].getUseFlag()==2) // not used
2400 {
2401 vector<int> aHitClu;
2402 vecWireId_tmp.push_back(wireIdx);
2403 while(!vecWireId_tmp.empty())
2404 {
2405 wireIdx=vecWireId_tmp.back();
2406 vecWireId_tmp.pop_back();
2407 if(myMdcDigiGroup[wireIdx].getUseFlag()==2) // not used
2408 aHitClu.push_back(wireIdx);
2409 myMdcDigiGroup[wireIdx].SetUsedFlag(3);
2410 vector<int> neighbours = myMdcDigiGroup[wireIdx].GetNeiborHits();
2411 for(int j=0; j<neighbours.size(); j++)
2412 if(myMdcDigiGroup[neighbours[j]].getUseFlag()==2) vecWireId_tmp.push_back(neighbours[j]);
2413 }
2414 vecHitClu.push_back(aHitClu);
2415 }
2416 }
2417
2418 for(int i=0; i<nHit; i++) {
2419 int wireIdx = vecWireIdx.at(i);
2420 myMdcDigiGroup[wireIdx].SetUsedFlag(vecUseFlag.at(i));
2421 }
2422}
2423
2424struct trkCandi DotsConnection::getTrkCandi(const vector<int>& vecWireIdx)
2425{
2426 struct trkCandi aTrkCandi;
2427
2428 int nHit=vecWireIdx.size();
2429 int layer, wireIdx, nAxial(0), nStereo(0), nStereo1(0), nStereo2(0);
2430 int xlayer_min=99;
2431 int xlayer_max=-1;
2432 int layer_min=99;
2433 int layer_max=-1;
2434 vector<int> vecMdcXDigiIdx;
2435 vector<int> vecMdcXDigiFitFlag;
2436 vector<int> vecMdcV1DigiIdx;
2437 vector<int> vecMdcV2DigiIdx;
2438 vector<int> vecMdcVDigiIdx;
2439 for(int i=0; i<nHit; i++) {
2440 wireIdx=vecWireIdx[i];
2441 layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
2442 if(layer<layer_min) layer_min=layer;
2443 if(layer>layer_max) layer_max=layer;
2444 if(myWireFlag[layer]==0) {
2445 aTrkCandi.mdcHitIdx[layer].push_back(nAxial);
2446 nAxial++;// axial
2447 vecMdcXDigiIdx.push_back(wireIdx);
2448 int fitFlag = 1;
2449 if(myMdcDigiGroup[wireIdx].isOnNode()) fitFlag=0;
2450 vecMdcXDigiFitFlag.push_back(fitFlag);
2451 if(layer<xlayer_min) xlayer_min=layer;
2452 if(layer>xlayer_max) xlayer_max=layer;
2453 }
2454 else {
2455 aTrkCandi.mdcHitIdx[layer].push_back(nStereo);
2456 vecMdcVDigiIdx.push_back(wireIdx);
2457 nStereo++;
2458 if(myWireFlag[layer]==1) {
2459 nStereo1++; // stereo 1
2460 vecMdcV1DigiIdx.push_back(wireIdx);
2461 }
2462 else if(myWireFlag[layer]==-1) {
2463 nStereo2++; // stereo 2
2464 vecMdcV2DigiIdx.push_back(wireIdx);
2465 }
2466 }
2467 }
2468 aTrkCandi.mdcXDigiWireIdx=vecMdcXDigiIdx;
2469 int nXMdcDigi = vecMdcXDigiIdx.size();
2470 aTrkCandi.mdcXDigiChi.clear();
2471 aTrkCandi.mdcXDigiChi.resize(nXMdcDigi, 9999.0);
2472 aTrkCandi.mdcXDigiFitted.clear();
2473 aTrkCandi.mdcXDigiFitted.resize(nXMdcDigi, 1);
2474 //aTrkCandi.mdcXDigiFitted=vecMdcXDigiFitFlag;
2475 aTrkCandi.mdcV1DigiWireIdx=vecMdcV1DigiIdx;
2476 aTrkCandi.mdcV2DigiWireIdx=vecMdcV2DigiIdx;
2477 aTrkCandi.mdcVDigiWireIdx=vecMdcVDigiIdx;
2478 int nVMdcDigi = vecMdcVDigiIdx.size();
2479 aTrkCandi.mdcVDigiChi.clear();
2480 aTrkCandi.mdcVDigiChi.resize(nVMdcDigi, 9999.0);
2481 aTrkCandi.mdcVDigiFitted.clear();
2482 aTrkCandi.mdcVDigiFitted.resize(nVMdcDigi, 1);
2483 aTrkCandi.xLayerMin=xlayer_min;
2484 aTrkCandi.xLayerMax=xlayer_max;
2485 aTrkCandi.layerMin=layer_min;
2486 aTrkCandi.layerMax=layer_max;
2487 if((nAxial+nStereo1+nStereo2)<3) aTrkCandi.isGood=0;
2488 else aTrkCandi.isGood=1;
2489
2490 return aTrkCandi;
2491}
2492
2493void DotsConnection::findCgemTrkSeg()
2494{
2495 // --- select unused CGEM clusters
2496 vector<int> vecCgemXClusterIdx[3];
2497 vector<int> vecCgemVClusterIdx[3];
2498 vector<vector<pair<int, double> > > vecCgemVCluIdxZ[3];
2499 for(int i=0; i<3; i++) {
2500 //cout<<__FUNCTION__<<__LINE__<<endl;
2501 int size(0);
2502 size = myVecCgemVClusterIdx[i].size();
2503 for(int j=0; j<size; j++) {
2504 if(myVecCgemVClusterTrkIdx[i][j]==-1) {
2505 vecCgemVClusterIdx[i].push_back(myVecCgemVClusterIdx[i][j]);
2506 }
2507 }
2508 //cout<<__FUNCTION__<<__LINE__<<endl;
2509 size = myVecCgemXClusterIdx[i].size();
2510 for(int j=0; j<size; j++) {
2511 if(myVecCgemXClusterTrkIdx[i][j]==-1) {
2512 int idx_Xclu = myVecCgemXClusterIdx[i][j];
2513 vecCgemXClusterIdx[i].push_back(idx_Xclu);
2514 vector<pair<int, double> > vecVidxZ;
2515 for(int k=0; k<vecCgemVClusterIdx[i].size(); k++) {
2516 int idx_Vclu = vecCgemVClusterIdx[i][k];
2517 double z_XV(9999.);
2518 if(getCgemClusterIntersection(idx_Xclu,idx_Vclu,z_XV)) {
2519 pair<int, double> idxZ(idx_Vclu, z_XV);
2520 vecVidxZ.push_back(idxZ);
2521 }
2522 }
2523 vecCgemVCluIdxZ[i].push_back(vecVidxZ);
2524 }// if unused X-clu
2525 }// loop X-clu
2526 //cout<<__FUNCTION__<<__LINE__<<endl;
2527 }// loop 3 layers
2528 //cout<<"vecCgemX/VClusterIdx, vecCgemVCluIdxZ filled "<<endl;
2529
2530 // --- select circle candidates
2531 for(int i2=0; i2<vecCgemXClusterIdx[1].size(); i2++) { // layer 2
2532 int idx2=vecCgemXClusterIdx[1][i2];
2533 //cout<<__FUNCTION__<<__LINE__<<endl;
2534 //myIterClu=myIterCgemClusterBegin+vecCgemXClusterIdx[1][i2];
2535 //double phi2=(*myIterClu)->getrecphi();
2536 for(int i1=0; i1<vecCgemXClusterIdx[0].size(); i1++) { // layer 1
2537 //myIterClu=myIterCgemClusterBegin+vecCgemXClusterIdx[0][i1];
2538 //double phi1=(*myIterClu)->getrecphi();
2539 //double phi12=phi1-phi2;
2540 int idx1=vecCgemXClusterIdx[0][i1];
2541 //cout<<__FUNCTION__<<__LINE__<<endl;
2542 for(int i3=0; i3<vecCgemXClusterIdx[2].size(); i3++) { // layer 3
2543 //myIterClu=myIterCgemClusterBegin+vecCgemXClusterIdx[2][i3];
2544 //double phi3=(*myIterClu)->getrecphi();
2545 //double phi32=phi3-phi2;
2546 int idx3=vecCgemXClusterIdx[2][i3];
2547 //cout<<__FUNCTION__<<__LINE__<<endl;
2548 struct trkCandi aTrkCandi;
2549 aTrkCandi.CgemXClusterID.push_back(idx3);
2550 aTrkCandi.CgemXClusterID.push_back(idx2);
2551 aTrkCandi.CgemXClusterID.push_back(idx1);
2552 if(myDebugNb==2)
2553 cout<<"--- Try a triple-CGEM_Xcluster circle fit: "<<idx3<<", "<<idx2<<", "<<idx1<<endl;
2554 int nDropHits = circleFitTaubin(aTrkCandi, 5);
2555 //calcuCiclePar3CgemClu(aTrkCandi);
2556 if(isGoodCgemCircleCandi(aTrkCandi)) {
2557 if(myDebugNb==2)
2558 cout<<"a good CGEM cluster circle candidate found"<<endl;
2559 double s[3];
2560 KalmanFit::Helix circle_fittedHelix = myDotsHelixFitter.getClassHelix();
2561 for(int i=0; i<3; i++) {
2562 double rCGEM = myDotsHelixFitter.getRmidGapCgem(i);
2563 double dphi = myDotsHelixFitter.IntersectCylinder(rCGEM);
2564 s[i] = fabs(dphi*circle_fittedHelix.radius());
2565 }
2566 // --- check if V-clusters satisfies z12/s12 = z23/s23
2567 double dz_min=9999.;
2568 double tanl_dzmin=9999.;
2569 int v_dzmin[3]={-1,-1,-1};
2570 int n_sz=3;
2571 for(int v1=0; v1<vecCgemVCluIdxZ[0][i1].size(); v1++) {
2572 double z1=vecCgemVCluIdxZ[0][i1][v1].second;
2573 for(int v2=0; v2<vecCgemVCluIdxZ[1][i2].size(); v2++) {
2574 double z2=vecCgemVCluIdxZ[1][i2][v2].second;
2575 for(int v3=0; v3<vecCgemVCluIdxZ[2][i3].size(); v3++) {
2576 double z3=vecCgemVCluIdxZ[2][i3][v3].second;
2577 double r21=(z2-z1)/(s[1]-s[0]);
2578 double r32=(z3-z2)/(s[2]-s[1]);
2579 double s_sum(0), z_sum(0);
2580 double s2_sum(0), sz_sum(0);
2581 s_sum=s[0]+s[1]+s[2];
2582 z_sum=z1+z2+z3;
2583 s2_sum=s[0]*s[0]+s[1]*s[1]+s[2]*s[2];
2584 sz_sum=s[0]*z1+s[1]*z2+s[2]*z3;
2585 double tanl_lfit = (n_sz*sz_sum-s_sum*z_sum)/(n_sz*s2_sum-s_sum*s_sum);
2586 double dz_lfit = (s2_sum*z_sum-s_sum*sz_sum)/(n_sz*s2_sum-s_sum*s_sum);
2587 if(myDebugNb==2){
2588 cout<<"r21, r32, del_r, dz, tanl = "<<r21<<", "<<r32<<", "<<fabs(r21-r32)<<", "<<dz_lfit<<", "<<tanl_lfit<<endl;
2589 //cout<<"del_r = "<<fabs(r21-r32)<<endl;
2590 }
2591 if(fabs(r21-r32)>0.08) {
2592 if(myDebugNb==2) cout<<" dropped "<<endl;
2593 continue;// ???
2594 }
2595 if(fabs(dz_lfit)<fabs(dz_min)) {
2596 dz_min=dz_lfit;
2597 tanl_dzmin=tanl_lfit;
2598 v_dzmin[0]=v1;
2599 v_dzmin[1]=v2;
2600 v_dzmin[2]=v3;
2601 }
2602 }// loop v-view layer 3
2603 }// loop v-view layer 2
2604 }// loop v-view layer 1
2605 if(v_dzmin[0]!=-1) {
2606 aTrkCandi.CgemVClusterID.push_back(vecCgemVCluIdxZ[2][i3][v_dzmin[2]].first);
2607 aTrkCandi.CgemVClusterID.push_back(vecCgemVCluIdxZ[1][i2][v_dzmin[1]].first);
2608 aTrkCandi.CgemVClusterID.push_back(vecCgemVCluIdxZ[0][i1][v_dzmin[0]].first);
2609 int fitFlag = helixFit(aTrkCandi, 5);
2610 // --- update the track candidate
2611 if(fitFlag==0) {
2612 updateCgemFitItem(aTrkCandi, 1);
2613 aTrkCandi.isGood=1;
2614 int trkIdx = myVecTrkCandidates.size();
2615 aTrkCandi.trkIdx = trkIdx;
2616 myVecTrkCandidates.push_back(aTrkCandi);
2617 }
2618 //else aTrkCandi.isGood=0;
2619 }// 3 V-clusters found
2620 }// good circle
2621 } // L3
2622 }// L1
2623 }// L2
2624
2625
2626 // --- dz dr sorting
2627}
2628
2629void DotsConnection::printTrkCandi(struct trkCandi& aTrkCandi)
2630{
2631 cout<<"Trk candidate id "<<aTrkCandi.trkIdx<<", good? "<<aTrkCandi.isGood<<endl;
2632 int nXHits = aTrkCandi.mdcXDigiWireIdx.size();
2633 cout<<" nXHits="<<nXHits<<":";
2634 for(int i=0; i<nXHits; i++) {
2635 cout<<" "<<aTrkCandi.mdcXDigiWireIdx[i];
2636 if((i+1)%20==0) cout<<endl<<" ";
2637 }
2638 cout<<endl;
2639}
2640
2641int DotsConnection::nXHitsActive(struct trkCandi& aTrkCandi)
2642{
2643 int nXActive = 0;
2644 int nXHits = aTrkCandi.mdcXDigiFitted.size();
2645 for(int i=0; i<nXHits; i++) if(aTrkCandi.mdcXDigiFitted[i]>0) nXActive++;
2646 return nXActive;
2647}
2648
2649int DotsConnection::setFitFlagUncertain(struct trkCandi& aTrkCandi, int layerMin, int layerMax)
2650{
2651 int nXHits = aTrkCandi.mdcXDigiWireIdx.size();
2652 int nSet = 0;
2653 for(int i=0; i<nXHits; i++) {
2654 int wireIdx = aTrkCandi.mdcXDigiWireIdx[i];
2655 int layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
2656 if(layer>=layerMin && layer<=layerMax) {
2657 aTrkCandi.mdcXDigiFitted[i]=0;
2658 nSet++;
2659 }
2660 }
2661 return nSet;
2662}
2663
2664int DotsConnection::setXHitsInBigSetFitFlagUncertain(struct trkCandi& aTrkCandi, bool set)
2665{
2666 int nXHits = aTrkCandi.mdcXDigiWireIdx.size();
2667 int nSet = 0;
2668 for(int i=0; i<nXHits; i++) {
2669 int wireIdx = aTrkCandi.mdcXDigiWireIdx[i];
2670 //int layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
2671 if(myMdcDigiGroup[wireIdx].isInBigSet()) {
2672 if(set) aTrkCandi.mdcXDigiFitted[i]=0;
2673 nSet++;
2674 }
2675 }
2676 return nSet;
2677}
2678
2679//vector<const MdcDigi*> DotsConnection::getXDigiVec(struct trkCandi& aTrkCandi, int sel, vector<int>& vecFitFlag)
2680//{
2681// vector<const MdcDigi*> aXDigiVec;
2682// vector<int>::iterator iter = aTrkCandi.mdcXDigiWireIdx.begin();
2683// //myVecDigiIdx.clear();
2684// int i=0;
2685// for(; iter!=aTrkCandi.mdcXDigiWireIdx.end(); iter++, i++) {
2686// int mdcDigiIdx = abs(*iter);
2687// if(sel==1&&(*iter)<0) continue;
2688// if(sel==2&&aTrkCandi.mdcXDigiFitted[i]<0) continue;
2689// if(sel==3&&aTrkCandi.mdcXDigiFitted[i]<=0) continue;
2690// aXDigiVec.push_back(myMapMdcDigi[mdcDigiIdx]);
2691// int fitFlag = aTrkCandi.mdcXDigiFitted[i];
2692// if(fitFlag<0) fitFlag=0;
2693// vecFitFlag.push_back(fitFlag);
2694// myVecDigiIdx.push_back(i);
2695// }
2696// return aXDigiVec;
2697//}
2698
2699
2700/**
2701 * @brief get x-digis in aTrkCandi with selection creteria sel:
2702 *
2703 * @param aTrkCandi
2704 * @param sel 0:all 1:all associated 2: all fitted or uncertain 3: all fitted
2705 * @param vecFitFlag fitflags for returned myVecDigiIdxs. 0:not sure or not used. 1 used in fit
2706 * @return vector<const MdcDigi*>
2707 */
2708vector<const MdcDigi*> DotsConnection::getXDigiVec(struct trkCandi& aTrkCandi, int sel, vector<int>* vecFitFlag)
2709{
2710 //myNOuterXHits=0;
2711
2712 vector<const MdcDigi*> aXDigiVec;
2713 vector<int>::iterator iter = aTrkCandi.mdcXDigiWireIdx.begin();
2714 //myVecDigiIdx.clear();
2715 int i=0;
2716
2717 for(; iter!=aTrkCandi.mdcXDigiWireIdx.end(); iter++, i++) {
2718 int mdcDigiIdx = abs(*iter);
2719 if(sel==1&&(*iter)<0) continue;
2720 if(sel==2&&aTrkCandi.mdcXDigiFitted[i]<0) continue;
2721 if(sel==3&&aTrkCandi.mdcXDigiFitted[i]<=0) continue;
2722 aXDigiVec.push_back(myMapMdcDigi[mdcDigiIdx]);
2723 int layer = myMdcGeomSvc->Wire(mdcDigiIdx)->Layer();
2724 if(vecFitFlag!=NULL) {
2725 int fitFlag = aTrkCandi.mdcXDigiFitted[i];
2726 if(fitFlag<0) fitFlag=0;
2727 vecFitFlag->push_back(fitFlag);
2728 //if(fitFlag>0&&layer>=36) myNOuterXHits++;
2729 }
2730 //else if(layer>=36) myNOuterXHits++;
2731 myVecDigiIdx.push_back(i);
2732 }
2733 return aXDigiVec;
2734}
2735
2736/**
2737 * @brief get v-digis in aTrkCandi with selection creteria sel:
2738 *
2739 * @param aTrkCandi
2740 * @param sel 0:all; 1:all associated 2: all fitted or uncertain 3: all fitted
2741 * @return vector<const MdcDigi*>
2742 */
2743vector<const MdcDigi*> DotsConnection::getVDigiVec(struct trkCandi& aTrkCandi, int sel)
2744{
2745 vector<const MdcDigi*> aVDigiVec;
2746 vector<int>::iterator iter = aTrkCandi.mdcVDigiWireIdx.begin();
2747 //myVecDigiIdx.clear();
2748 int i=0;
2749 for(; iter!=aTrkCandi.mdcVDigiWireIdx.end(); iter++, i++) {
2750 int mdcDigiIdx = abs(*iter);
2751 if(sel==1&&(*iter)<0) continue;
2752 if(sel==2&&aTrkCandi.mdcVDigiFitted[i]<0) continue;
2753 if(sel==3&&aTrkCandi.mdcVDigiFitted[i]<=0) continue;
2754 aVDigiVec.push_back(myMapMdcDigi[mdcDigiIdx]);
2755 myVecDigiIdx.push_back(-(i+1));// negative sign for V-hits
2756 }
2757 return aVDigiVec;
2758}
2759
2760vector<const MdcDigi*> DotsConnection::getDigiVec(struct trkCandi& aTrkCandi, int sel)
2761{
2762 myVecDigiIdx.clear();
2763 vector<const MdcDigi*> aDigiVec = getXDigiVec(aTrkCandi, sel);
2764 vector<const MdcDigi*> vDigiVec = getVDigiVec(aTrkCandi, sel);
2765 aDigiVec.insert(aDigiVec.end(), vDigiVec.begin(), vDigiVec.end());
2766 return aDigiVec;
2767}
2768
2769vector<const RecCgemCluster*> DotsConnection::getXCluVec(struct trkCandi& aTrkCandi, int sel)
2770{
2771 vector<const RecCgemCluster*> aVecCgemCluster;
2772 vector<int>::iterator iter = aTrkCandi.CgemXClusterID.begin();
2773 int i=0;
2774 for(; iter!=aTrkCandi.CgemXClusterID.end(); iter++, i++) {
2775 int cluIdx = *iter;
2776 if(cluIdx<0) {
2777 cluIdx=-cluIdx-1;
2778 if(sel==2) continue;
2779 }
2780 myIterClu=myIterCgemClusterBegin+cluIdx;
2781 aVecCgemCluster.push_back(*myIterClu);
2782 myVecCluIdx.push_back(i);
2783 }
2784 return aVecCgemCluster;
2785}
2786
2787vector<const RecCgemCluster*> DotsConnection::getVCluVec(struct trkCandi& aTrkCandi, int sel)
2788{
2789 vector<const RecCgemCluster*> aVecCgemCluster;
2790 vector<int>::iterator iter = aTrkCandi.CgemVClusterID.begin();
2791 int i=0;
2792 for(; iter!=aTrkCandi.CgemVClusterID.end(); iter++, i++) {
2793 int cluIdx = *iter;
2794 if(cluIdx<0) {
2795 cluIdx=-cluIdx-1;
2796 if(sel==2) continue;
2797 }
2798 myIterClu=myIterCgemClusterBegin+cluIdx;
2799 aVecCgemCluster.push_back(*myIterClu);
2800 myVecCluIdx.push_back(-(i+1));// negative sign for V-clusters
2801 }
2802 return aVecCgemCluster;
2803}
2804
2805vector<const RecCgemCluster*> DotsConnection::getCluVec(struct trkCandi& aTrkCandi, int sel)
2806{
2807 myVecCluIdx.clear();
2808 vector<const RecCgemCluster*> aVecCgemCluster = getXCluVec(aTrkCandi, sel);
2809 vector<const RecCgemCluster*> vVecCgemCluster = getVCluVec(aTrkCandi, sel);
2810 aVecCgemCluster.insert(aVecCgemCluster.end(), vVecCgemCluster.begin(), vVecCgemCluster.end());
2811 return aVecCgemCluster;
2812}
2813
2814void DotsConnection::tagRedudantHits(struct trkCandi& aTrkCandi)
2815{
2816 if(myDebugNb==2)
2817 cout<<"DotsConnection::tagRedudantHits: "<<endl;
2818 vector<vector<int> > hitSets[43];
2819 vector<vector<int> > outerHitSets[43];
2820 vector<vector<int> > innerHitSets[43];
2821 vector<int> isNode[43];
2822 vector<int> vecWireIdx;
2823 vector<vector<int> > trackPaths;
2824 int nPath=0;
2825 int iLayerHasHits=0;
2826 for(int layer=8; layer<43; layer++)
2827 {
2828 int nHits = aTrkCandi.mdcHitIdx[layer].size();
2829 if(nHits>=1) {
2830 iLayerHasHits++;
2831 map<int, int> idxSet;
2832 for(int iHit=0; iHit<nHits; iHit++) {
2833 int idx = aTrkCandi.mdcHitIdx[layer][iHit];
2834 int wireIdx;
2835 if(myWireFlag[layer]==0) wireIdx = aTrkCandi.mdcXDigiWireIdx[idx];
2836 else wireIdx = aTrkCandi.mdcVDigiWireIdx[idx];
2837 int wire = myMdcGeomSvc->Wire(wireIdx)->Cell();
2838 //idxSet.insert(wire);
2839 idxSet[wire]=wireIdx;
2840 }
2841 map<int, int>::iterator it=idxSet.begin();
2842 int first(-100), last(-100), prev(-100);
2843 int nGap(0);
2844 if(myDebugNb==2)
2845 cout<<" layer "<<layer<<", "<<nHits<<" hits: ";
2846 for(int iHit=0; iHit<nHits; iHit++, it++) {
2847 if(iHit==0) first=it->first;
2848 if(iHit==nHits-1) {
2849 last =it->first;
2850
2851 }
2852 if(iHit>0) {
2853 if((it->first-prev)>1) {
2854 nGap++;
2855 //cout<<"a "<<vecWireIdx.size()<<" hits-set filled ";
2856 hitSets[layer].push_back(vecWireIdx);
2857 vecWireIdx.clear();
2858 }
2859 }
2860 if(myDebugNb==2)
2861 cout<<" "<<it->first;
2862 prev=it->first;
2863 vecWireIdx.push_back(it->second);
2864 }
2865 if(first==0&&last+1==myNWire[layer]) {
2866 nGap--;
2867 if(hitSets[layer].size()>0) {
2868 vector<int> firstVec = hitSets[layer][0];
2869 hitSets[layer].erase(hitSets[layer].begin());
2870 vecWireIdx.insert(vecWireIdx.end(), firstVec.begin(), firstVec.end());
2871 }
2872 }
2873 //cout<<" a "<<vecWireIdx.size()<<" hits-set filled ";
2874 hitSets[layer].push_back(vecWireIdx);
2875 vecWireIdx.clear();
2876 if(myDebugNb==2)
2877 cout<<" ===> "<<nGap<<" gaps"<<endl;
2878 int nSet=hitSets[layer].size();
2879 isNode[layer].clear();
2880 isNode[layer].resize(nSet,0);
2881 if(iLayerHasHits==1) {
2882 for(int iSet=0; iSet<nSet; iSet++) {
2883 trackPaths.push_back(hitSets[layer][iSet]);
2884 }
2885 //nPath=hitSets[layer].size();
2886 } else if(iLayerHasHits>1) {
2887 int nSetIn = hitSets[layer-1].size();
2888 vector<vector<int> > newTrkPaths;
2889 vector<vector<int> > innerNb;
2890 for(int i2=0; i2<nSet; i2++) {
2891 vector<int> aVec;
2892 innerNb.push_back(aVec);
2893 }
2894 for(int i1=0; i1<nSetIn; i1++) {// loop inner hit-sets
2895 vector<int> outerNb;
2896 if(myDebugNb==2)
2897 cout<<" inner-hit-set "<<i1<<" has outer-Nb-hit-set: ";
2898 for(int iSet=0; iSet<nSet; iSet++) {// find the outer hit-sets
2899 if(isInOutNeighbours(hitSets[layer-1][i1], hitSets[layer][iSet])) {
2900 outerNb.push_back(iSet);
2901 if(myDebugNb==2)
2902 cout<<iSet<<" ";
2903 innerNb[iSet].push_back(i1);
2904 }
2905 }
2906 if(myDebugNb==2)
2907 cout<<" ("<<outerNb.size()<<" in total)"<<endl;
2908 if(outerNb.size()>1) {// set inner hits on node
2909 isNode[layer-1][i1]=1;
2910 if(myDebugNb==2)
2911 cout<<" innner set "<<i1<<" is a node"<<endl;
2912 }
2913 outerHitSets[layer-1].push_back(outerNb);
2914 // --- update path & add new path for nodes
2915 int nTrk=0;
2916 int aWireIdx=hitSets[layer-1][i1][0];
2917 vector<vector<int> >::iterator it_path=trackPaths.begin();
2918 for(; it_path!=trackPaths.end(); it_path++) {
2919 vector<int> aPath = *it_path;
2920 vector<int>::iterator it_hit = find(aPath.begin(), aPath.end(), aWireIdx);
2921 if(it_hit!=aPath.end()) {
2922 nTrk++;
2923 for(int iSet=0; iSet<outerNb.size(); iSet++) {
2924 vector<int> aNewPath=aPath;
2925 aNewPath.insert(aNewPath.end(), hitSets[layer][outerNb[iSet]].begin(), hitSets[layer][outerNb[iSet]].end());
2926 if(iSet==0) *it_path=aNewPath;
2927 else newTrkPaths.push_back(aNewPath);
2928 }
2929 //if(outerNb.size()==0) newTrkPaths.push_back(aPath);
2930 }
2931 }
2932 if(myDebugNb==2)
2933 cout<<" "<<nTrk<<" trk path(s) with this inner-hit-set"<<endl;
2934 }// loop inner hit-sets
2935
2936 for(int i2=0; i2<nSet; i2++) {
2937 if(innerNb[i2].size()>1) {
2938 isNode[layer][i2]=1;
2939 if(myDebugNb==2)
2940 cout<<" set "<<i2<<" is a node"<<endl;
2941 }
2942 }
2943
2944 trackPaths.insert(trackPaths.end(), newTrkPaths.begin(), newTrkPaths.end());
2945 if(myDebugNb==2)
2946 cout<<" "<<trackPaths.size()<<" possible track path(s) "<<endl;
2947
2948 }
2949 //if(layer<layerMax-1) // tag the hits as uncertain ones
2950 if(nGap>0) // tag the hits as uncertain ones
2951 {
2952 vector<int>* mdcDigiFitFlag;
2953 if(myWireFlag[layer]==0) mdcDigiFitFlag=&(aTrkCandi.mdcXDigiFitted);
2954 else mdcDigiFitFlag=&(aTrkCandi.mdcVDigiFitted);
2955 for(int iHit=0; iHit<nHits; iHit++) {
2956 int idx = aTrkCandi.mdcHitIdx[layer][iHit];
2957 mdcDigiFitFlag->at(idx)=0;// tag as uncertain
2958 }
2959 }
2960 }// has >1 hits
2961 }// loop layer
2962 if(myDebugNb==2)
2963 cout<<trackPaths.size()<<" possible track path(s) found "<<endl;
2964 // update onNode
2965 for(int l=8; l<43; l++) {
2966 int nSet = hitSets[l].size();
2967 for(int i=0; i<nSet; i++) {
2968 if(isNode[l][i]==1) {
2969 int nHit = hitSets[l][i].size();
2970 for(int j=0; j<nHit; j++) {
2971 int wireIdx = hitSets[l][i][j];
2972 myMdcDigiGroup[wireIdx].SetOnNode();
2973 }
2974 }
2975 }
2976 }
2977 if(trackPaths.size()>1) {
2978 int i_path = 0;
2979 int i_bestPath = -1;
2980 int nMax_goodHits=0;
2981 vector<struct trkCandi> vecTrkCandi;
2982 for(vector<vector<int> >::iterator it_path=trackPaths.begin(); it_path!=trackPaths.end(); it_path++, i_path++) {
2983 if(myDebugNb==2)
2984 cout<<"circlr fit of path "<<i_path<<": "<<endl;
2985 struct trkCandi aTrkCandi=getTrkCandi(*it_path);
2986 vecTrkCandi.push_back(aTrkCandi);
2987 int nDropHits = circleFitTaubin(vecTrkCandi.back(), 5, false, 2, true);
2988 int nFittedXhits=myDotsHelixFitter.getNActiveHits();
2989 if(nMax_goodHits<nFittedXhits) {
2990 nMax_goodHits=nFittedXhits;
2991 i_bestPath=i_path;
2992 }
2993 }
2994 if(myDebugNb==2)
2995 cout<<"the best path is "<<i_bestPath<<endl;
2996 }
2997}
2998
2999bool DotsConnection::split(struct trkCandi& aTrkCandi, int idxCandi)
3000{
3001 const int nHitsBig=3;
3002 const int nLayerHitsBig=3;
3003 vector<vector<int> > hitSets[43];// continueous hits sets, each set is a vector of wireIdx
3004 vector<int> gapSize[43];// gap size to the next set
3005 vector<int> gapSize_small[43];// smaller gap size, with sign
3006 vector<int> bigSets[43];// big hit-sets idx (nHits>nHitsBig)
3007 vector<int> inFatCluster[43];// if in a cluster larger than 3*3
3008 vector<vector<int> > bigInnerSets[43];// big inner NB sets idx
3009 vector<vector<int> > bigOuterSets[43];// big outer NB sets idx
3010 vector<vector<int> > outerHitSets[43];// outer NB hit-sets idx
3011 vector<vector<int> > innerHitSets[43];// inner NB hit-sets idx
3012 vector<int> isNode[43];// if have multi inner or outer hit-sets
3013 vector<int> vecWireIdx;// a continueous hit set
3014 vector<vector<int> > trackPaths;// vector of possible track path
3015 vector<vector<int> > fatPaths;// vector of fat track paths (background?), for each path, starting layer, isets
3016 vector<vector<int> > thinPaths;// vector of thin track paths (good signal), for each path, starting layer, isets
3017
3018
3019 //int nLayerTooManyHits=0;
3020 //int nContiLayTooManyHits=0;
3021 //for(int layer=8; layer<43; layer++) {
3022 // int nHits = aTrkCandi.mdcHitIdx[layer].size();
3023 // if(nHits>=3) {
3024 // nLayerTooManyHits++;
3025 // nContiLayTooManyHits++;
3026 // } else {
3027 // nContiLayTooManyHits=0;
3028 // }
3029 // cout<<"nLayer with 3 or more hits: "<<nLayerTooManyHits<<endl;
3030 //}
3031
3032 //int nPath=0;
3033
3034 // --- part 1 --- loop layer to form NB sets relationship, gaps, fat cluster/path
3035 int iLayerHasHits=0;
3036 for(int layer=8; layer<43; layer++) // for each layer, inner->outer
3037 {
3038 int nHits = aTrkCandi.mdcHitIdx[layer].size();
3039 int nGap(0);
3040 if(nHits>=1) {
3041 iLayerHasHits++;
3042
3043 //if(nHits>=3) nLayerTooManyHits++;
3044
3045 // ---> get nGap, fill hitSets[43], gapSize[43]
3046 // --- fill the map idxSet
3047 map<int, int> idxSet;// <cellId, wireIdx>
3048 for(int iHit=0; iHit<nHits; iHit++) {// for each hit on this layer.
3049 int idx = aTrkCandi.mdcHitIdx[layer][iHit];// index in trkCandi.mdcX/VDigiWireIdx
3050 int wireIdx;
3051 if(myWireFlag[layer]==0) wireIdx = aTrkCandi.mdcXDigiWireIdx[idx];
3052 else wireIdx = aTrkCandi.mdcVDigiWireIdx[idx];
3053 int wire = myMdcGeomSvc->Wire(wireIdx)->Cell();
3054 //idxSet.insert(wire);
3055 idxSet[wire]=wireIdx;
3056 }
3057 map<int, int>::iterator it=idxSet.begin();
3058 int first(-100), last(-100), prev(-100);
3059 int gap_size=0;
3060 if(myDebugNb==2)
3061 cout<<" layer "<<layer<<", "<<nHits<<" hits: ";
3062 for(int iHit=0; iHit<nHits; iHit++, it++) {// for each hit in idxSet
3063 if(iHit==0) first=it->first;
3064 if(iHit==nHits-1) {
3065 last =it->first;
3066 }
3067 if(iHit>0) {
3068 gap_size=it->first-prev-1;
3069 if(gap_size>0)
3070 {
3071 if(myDebugNb==2)
3072 cout<<" | ";
3073 nGap++;
3074 //cout<<"a "<<vecWireIdx.size()<<" hits-set filled ";
3075 //if(vecWireIdx.size()>3) {
3076 // bigSets[layer].push_back(hitSets[layer].size());
3077 //}
3078 hitSets[layer].push_back(vecWireIdx);
3079 gapSize[layer].push_back(gap_size);
3080 vecWireIdx.clear();
3081 }
3082 }
3083 if(myDebugNb==2)
3084 cout<<" "<<it->first;
3085 prev=it->first;
3086 vecWireIdx.push_back(it->second);
3087 }// loop hits in the layer
3088 gap_size=myNWire[layer]-last-1+first;
3089 if(first==0&&last+1==myNWire[layer]) {
3090 nGap--;
3091 if(hitSets[layer].size()>0) {
3092 vector<int> firstVec = hitSets[layer][0];
3093 //if(firstVec.size()>3) {
3094 // bigSets[layer].erase(bigSets[layer].begin());
3095 // int nBigSets = bigSets[layer].size();
3096 // for(int ib=0; ib<nBigSets; ib++) bigSets[layer][ib]--;
3097 //}
3098 hitSets[layer].erase(hitSets[layer].begin());
3099 vecWireIdx.insert(vecWireIdx.end(), firstVec.begin(), firstVec.end());
3100 gap_size=gapSize[layer][0];
3101 gapSize[layer].erase(gapSize[layer].begin());
3102 if(myDebugNb==2) cout<<" (comb. w. 1st set) ";
3103
3104 }
3105 }
3106 //cout<<" a "<<vecWireIdx.size()<<" hits-set filled ";
3107 //if(vecWireIdx.size()>3) bigSets[layer].push_back(hitSets[layer].size());
3108 hitSets[layer].push_back(vecWireIdx);
3109 gapSize[layer].push_back(gap_size);
3110 vecWireIdx.clear();
3111 int nSet=hitSets[layer].size();
3112 if(myDebugNb==2) {
3113 cout<<" ===> "<<nGap<<" gaps "<<endl; //gapSize[layer].size()<<endl;
3114 cout<<" N_gapSize = "<<gapSize[layer].size()<<endl;
3115 }
3116 // --- update gapSize
3117 for(int iGap=0; iGap<nSet; iGap++)
3118 {
3119 int gapSizeNext=gapSize[layer][iGap];
3120 int iPrevGap=iGap-1;
3121 if(iPrevGap<0) iPrevGap+=nSet;
3122 int gapSizePrev=gapSize[layer][iPrevGap];
3123 if(myDebugNb==2) cout<<" gap "<<iGap<<" size : "<<gapSizeNext;
3124 if(abs(gapSizePrev)<abs(gapSizeNext)) {
3125 //gapSize[layer][iGap]=-1*abs(gapSizePrev);
3126 gapSize_small[layer].push_back(-1*abs(gapSizePrev));
3127 //if(myDebugNb==2) cout<<" -> "<<gapSize[layer][iGap];
3128 }
3129 else gapSize_small[layer].push_back(abs(gapSizeNext));
3130 if(myDebugNb==2) cout<<" -> "<<gapSize_small[layer].back()<<endl;
3131 }
3132 // <--- get nGap, fill hitSets[43], gapSize[43]
3133
3134 // --- form inner and outer NBs, big cluster/path
3135 //int nSet=hitSets[layer].size();
3136 isNode[layer].clear(); isNode[layer].resize(nSet,0);
3137 inFatCluster[layer].clear(); inFatCluster[layer].resize(nSet,0);
3138 if(iLayerHasHits==1) {
3139 for(int iSet=0; iSet<nSet; iSet++) {
3140 //trackPaths.push_back(hitSets[layer][iSet]);
3141 if(hitSets[layer][iSet].size()>nHitsBig) {
3142 bigSets[layer].push_back(iSet);
3143 vector<int> aFatPath;
3144 aFatPath.push_back(layer);
3145 aFatPath.push_back(iSet);
3146 fatPaths.push_back(aFatPath);
3147 }
3148 }
3149 //nPath=hitSets[layer].size();
3150 } else if(iLayerHasHits>1) {
3151 int nSetIn = hitSets[layer-1].size();
3152 //vector<vector<int> > newTrkPaths;
3153 vector<vector<int> > newFatPaths;
3154 vector<vector<int> > innerNb;// inner NB set for the sets of the layer under looping
3155 vector<vector<int> > innerBigNb;// inner big NB set for the sets of the layer under looping
3156 for(int iSet=0; iSet<nSet; iSet++) {// prepare innerNb
3157 if(hitSets[layer][iSet].size()>nHitsBig) bigSets[layer].push_back(iSet);
3158 vector<int> aVec;
3159 innerNb.push_back(aVec);
3160 innerBigNb.push_back(aVec);
3161 //NbigInnerSets[layer].push_back(0);
3162 //NbigOuterSets[layer].push_back(0);
3163 }
3164 for(int i1=0; i1<nSetIn; i1++) {// loop inner hit-sets
3165 vector<int> outerNbSetIdx;// outer NB sets for the inner hit-set
3166 vector<int> bigOuterNbSetIdx;// outer NB sets for the inner hit-set
3167 if(myDebugNb==2)
3168 cout<<" inner-hit-set "<<i1<<" has outer-Nb-hit-set: ";
3169 //int nBigOuterSet=0;
3170 for(int iSet=0; iSet<nSet; iSet++) {// find the outer NB hit-sets
3171 if(isInOutNeighbours(hitSets[layer-1][i1], hitSets[layer][iSet])) {
3172 if(myDebugNb==2)
3173 cout<<iSet<<" ";
3174 outerNbSetIdx.push_back(iSet);
3175 innerNb[iSet].push_back(i1);
3176 if(hitSets[layer][iSet].size()>nHitsBig) {
3177 //nBigOuterSet++;
3178 //if(hitSets[layer-1][i1].size()>3)
3179 bigOuterNbSetIdx.push_back(iSet);
3180 }
3181 if(hitSets[layer-1][i1].size()>nHitsBig) innerBigNb[iSet].push_back(i1);
3182 }
3183 }
3184 //NbigOuterSets[layer-1].push_back(nBigOuterSet);
3185 if(myDebugNb==2)
3186 cout<<" ("<<outerNbSetIdx.size()<<" in total)"<<endl;
3187 if(outerNbSetIdx.size()>1) {// set inner hits on node
3188 isNode[layer-1][i1]=1;
3189 if(myDebugNb==2)
3190 cout<<" innner set "<<i1<<" is a node"<<endl;
3191 }
3192 outerHitSets[layer-1].push_back(outerNbSetIdx);
3193 bigOuterSets[layer-1].push_back(bigOuterNbSetIdx);
3194 // --- update newTrkPaths
3195 //int nTrk=0;
3196 //int aWireIdx=hitSets[layer-1][i1][0];
3197 //vector<vector<int> >::iterator it_path=trackPaths.begin();
3198 //for(; it_path!=trackPaths.end(); it_path++) {
3199 // vector<int> aPath = *it_path;
3200 // vector<int>::iterator it_hit = find(aPath.begin(), aPath.end(), aWireIdx);
3201 // if(it_hit!=aPath.end()) {
3202 // nTrk++;
3203 // for(int iSet=0; iSet<outerNbSetIdx.size(); iSet++) {
3204 // vector<int> aNewPath=aPath;
3205 // aNewPath.insert(aNewPath.end(), hitSets[layer][outerNbSetIdx[iSet]].begin(), hitSets[layer][outerNbSetIdx[iSet]].end());
3206 // if(iSet==0) *it_path=aNewPath;
3207 // else newTrkPaths.push_back(aNewPath);
3208 // }
3209 // //if(outerNbSetIdx.size()==0) newTrkPaths.push_back(aPath);
3210 // }
3211 //}
3212 //if(myDebugNb==2)
3213 // cout<<" "<<nTrk<<" trk path(s) with this inner-hit-set"<<endl;
3214 // --- update newFatPaths, fatPaths
3215 if(hitSets[layer-1][i1].size()>nHitsBig) {// if a big inner set
3216 int nBigPath = fatPaths.size();
3217 for(int iBigPath=0; iBigPath<nBigPath; iBigPath++)// loop paths
3218 {
3219 int last_layer=fatPaths[iBigPath][0]+fatPaths[iBigPath].size()-2;
3220 if(last_layer==(layer-1)&&fatPaths[iBigPath].back()==i1) {// find the big path with inner big set i1
3221 vector<int> aBigPath=fatPaths[iBigPath];
3222 for(int iSet=0; iSet<bigOuterNbSetIdx.size(); iSet++) {
3223 int setIdx = bigOuterNbSetIdx[iSet];
3224 vector<int> aNewBigPath = aBigPath;
3225 aNewBigPath.push_back(setIdx);
3226 if(iSet==0) fatPaths[iBigPath]=aNewBigPath;
3227 else newFatPaths.push_back(aNewBigPath);
3228 }// loop outer big Nb
3229 }// match big set and big path
3230 }// loop big paths
3231 }// if a big inner set
3232 }// i1 loop inner hit sets
3233 bigInnerSets[layer]=innerBigNb;
3234 innerHitSets[layer]=innerNb;
3235 for(int iSet=0; iSet<bigSets[layer].size(); iSet++) {
3236 int setIdx = bigSets[layer][iSet];
3237 if(innerBigNb[setIdx].size()==0) {
3238 vector<int> aFatPath;
3239 aFatPath.push_back(layer);
3240 aFatPath.push_back(setIdx);
3241 newFatPaths.push_back(aFatPath);
3242 }
3243 }
3244 fatPaths.insert(fatPaths.end(), newFatPaths.begin(), newFatPaths.end());
3245 for(int i2=0; i2<nSet; i2++) // loop hit-sets in current layer
3246 {
3247 if(innerNb[i2].size()>1) {
3248 isNode[layer][i2]=1;
3249 if(myDebugNb==2)
3250 cout<<" set "<<i2<<" is a node"<<endl;
3251 }
3252 //else if(innerNb[i2].size()==0) {// a brand-new path
3253 // newTrkPaths.push_back(hitSets[layer][i2]);
3254 //}
3255 //int nBigInnerSet=0;
3256 //vector<int> bigInnerNbSetIdx;// inner big NB sets for the hit-set in current layer with index i2
3257 //for(int i_innb=0; i_innb<innerNb[i2].size(); i_innb++)
3258 //{
3259 // int innerSetIdx=innerNb[i2][i_innb];
3260 // if(hitSets[layer-1][innerSetIdx].size()>3) {
3261 // //nBigInnerSet++;
3262 // bigInnerNbSetIdx.push_back(innerSetIdx);
3263 // int nBigPath = fatPaths.size();
3264 // for(int iBigPath=0; iBigPath<nBigPath; iBigPath++)
3265 // {
3266 // int last_layer=fatPaths[iBigPath][0]+fatPaths[iBigPath].size()-2;
3267 // if(last_layer==(layer-1)&&fatPaths[iBigPath].back()==innerSetIdx) {
3268 // fatPaths[iBigPath].push_back(i2);
3269 // }
3270 // }
3271 // }
3272 //}
3273 //NbigInnerSets[layer].push_back(nBigInnerSet);
3274 //bigInnerSets[layer].push_back(bigInnerNbSetIdx);
3275 }// loop hit-sets in current layer
3276 //trackPaths.insert(trackPaths.end(), newTrkPaths.begin(), newTrkPaths.end());
3277 //if(myDebugNb==2)
3278 // cout<<" "<<trackPaths.size()<<" possible track path(s) "<<endl;
3279 }// else if(iLayerHasHits>1)
3280 }// has >1 hits
3281 }// <--- loop layer to form NB sets relationship
3282 //if(myDebugNb==2) {
3283 // cout<<" In total, "<<trackPaths.size()<<" possible track path(s) found "<<endl;
3284 //}
3285 if(myDebugNb==2) cout<<" In total, "<<fatPaths.size()<<" fat path(s) found "<<endl;
3286
3287 // --- update inFatCluster[43]
3288 int nFatPath = fatPaths.size();
3289 for(int iFat=0; iFat<nFatPath; iFat++) {
3290 int nLayer = fatPaths[iFat].size()-1;
3291 if(nLayer>nLayerHitsBig) {
3292 if(myDebugNb==2)
3293 cout<<" a fat path with nLayer="<<nLayer<<" :";
3294 for(int iL=0; iL<nLayer; iL++) {
3295 int l=fatPaths[iFat][0]+iL;
3296 int setIdx = fatPaths[iFat][iL+1];
3297 if(myDebugNb==2)
3298 cout<<" L"<<l<<",Set"<<setIdx<<" ";
3299 inFatCluster[l][setIdx]=1;
3300 }
3301 if(myDebugNb==2)
3302 cout<<endl;
3303 }
3304 }
3305
3306 if(myDebugNb==2) {
3307 int nBig=0;
3308 for(int l=8; l<43; l++) {
3309 int nBigThisLayer = 0;
3310 int nSet= inFatCluster[l].size();
3311 if(nSet>0) {
3312 for(int iSet=0; iSet<nSet; iSet++)
3313 if(inFatCluster[l][iSet]!=0) {
3314 nBig++;
3315 nBigThisLayer++;
3316 if(nBig==1)
3317 if(myDebugNb==2) cout<<" in big cluster:"<<endl;
3318 if(nBigThisLayer==1) if(myDebugNb==2) cout<<" layer "<<l<<" set";
3319 if(myDebugNb==2)
3320 cout<<" "<<iSet;
3321 }
3322 if(nBigThisLayer>0) if(myDebugNb==2) cout<<endl;
3323 }
3324 }
3325 }
3326
3327
3328 // --- part 2 --- update onNode, form track paths
3329 if(myDebugNb==2)
3330 cout<<" === form track paths === "<<endl;
3331 iLayerHasHits=0;
3332 for(int l=8; l<43; l++) {// loop layers, from inside to outside
3333 vector<vector<int> > newTrkPaths;
3334
3335 int nSet = hitSets[l].size();
3336 if(nSet>0) iLayerHasHits++;
3337 else continue;
3338 if(myDebugNb==2)
3339 cout<<" layer "<<l<<", "<<nSet<<" hit-sets";
3340
3341 /*
3342 // ---> test 4 hit line fit with TLS
3343 const int nHitLineFit=4;
3344 int iSet1(0), iSet2(0), iSet3(0), iSet4(0);
3345 int iHitSet[nHitLineFit]={0,0,0,0};
3346 if(l<17||l==20||l==24||l==28||l==32||(l>=36&&l<40)) {
3347 for(int iSet1=0; iSet1<nSet; iSet1++) {
3348 if(inFatCluster[l][iSet1]!=0) continue; // not in big cluster
3349 vector<int>& v_setIdx2 = outerHitSets[l][iSet1];
3350 int nSet2=v_setIdx2.size();
3351 for(int iSet2=0; iSet2<nSet2; iSet2++) {
3352 int setIdx2 = v_setIdx2[iSet2];
3353 if(inFatCluster[l+1][setIdx2]!=0) continue; // not in big cluster
3354 vector<int>& v_setIdx3 = outerHitSets[l+1][setIdx2];
3355 int nSet3=v_setIdx3.size();
3356 for(int iSet3=0; iSet3<nSet3; iSet3++) {
3357 int setIdx3 = v_setIdx3[iSet3];
3358 if(inFatCluster[l+2][setIdx3]!=0) continue; // not in big cluster
3359 vector<int>& v_setIdx4 = outerHitSets[l+2][setIdx3];
3360 int nSet4=v_setIdx4.size();
3361 for(int iSet4=0; iSet4<nSet4; iSet4++) {
3362 int setIdx4 = v_setIdx4[iSet4];
3363 if(inFatCluster[l+3][setIdx4]!=0) continue; // not in big cluster
3364 cout<<" four neighbour hit sets found "<<endl;
3365 vector<const MdcDigi*> aVecMdcDigi;
3366 for(int iHit1=0; iHit1<hitSets[l][iSet1].size(); iHit1++)
3367 {
3368 for(int iHit2=0; iHit2<hitSets[l+1][setIdx2].size(); iHit2++)
3369 {
3370 for(int iHit3=0; iHit3<hitSets[l+2][setIdx3].size(); iHit3++)
3371 {
3372 for(int iHit4=0; iHit4<hitSets[l+3][setIdx4].size(); iHit4++)
3373 {
3374 cout<<" fit 4 hits (L, W): ";
3375 int wire_idx = hitSets[l][iSet1][iHit1];
3376 int layer= myMdcGeomSvc->Wire(wire_idx)->Layer();
3377 int wire = myMdcGeomSvc->Wire(wire_idx)->Cell();
3378 cout<<"("<<setw(2)<<layer<<","<<setw(3)<<wire<<") ";
3379 aVecMdcDigi.push_back(myMapMdcDigi[wire_idx]);
3380 wire_idx = hitSets[l+1][setIdx2][iHit2];
3381 layer= myMdcGeomSvc->Wire(wire_idx)->Layer(); wire = myMdcGeomSvc->Wire(wire_idx)->Cell(); cout<<"("<<setw(2)<<layer<<","<<setw(3)<<wire<<") ";
3382 aVecMdcDigi.push_back(myMapMdcDigi[wire_idx]);
3383 wire_idx = hitSets[l+2][setIdx3][iHit3];
3384 layer= myMdcGeomSvc->Wire(wire_idx)->Layer(); wire = myMdcGeomSvc->Wire(wire_idx)->Cell(); cout<<"("<<setw(2)<<layer<<","<<setw(3)<<wire<<") ";
3385 aVecMdcDigi.push_back(myMapMdcDigi[wire_idx]);
3386 wire_idx = hitSets[l+3][setIdx4][iHit4];
3387 layer= myMdcGeomSvc->Wire(wire_idx)->Layer(); wire = myMdcGeomSvc->Wire(wire_idx)->Cell(); cout<<"("<<setw(2)<<layer<<","<<setw(3)<<wire<<") ";
3388 cout<<endl;
3389 aVecMdcDigi.push_back(myMapMdcDigi[wire_idx]);
3390 LineFit_TLS(aVecMdcDigi);
3391 aVecMdcDigi.clear();
3392 }
3393 }
3394 }
3395 }
3396 }// set 4
3397 }// set 3
3398 }// set 2
3399 }// set 1
3400 }
3401 // <--- test 4 hit line fit with TLS
3402 */
3403
3404 // --- update track paths, newTrkPaths
3405 if(iLayerHasHits>1) {// not the the inner most layer
3406 int nPath=trackPaths.size();
3407 int nSetIn=hitSets[l-1].size();
3408 for(int i1=0; i1<nSetIn; i1++)// loop inner hit sets
3409 {
3410 if(inFatCluster[l-1][i1]!=0) continue; // not in big cluster
3411 int aWireIdx=hitSets[l-1][i1][0];
3412 for(int ipath=0; ipath<nPath; ipath++) { // loop current path
3413 vector<int> aPath = trackPaths[ipath];
3414 int pathSize = aPath.size();
3415 vector<int>::iterator it_hit = find(aPath.begin(), aPath.end(), aWireIdx);
3416 if(it_hit!=aPath.end()) {// match a inner hit set and a path
3417 int nBr=0;
3418 vector<int>& outerNbSetIdx=outerHitSets[l-1][i1];
3419 // ---> check if this path can be fitted to a line
3420 //if(l<19&&pathSize>=3) {
3421 // vector<const MdcDigi*> aVecMdcDigi;
3422 // cout<<" fit 3 hits (L, W): ";
3423 // for(int i=1; i<=3; i++) {
3424 // int wire_idx = aPath[pathSize-i];
3425 // int layer= myMdcGeomSvc->Wire(wire_idx)->Layer();
3426 // int wire = myMdcGeomSvc->Wire(wire_idx)->Cell();
3427 // cout<<"("<<setw(2)<<layer<<","<<setw(3)<<wire<<") ";
3428 // aVecMdcDigi.push_back(myMapMdcDigi[wire_idx]);
3429 // }
3430 // cout<<endl;
3431 // LineFit_TLS(aVecMdcDigi);
3432 //}// <--- check if this path can be fitted to a line
3433 for(int i2=0; i2<outerNbSetIdx.size(); i2++) {// loop outer NB hit-sets
3434 int setIdx=outerNbSetIdx[i2];
3435 if(inFatCluster[l][setIdx]!=0) continue; // not in big cluster
3436 nBr++;
3437 vector<int> aNewPath=aPath;
3438 aNewPath.insert(aNewPath.end(), hitSets[l][setIdx].begin(), hitSets[l][setIdx].end());// make a longer path
3439 // ---> check if this path can be fitted to a line
3440 //if(l<19&&aNewPath.size()>=4) {
3441 // vector<const MdcDigi*> aVecMdcDigi;
3442 // cout<<" fit 4 hits (L, W): ";
3443 // for(int i=1; i<=4; i++) {
3444 // int wire_idx = aNewPath[aNewPath.size()-i];
3445 // int layer= myMdcGeomSvc->Wire(wire_idx)->Layer();
3446 // int wire = myMdcGeomSvc->Wire(wire_idx)->Cell();
3447 // cout<<"("<<setw(2)<<layer<<","<<setw(3)<<wire<<") ";
3448 // aVecMdcDigi.push_back(myMapMdcDigi[wire_idx]);
3449 // }
3450 // cout<<endl;
3451 // LineFit_TLS(aVecMdcDigi);
3452 //}// <--- check if this path can be fitted to a line
3453
3454 if(nBr==1) trackPaths[ipath]=aNewPath;// update the matched path
3455 else newTrkPaths.push_back(aNewPath);// a new branch/path
3456 }
3457 if(myDebugNb==2)
3458 cout<<" inner-hit-set "<<i1<<" matches trk path "<<ipath<<", "<<nBr<<" branches found"<<endl;
3459 }
3460 }
3461 }
3462 } // if(iLayerHasHits>1) // not the the inner most layer
3463
3464 for(int i=0; i<nSet; i++) { // loop sets
3465 int nHit = hitSets[l][i].size();
3466 // --- update onNode
3467 if(isNode[l][i]==1) {
3468 for(int j=0; j<nHit; j++) {
3469 int wireIdx = hitSets[l][i][j];
3470 myMdcDigiGroup[wireIdx].SetOnNode();
3471 }
3472 }
3473 // --- update InBigSet
3474 if(nHit>=3) {
3475 for(int j=0; j<nHit; j++) {
3476 int wireIdx = hitSets[l][i][j];
3477 myMdcDigiGroup[wireIdx].SetInBigSet();
3478 }
3479 }
3480
3481 // --- form brand new track paths
3482 if(inFatCluster[l][i]==0) {// not in big cluster
3483 int nNewPath = newTrkPaths.size();
3484 if(iLayerHasHits==1) newTrkPaths.push_back(hitSets[l][i]);
3485 else {
3486 int nInNb=innerHitSets[l][i].size();
3487 //if(nInNb==0) newTrkPaths.push_back(hitSets[l][i]);
3488 int nInSmallNb=0;
3489 for(int i1=0; i1<innerHitSets[l][i].size(); i1++) {
3490 if(inFatCluster[l-1][innerHitSets[l][i][i1]]==0) nInSmallNb++;
3491 }
3492 if(nInSmallNb==0) {
3493 newTrkPaths.push_back(hitSets[l][i]);
3494 //if(nInNb>0) {
3495 // int nPath=trackPaths.size();
3496 // for(int ipath=0; ipath<nPath; ipath++) { // loop current paths
3497 // vector<int> aNewPath=trackPaths[ipath];
3498 // aNewPath.insert(aNewPath.end(), hitSets[l][i].begin(), hitSets[l][i].end());// make a longer path
3499 // newTrkPaths.push_back(aNewPath);// a new branch/path
3500 // }
3501 //}
3502 }
3503 }
3504 if(myDebugNb==2&&nNewPath<newTrkPaths.size()) cout<<" hit-set "<<i<<" taken as a start of a brand new trk path (root)"<<endl;
3505 }// not in big cluster
3506 }// loop sets
3507
3508 trackPaths.insert(trackPaths.end(), newTrkPaths.begin(), newTrkPaths.end());
3509 if(myDebugNb==2)
3510 cout<<" ---> "<<trackPaths.size()<<" possible track path(s) "<<endl;
3511
3512 }// loop layer to update onNode, form track paths
3513 if(myDebugNb==2)
3514 cout<<" In total, "<<trackPaths.size()<<" possible track path(s) found "<<endl;
3515
3516
3517 // --- part 3 --- loop track paths to find the best
3518 if(trackPaths.size()>1) {
3519 int i_path = 0;
3520 int i_bestPath = -1;
3521 int nMax_goodHits=0;
3522 //vector<struct trkCandi> vecTrkCandi;
3523 //vector<int> vecNGoodHits;
3524 myVecNhitPathId.clear();
3525 myVecTrkPaths.clear();
3526 for(vector<vector<int> >::iterator it_path=trackPaths.begin(); it_path!=trackPaths.end(); it_path++, i_path++) {
3527 if(myDebugNb==2)
3528 cout<<" ~~~ circlr fit of path "<<i_path<<": "<<endl;
3529 struct trkCandi oneTrkCandi=getTrkCandi(*it_path);
3530 //tagClusterHits(oneTrkCandi);
3531 myVecTrkPaths.push_back(oneTrkCandi);
3532 int nDropHits = circleFitTaubin(myVecTrkPaths.back(), 5, false, 2, true);
3533 int nFittedXhits=myDotsHelixFitter.getNActiveHits();
3534 if(nFittedXhits<4) continue;
3535 //vecNGoodHits.push_back(nFittedXhits);
3536 pair<int, int> nHitPathId(nFittedXhits, myVecTrkPaths.size()-1);
3537 myVecNhitPathId.push_back(nHitPathId);
3538 if(nMax_goodHits<nFittedXhits) {
3539 nMax_goodHits=nFittedXhits;
3540 i_bestPath=i_path;
3541 }
3542 }// loop paths for circle fits
3543 // --- sort myVecNhitPathId (to be done)
3544 int nPath = myVecNhitPathId.size();
3545 if(nPath==0) {
3546 aTrkCandi.isGood=0;
3547 return false;
3548 }
3549 myVecNhitPathId.erase(myVecNhitPathId.begin()+i_bestPath);
3550 // --- save the current trk candidate as the last one
3551 //struct trkCandi currentTrkCandi=aTrkCandi;
3552 int trkIdx = myVecTrkCandidates.size();
3553 //currentTrkCandi.trkIdx = trkIdx;
3554 //myVecTrkCandidates.push_back(currentTrkCandi);
3555 // --- update the current trk candidate's track index
3556 aTrkCandi.trkIdx = trkIdx;
3557 // --- update the current trk candidate with the best path
3558 // // printTrkCandi(myVecTrkPaths[i_bestPath]);
3559 myVecTrkPaths[i_bestPath].trkIdx = idxCandi;
3560 // // myVecTrkCandidates[idxCandi]=myVecTrkPaths[i_bestPath];
3561 //myVecTrkCandidates.erase(myVecTrkCandidates.begin()+idxCandi);
3562 myVecTrkCandidates.insert(myVecTrkCandidates.begin()+idxCandi, myVecTrkPaths[i_bestPath]);
3563 for(size_t idxx = idxCandi; idxx < myVecTrkCandidates.size();idxx ++) myVecTrkCandidates[trkIdx].trkIdx = idxx;// update track index
3564 //printTrkCandi(myVecTrkCandidates[idxCandi]);
3565
3566 if(myDebugNb==2) {
3567 cout<<" ----- the best path is "<<i_bestPath<<endl;
3568 cout<<" save the original trk candidate as the last one "<<endl;
3569 cout<<" save the best path as the trk candidate in processing"<<endl;
3570 }
3571 return true;
3572 }// if multi pathes
3573
3574 return false;
3575
3576}// split()
3577
3578void DotsConnection::tagClusterHits(struct trkCandi& aTrkCandi)
3579{
3580 //int nLayerTooManyHits=0;
3581 int nContiLayTooManyHits=0;
3582 for(int layer=8; layer<43; layer++) {
3583 int nHits = aTrkCandi.mdcHitIdx[layer].size();
3584 if(nHits>=3) {
3585 //nLayerTooManyHits++;
3586 nContiLayTooManyHits++;
3587 }
3588 if(nHits<3||layer==42) {
3589 if(nContiLayTooManyHits>=3) // tag fit flag =0
3590 {
3591 if(myDebugNb==2)
3592 cout<<" nContiLayTooManyHits>=3 to set fit flag=0"<<endl;
3593 for(int iL=layer; iL>layer-nContiLayTooManyHits; iL--)
3594 {
3595 vector<int>& hitId = aTrkCandi.mdcHitIdx[iL];
3596 if(myWireFlag[iL]==0) {
3597 for(int i=0; i<hitId.size(); i++) {
3598 int iHit=hitId[i];
3599 aTrkCandi.mdcXDigiFitted[iHit]=0;
3600 }
3601 }
3602 else {
3603 for(int i=0; i<hitId.size(); i++) {
3604 int iHit=hitId[i];
3605 aTrkCandi.mdcVDigiFitted[iHit]=0;
3606 }
3607 }
3608 }
3609 }
3610 nContiLayTooManyHits=0;
3611 }
3612 if(myDebugNb==2)
3613 cout<<"tagClusterHits: layer "<<layer<<", nHits="<<nHits<<", nContiLayTooManyHits="<<nContiLayTooManyHits<<endl;
3614 }
3615}
3616
3617/**
3618 * @brief check if element.GetOuter() in innerSet has intersection with outerSet; //weired.
3619 *
3620 * @param innerSet
3621 * @param outerSet
3622 * @return true
3623 * @return false
3624 */
3625bool DotsConnection::isInOutNeighbours(const vector<int>& innerSet, const vector<int>& outerSet)
3626{
3627 bool isNeighbour=false;
3628 int nInner = innerSet.size();
3629 vector<int>::const_iterator iter;
3630 //cout<<" outer-NB-hits: ";
3631 for(int i=0; i<nInner; i++) {
3632 int wireIdx=innerSet[i];
3633 //cout<<"("<<wireIdx<<")";
3634 //vector<int> vectmp = myMdcGeomSvc->Wire(wireIdx)->GetNeighborIDType4();
3635 const vector<int>& vectmp=myMdcDigiGroup[wireIdx].GetOuter();
3636 vector<int>::const_iterator it=vectmp.begin();
3637 for(; it!=vectmp.end(); it++) {
3638 //cout<<*it<<" ";
3639 iter = find(outerSet.begin(), outerSet.end(), *it);
3640 //if(outerSet.find(*it)!=outerSet.end())
3641 if(iter!=outerSet.end())
3642 {
3643 isNeighbour=true;
3644 break;
3645 }
3646 }
3647 if(isNeighbour) break;
3648 }
3649 //cout<<endl;
3650 return isNeighbour;
3651}
3652
3653bool DotsConnection::isInOutNeighbours(struct trkCandi& innerTrkCandi, struct trkCandi& outerTrkCandi, int gap)
3654{
3655 bool isNeighbour=false;
3656
3657 vector<int>* innerHitIdxVec;
3658 int type = myWireFlag[innerTrkCandi.layerMax];
3659 if(type==0) innerHitIdxVec=&(innerTrkCandi.mdcXDigiWireIdx);
3660 else if(type==1) innerHitIdxVec=&(innerTrkCandi.mdcV1DigiWireIdx);
3661 else if(type==-1) innerHitIdxVec=&(innerTrkCandi.mdcV2DigiWireIdx);
3662 vector<int> vecNeighbours1;
3663 for(int i=0; i<innerHitIdxVec->size(); i++)
3664 {
3665 int wireIdx = innerHitIdxVec->at(i);
3666 if(myMdcGeomSvc->Wire(wireIdx)->Layer()==innerTrkCandi.layerMax)
3667 {
3668 vector<int> vectmp = myMdcGeomSvc->Wire(wireIdx)->GetNeighborIDType4();
3669 vecNeighbours1.insert(vecNeighbours1.end(), vectmp.begin(), vectmp.end());
3670 }
3671 }
3672
3673 vector<int>* outerHitIdxVec;
3674 type = myWireFlag[outerTrkCandi.layerMin];
3675 if(type==0) outerHitIdxVec=&(outerTrkCandi.mdcXDigiWireIdx);
3676 else if(type==1) outerHitIdxVec=&(outerTrkCandi.mdcV1DigiWireIdx);
3677 else if(type==-1) outerHitIdxVec=&(outerTrkCandi.mdcV2DigiWireIdx);
3678 vector<int> vecNeighbours2;
3679 for(int i=0; i<outerHitIdxVec->size(); i++)
3680 {
3681 int wireIdx = outerHitIdxVec->at(i);
3682 if(myMdcGeomSvc->Wire(wireIdx)->Layer()==outerTrkCandi.layerMin)
3683 {
3684 vector<int> vectmp;
3685 if(gap==0) {
3686 vectmp.push_back(myMdcGeomSvc->Wire(wireIdx)->GetNeighborIDType1());
3687 vectmp.push_back(myMdcGeomSvc->Wire(wireIdx)->GetNeighborIDType2());
3688 }
3689 else if(gap>0) {
3690 vectmp = myMdcGeomSvc->Wire(wireIdx)->GetNeighborIDType3();
3691 }
3692 int iGap=gap;
3693 while(iGap>1) {
3694 vector<int> vectmp2;
3695 int nwire=vectmp.size();
3696 for(int j=0; j<nwire; j++) {
3697 vector<int> vectmp3 = myMdcGeomSvc->Wire(vectmp[j])->GetNeighborIDType3();
3698 vectmp2.insert(vectmp2.end(), vectmp3.begin(), vectmp3.end());
3699 }
3700 vectmp=vectmp2;
3701 iGap--;
3702 }
3703 vecNeighbours2.insert(vecNeighbours2.end(), vectmp.begin(), vectmp.end());
3704 }
3705 }
3706
3707 vector<int>::iterator iter;
3708 for(int i=0; i<vecNeighbours1.size(); i++)
3709 {
3710 iter = find(vecNeighbours2.begin(), vecNeighbours2.end(), vecNeighbours1[i]);
3711 if(iter!=vecNeighbours2.end()) {
3712 isNeighbour=true;
3713 break;
3714 }
3715 }
3716
3717 return isNeighbour;
3718}
3719
3720void DotsConnection::combineTrkCandi(struct trkCandi& trkCandi_1, struct trkCandi& trkCandi_2)
3721{
3722 trkCandi_2.isGood=-1;
3723
3724 int wireIdx, layer;
3725
3726 int nXhits_1 = trkCandi_1.mdcXDigiWireIdx.size();
3727 int nXhits_2 = trkCandi_2.mdcXDigiWireIdx.size();
3728 if(nXhits_2>0)
3729 {
3730 trkCandi_1.mdcXDigiWireIdx.insert(trkCandi_1.mdcXDigiWireIdx.end(), trkCandi_2.mdcXDigiWireIdx.begin(), trkCandi_2.mdcXDigiWireIdx.end());
3731 trkCandi_1.mdcXDigiChi.insert(trkCandi_1.mdcXDigiChi.end(), trkCandi_2.mdcXDigiChi.begin(), trkCandi_2.mdcXDigiChi.end());
3732 trkCandi_1.mdcXDigiFitted.insert(trkCandi_1.mdcXDigiFitted.end(), trkCandi_2.mdcXDigiFitted.begin(), trkCandi_2.mdcXDigiFitted.end());
3733 vector<int>::iterator iter = trkCandi_2.mdcXDigiWireIdx.begin();
3734 //vector<int>::iterator iter_fit = trkCandi_2.mdcXDigiFitted.begin();
3735 //cout<<"to combine the following X-digi: ";
3736 //for(; iter!=trkCandi_2.mdcXDigiWireIdx.end(); iter++, iter_fit++)
3737 for(; iter!=trkCandi_2.mdcXDigiWireIdx.end(); iter++)
3738 {
3739 wireIdx = *iter;
3740 layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
3741 trkCandi_1.mdcHitIdx[layer].push_back(nXhits_1);
3742 nXhits_1++;
3743 if(trkCandi_1.xLayerMin>layer) trkCandi_1.xLayerMin=layer;
3744 if(trkCandi_1.xLayerMax<layer) trkCandi_1.xLayerMax=layer;
3745 //cout<<"L="<<layer<<"("<<*iter_fit<<") ";
3746 }
3747 //cout<<endl;
3748 }
3749 if(trkCandi_1.layerMin>trkCandi_1.xLayerMin) trkCandi_1.layerMin=trkCandi_1.xLayerMin;
3750 if(trkCandi_1.layerMax<trkCandi_1.xLayerMax) trkCandi_1.layerMax=trkCandi_1.xLayerMax;
3751
3752 int nV1hits_1 = trkCandi_1.mdcV1DigiWireIdx.size();
3753 int nV1hits_2 = trkCandi_2.mdcV1DigiWireIdx.size();
3754 if(nV1hits_2>0)
3755 {
3756 trkCandi_1.mdcV1DigiWireIdx.insert(trkCandi_1.mdcV1DigiWireIdx.end(), trkCandi_2.mdcV1DigiWireIdx.begin(), trkCandi_2.mdcV1DigiWireIdx.end());
3757 vector<int>::iterator iter = trkCandi_2.mdcV1DigiWireIdx.begin();
3758 for(; iter!=trkCandi_2.mdcV1DigiWireIdx.end(); iter++)
3759 {
3760 wireIdx = *iter;
3761 layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
3762 //trkCandi_1.mdcHitIdx[layer].push_back(nV1hits_1);
3763 nV1hits_1++;
3764 if(trkCandi_1.layerMin>layer) trkCandi_1.layerMin=layer;
3765 if(trkCandi_1.layerMax<layer) trkCandi_1.layerMax=layer;
3766 }
3767 }
3768
3769 int nV2hits_1 = trkCandi_1.mdcV2DigiWireIdx.size();
3770 int nV2hits_2 = trkCandi_2.mdcV2DigiWireIdx.size();
3771 if(nV2hits_2>0)
3772 {
3773 trkCandi_1.mdcV2DigiWireIdx.insert(trkCandi_1.mdcV2DigiWireIdx.end(), trkCandi_2.mdcV2DigiWireIdx.begin(), trkCandi_2.mdcV2DigiWireIdx.end());
3774 vector<int>::iterator iter = trkCandi_2.mdcV2DigiWireIdx.begin();
3775 for(; iter!=trkCandi_2.mdcV2DigiWireIdx.end(); iter++)
3776 {
3777 wireIdx = *iter;
3778 layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
3779 //trkCandi_1.mdcHitIdx[layer].push_back(nV2hits_1);
3780 nV2hits_1++;
3781 if(trkCandi_1.layerMin>layer) trkCandi_1.layerMin=layer;
3782 if(trkCandi_1.layerMax<layer) trkCandi_1.layerMax=layer;
3783 }
3784 }
3785
3786 int nVhits_1 = trkCandi_1.mdcVDigiWireIdx.size();
3787 int nVhits_2 = trkCandi_2.mdcVDigiWireIdx.size();
3788 if(nVhits_2>0)
3789 {
3790 trkCandi_1.mdcVDigiWireIdx.insert(trkCandi_1.mdcVDigiWireIdx.end(), trkCandi_2.mdcVDigiWireIdx.begin(), trkCandi_2.mdcVDigiWireIdx.end());
3791 vector<int>::iterator iter = trkCandi_2.mdcVDigiWireIdx.begin();
3792 for(; iter!=trkCandi_2.mdcVDigiWireIdx.end(); iter++)
3793 {
3794 wireIdx = *iter;
3795 layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
3796 trkCandi_1.mdcHitIdx[layer].push_back(nVhits_1);
3797 nVhits_1++;
3798 if(trkCandi_1.layerMin>layer) trkCandi_1.layerMin=layer;
3799 if(trkCandi_1.layerMax<layer) trkCandi_1.layerMax=layer;
3800 }
3801 }
3802}
3803
3804void DotsConnection::rmPathInTrkCandi(struct trkCandi& aTrkCandi, struct trkCandi& path)
3805{
3806 for(int i=0; i<43; i++) aTrkCandi.mdcHitIdx[i].clear();
3807 aTrkCandi.layerMin=99;
3808 aTrkCandi.layerMax=-1;
3809 aTrkCandi.xLayerMin=99;
3810 aTrkCandi.xLayerMax=-1;
3811
3812 vector<int> vecMdcXDigiIdx = aTrkCandi.mdcXDigiWireIdx;
3813 if(myDebugNb==2)
3814 cout<<"rmPathInTrkCandi: "<<vecMdcXDigiIdx.size()<<" X-hits to ";
3815 vector<int>& vecMdcXDigiIdx_2 = path.mdcXDigiWireIdx;
3816 vector<int> vecMdcXDigiIdx_2_fitted;
3817 int n2=vecMdcXDigiIdx_2.size();
3818 int wireIdx, layer;
3819 for(int i=0; i<n2; i++) {
3820 wireIdx=vecMdcXDigiIdx_2[i];
3821 if(path.mdcXDigiFitted[i]>0||myMdcDigiGroup[wireIdx].isOnNode()==0) vecMdcXDigiIdx_2_fitted.push_back(wireIdx);
3822 }
3823 vector<int> vecMdcXDigiIdx_new = getUncommonVec(vecMdcXDigiIdx, vecMdcXDigiIdx_2_fitted);
3824 aTrkCandi.mdcXDigiWireIdx=vecMdcXDigiIdx_new;
3825 int nXMdcDigi = vecMdcXDigiIdx_new.size();
3826 for(int i=0; i<nXMdcDigi; i++) {
3827 wireIdx = vecMdcXDigiIdx_new[i];
3828 layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
3829 aTrkCandi.mdcHitIdx[layer].push_back(i);
3830 //if(layer>aTrkCandi.layerMax) aTrkCandi.layerMax=layer;
3831 //if(layer<aTrkCandi.layerMin) aTrkCandi.layerMin=layer;
3832 if(layer>aTrkCandi.xLayerMax) aTrkCandi.xLayerMax=layer;
3833 if(layer<aTrkCandi.xLayerMin) aTrkCandi.xLayerMin=layer;
3834 }
3835 aTrkCandi.layerMin=aTrkCandi.xLayerMin;
3836 aTrkCandi.layerMax=aTrkCandi.xLayerMax;
3837 if(myDebugNb==2)
3838 cout<<nXMdcDigi<<endl;
3839 double nXRm=vecMdcXDigiIdx.size()-nXMdcDigi;
3840 aTrkCandi.mdcXDigiChi.clear();
3841 aTrkCandi.mdcXDigiChi.resize(nXMdcDigi, 9999.0);
3842 aTrkCandi.mdcXDigiFitted.clear();
3843 aTrkCandi.mdcXDigiFitted.resize(nXMdcDigi, 1);
3844
3845 vector<int> vecMdcVDigiIdx = aTrkCandi.mdcVDigiWireIdx;
3846 vector<int>& vecMdcVDigiIdx_2 = path.mdcVDigiWireIdx;
3847 vector<int> vecMdcVDigiIdx_2_fitted;
3848 n2=vecMdcVDigiIdx_2.size();
3849 for(int i=0; i<n2; i++) {
3850 wireIdx=vecMdcVDigiIdx_2[i];
3851 if(path.mdcVDigiFitted[i]>0||myMdcDigiGroup[wireIdx].isOnNode()==0) vecMdcVDigiIdx_2_fitted.push_back(vecMdcVDigiIdx_2[i]);
3852 }
3853 vector<int> vecMdcVDigiIdx_new = getUncommonVec(vecMdcVDigiIdx, vecMdcVDigiIdx_2_fitted);
3854 int nVMdcDigi = vecMdcVDigiIdx_new.size();
3855 if(myDebugNb==2)
3856 cout<<" "<<vecMdcVDigiIdx.size()<<" V-hits to "<<nVMdcDigi<<endl;
3857 double nVRm=vecMdcVDigiIdx.size()-nVMdcDigi;
3858 for(int i=0; i<nVMdcDigi; i++) {
3859 wireIdx = vecMdcVDigiIdx_new[i];
3860 layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
3861 aTrkCandi.mdcHitIdx[layer].push_back(i);
3862 if(layer>aTrkCandi.layerMax) aTrkCandi.layerMax=layer;
3863 if(layer<aTrkCandi.layerMin) aTrkCandi.layerMin=layer;
3864 }
3865 aTrkCandi.mdcVDigiWireIdx=vecMdcVDigiIdx_new;
3866 aTrkCandi.mdcVDigiChi.clear();
3867 aTrkCandi.mdcVDigiChi.resize(nVMdcDigi, 9999.0);
3868 aTrkCandi.mdcVDigiFitted.clear();
3869 aTrkCandi.mdcVDigiFitted.resize(nVMdcDigi, 1);
3870
3871 if((nXMdcDigi+nVMdcDigi)<3 || nXRm==0)
3872 aTrkCandi.isGood=0;
3873 else
3874 aTrkCandi.isGood=1;
3875}
3876
3877/**
3878 * @brief get items in v1 that are not in v2
3879 *
3880 * @param v1
3881 * @param v2
3882 * @return vector<int>
3883 */
3884vector<int> DotsConnection::getUncommonVec(vector<int> v1, vector<int>& v2)
3885{
3886 int n=v2.size();
3887 vector<int>::iterator it;
3888 for(int i=0; i<n; i++) {
3889 it=find(v1.begin(), v1.end(), v2[i]);
3890 if(it!=v1.end()) v1.erase(it);
3891 }
3892 return v1;
3893}
3894
3895void DotsConnection::setMinusVec(set<int>& s, vector<int>& v)
3896{
3897 int n=v.size();
3898 for(int i=0; i<n; i++) {
3899 set<int>::iterator it_s = s.find(v.at(i));
3900 if(it_s!=s.end()) s.erase(it_s);
3901 }
3902}
3903
3904void DotsConnection::resetXDigiFitItem(struct trkCandi& aTrkCandi)
3905{
3906 int nMdcXHits=aTrkCandi.mdcXDigiWireIdx.size();
3907 aTrkCandi.mdcXDigiFitted.clear();// must be called to make the following assignment valid
3908 aTrkCandi.mdcXDigiFitted.resize(nMdcXHits,1);
3909 aTrkCandi.mdcXDigiChi.clear();
3910 aTrkCandi.mdcXDigiChi.resize(nMdcXHits, 9999);
3911}
3912
3913void DotsConnection::resetVDigiFitItem(struct trkCandi& aTrkCandi)
3914{
3915 int nMdcVHits=aTrkCandi.mdcVDigiWireIdx.size();
3916 aTrkCandi.mdcVDigiFitted.clear();
3917 aTrkCandi.mdcVDigiFitted.resize(nMdcVHits,1);
3918 aTrkCandi.mdcVDigiChi.clear();
3919 aTrkCandi.mdcVDigiChi.resize(nMdcVHits, 9999);
3920}
3921
3922void DotsConnection::updateDigiFitItem(struct trkCandi& aTrkCandi)
3923{
3924 vector<int> vecActive = myDotsHelixFitter.getVecMdcDigiIsAct();
3925 //vector<int>::iterator iterActive = vecActive.begin();
3926 vector<double> vecChi = myDotsHelixFitter.getVecChiMdcDigi();
3927 //vector<double>::iterator iterChi = vecChi.begin();
3928 for(int i=0; i<vecActive.size(); i++)
3929 {
3930 int idx = myVecDigiIdx[i];
3931 if(idx>=0) {
3932 aTrkCandi.mdcXDigiChi[idx]=vecChi[i];
3933 aTrkCandi.mdcXDigiFitted[idx]=vecActive[i];
3934 }
3935 else {
3936 idx=-idx-1;
3937 aTrkCandi.mdcVDigiChi[idx]=vecChi[i];
3938 aTrkCandi.mdcVDigiFitted[idx]=vecActive[i];
3939 }
3940 }
3941}
3942
3943void DotsConnection::updateCgemFitItem(struct trkCandi& aTrkCandi, int assignCgemClu)
3944{
3945 vector<int> vecActive = myDotsHelixFitter.getVecIsActiveCgemCluster();
3946 vector<double> vecChi = myDotsHelixFitter.getVecChiCgemCluster();
3947 //if(assignCgemClu>0) cout<<__FUNCTION__<<" to assign CGEM clusters "<<endl;
3948 for(int i=0; i<vecActive.size(); i++)
3949 {
3950 int idx = myVecCluIdx[i];
3951 if(idx>=0) {// X-cluster
3952 //aTrkCandi.CgemXClusterChi[idx]=vecChi[i];
3953 int cluIdx = aTrkCandi.CgemXClusterID[idx];
3954 //cout<<"CGEM X-cluster, id = "<<cluIdx<<endl;
3955 if(vecActive[i]==-1) {
3956 if(cluIdx>=0) {
3957 cluIdx=-cluIdx-1;
3958 aTrkCandi.CgemXClusterID[idx]=cluIdx;
3959 }
3960 }
3961 else if(assignCgemClu>0&&cluIdx>=0){
3962 myIterClu=myIterCgemClusterBegin+cluIdx;
3963 int layer= (*myIterClu)->getlayerid();
3964 int size=myVecCgemXClusterIdx[layer].size();
3965 for(int j=0; j<size; j++) {
3966 if(myVecCgemXClusterIdx[layer][j]==cluIdx) {
3967 myVecCgemXClusterTrkIdx[layer][j]=aTrkCandi.trkIdx;
3968 //cout<<"layer "<<layer<<" "<<j<<" X-cluster is assigned to trk candi "<<aTrkCandi.trkIdx<<endl;
3969 break;
3970 }
3971 }
3972 }
3973 }
3974 else {// V-cluster
3975 idx=-idx-1;
3976 //aTrkCandi.CgemVClusterChi[idx]=vecChi[i];
3977 int cluIdx = aTrkCandi.CgemVClusterID[idx];
3978 if(vecActive[i]==-1) {
3979 if(cluIdx>=0) {
3980 cluIdx=-cluIdx-1;
3981 aTrkCandi.CgemVClusterID[idx]=cluIdx;
3982 }
3983 }
3984 else if(assignCgemClu>0&&cluIdx>=0){
3985 myIterClu=myIterCgemClusterBegin+cluIdx;
3986 int layer= (*myIterClu)->getlayerid();
3987 int size=myVecCgemVClusterIdx[layer].size();
3988 for(int j=0; j<size; j++) {
3989 if(myVecCgemVClusterIdx[layer][j]==cluIdx) {
3990 myVecCgemVClusterTrkIdx[layer][j]=aTrkCandi.trkIdx;
3991 break;
3992 }
3993 }
3994 }
3995 }
3996 }
3997}
3998
3999
4000void DotsConnection::dropRedundantMdcXDigi(struct trkCandi& aTrkCandi)
4001{
4002 vector<const MdcDigi*> aGoodXDigiVec;
4003 for(int i=8; i<43; i++)
4004 {
4005 if(aTrkCandi.mdcHitIdx[i].size()==1) {
4006 int idx = aTrkCandi.mdcHitIdx[i][0];
4007 int wireIdx = aTrkCandi.mdcXDigiWireIdx[idx];
4008 aGoodXDigiVec.push_back(myMapMdcDigi[wireIdx]);
4009 }
4010 else {// if too many hits on the same layer, but they are nonadjacent
4011 vector<int> idxVec = aTrkCandi.mdcHitIdx[i];
4012 }
4013 //if(i==19) i=35;
4014 }
4015}
4016
4017void DotsConnection::calcuCiclePar3CgemClu(struct trkCandi& aTrkCandi)
4018{
4019 if(aTrkCandi.CgemXClusterID.size()==3) {
4020 double x[3]={0,0,0};
4021 double y[3]={0,0,0};
4022 int i=0;
4023 for(; i<3; i++) {
4024 int cluIdx = aTrkCandi.CgemXClusterID[i];
4025 myIterClu=myIterCgemClusterBegin+cluIdx;
4026 double phi_cluster = (*myIterClu)->getrecphi();
4027 int layer= (*myIterClu)->getlayerid();
4028 double r =myDotsHelixFitter.getRmidGapCgem(layer);
4029 x[i]=r*cos(phi_cluster);
4030 y[i]=r*sin(phi_cluster);
4031 }
4032 double x0,y0,r0;
4033 x0 = ((pow(x[2],2)+pow(y[2],2))*(y[1]-y[0])+(pow(x[1],2)+pow(y[1],2))*(y[0]-y[2])+(pow(x[0],2)+pow(y[0],2))*(y[2]-y[1]))/(2.*((x[2] - x[0])*(y[1] - y[0]) - (x[1] -x[0])*(y[2] - y[0])));
4034 y0 = ((pow(x[2],2)+pow(y[2],2))*(x[1]-x[0])+(pow(x[1],2)+pow(y[1],2))*(x[0]-x[2])+(pow(x[0],2)+pow(y[0],2))*(x[2]-x[1]))/(2.*((y[2] - y[0])*(x[1] - x[0]) - (y[1] -y[0])*(x[2] - x[0])));
4035 r0 = sqrt(pow(x[1]-x0, 2) + pow(y[1]-y0,2));
4036 double xmean=(x[0]+x[1]+x[2])/3.0;
4037 double ymean=(y[0]+y[1]+y[2])/3.0;
4038 double dr_fit = sqrt(x0*x0+y0*y0)-r0;
4039 double phi0_fit = atan2(y0,x0);
4040 KalmanFit::Helix aHelix;
4041 double myAlpha=aHelix.alpha();
4042 double kappa_fit= myAlpha/r0;
4043 Hep3Vector pos_mean(xmean, ymean);
4044 Hep3Vector pos_center(x0, y0);
4045 Hep3Vector vec_z=pos_mean.cross(pos_center);
4046 double charge=vec_z.z()/fabs(vec_z.z());
4047 if(charge>0)
4048 {
4049 dr_fit = -dr_fit;
4050 phi0_fit+=M_PI;
4051 kappa_fit = -kappa_fit;
4052 }
4053 while(phi0_fit< 0 ) phi0_fit+=2*M_PI;
4054 while(phi0_fit> 2*M_PI) phi0_fit-=2*M_PI;
4055 aTrkCandi.a_helix[0]=dr_fit;
4056 aTrkCandi.a_helix[1]=phi0_fit;
4057 aTrkCandi.a_helix[2]=kappa_fit;
4058 if(myDebugNb==2)
4059 cout<<__FUNCTION__<<": circle par = "<<dr_fit<<", "<<phi0_fit<<", "<<kappa_fit<<endl;
4060 }
4061}
4062
4063/**
4064 * @brief gives points that might be
4065 *
4066 * @param aTrkCandi the candi
4067 * @return std::vector<std::pair<double, double> >
4068 */
4069std::vector<std::pair<double, double> > DotsConnection::findWireCrossPoint(struct trkCandi& aTrkCandi, vector<double>* ref_track_param){
4070 std::vector<const MdcDigi *> usedDigis=getVDigiVec(aTrkCandi,1);
4071 // double d_rho,phi_0,kappa;
4072 // std::auto_ptr< KalmanFit::Helix> aHelix(nullptr);
4073 // if (ref_track_param) {
4074 // // d_rho = (*ref_track_param)[0];
4075 // // phi_0 = (*ref_track_param)[1];
4076 // // kappa = (*ref_track_param)[2];
4077 // HepPoint3D pivot(0,0,0);
4078 // HepVector a(5,0);
4079 // a(1)=(*ref_track_param)[0];
4080 // a(2)=(*ref_track_param)[1];
4081 // a(3)=(*ref_track_param)[2];
4082 // aHelix.reset(new KalmanFit::Helix(pivot,a));
4083 // }
4084
4085
4086 // since in MDC, we have such arrangement according to
4087 // https://doi.org/10.1016/j.nima.2009.12.050.
4088 // layer supL TiltAng
4089 // 1–4 1 U: (3.01–3.31)
4090 // 5–8 2 V: +(3.41–3.91)
4091 // 9–20 3–5 A: 0
4092 // 21–24 6 U: (2.41–2.81)
4093 // 25–28 7 V: +(2.81–3.11)
4094 // 29–32 8 U: (3.11–3.41)
4095 // 33–36 9 V: +(3.41–3.61)
4096 // 37–43 10–11 A: 0
4097 const int prevLayers[]={23,27,31};
4098 const int nextLayers[]={24,28,32};
4099 const int allNotedLayers[]={23,24,27,28,31,32};
4100 // const int allNotedLayers[]={22,23,26,27,30,31};// what if we let it -1 layer
4101 std::vector<const MdcGeoWire *> crossWires[6];
4102 std::cout<<"---findWireCrossPoint: getting digi layer and wires"<<'\n';
4103 for (size_t ii=0; ii<usedDigis.size(); ++ii){
4104 const MdcDigi * digi=usedDigis[ii];
4105 Identifier id = digi->identify();
4106 int layer = MdcID::layer(id);
4107 int wire = MdcID::wire(id);
4108 int layerIdx=-1;
4109
4110 for (size_t i=0;i< sizeof(allNotedLayers)/sizeof(int) ;++i){
4111 if (layer==allNotedLayers[i]) {
4112 layerIdx=i;
4113 break;
4114 }
4115 }
4116 if (layerIdx == -1) continue;
4117 const MdcGeoWire* wir=myMdcGeomSvc->Wire(layer,wire);
4118 crossWires[layerIdx].push_back(wir);// wish we are getting id right.
4119 // cout<<"\t\t wire: id="<<id<<" layer"<<layer<<" layerIdx"<<layerIdx<<" wire.layer"<<wir->Layer()<<" wire.Id"<<wir->Id()<<"\n";
4120 }
4121 for (size_t ii=0; ii<sizeof(allNotedLayers)/sizeof(int); ii++) {// for allNotedLayers
4122 int layerGroupId=ii/2;
4123 if (crossWires[ii].empty()){
4124 crossWires[(ii xor (size_t)1)].clear(); // the other one in the group.
4125 }
4126 }
4127 std::vector<std::pair<double, double> > res;
4128 for (size_t ii=0; ii<sizeof(allNotedLayers)/sizeof(int)/2; ii++){//for allNotedLayer groups
4129 std::vector<const MdcGeoWire *> & wirePrev=crossWires[ii*2];
4130 std::vector<const MdcGeoWire *> & wirePost=crossWires[ii*2+1];
4131 typedef std::vector<const MdcGeoWire *>::iterator WireIt;
4132 std::vector<std::pair<double, double> > conjs;
4133 for (WireIt it1=wirePrev.begin(); it1!=wirePrev.end(); ++it1){
4134 for(WireIt it2=wirePost.begin(); it2!=wirePost.end(); ++it2){
4135 HepPoint3D p;
4136 p=myMdcGeomSvc->getAdjacentIntersectionPointSlower(*it1,*it2);
4137 p/=10.;
4138 // if(ref_track_param){
4139 // double ref_dphi=aHelix->dPhi(p);
4140
4141 // }
4142 // if (isnan(p.x()) || isnan(p.y()))
4143 // continue; // why nan??
4144 if (conjs.empty()){
4145 cout<<"--- findWireCrossPoint found point: ";
4146 }
4147 cout<<"("<<p.x()<<','<<p.y()<<','<<p.z()<<": layer.wire "<<(*it1)->Layer()<<"."<<(*it1)->Id() <<" : "<<(*it2)->Layer()<<"."<<(*it2)->Id()<<") ";
4148 conjs.push_back(std::make_pair(p.x(),p.y()));
4149 }
4150 }
4151 if (conjs.empty()) continue;
4152 cout<<"\n";
4153 std::pair<double, double> res2=std::make_pair(0.,0.);
4154 typedef std::vector<std::pair<double, double> >::iterator PairIt;
4155 int nCount=0;
4156 for (PairIt it1=conjs.begin(); it1!=conjs.end(); it1++){
4157 if (!isfinite(it1->first) || !isfinite(it1->second))continue;
4158 if (!myWireCrossPointAvgMode)res.push_back(*it1);
4159 res2.first+= it1->first;
4160 res2.second+= it1->second;
4161 nCount++;
4162 }
4163 if (nCount==0) continue;
4164 res2.first /=nCount;
4165 res2.second/=nCount;
4166 if (myWireCrossPointAvgMode)res.push_back(res2);
4167
4168
4169 }
4170 return res;
4171
4172
4173}
4174
4175/**
4176 * @brief
4177 *
4178 * @param aTrkCandi
4179 * @param chiCut
4180 * @param useIniHelix use aTrkCandi.a_helix and origin(0, 0, 0)
4181 * @param hitSel - 0:all 1:all associated 2: all fitted or uncertain 3: all fitted
4182 * @param setHitFitFlag
4183 * @param layerMin
4184 * @param layerMax
4185 * @return int
4186 */
4187int DotsConnection::circleFitTaubin(struct trkCandi& aTrkCandi, double chiCut, bool useIniHelix, int hitSel, bool setHitFitFlag, int layerMin, int layerMax, bool use_additional_points, bool usePhiAmbi, const vector<double>& vPhiAmb)
4188{
4189 myVecDigiIdx.clear();
4190 vector<int> aXDigiFitFlagVec;
4191 vector<const MdcDigi*> aXDigiVec = getXDigiVec(aTrkCandi, hitSel, &aXDigiFitFlagVec);
4192 //vector<const MdcDigi*> aXDigiVec = getXDigiVec(aTrkCandi, hitSel, aXDigiFitFlagVec);
4193 //if(myDebugNb==2) {
4194 // cout<<"N MDC X-digi : "<<aXDigiVec.size()<<endl;
4195 // int nHits=aXDigiFitFlagVec.size();
4196 // cout<<"aXDigiFitFlagVec size("<<nHits<<"): ";
4197 // for(int iHit=0; iHit<nHits; iHit++) cout<<aXDigiFitFlagVec[iHit]<<" ";
4198 // cout<<endl;
4199 //}
4200 //if(myDebugNb==2) cout<<"to setDChits"<<endl;
4201 myDotsHelixFitter.clearAllHits();
4202 //if(myDebugNb==2) cout<<"hits clear done"<<endl;
4203 myDotsHelixFitter.setDChits(aXDigiVec, myEvtT0);
4204 //if(myDebugNb==2) cout<<"setDChits done"<<endl;
4205 if(setHitFitFlag&&myDotsHelixFitter.setDChitsFitFlag(aXDigiFitFlagVec)) if(myDebugNb==2) cout<<"set fit flag successfully "<<endl;
4206 myDotsHelixFitter.usePhiAmbi(usePhiAmbi);
4207 if(usePhiAmbi) {
4208 if(myDotsHelixFitter.setDChitsPhiAmbi(vPhiAmb)) if(myDebugNb==2) cout<<"usePhiAmbi"<<endl;
4209 }
4210 //if(myDebugNb==2) cout<<"setDChitsFitFlag tried"<<endl;
4211 myVecCluIdx.clear();
4212 vector<const RecCgemCluster*> aVecCgemCluster = getXCluVec(aTrkCandi,hitSel);
4213 myDotsHelixFitter.setCgemClusters(aVecCgemCluster);
4214 //if(myDebugNb==2) cout<<"setCgemClusters done"<<endl;
4215 if(useIniHelix) {
4216 HepPoint3D origin(0, 0, 0);
4217 HepVector a_helix(5,0);
4218 a_helix(1)=aTrkCandi.a_helix[0];
4219 a_helix(2)=aTrkCandi.a_helix[1];
4220 a_helix(3)=aTrkCandi.a_helix[2];
4221 KalmanFit::Helix ini_helix(origin,a_helix);
4222 myDotsHelixFitter.setInitialHelix(ini_helix);
4223 }
4224 int nDeactived=0;
4225 vector<double> circleParVec;
4226 if(use_additional_points) {
4227 // vector<double> circleParVec2;
4228 // get d_rho, phi_0, kappa.
4229 // circleParVec2 = myDotsHelixFitter.calculateCirclePar_Taubin(useIniHelix, layerMin, layerMax); // but i guess first easily wrong?
4230
4231 std::vector<std::pair<double, double> > extraPoints=findWireCrossPoint(aTrkCandi);//&circleParVec2
4232 myDotsHelixFitter.setExtraPoints(extraPoints);
4233 if(myDebugNb==2){
4234 cout<<" --- extraPoint for Taubin fit: ";
4235 for (int i=0; i < extraPoints.size(); i++){
4236 cout<<"("<<extraPoints[i].first<<","<<extraPoints[i].second<<") ";
4237 }
4238 cout<<endl;
4239 }
4240 }
4241 while(1) {
4242 circleParVec = myDotsHelixFitter.calculateCirclePar_Taubin(useIniHelix, layerMin, layerMax, use_additional_points);
4243 use_additional_points=false;
4244 if(myDebugNb==2)
4245 cout<<" --- Circle par from Taubin fit: "<<circleParVec[0]
4246 <<", "<<circleParVec[1]
4247 <<", "<<circleParVec[2]
4248 <<", chi2 = "<<myDotsHelixFitter.getChi2()
4249 <<", nHitFit = "<<myDotsHelixFitter.getNActiveHits()
4250 <<endl;
4251 if(fabs(chiCut-9999.0)<0.001) break;
4252 if(myDotsHelixFitter.deactiveHits(chiCut, 1)==0) break;
4253 else nDeactived++;
4254 }
4255 if(myDebugNb==2)
4256 cout<<"DotsConnection::"<<__FUNCTION__<<": "<<nDeactived<<" hits deactived "<<endl;
4257
4258 int n_active=0;
4259 while(1) {
4260 int n_reactive = myDotsHelixFitter.activeHits(20, 1);// for uncertain hits
4261 if(n_reactive==0) break;
4262 //nDeactived-=n_reactive;
4263 n_active+=n_reactive;
4264 circleParVec = myDotsHelixFitter.calculateCirclePar_Taubin(useIniHelix, layerMin, layerMax);
4265 if(myDebugNb==2)
4266 cout<<" +++ Circle par from Taubin fit: "<<circleParVec[0]
4267 <<", "<<circleParVec[1]
4268 <<", "<<circleParVec[2]
4269 <<", chi2 = "<<myDotsHelixFitter.getChi2()
4270 <<", nHitFit = "<<myDotsHelixFitter.getNActiveHits()
4271 <<endl;
4272 }
4273 //cout<<"DotsConnection::"<<__FUNCTION__<<": "<<nDeactived<<" hits deactived "<<endl;
4274 if(myDebugNb==2)
4275 cout<<"DotsConnection::"<<__FUNCTION__<<": "<<n_active<<" uncertain hits actived "<<endl;
4276
4277 int n_active_2=0;
4278 while(1) {
4279 int n_reactive = myDotsHelixFitter.activeHits(chiCut, 0);// for all hits
4280 if(n_reactive==0) break;
4281 n_active_2+=n_reactive;
4282 //circleParVec = myDotsHelixFitter.calculateCirclePar_Taubin(useIniHelix, layerMin, layerMax);
4283 circleParVec = myDotsHelixFitter.calculateCirclePar_Taubin(true, layerMin, layerMax);
4284 if(myDebugNb==2)
4285 cout<<" +++ Circle par from Taubin fit: "<<circleParVec[0]
4286 <<", "<<circleParVec[1]
4287 <<", "<<circleParVec[2]
4288 <<", chi2 = "<<myDotsHelixFitter.getChi2()
4289 <<", nHitFit = "<<myDotsHelixFitter.getNActiveHits()
4290 <<endl;
4291 }
4292 //cout<<"DotsConnection::"<<__FUNCTION__<<": "<<nDeactived<<" hits deactived "<<endl;
4293 if(myDebugNb==2)
4294 cout<<"DotsConnection::"<<__FUNCTION__<<": "<<n_active_2<<" hits reactived "<<endl;
4295
4296 int nDeactived_2=0;
4297 while(1) {
4298 if(myDotsHelixFitter.deactiveHits(chiCut, 1)==0) break;
4299 if(fabs(chiCut-9999.0)<0.001) break;
4300 else nDeactived_2++;
4301 circleParVec = myDotsHelixFitter.calculateCirclePar_Taubin(useIniHelix, layerMin, layerMax);
4302 if(myDebugNb==2)
4303 cout<<" --- Circle par from Taubin fit: "<<circleParVec[0]
4304 <<", "<<circleParVec[1]
4305 <<", "<<circleParVec[2]
4306 <<", chi2 = "<<myDotsHelixFitter.getChi2()
4307 <<", nHitFit = "<<myDotsHelixFitter.getNActiveHits()
4308 <<endl;
4309 }
4310 if(myDebugNb==2)
4311 cout<<"DotsConnection::"<<__FUNCTION__<<": "<<nDeactived_2<<" hits deactived "<<endl;
4312 nDeactived=nDeactived-n_active-n_active_2+nDeactived_2;
4313
4314 aTrkCandi.a_helix[0]=circleParVec[0];
4315 aTrkCandi.a_helix[1]=circleParVec[1];
4316 aTrkCandi.a_helix[2]=circleParVec[2];
4317 aTrkCandi.chi2=myDotsHelixFitter.getChi2();
4318
4319 return nDeactived;
4320}
4321
4322void DotsConnection::circleFit(struct trkCandi& aTrkCandi)
4323{
4324 myVecDigiIdx.clear();
4325 vector<const MdcDigi*> aXDigiVec = getXDigiVec(aTrkCandi);
4326 //cout<<"N MDC X-digi : "<<aXDigiVec.size()<<endl;
4327 myDotsHelixFitter.clearAllHits();
4328 myDotsHelixFitter.setDChits(aXDigiVec, myEvtT0);
4329
4330 HepPoint3D origin(0, 0, 0);
4331 HepVector a_helix(5,0);
4332 a_helix(1)=aTrkCandi.a_helix[0];
4333 a_helix(2)=aTrkCandi.a_helix[1];
4334 a_helix(3)=aTrkCandi.a_helix[2];
4335 KalmanFit::Helix ini_helix(origin,a_helix);
4336 myDotsHelixFitter.setInitialHelix(ini_helix);
4337 myDotsHelixFitter.fitCircleOnly();
4338 myDotsHelixFitter.useAxialHitsOnly();
4339 int fitFlag = myDotsHelixFitter.calculateNewHelix();
4340 HepVector new_a = myDotsHelixFitter.getHelix();
4341 if(myDebugNb==2)
4342 cout<<"Circle par from LS fit: "<<new_a[0]
4343 <<", "<<new_a[1]
4344 <<", "<<new_a[2]
4345 <<", chi2 = "<<myDotsHelixFitter.getChi2()
4346 <<", nHitFit = "<<myDotsHelixFitter.getNActiveHits()
4347 <<endl;
4348}
4349
4350int DotsConnection::helixFit(struct trkCandi& aTrkCandi, double chiCut, int layerMin, int layerMax)
4351{
4352 myDotsHelixFitter.clearAllHits();
4353 vector<const MdcDigi*> aDigiVec = getDigiVec(aTrkCandi, 3);
4354 myDotsHelixFitter.setDChits(aDigiVec, myEvtT0);
4355 vector<const RecCgemCluster*> aVecCgemCluster = getCluVec(aTrkCandi, 2);
4356 myDotsHelixFitter.setCgemClusters(aVecCgemCluster);
4357
4358 HepPoint3D origin(0, 0, 0);
4359 HepVector a_helix(5,0);
4360 a_helix(1)=aTrkCandi.a_helix[0];
4361 a_helix(2)=aTrkCandi.a_helix[1];
4362 a_helix(3)=aTrkCandi.a_helix[2];
4363 a_helix(4)=aTrkCandi.a_helix[3];
4364 a_helix(5)=aTrkCandi.a_helix[4];
4365 KalmanFit::Helix ini_helix(origin,a_helix);
4366 myDotsHelixFitter.setInitialHelix(ini_helix);
4367
4368 int fitFlag=99;
4369 myDotsHelixFitter.fitModeHelix();
4370 int nIter=0;
4371 int nDropTot=0;
4372 while(1)
4373 {
4374 fitFlag = myDotsHelixFitter.calculateNewHelix();
4375 nIter++;
4376 if(fitFlag!=0) break;
4377 //if(myDotsHelixFitter.deactiveHits(myChiCut_helix,myNmaxDeact_helix)==0) break;
4378 int nDrop = myDotsHelixFitter.deactiveHits(chiCut,1);
4379 if(nDrop==0) break;
4380 nDropTot+=nDrop;
4381 //if(nIter>100) break;
4382 }
4383 nIter=0;
4384 int nReActiTot=0;
4385 while(1)
4386 {
4387 if(fitFlag!=0) break;
4388 //if(myDotsHelixFitter.activeHits(myChiCut_helix)==0) break;
4389 int nReActi = myDotsHelixFitter.activeHits(chiCut);
4390 if(nReActi==0) break;
4391 nReActiTot+=nReActi;
4392 fitFlag = myDotsHelixFitter.calculateNewHelix();
4393 nIter++;
4394 //if(nIter>100) break;
4395 }
4396 HepVector aHelix = myDotsHelixFitter.getHelix();
4397 double chi2 = myDotsHelixFitter.getChi2();
4398 if(fitFlag==0) {
4399 for(int i=0; i<5; i++) aTrkCandi.a_helix[i]=aHelix[i];
4400 aTrkCandi.chi2=chi2;
4401 aTrkCandi.RecMdcHitVec = myDotsHelixFitter.makeRecMdcHitVec(1);
4402 }
4403 else aTrkCandi.isGood=0;
4404 //if(myDebug)
4405 if(myDebugNb==2)
4406 {
4407 cout<<"fitFlag="<<fitFlag<<endl;
4408 cout<<nDropTot<<" hits dropped, "<<nReActiTot<<" hits reactived "<<endl;
4409 cout<<"helix chi2="<<myDotsHelixFitter.getChi2()<<endl;
4410 cout<<"fitted helix: ("<<aHelix(1)<<", "<<aHelix(2)<<", "<<aHelix(3)<<", "<<aHelix(4)<<", "<<aHelix(5)<<")"<<endl;
4411 //cout<<"helix error="<<myDotsHelixFitter.getEa()<<endl;
4412 }
4413
4414 return fitFlag;
4415}
4416
4417bool DotsConnection::matchMdcDigi(struct trkCandi& aTrkCandi, int idx)
4418{
4419 int direct = -1;
4420 int nMaxXHits = nXHitsActive(aTrkCandi);
4421 for(; direct<=1; direct+=2)
4422 {
4423 if(aTrkCandi.isGood!=1) continue;
4424 int layer;
4425 if(direct<0) layer = aTrkCandi.layerMin;
4426 else layer = aTrkCandi.layerMax;
4427 int layerToFind = layer+direct;
4428 if(myDebugNb==2)
4429 cout<<" try to match "<<direct<<" MDC hits: "<<endl;
4430 while(layerToFind>=8&&layerToFind<=42)
4431 {
4432 int gap = abs(layer-layerToFind)-1;
4433 if(gap>3) break;// if the gap size >3, stop matching ???
4434 //cout<<" trkCandi is good "<<aTrkCandi.isGood<<endl;
4435 if(myDebugNb==2)
4436 cout<<" layerToFind = "<<layerToFind<<", gap="<<gap<<endl;
4437 vector<struct trkCandi>::iterator iter_other = myVecTrkCandidates.begin();
4438 int idxTrk=0;
4439 int n_neighbSeg=0;
4440 int nmax_match=-1;
4441 int n_Xhits=0;
4442 vector<struct trkCandi>::iterator iter_matchBest;
4443 for(; iter_other!=myVecTrkCandidates.end(); iter_other++, idxTrk++)
4444 {
4445 //if(iter_other==iter_trkCandi) continue;
4446 if(idxTrk==idx) continue;
4447 int layerFound;
4448 if(direct<0) layerFound = (*iter_other).layerMax;
4449 else layerFound = (*iter_other).layerMin;
4450 if(layerFound!=layerToFind) continue;
4451 if((*iter_other).isGood==-1) continue;
4452 if(myDebugNb==2)
4453 cout<<" layer "<<layerToFind<<" is found"<<endl;
4454 if(direct<0) {
4455 struct trkCandi& innerTrkCandi = *iter_other;
4456 struct trkCandi& outerTrkCandi = aTrkCandi;
4457 if( isInOutNeighbours(innerTrkCandi,outerTrkCandi,gap)==false ) continue;
4458 }
4459 else if(direct>0) {
4460 struct trkCandi& outerTrkCandi = *iter_other;
4461 struct trkCandi& innerTrkCandi = aTrkCandi;
4462 if( isInOutNeighbours(innerTrkCandi,outerTrkCandi,gap)==false ) continue;
4463 }
4464 if(myDebugNb==2){
4465 cout<<" "<<gap<<"-layer-gap neighboured ";
4466 if(direct<0) cout<<"inner ";
4467 else cout<<"outer ";
4468 cout<<"segment found: "<<endl;}
4469 n_neighbSeg++;
4470 //iter_matchBest = iter_other;
4471 vector<int>::iterator iter_digi = (*iter_other).mdcXDigiWireIdx.begin();
4472 int n_matchedXhits=0;
4473 //printTrkCandi(*iter_other);
4474 for(; iter_digi!=(*iter_other).mdcXDigiWireIdx.end(); iter_digi++)
4475 {
4476 int wireIdx = *iter_digi;
4477 int layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
4478 if(myWireFlag[layer]!=0) continue;
4479 int wire = myMdcGeomSvc->Wire(wireIdx)->Cell();
4480 myDotsHelixFitter.updateDcDigiInfo(myMapMdcDigi[wireIdx]);
4481 if(myDebugNb==2)
4482 cout<<" (layer "<<layer<<", wire "<<wire<<", view "<<myWireFlag[layer]<<", chi "<<myDotsHelixFitter.getDigiChi()<<") "<<endl;
4483 n_Xhits++;
4484 if(fabs(myDotsHelixFitter.getDigiChi())<500) n_matchedXhits++;// ???
4485 }
4486 if(n_matchedXhits>nmax_match) {
4487 nmax_match=n_matchedXhits;
4488 iter_matchBest = iter_other;
4489 }
4490 }// loop other track candidates
4491 // --- combine two trk candi
4492 if(n_neighbSeg>0) {
4493 if(myDebugNb==2)
4494 cout<<" "<<n_neighbSeg<<" neighboured trk segments found, and the best one is to be combined"<<endl;
4495 //resetXDigiFitItem(*iter_matchBest);
4496 combineTrkCandi(aTrkCandi, *iter_matchBest);
4497 // int nDropHits =
4498 if(myDebugNb==2)
4499 cout<<"nmax_match="<<nmax_match<<", n_Xhits="<<n_Xhits<<endl;
4500 if(nmax_match>0) {
4501 bool useIniHelix=true;
4502 if(n_Xhits>nMaxXHits) {
4503 useIniHelix=false;
4504 if(myDebugNb==2)
4505 cout<<" circle fit without ini Helix, with all hits"<<endl;
4506 }
4507 else if(myDebugNb==2) cout<<" circle fit with ini Helix and all hits"<<endl;
4508 circleFitTaubin(aTrkCandi, 5, useIniHelix, 1, false);// use useIniHelix, all associated hits, not fit flag setting
4509 updateDigiFitItem(aTrkCandi);
4510 }
4511 else if(n_Xhits>0) {
4512 //circleFitTaubin(aTrkCandi, 5, false, 1, false);
4513 if(myDebugNb==2)
4514 cout<<" circle fit without ini Helix, rejected hits"<<endl;
4515 circleFitTaubin(aTrkCandi, 5, false, 2, true);// no iniHelix, fitted and uncertain hits, fit flag setting
4516 //updateDigiFitItem(aTrkCandi);
4517 int nXHitAct = myDotsHelixFitter.getNActiveHits();
4518 if(nXHitAct<nMaxXHits) {
4519 if(myDebugNb==2) {
4520 cout<<" "<<nXHitAct<<" hits kept, < "<<nMaxXHits<<" "<<endl;
4521 cout<<" circle fit with inner layer hits: "<<endl;}
4522 setFitFlagUncertain(aTrkCandi, 20, 60);
4523 circleFitTaubin(aTrkCandi, 5, false, 2, true);// no iniHelix, fitted and uncertain hits, fit flag setting
4524 nXHitAct = myDotsHelixFitter.getNActiveHits();
4525 if(myDebugNb==2)
4526 cout<<" "<<nXHitAct<<" hits kept"<<endl;
4527 }
4528 updateDigiFitItem(aTrkCandi);
4529 }
4530 double dr=aTrkCandi.a_helix[0];
4531 if(myDotsHelixFitter.getNActiveHits()<4||dr!=dr)
4532 {
4533 if(myDebugNb==2)
4534 cout<<"a bad circleFitTaubin! "<<endl;
4535 aTrkCandi.isGood=0;
4536 resetXDigiFitItem(aTrkCandi);
4537 break;// stop one direction match
4538 }
4539 else {
4540 if(direct<0) layer = aTrkCandi.layerMin;
4541 else layer = aTrkCandi.layerMax;
4542 layerToFind = layer+direct;
4543 //moreHitsFound=true;
4544 }
4545 }
4546 else layerToFind +=direct;
4547
4548 }// iterative searching seg in one direction
4549 }// try two directions
4550
4551 return true;
4552}
4553
4554bool DotsConnection::matchCgemXCluster(struct trkCandi& aTrkCandi)
4555{
4556 if(aTrkCandi.layerMin>10) { // optimization ???
4557 if(myDebugNb==2)
4558 cout<<"as layerMin = "<<aTrkCandi.layerMin<<" > 10, no CGEM cluster matching tried "<<endl;
4559 return false;
4560 }
4561 int nCluMatchedLastTime=0;
4562 int nIter = 0;
4563 while(1) {
4564 if(myDebugNb==2)
4565 cout<<" ~~ the "<<nIter+1<<" time to match Cgem X-Cluster: "<<endl;
4566 HepPoint3D pos;
4567 double phi_trk;
4568 double minResidX[3]={9999., 9999., 9999.};
4569 int idxClusterMinResid[3]={-1, -1, -1};
4570 int nCluMatched=0;
4571 int nCluExpt(0), nLayerWithCluNearby(0);
4572 aTrkCandi.CgemXClusterID.clear();
4573 for(int i=2; i>=0; i--)// loop layer (3 to 1)
4574 {
4575 if(myDotsHelixFitter.getPosAtCgem(i, pos)) {
4576 nCluExpt++;
4577 phi_trk = pos.phi();// in radian
4578 int nClu = myVecCgemXClusterIdx[i].size();
4579 for(int j=0; j<nClu; j++)
4580 {
4581 myIterClu=myIterCgemClusterBegin+myVecCgemXClusterIdx[i][j];
4582 double phi_CC = (*myIterClu)->getrecphi();
4583 double del_phi = phi_CC-phi_trk;
4584 if(del_phi<-M_PI||del_phi> M_PI) del_phi=atan2(sin(del_phi),cos(del_phi));
4585 double del_X=del_phi*myDotsHelixFitter.getRmidGapCgem(i);
4586 if(fabs(del_X)<10.0) // in cm
4587 {
4588 if(myDebugNb==2)
4589 cout<<"CGEM layer "<<i<<", a X-cluster with dX="<<del_X*10<<" mm found"<<endl;
4590 if(fabs(del_X)<fabs(minResidX[i])) {
4591 minResidX[i]=del_X;
4592 idxClusterMinResid[i]=myVecCgemXClusterIdx[i][j];
4593 }
4594 }// if in the rough window
4595 }// loop cluster on the layer
4596 if(fabs(minResidX[i])<1.0) // cut at 10 mm ???
4597 {
4598 aTrkCandi.CgemXClusterID.push_back(idxClusterMinResid[i]);
4599 nCluMatched++;
4600 }
4601 if(fabs(minResidX[i])<10.) nLayerWithCluNearby++;
4602 }// if there is an intersection between track and CGEM
4603 }// loop layer
4604 if(nCluMatched>0) {
4605 int nDropHits = circleFitTaubin(aTrkCandi, 5, true, 2, true);
4606 if(myDebugNb==2)
4607 cout<<"After matching CGEM and circle fit, nDropHits="<<nDropHits<<endl;
4608 if(nDropHits>nCluMatched) {// --- try circle fit without initial helix
4609 double circlePar[3];
4610 circlePar[0]=aTrkCandi.a_helix[0];
4611 circlePar[1]=aTrkCandi.a_helix[1];
4612 circlePar[2]=aTrkCandi.a_helix[2];
4613 if(myDebugNb==2)
4614 cout<<"nDropHits>nAdd => refit without initial helix: "<<endl;
4615 int nDropHits_2 = circleFitTaubin(aTrkCandi, 5, false, 2, true);
4616 if(myDebugNb==2)
4617 cout<<"Without initial helix, nDropHits="<<nDropHits_2<<endl;
4618 if(nDropHits_2<nDropHits) nDropHits=nDropHits_2;
4619 else {
4620 aTrkCandi.a_helix[0]=circlePar[0];
4621 aTrkCandi.a_helix[1]=circlePar[1];
4622 aTrkCandi.a_helix[2]=circlePar[2];
4623 nDropHits = circleFitTaubin(aTrkCandi, 5, true, 2, true);
4624 }
4625 }
4626 updateCgemFitItem(aTrkCandi);
4627 int nXCluDrop = NXcluToDrop(aTrkCandi);
4628 while(nDropHits>nCluMatched||nXCluDrop>0) {
4629 if(myDebugNb==2)
4630 cout<<" nDropHits="<<nDropHits<<", nCluMatched="<<nCluMatched<<", nXCluDrop="<<nXCluDrop<<"=> drop one CGEM X-cluster"<<endl;
4631 aTrkCandi.CgemXClusterID.pop_back();// drop the inner most cluster if fitted hit has |chi|>5
4632 nDropHits = circleFitTaubin(aTrkCandi, 5, true, 2, true);
4633 updateCgemFitItem(aTrkCandi);
4634 nXCluDrop = NXcluToDrop(aTrkCandi);
4635 nCluMatched--;
4636 if(nCluMatched<=0) break;
4637 }
4638 }
4639 if(nLayerWithCluNearby==nCluMatched) break;// good
4640 //if(nCluMatched==0) break;// nothing found
4641 if(nCluMatched<=nCluMatchedLastTime) break;// noting more found
4642 nIter++;
4643 nCluMatchedLastTime = nCluMatched;
4644 }// while iteration
4645
4646 // --- update myVecCgemXClusterTrkIdx
4647 //vector<int>::iterator iter = aTrkCandi.CgemXClusterID.begin();
4648 //for(; iter!=aTrkCandi.CgemXClusterID.end(); iter++) {
4649 // int cluIdx = *iter;
4650 // if(cluIdx<0) continue;
4651 // myIterClu=myIterCgemClusterBegin+cluIdx;
4652 // int layer= (*myIterClu)->getlayerid();
4653 // int size=myVecCgemXClusterIdx[layer].size();
4654 // for(int i=0; i<size; i++) {
4655 // if(myVecCgemXClusterIdx[layer][i]==cluIdx) {
4656 // myVecCgemXClusterTrkIdx[layer][i]==aTrkCandi.trkIdx;
4657 // break;
4658 // }
4659 // }
4660 //}
4661
4662 return true;
4663}
4664
4665void DotsConnection::matchCgemClusterMdcDigi()
4666{
4667 int i_candi=0;
4668 vector<struct trkCandi>::iterator iter_trkCandi = myVecTrkCandidates.begin();
4669 //for(; iter_trkCandi!=myVecTrkCandidates.end(); i_candi++)
4670 for(; iter_trkCandi!=myVecTrkCandidates.end(); iter_trkCandi++, i_candi++)
4671 {
4672 if(myDebugNb==2)
4673 cout<<endl<<" ----> trk candi "<<i_candi<<": "<<endl;
4674 if((*iter_trkCandi).isGood!=1) continue;
4675 if((*iter_trkCandi).mdcXDigiWireIdx.size()>=3)
4676 {
4677 //resetXDigiFitItem(*iter_trkCandi);
4678 tagRedudantHits(*iter_trkCandi);
4679 int nDropHits = circleFitTaubin(*iter_trkCandi, 5, false, 2, true);
4680 updateDigiFitItem(*iter_trkCandi);
4681 //if(myDotsHelixFitter.getChi2()>10*myDotsHelixFitter.getNActiveHits() && fabs((*iter_trkCandi).a_helix[2]<0.35)) {
4682 // double kappa = (*iter_trkCandi).a_helix[2];
4683 // (*iter_trkCandi).a_helix[2]=kappa/fabs(kappa)*1.0;
4684 // cout<<" fit not good, refit with kappa=1 : ";
4685 // circleFitTaubin(*iter_trkCandi, true);
4686 //}
4687 double circlePar[3];
4688 circlePar[0]=(*iter_trkCandi).a_helix[0];
4689 circlePar[1]=(*iter_trkCandi).a_helix[1];
4690 circlePar[2]=(*iter_trkCandi).a_helix[2];
4691 if(myDotsHelixFitter.getNActiveHits()<4||circlePar[0]!=circlePar[0])
4692 {
4693 if(myDebugNb==2)
4694 cout<<"a bad circleFitTaubin! "<<endl;
4695 (*iter_trkCandi).isGood=0;
4696 resetXDigiFitItem(*iter_trkCandi);
4697 continue;
4698 }
4699 /*
4700 // --- to match outer MDC digi but with a gap layer
4701 //cout<<" xLayerMax = "<<(*iter_trkCandi).xLayerMax<<endl;
4702 //if((*iter_trkCandi).xLayerMax<41&&(*iter_trkCandi).xLayerMax>=11)
4703 cout<<" layerMax = "<<(*iter_trkCandi).layerMax<<endl;
4704 while((*iter_trkCandi).layerMax<41&&(*iter_trkCandi).layerMax>=11)
4705 {
4706 int layerToFind = (*iter_trkCandi).layerMax+2;
4707 //if(xlayerToFind==20||xlayerToFind==21) xlayerToFind=36;
4708 cout<<" could have outer hits "<<endl;
4709 vector<struct trkCandi>::iterator iter_other = myVecTrkCandidates.begin();
4710 int n_neighbSeg=0;
4711 int nmax_match=-1;
4712 vector<struct trkCandi>::iterator iter_matchBest;
4713 for(; iter_other!=myVecTrkCandidates.end(); iter_other++)
4714 {
4715 if(iter_other==iter_trkCandi) continue;
4716 //cout<<"there is one other trk candi with layer min "<<(*iter_other).xLayerMin<<endl;
4717 //cout<<"there is one other trk candi with layer min "<<(*iter_other).layerMin<<endl;
4718 //if((*iter_other).xLayerMin==(*iter_trkCandi).xLayerMax+2)
4719 if((*iter_other).layerMin!=layerToFind) continue;
4720 if((*iter_other).isGood==-1) continue;
4721 if( isInOutNeighbours(*iter_trkCandi,*iter_other)==false ) continue;
4722 cout<<" one-layer-gap neighboured outer segment found: "<<endl;
4723 n_neighbSeg++;
4724 iter_matchBest = iter_other;
4725 vector<int>::iterator iter_digi = (*iter_other).mdcXDigiWireIdx.begin();
4726 int n_matchedXhits=0;
4727 for(; iter_digi!=(*iter_other).mdcXDigiWireIdx.end(); iter_digi++)
4728 {
4729 int wireIdx = *iter_digi;
4730 int layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
4731 if(myWireFlag[layer]!=0) continue;
4732 int wire = myMdcGeomSvc->Wire(wireIdx)->Cell();
4733 myDotsHelixFitter.updateDcDigiInfo(myMapMdcDigi[wireIdx]);
4734 cout<<" (layer "<<layer<<", wire "<<wire<<", view "<<myWireFlag[layer]<<", chi "<<myDotsHelixFitter.getDigiChi()<<") "<<endl;
4735 if(fabs(myDotsHelixFitter.getDigiChi())<50) n_matchedXhits++;
4736 }
4737 if(n_matchedXhits>nmax_match) {
4738 nmax_match=n_matchedXhits;
4739 iter_matchBest = iter_other;
4740 }
4741 }
4742 // --- combine two trk candi
4743 if(n_neighbSeg>0) {
4744 cout<<n_neighbSeg<<" outer neighboured trk segments found, and the best one is to be combined"<<endl;
4745 //resetXDigiFitItem(*iter_matchBest);
4746 combineTrkCandi(*iter_trkCandi, *iter_matchBest);
4747 nDropHits = circleFitTaubin(*iter_trkCandi, 5, true);
4748 updateDigiFitItem(*iter_trkCandi);
4749 circlePar[0]=(*iter_trkCandi).a_helix[0];
4750 if(myDotsHelixFitter.getNActiveHits()<4||circlePar[0]!=circlePar[0])
4751 {
4752 cout<<"a bad circleFitTaubin! "<<endl;
4753 (*iter_trkCandi).isGood=0;
4754 resetXDigiFitItem(*iter_trkCandi);
4755 break;
4756 }
4757 }
4758 else break;
4759 }// while outer-most layer < 41
4760 if((*iter_trkCandi).isGood==0) continue;
4761
4762 // --- to match inner MDC digi but with one or two gap layers
4763 cout<<" layerMin = "<<(*iter_trkCandi).layerMin<<endl;
4764 while((*iter_trkCandi).layerMin>9&&(*iter_trkCandi).layerMin<40)
4765 {
4766 cout<<" could have inner hits "<<endl;
4767 int gapMax=2;
4768 bool innerHitsFound=false;
4769 for(int gap=1; gap<=gapMax; gap++) {
4770 int layerToFind = (*iter_trkCandi).layerMin-1-gap;
4771 vector<struct trkCandi>::iterator iter_other = myVecTrkCandidates.begin();
4772 int n_neighbSeg=0;
4773 int nmax_match=-1;
4774 vector<struct trkCandi>::iterator iter_matchBest;
4775 for(; iter_other!=myVecTrkCandidates.end(); iter_other++)
4776 {
4777 if(iter_other==iter_trkCandi) continue;
4778 //cout<<"there is one other trk candi with layer min "<<(*iter_other).xLayerMin<<endl;
4779 //cout<<"there is one other trk candi with layer min "<<(*iter_other).layerMin<<endl;
4780 //if((*iter_other).xLayerMin==(*iter_trkCandi).xLayerMin+2)
4781 if((*iter_other).layerMax!=layerToFind) continue;
4782 if((*iter_other).isGood==-1) continue;
4783 if( isInOutNeighbours(*iter_other,*iter_trkCandi,gap)==false ) continue;
4784 cout<<" "<<gap<<"-layer-gap neighboured inner segment found: "<<endl;
4785 n_neighbSeg++;
4786 iter_matchBest = iter_other;
4787 vector<int>::iterator iter_digi = (*iter_other).mdcXDigiWireIdx.begin();
4788 int n_matchedXhits=0;
4789 for(; iter_digi!=(*iter_other).mdcXDigiWireIdx.end(); iter_digi++)
4790 {
4791 int wireIdx = *iter_digi;
4792 int layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
4793 if(myWireFlag[layer]!=0) continue;
4794 int wire = myMdcGeomSvc->Wire(wireIdx)->Cell();
4795 myDotsHelixFitter.updateDcDigiInfo(myMapMdcDigi[wireIdx]);
4796 cout<<" (layer "<<layer<<", wire "<<wire<<", view "<<myWireFlag[layer]<<", chi "<<myDotsHelixFitter.getDigiChi()<<") "<<endl;
4797 if(fabs(myDotsHelixFitter.getDigiChi())<50) n_matchedXhits++;
4798 }
4799 if(n_matchedXhits>nmax_match) {
4800 nmax_match=n_matchedXhits;
4801 iter_matchBest = iter_other;
4802 }
4803 }
4804 // --- combine two trk candi
4805 if(n_neighbSeg>0) {
4806 cout<<n_neighbSeg<<" inner neighboured trk segments found, and the best one is to be combined"<<endl;
4807 //resetXDigiFitItem(*iter_matchBest);
4808 combineTrkCandi(*iter_trkCandi, *iter_matchBest);
4809 nDropHits = circleFitTaubin(*iter_trkCandi, 5, true);
4810 updateDigiFitItem(*iter_trkCandi);
4811 circlePar[0]=(*iter_trkCandi).a_helix[0];
4812 if(myDotsHelixFitter.getNActiveHits()<4||circlePar[0]!=circlePar[0])
4813 {
4814 cout<<"a bad circleFitTaubin! "<<endl;
4815 (*iter_trkCandi).isGood=0;
4816 continue;
4817 }
4818 else {
4819 innerHitsFound=true;
4820 break;// skip two-gap-layer neighbours
4821 }
4822 }
4823 }// for gap=1,2
4824 if(!innerHitsFound) break;
4825 }// while inner-most layer > 9
4826 */
4827
4828 //cout<<"trkCandi is good "<<(*iter_trkCandi).isGood<<endl;
4829 matchMdcDigi(*iter_trkCandi, i_candi);
4830 //cout<<"trkCandi is good "<<(*iter_trkCandi).isGood<<endl;
4831 if((*iter_trkCandi).isGood==0) continue;
4832
4833 // --- if continuous hits dropped, drop all the outer hits if not many
4834
4835 // --- to match inner CGEM X-cluster
4836 matchCgemXCluster(*iter_trkCandi);
4837 //HepPoint3D pos;
4838 //double phi_trk;
4839 //double minResidX[3]={9999., 9999., 9999.};
4840 //int idxClusterMinResid[3]={-1, -1, -1};
4841 //int nCluMatched=0;
4842 //for(int i=2; i>=0; i--)// loop layer (3 to 1)
4843 //{
4844 // if(myDotsHelixFitter.getPosAtCgem(i, pos)) {
4845 // phi_trk = pos.phi();// in radian
4846 // int nClu = myVecCgemXClusterIdx[i].size();
4847 // for(int j=0; j<nClu; j++)
4848 // {
4849 // myIterClu=myIterCgemClusterBegin+myVecCgemXClusterIdx[i][j];
4850 // double phi_CC = (*myIterClu)->getrecphi();
4851 // double del_phi = phi_CC-phi_trk;
4852 // if(del_phi<-M_PI||del_phi> M_PI) del_phi=atan2(sin(del_phi),cos(del_phi));
4853 // double del_X=del_phi*myDotsHelixFitter.getRmidGapCgem(i);
4854 // if(fabs(del_X)<10.0) // in cm
4855 // {
4856 // cout<<"CGEM layer "<<i<<", a X-cluster with dX="<<del_X*10<<" mm found"<<endl;
4857 // if(fabs(del_X)<fabs(minResidX[i])) {
4858 // minResidX[i]=del_X;
4859 // idxClusterMinResid[i]=myVecCgemXClusterIdx[i][j];
4860 // }
4861 // }// if in the rough window
4862 // }// loop cluster on the layer
4863 // if(fabs(minResidX[i])<0.4) // cut at 4 mm
4864 // {
4865 // iter_trkCandi->CgemXClusterID.push_back(idxClusterMinResid[i]);
4866 // //nDropHits = circleFitTaubin(*iter_trkCandi, 5, true);
4867 // nCluMatched++;
4868 // }
4869 // }// if there is an intersection between track and CGEM
4870 //}// loop layer
4871 //if(nCluMatched>0) {
4872 // int nAdd=nCluMatched;
4873 // nDropHits = circleFitTaubin(*iter_trkCandi, 5, true);
4874 // cout<<"After matching CGEM and circle fit, nDropHits="<<nDropHits<<endl;
4875 // if(nDropHits>nAdd) {
4876 // circlePar[0]=(*iter_trkCandi).a_helix[0];
4877 // circlePar[1]=(*iter_trkCandi).a_helix[1];
4878 // circlePar[2]=(*iter_trkCandi).a_helix[2];
4879 // cout<<"nDropHits>nAdd => refit without initial helix: "<<endl;
4880 // int nDropHits_2 = circleFitTaubin(*iter_trkCandi, 5, false);
4881 // cout<<"Without initial helix, nDropHits="<<nDropHits_2<<endl;
4882 // if(nDropHits_2<nDropHits) nDropHits=nDropHits_2;
4883 // else {
4884 // (*iter_trkCandi).a_helix[0]=circlePar[0];
4885 // (*iter_trkCandi).a_helix[1]=circlePar[1];
4886 // (*iter_trkCandi).a_helix[2]=circlePar[2];
4887 // nDropHits = circleFitTaubin(*iter_trkCandi, 5, true);
4888 // }
4889 // }
4890 // updateCgemFitItem(*iter_trkCandi);
4891 // int nXCluDrop = NXcluToDrop(*iter_trkCandi);
4892 // //int nBadCgemHit=0;
4893 // while(nDropHits>nAdd||nXCluDrop>0) {
4894 // iter_trkCandi->CgemXClusterID.pop_back();// drop the inner most cluster if fitted hit has |chi|>5
4895 // cout<<" drop one CGEM X-cluster"<<endl;
4896 // nDropHits = circleFitTaubin(*iter_trkCandi, 5, true);
4897 // nAdd--;
4898 // //nBadCgemHit++;
4899 // //if(nBadCgemHit>=nCluMatched) break;
4900 // if(nAdd<=0) break;
4901 // }
4902 // // --- update fitted items? to be implemented
4903 // updateDigiFitItem(*iter_trkCandi);
4904 // updateCgemFitItem(*iter_trkCandi);
4905 //}
4906
4907 //(*iter_trkCandi).a_helix[0]=circlePar[0];
4908 //(*iter_trkCandi).a_helix[1]=circlePar[1];
4909 //(*iter_trkCandi).a_helix[2]=circlePar[2];
4910 //circleFitTaubin(*iter_trkCandi, 9999., true, -1, 19);// fit MDC inner x-hits
4911
4912 //(*iter_trkCandi).a_helix[0]=circlePar[0];
4913 //(*iter_trkCandi).a_helix[1]=circlePar[1];
4914 //(*iter_trkCandi).a_helix[2]=circlePar[2];
4915 //circleFitTaubin(*iter_trkCandi, 9999., true, 20, 50);// fit MDC outer x-hits
4916
4917 //circleFit(*iter_trkCandi);// LS fit
4918
4919 // --- to get all intersected V-cluster, calculate s vs z, fill Hough map
4920 int nsz_cgem=0;
4921 if(myDebugNb==2)
4922 cout<<"CGEM V-cluster candidates (s,z): "<<endl;
4923 KalmanFit::Helix circle_fittedHelix = myDotsHelixFitter.getClassHelix();
4924 vector<int>::iterator iter_XClu = iter_trkCandi->CgemXClusterID.begin();
4925 double z_XV=9999.;
4926 myRoughTanlDzMap.Reset();
4927 map<int,pair<double,double> > map_Vclu_sz;
4928 for(; iter_XClu!=iter_trkCandi->CgemXClusterID.end(); iter_XClu++)
4929 {
4930 int idx_Xclu = *iter_XClu;
4931 if(idx_Xclu<0) continue;// only use fitted X-cluster
4932 myIterClu=myIterCgemClusterBegin+idx_Xclu;
4933 int layer = (*myIterClu)->getlayerid();
4934 if(myDebugNb==2)
4935 cout<<"layer "<<layer;
4936 double rCGEM = myDotsHelixFitter.getRmidGapCgem(layer);
4937 double dphi = myDotsHelixFitter.IntersectCylinder(rCGEM);
4938 if(fabs(dphi)<1e-10) {
4939 if(myDebugNb==2)
4940 cout<<"DotsConnection::"<<__FUNCTION__<<": error, no intersection between track and CGEM layer "<<layer<<endl;
4941 continue;
4942 }
4943 double s = fabs(dphi*circle_fittedHelix.radius());
4944 //int sheet = (*myIterClu)->getsheetid();
4945 int nV = myVecCgemVClusterIdx[layer].size();
4946 for(int iV=0; iV<nV; iV++) {
4947 int idx_Vclu = myVecCgemVClusterIdx[layer][iV];
4948 if(getCgemClusterIntersection(idx_Xclu,idx_Vclu,z_XV)) {
4949 pair<double, double> sz(s,z_XV);
4950 fillTanlDzMap(s,z_XV);
4951 nsz_cgem++;
4952 map_Vclu_sz[idx_Vclu]=sz;
4953 if(myDebugNb==2)
4954 cout<<" ("<<s<<", "<<z_XV<<")";
4955 }
4956 }
4957 if(myDebugNb==2)
4958 cout<<"; ";
4959 }// loop X-clusters
4960 if(myDebugNb==2)
4961 cout<<endl;
4962
4963 // --- to calculate s vs z for MDC stereo hits, fill Hough map
4964 int nsz_mdc=0;
4965 //mdcVDigiWireIdx.insert(mdcVDigiWireIdx.end(), iter_trkCandi->mdcV2DigiWireIdx.begin(), iter_trkCandi->mdcV2DigiWireIdx.end());
4966 vector<vector<pair<double, double> > > vec_vecsz;
4967 vector<int>& mdcVDigiWireIdx = iter_trkCandi->mdcVDigiWireIdx;
4968 int nVdigi = mdcVDigiWireIdx.size();
4969 vector<int>::iterator iter_digi = mdcVDigiWireIdx.begin();
4970 if(myDebugNb==2)
4971 cout<<"MDC V-hits candidates (s,z): "<<endl;
4972 int i_digi=0;
4973 for( ; i_digi<nVdigi; i_digi++,iter_digi++)
4974 {
4975 int wireIdx = *iter_digi;
4976 const MdcDigi* aMdcDigi = myMapMdcDigi[wireIdx];
4977 vector<pair<double, double> > vec_sz = myDotsHelixFitter.getSZ(aMdcDigi);
4978 vec_vecsz.push_back(vec_sz);
4979 vector<pair<double, double> >::iterator iter_sz = vec_sz.begin();
4980 for(; iter_sz!=vec_sz.end(); iter_sz++) {
4981 fillTanlDzMap(iter_sz->first,iter_sz->second);
4982 }
4983 if(vec_sz.size()>0) nsz_mdc++;
4984 if(myDebugNb==2)
4985 if((i_digi+1)%3==0) if(myDebugNb==2) cout<<endl;
4986 }
4987 if((i_digi+1)%3!=1) if(myDebugNb==2) cout<<endl;
4988
4989 // --- requirement for nsz
4990 if((nsz_cgem+nsz_mdc)<3) {
4991 if(myDebugNb==2)
4992 cout<<" no sufficient sz pair! stop tanl, dz, V-hits association. "<<endl;
4993 (*iter_trkCandi).isGood=0;
4994 continue;
4995 }
4996
4997
4998 // --- get tanl, dz from Hough map
4999 double x_peak(0.), y_peak(0.);
5000 double x_weight(0.), y_weight(0.);
5001 getWeightedPeak(myRoughTanlDzMap, x_peak, y_peak, x_weight, y_weight);
5002 //cout<<"from tanL-dz Hough map: dz_peak="<<y_peak<<", tanL_peak = "<<x_peak<<endl;
5003 if(myDebugNb==2)
5004 cout<<"from tanL-dz Hough map: dz="<<y_weight<<", tanL = "<<x_weight<<endl;
5005
5006 // --- to refill tanl, dz Hough map & linear fit
5007 myRoughTanlDzMap.Reset();
5008 double s_sum(0), z_sum(0);
5009 double s2_sum(0), sz_sum(0);
5010 int n_sz(0);
5011
5012 // --- a rough selection of V-cluster
5013 int cgemVCluIdx[3]={-1,-1,-1};
5014 double cgemVClu_dz_min[3]={9999.,9999.,9999.};
5015 double cgemVClu_s_dzmin[3]={9999.,9999.,9999.};
5016 double cgemVClu_z_dzmin[3]={9999.,9999.,9999.};
5017 if(myDebugNb==2)
5018 cout<<"CGEM V-cluster candidates: "<<endl;
5019 for(map<int,pair<double,double> >::iterator i_map=map_Vclu_sz.begin(); i_map!=map_Vclu_sz.end(); i_map++)
5020 {
5021 double s = (*i_map).second.first;
5022 double z = (*i_map).second.second;
5023 double z_hough = x_weight*s+y_weight;
5024 double delta_z = z-z_hough;
5025 if(myDebugNb==2)
5026 cout<<" delta_z = "<<delta_z<<" ";
5027 double deltaZcut=10.;// in cm, need optimization
5028 if(fabs(delta_z)<deltaZcut) {
5029 int idx_Vclu = (*i_map).first;
5030 myIterClu=myIterCgemClusterBegin+idx_Vclu;
5031 int layer = (*myIterClu)->getlayerid();
5032 if(fabs(delta_z)<fabs(cgemVClu_dz_min[layer])) {
5033 cgemVClu_dz_min[layer]=delta_z;
5034 cgemVClu_s_dzmin[layer]=s;
5035 cgemVClu_z_dzmin[layer]=z;
5036 cgemVCluIdx[layer]=idx_Vclu;
5037 }
5038 }
5039 }
5040 if(myDebugNb==2)
5041 cout<<endl;
5042 for(int layer=2; layer>=0; layer--) {
5043 if(cgemVCluIdx[layer]!=-1) {
5044 //iter_trkCandi->CgemVClusterID.push_back(cgemVCluIdx[layer]);
5045 fillTanlDzMap(cgemVClu_s_dzmin[layer],cgemVClu_z_dzmin[layer]);
5046 s_sum+=cgemVClu_s_dzmin[layer];
5047 s2_sum+=cgemVClu_s_dzmin[layer]*cgemVClu_s_dzmin[layer];
5048 z_sum+=cgemVClu_z_dzmin[layer];
5049 sz_sum+=cgemVClu_s_dzmin[layer]*cgemVClu_z_dzmin[layer];
5050 n_sz++;
5051 }
5052 }
5053
5054 // --- a rough selection of stereo wires
5055 if(myDebugNb==2)
5056 cout<<"MDC V-hits candidates: "<<endl;
5057 resetVDigiFitItem(*iter_trkCandi);
5058 vector<vector<pair<double, double> > >::iterator iter_vvsz = vec_vecsz.begin();
5059 i_digi=0;
5060 for(; iter_vvsz!=vec_vecsz.end(); iter_vvsz++, i_digi++)
5061 {
5062 vector<pair<double, double> >& vec_sz = *iter_vvsz;
5063 vector<pair<double, double> >::iterator iter_sz = vec_sz.begin();
5064 double delta_z_min = 9999.0;
5065 double z_dzmin(0), s_dzmin(0);
5066 for(; iter_sz!=vec_sz.end(); iter_sz++) {
5067 double s = iter_sz->first;
5068 double z = iter_sz->second;
5069 double z_hough = x_weight*s+y_weight;
5070 double delta_z = z-z_hough;
5071 if(fabs(delta_z)<fabs(delta_z_min)) {
5072 delta_z_min=delta_z;
5073 s_dzmin = s;
5074 z_dzmin = z;
5075 }
5076 }
5077 if(myDebugNb==2)
5078 cout<<"delta_z_min="<<delta_z_min;
5079 double deltaZcut_mdc = 10.0; // ??? in cm, need optimization
5080 if(fabs(delta_z_min)>deltaZcut_mdc) {
5081 if(myDebugNb==2)
5082 cout<<"(dropped)";
5083 iter_trkCandi->mdcVDigiFitted[i_digi]=-1;
5084 }
5085 else {
5086 iter_trkCandi->mdcVDigiFitted[i_digi]=1;
5087 fillTanlDzMap(s_dzmin, z_dzmin);
5088 if(myDebugNb==2)
5089 cout<<"("<<s_dzmin<<","<<z_dzmin<<")";
5090 s_sum+=s_dzmin;
5091 z_sum+=z_dzmin;
5092 s2_sum+=s_dzmin*s_dzmin;
5093 sz_sum+=s_dzmin*z_dzmin;
5094 n_sz++;
5095 }
5096 if(myDebugNb==2) {
5097 cout<<" ";
5098 if((i_digi+1)%3==0) cout<<endl;}
5099 }
5100 if(myDebugNb==2)
5101 if((i_digi+1)%3!=1) cout<<endl;
5102
5103 // --- updated track tanl, dz from the new Hough map
5104 getWeightedPeak(myRoughTanlDzMap, x_peak, y_peak, x_weight, y_weight);
5105 if(myDebugNb==2){
5106 cout<<"After rough selection of sz of V-hits: "<<endl;
5107 //cout<<"from tanL-dz Hough map: dz_peak="<<y_peak<<", tanL_peak = "<<x_peak<<endl;
5108 cout<<"from tanL-dz Hough map: dz="<<y_weight<<", tanL = "<<x_weight<<endl;}
5109
5110 // --- linear fit of s z
5111 double tanl_lfit = (n_sz*sz_sum-s_sum*z_sum)/(n_sz*s2_sum-s_sum*s_sum);
5112 double dz_lfit = (s2_sum*z_sum-s_sum*sz_sum)/(n_sz*s2_sum-s_sum*s_sum);
5113 if(myDebugNb==2)
5114 cout<<"from s-z line fit: dz="<<dz_lfit<<", tanL = "<<tanl_lfit<<endl;
5115 // --- update tanL and dz of the track candidate
5116 iter_trkCandi->a_helix[3]=dz_lfit;
5117 iter_trkCandi->a_helix[4]=tanl_lfit;
5118
5119 int nVhits=0;
5120 // --- reselection of V-clusters
5121 for(int i=0; i<3; i++) {
5122 cgemVCluIdx[i]=-1;
5123 cgemVClu_dz_min[i]=9999.;
5124 cgemVClu_s_dzmin[i]=9999.;
5125 cgemVClu_z_dzmin[i]=9999.;
5126 }
5127 if(myDebugNb==2)
5128 cout<<"CGEM V-cluster candidates: "<<endl;
5129 for(map<int,pair<double,double> >::iterator i_map=map_Vclu_sz.begin(); i_map!=map_Vclu_sz.end(); i_map++)
5130 {
5131 double s = (*i_map).second.first;
5132 double z = (*i_map).second.second;
5133 double z_hough = tanl_lfit*s+dz_lfit;
5134 double delta_z = z-z_hough;
5135 if(myDebugNb==2)
5136 cout<<" delta_z = "<<delta_z<<" ";
5137 double deltaZcut=10.;// in cm, need optimization
5138 if(fabs(delta_z)<deltaZcut) {
5139 int idx_Vclu = (*i_map).first;
5140 myIterClu=myIterCgemClusterBegin+idx_Vclu;
5141 int layer = (*myIterClu)->getlayerid();
5142 if(fabs(delta_z)<fabs(cgemVClu_dz_min[layer])) {
5143 cgemVClu_dz_min[layer]=delta_z;
5144 cgemVClu_s_dzmin[layer]=s;
5145 cgemVClu_z_dzmin[layer]=z;
5146 cgemVCluIdx[layer]=idx_Vclu;
5147 }
5148 }
5149 }
5150 if(myDebugNb==2)
5151 cout<<endl;
5152 for(int layer=2; layer>=0; layer--) {
5153 if(cgemVCluIdx[layer]!=-1) {
5154 iter_trkCandi->CgemVClusterID.push_back(cgemVCluIdx[layer]);
5155 nVhits++;
5156 }
5157 }
5158
5159 // --- reselection of stereo wires
5160 if(myDebugNb==2)
5161 cout<<"MDC V-hits candidates: "<<endl;
5162 resetVDigiFitItem(*iter_trkCandi);
5163 //vector<vector<pair<double, double> > >::iterator
5164 iter_vvsz = vec_vecsz.begin();
5165 i_digi=0;
5166 for(; iter_vvsz!=vec_vecsz.end(); iter_vvsz++, i_digi++)
5167 {
5168 vector<pair<double, double> >& vec_sz = *iter_vvsz;
5169 vector<pair<double, double> >::iterator iter_sz = vec_sz.begin();
5170 double delta_z_min = 9999.0;
5171 double z_dzmin(0), s_dzmin(0);
5172 for(; iter_sz!=vec_sz.end(); iter_sz++) {
5173 double s = iter_sz->first;
5174 double z = iter_sz->second;
5175 double z_hough = tanl_lfit*s+dz_lfit;
5176 double delta_z = z-z_hough;
5177 if(fabs(delta_z)<fabs(delta_z_min)) {
5178 delta_z_min=delta_z;
5179 s_dzmin = s;
5180 z_dzmin = z;
5181 }
5182 }
5183 if(myDebugNb==2)
5184 cout<<"delta_z_min="<<delta_z_min;
5185 double deltaZcut_mdc = 10.0; // in cm, ??? need optimization
5186 if(fabs(delta_z_min)>deltaZcut_mdc) {
5187 if(myDebugNb==2)
5188 cout<<"(dropped)";
5189 iter_trkCandi->mdcVDigiFitted[i_digi]=-1;
5190 }
5191 else {
5192 iter_trkCandi->mdcVDigiFitted[i_digi]=1;
5193 if(myDebugNb==2)
5194 cout<<"("<<s_dzmin<<","<<z_dzmin<<")";
5195 nVhits++;
5196 }
5197 if(myDebugNb==2){
5198 cout<<" ";
5199 if((i_digi+1)%3==0) cout<<endl;}
5200 }
5201 if(myDebugNb==2)
5202 if((i_digi+1)%3!=1) cout<<endl;
5203
5204 // --- fit all hits to helix
5205 if(nVhits>2) {
5206 int fitFlag = helixFit(*iter_trkCandi, 5);
5207 // --- update the track candidate
5208 if(fitFlag==0) {
5209 updateDigiFitItem(*iter_trkCandi);
5210 updateCgemFitItem(*iter_trkCandi, 1);
5211 }
5212 }
5213
5214 }// if MDC nXhits > 3
5215 //iter_trkCandi = myVecTrkCandidates.begin();
5216 //iter_trkCandi +=i_candi;
5217 //iter_trkCandi++;
5218 }// loop track candidates
5219}
5220
5221/**
5222 * @brief remove 'bad track' from myVecTrkCandidates,
5223 *
5224 */
5225void DotsConnection::processTrkCandi()
5226{
5227 //cout<<"Trk candidates before process: "<<endl;
5228 //vector<struct trkCandi>::iterator it = myVecTrkCandidates.begin();
5229 //for(; it!=myVecTrkCandidates.end(); it++) printTrkCandi(*it);
5230 bool multiPath, isGoodTrk;
5231 int i_candi=0; //i_candi=myVecTrkCandidates.size()-1;
5232 vector<struct trkCandi>::iterator iter_trkCandi = myVecTrkCandidates.begin();
5233 //vector<struct trkCandi>::iterator iter_trkCandi = myVecTrkCandidates.back();
5234 for(; iter_trkCandi!=myVecTrkCandidates.end(); i_candi++, iter_trkCandi=myVecTrkCandidates.begin()+i_candi)
5235 {
5236 if(myDebugNb==2)
5237 cout<<endl<<" ----> process trk candi "<<i_candi<<": "<<endl;
5238 struct trkCandi& aTrkCandi=myVecTrkCandidates[i_candi]; // rename
5239 //if((*iter_trkCandi).isGood!=1) goto NextCandi;
5240 //if((*iter_trkCandi).mdcXDigiWireIdx.size()<3) goto NextCandi;
5241 if(aTrkCandi.isGood!=1) continue;
5242 if(aTrkCandi.mdcXDigiWireIdx.size()<3) continue;
5243 //printTrkCandi(aTrkCandi);
5244 multiPath = split(aTrkCandi, i_candi);
5245 //cout<<"Trk candidates before rename: "<<endl;
5246 //it = myVecTrkCandidates.begin();
5247 //for(; it!=myVecTrkCandidates.end(); it++) printTrkCandi(*it);
5248 //matchMdcDigi(aTrkCandi, i_candi);
5249 //matchCgemXCluster(aTrkCandi);
5250 //selectVHits(aTrkCandi);
5251 while(1) {
5252 struct trkCandi& aTrkCandi_new=myVecTrkCandidates[i_candi]; // rename again in case
5253 if(aTrkCandi_new.isGood!=1) break;
5254 //printTrkCandi(aTrkCandi);
5255 isGoodTrk = completeTrkCandi(aTrkCandi_new, i_candi);
5256 if(multiPath) {
5257 if(!isGoodTrk) {
5258 // --- try next path
5259 int nPath=myVecNhitPathId.size();
5260 if(nPath>0) {// if there are other paths
5261 int nMax_goodHits=0;
5262 int i_bestPath=-1;
5263 int j_bestPath=-1;
5264 for(int i=0; i<nPath; i++) {
5265 int nFittedXhits = myVecNhitPathId[i].first;
5266 if(nMax_goodHits<nFittedXhits) {
5267 nMax_goodHits=nFittedXhits;
5268 i_bestPath=myVecNhitPathId[i].second;
5269 j_bestPath=i;
5270 }
5271 }
5272 myVecTrkPaths[i_bestPath].trkIdx = i_candi;
5273 myVecTrkCandidates[i_candi] = myVecTrkPaths[i_bestPath];
5274 //myVecTrkCandidates.erase(myVecTrkCandidates.begin()+i_candi);
5275 //myVecTrkCandidates.insert(myVecTrkCandidates.begin()+i_candi, myVecTrkPaths[i_bestPath]);
5276 //cout<<"processTrkCandi: comparasion: myVecTrkCandidates[i_candi]==myVecTrkPaths[i_bestPath]? "<<(myVecTrkCandidates[i_candi]==myVecTrkPaths[i_bestPath])<<endl;
5277 myVecNhitPathId.erase(myVecNhitPathId.begin()+j_bestPath);
5278 //i_candi--;
5279 if(myDebugNb==2) cout<<" ~~~~~ try another path "<<endl;
5280 continue;
5281 }
5282 else {// if no other path
5283 //myVecTrkCandidates.back().isGood=0;
5284 myVecTrkCandidates[i_candi+1].isGood=0;
5285 if(myDebugNb==2) cout<<" ~~~~~ no more path "<<endl;
5286 break;
5287 }
5288 }
5289 else {
5290 // --- remove the path
5291 //rmPathInTrkCandi(myVecTrkCandidates.back(), myVecTrkCandidates[i_candi]);
5292 rmPathInTrkCandi(myVecTrkCandidates[i_candi+1], myVecTrkCandidates[i_candi]);
5293 break;
5294 }
5295 //rmPathInTrkCandi(myVecTrkCandidates.back(), myVecTrkCandidates[i_candi]);
5296 }// if multiPath
5297 else break;
5298 }// while
5299
5300 //NextCandi:
5301 // update iter_trkCandi
5302 //iter_trkCandi = myVecTrkCandidates.begin();
5303 //iter_trkCandi +=i_candi;
5304 //iter_trkCandi++;
5305 //i_candi++;
5306 }
5307
5308}
5309
5310void DotsConnection::processMdcHitCluter()
5311{
5312 bool debug=false; debug=true;
5313 int nMdcClu = myVecTrkCandidates.size();
5314 for(int iMdcClu=0; iMdcClu<nMdcClu; iMdcClu++)
5315 {
5316 if(debug) cout<<"processMdcHitCluter "<<iMdcClu<<endl;
5317 struct trkCandi& aTrkCandi = myVecTrkCandidates.at(iMdcClu);
5318 // --- filter out hits in big clusters
5319 // --- check if only one path
5320 // --- if one path
5321 // --- if one good path -> tag a good track in myVecTrkCandidates
5322
5323 // --- if multi paths or one bad path, tag a bad track, area level clustering
5324
5325 // --- fill vecHit in 8 areas
5326 vector<int> vecHit[8];// vector of wireIdx of good hits in areas
5327 for(int layer=8; layer<43; layer++) // for each layer, inner->outer
5328 {
5329 int iArea = myAreaLayer[layer];
5330 int nHits = aTrkCandi.mdcHitIdx[layer].size();
5331 for(int iHit=0; iHit<nHits; iHit++) // for each hit on this layer
5332 {
5333 int idx = aTrkCandi.mdcHitIdx[layer][iHit];// index in trkCandi.mdcX/VDigiWireIdx
5334 int wireIdx;
5335 if(myWireFlag[layer]==0) wireIdx = aTrkCandi.mdcXDigiWireIdx[idx];
5336 else wireIdx = aTrkCandi.mdcVDigiWireIdx[idx];
5337 vecHit[iArea].push_back(wireIdx);
5338 }
5339 }
5340
5341 // --- area level clustering, path finding with CA
5342 vector<struct trkCandi> vTrkSeg[8];//
5343 for(int iArea=2; iArea<=7; iArea++) // loop areas
5344 {
5345 if(vecHit[iArea].size()==0) continue;
5346 vector<vector<int> > vecHitClu;
5347 mdcHitClustering(vecHit[iArea], vecHitClu);
5348 int nHitClu = vecHitClu.size();
5349 if(debug) cout<<endl<<"Area "<<iArea<<" has "<<vecHit[iArea].size()<<" hits, "<<nHitClu<<" hit-cluster(s)"<<endl;
5350 for(int iHitClu=0; iHitClu<nHitClu; iHitClu++) // loop area level hit clusters
5351 {
5352 if(debug) cout<<setw(4)<<""<<"hit-cluster "<<iHitClu<<":"<<endl;
5353 vector<int>& aHitClu = vecHitClu.at(iHitClu);
5354 int nHit=aHitClu.size();
5355 set<int> aSetHits(aHitClu.begin(),aHitClu.end());
5356 // --- find a path with CA until no more path
5357 while(true)
5358 {
5359 //int nTrkFill=0;
5360
5361 vector<int> aPath(aSetHits.begin(), aSetHits.end()); //=aHitClu;
5362 if(aPath.size()>3 && (iArea==2||iArea==7) ) {
5363 struct trkCandi oneTrkCandi=getTrkCandi(aPath);
5364 int nDropHits = circleFitTaubin(oneTrkCandi, 5, false, 2, true);
5365 int nFittedXhits=myDotsHelixFitter.getNActiveHits();
5366 if(nFittedXhits>3&&nDropHits<=3) {
5367 //nTrkFill++;
5368 vTrkSeg[iArea].push_back(oneTrkCandi);
5369 setMinusVec(aSetHits,aPath);
5370 break;
5371 }
5372 }
5373
5374 int nTrkFill=0;
5375 vector<vector<int> > VPathCA;
5376 longestPathFromCA(aSetHits, VPathCA);
5377 if(VPathCA.size()>0) {
5378 for(int iPath=0; iPath<VPathCA.size(); iPath++) {
5379 aPath=VPathCA.at(iPath);
5380 struct trkCandi oneTrkCandi=getTrkCandi(aPath);
5381 if(iArea==2||iArea==7) {
5382 int nDropHits = circleFitTaubin(oneTrkCandi, 5, false, 2, true);
5383 int nFittedXhits=myDotsHelixFitter.getNActiveHits();
5384 if(nFittedXhits>=3&&nDropHits<=3) {
5385 nTrkFill++;
5386 vTrkSeg[iArea].push_back(oneTrkCandi);
5387 setMinusVec(aSetHits,aPath);
5388 }
5389 }
5390 }
5391 }
5392 if(nTrkFill==0)
5393 {
5394 if(debug) cout<<"No good circle fit from CA path, fill all hits as one (bad) trk candidate"<<endl;
5395 vector<int> aPath(aSetHits.begin(), aSetHits.end());
5396 vTrkSeg[iArea].push_back(getTrkCandi(aPath));// take the remaining hits a trkCandi
5397 break;
5398 }
5399 //vector<const MdcDigi*> vDigi = getXDigiVec(vTrkSeg[iArea].back(), 0);
5400 //getBestTangentCircle(vDigi);
5401 if(aSetHits.size()==0) break;
5402 }// while <--- find a path with CA until no more path
5403 }// loop area level hit clusters
5404 } // loop areas
5405 // --- make track segments (path fit or CA) in each area
5406 // --- track segments extension in each area
5407 // --- connect track segments between areas
5408 // --- form good track candidates into myVecTrkCandidates
5409 }// loop event level hit cluster
5410
5411}// processMdcHitCluter()
5412
5413bool DotsConnection::completeTrkCandi(struct trkCandi& aTrkCandi, int idxCandi)
5414{
5415 //bool flag=false;
5416 if(myDebugNb==2) cout<<" ~~~~~ completeTrkCandi "<<idxCandi<<endl;
5417
5418 // --- circle fit
5419 //cout<<"DotsConnection::completeTrkCandi: before circleFitTaubin"<<endl;
5420 //vector<struct trkCandi>::iterator it = myVecTrkCandidates.begin();
5421 //for(; it!=myVecTrkCandidates.end(); it++) printTrkCandi(*it);
5422 int iTryCircleFit=0;
5423 int nDropMin=9999; int iCircleFitBest=-1;
5424 bool needUseWireCrossPoint=myUseWireCrossPoint;
5425 for(; iTryCircleFit<2; iTryCircleFit++) {// do circle fit twice at first.
5426 int nDropHits = circleFitTaubin(aTrkCandi, 5, false, 2, true,-1,50,needUseWireCrossPoint);
5427 needUseWireCrossPoint=false;
5428 if(nDropMin>nDropHits) {
5429 nDropMin=nDropHits;
5430 iCircleFitBest=iTryCircleFit;
5431 }
5432 if(nDropHits<myDotsHelixFitter.getNActiveHits()) {
5433 int nActOuterXHits=myDotsHelixFitter.getNActiveOuterXHits();
5434 int nDropInnerXHits=myDotsHelixFitter.getNInnerXHits()-(myDotsHelixFitter.getNActiveHits()-nActOuterXHits);
5435 if(myDebugNb==2)
5436 cout<<"nDropHits="<<nDropHits<<" < NActiveHits=myDotsHelixFitter.getNActiveHits(), nDropInnerXHits="<<nDropInnerXHits<<", nActOuterXHits="<<nActOuterXHits<<endl;
5437 if(iTryCircleFit==0&&nActOuterXHits>0&&nDropInnerXHits>nActOuterXHits) {// if N_drop_innerXhits >= N_keep_outerXhits, try circle fit without outer X-hits
5438 if(myDebugNb==2)
5439 cout<<"N_drop_innerXhits="<<nDropInnerXHits<<" >= N_keep_outerXhits="<<nActOuterXHits<<", try circle fit without outer X-hits!"<<endl;
5440 setFitFlagUncertain(aTrkCandi, 20, 60);
5441 continue;
5442 }
5443 break;
5444 }
5445 else if(iTryCircleFit==0) {// if drop too many hits, try one more circle fit without hits in big cluster
5446 //int nXhits=nXHitsActive(aTrkCandi);
5447 int nXInBig=setXHitsInBigSetFitFlagUncertain(aTrkCandi, false);
5448 if(nXInBig>0&&nXInBig<nDropMin) {
5449 if(myDebugNb==2)
5450 cout<<"nDropHits>=NActiveHits, try circle fit without hits in big cluster"<<endl;
5451 nXInBig=setXHitsInBigSetFitFlagUncertain(aTrkCandi, true);
5452 continue;
5453 }
5454 else break;
5455 }
5456 }
5457
5458 //cout<<"DotsConnection::completeTrkCandi: before updateDigiFitItem"<<endl;
5459 //vector<struct trkCandi>::iterator
5460 //it = myVecTrkCandidates.begin();
5461 //for(; it!=myVecTrkCandidates.end(); it++) printTrkCandi(*it);
5462 updateDigiFitItem(aTrkCandi);
5463 double circlePar[3];
5464 circlePar[0]=aTrkCandi.a_helix[0];
5465 circlePar[1]=aTrkCandi.a_helix[1];
5466 circlePar[2]=aTrkCandi.a_helix[2];
5467 if(myDotsHelixFitter.getNActiveHits()<4||circlePar[0]!=circlePar[0])
5468 {
5469 if(myDebugNb==2)
5470 cout<<"a bad circleFitTaubin! "<<endl;
5471 aTrkCandi.isGood=0;
5472 resetXDigiFitItem(aTrkCandi);
5473 return false;
5474 }
5475
5476 // --- match other MDC hits and refit to circle
5477 matchMdcDigi(aTrkCandi, idxCandi);
5478 if(aTrkCandi.isGood==0) return false;
5479
5480 // --- match CGEM X-clusters & refit to circle
5481 matchCgemXCluster(aTrkCandi);
5482
5483 // --- select V-hits and fit to helix
5484 if(selectVHits(aTrkCandi)) {
5485 int fitFlag = helixFit(aTrkCandi, 5);
5486 // --- update the track candidate
5487 if(fitFlag==0) {
5488 if(myDebugNb==2) cout<<"a good Helix fit"<<endl;
5489 updateDigiFitItem(aTrkCandi);
5490 updateCgemFitItem(aTrkCandi, 1);
5491 return true;
5492 }
5493 }
5494
5495 return false;
5496}
5497
5498bool DotsConnection::selectVHits(struct trkCandi& aTrkCandi)
5499{
5500 // --- to get all intersected V-cluster, calculate s vs z, fill Hough map
5501 int nsz_cgem=0;
5502 if(myDebugNb==2)
5503 cout<<"CGEM V-cluster candidates (s,z): "<<endl;
5504 KalmanFit::Helix circle_fittedHelix = myDotsHelixFitter.getClassHelix();
5505 vector<int>::iterator iter_XClu = aTrkCandi.CgemXClusterID.begin();
5506 double z_XV=9999.;
5507 myRoughTanlDzMap.Reset();
5508 map<int,pair<double,double> > map_Vclu_sz;
5509 for(; iter_XClu!=aTrkCandi.CgemXClusterID.end(); iter_XClu++)
5510 {
5511 int idx_Xclu = *iter_XClu;
5512 if(idx_Xclu<0) continue;// only use fitted X-cluster
5513 myIterClu=myIterCgemClusterBegin+idx_Xclu;
5514 int layer = (*myIterClu)->getlayerid();
5515 if(myDebugNb==2)
5516 cout<<"layer "<<layer;
5517 double rCGEM = myDotsHelixFitter.getRmidGapCgem(layer);
5518 double dphi = myDotsHelixFitter.IntersectCylinder(rCGEM);
5519 if(fabs(dphi)<1e-10) {
5520 if(myDebugNb==2)
5521 cout<<"DotsConnection::"<<__FUNCTION__<<": error, no intersection between track and CGEM layer "<<layer<<endl;
5522 continue;
5523 }
5524 double s = fabs(dphi*circle_fittedHelix.radius());
5525 //int sheet = (*myIterClu)->getsheetid();
5526 int nV = myVecCgemVClusterIdx[layer].size();
5527 for(int iV=0; iV<nV; iV++) {
5528 int idx_Vclu = myVecCgemVClusterIdx[layer][iV];
5529 if(getCgemClusterIntersection(idx_Xclu,idx_Vclu,z_XV)) {
5530 pair<double, double> sz(s,z_XV);
5531 fillTanlDzMap(s,z_XV);
5532 nsz_cgem++;
5533 map_Vclu_sz[idx_Vclu]=sz;
5534 if(myDebugNb==2)
5535 cout<<" ("<<s<<", "<<z_XV<<")";
5536 }
5537 }
5538 if(myDebugNb==2)
5539 cout<<"; ";
5540 }// loop X-clusters
5541 if(myDebugNb==2)
5542 cout<<endl;
5543
5544 // --- to calculate s vs z for MDC stereo hits, fill Hough map
5545 int nsz_mdc=0;
5546 //mdcVDigiWireIdx.insert(mdcVDigiWireIdx.end(), aTrkCandi.mdcV2DigiWireIdx.begin(), aTrkCandi.mdcV2DigiWireIdx.end());
5547 vector<vector<pair<double, double> > > vec_vecsz;
5548 vector<int>& mdcVDigiWireIdx = aTrkCandi.mdcVDigiWireIdx;
5549 int nVdigi = mdcVDigiWireIdx.size();
5550 vector<int>::iterator iter_digi = mdcVDigiWireIdx.begin();
5551 if(myDebugNb==2)
5552 cout<<"MDC V-hits candidates (s,z): "<<endl;
5553 int i_digi=0;
5554 for( ; i_digi<nVdigi; i_digi++,iter_digi++)
5555 {
5556 int wireIdx = *iter_digi;
5557 const MdcDigi* aMdcDigi = myMapMdcDigi[wireIdx];
5558 vector<pair<double, double> > vec_sz = myDotsHelixFitter.getSZ(aMdcDigi);
5559 vec_vecsz.push_back(vec_sz);
5560 vector<pair<double, double> >::iterator iter_sz = vec_sz.begin();
5561 for(; iter_sz!=vec_sz.end(); iter_sz++) {
5562 fillTanlDzMap(iter_sz->first,iter_sz->second);
5563 }
5564 if(vec_sz.size()>0) nsz_mdc++;
5565 if(myDebugNb==2)
5566 if((i_digi+1)%3==0) cout<<endl;
5567 }
5568 if(myDebugNb==2) if((i_digi+1)%3!=1) cout<<endl;
5569
5570 // --- requirement for nsz
5571 if((nsz_cgem+nsz_mdc)<3) {
5572 if(myDebugNb==2)
5573 cout<<" no sufficient sz pair! stop tanl, dz, V-hits association. "<<endl;
5574 aTrkCandi.isGood=0;
5575 return false;
5576 }
5577
5578
5579 // --- get tanl, dz from Hough map
5580 double x_peak(0.), y_peak(0.);
5581 double x_weight(0.), y_weight(0.);
5582 getWeightedPeak(myRoughTanlDzMap, x_peak, y_peak, x_weight, y_weight);
5583 //cout<<"from tanL-dz Hough map: dz_peak="<<y_peak<<", tanL_peak = "<<x_peak<<endl;
5584 if(myDebugNb==2)
5585 cout<<"from tanL-dz Hough map: dz="<<y_weight<<", tanL = "<<x_weight<<endl;
5586
5587 // --- to refill tanl, dz Hough map & linear fit
5588 myRoughTanlDzMap.Reset();
5589 double s_sum(0), z_sum(0);
5590 double s2_sum(0), sz_sum(0);
5591 int n_sz(0);
5592
5593 // --- a rough selection of V-cluster
5594 int cgemVCluIdx[3]={-1,-1,-1};
5595 double cgemVClu_dz_min[3]={9999.,9999.,9999.};
5596 double cgemVClu_s_dzmin[3]={9999.,9999.,9999.};
5597 double cgemVClu_z_dzmin[3]={9999.,9999.,9999.};
5598 if(myDebugNb==2)
5599 cout<<"CGEM V-cluster candidates: "<<endl;
5600 for(map<int,pair<double,double> >::iterator i_map=map_Vclu_sz.begin(); i_map!=map_Vclu_sz.end(); i_map++)
5601 {
5602 double s = (*i_map).second.first;
5603 double z = (*i_map).second.second;
5604 double z_hough = x_weight*s+y_weight;
5605 double delta_z = z-z_hough;
5606 if(myDebugNb==2)
5607 cout<<" delta_z = "<<delta_z<<" ";
5608 double deltaZcut=10.;// in cm, need optimization
5609 if(fabs(delta_z)<deltaZcut) {
5610 int idx_Vclu = (*i_map).first;
5611 myIterClu=myIterCgemClusterBegin+idx_Vclu;
5612 int layer = (*myIterClu)->getlayerid();
5613 if(fabs(delta_z)<fabs(cgemVClu_dz_min[layer])) {
5614 cgemVClu_dz_min[layer]=delta_z;
5615 cgemVClu_s_dzmin[layer]=s;
5616 cgemVClu_z_dzmin[layer]=z;
5617 cgemVCluIdx[layer]=idx_Vclu;
5618 }
5619 }
5620 }
5621 if(myDebugNb==2)
5622 cout<<endl;
5623 for(int layer=2; layer>=0; layer--) {
5624 if(cgemVCluIdx[layer]!=-1) {
5625 //aTrkCandi.CgemVClusterID.push_back(cgemVCluIdx[layer]);
5626 fillTanlDzMap(cgemVClu_s_dzmin[layer],cgemVClu_z_dzmin[layer]);
5627 s_sum+=cgemVClu_s_dzmin[layer];
5628 s2_sum+=cgemVClu_s_dzmin[layer]*cgemVClu_s_dzmin[layer];
5629 z_sum+=cgemVClu_z_dzmin[layer];
5630 sz_sum+=cgemVClu_s_dzmin[layer]*cgemVClu_z_dzmin[layer];
5631 n_sz++;
5632 }
5633 }
5634
5635 // --- a rough selection of stereo wires
5636 if(myDebugNb==2)
5637 cout<<"MDC V-hits candidates: "<<endl;
5638 resetVDigiFitItem(aTrkCandi);
5639 vector<vector<pair<double, double> > >::iterator iter_vvsz = vec_vecsz.begin();
5640 i_digi=0;
5641 for(; iter_vvsz!=vec_vecsz.end(); iter_vvsz++, i_digi++)
5642 {
5643 vector<pair<double, double> >& vec_sz = *iter_vvsz;
5644 vector<pair<double, double> >::iterator iter_sz = vec_sz.begin();
5645 double delta_z_min = 9999.0;
5646 double z_dzmin(0), s_dzmin(0);
5647 for(; iter_sz!=vec_sz.end(); iter_sz++) {
5648 double s = iter_sz->first;
5649 double z = iter_sz->second;
5650 double z_hough = x_weight*s+y_weight;
5651 double delta_z = z-z_hough;
5652 if(fabs(delta_z)<fabs(delta_z_min)) {
5653 delta_z_min=delta_z;
5654 s_dzmin = s;
5655 z_dzmin = z;
5656 }
5657 }
5658 if(myDebugNb==2)
5659 cout<<"delta_z_min="<<delta_z_min;
5660 double deltaZcut_mdc = 10.0; // ??? in cm, need optimization
5661 if(fabs(delta_z_min)>deltaZcut_mdc) {
5662 if(myDebugNb==2)
5663 cout<<"(dropped)";
5664 aTrkCandi.mdcVDigiFitted[i_digi]=-1;
5665 }
5666 else {
5667 aTrkCandi.mdcVDigiFitted[i_digi]=1;
5668 fillTanlDzMap(s_dzmin, z_dzmin);
5669 if(myDebugNb==2)
5670 cout<<"("<<s_dzmin<<","<<z_dzmin<<")";
5671 s_sum+=s_dzmin;
5672 z_sum+=z_dzmin;
5673 s2_sum+=s_dzmin*s_dzmin;
5674 sz_sum+=s_dzmin*z_dzmin;
5675 n_sz++;
5676 }
5677 if(myDebugNb==2) {
5678 cout<<" ";
5679 if((i_digi+1)%3==0) cout<<endl;}
5680 }
5681 if(myDebugNb==2)
5682 if((i_digi+1)%3!=1) cout<<endl;
5683
5684 // --- updated track tanl, dz from the new Hough map
5685 getWeightedPeak(myRoughTanlDzMap, x_peak, y_peak, x_weight, y_weight);
5686 if(myDebugNb==2){
5687 cout<<"After rough selection of sz of V-hits: "<<endl;
5688 //cout<<"from tanL-dz Hough map: dz_peak="<<y_peak<<", tanL_peak = "<<x_peak<<endl;
5689 cout<<"from tanL-dz Hough map: dz="<<y_weight<<", tanL = "<<x_weight<<endl;
5690 }
5691
5692 // --- linear fit of s z
5693 double tanl_lfit = (n_sz*sz_sum-s_sum*z_sum)/(n_sz*s2_sum-s_sum*s_sum);
5694 double dz_lfit = (s2_sum*z_sum-s_sum*sz_sum)/(n_sz*s2_sum-s_sum*s_sum);
5695 if(myDebugNb==2)
5696 cout<<"from s-z line fit: dz="<<dz_lfit<<", tanL = "<<tanl_lfit<<endl;
5697 // --- update tanL and dz of the track candidate
5698 aTrkCandi.a_helix[3]=dz_lfit;
5699 aTrkCandi.a_helix[4]=tanl_lfit;
5700
5701 int nVhits=0;
5702 // --- reselection of V-clusters
5703 for(int i=0; i<3; i++) {
5704 cgemVCluIdx[i]=-1;
5705 cgemVClu_dz_min[i]=9999.;
5706 cgemVClu_s_dzmin[i]=9999.;
5707 cgemVClu_z_dzmin[i]=9999.;
5708 }
5709 if(myDebugNb==2)
5710 cout<<"CGEM V-cluster candidates: "<<endl;
5711 for(map<int,pair<double,double> >::iterator i_map=map_Vclu_sz.begin(); i_map!=map_Vclu_sz.end(); i_map++)
5712 {
5713 double s = (*i_map).second.first;
5714 double z = (*i_map).second.second;
5715 double z_hough = tanl_lfit*s+dz_lfit;
5716 double delta_z = z-z_hough;
5717 if(myDebugNb==2)
5718 cout<<" delta_z = "<<delta_z<<" ";
5719 double deltaZcut=10.;// in cm, need optimization
5720 if(fabs(delta_z)<deltaZcut) {
5721 int idx_Vclu = (*i_map).first;
5722 myIterClu=myIterCgemClusterBegin+idx_Vclu;
5723 int layer = (*myIterClu)->getlayerid();
5724 if(fabs(delta_z)<fabs(cgemVClu_dz_min[layer])) {
5725 cgemVClu_dz_min[layer]=delta_z;
5726 cgemVClu_s_dzmin[layer]=s;
5727 cgemVClu_z_dzmin[layer]=z;
5728 cgemVCluIdx[layer]=idx_Vclu;
5729 }
5730 }
5731 }
5732 if(myDebugNb==2)
5733 cout<<endl;
5734 for(int layer=2; layer>=0; layer--) {
5735 if(cgemVCluIdx[layer]!=-1) {
5736 aTrkCandi.CgemVClusterID.push_back(cgemVCluIdx[layer]);
5737 nVhits++;
5738 }
5739 }
5740
5741 // --- reselection of stereo wires
5742 if(myDebugNb==2)
5743 cout<<"MDC V-hits candidates: "<<endl;
5744 resetVDigiFitItem(aTrkCandi);
5745 //vector<vector<pair<double, double> > >::iterator
5746 iter_vvsz = vec_vecsz.begin();
5747 i_digi=0;
5748 for(; iter_vvsz!=vec_vecsz.end(); iter_vvsz++, i_digi++)
5749 {
5750 vector<pair<double, double> >& vec_sz = *iter_vvsz;
5751 vector<pair<double, double> >::iterator iter_sz = vec_sz.begin();
5752 double delta_z_min = 9999.0;
5753 double z_dzmin(0), s_dzmin(0);
5754 for(; iter_sz!=vec_sz.end(); iter_sz++) {
5755 double s = iter_sz->first;
5756 double z = iter_sz->second;
5757 double z_hough = tanl_lfit*s+dz_lfit;
5758 double delta_z = z-z_hough;
5759 if(fabs(delta_z)<fabs(delta_z_min)) {
5760 delta_z_min=delta_z;
5761 s_dzmin = s;
5762 z_dzmin = z;
5763 }
5764 }
5765 if(myDebugNb==2)
5766 cout<<"delta_z_min="<<delta_z_min;
5767 double deltaZcut_mdc = 10.0; // in cm, ??? need optimization
5768 if(fabs(delta_z_min)>deltaZcut_mdc) {
5769 if(myDebugNb==2)
5770 cout<<"(dropped)";
5771 aTrkCandi.mdcVDigiFitted[i_digi]=-1;
5772 }
5773 else {
5774 aTrkCandi.mdcVDigiFitted[i_digi]=1;
5775 if(myDebugNb==2)
5776 cout<<"("<<s_dzmin<<","<<z_dzmin<<")";
5777 nVhits++;
5778 }
5779 if(myDebugNb==2){
5780 cout<<" ";
5781 if((i_digi+1)%3==0) cout<<endl;}
5782 }
5783 if(myDebugNb==2)
5784 if((i_digi+1)%3!=1) cout<<endl;
5785
5786 if(nVhits>2) return true;
5787 else return false;
5788
5789}
5790
5791int DotsConnection::fillTanlDzMap(double s, double z, int vote)
5792{
5793 int nPoint(0);
5794 /* x: tanLambda, y: dz */
5795 double dx = (2.0*myTanlRange)/(myNBinTanl*vote);
5796 dx = dx>1e-6?dx:1e-6;// step size
5797 double x = -1.0*myTanlRange + dx/2;// first step
5798 while(x<myTanlRange)
5799 {
5800 double y = -s*x + z;
5801 bool cut(true);
5802 cut = fabs(y)<myDzRange;
5803 if(cut)
5804 {
5805 myRoughTanlDzMap.Fill(x,y);
5806 nPoint++;
5807 }
5808 x += dx;
5809 }
5810 return nPoint;
5811}
5812
5813void DotsConnection::getWeightedPeak(TH2D& h, double& x_peak, double& y_peak, double& x_weight, double& y_weight, int x_ext, int y_ext)
5814{
5815 int ix_max, iy_max, iz_max;
5816 h.GetMaximumBin(ix_max, iy_max, iz_max);
5817 int nx=h.GetXaxis()->GetNbins();
5818 int ny=h.GetYaxis()->GetNbins();
5819 //cout<<"peak at "<<ix_max<<", "<<iy_max<<" in a map "<<nx<<" * "<<ny<<endl;
5820
5821 if(ix_max==0&&iy_max==0) {
5822 //cout<<"nx, ny = "<<nx<<", "<<ny<<endl;
5823 for(int i=0; i<nx; i++)
5824 {
5825 //cout<<endl;
5826 for(int j=0; j<ny; j++)
5827 {
5828 double n_tmp = h.GetBinContent(i,j);
5829 //cout<<n_tmp<<" ";
5830 }
5831 }
5832 }
5833
5834 x_peak=h.GetXaxis()->GetBinCenter(ix_max);
5835 y_peak=h.GetYaxis()->GetBinCenter(iy_max);
5836 x_weight=0.; y_weight=0.;
5837 double weight(0.);
5838 if(x_ext>=0&&y_ext>=0) {
5839 for(int i1=ix_max-x_ext; i1<=ix_max+x_ext; i1++)
5840 {
5841 double x_tmp = h.GetXaxis()->GetBinCenter(i1);
5842 int i1_tmp = i1;
5843 //if(i1<1) i1_tmp=m_nBinTheta+i1;
5844 //if(i1>1) i1_tmp=m_nBinTheta+i1;
5845 //if(i1==m_nBinTheta+1) i1_tmp=1;
5846 for(int i2=iy_max-y_ext; i2<=iy_max+y_ext; i2++)
5847 {
5848 double n_tmp = h.GetBinContent(i1_tmp,i2);
5849 if(i2<1||i2>ny) n_tmp=0.;
5850 if(i1<1||i1>nx) n_tmp=0.;
5851 weight+=n_tmp;
5852 double y_tmp = h.GetYaxis()->GetBinCenter(i2);
5853 x_weight+=x_tmp*n_tmp;
5854 y_weight+=y_tmp*n_tmp;
5855 //cout<<"i1,i2="<<i1<<","<<i2<<endl;
5856 }
5857 }
5858 x_weight=x_weight/weight;
5859 y_weight=y_weight/weight;
5860 }
5861 else {
5862 x_weight=x_peak;
5863 y_weight=y_peak;
5864 }
5865}
5866
5867void DotsConnection::getRhoTheta_bisection(vector<const MdcDigi*>& aVecMdcDigi)
5868{
5869 bool debug=false; debug=true;
5870
5871 int nHits=aVecMdcDigi.size();
5872 // --- fill x, y, r for MDC hits
5873 vector<double> vx, vy, vr;
5874 vector<const MdcDigi*>::iterator i_digi = aVecMdcDigi.begin();
5875 for(int ihit=0; i_digi!=aVecMdcDigi.end(); i_digi++,ihit++)
5876 {
5877 Identifier id = (*i_digi)->identify();
5878 int layer = MdcID::layer(id);
5879 int wire = MdcID::wire(id);
5880 int wireid = myMdcGeomSvc->Wire(layer,wire)->Id();
5881 vx.push_back(0.1*myRLayer[layer]*cos(myWirePhi[layer][wire]));
5882 vy.push_back(0.1*myRLayer[layer]*sin(myWirePhi[layer][wire]));
5883 vr.push_back(myMapMdcDigiDd[wireid]);
5884 if( (myNtProd&2) && ihit<100) {
5885 myNt_Xhit[ihit]=vx.back();
5886 myNt_Yhit[ihit]=vy.back();
5887 myNt_DDhit[ihit]=vr.back();
5888 }
5889 }
5890
5891 // --- find the peak with bisection method
5892 double rho_center = 0.0; //myRhoRange/2.0;
5893 double theta_center = myThetaRange/2.0;
5894 double bin_rho=myRhoRange;
5895 double bin_theta=myThetaRange/2.0;
5896 double theta, rho, theta_min, rho_min, rho_max;
5897 int quarter_peak;
5898 int nAccu_peak;
5899 int i_iter=0;
5900 cout<<" ------ hough start : rho_center, theta_center = "<<rho_center<<", "<<theta_center<<endl;
5901 while(1) {
5902 theta_min=theta_center-bin_theta;
5903 rho_min=rho_center-bin_rho;
5904
5905 // --- fill nPass
5906 int Npass[2][2]={0,0,0,0};
5907 for(int iHit=0; iHit<nHits; iHit++) {
5908 int pass[2][2]={0,0,0,0};
5909 for(int i=0; i<3; i++) {// loop theta boundaries
5910 theta=theta_center+(i-1)*bin_theta;
5911 for(int sign=-1; sign<2; sign+=2) {// sign
5912 rho=vx[iHit]*cos(theta)+vy[iHit]*sin(theta)+sign*vr[iHit];
5913 int i_rho=(int)floor((rho-rho_min)/bin_rho);
5914 if(i_rho>=0&&i_rho<2) {
5915 if(i<2) pass[0][i_rho]=1;
5916 if(i>0) pass[1][i_rho]=1;
5917 }
5918 }
5919 }
5920 for(int i=0; i<3; i++) {// loop rho boundaries
5921 rho=rho_center+(i-1)*bin_rho;
5922 for(int sign=-1; sign<2; sign+=2) {// sign
5923 double a=vx[iHit]*vx[iHit]+vy[iHit]*vy[iHit];
5924 double b=-2.0*(rho+sign*vr[iHit])*vx[iHit];
5925 double c=pow(rho+sign*vr[iHit],2)-vy[iHit]*vy[iHit];
5926 double d=b*b-4*a*c;
5927 if(d>=0) {
5928 d=sqrt(d);
5929 for(int sign2=-1; sign2<2; sign2+=2) {// sign2
5930 double costh=(-b+sign2*d)/(2.0*a);
5931 if(fabs(costh)<=1) {
5932 theta=acos(costh);
5933 int i_theta=(int)floor((theta-theta_min)/bin_theta);
5934 if(i_theta>=0&&i_theta<2) {
5935 if(i<2) pass[i_theta][0]=1;
5936 if(i>2) pass[i_theta][1]=1;
5937 }
5938 }
5939 }
5940 }
5941 }
5942 }
5943 Npass[0][0]+=pass[0][0];
5944 Npass[0][1]+=pass[0][1];
5945 Npass[1][0]+=pass[1][0];
5946 Npass[1][1]+=pass[1][1];
5947 }// loop hits
5948
5949 // --- find the quarter at the peak
5950 quarter_peak=-1;
5951 nAccu_peak=0;
5952 cout<<" Npass: ";
5953 for(int i=0; i<4; i++) {
5954 int ii=i/2;
5955 int jj=i%2;
5956 cout<<"["<<ii<<","<<jj<<"]="<<Npass[ii][jj]<<" ";
5957 if(nAccu_peak<Npass[ii][jj]) {
5958 nAccu_peak=Npass[ii][jj];
5959 quarter_peak=i;
5960 }
5961 }
5962 cout<<endl;
5963
5964 //myRoughRhoThetaMap.Reset();
5965 //for(int iHit=0; iHit<nHits; iHit++) {
5966 // for(int i=0; i<100; i++) {// loop theta bin
5967 // theta=;
5968 // for(int sign=-1; sign<2; sign+=2) {// sign
5969 // rho=vx[iHit]*cos(theta)+vy[iHit]*sin(theta)+sign*vr[iHit];
5970 // if() myRoughRhoThetaMap.Fill(theta,rho);
5971 // }
5972 // }
5973 //}
5974
5975
5976 // --- update center and bin
5977 theta_center=(quarter_peak/2-1)*0.5*bin_theta;
5978 rho_center=(quarter_peak%2-1)*0.5*bin_rho;
5979 bin_rho/=2.0;
5980 bin_theta/=2.0;
5981 // 1.1 increase the bin by 10% to reduce the boundary effect
5982 bin_rho*=1.1;
5983 bin_theta*=1.1;
5984 cout<<"hough iter "<<i_iter<<": rho_center, theta_center = "<<rho_center<<", "<<theta_center<<endl;
5985
5986 // --- stop iteration if sufficient
5987 i_iter++;
5988 if(i_iter>10) break;
5989
5990 }// iterations
5991
5992 // --- line fit
5993 double x_sum(0), y_sum(0), x2_sum(0), y2_sum(0), xy_sum(0);
5994 int sign_prod=0;
5995 int sign[10]={0};
5996 //while(1) {
5997 x_sum=0.; y_sum=0.; x2_sum=0.; y2_sum=0.; xy_sum=0.;
5998 for(int iHit=0; iHit<nHits; iHit++) {
5999 x_sum+=vx[iHit];
6000 y_sum+=vy[iHit];
6001 x2_sum+=pow(vx[iHit],2);
6002 y2_sum+=pow(vy[iHit],2);
6003 xy_sum+=vx[iHit]*vy[iHit];
6004 }
6005 double Y=x_sum*x_sum-nHits*x2_sum;
6006 double X=nHits*xy_sum-x_sum*y_sum;
6007 theta=atan2(Y,X);
6008 rho=(x_sum*xy_sum-x2_sum*y_sum)/sqrt(X*X+Y*Y);
6009 if(theta<0) {
6010 theta+=M_PI;
6011 rho*=-1;
6012 }
6013 //}
6014
6015 // --- fill ntuple
6016 if(myNtProd&2) {
6017 myRUN=myRun;
6018 myEVT=myEvt;
6019 myNt_nhits=nHits;
6020 myNt_rho=rho_center;
6021 myNt_theta=theta_center;
6022 myNtTrkSeg->write();
6023 }
6024}
6025
6026bool DotsConnection::LineFit_TLS(vector<const MdcDigi*>& aVecMdcDigi, vector<double>& vRho, vector<double>& vTheta, vector<vector<int> >& vvLR, vector<vector<double> >& vvS, bool ini, double rho_ini, double theta_ini,const vector<int>& LR_ini)
6027{
6028 bool debug=false; debug=true;
6029
6030 bool goodLine=false;
6031
6032 const int nHitMax=5;
6033
6034 int nHits=aVecMdcDigi.size();
6035 if(nHits<3) return false;
6036 if(nHits>nHitMax) nHits=nHitMax;
6037
6038 // --- fill x, y, r for MDC hits
6039 vector<double> vx, vy, vr;
6040 vector<int> vLR;
6041 vector<const MdcDigi*>::iterator i_digi = aVecMdcDigi.begin();
6042 vector<int> vLRFloat;
6043 if(debug) {
6044 cout<<setw(6)<<""<<"---> Try fitting "<<nHits<<" hits (L,W,dd): ";
6045 }
6046 for(int ihit=0; i_digi!=aVecMdcDigi.end(); i_digi++,ihit++)
6047 {
6048 Identifier id = (*i_digi)->identify();
6049 int layer = MdcID::layer(id);
6050 int wire = MdcID::wire(id);
6051 int wireid = myMdcGeomSvc->Wire(layer,wire)->Id();
6052 vx.push_back(0.1*myRLayer[layer]*cos(myWirePhi[layer][wire]));
6053 vy.push_back(0.1*myRLayer[layer]*sin(myWirePhi[layer][wire]));
6054 vr.push_back(myMapMdcDigiDd[wireid]);
6055 if(debug) cout<<"("<<setw(2)<<layer <<", "<<setw(3)<<wire<<", "<<setw(8)<<vr.back()<<") ";
6056 if( (myNtProd&2) && ihit<100) {
6057 myNt_layer[ihit]=layer;
6058 myNt_wire[ihit]=wire;
6059 myNt_Xhit[ihit]=vx.back();
6060 myNt_Yhit[ihit]=vy.back();
6061 myNt_DDhit[ihit]=vr.back();
6062 }
6063 if(ini) {
6064 int LR=LR_ini.at(ihit);
6065 vLR.push_back(LR);
6066 if(debug) cout<<"LR="<<setw(2)<<LR<<"; ";
6067 if(LR==0) vLRFloat.push_back(ihit);
6068 }
6069 else vLR.push_back(0);
6070 }
6071 if(debug) cout<<endl;
6072
6073 // --- LR
6074 //int LR[9][3]={ //[nCombi][nhit]
6075 // { 0, 0, 0},// only use wire positions
6076 // { 1, 1, 1},
6077 // {-1, 1, 1},
6078 // { 1,-1, 1},
6079 // { 1, 1,-1},
6080 // {-1,-1, 1},
6081 // {-1, 1,-1},
6082 // { 1,-1,-1},
6083 // {-1,-1,-1}
6084 //};
6085
6086 // --- loop all LR combinations
6087 double theta_TLS, rho_TLS, theta0_TLS(0.), rho0_TLS(0.), theta_last, rho_last;
6088 double x_sum, y_sum, x_mean, y_mean, dxdy_sum, dx2mdy2_sum, rho_hit[nHitMax];
6089 //if(debug) {
6090 // cout<<setw(35)<<" ---- One TLS Line fit ---- "<<endl;
6091 // cout<<setw(39)<<" ";
6092 //}
6093 int nLRFloat = nHits;
6094 int iLR_0=0;
6095 if(ini) {
6096 nLRFloat=vLRFloat.size();
6097 theta0_TLS=theta_ini;
6098 rho0_TLS=rho_ini;
6099 iLR_0=1;
6100 if(debug) cout<<setw(6)<<""<<"ini rho, theta = "<<rho0_TLS<<", "<<theta0_TLS<<endl;
6101 }
6102 int nLR=pow(2,nLRFloat);
6103 for(int iLR=iLR_0; iLR<=nLR; iLR++) {
6104 // --- set LR
6105 if(iLR>0) {
6106 for(int j=0; j<nLRFloat; j++) {
6107 int ibHit = pow(2,j);
6108 int i_LR=j;
6109 if(ini) i_LR=vLRFloat.at(j);
6110 if( (iLR-1) & ibHit ) vLR[i_LR]= 1;
6111 else vLR[i_LR]=-1;
6112 }
6113 }
6114
6115 // --- TLS
6116 theta_TLS=theta0_TLS;
6117 rho_TLS=rho0_TLS;
6118 int iter=0;
6119 double drho2_tls=99999.;
6120 double drho2_min=999999.;
6121 double theta_TLS_drmin, rho_TLS_drmin;
6122 int i_lastMin(0), iPeriod(0), period(0);
6123 double drho2_last=0.;
6124 set<double> set_drho2;
6125 while(1) {
6126 x_sum=0.; y_sum=0.; //x2_sum=0.; y2_sum=0.; xy_sum=0.;
6127 drho2_tls=0;
6128 for(int j=0; j<nHits; j++)
6129 {
6130 //double x=vx[j]+vr[j]*cos(theta_TLS)*LR[iLR][j];
6131 //double y=vy[j]+vr[j]*sin(theta_TLS)*LR[iLR][j];
6132 double x=vx[j]+vr[j]*cos(theta_TLS)*vLR[j];
6133 double y=vy[j]+vr[j]*sin(theta_TLS)*vLR[j];
6134 x_sum+=x;
6135 y_sum+=y;
6136 rho_hit[j]=x*cos(theta_TLS)+y*sin(theta_TLS);
6137 drho2_tls+=pow(rho_hit[j]-rho_TLS, 2);
6138 }
6139 x_mean=x_sum/nHits;
6140 y_mean=y_sum/nHits;
6141 dxdy_sum=0.; dx2mdy2_sum=0.;
6142 for(int j=0; j<nHits; j++)
6143 {
6144 //double x=vx[j]+vr[j]*cos(theta_TLS)*LR[iLR][j];
6145 //double y=vy[j]+vr[j]*sin(theta_TLS)*LR[iLR][j];
6146 double x=vx[j]+vr[j]*cos(theta_TLS)*vLR[j];
6147 double y=vy[j]+vr[j]*sin(theta_TLS)*vLR[j];
6148 double dx=x-x_mean;
6149 double dy=y-y_mean;
6150 dxdy_sum+=dx*dy;
6151 dx2mdy2_sum+=dy*dy-dx*dx;
6152 }
6153 double Y_TLS=-2*dxdy_sum;
6154 double X_TLS=dx2mdy2_sum;
6155 theta_TLS=0.5*atan2(Y_TLS,X_TLS);// -pi/2 ~ pi/2
6156 rho_TLS=x_mean*cos(theta_TLS)+y_mean*sin(theta_TLS);
6157
6158 if(iLR==0) {
6159 theta0_TLS=theta_TLS;
6160 rho0_TLS=rho_TLS;
6161 if(theta0_TLS<0) {
6162 theta0_TLS+=acos(-1.);
6163 rho0_TLS*=-1.;
6164 }
6165 break;
6166 }
6167 else {
6168 // ---> to avoid the reverse of left-right ambiguity
6169 //while(fabs(theta_TLS-theta_last+acos(-1.))<fabs(theta_TLS-theta_last))
6170 while(fabs(theta_TLS-theta0_TLS+acos(-1.))<fabs(theta_TLS-theta0_TLS))
6171 {
6172 //cout<<"theta_last="<<theta_last<<", theta="<<theta_TLS<<"+pi"<<endl;
6173 //cout<<"theta0="<<theta0_TLS<<", theta="<<theta_TLS<<"+pi"<<endl;
6174 theta_TLS+=acos(-1.);
6175 rho_TLS*=-1.;
6176 }
6177 //while(fabs(theta_TLS-theta_last-acos(-1.))<fabs(theta_TLS-theta_last))
6178 while(fabs(theta_TLS-theta0_TLS-acos(-1.))<fabs(theta_TLS-theta0_TLS))
6179 {
6180 //cout<<"theta_last="<<theta_last<<", theta="<<theta_TLS<<"-pi"<<endl;
6181 //cout<<"theta0="<<theta0_TLS<<", theta="<<theta_TLS<<"-pi"<<endl;
6182 theta_TLS-=acos(-1.);
6183 rho_TLS*=-1.;
6184 }
6185 // <--- to avoid the reverse of left-right ambiguity
6186
6187 if(fabs(drho2_tls-drho2_last)<0.0001)
6188 {
6189 if(debug) cout<<setw(6)<<""<<"Line TLS fit converges at iter "<<setw(2)<<iter<<" ";//<<endl;
6190 break;
6191 }
6192 if(drho2_min>drho2_tls) {
6193 drho2_min=drho2_tls;
6194 theta_TLS_drmin=theta_TLS;
6195 rho_TLS_drmin=rho_TLS;
6196 i_lastMin=iter;
6197 }
6198 //else if(fabs(drho2_min-drho2_tls)<Epsilon) {
6199 // iPeriod++;
6200 // period=iter-i_lastMin;
6201 // i_lastMin=iter;
6202 // cout<<"Periodic min drho2 "<<setw(3)<<iPeriod<<", period="<<period<<endl;
6203 //}
6204 bool findDrho2=false;
6205 set<double>::iterator it_set=set_drho2.begin();
6206 for(; it_set!=set_drho2.end(); it_set++) {
6207 if(fabs(*it_set-drho2_tls)<0.0001) {
6208 findDrho2=true;
6209 break;
6210 }
6211 }
6212 if(findDrho2)
6213 {
6214 if(debug) cout<<setw(6)<<""<<setw(38)<<"Repeat a result, break!";
6215 //drho2_tls=drho2_min;
6216 //rho_TLS=rho_TLS_drmin;
6217 //theta_TLS=theta_TLS_drmin;
6218 break;
6219 }
6220 else set_drho2.insert(drho2_tls);
6221 //if(iter>20) {
6222 // cout<<" iter "<<setw(4)<<iter<<" rho="<<setw(8)<<rho_TLS<<", theta="<<setw(8)<<theta_TLS<<", drho2="<<setw(8)<<drho2_tls<<", drho2_min="<<setw(8)<<drho2_min<<endl;
6223 //}
6224 if(iter>50) {
6225 if(debug) cout<<setw(6)<<""<<setw(38)<<"Too many iterations, break!";//<<endl;
6226 drho2_tls=drho2_min;
6227 rho_TLS=rho_TLS_drmin;
6228 theta_TLS=theta_TLS_drmin;
6229 break;
6230 }
6231 theta_last=theta_TLS;
6232 drho2_last=drho2_tls;
6233 iter++;
6234 } // iLR!=0
6235 }// line fit iterations
6236 vector<double> vS;
6237 if(isGood_Drho2_line(drho2_tls)) {
6238 goodLine=true;
6239 vRho.push_back(rho_TLS);
6240 vTheta.push_back(theta_TLS);
6241 vvLR.push_back(vLR);
6242 // fill S
6243 for(int j=0; j<nHits; j++)
6244 {
6245 double s=getS(rho_TLS,theta_TLS,vx[j],vy[j]);
6246 vS.push_back(s);
6247 }
6248 vvS.push_back(vS);
6249 }
6250
6251 if(debug) {
6252 while(theta_TLS<-0.5*acos(-1.)) {
6253 theta_TLS+=acos(-1.);
6254 rho_TLS*=-1.;
6255 }
6256 while(theta_TLS>0.5*acos(-1.)) {
6257 theta_TLS-=acos(-1.);
6258 rho_TLS*=-1.;
6259 }
6260 cout<<setw(6)<<""<<"rho="<<setw(8)<<rho_TLS<<", theta="<<setw(8)<<theta_TLS;
6261 cout<<", LR={";
6262 for(int j=0; j<nHits; j++) cout<<setw(3)<<std::right<<vLR[j];
6263 cout<<"}, drho2="<<setw(8)<<drho2_tls;
6264 if(isGood_Drho2_line(drho2_tls)) {// if good
6265 cout<<" good ";
6266 cout<<" s={";
6267 for(int j=0; j<nHits; j++) cout<<setw(4)<<vS[j]<<" ";
6268 cout<<"}";
6269 }
6270 cout<<endl;
6271 }
6272
6273 }// <- loop LR combinations
6274
6275 // --- fill ntuple
6276 if(myNtProd&2) {
6277 myRUN=myRun;
6278 myEVT=myEvt;
6279 myNt_nhits=nHits;
6280 //myNt_rho=rho_center;
6281 //myNt_theta=theta_center;
6282 myNtTrkSeg->write();
6283 }
6284
6285 return goodLine;
6286
6287}// LineFit_TLS
6288
6289vector<vector<double> > DotsConnection::getTangentCircles(vector<const MdcDigi*>& aVecMdcDigi)
6290{
6291 vector<vector<double> > circles;
6292 int nHits=aVecMdcDigi.size();
6293 if(nHits<3) return circles;
6294
6295 vector<double> xhit, yhit, DDhit;
6296 vector<const MdcDigi*>::iterator i_digi = aVecMdcDigi.begin();
6297 for(int ihit=0; ihit<3&&i_digi!=aVecMdcDigi.end(); i_digi++,ihit++)
6298 {
6299 Identifier id = (*i_digi)->identify();
6300 int layer = MdcID::layer(id);
6301 int wire = MdcID::wire(id);
6302 int wireid = myMdcGeomSvc->Wire(layer,wire)->Id();
6303 xhit.push_back(0.1*myRLayer[layer]*cos(myWirePhi[layer][wire]));
6304 yhit.push_back(0.1*myRLayer[layer]*sin(myWirePhi[layer][wire]));
6305 DDhit.push_back(myMapMdcDigiDd[wireid]);
6306 }
6307
6308 int LR[8][3]={ //[nCombi][nhit]
6309 { 1, 1, 1},
6310 {-1, 1, 1},
6311 { 1,-1, 1},
6312 { 1, 1,-1},
6313 {-1,-1, 1},
6314 {-1, 1,-1},
6315 { 1,-1,-1},
6316 {-1,-1,-1}
6317 };
6318
6319 double xmean=(xhit[0]+xhit[1]+xhit[2])/3.0;
6320 double ymean=(yhit[0]+yhit[1]+yhit[2])/3.0;
6321
6322 for(int ic=0; ic<8; ic++) {
6323 double v11 = 2 * xhit[1] - 2 * xhit[0];
6324 double v12 = 2 * yhit[1] - 2 * yhit[0];
6325 double v13 = xhit[0] * xhit[0] - xhit[1] * xhit[1] + yhit[0] * yhit[0] - yhit[1] * yhit[1] - DDhit[0] * DDhit[0] + DDhit[1] * DDhit[1];
6326 double v14 = 2 * LR[ic][1] * DDhit[1] - 2 * LR[ic][0] * DDhit[0];
6327
6328 double v21 = 2 * xhit[2] - 2 * xhit[1];
6329 double v22 = 2 * yhit[2] - 2 * yhit[1];
6330 double v23 = xhit[1] * xhit[1] - xhit[2] * xhit[2] + yhit[1] * yhit[1] - yhit[2] * yhit[2] - DDhit[1] * DDhit[1] + DDhit[2] * DDhit[2];
6331 double v24 = 2 * LR[ic][2] * DDhit[2] - 2 * LR[ic][1] * DDhit[1];
6332
6333 double w12 = v12 / v11;
6334 double w13 = v13 / v11;
6335 double w14 = v14 / v11;
6336
6337 double w22 = v22 / v21 - w12;
6338 double w23 = v23 / v21 - w13;
6339 double w24 = v24 / v21 - w14;
6340
6341 double P = -w23 / w22;
6342 double Q = w24 / w22;
6343 double M = -w12 * P - w13;
6344 double n = w14 - w12 * Q;
6345
6346 double aa = n * n + Q * Q - 1;
6347 double bb = 2 * M * n - 2 * n * xhit[0] + 2 * P * Q - 2 * Q * yhit[0] + 2 * LR[ic][0] * DDhit[0];
6348 double cc = xhit[0] * xhit[0] + M * M - 2 * M * xhit[0] + P * P + yhit[0] * yhit[0] - 2 * P * yhit[0] - DDhit[0] * DDhit[0];
6349
6350 double D = bb * bb - 4 * aa * cc;
6351 double rs = (-bb - sqrt(D)) / (2 * aa);
6352
6353 double xs = M + n * rs;
6354 double ys = P + Q * rs;
6355
6356 // --- make radius positive
6357 rs = fabs(rs);
6358 if(rs>10.) // in cm, i.e. pT>2.99792458â‹…rs ~ 30(MeV/c)
6359 {
6360 vector<double> circle;
6361 circle.push_back(xs);
6362 circle.push_back(ys);
6363 circle.push_back(rs);
6364 circle.push_back(xmean);
6365 circle.push_back(ymean);
6366 circles.push_back(circle);
6367 }
6368 }// loop 8 results
6369 return circles;
6370}// getTangentCircles()
6371
6372vector<double> DotsConnection::getBestTangentCircle(vector<const MdcDigi*>& aVecMdcDigi)
6373{
6374 vector<double> circle;
6375
6376 int nHits=aVecMdcDigi.size();
6377 if(nHits<=3) return circle;
6378
6379 // --- fill vdr,vphi0,vkap
6380 /*
6381 vector<double> vxc,vyc,vrc;
6382 vector<double> vdr,vphi0,vkap;
6383 for(int ihit1=0; ihit1<nHits; ihit1++)
6384 for(int ihit2=ihit1+1; ihit1<nHits; ihit2++)
6385 for(int ihit3=ihit2+1; ihit3<nHits; ihit3++)
6386 {
6387 vector<const MdcDigi*> tripleMdcDigi;
6388 tripleMdcDigi.push_back(aVecMdcDigi.at(ihit1));
6389 tripleMdcDigi.push_back(aVecMdcDigi.at(ihit2));
6390 tripleMdcDigi.push_back(aVecMdcDigi.at(ihit3));
6391 vector<vector<double> > circles = getTangentCircles(tripleMdcDigi);
6392 for(int iC=0; iC<circles.size(); iC++)
6393 {
6394 vector<double> circle_bes = myDotsHelixFitter.circleParConversion(circles.at(iC));
6395 double x=circles.at(iC).at(0);
6396 double y=circles.at(iC).at(1);
6397 double r=circles.at(iC).at(2);
6398 vxc.push_back(x);
6399 vyc.push_back(y);
6400 vrc.push_back(r);
6401 vdr.push_back(circle_bes.at(0));
6402 vphi0.push_back(circle_bes.at(1));
6403 vkap.push_back(circle_bes.at(2));
6404 }
6405 }
6406 */
6407
6408 // --- fill myNtTrkSeg for test
6409 if(myNtProd&4)
6410 {
6411 int nFill=min(nHits,100);
6412 for(int ihit=0; ihit<nFill; ihit++)
6413 {
6414 Identifier id = aVecMdcDigi.at(ihit)->identify();
6415 int layer = MdcID::layer(id);
6416 int wire = MdcID::wire(id);
6417 int wireid = myMdcGeomSvc->Wire(layer,wire)->Id();
6418 double x=0.1*myRLayer[layer]*cos(myWirePhi[layer][wire]);
6419 double y=0.1*myRLayer[layer]*sin(myWirePhi[layer][wire]);
6420 double r=myMapMdcDigiDd[wireid];
6421 myNt_layer[ihit]=layer;
6422 myNt_wire[ihit]=wire;
6423 myNt_Xhit[ihit]=x;
6424 myNt_Yhit[ihit]=y;
6425 myNt_DDhit[ihit]=r;
6426 }
6427 myRUN=myRun;
6428 myEVT=myEvt;
6429 myNt_nhits=nFill;
6430 myNtTrkSeg->write();
6431 }
6432
6433 // --- search maximum at phi0 kappa plane?
6434
6435 return circle;
6436}
6437
6438void DotsConnection::fillVecCgemClu(struct trkCandi& aTrkCandi)
6439{
6440 clearVecCgemClu();
6441
6442 vector<int>::iterator iter_XClu = aTrkCandi.CgemXClusterID.begin();
6443 for(; iter_XClu!=aTrkCandi.CgemXClusterID.end(); iter_XClu++)
6444 {
6445 int idx_Xclu = *iter_XClu;
6446 if(idx_Xclu<0) continue;
6447 myIterClu=myIterCgemClusterBegin+idx_Xclu;
6448 int layer = (*myIterClu)->getlayerid();
6449 int sheet = (*myIterClu)->getsheetid();
6450 myVecCgemXCluIdx[layer][sheet].push_back(idx_Xclu);
6451 //myVecCgemXCluChi[layer][sheet]
6452 }
6453
6454 vector<int>::iterator iter_VClu = aTrkCandi.CgemVClusterID.begin();
6455 for(; iter_VClu!=aTrkCandi.CgemVClusterID.end(); iter_VClu++)
6456 {
6457 int idx_clu = *iter_VClu;
6458 if(idx_clu<0) continue;
6459 myIterClu=myIterCgemClusterBegin+idx_clu;
6460 int layer = (*myIterClu)->getlayerid();
6461 int sheet = (*myIterClu)->getsheetid();
6462 myVecCgemVCluIdx[layer][sheet].push_back(idx_clu);
6463 //myVecCgemVCluChi[layer][sheet]
6464 }
6465
6466}
6467
6468int DotsConnection::NXcluToDrop(struct trkCandi& aTrkCandi)
6469{
6470 int nToDrop=0;
6471 vector<int>::iterator iter_XClu = aTrkCandi.CgemXClusterID.begin();
6472 for(; iter_XClu!=aTrkCandi.CgemXClusterID.end(); iter_XClu++)
6473 {
6474 int idx_Xclu = *iter_XClu;
6475 if(idx_Xclu<0) nToDrop++;
6476 }
6477 return nToDrop;
6478}
6479
6480
6481bool DotsConnection::isGoodCgemCircleCandi(struct trkCandi& aTrkCandi)
6482{
6483 HepPoint3D origin(0, 0, 0);
6484 HepVector a_helix(5,0);
6485 a_helix(1)=aTrkCandi.a_helix[0];
6486 a_helix(2)=aTrkCandi.a_helix[1];
6487 a_helix(3)=aTrkCandi.a_helix[2];
6488 KalmanFit::Helix helix(origin,a_helix);
6489
6490 int n_sign[2]={0,0};
6491
6492 HepPoint3D center = helix.center();
6493 Hep3Vector pos_center(center.x(), center.y());
6494 int size = aTrkCandi.CgemXClusterID.size();
6495 vector<int>::iterator iter = aTrkCandi.CgemXClusterID.begin();
6496 for(int i=0; i<size; i++, iter++) {
6497 int cluIdx = *iter;
6498 if(cluIdx<0) {
6499 cluIdx=-cluIdx-1;
6500 //if(sel==2)
6501 continue;
6502 }
6503 myIterClu=myIterCgemClusterBegin+cluIdx;
6504 int layer = (*myIterClu)->getlayerid();
6505 double rCGEM = myDotsHelixFitter.getRmidGapCgem(layer);
6506 double phi_cluster = (*myIterClu)->getrecphi();
6507 double x_clu = rCGEM*cos(phi_cluster);
6508 double y_clu = rCGEM*sin(phi_cluster);
6509 Hep3Vector pos_clu(x_clu, y_clu);
6510 Hep3Vector vec_z=pos_clu.cross(pos_center);
6511 if(vec_z.z()<0) n_sign[0]++;
6512 else if(vec_z.z()>0) n_sign[1]++;
6513 }
6514
6515 if(n_sign[0]+n_sign[1]>0 && n_sign[0]*n_sign[1]==0) return true;
6516 else return false;
6517}
6518
6519bool DotsConnection::saveARecMdcTrack(struct trkCandi& aTrkCandi)
6520{
6521 if(aTrkCandi.isGood!=1) return false;
6522
6523 int tkStat =5;
6524
6525 RecMdcTrack* recMdcTrack = new RecMdcTrack();
6526 int trackId = myRecMdcTrackCol->size();
6527 recMdcTrack->setTrackId(trackId);
6528
6529 double helixPar[5];
6530 HepVector a_helix(5,0);
6531 for(int i=0; i<5; i++) {
6532 helixPar[i]=aTrkCandi.a_helix[i];
6533 a_helix(i+1)=helixPar[i];
6534 }
6535 recMdcTrack->setHelix(helixPar);
6536
6537 HepPoint3D origin(0, 0, 0);
6538 KalmanFit::Helix aHelix(origin,a_helix);
6539 myDotsHelixFitter.setInitialHelix(aHelix);
6540 int q = helixPar[2]>0? 1:-1;
6541 double pxy = aHelix.pt();
6542 double px = aHelix.momentum(0).x();
6543 double py = aHelix.momentum(0).y();
6544 double pz = aHelix.momentum(0).z();
6545 double p = aHelix.momentum(0).mag();
6546 double theta = aHelix.direction(0).theta();
6547 double phi = aHelix.direction(0).phi();
6548 HepPoint3D poca = aHelix.x(0);
6549 HepPoint3D pivot = aHelix.pivot();
6550 double r = poca.perp();
6551 HepSymMatrix Ea = aHelix.Ea();
6552 //cout<<"Ea="<<Ea<<endl;
6553 double errorMat[15];
6554 int k = 0;
6555 for (int ie = 0 ; ie < 5 ; ie ++){
6556 for (int je = ie ; je < 5 ; je ++){
6557 errorMat[k] = Ea[ie][je];
6558 k++;
6559 }
6560 }
6561 double chisq = aTrkCandi.chi2;
6562 recMdcTrack->setCharge(q);
6563 recMdcTrack->setPxy(pxy);
6564 recMdcTrack->setPx(px);
6565 recMdcTrack->setPy(py);
6566 recMdcTrack->setPz(pz);
6567 recMdcTrack->setP(p);
6568 recMdcTrack->setTheta(theta);
6569 recMdcTrack->setPhi(phi);
6570 recMdcTrack->setPoca(poca);
6571 recMdcTrack->setX(poca.x());//poca
6572 recMdcTrack->setY(poca.y());
6573 recMdcTrack->setZ(poca.z());
6574 recMdcTrack->setR(sqrt(poca.x()*poca.x() + poca.y()*poca.y()));
6575 recMdcTrack->setPivot(origin);
6576 recMdcTrack->setVX0(0.);//pivot
6577 recMdcTrack->setVY0(0.);
6578 recMdcTrack->setVZ0(0.);
6579 recMdcTrack->setError(errorMat);
6580 recMdcTrack->setError(Ea);
6581 recMdcTrack->setChi2(chisq);
6582 recMdcTrack->setStat(tkStat);
6583
6584 int maxLayerId = -1;
6585 int minLayerId = 43;
6586 double fiTerm = 0.;
6587 double fltLen = -0.00001;
6588 int layerMaxFltLen=-1;
6589
6590 fillVecCgemClu(aTrkCandi);
6591 ClusterRefVec clusterRefVec;
6592 map<int,int> clusterFitStat;
6593 myIterClu=myIterCgemClusterBegin;
6594 for(; myIterClu!=myIterCgemClusterEnd; myIterClu++)
6595 {
6596 int flag = (*myIterClu)->getflag();
6597 if(flag!=2) continue;// skip 1D clusters
6598 int layer=(*myIterClu)->getlayerid();
6599 int sheet=(*myIterClu)->getsheetid();
6600 int idXClu = (*myIterClu)->getclusterflagb();
6601 bool matchX=false;
6602 vector<int>::iterator iter=myVecCgemXCluIdx[layer][sheet].begin();
6603 int i_cluster=0;
6604 for(; iter!=myVecCgemXCluIdx[layer][sheet].end(); iter++, i_cluster++)
6605 //if((*iter)==idXClu && fabs(myVecCgemXCluChi[layer][sheet][i_cluster]+9999)>1e-10)
6606 if((*iter)==idXClu)
6607 matchX=true;
6608 if(!matchX) continue;
6609 int idVClu = (*myIterClu)->getclusterflage();
6610 bool matchV=false;
6611 iter=myVecCgemVCluIdx[layer][sheet].begin();
6612 for(; iter!=myVecCgemVCluIdx[layer][sheet].end(); iter++)
6613 if((*iter)==idVClu) matchV=true;
6614 if(matchV)
6615 {
6616 const RecCgemCluster* recCgemCluster = (*myIterClu);
6617 int clusterid = recCgemCluster->getclusterid();
6618 clusterRefVec.push_back(recCgemCluster);
6619 clusterFitStat[clusterid] = 1;
6620 if(maxLayerId<layer)
6621 {
6622 maxLayerId=layer;
6623 }
6624 }
6625 }
6626
6627 // --- MDC hits
6628 int hitId = 0;
6629 HitRefVec hitRefVec;
6630 vector<RecMdcHit> aRecMdcHitVec = aTrkCandi.RecMdcHitVec;
6631 vector<RecMdcHit>::iterator iter_recMdcHit = aRecMdcHitVec.begin();
6632 for(; iter_recMdcHit!=aRecMdcHitVec.end(); iter_recMdcHit++)
6633 {
6634 if(iter_recMdcHit->getChisqAdd()>myMdcHitChi2Cut) // skip hit with chi2>myMdcHitChi2Cut
6635 continue;
6636
6637 RecMdcHit* recMdcHit = new RecMdcHit(*iter_recMdcHit);
6638 recMdcHit->setId(hitId);
6639 recMdcHit->setTrkId(trackId);
6640 recMdcHit->setStat(1);
6641 myRecMdcHitCol->push_back(recMdcHit);
6642 SmartRef<RecMdcHit> refHit(recMdcHit);
6643 hitRefVec.push_back(refHit);
6644
6645 Identifier mdcid = recMdcHit->getMdcId();
6646 int layer = MdcID::layer(mdcid);
6647 int wire = MdcID::wire(mdcid);
6648 if(layer>maxLayerId)
6649 {
6650 maxLayerId = layer;
6651 }
6652 if(layer<minLayerId)
6653 {
6654 minLayerId = layer;
6655 }
6656 if(fltLen<recMdcHit->getFltLen()) {
6657 fltLen=recMdcHit->getFltLen();
6658 layerMaxFltLen=layer;
6659 }
6660 hitId++;
6661 }
6662
6663 // --- phi term (phi for the outmost hit/cluster)
6664 if(maxLayerId>=0&&maxLayerId<3) {
6665 double rmax=myDotsHelixFitter.getRmidGapCgem(maxLayerId);
6666 fltLen=aHelix.flightLength(rmax);
6667 }
6668 if(fltLen>0) fiTerm=-fltLen*sin(theta)/aHelix.radius();
6669 else {
6670 cout<<"fltLen<0!: maxLayerId="<<maxLayerId<<", n_cluster="<<clusterRefVec.size()<<endl;
6671 cout<<"myVecCgem1DCluster.size="<<myVecCgem1DCluster.size()<<endl;
6672 return false;
6673 }
6674 recMdcTrack->setFiTerm(fiTerm);
6675
6676 // --- setN* functions called in setVec* functions
6677 recMdcTrack->setVecHits(hitRefVec);
6678 std::sort(clusterRefVec.begin(),clusterRefVec.end(),sortCluster);
6679 recMdcTrack->setVecClusters(clusterRefVec,clusterFitStat);
6680
6681 // --- put a new track into RecMdcTrackCol
6682 myRecMdcTrackCol->push_back(recMdcTrack);
6683
6684 return true;
6685}
6686
6687int DotsConnection::saveGoodTrkCandi()
6688{
6689 int i_candi=0;
6690 int nSaved=0;
6691 vector<struct trkCandi>::iterator iter_trkCandi = myVecTrkCandidates.begin();
6692 for(; iter_trkCandi!=myVecTrkCandidates.end(); iter_trkCandi++, i_candi++)
6693 {
6694 if((*iter_trkCandi).isGood!=1) continue;
6695 //cout<<"track candidate "<<i_candi<<" is to be saved "<<endl;
6696 if(saveARecMdcTrack(*iter_trkCandi)) nSaved++;
6697 }
6698 return nSaved;
6699}
6700
6701vector<const MdcDigi*> DotsConnection::getMdcDigiVec(cell& aCell)
6702{
6703 vector<const MdcDigi*> aMdcDigiVec;
6704 //set<int>::iterator it = aCell.set_dotIdx.begin();
6705 //for(; it != aCell.set_dotIdx.end(); it++)
6706 for(int i=0; i<NUMBER_OF_DOTS_PER_CELL; i++)
6707 {
6708 //aMdcDigiVec.push_back(myMapMdcDigi[*it]);
6709 aMdcDigiVec.push_back(myMapMdcDigi[aCell.dots[i]->id]);
6710 }
6711 return aMdcDigiVec;
6712}
6713
6715{
6716 int nShare=0;
6717
6718 //set<int>::iterator it_dot_a = a.set_dotIdx.begin();
6719 //set<int>::iterator it_dot_b = b.set_dotIdx.begin();
6720 //set<int>::iterator it_dot_b_lastMatch = it_dot_b;
6721 //for(; it_dot_a!=a.set_dotIdx.end(); it_dot_a++) {
6722 // it_dot_b = it_dot_b_lastMatch;
6723 // for(; it_dot_b!=b.set_dotIdx.end(); it_dot_b++) {
6724 // if(*it_dot_a == *it_dot_b) {
6725 // nShare++;
6726 // it_dot_b_lastMatch=it_dot_b;
6727 // it_dot_b_lastMatch++;
6728 // break;
6729 // }
6730 // }
6731 //}
6732
6733 for(int i=0; i<NUMBER_OF_DOTS_PER_CELL; i++) {
6734 int id_a=a.dots[i]->id;
6735 for(int j=0; j<NUMBER_OF_DOTS_PER_CELL; j++) {
6736 int id_b=b.dots[j]->id;
6737 if(id_a==id_b) {
6738 nShare++;
6739 break;
6740 }
6741 }
6742 }
6743
6744 return nShare;
6745}
6746
6748{
6749 return numSharedDots(a, b)==NUMBER_OF_DOTS_PER_CELL ;
6750}
6751
6753{
6754 bool forward=false;
6755 //set<int>::iterator it_dot_a = a.set_dotIdx.begin();
6756 //set<int>::iterator it_dot_b = b.set_dotIdx.begin();
6757 for(int i=0; i<NUMBER_OF_DOTS_PER_CELL; i++)
6758 {
6759 //if(*it_dot_a == *it_dot_b)
6760 if(a.dots[i]->id == b.dots[i]->id)
6761 {
6762 //it_dot_a++; it_dot_b++;
6763 continue;
6764 }
6765 //else if(*it_dot_a < *it_dot_b)
6766 else if(dotComp(a.dots[i], b.dots[i]))
6767 {
6768 //int layer=myMdcGeomSvc->Wire(*it_dot_a)->Layer();
6769 //if(layer==myMdcGeomSvc->Wire(*it_dot_b)->Layer())
6770 //{// same layer
6771 // int Cell_a=myMdcGeomSvc->Wire(*it_dot_a)->Cell();
6772 // if(Cell_a+1!=myMdcGeomSvc->Wire(*it_dot_b)->Cell()) break;// at the boundary
6773 //}
6774 forward=true;
6775 break;
6776 }
6777 }
6778 return forward;
6779}
6780
6782{
6783 bool twoDotsShare=false;
6784
6785 //if(a.dots[0]->id==b.dots[1]->id) {
6786 // if(a.dots[1]->id==b.dots[0]->id && a.dots[2]->id!=b.dots[2]->id) twoDotsShare=true;
6787 // else if(a.dots[2]->id==b.dots[0]->id && a.dots[1]->id!=b.dots[2]->id) twoDotsShare=true;
6788 //}
6789 //else if(a.dots[0]->id==b.dots[2]->id) {
6790 // if(a.dots[1]->id==b.dots[0]->id && a.dots[2]->id!=b.dots[1]->id) twoDotsShare=true;
6791 // else if(a.dots[2]->id==b.dots[0]->id && a.dots[1]->id!=b.dots[1]->id) twoDotsShare=true;
6792 //}
6793
6794 if(a.dots[0]->id!=b.dots[2]->id && ( (a.dots[1]->id==b.dots[0]->id&&a.dots[2]->id==b.dots[1]->id )||( a.dots[1]->id==b.dots[1]->id&&a.dots[2]->id==b.dots[0]->id)) ) twoDotsShare=true;
6795 else if(a.dots[2]->id!=b.dots[0]->id && ( (a.dots[0]->id==b.dots[1]->id&&a.dots[1]->id==b.dots[2]->id )||( a.dots[0]->id==b.dots[2]->id&&a.dots[1]->id==b.dots[1]->id)) ) twoDotsShare=true;
6796
6797 return twoDotsShare;
6798}
6799
6801{
6802 cout<<" cell "<<setw(5)<<aCell.id;
6803 //cout<<": (id, L, W) = ";
6804 cout<<": (L, W, id) = ";
6805 for(int i=0; i<NUMBER_OF_DOTS_PER_CELL; i++) {
6806 if(aCell.dots[i]->detector==dot::MDC) {
6807 int layer = myMdcGeomSvc->Wire(aCell.dots[i]->id)->Layer();
6808 int Cell = myMdcGeomSvc->Wire(aCell.dots[i]->id)->Cell();
6809 cout<<"("<<setw(3)<<layer<<","<<setw(3)<<Cell<<", "<<setw(5)<<aCell.dots[i]->id<<") ";
6810 }
6811 }
6812 cout<<endl;
6813}
6814
6815
6817{
6818 // --- get the set of shared dots
6819 int a_shared[NUMBER_OF_DOTS_PER_CELL]={0,0,0};
6820 int b_shared[NUMBER_OF_DOTS_PER_CELL]={0,0,0};
6821 int n_shared=0;
6822 set<int> comDots;
6823 vector<int> viDotShared_a;
6824 vector<int> viDotShared_b;
6825 //set<int>& dots_a = a.set_dotIdx;
6826 //set<int>& dots_b = b.set_dotIdx;
6827 //std::set_intersection(dots_a.begin(), dots_a.end(), dots_b.begin(), dots_b.end(),
6828 // std::inserter(comDots, comDots.begin()));
6829 for(int i=0; i<NUMBER_OF_DOTS_PER_CELL; i++) {
6830 int id_a=a.dots[i]->id;
6831 for(int j=0; j<NUMBER_OF_DOTS_PER_CELL; j++) {
6832 int id_b=b.dots[j]->id;
6833 if(id_a==id_b) {
6834 comDots.insert(id_a);
6835 viDotShared_a.push_back(i);
6836 viDotShared_b.push_back(j);
6837 //e.set_dotIdx.insert(id_a);
6838 e.dots.push_back(a.dots[i]);// fill the common hits as the 1st, 2ed hits
6839 a_shared[i]=1;
6840 b_shared[j]=1;
6841 n_shared++;
6842 }
6843 }
6844 }
6845 if(n_shared!=2) {
6846 cout<<setw(6)<<""<<"cannot make edge due to n_shared="<<n_shared<<endl;
6847 return false;
6848 }
6849
6850 // --- get the indices of shared dots
6851 //set<int>::iterator it_dots_a=dots_a.begin();
6852 //for(int i=0; it_dots_a!=dots_a.end(); it_dots_a++, i++) if(comDots.find(*it_dots_a)!=comDots.end()) viDotShared_a.push_back(i);
6853 //for(int i=0; i<NUMBER_OF_DOTS_PER_CELL; i++) if(comDots.find(a.dots[i]->id)!=comDots.end()) viDotShared_a.push_back(i);
6854
6855 //for(int i=0; i<NUMBER_OF_DOTS_PER_CELL; i++) if(comDots.find(b.dots[i]->id)!=comDots.end()) viDotShared_b.push_back(i);
6856 //set<int>::iterator it_dots_b=dots_b.begin();
6857 //for(int i=0; it_dots_b!=dots_b.end(); it_dots_b++, i++) if(comDots.find(*it_dots_b)!=comDots.end()) viDotShared_b.push_back(i);
6858
6859 // --- compare rho, theta
6860 double diff_theta_min=9999.;
6861 double diff_rho_min =9999.;
6862 //vector<Line>::iterator itL_a_match = a.vecFittedLine.end();
6863 //vector<Line>::iterator itL_b_match = b.vecFittedLine.end();
6864 int iL_a_match(-1), iL_b_match(-1);
6865 int nReverse_b_match=0;
6866 vector<Line>::iterator itL_a=a.vecFittedLine.begin();
6867 for(int iL_a=0; itL_a!=a.vecFittedLine.end(); itL_a++, iL_a++) {
6868 double rho_a = (*itL_a).rho;
6869 double theta_a = (*itL_a).theta;
6870 vector<Line>::iterator itL_b=b.vecFittedLine.begin();
6871 for(int iL_b=0; itL_b!=b.vecFittedLine.end(); itL_b++, iL_b++) {
6872 double rho_b = (*itL_b).rho;
6873 double theta_b = (*itL_b).theta;
6874 int nReverse=0;
6875 while( fabs(theta_b-acos(-1.)-theta_a) < fabs(theta_b-theta_a) ) {
6876 theta_b-=acos(-1.);
6877 rho_b*=-1;
6878 nReverse++;
6879 }
6880 while( fabs(theta_b+acos(-1.)-theta_a) < fabs(theta_b-theta_a) ) {
6881 theta_b+=acos(-1.);
6882 rho_b*=-1;
6883 nReverse++;
6884 }
6885 if(diff_theta_min>fabs(theta_b-theta_a)) {
6886 diff_theta_min=fabs(theta_b-theta_a);
6887 diff_rho_min = fabs(rho_b-rho_a);
6888 //itL_a_match=itL_a; itL_b_match=itL_b;
6889 iL_a_match=iL_a; iL_b_match=iL_b;
6890 nReverse_b_match=nReverse;
6891 }
6892 }// loop lines of cell b
6893 }// loop lines of cell a
6894 if(diff_theta_min>0.1) // || diff_rho_min>1.0)
6895 {
6896 //cout<<"theta or rho unmatched!"<<endl;
6897 cout<<setw(6)<<""<<"theta unmatched!"<<endl;
6898 return false;
6899 }
6900 else cout<<setw(6)<<""<<"theta matched!"<<endl;
6901
6902 // --- compare LR of shared dots
6903 vector<int>& LR_a=a.vecFittedLine.at(iL_a_match).LR;
6904 vector<int>& LR_b=b.vecFittedLine.at(iL_b_match).LR;
6905 int nShared=viDotShared_a.size();
6906 cout<<setw(6)<<""<<"shared LR in a: (";
6907 for(int i=0; i<nShared; i++) cout<<setw(3)<<LR_a.at(viDotShared_a.at(i));
6908 cout<<")"<<endl;
6909 int reverse=1; if(nReverse_b_match%2!=0) {reverse=-1; cout<<setw(6)<<""<<"LR reversed for b"<<endl;}
6910 cout<<setw(6)<<""<<"shared LR in b: (";
6911 for(int i=0; i<nShared; i++) cout<<setw(3)<<reverse*LR_b.at(viDotShared_b.at(i));
6912 cout<<")"<<endl;
6913 bool LR_match=true;
6914 const double shortDD=0.16;// to be optimized
6915 for(int i=0; i<nShared; i++) {
6916 if( reverse*LR_b.at(viDotShared_b.at(i)) != LR_a.at(viDotShared_a.at(i)) ) {
6917 if(myMapMdcDigiDd[b.dots[viDotShared_b.at(i)]->id]<shortDD) continue;// to be optimized
6918 LR_match=false;
6919 break;
6920 }
6921 }
6922 if(LR_match) cout<<setw(6)<<""<<"LR matched"<<endl;
6923 else {
6924 cout<<setw(6)<<""<<"LR unmatched"<<endl;
6925 return false;
6926 }
6927
6928 // --- fill mapWidxLR and uncommon dots of the edge
6929 map<int, int> mapWidxLR;
6930 vector<int>::iterator it =LR_a.begin();
6931 int idot_a_uncom=-1;
6932 for(int i=0; i<NUMBER_OF_DOTS_PER_CELL; i++, it++) {
6933 mapWidxLR[a.dots[i]->id]=*it;
6934 if(a_shared[i]==0)
6935 {
6936 e.dots.push_back(a.dots[i]);// fill the uncommon hit of cell a as the 3rd hit
6937 idot_a_uncom=i;
6938 }
6939 }
6940 it =LR_b.begin();
6941 int idot_b_uncom=-1;
6942 for(int i=0; i<NUMBER_OF_DOTS_PER_CELL; i++, it++) {
6943 mapWidxLR[b.dots[i]->id]=(*it)*reverse;
6944 if(b_shared[i]==0)
6945 {
6946 e.dots.push_back(b.dots[i]);// fill the uncommon hit of cell b as the 4th hit
6947 idot_b_uncom=i;
6948 }
6949 }
6950
6951 // --- get all dots
6952 //std::set_union(dots_a.begin(), dots_a.end(), dots_b.begin(), dots_b.end(),
6953 // std::inserter(e.set_dotIdx, e.set_dotIdx.begin()) );
6954 //set<int>::iterator it_dot = e.set_dotIdx.begin();
6955 //for(; it_dot!=e.set_dotIdx.end(); it_dot++) {
6956 // int idx = *it_dot;
6957 // if(comDots.find(idx)!=comDots.end()) e.vDotStatus.push_back(edge::Common);
6958 // else {
6959 // if(dots_a.find(idx)!=dots_a.end()) e.vDotStatus.push_back(edge::Prev);
6960 // else if(dots_b.find(idx)!=dots_b.end()) e.vDotStatus.push_back(edge::Next);
6961 // }
6962 //}
6963 vector<int> LR_ini;
6964 vector<dot*>::iterator it_dot=e.dots.begin();
6965 for(; it_dot!=e.dots.end(); it_dot++) {
6966 int idx = (*it_dot)->id;
6967 int LR_i=0;
6968 if(myMapMdcDigiDd[idx]>=shortDD) LR_i=mapWidxLR[idx];
6969 LR_ini.push_back(LR_i);
6970 }
6971
6972 // --- fit
6973 //double rho_ini =0.5*(a.vecFittedLine.at(iL_a_match).rho +b.vecFittedLine.at(iL_b_match).rho);
6974 //double theta_ini=0.5*(a.vecFittedLine.at(iL_a_match).theta+b.vecFittedLine.at(iL_b_match).theta);
6975 double rho_ini = a.vecFittedLine.at(iL_a_match).rho ;
6976 double theta_ini = a.vecFittedLine.at(iL_a_match).theta;
6977 vector<double> vRho; vector<double> vTheta; vector<vector<int> > vvLR; vector<vector<double> > vvS;
6978 vector<const MdcDigi*> aVecMdcDigi=getMdcDigiVec(e);
6979 bool hasGdLine = LineFit_TLS(aVecMdcDigi, vRho,vTheta,vvLR,vvS,true,rho_ini,theta_ini,LR_ini);
6980 if(!hasGdLine) {
6981 cout<<setw(6)<<""<<" no good line fit for the edge"<<endl;
6982 return false;
6983 }
6984
6985 // --- make an edge
6986 e.twoCells.first=a.id;
6987 e.twoCells.second=b.id;
6988 e.twoLines.first=iL_a_match;
6989 e.twoLines.second=iL_b_match;
6990 int n_rho = vRho.size();
6991 cout<<setw(6)<<""<<"an good edge with "<<n_rho<<" fitted lines"<<endl;
6992 for(int i_line=0; i_line<n_rho; i_line++) {
6993 Line aLine;
6994 aLine.rho=vRho[i_line];
6995 aLine.theta=vTheta[i_line];
6996 aLine.LR=vvLR[i_line];
6997 aLine.S=vvS[i_line];
6998 // --- save the good fitted line to the edge
6999 if(makeOrder(aLine))
7000 {
7001 if(aLine.order.front()>1&&aLine.order.back()>1)
7002 {
7003 e.vecFittedLine.push_back(aLine);
7004 cout<<setw(6)<<""<<"good S order : ";
7005 for(int i=0; i<aLine.order.size(); i++) cout<<setw(2)<<aLine.order.at(i);
7006 cout<<endl;
7007 if(aLine.order.front()==3) { // uncommon hit of cell b
7008 e.twoCells.first=b.id;
7009 e.twoCells.second=a.id;
7010 e.twoLines.first=iL_b_match;
7011 e.twoLines.second=iL_a_match;
7012 }
7013 else if(aLine.order.front()!=2) {// uncommon hit of cell a
7014 cout<<setw(6)<<""<<" something wrong about the dots' order"<<endl;
7015 }
7016 }
7017 }
7018 }// loop fitted lines
7019
7020 if(e.vecFittedLine.size()>0) return true;
7021 else return false;
7022}
7023
7024vector<const MdcDigi*> DotsConnection::getMdcDigiVec(edge& aEdge)
7025{
7026 vector<const MdcDigi*> aMdcDigiVec;
7027 //set<int>::iterator it = aEdge.set_dotIdx.begin(); for(; it != aEdge.set_dotIdx.end(); it++)
7028 vector<dot*>::iterator it_dot=aEdge.dots.begin();
7029 for(; it_dot!=aEdge.dots.end(); it_dot++)
7030 {
7031 aMdcDigiVec.push_back(myMapMdcDigi[(*it_dot)->id]);
7032 }
7033 return aMdcDigiVec;
7034}
7035
7036vector<vector<int> > DotsConnection::CellAutomaton(vector<int>& v_cellIdx, vector<cell>& v_cell, vector<edge>& v_edge)
7037{
7038 bool debug=false; debug=true;
7039
7040 vector<int> v_rootCellIdx;
7041
7042 vector<vector<int> > v_path;
7043 if(v_cellIdx.size()==0) return v_path;
7044
7045 // --- initialize
7046 for(vector<int>::iterator it_cellIdx=v_cellIdx.begin(); it_cellIdx!=v_cellIdx.end(); it_cellIdx++) {
7047 cell& aCell=v_cell.at(*it_cellIdx);
7048 aCell.state=-1;
7049 aCell.color=0;
7050 if(aCell.set_inEdge.empty()) v_rootCellIdx.push_back(*it_cellIdx);
7051 }
7052 myNCycle=0;
7053 myCellMaxState.clear();
7054
7055 // --- state calculation with depth-first-visit
7056 for(vector<int>::iterator it_cellIdx=v_cellIdx.begin(); it_cellIdx!=v_cellIdx.end(); it_cellIdx++) {
7057 cell& aCell=v_cell.at(*it_cellIdx);
7058 //if(aCell.color==2) continue;
7059 if(aCell.color==0) {
7060 if(debug) cout<<setw(6)<<""<<"== start state calculation with cell "<<aCell.id<<endl;
7061 stateAutomaton(aCell, v_cell, v_edge);
7062 }
7063 }
7064 if(debug) cout<<setw(6)<<""<<"The graph has a cycle? "<<myNCycle<<endl;
7065 int maxState = 0;
7066 if(myCellMaxState.size()) {
7067 maxState = v_cell.at(myCellMaxState.at(0)).state;
7068 if(debug) cout<<setw(6)<<""<<"maximum state: "<<v_cell.at(myCellMaxState.at(0)).state<<", "<<myCellMaxState.size()<<" cells"<<endl;
7069 }
7070
7071 // --- form track segments (fit to circles)
7072 for(vector<int>::iterator it_cell_maxStat=myCellMaxState.begin(); it_cell_maxStat!=myCellMaxState.end(); it_cell_maxStat++)
7073 //for(int iRootCell=0; iRootCell<=v_rootCellIdx.size(); iRootCell++)
7074 {
7075 if(debug) cout<<setw(6)<<""<<"~~~~> to find a path: "<<endl;
7076 cell& aRootCell = v_cell.at(*it_cell_maxStat);
7077 //cell& aRootCell = v_cell.at(v_rootCellIdx.at(iRootCell));
7078
7079 map<int, pair<double,double> > setWireHitPos;
7080 map<int, int> setWireEntry;
7081 if(aRootCell.state==1) {
7082 for(vector<Line>::iterator it_line=aRootCell.vecFittedLine.begin(); it_line!=aRootCell.vecFittedLine.end(); it_line++) {
7083 double rho=(*it_line).rho;
7084 double theta=(*it_line).theta;
7085 vector<double>& vS=(*it_line).S;
7086 for(int i=0; i<NUMBER_OF_DOTS_PER_CELL; i++) {
7087 int wireIdx = aRootCell.dots[i]->id;
7088 double s=vS.at(i);
7089 double x, y;
7090 getXY(rho,theta,s,x,y);
7091 map<int, int>::iterator it_entry; // setWireEntry;
7092 it_entry = setWireEntry.find(wireIdx);
7093 if(it_entry!=setWireEntry.end()) {
7094 it_entry->second++;
7095 map<int, pair<double,double> >::iterator it_pos=setWireHitPos.find(wireIdx);
7096 it_pos->second.first+=x;
7097 it_pos->second.second+=y;
7098 }
7099 else {
7100 setWireEntry[wireIdx]=1;
7101 pair<double,double> xy(x,y);
7102 setWireHitPos[wireIdx]=xy;
7103 }
7104 }
7105 }
7106 }
7107 else nextCellFinding(aRootCell, v_cell, v_edge, setWireHitPos, setWireEntry);
7108 cout<<setw(6)<<""<<"a path found with "<<setWireEntry.size()<<" dots: "; //<<endl;
7109 vector<int> aTrkPath;
7110 //vector< pair<double, double> > pos_hits;
7111 //vector<double> phi_LR;
7112 for(map<int, int>::iterator it_entry=setWireEntry.begin(); it_entry!=setWireEntry.end(); it_entry++) {
7113 int wireIdx = it_entry->first;
7114 aTrkPath.push_back(wireIdx);
7115 int layer = myMdcGeomSvc->Wire(wireIdx)->Layer();
7116 int wire = myMdcGeomSvc->Wire(wireIdx)->Cell();
7117 cout<<"("<<layer<<","<<wire<<") ";
7118 //map<int, pair<double,double> >::iterator it_pos=setWireHitPos.find(wireIdx);
7119 //it_pos->second.first/=it_entry->second;
7120 //it_pos->second.second/=it_entry->second;
7121 ////cout<<"hit ("<<layer<<","<<wire<<"), filled "<<it_entry->second<<" times, mean x,y="<<it_pos->second.first<<","<<it_pos->second.second<<endl;
7122 ////pos_hits.push_back(it_pos->second);
7123 //double phiLR=atan2(it_pos->second.second-0.1*myRLayer[layer]*sin(myWirePhi[layer][wire]),
7124 // it_pos->second.first -0.1*myRLayer[layer]*cos(myWirePhi[layer][wire]));
7125 //if(myMapMdcDigiDd[wireIdx]<0.15) phiLR=-9999.;
7126 //phi_LR.push_back(phiLR);
7127 }
7128 cout<<endl;
7129 v_path.push_back(aTrkPath);
7130 //vector<double> par_Taubin = myDotsHelixFitter.CircleFitByTaubin(pos_hits);
7131 //vector<double> par_circle = myDotsHelixFitter.circleParConversion(par_Taubin);
7132 //cout<<"fitted circle: dr="<<par_circle.at(0)<<", phi0="<<par_circle.at(1)<<", kappa="<<par_circle.at(2)<<endl;
7133 //struct trkCandi oneTrkCandi=getTrkCandi(aTrkPath);
7134 //int nDropHits;
7135 //cout<<"the path fitted to circle with initial LR : "<<endl;
7136 // ---------------------------- trkCandi, chiCut, useIniHelix,hitSel,setHitFitFlag, layerMin, layerMax, use_additional_points, usePhiAmbi, vPhiAmb
7137 //nDropHits = circleFitTaubin(oneTrkCandi, 5, false, 2, true, -1, 50, false, true, phi_LR);
7138 //nDropHits = circleFitTaubin(oneTrkCandi, 5, false, 2, true);
7139 }
7140
7141 return v_path;
7142}// CellAutomaton
7143
7144void DotsConnection::stateAutomaton(cell& aCell, vector<cell>& v_cell, vector<edge>& v_edge)
7145{
7146 bool debug=false; debug=true;
7147 aCell.color=1;
7148 if(debug) {
7149 cout<<"[ discover"; print(aCell);
7150 cout<<setw(5)<<""<<"loop next cells:"<<endl;
7151 }
7152 set<int>& outEdges = aCell.set_outEdge;
7153 int state_max=0;
7154 for(set<int>::iterator it_edgeIdx=outEdges.begin(); it_edgeIdx!=outEdges.end(); it_edgeIdx++) {
7155 cell& aNextCell = v_cell.at(v_edge.at(*it_edgeIdx).twoCells.second);
7156 if(debug) cout<<setw(5)<<""<<"cell "<<aNextCell.id<<endl;
7157 if(aNextCell.color==0) stateAutomaton(aNextCell, v_cell, v_edge);
7158 else if(aNextCell.color==1) myNCycle++;
7159 if(aNextCell.state>state_max) state_max=aNextCell.state;
7160 }
7161 aCell.state=1;
7162 aCell.state+=state_max;
7163 aCell.color=2;
7164
7165 //if(!(myCellMaxState.size()>0&&aCell.state<v_cell.at(myCellMaxState.at(0)).state)) {
7166 // myCellMaxState.push_back(aCell.id);
7167 //}
7168 if(myCellMaxState.size()==0) myCellMaxState.push_back(aCell.id);
7169 else if(v_cell.at(myCellMaxState.at(0)).state==aCell.state) myCellMaxState.push_back(aCell.id);
7170 else if(v_cell.at(myCellMaxState.at(0)).state<aCell.state) {
7171 myCellMaxState.clear();
7172 myCellMaxState.push_back(aCell.id);
7173 }
7174 if(debug) {
7175 cout<<"finish cell "<<aCell.id<<" with state "<<aCell.state;//<<endl;
7176 if(myCellMaxState.size())
7177 cout<<" maximum state: "<<v_cell.at(myCellMaxState.at(0)).state<<", "<<myCellMaxState.size()<<" cells"<<endl;
7178 cout<<"]"<<endl;
7179 }
7180}
7181
7182void DotsConnection::nextCellFinding(cell& aCell, vector<cell>& v_cell, vector<edge>& v_edge, map<int, pair<double,double> >& setWireHitPos, map<int, int>& setWireEntry)
7183{
7184 bool debug=false; debug=true;
7185
7186 set<int>& outEdges = aCell.set_outEdge;
7187 if(debug) {
7188 cout<<setw(5)<<""<<"cell "<<aCell.id<<", state="<<aCell.state;
7189 if(outEdges.size()) cout<<", to fine the next cell";
7190 else cout<<", no next cell"<<endl;
7191 }
7192 for(set<int>::iterator it_edgeIdx=outEdges.begin(); it_edgeIdx!=outEdges.end(); it_edgeIdx++) {
7193 edge& aEdge = v_edge.at(*it_edgeIdx);
7194 for(vector<Line>::iterator it_line=aEdge.vecFittedLine.begin(); it_line!=aEdge.vecFittedLine.end(); it_line++) {
7195 double rho=(*it_line).rho;
7196 double theta=(*it_line).theta;
7197 vector<double>& vS=(*it_line).S;
7198 vector<dot*>::iterator it_dot=aEdge.dots.begin();
7199 for(int i=0; it_dot!=aEdge.dots.end(); it_dot++, i++) {
7200 int wireIdx = (*it_dot)->id;
7201 double s=vS.at(i);
7202 double x, y;
7203 getXY(rho,theta,s,x,y);
7204 map<int, int>::iterator it_entry; // setWireEntry;
7205 it_entry = setWireEntry.find(wireIdx);
7206 if(it_entry!=setWireEntry.end()) {
7207 it_entry->second++;
7208 map<int, pair<double,double> >::iterator it_pos=setWireHitPos.find(wireIdx);
7209 it_pos->second.first+=x;
7210 it_pos->second.second+=y;
7211 }
7212 else {
7213 setWireEntry[wireIdx]=1;
7214 pair<double,double> xy(x,y);
7215 setWireHitPos[wireIdx]=xy;
7216 }
7217 }
7218 }
7219
7220 cell& aNextCell = v_cell.at(v_edge.at(*it_edgeIdx).twoCells.second);
7221 //cout<<setw(5)<<""<<"cell "<<aNextCell.id<<endl;
7222 if((aNextCell.state+1)==aCell.state) {// find the next cell
7223 if(debug) cout<<", cell "<<aNextCell.id<<" found, state = "<<aNextCell.state<<endl;
7224 nextCellFinding(aNextCell, v_cell, v_edge, setWireHitPos, setWireEntry);
7225 break;
7226 }
7227 }// loop out edges
7228}// nextCellFinding
7229
7230
7231void DotsConnection::makeDotCellEdge(vector<int>& vecWireIdx)
7232{
7233 bool debug=false; //debug=true;
7234 myMapDots.clear();
7235 myVecCells.clear();
7236 myVecGoodCellIdx.clear();
7237 myVecEdges.clear();
7238
7239 // --- make dots and put into myMapDots
7240 int nHit=vecWireIdx.size();
7241 for(int i=0; i<nHit; i++) {
7242 int wireIdx=vecWireIdx.at(i);
7243 dot aDot;
7244 aDot.detector = dot::MDC;
7245 aDot.digi.mdcDigi=myMapMdcDigi[wireIdx];
7246 aDot.id=wireIdx;
7247 aDot.cluId=-1;
7248 myMapDots[wireIdx]=aDot;
7249 }
7250
7251 // --- make Cells, fill myVecCells, myVecGoodCellIdx, associate cells to wireMids
7252 map<int, dot>::iterator it_mapDots = myMapDots.begin();
7253 for(; it_mapDots!=myMapDots.end(); it_mapDots++)
7254 {
7255 int wireIdx=it_mapDots->first;
7256 int layer= myMdcGeomSvc->Wire(wireIdx)->Layer(); //myWireFlag[layer]
7257 int Cell = myMdcGeomSvc->Wire(wireIdx)->Cell();
7258
7259 //vector<int> vec_neib = myMdcDigiGroup[wireIdx].GetNeiborHits();// get all neighbours, but causes cell duplication
7260 vector<int> vec_neib = myMdcDigiGroup[wireIdx].GetNeiborHits(1);// get all neighbours and nbs nb, but causes cell duplication
7261 for(vector<int>::iterator it_nb1=vec_neib.begin(); it_nb1!=vec_neib.end(); it_nb1++)
7262 {
7263 // --- get a neighbour
7264 int wireIdx1=*it_nb1;
7265 if(myMapDots.find(wireIdx1)==myMapDots.end()) continue;// good dot
7266 int layer1= myMdcGeomSvc->Wire(wireIdx1)->Layer();
7267 if(myWireFlag[layer1]!=myWireFlag[layer]) continue;// same stereo angle
7268 int Cell1 = myMdcGeomSvc->Wire(wireIdx1)->Cell();
7269
7270 // --- get another neighbour
7271 vector<int>::iterator it_nb2=it_nb1; it_nb2++;
7272 while(true) {// loops
7273 if(it_nb2==vec_neib.end()) break; // end of loops
7274 int wireIdx2=*it_nb2;
7275 if(myMapDots.find(wireIdx2)==myMapDots.end()) {it_nb2++; continue;}// good dot
7276 int layer2= myMdcGeomSvc->Wire(wireIdx2)->Layer();
7277 if(myWireFlag[layer2]!=myWireFlag[layer]) {it_nb2++; continue;}// same stereo angle
7278 int Cell2 = myMdcGeomSvc->Wire(wireIdx2)->Cell();
7279 if(debug) cout<<" === try cell (id, L, W): "
7280 <<"("<<setw(5)<<wireIdx1<<","<<setw(3)<<layer1<<","<<setw(3)<<Cell1<<") "
7281 <<"("<<setw(5)<<wireIdx<<","<<setw(3)<<layer<<","<<setw(3)<<Cell<<") "
7282 <<"("<<setw(5)<<wireIdx2<<","<<setw(3)<<layer2<<","<<setw(3)<<Cell2<<") "
7283 <<endl;
7284 // --- create a cell
7285 cell aCell;
7286 aCell.dots[0]=&(myMapDots[wireIdx1]);
7287 aCell.dots[1]=&(myMapDots[wireIdx]);
7288 aCell.dots[2]=&(myMapDots[wireIdx2]);
7289 // --- check if the cell has already exist
7290 int wireMid = aCell.dots[1]->id;// wire index of the middle hit
7291 int nCell_wireMid = myMapDots[wireMid].vecCellIdx.size();
7292 bool cellExist=false;
7293 if(debug) cout<<" wireMid="<<wireMid<<" with "<<nCell_wireMid<<" cells"<<endl;
7294 for(int iCell=0; iCell<nCell_wireMid; iCell++) {
7295 if(debug) cout<<" i-cell "<<iCell<<endl;
7296 if(sameCell(aCell, myVecCells.at(myMapDots[wireMid].vecCellIdx[iCell]))) { cellExist=true; break; }
7297 }
7298 if(cellExist) {
7299 if(debug) cout<<" the cell exists"<<endl;
7300 it_nb2++; continue;
7301 }// drop a duplicated cell
7302 else if(debug) cout<<" the cell is new"<<endl;
7303 // --- a new cell found
7304 aCell.id=myVecCells.size();
7305 myMapDots.find(wireMid)->second.vecCellIdx.push_back(myVecCells.size());// associate the cell to wireMid
7306 myVecCells.push_back(aCell);
7307 myVecCells.back().idInGood=-1;
7308 // --- fit the cell
7309 vector<const MdcDigi*> aVecMdcDigi=getMdcDigiVec(aCell);
7310 vector<double> vRho; vector<double> vTheta; vector<vector<int> > vvLR; vector<vector<double> > vvS;
7311 bool hasGdLine = LineFit_TLS(aVecMdcDigi, vRho,vTheta,vvLR,vvS);
7312 if(hasGdLine) {
7313 int n_rho = vRho.size();
7314 if(debug) cout<<" the cell is good with N_lines="<<setw(2)<<n_rho<<endl;
7315 for(int i_line=0; i_line<n_rho; i_line++) {
7316 Line aLine;
7317 aLine.rho=vRho[i_line];
7318 aLine.theta=vTheta[i_line];
7319 aLine.LR=vvLR[i_line];
7320 aLine.S=vvS[i_line];
7321 if(debug) cout<<" S={"
7322 <<setw(5)<<aLine.S[0]<<" "
7323 <<setw(5)<<aLine.S[1]<<" "
7324 <<setw(5)<<aLine.S[2]<<"}"
7325 <<endl;
7326 // --- only keep the line fit if the middle hit has a middle S
7327 if(aLine.S[0]<aLine.S[1]&&aLine.S[2]<aLine.S[1]) {
7328 if(debug) cout<<" line "<<i_line<<" has a min S_middle"<<endl;
7329 continue;
7330 }
7331 if(aLine.S[0]>aLine.S[1]&&aLine.S[2]>aLine.S[1]) {
7332 if(debug) cout<<" line "<<i_line<<" has a max S_middle"<<endl;
7333 continue;
7334 }
7335 //if(aLine.S[0]*aLine.S[2]<0) {
7336 // if(debug) cout<<" line "<<i_line<<" has different sign for S"<<endl;
7337 // continue;
7338 //}
7339 if(fabs(aLine.S[0])<fabs(aLine.S[2])) {
7340 aLine.order.push_back(0);
7341 aLine.order.push_back(1);
7342 aLine.order.push_back(2);
7343 }
7344 else {
7345 aLine.order.push_back(2);
7346 aLine.order.push_back(1);
7347 aLine.order.push_back(0);
7348 }
7349 if(debug) cout<<" line "<<i_line<<" hits' order "<<aLine.order[0]<<" "<<aLine.order[1]<<" "<<aLine.order[2]<<endl;
7350
7351 // --- save the good fitted line to the cell
7352 myVecCells.back().vecFittedLine.push_back(aLine);
7353 }
7354 if(myVecCells.back().vecFittedLine.size()>0) {
7355 if(debug) cout<<"Good Cell "<<myVecGoodCellIdx.size()<<endl;
7356 cout<<setw(6)<<""<<"# Good Cell "<<myVecCells.back().id<<endl;
7357 myVecCells.back().idInGood=myVecGoodCellIdx.size();
7358 myMapDots[wireMid].vecGoodCellIdx[0].push_back(myVecGoodCellIdx.size());// associate the good cell to wireMid
7359 myVecGoodCellIdx.push_back(myVecCells.size()-1);// good cells
7360 }
7361 }
7362 it_nb2++;
7363 }// loop nb2
7364 }// loop nb1
7365 }// loop the map of dots to make cells
7366
7367 // --- make edges
7368 debug=true;
7369 vector<int>::iterator i1_goodCell = myVecGoodCellIdx.begin();
7370 vector<int>::iterator i2_goodCell;
7371 int iGdCell=0;
7372 for(; i1_goodCell!=myVecGoodCellIdx.end(); i1_goodCell++, iGdCell++) {// ---> loop good cells
7373 // --- set Cells' id, state, weight
7374 cell& cell_a = myVecCells.at(*i1_goodCell);
7375 for(int idot=0; idot<3; idot++) {// loop the two end-dots of the good cell (non-middle)
7376 int ivc=0;
7377 vector<int>& vCellIdx=myMapDots[cell_a.dots[idot]->id].vecGoodCellIdx[ivc];
7378 i2_goodCell=vCellIdx.begin();
7379 for(; i2_goodCell!=vCellIdx.end(); i2_goodCell++) {// loop another good cells
7380 int iGdCell2=*i2_goodCell;
7381 if(iGdCell2<iGdCell) continue;//reduce number of comparisons
7382 cell& cell_b = myVecCells.at(myVecGoodCellIdx.at(*i2_goodCell));
7383 if(debug) {
7384 cout<<" ===> compare two cells: "<<endl;
7385 cout<<setw(6)<<""<<"Good cell "<<iGdCell<<", "; print(cell_a);
7386 cout<<setw(6)<<""<<"Good cell "<<*i2_goodCell<<", "; print(cell_b);
7387 }
7388 //if( (cell_b.dots[0]->id==cell_a.dots[1]->id&&cell_b.dots[2]->id!=cell_a.dots[2-idot]->id) || (cell_b.dots[2]->id==cell_a.dots[1]->id&&cell_b.dots[0]->id!=cell_a.dots[2-idot]->id) )
7389 if(isNeighbour(cell_a,cell_b))
7390 {
7391 if(debug) cout<<setw(6)<<""<<"neighbour with two shared dots in the middle"<<endl;
7392 cell* cell_bkd;
7393 cell* cell_fwd;
7394 int idx_cell_fwd;
7395 if(cell_a.dots[1]->id>cell_b.dots[1]->id)
7396 {
7397 cell_bkd = &cell_b;
7398 cell_fwd = &cell_a;
7399 idx_cell_fwd = *i1_goodCell;
7400 if(debug) cout<<setw(6)<<""<<"two cells' order reversed"<<endl;
7401 }
7402 else {
7403 cell_bkd = &cell_a;
7404 cell_fwd = &cell_b;
7405 idx_cell_fwd = myVecGoodCellIdx.at(*i2_goodCell);
7406 }
7407 if(cell_bkd->set_fwdCell.find(idx_cell_fwd)==cell_bkd->set_fwdCell.end()) {// a new forward cell
7408 cell_bkd->set_fwdCell.insert(idx_cell_fwd);
7409 if(debug) cout<<setw(6)<<""<<"cell "<<cell_fwd->id<<" tagged as a new forward cell of cell "<<cell_bkd->id<<endl;
7410 edge aNewEdge;
7411 if(makeEdge(cell_a,cell_b,aNewEdge)) {
7412 cell& cell_first = myVecCells.at(aNewEdge.twoCells.first);
7413 cell_first.set_outEdge.insert(myVecEdges.size());
7414 cell& cell_second = myVecCells.at(aNewEdge.twoCells.second);
7415 cell_second.set_inEdge.insert(myVecEdges.size());
7416 aNewEdge.id=myVecEdges.size();
7417 myVecEdges.push_back(aNewEdge);
7418 if(debug) cout<<setw(6)<<""<<"a good out edge added to cell "<<aNewEdge.twoCells.first<<" and "<<aNewEdge.twoCells.second<<endl;
7419 }
7420 }
7421 }
7422 }
7423 }// loop the two end-dots of the good cell (non-middle)
7424 }// <--- loop good cells
7425
7426}// makeDotCellEdge(vector<int>& vecWireIdx)
7427
7428void DotsConnection::longestPathFromCA(vector<int>& vecWireIdx, vector<vector<int> >& v_path)
7429{
7430 makeDotCellEdge(vecWireIdx);
7431
7433
7434 int n_path = v_path.size();
7435 //for(int i_path=0; i_path<n_path; i_path++) {
7436 // vector<int>& aPath = v_path.at(i_path);
7437 //}
7438 if(n_path>0) {
7439 //path = v_path.at(0);
7440 //if(n_path>1)
7441 cout<<setw(6)<<""<<n_path<<" longest paths found"<<endl;
7442 }
7443 else cout<<setw(6)<<""<<"no path found"<<endl;
7444}
7445
7446void DotsConnection::longestPathFromCA(set<int>& setWireIdx, vector<vector<int> >& v_path)
7447{
7448 vector<int> vecWireIdx(setWireIdx.begin(),setWireIdx.end());
7449 longestPathFromCA(vecWireIdx, v_path);
7450}
double sin(const BesAngle a)
Definition BesAngle.h:210
double cos(const BesAngle a)
Definition BesAngle.h:213
double P(RecMdcKalTrack *trk)
bool sortCluster(const RecCgemCluster *clusterA, const RecCgemCluster *clusterB)
const Int_t n
Double_t phi2
Double_t x[10]
Double_t phi1
const DifPoint origin
bool global_show_this_event_detail
bool sortCluster(const RecCgemCluster *clusterA, const RecCgemCluster *clusterB)
double abs(const EvtComplex &c)
EvtStreamInputIterator< typename Generator::result_type > iter(Generator gen, int N=0)
XmlRpcServer s
****INTEGER imax DOUBLE PRECISION m_pi *DOUBLE PRECISION m_amfin DOUBLE PRECISION m_Chfin DOUBLE PRECISION m_Xenph DOUBLE PRECISION m_sinw2 DOUBLE PRECISION m_GFermi DOUBLE PRECISION m_MfinMin DOUBLE PRECISION m_ta2 INTEGER m_out INTEGER m_KeyFSR INTEGER m_KeyQCD *COMMON c_Semalib $ !copy of input $ !CMS energy $ !beam mass $ !final mass $ !beam charge $ !final charge $ !smallest final mass $ !Z mass $ !Z width $ !EW mixing angle $ !Gmu Fermi $ alphaQED at q
Definition KKsem.h:33
*********Class see also m_nmax DOUBLE PRECISION m_MasPhot DOUBLE PRECISION m_phsu DOUBLE PRECISION m_Xenph DOUBLE PRECISION m_r2 DOUBLE PRECISION m_WtMass INTEGER m_nmax INTEGER m_Nevgen INTEGER m_IsFSR INTEGER m_MarTot *COMMON c_KarFin $ !Output file $ !Event serial number $ !alpha QED at Thomson limit $ !minimum energy at CMS for remooval $ !infrared cut
Definition KarFin.h:27
*********Class see also m_nmax DOUBLE PRECISION m_MasPhot DOUBLE PRECISION m_phsu DOUBLE PRECISION m_Xenph DOUBLE PRECISION m_r2 DOUBLE PRECISION m_WtMass INTEGER m_nmax INTEGER m_Nevgen INTEGER m_IsFSR INTEGER m_MarTot *COMMON c_KarFin $ !Output file $ !Event serial number $ !alpha QED at Thomson limit $ !minimum energy at CMS for remooval $ !infrared dimensionless $ !dummy photon IR regulator $ !crude photon multiplicity enhancement factor *EVENT $ !MC crude volume of PhhSpace *Sfactors $ !YFS formfactor IR part only $ !YFS formfactor non IR finite part $ !mass weight
Definition KarFin.h:34
**********Class see also m_nmax DOUBLE PRECISION m_amel DOUBLE PRECISION m_x2 DOUBLE PRECISION m_alfinv DOUBLE PRECISION m_Xenph INTEGER m_KeyWtm INTEGER m_idyfs DOUBLE PRECISION m_zini DOUBLE PRECISION m_q2 DOUBLE PRECISION m_Wt_KF DOUBLE PRECISION m_WtCut INTEGER m_KFfin *COMMON c_KarLud $ !Input CMS energy[GeV] $ !CMS energy after beam spread beam strahlung[GeV] $ !Beam energy spread[GeV] $ !z boost due to beam spread $ !electron beam mass *ff pair spectrum $ !minimum v
Definition KarLud.h:35
std::vector< MdcDigi * > MdcDigiVec
ObjectVector< RecMdcHit > RecMdcHitCol
Definition RecMdcHit.h:99
SmartRefVector< RecCgemCluster > ClusterRefVec
Definition RecMdcTrack.h:28
ObjectVector< RecMdcTrack > RecMdcTrackCol
SmartRefVector< RecMdcHit > HitRefVec
Definition RecMdcTrack.h:26
int n2
Definition SD0Tag.cxx:55
INTupleSvc * ntupleSvc()
IMessageSvc * msgSvc()
#define M_PI
Definition TConstant.h:4
double getZFromPhiV(double phi, double V, int checkXRange=1) const
bool OnThePlane(double phi, double z) const
CgemGeoReadoutPlane * getReadoutPlane(int iLayer, int iSheet) const
static const double c
Definition Constants.h:43
void print(cell &aCell)
void stateAutomaton(cell &aCell, vector< cell > &v_cell, vector< edge > &v_edge)
void longestPathFromCA(vector< int > &vecWireIdx, vector< vector< int > > &v_path)
DotsConnection(const std::string &name, ISvcLocator *pSvcLocator)
bool forward(cell &a, cell &b)
bool dotComp(dot *dot1, dot *dot2)
int numSharedDots(cell &a, cell &b)
StatusCode execute()
void nextCellFinding(cell &aCell, vector< cell > &v_cell, vector< edge > &v_edge, map< int, pair< double, double > > &setWireHitPos, map< int, int > &setWireEntry)
bool makeEdge(cell &a, cell &b, edge &e)
bool sameCell(cell &a, cell &b)
StatusCode finalize()
vector< int > myVecGoodCellIdx
StatusCode initialize()
vector< cell > myVecCells
vector< int > myCellMaxState
bool makeOrder(Line &l)
vector< edge > myVecEdges
map< int, dot > myMapDots
void makeDotCellEdge(vector< int > &vecWireIdx)
vector< const MdcDigi * > getMdcDigiVec(cell &aCell)
bool isNeighbour(cell &a, cell &b)
vector< vector< int > > CellAutomaton(vector< int > &v_cellIdx, vector< cell > &v_cell, vector< edge > &v_edge)
void setInitialHelix(KalmanFit::Helix aHelix)
void setChi2Diverge(double cut=1000000)
int activeHits(double chi_cut=10, int sel=0)
activate myMdcDigiIsActive's hit based on myChiVecMdcDigi
double getFlightLength()
int getLayer(const MdcDigi *aDcDigi)
void setDChits(vector< const MdcDigi * > aVecMdcDigi, double T0)
void setCgemClusters(vector< const RecCgemCluster * > aVecCgemCluster)
void useAxialHitsOnly(bool x=true)
bool getPosAtCgem(int layer, HepPoint3D &pos)
int deactiveHits(double chi_cut=10, int nMax=1, int layerMin=0, int layerMax=50)
bool setDChitsPhiAmbi(const vector< double > &vec)
vector< double > calculateCirclePar_Taubin(bool useIniHelix=false, int layerMin=-1, int layerMax=50, bool useExtraPoints=false)
double getRmidGapCgem(int i)
vector< double > getVecChiCgemCluster()
const HepSymMatrix & getEa()
KalmanFit::Helix getClassHelix()
HepVector getHelix()
void setModeWireCrossPointPersistent(bool mode)
vector< pair< double, double > > getSZ(const MdcDigi *aDcDigi)
return S, the track length in XY; and Z of a hit on a stereo wire
bool setDChitsFitFlag(vector< int > &vec)
set myMdcDigiIsActive from vec
void fitCircleOnly(bool x=true)
void setExtraPoints(vector< pair< double, double > > extraPoints)
void usePhiAmbi(bool x=true)
vector< RecMdcHit > makeRecMdcHitVec(int sel=1)
vector< double > getVecChiMdcDigi()
void setT0(double T0)
vector< int > getVecMdcDigiIsAct()
double IntersectCylinder(double r)
void updateDcDigiInfo(const MdcDigi *aDcDigi)
based on input aDcDigi, modifies myFlightLength, myLeftRight, myPosOnWire, myDocaFromDigi,...
double getDocaFromTrk()
vector< int > getVecIsActiveCgemCluster()
void setPxy(const double pxy)
Definition DstMdcTrack.h:86
void setTrackId(const int trackId)
Definition DstMdcTrack.h:84
void setPy(const double py)
Definition DstMdcTrack.h:88
void setZ(const double z)
Definition DstMdcTrack.h:95
void setX(const double x)
Definition DstMdcTrack.h:93
void setError(double err[15])
void setTheta(const double theta)
Definition DstMdcTrack.h:91
void setStat(const int stat)
Definition DstMdcTrack.h:97
void setP(const double p)
Definition DstMdcTrack.h:90
void setHelix(double helix[5])
void setPoca(double poca[3])
void setR(const double r)
Definition DstMdcTrack.h:96
void setCharge(const int charge)
Definition DstMdcTrack.h:85
void setY(const double y)
Definition DstMdcTrack.h:94
void setChi2(const double chi)
Definition DstMdcTrack.h:98
void setPhi(const double phi)
Definition DstMdcTrack.h:92
void setPz(const double pz)
Definition DstMdcTrack.h:89
void setPx(const double px)
Definition DstMdcTrack.h:87
Hep3Vector momentum(double dPhi=0.) const
returns momentum vector after rotating angle dPhi in phi direction.
const HepSymMatrix & Ea(void) const
returns error matrix.
HepPoint3D x(double dPhi=0.) const
returns position after rotating angle dPhi in phi direction.
const HepVector & a(void) const
returns helix parameters.
const HepPoint3D & pivot(void) const
returns pivot position.
Hep3Vector direction(double dPhi=0.) const
returns direction vector after rotating angle dPhi in phi direction.
double getT0(int layid, int cellid) const
double driftTimeToDist(double drifttime, int layid, int cellid, int lr, double entrance=0.0) const
double getTprop(int lay, double z) const
double getTimeWalk(int layid, double Q) const
void SetInBigSet()
int GetPrev(int i=0)
vector< int > GetInner(int i=0)
void AddOuter(int wireID, int gap=0)
void SetWire(const MdcGeoWire *aWire)
vector< int > GetOuter(int i=0)
void AddInner(int wireID, int gap=0)
int GetNext(int i=0)
void AddPrev(int wireID, int gap=0)
void SetUsedFlag(int flag=1)
void AddHit(const MdcDigi *aHit)
void AddNext(int wireID, int gap=0)
vector< int > GetNeiborHits()
vector< int > GetNeighborIDType4(void) const
vector< int > GetNeighborIDType3(void) const
const MdcGeoWire *const Wire(unsigned id)
HepPoint3D getAdjacentIntersectionPointSlower(const MdcGeoWire *wireA, const MdcGeoWire *wireB)
const MdcGeoLayer *const Layer(unsigned id)
static int layer(const Identifier &id)
Values of different levels (failure returns 0)
Definition MdcID.cxx:49
static int wire(const Identifier &id)
Definition MdcID.cxx:54
MdcDigiVec & getMdcDigiVec(uint32_t control=0)
static double MdcTime(int timeChannel)
Definition RawDataUtil.h:8
virtual Identifier identify() const
Definition RawData.cxx:15
unsigned int getChargeChannel() const
Definition RawData.cxx:45
unsigned int getTimeChannel() const
Definition RawData.cxx:40
int getclusterid(void) const
int getlayerid(void) const
const Identifier getMdcId(void) const
Definition RecMdcHit.h:49
void setStat(int stat)
Definition RecMdcHit.h:66
const double getFltLen(void) const
Definition RecMdcHit.h:56
void setTrkId(int trkid)
Definition RecMdcHit.h:59
void setId(int id)
Definition RecMdcHit.h:58
void setVecClusters(ClusterRefVec vecclusters)
void setPivot(const HepPoint3D &pivot)
Definition RecMdcTrack.h:79
void setVZ0(double z0)
Definition RecMdcTrack.h:76
void setVY0(double y0)
Definition RecMdcTrack.h:75
void setVecHits(HitRefVec vechits)
void setFiTerm(double fiterm)
Definition RecMdcTrack.h:77
void setVX0(double x0)
Definition RecMdcTrack.h:74
CalibPairCol::const_iterator PairIt
Definition CalibModel.h:110
Definition Event.h:21
Index prev(Index i)
Definition EvtCyclic3.cc:96
Index first(Pair i)
vector< Line > vecFittedLine
dot * dots[NUMBER_OF_DOTS_PER_CELL]
vector< Line > vecFittedLine
pair< int, int > twoCells
pair< int, int > twoLines
vector< dot * > dots
vector< double > S
vector< int > LR
double rho
vector< int > order
double theta
DigiPtr digi
DetectorEnum detector
int cluId
vector< RecMdcHit > RecMdcHitVec
vector< int > mdcV2DigiWireIdx
double chi2
vector< int > mdcXDigiFitted
vector< double > mdcVDigiChi
vector< int > mdcXDigiWireIdx
vector< int > CgemXClusterID
vector< double > mdcXDigiChi
vector< int > mdcVDigiWireIdx
vector< int > mdcVDigiFitted
vector< int > mdcHitIdx[43]
double a_helix[5]
vector< int > mdcV1DigiWireIdx
vector< int > CgemVClusterID
const MdcDigi * mdcDigi