00001
00002 #include "RecoPixelVertexing/PixelTriplets/interface/QuadrupletSeedMerger.h"
00003 #include <time.h>
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00030 QuadrupletSeedMerger::QuadrupletSeedMerger( ) {
00031
00032
00033
00034 isMergeTriplets_ = false;
00035
00036 isAddRemainingTriplets_ = false;
00037
00038
00039
00040 layerListName_ = std::string( "PixelSeedMergerQuadruplets" );
00041 }
00042
00043 void QuadrupletSeedMerger::update(const edm::EventSetup& es) {
00044
00045 es.get<TrackerDigiGeometryRecord>().get( theTrackerGeometry_ );
00046 }
00047
00051 QuadrupletSeedMerger::~QuadrupletSeedMerger() {
00052
00053 }
00054
00055
00056
00065
00066
00067 const OrderedSeedingHits& QuadrupletSeedMerger::mergeTriplets( const OrderedSeedingHits& inputTriplets, const edm::EventSetup& es ) {
00068
00069
00070 edm::ESHandle<SeedingLayerSetsBuilder> layerBuilder;
00071 es.get<TrackerDigiGeometryRecord>().get( layerListName_.c_str(), layerBuilder );
00072 theLayerSets_ = layerBuilder->layers( es );
00073
00074
00075
00076
00077
00078 std::vector<std::pair<double,double> > phiEtaCache;
00079 std::vector<SeedingHitSet> tripletCache;
00080
00081 const unsigned int nInputTriplets = inputTriplets.size();
00082 phiEtaCache.reserve(nInputTriplets);
00083 tripletCache.reserve(nInputTriplets);
00084
00085 for( unsigned int it = 0; it < nInputTriplets; ++it ) {
00086 tripletCache.push_back((inputTriplets[it]));
00087 phiEtaCache.push_back(calculatePhiEta( (tripletCache[it]) ));
00088
00089 }
00090
00091
00092 quads_.clear();
00093
00094
00095
00096
00097 bool isAllTriplets = true;
00098 for( unsigned int it = 0; it < nInputTriplets; ++it ) {
00099 if( tripletCache[it].size() != 3 ) {
00100 isAllTriplets = false;
00101 break;
00102 }
00103 }
00104
00105 if( !isAllTriplets && isMergeTriplets_ )
00106 std::cout << "[QuadrupletSeedMerger::mergeTriplets] (in HLT) ** bailing out since non-triplets in input." << std::endl;
00107
00108 if( !isAllTriplets || !isMergeTriplets_ ) {
00109 quads_.reserve(nInputTriplets);
00110 for( unsigned int it = 0; it < nInputTriplets; ++it ) {
00111 quads_.push_back( (tripletCache[it]));
00112 }
00113
00114 return quads_;
00115 }
00116
00117
00118 quads_.reserve(0.2*nInputTriplets);
00119
00120
00121
00122
00123 std::vector<bool> usedTriplets(nInputTriplets,false);
00124 std::pair<TransientTrackingRecHit::ConstRecHitPointer,TransientTrackingRecHit::ConstRecHitPointer> sharedHits;
00125 std::pair<TransientTrackingRecHit::ConstRecHitPointer,TransientTrackingRecHit::ConstRecHitPointer> nonSharedHits;
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 std::vector<unsigned int> t1List;
00145 std::vector<unsigned int> t2List;
00146 for (unsigned int t1=0; t1<nInputTriplets-1; t1++) {
00147 for (unsigned int t2=t1+1; t2<nInputTriplets; t2++) {
00148 if( fabs( phiEtaCache[t1].second - phiEtaCache[t2].second ) > 0.05 )
00149 continue;
00150 double temp = fabs( phiEtaCache[t1].first - phiEtaCache[t2].first );
00151 if( (temp > 0.15) && (temp <6.133185) ) {
00152 continue;
00153 }
00154 t1List.push_back(t1);
00155 t2List.push_back(t2);
00156 }
00157 }
00158
00159 for( ctfseeding::SeedingLayerSets::const_iterator lsIt = theLayerSets_.begin(); lsIt < theLayerSets_.end(); ++lsIt ) {
00160
00161
00162 std::vector<SeedMergerPixelLayer> currentLayers;
00163 currentLayers.reserve(lsIt->size());
00164 for( ctfseeding::SeedingLayers::const_iterator layIt = lsIt->begin(); layIt < lsIt->end(); ++layIt ) {
00165 currentLayers.push_back( SeedMergerPixelLayer( layIt->name() ) );
00166 }
00167
00168
00169
00170
00171
00172 for( unsigned int s1=0; s1<currentLayers.size()-1; s1++) {
00173
00174 for( unsigned int s2=s1+1; s2<currentLayers.size(); s2++) {
00175
00176 std::vector<unsigned int> nonSharedLayerNums;
00177 for ( unsigned int us1=0; us1<currentLayers.size(); us1++) {
00178 if ( s1!=us1 && s2!=us1) nonSharedLayerNums.push_back(us1);
00179 }
00180
00181
00182 for (unsigned int t12=0; t12<t1List.size(); t12++) {
00183 unsigned int t1=t1List[t12];
00184 unsigned int t2=t2List[t12];
00185
00186 if (usedTriplets[t1] || usedTriplets[t2] ) continue;
00187
00188
00189
00190
00191 if( isTripletsShareHitsOnLayers( (tripletCache[t1]), (tripletCache[t2]),
00192 currentLayers[s1],
00193 currentLayers[s2], sharedHits ) ) {
00194
00195
00196 if( isMergeableHitsInTriplets( (tripletCache[t1]), (tripletCache[t2]),
00197 currentLayers[nonSharedLayerNums[0]],
00198 currentLayers[nonSharedLayerNums[1]], nonSharedHits ) ) {
00199
00200
00201 std::vector<TransientTrackingRecHit::ConstRecHitPointer> unsortedHits=mySort(sharedHits.first,
00202 sharedHits.second,
00203 nonSharedHits.first,
00204 nonSharedHits.second);
00205
00206
00207 if( isValidQuadruplet( unsortedHits, currentLayers ) ) {
00208
00209 SeedingHitSet quadruplet(unsortedHits[0],unsortedHits[1],unsortedHits[2],unsortedHits[3]);
00210
00211
00212 quads_.push_back( quadruplet );
00213
00214
00215 usedTriplets[t1]=true;
00216 usedTriplets[t2]=true;
00217 }
00218
00219 }
00220 }
00221
00222 }
00223 }
00224 }
00225
00226 }
00227
00228
00229 if( isAddRemainingTriplets_ ) {
00230 for( unsigned int it = 0; it < nInputTriplets; ++it ) {
00231 if ( !usedTriplets[it] )
00232 quads_.push_back( tripletCache[it]);
00233 }
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 return quads_;
00248
00249 }
00250
00251
00252
00263 const TrajectorySeedCollection QuadrupletSeedMerger::mergeTriplets( const TrajectorySeedCollection& seedCollection,
00264 const TrackingRegion& region,
00265 const edm::EventSetup& es,
00266 const edm::ParameterSet& cfg ) {
00267
00268
00269
00270 es.get<TransientRecHitRecord>().get( theTTRHBuilderLabel_, theTTRHBuilder_ );
00271
00272
00273 TrajectorySeedCollection theResult;
00274
00275
00276
00277 bool isAllTriplets = true;
00278 for( TrajectorySeedCollection::const_iterator aTrajectorySeed = seedCollection.begin();
00279 aTrajectorySeed < seedCollection.end(); ++aTrajectorySeed ) {
00280 if( 3 != aTrajectorySeed->nHits() ) isAllTriplets = false;
00281 }
00282
00283 if( !isAllTriplets && isMergeTriplets_ )
00284 std::cout << " [QuadrupletSeedMerger::mergeTriplets] (in RECO) -- bailing out since non-triplets in input." << std::endl;
00285
00286 if( !isAllTriplets || !isMergeTriplets_ ) {
00287 for( TrajectorySeedCollection::const_iterator aTrajectorySeed = seedCollection.begin();
00288 aTrajectorySeed < seedCollection.end(); ++aTrajectorySeed ) {
00289 theResult.push_back( *aTrajectorySeed );
00290 }
00291
00292 return theResult;
00293 }
00294
00295
00296
00297
00298
00299
00300 OrderedHitTriplets inputTriplets;
00301
00302
00303 for( TrajectorySeedCollection::const_iterator aTrajectorySeed = seedCollection.begin();
00304 aTrajectorySeed < seedCollection.end(); ++aTrajectorySeed ) {
00305
00306 std::vector<TransientTrackingRecHit::RecHitPointer> recHitPointers;
00307
00308
00309 const TrajectorySeed::range theHitsRange = aTrajectorySeed->recHits();
00310 for( edm::OwnVector<TrackingRecHit>::const_iterator aHit = theHitsRange.first;
00311 aHit < theHitsRange.second; ++aHit ) {
00312
00313
00314 recHitPointers.push_back( theTTRHBuilder_->build( &(*aHit) ) );
00315
00316 }
00317
00318
00319 inputTriplets.push_back( OrderedHitTriplet( recHitPointers.at( 0 ), recHitPointers.at( 1 ), recHitPointers.at( 2 ) ) );
00320
00321 }
00322
00323
00324 const OrderedSeedingHits &quadrupletHitSets = mergeTriplets( inputTriplets, es );
00325
00326
00327
00328
00329
00330
00331 edm::ParameterSet creatorPSet = cfg.getParameter<edm::ParameterSet>("SeedCreatorPSet");
00332 std::string const& creatorName = creatorPSet.getParameter<std::string>( "ComponentName" );
00333 SeedCreator* seedCreator = SeedCreatorFactory::get()->create( creatorName, creatorPSet );
00334
00335 for ( unsigned int i=0; i< quadrupletHitSets.size(); i++) {
00336
00337 seedCreator->trajectorySeed( theResult, quadrupletHitSets[i], region, es, 0 );
00338 }
00339
00340 return theResult;
00341
00342 }
00343
00344
00345
00349 bool QuadrupletSeedMerger::isEqual( const TrackingRecHit* hit1, const TrackingRecHit* hit2 ) const {
00350
00351 const double epsilon = 0.00001;
00352
00353 DetId det1 = hit1->geographicalId(), det2 = hit2->geographicalId();
00354 if (det1 == det2) {
00355 LocalPoint lp1 = hit1->localPosition(), lp2 = hit2->localPosition();
00356 if( ( fabs( lp1.x() - lp2.x() ) < epsilon ) &&
00357 ( fabs( lp1.y() - lp2.y() ) < epsilon ) ) {
00358 return true;
00359 }
00360
00361 }
00362 return false;
00363
00364 }
00365
00366
00367
00371 std::pair<double,double> QuadrupletSeedMerger::calculatePhiEta( SeedingHitSet const& nTuplet ) const {
00372
00373
00374
00375
00376
00377
00378 const TrackingRecHit* hit1 = nTuplet[0]->hit();
00379 const GeomDet* geomDet1 = theTrackerGeometry_->idToDet( hit1->geographicalId() );
00380
00381 const TrackingRecHit* hit2 = nTuplet[1]->hit();
00382 const GeomDet* geomDet2 = theTrackerGeometry_->idToDet( hit2->geographicalId() );
00383
00384 GlobalPoint p1=geomDet1->toGlobal( hit1->localPosition() );
00385 GlobalPoint p2=geomDet2->toGlobal( hit2->localPosition() );
00386
00387 const double x1 = p1.x();
00388 const double x2 = p2.x();
00389 const double y1 = p1.y();
00390 const double y2 = p2.y();
00391 const double z1 = p1.z();
00392 const double z2 = p2.z();
00393
00394 const double phi = atan2( x2 - x1, y2 -y1 );
00395 const double eta = acos( (z2 - z1) / sqrt( pow( x2 - x1, 2. ) + pow( y2 - y1, 2. ) + pow( z2 - z1, 2. ) ) );
00396
00397 std::pair<double,double> retVal;
00398 retVal=std::make_pair (phi,eta);
00399 return retVal;
00400
00401
00402 }
00403
00404
00405
00409 void QuadrupletSeedMerger::printHit( const TransientTrackingRecHit::ConstRecHitPointer& aRecHitPointer ) const {
00410
00411 printHit( aRecHitPointer->hit() );
00412
00413 }
00414
00415
00416
00420 void QuadrupletSeedMerger::printHit( const TrackingRecHit* aHit ) const {
00421
00422 const GeomDet* geomDet = theTrackerGeometry_->idToDet( aHit->geographicalId() );
00423 const double r = geomDet->surface().position().perp();
00424 const double x = geomDet->toGlobal( aHit->localPosition() ).x();
00425 const double y = geomDet->toGlobal( aHit->localPosition() ).y();
00426 const double z = geomDet->toGlobal( aHit->localPosition() ).z();
00427 std::cout << "<RecHit> x: " << x << " y: " << y << " z: " << z << " r: " << r << std::endl;
00428
00429 }
00430
00434 void QuadrupletSeedMerger::printNtuplet( const SeedingHitSet& aNtuplet ) const {
00435
00436 std::cout << "DUMPING NTUPLET OF SIZE:";
00437 std::cout << aNtuplet.size() << std::endl;
00438
00439 for( unsigned int aHit = 0; aHit < aNtuplet.size(); ++aHit ) {
00440
00441 const TrackingRecHit* theHit = aNtuplet[aHit]->hit();
00442 const GeomDet* geomDet = theTrackerGeometry_->idToDet( theHit->geographicalId() );
00443 const double x = geomDet->toGlobal( theHit->localPosition() ).x();
00444 const double y = geomDet->toGlobal( theHit->localPosition() ).y();
00445 const double z = geomDet->toGlobal( theHit->localPosition() ).z();
00446 const double r = sqrt( x*x + y*y );
00447
00448 unsigned int layer;
00449 std::string detName;
00450 if( PixelSubdetector::PixelBarrel == theHit->geographicalId().subdetId() ) {
00451 detName = "BPIX ";
00452 PixelBarrelName pbn( aNtuplet[aHit]->hit()->geographicalId());
00453 layer = pbn.layerName();
00454 }
00455 else {
00456 detName = "FPIX";
00457 if( z > 0 ) detName += "+";
00458 else detName += "-";
00459
00460 PixelEndcapName pen( theHit->geographicalId() );
00461 layer = pen.diskName();
00462 }
00463
00464 std::cout << "<NtupletHit> D: " << detName << " L: " << layer << " x: " << x << " y: " << y << " z: " << z << " r: " << r << std::endl;
00465
00466 }
00467
00468 std::cout << "<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
00469
00470 }
00471
00472
00473
00477 void QuadrupletSeedMerger::setTTRHBuilderLabel( std::string label ) {
00478
00479 theTTRHBuilderLabel_ = label;
00480
00481 }
00482
00483
00484
00488 void QuadrupletSeedMerger::setLayerListName( std::string layerListName ) {
00489 layerListName_ = layerListName;
00490 }
00491
00492
00493
00497 void QuadrupletSeedMerger::setMergeTriplets( bool isMergeTriplets ) {
00498 isMergeTriplets_ = isMergeTriplets;
00499 }
00500
00501
00502
00506 void QuadrupletSeedMerger::setAddRemainingTriplets( bool isAddTriplets ) {
00507 isAddRemainingTriplets_ = isAddTriplets;
00508 }
00509
00510
00511
00517 bool QuadrupletSeedMerger::isValidQuadruplet( std::vector<TransientTrackingRecHit::ConstRecHitPointer> &quadruplet, const std::vector<SeedMergerPixelLayer>& layers ) const {
00518
00519 const unsigned int quadrupletSize = quadruplet.size();
00520
00521
00522 if( quadrupletSize != layers.size() ) {
00523 std::cout << " [QuadrupletSeedMerger::isValidQuadruplet] ** WARNING: size mismatch: "
00524 << quadrupletSize << "/" << layers.size() << std::endl;
00525 return false;
00526 }
00527
00528
00529 for( unsigned int index = 0; index < quadrupletSize; ++index ) {
00530 if( ! layers[index].isContainsDetector( quadruplet[index]->geographicalId() ) ) {
00531 return false;
00532 }
00533 }
00534
00535 return true;
00536
00537 }
00538
00539
00540
00546 bool QuadrupletSeedMerger::isTripletsShareHitsOnLayers( const SeedingHitSet& firstTriplet, const SeedingHitSet& secondTriplet,
00547 const SeedMergerPixelLayer &shared1, const SeedMergerPixelLayer &shared2,
00548 std::pair<TransientTrackingRecHit::ConstRecHitPointer,TransientTrackingRecHit::ConstRecHitPointer>& hits ) const {
00549
00550 bool isSuccess1[2],isSuccess2[2];
00551 isSuccess1[0]=false;
00552 isSuccess1[1]=false;
00553 isSuccess2[0]=false;
00554 isSuccess2[1]=false;
00555
00556 std::pair<TransientTrackingRecHit::ConstRecHitPointer,TransientTrackingRecHit::ConstRecHitPointer> hitsTriplet1, hitsTriplet2;
00557
00558
00559 for( unsigned int index = 0; index < 3; ++index )
00560 {
00561 if( ! firstTriplet[index]->isValid() ) return false;
00562 bool firsthit(false);
00563 DetId const& thisDetId = firstTriplet[index]->hit()->geographicalId();
00564
00565 if( ! isSuccess1[0] ) {
00566 if( shared1.isContainsDetector( thisDetId ) ) {
00567 isSuccess1[0] = true;
00568 firsthit = true;
00569 hitsTriplet1.first = firstTriplet[index];
00570 }
00571 }
00572
00573 if ( (! firsthit) && (! isSuccess1[1] ) && ((index !=3) || isSuccess1[0]) ) {
00574 if( shared2.isContainsDetector( thisDetId ) ) {
00575 isSuccess1[1] = true;
00576 hitsTriplet1.second = firstTriplet[index];
00577 }
00578 }
00579 }
00580
00581 if ( isSuccess1[0] && isSuccess1[1]) {
00582 for( unsigned int index = 0; index < 3; ++index )
00583 {
00584 if( ! secondTriplet[index]->isValid() ) { return false; }
00585 bool firsthit(false);
00586 DetId const& thisDetId = secondTriplet[index]->hit()->geographicalId();
00587
00588 if( ! isSuccess2[0] ) {
00589 if( shared1.isContainsDetector( thisDetId ) ) {
00590 isSuccess2[0] = true;
00591 firsthit = true;
00592 hitsTriplet2.first = secondTriplet[index];
00593 }
00594 }
00595
00596 if( (! firsthit) && (! isSuccess2[1]) && ((index !=3) || isSuccess2[0]) ) {
00597 if( shared2.isContainsDetector( thisDetId ) ) {
00598 isSuccess2[1] = true;
00599 hitsTriplet2.second = secondTriplet[index];
00600 }
00601 }
00602 }
00603
00604
00605 if( isSuccess2[0] && isSuccess2[1] ) {
00606 if( isEqual( hitsTriplet1.first->hit(), hitsTriplet2.first->hit() ) &&
00607 isEqual( hitsTriplet1.second->hit(), hitsTriplet2.second->hit() ) ) {
00608
00609
00610 hits.first = hitsTriplet1.first;
00611 hits.second = hitsTriplet1.second;
00612 return true;
00613 }
00614 }
00615 }
00616
00617
00618 return false;
00619
00620 }
00621
00622
00623
00628 bool QuadrupletSeedMerger::isMergeableHitsInTriplets( const SeedingHitSet& firstTriplet, const SeedingHitSet& secondTriplet,
00629 const SeedMergerPixelLayer &nonShared1, const SeedMergerPixelLayer &nonShared2,
00630 std::pair<TransientTrackingRecHit::ConstRecHitPointer,TransientTrackingRecHit::ConstRecHitPointer>& hits ) const {
00631
00632
00633 for( unsigned int index1 = 0; index1 < 3; ++index1 ) {
00634
00635 {
00636 DetId const& aDetId = firstTriplet[index1]->hit()->geographicalId();
00637 if( nonShared1.isContainsDetector( aDetId ) ) {
00638
00639
00640 for( unsigned int index2 = 0; index2 < 3; ++index2 ) {
00641
00642 DetId const& anotherDetId = secondTriplet[index2]->hit()->geographicalId();
00643 if( nonShared2.isContainsDetector( anotherDetId ) ) {
00644
00645
00646 hits.first = firstTriplet[index1];
00647 hits.second = secondTriplet[index2];
00648 return true;
00649
00650 }
00651 }
00652 }
00653 }
00654
00655
00656
00657 {
00658 DetId const& aDetId = secondTriplet[index1]->hit()->geographicalId();
00659 if( nonShared1.isContainsDetector( aDetId ) ) {
00660
00661
00662 for( unsigned int index2 = 0; index2 < 3; ++index2 ) {
00663
00664 DetId const& anotherDetId = firstTriplet[index2]->hit()->geographicalId();
00665 if( nonShared2.isContainsDetector( anotherDetId ) ) {
00666
00667
00668 hits.first = firstTriplet[index1];
00669 hits.second = secondTriplet[index2];
00670 return true;
00671
00672 }
00673 }
00674 }
00675 }
00676
00677 }
00678
00679 return false;
00680
00681 }
00682
00683
00684
00688 SeedMergerPixelLayer::SeedMergerPixelLayer( const std::string& name ) {
00689
00690 if( ! isValidName( name ) ) {
00691 std::cerr << " [SeedMergerPixelLayer::SeedMergerPixelLayer] ** ERROR: illegal name: \"" << name << "\"." << std::endl;
00692 isValid_ = false;
00693 return;
00694 }
00695
00696
00697 name_ = name;
00698
00699
00700 if( std::string::npos != name_.find( "BPix" ) )
00701 { subdet_ = PixelSubdetector::PixelBarrel; side_ = Undefined;}
00702 else if( std::string::npos != name_.find( "FPix" ) )
00703 { subdet_ = PixelSubdetector::PixelEndcap;
00704 if( std::string::npos != name_.find( "pos", 6 ) ) side_ = Plus;
00705 else if( std::string::npos != name_.find( "neg", 6 ) ) side_ = Minus;
00706 else {
00707 std::cerr << " [PixelLayerNameParser::side] ** ERROR: something's wrong here.." << std::endl;
00708 side_ = SideError;
00709 }
00710 }
00711 else {
00712 std::cerr << " [PixelLayerNameParser::subdetector] ** ERROR: something's wrong here.." << std::endl;
00713 }
00714
00715
00716 layer_ = atoi( name_.substr( 4, 1 ).c_str() );
00717
00718 }
00719
00720
00721
00725 bool SeedMergerPixelLayer::isValidName( const std::string& name ) {
00726
00727 const int layer = atoi( name.substr( 4, 1 ).c_str() );
00728
00729 if( std::string::npos != name.find( "BPix" ) ) {
00730 if( layer > 0 && layer < 5 ) return true;
00731 }
00732
00733 else if( std::string::npos != name.find( "FPix" ) ) {
00734 if( layer > 0 && layer < 4 ) {
00735 if( std::string::npos != name.find( "pos", 6 ) || std::string::npos != name.find( "neg", 6 ) ) return true;
00736 }
00737
00738 }
00739
00740 std::cerr << " [SeedMergerPixelLayer::isValidName] ** WARNING: invalid name: \"" << name << "\"." << std::endl;
00741 return false;
00742
00743 }
00744
00745
00746
00751 bool SeedMergerPixelLayer::isContainsDetector( const DetId& detId ) const {
00752
00753 PixelSubdetector::SubDetector subdet = getSubdet();
00754
00755
00756 if( detId.subdetId() == subdet ) {
00757
00758
00759 if( PixelSubdetector::PixelBarrel == subdet ) {
00760 const PXBDetId cmssw_numbering(detId);
00761 if (cmssw_numbering.layer() == getLayerNumber()) {
00762 return true;
00763 }
00764 }
00765
00766
00767 else if( PixelSubdetector::PixelEndcap == subdet ) {
00768 PXFDetId px_numbering(detId);
00769 if (px_numbering.disk() == getLayerNumber()) {
00770 if (px_numbering.side() == (unsigned)getSide()) {
00771 return true;
00772 }
00773 }
00774 }
00775
00776 }
00777
00778 return false;
00779
00780 }
00781
00782
00783 std::vector<TransientTrackingRecHit::ConstRecHitPointer> QuadrupletSeedMerger::mySort(TransientTrackingRecHit::ConstRecHitPointer &h1,
00784 TransientTrackingRecHit::ConstRecHitPointer &h2,
00785 TransientTrackingRecHit::ConstRecHitPointer &h3,
00786 TransientTrackingRecHit::ConstRecHitPointer &h4) {
00787
00788 std::vector<TransientTrackingRecHit::ConstRecHitPointer> unsortedHits;
00789 unsortedHits.reserve(4);
00790 unsortedHits.push_back( h1);
00791 unsortedHits.push_back( h2);
00792 unsortedHits.push_back( h3);
00793 unsortedHits.push_back( h4);
00794
00795 float radiiSq[4];
00796 for ( unsigned int iR=0; iR<4; iR++){
00797 const GeomDet* geom1=theTrackerGeometry_->idToDet( unsortedHits[iR]->hit()->geographicalId() );
00798 GlobalPoint p1=geom1->toGlobal( unsortedHits[iR]->hit()->localPosition() );
00799 radiiSq[iR]=( p1.x()*p1.x()+p1.y()*p1.y());
00800 }
00801 TransientTrackingRecHit::ConstRecHitPointer tempRHP;
00802 float tempFloat=0.;
00803 for ( unsigned int iR1=0; iR1<3; iR1++) {
00804 for ( unsigned int iR2=iR1+1; iR2<4; iR2++) {
00805 if (radiiSq[iR1]>radiiSq[iR2]) {
00806 tempRHP=unsortedHits[iR1];
00807 unsortedHits[iR1]=unsortedHits[iR2];
00808 unsortedHits[iR2]=tempRHP;
00809 tempFloat=radiiSq[iR1];
00810 radiiSq[iR1]=radiiSq[iR2];
00811 radiiSq[iR2]=tempFloat;
00812 }
00813 }
00814 }
00815 return unsortedHits;
00816 }
00817
00818
00819