ATLAS Offline Software
Loading...
Searching...
No Matches
TrigZFinderInternal.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "PhiSlice.h"
7
11
12
13TrigZFinderInternal::TrigZFinderInternal( const std::string& type, const std::string& name)
14 : m_type (type),
15 m_name (name)
16{
17 m_phiBinSize = 0.2 ;
19 m_pixOnly = false ;
20 m_ROIphiWidth = 0.2 ;
21 m_minZBinSize = 0.2 ;
22 m_zBinSizeEtaCoeff = 0.1 ;
23 m_dphideta = -0.02 ;
25 m_numberOfPeaks = 1 ;
26 m_chargeAware = true ;
27 m_zHistoPerPhi = true ;
28 m_nFirstLayers = 3 ;
29 m_vrtxDistCut = 0. ;
30 m_vrtxMixing = 0. ;
32 m_preferCentralZ = false ;
33 m_trustSPprovider = true ;
34 m_fullScanMode = false ;
35 m_tripletMode = 0 ;
36 m_tripletDZ = 25. ;
37 m_tripletDK = 0.005 ;
38 m_halfTripletDK = 0.5*m_tripletDK; // using this in internals avoids unnecessary multiplications when calculating curvature
39 m_tripletDP = 0.05 ;
40
41 m_maxLayer = 32;
42
44 m_percentile = 1;
45
46 // m_applyWeightThreshold = false;
48
49
51 m_IdScan_MaxNumLayers = 20; // dphiEC depends on this value !!! 19 without IBL, 20 with IBL!!
52 m_IdScan_LastBrlLayer = 7; // dphiBrl depends on this value
53
54}
55
56
57
58void TrigZFinderInternal::initializeInternal(long maxLayers, long lastBarrel )
59{
61
62 m_IdScan_MaxNumLayers = maxLayers;
63 m_IdScan_LastBrlLayer = lastBarrel;
64
65 //initialize new/old layer number transform table
66
67 if(maxLayers > 20) {
68 int offsetEndcapPixels = lastBarrel + 1;
69 int M = (maxLayers-offsetEndcapPixels)/2;
70 for(int l=0;l<maxLayers;l++) {
71 int oldL = l;
72 if(l>lastBarrel) {
73 oldL = l-offsetEndcapPixels;
74 oldL = oldL < M ? oldL : oldL - M;
75 oldL += offsetEndcapPixels;
76 }
77 m_new2old.push_back(oldL);
78 }
79 m_IdScan_MaxNumLayers = lastBarrel + M + 1;
80 } else {
81 for(int l=0;l<maxLayers;l++) m_new2old.push_back(l);
82 }
83
84
85 // std::cout << "m_IdScan_MaxNumLayers " << m_IdScan_MaxNumLayers
86 // << "\tm_IdScan_LastBrlLayer " << m_IdScan_LastBrlLayer << std::endl;
87
88 // number of phi neighbours to look at
89 // if ( extraPhi.size()==0 )
90
91 m_extraPhi = std::vector< std::vector<long> >( m_IdScan_MaxNumLayers, std::vector<long>(m_IdScan_MaxNumLayers) );
92
93 // from TrigZFinder::initialize
96 if ( m_dphideta > 0 ) m_dphideta *= -m_dphideta;
97
100
101 for (long l1=0; l1<m_IdScan_MaxNumLayers-1; ++l1) {
102 for (long l2=l1+1; l2<m_IdScan_MaxNumLayers; ++l2) {
103 m_extraPhi[l1][l2]=1; // look at a single phi neighbour
104 }
105 }
106
108
109 long first_layer = 0;
110 long offset_layer = 1;
111 if ( m_IdScan_MaxNumLayers<20 ) {
112 first_layer = 1;
113 offset_layer = 0;
114 }
115
116 long lyrcnt = 0;
117 for (long l1=0; l1<m_IdScan_LastBrlLayer; ++l1) {
118 for (long l2=l1+1; l2<=m_IdScan_LastBrlLayer; ++l2) {
119 double dphi = ZF_dphiBrl[lyrcnt + 7*first_layer];
120 dphi *= m_neighborMultiplier;
121 m_extraPhi[l1][l2]=static_cast<long>( ceil( sqrt(dphi*dphi+ZF_phiRes*ZF_phiRes*2) * m_invPhiSliceSize ) );
122
123 // std::cout << "test 1 " << l1 << " " << l2 << "\tmax : " << m_IdScan_MaxNumLayers << std::endl;
124
125 if (m_extraPhi[l1][l2]<1) m_extraPhi[l1][l2]=1;
126 // std::cout << "Delta Phi between layers " << l1 << " and " << l2
127 // << " = "<< ZF_dphiBrl[lyrcnt]
128 // << " rads ( " << m_extraPhi[l1][l2] << " bins including phi resln.)\n";
129 lyrcnt++;
130 }
131 }
132
133
135
136
137
138 for ( long lyrpair=12*first_layer ; lyrpair<117; ++lyrpair ) {
139
140 double dphi = ZF_dphiEC[lyrpair*4+2];
143 long l1 = (long)ZF_dphiEC[lyrpair*4] + offset_layer;
144 long l2 = (long)ZF_dphiEC[lyrpair*4+1] + offset_layer;
145 double eta = ZF_dphiEC[lyrpair*4+3];
146 // std::cout << "Delta Phi between layers " << l1 << " and " << l2
147 // << " = " << dphi << " rads @ eta=" << eta
148 // << ". Extrapolate it to eta=0.9 to get ";
149 dphi = dphi + m_dphideta * ( 0.9 - eta );
150 dphi *= m_neighborMultiplier;
151 m_extraPhi[l1][l2]=static_cast<long>(ceil(sqrt(dphi*dphi+ZF_phiRes*ZF_phiRes*2)*m_invPhiSliceSize));
152
153 if (m_extraPhi[l1][l2]<1) m_extraPhi[l1][l2]=1;
154
155 // std::cout << "test 2 " << l1 << " " << l2 << "\tmax : " << m_IdScan_MaxNumLayers << std::endl;
156
157 // std::cout << dphi << " rads ( " << m_extraPhi[l1][l2] << " bins including phi resln.)\n";
158 }
159
160}
161
162
163
164
165
166double TrigZFinderInternal::computeZV(double r1, double z1, double r2, double z2) const {
167 return (z2*r1-z1*r2)/(r1-r2);
168}
169
170double TrigZFinderInternal::computeZV(double r1, double p1, double z1,
171 double r2, double p2, double z2) const {
172
173 double x1, y1, x2, y2;
174 //sincos( p1, &y1, &x1 ); x1 *= r1; y1 *= r1;
175 //sincos( p2, &y2, &x2 ); x2 *= r2; y2 *= r2;
176 x1 = r1 * cos(p1);
177 x2 = r2 * cos(p2);
178 y1 = r1 * sin(p1);
179 y2 = r2 * sin(p2);
180
181#define _COMPUTEX0_
182
183#ifdef _COMPUTEX0_
184 double slope = (y2-y1)/(x2-x1);
185 double invslope = 1./slope;
186 double x0 = (slope*x1-y1)/(slope+invslope);
187 //double y0 = -1*x0*invslope;
188 double d0sqr = x0*x0*(1+invslope*invslope);
189 // s1 and s2 are the track lengths from the point of closest approach
190 double s1 = sqrt(r1*r1-d0sqr);
191 double s2 = sqrt(r2*r2-d0sqr); // or s1*(x1-x0)/(x2-x0)
192#else
193 double inv_dels = 1./sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
194 double dotrr = x1*x2 + y1*y2;
195 double s1 = ( dotrr - r1*r1 ) * inv_dels;
196 double s2 = ( r2*r2 - dotrr ) * inv_dels;
197#endif
198
199 return (z2*s1-z1*s2)/(s1-s2);
200}
201
202
203long TrigZFinderInternal::fillVectors(const std::vector<TrigSiSpacePointBase>& spVec,
204 const IRoiDescriptor& roi,
205 std::vector<double>& phi,
206 std::vector<double>& rho,
207 std::vector<double>& zed,
208 std::vector<long>& lyr,
209 std::vector<long>& filledLayers,
210 long& numPhiSlices ) const
211{
212
213 std::vector<bool> lcount( m_IdScan_MaxNumLayers, false );
214
215 // full scan check
216 std::vector<TrigSiSpacePointBase>::const_iterator SpItr = spVec.begin();
217
218 long nSPs = spVec.size();
219
220 // to shift the phi of space points as if the RoI starts at phi~0
221 // assumes that RoI->phi0() and the SPs are in range [-pi,+pi]
222 //
223 double roiPhiMin, roiPhiMax;
224
225 if ( m_fullScanMode || roi.isFullscan() ) {
226 roiPhiMin = -M_PI;
227 roiPhiMax = M_PI;
228 }
229 else {
230 // If we trust that all the SPs are properly input, we determine the RoI phi width
231 // using the SPs themselves.
232 // If the RoI phi range is wider than pi, we keep everything as usual.
234 {
235 double roiPhiPosMin( 9.9), roiPhiPosMax(0);
236 double roiPhiNegMin(-9.9), roiPhiNegMax(0); // least negative and most negative
237 for(long i=0; i<nSPs; ++i, ++SpItr)
238 {
239 double spphi = SpItr->phi();
240 if ( spphi>0 && spphi>roiPhiPosMax ) roiPhiPosMax = spphi;
241 if ( spphi>0 && spphi<roiPhiPosMin ) roiPhiPosMin = spphi;
242
243 if ( spphi<0 && spphi<roiPhiNegMax ) roiPhiNegMax = spphi;
244 if ( spphi<0 && spphi>roiPhiNegMin ) roiPhiNegMin = spphi;
245 }
246
247 if ( roiPhiNegMax > roiPhiNegMin ) {
248 // if all SPs are in (0, pi):
249 roiPhiMin = roiPhiPosMin;
250 roiPhiMax = roiPhiPosMax;
251 }
252 else if ( roiPhiPosMax < roiPhiPosMin ) {
253 // if all SPs are in (-pi, 0):
254 roiPhiMin = roiPhiNegMax;
255 roiPhiMax = roiPhiNegMin;
256 }
257 else if ( roiPhiPosMin - roiPhiNegMin < M_PI ) {
258 // if we have an RoI that covers phi=0 axis
259 roiPhiMin = roiPhiNegMax;
260 roiPhiMax = roiPhiPosMax;
261 }
262 else {
263 // if we have an RoI that covers phi=pi axis
264 roiPhiMin = roiPhiPosMin;
265 roiPhiMax = roiPhiNegMin;
266 }
267
268 roiPhiMin -= 1e-10;
269 roiPhiMax += 1e-10;
270
271 SpItr = spVec.begin(); // rewind the iterator
272 }
273 else {
274
276 if ( roi.phiMinus()==roi.phiPlus() ) {
277 roiPhiMin = roi.phi()-0.5*m_ROIphiWidth;
278 roiPhiMax = roi.phi()+0.5*m_ROIphiWidth;
279 if(roiPhiMin<-M_PI) roiPhiMin+=2*M_PI;
280 if(roiPhiMax>M_PI) roiPhiMax-=2*M_PI;
281 }
282 else {
283 // already wrapped by RoiDescriptor
284 roiPhiMin = roi.phiMinus();
285 roiPhiMax = roi.phiPlus();
286 }
287
288 }
289
290 }
291
292
293 double dphi = roiPhiMax-roiPhiMin;
294
295 if ( dphi<0 ) dphi+=2*M_PI;
296
297 numPhiSlices = long (ceil( dphi*m_invPhiSliceSize ));
298
299
300 bool piBound=(roiPhiMin>roiPhiMax);
301
302 int icount = 0;
303
304 if(!piBound)
305 {
307 for(long i=0; i<nSPs; ++i, ++SpItr)
308 {
309 if ( SpItr->layer()>m_maxLayer || (m_pixOnly && !SpItr->isPixel()) ) continue;
310 double phi2 = SpItr->phi() - roiPhiMin;
311
312 if ( phi2>=0 && phi2<dphi ) { // ensures space point is in ROI
313 phi[icount] = phi2;
314 rho[icount] = SpItr->r();
315 zed[icount] = SpItr->z();
316 lyr[icount] = m_new2old[SpItr->layer()];
317 lcount[lyr[icount]]=true;
318 ++icount;
319 }
320 }
321 }
322 else
323 {
325 for(long i=0; i<nSPs; ++i, ++SpItr)
326 {
327 if ( SpItr->layer()>m_maxLayer || (m_pixOnly && !SpItr->isPixel()) ) continue;
328 double phi2 = SpItr->phi() - roiPhiMin;
329 if( phi2<0.0) phi2+=2*M_PI;
330 if ( phi2>=0 && phi2<dphi ) { // ensures space point is in ROI
331 phi[icount] = phi2;
332 rho[icount] = SpItr->r();
333 zed[icount] = SpItr->z();
334 lyr[icount] = m_new2old[SpItr->layer()];
335 lcount[lyr[icount]]=true;
336 ++icount;
337 }
338 }
339 }
340
341 if ( icount<nSPs ) {
342
343 // std::cout << "TrigZFinderInternal::fillVectors() filtered some spacepoints " << nSPs
344 // << " -> " << icount << std::endl;
346 phi.resize(icount);
347 rho.resize(icount);
348 zed.resize(icount);
349 lyr.resize(icount);
350 }
351
352
353 // Store in filledLayers the layerNumber of those layers that contain hits.
354 // So, if there are hits in layers 1,3,8 filledLayers[0]=1, filledLayers[1]=3
355 // and filledLayers[2]=8
356 //
357 long filled = 0;
358
359 for ( long i=0; i<m_IdScan_MaxNumLayers; ++i ) {
360 if ( lcount[i] ) {
361 filledLayers[filled] = i;
362 ++filled;
363 }
364 }
365
366 // std::cout << "SUTT NSP : " << phi.size() << " " << spVec.size() << std::endl;
367 // for ( unsigned i=0 ; i<phi.size() ; i++ ) {
368 // std::cout << "SUTT SP : " << i << "\tphi " << phi[i] << "\tz " << zed[i] << "\tr " << rho[i] << std::endl;
369 // }
370
371 return filled;
372}
373
374
375
376
377std::vector<typename TrigZFinderInternal::vertex>*
378TrigZFinderInternal::findZInternal( const std::vector<TrigSiSpacePointBase>& spVec,
379 const IRoiDescriptor& roi) const {
380
381 std::vector<vertex>* output = new std::vector<vertex>();
382
383 long nsp = spVec.size();
384 if ( !nsp ) return output; //No points - return nothing
385
386 // Creating vectors of doubles/longs for storing phi,rho,z and layer of space points.
387 // filledLayers is used to know which of all layers contain space points
388 // and fill with relevant info...
389 //
390 std::vector<double> phi(nsp), rho(nsp), zed(nsp);
391 std::vector<long> lyr(nsp), filledLayers(m_IdScan_MaxNumLayers);
392
393 long numPhiSlices = 0;
394
395 long filled = this->fillVectors( spVec, roi, phi, rho, zed, lyr, filledLayers, numPhiSlices );
396
397 nsp = phi.size();
398
399 // std::cout << "SUTT roi " << roi << "nsp: " << nsp << std::endl;
400
401
402 double zMin = roi.zedMinus();
403 double zMax = roi.zedPlus();
404
405
406 // The bin size of the z-histo -and hence the number of bins-
407 // depends on the RoI's |eta| (to account for worsening z-resolution)
408 //
409 const double ZBinSize = m_minZBinSize + m_zBinSizeEtaCoeff*fabs(roi.eta());
410 const double invZBinSize = 1./ZBinSize;
411
412
413 const long HalfZhistoBins = long ( ceil( 0.5*(zMax-zMin)*invZBinSize ) );
414 const long NumZhistoBins = 2*HalfZhistoBins;
415
416 // number of phi bins to look at will get fewer as eta increases
417 const long extraPhiNeg = static_cast<long> ( floor( (0.9 - fabs(roi.eta()))*m_dphideta*m_invPhiSliceSize*m_neighborMultiplier ) );
418
419
420
421 // These are the z-Histograms
422 // Two sets are defined: {n/z}Histo[0][phi][z] will be for positively bending tracks
423 // {n/z}Histo[1][phi][z] will be for negatively bending tracks
424 //
425
426 long numZhistos = m_zHistoPerPhi ? numPhiSlices : 1 ;
427
428 // std::vector < std::vector < std::vector<long> > > nHisto( 2, std::vector < std::vector<long> > (numZhistos, std::vector<long> () ) );
429 // std::vector < std::vector < std::vector<double> > > zHisto( 2, std::vector < std::vector<double> > (numZhistos, std::vector<double>() ) );
430
431 std::vector < std::vector<long> > nHisto[2]; // the actual z histogram count of pairs
432 std::vector < std::vector<double> > zHisto[2]; // summed z position histograms
433
434 for ( int i=2 ; i-- ; ) { nHisto[i].clear(); nHisto[i].resize(numZhistos); }
435 for ( int i=2 ; i-- ; ) { zHisto[i].clear(); zHisto[i].resize(numZhistos); }
436
437 // std::vector< std::vector<long> >* nHisto = m_nHisto;
438 // std::vector< std::vector<double> >* zHisto = m_zHisto;
439
440 // nMax = 0;
441
442 //Make a vector of all the PhiSlice instances we need
443 std::vector< PhiSlice* > allSlices( numPhiSlices );
444 for ( unsigned int sliceIndex = 0; sliceIndex < numPhiSlices; sliceIndex++ )
445 {
446 allSlices[ sliceIndex ] = new PhiSlice( sliceIndex, ZBinSize, m_invPhiSliceSize,
449 }
450
451 int allSlicesSize = allSlices.size();
452
453 //Populate the slices
454 for ( long pointIndex = 0; pointIndex < nsp; pointIndex++ )
455 {
456 int phiIndex = floor( phi[ pointIndex ] * m_invPhiSliceSize );
457 if (phiIndex > allSlicesSize) {
458 continue;
459 }
460 allSlices[ phiIndex ]->AddPoint( rho[ pointIndex ], zed[ pointIndex ], phi[ pointIndex ], lyr[ pointIndex ] );
461 }
462
463 //Read out the slices into flat structures for the whole layers
464 std::vector< std::vector< double > > allLayerRhos, allLayerZs, allLayerPhis;
465 allLayerRhos.resize( m_IdScan_MaxNumLayers );
466 allLayerZs.resize( m_IdScan_MaxNumLayers );
467 allLayerPhis.resize( m_IdScan_MaxNumLayers );
468
469 std::vector< std::vector< int > > allSliceWidths( m_IdScan_MaxNumLayers, std::vector< int >( numPhiSlices + 1, 0 ) );
470 for ( unsigned int sliceIndex = 0; sliceIndex < numPhiSlices; sliceIndex++ )
471 {
472 allSlices[ sliceIndex ]->MakeWideLayers( &allLayerRhos, &allLayerZs, &allLayerPhis, &allSliceWidths, filled, &filledLayers );
473 }
474
475 //One histogram per phi slice?
476 if ( m_zHistoPerPhi )
477 {
478 //Allocate all the histograms
479 for ( unsigned int sliceIndex = 0; sliceIndex < numPhiSlices; sliceIndex++ )
480 {
481 nHisto[0][sliceIndex].resize( NumZhistoBins + 1 );
482 zHisto[0][sliceIndex].resize( NumZhistoBins + 1 );
483 }
484 if ( m_chargeAware ) {
485 for ( unsigned int sliceIndex = 0; sliceIndex < numPhiSlices; sliceIndex++ ) {
486 nHisto[1][sliceIndex].resize( NumZhistoBins + 1 );
487 zHisto[1][sliceIndex].resize( NumZhistoBins + 1 );
488 }
489 }
490
491 //Populate the histograms
492 for ( unsigned int sliceIndex = 0; sliceIndex < numPhiSlices; sliceIndex++ ) {
493 allSlices[ sliceIndex ]->GetHistogram( &( nHisto[0][sliceIndex] ), &( zHisto[0][sliceIndex] ),
494 &( nHisto[1][sliceIndex] ), &( zHisto[1][sliceIndex] ),
495 m_extraPhi, extraPhiNeg, m_nFirstLayers, m_tripletMode, m_chargeAware, nHisto, zHisto );
496
497 //Note the extra arguments here - pointers to the whole histogram collection
498 //This allows the filling of neighbouring slice histograms as required, but breaks thread safety
499
500 delete allSlices[ sliceIndex ];
501 }
502 }
503 else {
504 //Allocate the z-axis histograms
505 nHisto[0][0].resize( NumZhistoBins + 1 );
506 zHisto[0][0].resize( NumZhistoBins + 1 );
507 if ( m_chargeAware ) {
508 nHisto[1][0].resize( NumZhistoBins + 1 );
509 zHisto[1][0].resize( NumZhistoBins + 1 );
510 }
511
512 //Populate the histogram - fast and memory-efficient, but not thread safe (use MakeHistogram for thread safety)
513 for ( unsigned int sliceIndex = 0; sliceIndex < numPhiSlices; sliceIndex++ ) {
514 allSlices[ sliceIndex ]->GetHistogram( &( nHisto[0][0] ), &( zHisto[0][0] ),
515 &( nHisto[1][0] ), &( zHisto[1][0] ),
517
518 delete allSlices[ sliceIndex ];
519 }
520 }
521
522
523
526
527 double pedestal = 0;
528
529 if ( m_weightThreshold>0 ) {
530
531 int count = 0;
532
533 for ( long zpm=0; zpm<1 || ( m_chargeAware && zpm<2 ) ; ++zpm ) {
534
535 for(std::vector< std::vector<long> >::iterator nfiter = nHisto[zpm].begin(); nfiter!=nHisto[zpm].end(); ++nfiter) {
536
537 if((*nfiter).empty()) continue; // only check the filled zHistos
538 if((*nfiter).size() <= 2 ) continue;// this is only a protection : with proper inputs to zfinder, it is always satisfied
539
540 for(std::vector<long>::iterator niter=nfiter->begin()+2; niter!=nfiter->end(); ++niter ) {
542 if ( *niter>=0 ) {
543 count++;
544 pedestal += *(niter) + *(niter-1) + *(niter-2);
545 }
546 }
547 }
548 }
549
550 if ( count>0 ) pedestal /= count;
551
552 }
553
554
561
562 double bg = 0;
563
564 if ( m_minVtxSignificance > 0 ) {
565
566 if ( !m_chargeAware ) {
567
568 std::vector<long>& n = nHisto[0][0];
569
570 std::vector<long> n3( nHisto[0][0].size()-2, 0);
571
572 for( unsigned i=n.size()-2 ; i-- ; ) n3[i] = ( n[i+2] + n[i+1] + n[i] );
573 std::sort( n3.begin(), n3.end() );
574
575 unsigned nmax = unsigned(n3.size()*m_percentile);
576
577 for( unsigned i=nmax ; i-- ; ) bg += n3[i];
578
579 if ( nmax>0 ) bg /= nmax;
580
581 }
582 }
583
584
585
586 // Now the nHisto's are filled; find the 3 consecutive bins with the highest number of entries...
587 //
588
589 std::vector<double> zoutput;
590 std::vector<double> woutput;
591
592
593
594 while((int)zoutput.size() < m_numberOfPeaks) {
595
596 long maxh=0; // was 1 before triplets were introduced
597 long binMax=0;
598 long bending=0, bestPhi=0;
599 long ztest;
600
601 for ( long zpm=0; zpm<1 || ( m_chargeAware && zpm<2 ) ; ++zpm ) {
602
603 std::vector< std::vector<long> >::iterator nfiter = nHisto[zpm].begin();
604 for( ; nfiter!=nHisto[zpm].end() ; ++nfiter) {
605
606 if((*nfiter).empty()) continue; // only check the filled zHistos
607 if((*nfiter).size() <= 2 ) continue;// this is only a protection : with proper inputs to zfinder, it is always satisfied
608
609 for(std::vector<long>::iterator niter=(*nfiter).begin()+2; niter!=(*nfiter).end(); ++niter ) {
610
611 ztest = *(niter-2) + *(niter-1) + *(niter);
612 if ( ztest <= 0 || ztest < maxh ) continue;
615 if ( ztest >= maxh ) { // && ztest>m_weightThreshold ) {
616 long bintest = niter-(*nfiter).begin()-1;
617 if ( ztest > maxh ||
618 // for two candidates at same "height", prefer the more central one
619 (m_preferCentralZ && std::abs( bintest - HalfZhistoBins ) < std::abs( binMax - HalfZhistoBins ) ) ) {
620 maxh = ztest;
621 binMax = bintest;
622 bestPhi = nfiter-nHisto[zpm].begin();
623 bending = zpm;
624 }
625 }
626 }// end of niter loop
627 }
628 }
629
630 // nMax = maxh;
633 if ( maxh==0 || ( m_tripletMode==0 && maxh<2 ) ) {
634 break;
635 }
636
637 // ...and compute the "entries-weighted" average bin position
638
639 double weightedMax = ( zHisto[bending][bestPhi][binMax] +
640 zHisto[bending][bestPhi][binMax+1] +
641 zHisto[bending][bestPhi][binMax-1] ) /maxh;
642
644 if ( m_numberOfPeaks>0 ) {
645 nHisto[bending][bestPhi][binMax] = -1;
646 nHisto[bending][bestPhi][binMax-1] = -1;
647 nHisto[bending][bestPhi][binMax+1] = -1;
648 zHisto[bending][bestPhi][binMax] = 0;
649 zHisto[bending][bestPhi][binMax-1] = 0;
650 zHisto[bending][bestPhi][binMax+1] = 0;
651 }
652
653 int closestVtx = -1; // find the closest vertex already put into the output list
654 float dist2closestVtx = 1000; // should be larger than m_ZFinder_MaxZ*2
655 for ( size_t iv = 0; iv < zoutput.size(); ++iv ) {
656 if ( fabs(weightedMax-zoutput[iv]) < dist2closestVtx ) {
657 closestVtx = iv;
658 dist2closestVtx = fabs(weightedMax-zoutput[iv]);
659 }
660 }
661
662 if ( dist2closestVtx < m_nvrtxSeparation*ZBinSize || dist2closestVtx < fabs(weightedMax)*m_vrtxDistCut ) {
663 zoutput[closestVtx] = m_vrtxMixing * weightedMax + (1.0 - m_vrtxMixing) * zoutput[closestVtx] ;
664 woutput[closestVtx] = m_vrtxMixing * maxh + (1.0 - m_vrtxMixing) * woutput[closestVtx] ;
665 }
666 else {
667
670 bool addvtx = true;
671 double significance = 0;
672 if ( bg>0 ) {
673 significance = (maxh-bg)/std::sqrt(bg);
674 if ( significance < m_minVtxSignificance ) break; // if this vertex is not significant then no subsequent vertex could be either
675 }
676
677 if ( addvtx ) {
678 zoutput.push_back( weightedMax );
679 woutput.push_back( maxh );
680 }
681 }
682
683 }
684
685
690
698
701
702
706 if ( m_weightThreshold>0 ) {
707 for ( unsigned i=0 ; i<zoutput.size() ; i++ ) {
708 output->push_back( vertex( woutput[i] - pedestal, zoutput[i] ) );
709 }
710 }
711 else {
712 for ( unsigned i=0 ; i<zoutput.size() ; i++ ) {
713 output->push_back( vertex( zoutput[i], woutput[i] - pedestal ) );
714 }
715 }
716
717 // std::cout << "SUTT zoutput size " << zoutput.size() << "\t" << roi << std::endl;
718 // for ( unsigned i=0 ; i<zoutput.size() ; i++ ) std::cout << "SUTT zoutput " << i << "\t" << zoutput[i] << std::endl;
719
720 return output;
721
722}
723
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
const int nmax(200)
static const double ZF_dphiBrl[28]
static const double ZF_dphiEC[468]
const double ZFinder_MinPhiSliceSize
const double ZF_phiRes
Describes the API of the Region of Ineterest geometry.
virtual bool isFullscan() const =0
is this a full detector RoI?
virtual double eta() const =0
virtual double phiPlus() const =0
extreme phi values
virtual double zedPlus() const =0
the zed and eta values at the most forward and most rear ends of the RoI
virtual double phiMinus() const =0
virtual double phi() const =0
Methods to retrieve data members.
virtual double zedMinus() const =0
double computeZV(double r1, double z1, double r2, double z2) const
std::vector< vertex > * findZInternal(const std::vector< TrigSiSpacePointBase > &spVec, const IRoiDescriptor &roi) const
long fillVectors(const std::vector< TrigSiSpacePointBase > &spVec, const IRoiDescriptor &roi, std::vector< double > &phi, std::vector< double > &rho, std::vector< double > &zed, std::vector< long > &lyr, std::vector< long > &filledLayers, long &numPhiSlices) const
TrigZFinderInternal(const std::string &, const std::string &)
std::vector< std::vector< long > > m_extraPhi
std::vector< int > m_new2old
double m_weightThreshold
to apply a threshold to the found vertex candidates
long m_IdScan_MaxNumLayers
maximum number of layers and last barrel layer
void initializeInternal(long maxLayers, long lastBarrel)
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.