47 (
"GsfTrackModuleLabel"));
53 (
"PrimaryVertexLabel"));
72 produces<GsfPFRecTrackCollection>();
73 produces<GsfPFRecTrackCollection>(
"Secondary" ).setBranchAlias(
"secondary" );
116 auto gsfPFRecTrackCollection = std::make_unique<GsfPFRecTrackCollection>();
118 auto gsfPFRecTrackCollectionSecondary = std::make_unique<GsfPFRecTrackCollection>();
160 vector<Trajectory> tjvec(0);
164 tjvec= *(TrajectoryCollection.
product());
168 vector<reco::GsfPFRecTrack> selGsfPFRecTracks;
169 vector<reco::GsfPFRecTrack> primaryGsfPFRecTracks;
170 std::map<unsigned int, std::vector<reco::GsfPFRecTrack> > GsfPFMap;
172 for(
unsigned igsf = 0; igsf < gsftracks.size(); igsf++ ) {
183 for (
unsigned int igsf=0; igsf<gsftracks.size();igsf++) {
187 int kf_ind=
FindPfRef(PfRTkColl,gsftracks[igsf],
false);
199 bool isEcalDriven =
true;
200 bool isTrackerDriven =
true;
202 if (&(*trackRef->seedRef())==
nullptr) {
203 isEcalDriven =
false;
204 isTrackerDriven =
false;
207 auto const& SeedFromRef=
static_cast<ElectronSeed const&
>(*(trackRef->extra()->seedRef()) );
208 if(SeedFromRef.caloCluster().isNull())
209 isEcalDriven =
false;
210 if(SeedFromRef.ctfTrack().isNull())
211 isTrackerDriven =
false;
214 if(isFifthStepTrack &&
216 isTrackerDriven ==
false &&
221 if(isFifthStepTrack &&
223 isEcalDriven ==
false &&
228 if(isFifthStepTrack &&
250 bool validgsfbrem =
false;
266 if(validgsfbrem && passSel)
267 selGsfPFRecTracks.push_back(
pftrack_);
271 unsigned int count_primary = 0;
272 if(!selGsfPFRecTracks.empty()) {
273 for(
unsigned int ipfgsf=0; ipfgsf<selGsfPFRecTracks.size();ipfgsf++) {
275 vector<unsigned int> secondaries(0);
280 keepGsf =
resolveGsfTracks(selGsfPFRecTracks,ipfgsf,secondaries,theEcalClusters);
284 if(keepGsf ==
true) {
287 if(
convBremFinder_->foundConvBremPFRecTrack(thePfRecTrackCollection,thePrimaryVertexColl,
288 pfNuclears,pfConversions,pfV0,
291 theEcalClusters,selGsfPFRecTracks[ipfgsf])) {
292 const vector<PFRecTrackRef>& convBremPFRecTracks(
convBremFinder_->getConvBremPFRecTracks());
293 for(
unsigned int ii = 0;
ii<convBremPFRecTracks.size();
ii++) {
294 selGsfPFRecTracks[ipfgsf].addConvBremPFRecTrackRef(convBremPFRecTracks[
ii]);
300 primaryGsfPFRecTracks.push_back(selGsfPFRecTracks[ipfgsf]);
306 unsigned int primGsfIndex = selGsfPFRecTracks[ipfgsf].trackId();
307 vector<reco::GsfPFRecTrack> trueGsfPFRecTracks;
308 if(!secondaries.empty()) {
310 for(
unsigned int isecpfgsf=0; isecpfgsf<secondaries.size();isecpfgsf++) {
312 PFRecTrackRef refsecKF = selGsfPFRecTracks[(secondaries[isecpfgsf])].kfPFRecTrackRef();
314 unsigned int secGsfIndex = selGsfPFRecTracks[(secondaries[isecpfgsf])].trackId();
315 GsfTrackRef secGsfRef = selGsfPFRecTracks[(secondaries[isecpfgsf])].gsfTrackRef();
321 primGsfIndex, secGsfRef,
329 primGsfIndex, secGsfRef,
333 bool validgsfbrem =
false;
336 gsftracks[secGsfIndex],
341 gsftracks[secGsfIndex],
346 gsfPFRecTrackCollectionSecondary->push_back(
secpftrack_);
351 GsfPFMap.insert(pair<
unsigned int,std::vector<reco::GsfPFRecTrack> >(count_primary,trueGsfPFRecTracks));
352 trueGsfPFRecTracks.clear();
360 iEvent.
put(
std::move(gsfPFRecTrackCollectionSecondary),
"Secondary");
366 for(
unsigned int iGSF = 0; iGSF<primaryGsfPFRecTracks.size();iGSF++){
367 gsfPFRecTrackCollection->push_back(primaryGsfPFRecTracks[iGSF]);
371 selGsfPFRecTracks.clear();
373 primaryGsfPFRecTracks.clear();
381 std::vector<reco::GsfPFRecTrack>& gsfPFRecTrackPrimary,
382 const std::map<
unsigned int, std::vector<reco::GsfPFRecTrack> >& MapPrimSec) {
384 unsigned int csecgsf=0;
385 for (
std::map<
unsigned int, std::vector<reco::GsfPFRecTrack> >::const_iterator igsf = MapPrimSec.begin();
386 igsf != MapPrimSec.end(); igsf++,cgsf++) {
387 vector<reco::GsfPFRecTrack> SecGsfPF = igsf->second;
388 for (
unsigned int iSecGsf=0; iSecGsf < SecGsfPF.size(); iSecGsf++) {
390 gsfPFRecTrackPrimary[cgsf].addConvBremGsfPFRecTrackRef(refgprt);
404 if (&(*gsftk.
seedRef())==
nullptr)
return -1;
405 auto const & ElSeedFromRef=
static_cast<ElectronSeed const&
>( *(gsftk.
extra()->seedRef()) );
407 if (ElSeedFromRef.ctfTrack().isNull()){
408 reco::PFRecTrackCollection::const_iterator pft=PfRTkColl.begin();
409 reco::PFRecTrackCollection::const_iterator pftend=PfRTkColl.end();
412 unsigned int ish_max=0;
416 for(;pft!=pftend;++pft){
419 float dph= fabs(pft->trackRef()->phi()-gsftk.
phi());
421 float det=fabs(pft->trackRef()->eta()-gsftk.
eta());
422 float dr =
sqrt(dph*dph+det*det);
425 pft->trackRef()->recHitsBegin();
427 pft->trackRef()->recHitsEnd();
431 for(;hhit!=hhit_end;++hhit){
432 if (!(*hhit)->isValid())
continue;
437 for(;hit!=hit_end;++hit){
438 if (!(hit->isValid()))
continue;
448 ((ish==ish_max)&&(dr<dr_min))){
458 if (ibest<0)
return -1;
460 if((ish_max==0) || (dr_min>0.05))
return -1;
461 if(otherColl && (ish_max==0))
return -1;
467 reco::PFRecTrackCollection::const_iterator pft=PfRTkColl.begin();
468 reco::PFRecTrackCollection::const_iterator pftend=PfRTkColl.end();
471 for(;pft!=pftend;++pft){
473 if (pft->trackRef()==ElSeedFromRef.ctfTrack()){
485 if (&(*gsftk.
seedRef())==
nullptr)
return false;
486 auto const& ElSeedFromRef=
static_cast<ElectronSeed const&
>( *(gsftk.
extra()->seedRef()) );
488 bool passCut =
false;
489 if (ElSeedFromRef.ctfTrack().isNull()){
490 if(ElSeedFromRef.caloCluster().isNull())
return passCut;
491 auto const* scRef =
static_cast<SuperCluster const*
>(ElSeedFromRef.caloCluster().get());
494 float caloEne = scRef->
energy();
495 float feta = fabs(scRef->eta()-gsftk.
etaMode());
496 float fphi = fabs(scRef->phi()-gsftk.
phiMode());
511 vector<unsigned int> &secondaries,
514 bool n_keepGsf =
true;
518 if (&(*nGsfTrack->seedRef())==
nullptr)
return false;
519 auto const& nElSeedFromRef=
static_cast<ElectronSeed const&
>( *(nGsfTrack->extra()->seedRef()) );
532 float neta = nGsfTrack->innerMomentum().eta();
533 float nphi = nGsfTrack->innerMomentum().phi();
539 cout <<
" PFElecTkProducer:: considering track " << nGsfTrack->pt()
540 <<
" eta,phi " << nGsfTrack->eta() <<
", " << nGsfTrack->phi() << endl;
543 for (
unsigned int igsf=0; igsf< GsfPFVec.size();igsf++) {
548 cout <<
" PFElecTkProducer:: and comparing with track " << iGsfTrack->pt()
549 <<
" eta,phi " << iGsfTrack->eta() <<
", " << iGsfTrack->phi() << endl;
551 float ieta = iGsfTrack->innerMomentum().eta();
552 float iphi = iGsfTrack->innerMomentum().phi();
553 float feta = fabs(neta - ieta);
554 float fphi = fabs(nphi - iphi);
559 if(feta < 0.5 && fabs(fphi) < 1.0) {
561 cout <<
" Entering angular superloose preselection " << endl;
574 if (&(*iGsfTrack->seedRef())==
nullptr)
continue;
575 auto const& iElSeedFromRef=
static_cast<ElectronSeed const&
>( *(iGsfTrack->extra()->seedRef()) );
577 float SCEnergy = -1.;
579 bool areBothGsfEcalDriven =
false;;
580 bool isSameSC =
isSameEgSC(nElSeedFromRef,iElSeedFromRef,areBothGsfEcalDriven,SCEnergy);
583 if(areBothGsfEcalDriven ) {
585 float nEP = SCEnergy/nPin;
586 float iEP = SCEnergy/iPin;
588 cout <<
" Entering SAME supercluster case " 590 <<
" iEP " << iEP << endl;
598 bool isSameLayer =
false;
599 bool iGsfInnermostWithLostHits =
604 cout <<
" iGsf is InnerMostWithLostHits " << iGsfInnermostWithLostHits
605 <<
" isSameLayer " << isSameLayer << endl;
607 if (iGsfInnermostWithLostHits) {
611 else if(isSameLayer){
612 if(fabs(iEP-1) < fabs(nEP-1)) {
617 secondaries.push_back(igsf);
622 secondaries.push_back(igsf);
628 float minBremDphi =
minTangDist(GsfPFVec[ngsf],GsfPFVec[igsf]);
631 bool isBothGsfTrackerDriven =
false;
632 bool nEcalDriven =
false;
633 bool iEcalDriven =
false;
639 isBothGsfTrackerDriven,
646 bool isSameLayer =
false;
647 bool iGsfInnermostWithLostHits =
654 cout <<
" Sharing ECAL energy passed " 655 <<
" nEtot " << nETot
656 <<
" iEtot " << iETot << endl;
657 if(isBothGsfTrackerDriven)
658 cout <<
" Both Track are trackerDriven " << endl;
662 if (iGsfInnermostWithLostHits) {
666 else if(isSameLayer){
675 if(isBothGsfTrackerDriven ==
false) {
682 secondaries.push_back(igsf);
699 float nEP = ETot/nPin;
700 float iEP = ETot/iPin;
704 cout <<
" nETot " << nETot
705 <<
" iETot " << iETot
706 <<
" ETot " << ETot << endl
710 <<
" iEP " << iEP << endl;
713 if(fabs(iEP-1) < fabs(nEP-1)) {
718 secondaries.push_back(igsf);
723 secondaries.push_back(igsf);
728 bool secPushedBack =
false;
729 if(nEcalDriven ==
false && nETot == 0.) {
733 else if(iEcalDriven ==
false && iETot == 0.) {
734 secondaries.push_back(igsf);
735 secPushedBack =
true;
738 cout <<
" Close Tracks " 739 <<
" feta " << feta <<
" fabs(fphi) " << fabs(fphi)
740 <<
" minBremDphi " << minBremDphi
741 <<
" nETot " << nETot
742 <<
" iETot " << iETot
743 <<
" nLostHits " << nGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS)
744 <<
" iLostHits " << iGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS) << endl;
748 if (iGsfInnermostWithLostHits) {
752 else if(isSameLayer ==
false) {
753 if(secPushedBack ==
false)
754 secondaries.push_back(igsf);
758 else if(feta < 0.1 && minBremDphi < 0.2){
762 cout <<
" Close Tracks and failed all the conditions " 763 <<
" feta " << feta <<
" fabs(fphi) " << fabs(fphi)
764 <<
" minBremDphi " << minBremDphi
765 <<
" nETot " << nETot
766 <<
" iETot " << iETot
767 <<
" nLostHits " << nGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS)
768 <<
" iLostHits " << iGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS) << endl;
770 if(nEcalDriven ==
false && nETot == 0.) {
787 float minDphi = 1000.;
790 std::vector<reco::PFBrem> primPFBrem = primGsf.
PFRecBrem();
791 std::vector<reco::PFBrem> secPFBrem = secGsf.
PFRecBrem();
794 unsigned int cbrem = 0;
795 for (
unsigned isbrem = 0; isbrem < secPFBrem.size(); isbrem++) {
796 if(secPFBrem[isbrem].indTrajPoint() == 99)
continue;
799 if( ! atSecECAL.
isValid() )
continue;
802 unsigned int sbrem = 0;
803 for(
unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
804 if(primPFBrem[ipbrem].indTrajPoint() == 99)
continue;
807 if( ! atPrimECAL.
isValid() )
continue;
812 float dphi = fabs(primPhi - secPhi);
814 if(fabs(dphi) < minDphi) {
815 minDphi = fabs(dphi);
830 bool& bothGsfEcalDriven,
833 bool isSameSC =
false;
839 if(nscRef && iscRef) {
840 bothGsfEcalDriven =
true;
841 if(nscRef == iscRef) {
844 SCEnergy = nscRef->
energy();
856 bool& bothGsfTrackerDriven,
862 bool isSharingEnergy =
false;
865 bool oneEcalDriven =
true;
872 nEnergy = scRef->
energy();
874 gsfPfTrack = iGsfPFRecTrack;
879 iEnergy = scRef->
energy();
881 gsfPfTrack = nGsfPFRecTrack;
884 oneEcalDriven =
false;
890 vector<PFCluster> vecPFClusters;
891 vecPFClusters.clear();
893 for (PFClusterCollection::const_iterator clus = theEClus.begin();
894 clus != theEClus.end();
905 if(deta < 0.5 && fabs(dphi) < 1.0) {
911 iEnergy += clust.
energy();
913 nEnergy += clust.
energy();
914 vecPFClusters.push_back(clust);
918 vector<PFBrem> primPFBrem = gsfPfTrack.
PFRecBrem();
919 for(
unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
920 if(primPFBrem[ipbrem].indTrajPoint() == 99)
continue;
926 iEnergy += clust.
energy();
928 nEnergy += clust.
energy();
929 vecPFClusters.push_back(clust);
935 if(!vecPFClusters.empty() ) {
936 for(
unsigned int pf = 0;
pf < vecPFClusters.size();
pf++) {
939 isSharingEnergy =
true;
948 bothGsfTrackerDriven =
true;
949 vector<PFCluster> nPFCluster;
950 vector<PFCluster> iPFCluster;
955 for (PFClusterCollection::const_iterator clus = theEClus.begin();
956 clus != theEClus.end();
966 if(ndeta < 0.5 && fabs(ndphi) < 1.0) {
971 nPFCluster.push_back(clust);
972 nEnergy += clust.
energy();
975 const vector<PFBrem>& primPFBrem = nGsfPFRecTrack.
PFRecBrem();
976 for(
unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
977 if(primPFBrem[ipbrem].indTrajPoint() == 99)
continue;
982 nPFCluster.push_back(clust);
983 nEnergy += clust.
energy();
995 if(ideta < 0.5 && fabs(idphi) < 1.0) {
999 iPFCluster.push_back(clust);
1000 iEnergy += clust.
energy();
1003 vector<PFBrem> primPFBrem = iGsfPFRecTrack.
PFRecBrem();
1004 for(
unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
1005 if(primPFBrem[ipbrem].indTrajPoint() == 99)
continue;
1009 iPFCluster.push_back(clust);
1010 iEnergy += clust.
energy();
1019 if(!nPFCluster.empty() && !iPFCluster.empty()) {
1020 for(
unsigned int npf = 0; npf < nPFCluster.size(); npf++) {
1021 for(
unsigned int ipf = 0; ipf < iPFCluster.size(); ipf++) {
1024 isSharingEnergy =
true;
1034 return isSharingEnergy;
1047 int gsfHitCounter1 = 0 ;
1050 ( elHitsIt1 = nGsfTrack->recHitsBegin() ;
1051 elHitsIt1 != nGsfTrack->recHitsEnd() ;
1052 elHitsIt1++, gsfHitCounter1++ )
1053 {
if (((**elHitsIt1).isValid())) break ; }
1055 int gsfHitCounter2 = 0 ;
1058 ( elHitsIt2 = iGsfTrack->recHitsBegin() ;
1059 elHitsIt2 != iGsfTrack->recHitsEnd() ;
1060 elHitsIt2++, gsfHitCounter2++ )
1061 {
if (((**elHitsIt2).isValid())) break ; }
1063 uint32_t gsfHit1 = gsfHitPattern1.
getHitPattern(HitPattern::TRACK_HITS, gsfHitCounter1) ;
1064 uint32_t gsfHit2 = gsfHitPattern2.
getHitPattern(HitPattern::TRACK_HITS, gsfHitCounter2) ;
1071 else if (gsfHitPattern1.
getLayer(gsfHit1)!=gsfHitPattern2.
getLayer(gsfHit2))
1073 return (gsfHitPattern2.
getLayer(gsfHit2)<gsfHitPattern1.
getLayer(gsfHit1));
1086 unsigned int nLostHits = nGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
1087 unsigned int iLostHits = iGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
1089 if (nLostHits!=iLostHits) {
1090 return (nLostHits > iLostHits);
const REPPoint & positionREP() const
trajectory position in (rho, eta, phi) base
bool trajinev_
Trajectory of GSfTracks in the event?
const edm::RefToBase< TrajectorySeed > & seedRef() const
value_type const * get() const
T getParameter(std::string const &) const
const math::XYZPoint & position() const
cluster centroid position
reconstructed track used as an input to particle flow
edm::EDGetTokenT< reco::PFRecTrackCollection > pfTrackLabel_
static uint32_t getLayer(uint16_t pattern)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
static bool overlap(const reco::CaloCluster &sc1, const reco::CaloCluster &sc, float minfrac=0.01, bool debug=false)
bool isNonnull() const
Checks for non-null.
edm::EDGetTokenT< reco::GsfTrackCollection > gsfTrackLabel_
void createGsfPFRecTrackRef(const edm::OrphanHandle< reco::GsfPFRecTrackCollection > &gsfPfHandle, std::vector< reco::GsfPFRecTrack > &gsfPFRecTrackPrimary, const std::map< unsigned int, std::vector< reco::GsfPFRecTrack > > &MapPrimSec)
const TrackExtraRef & extra() const
reference to "extra" object
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
double mvaConvBremFinderIDEndcapsLowPt_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
bool useFifthStepForTrackDriven_
const std::vector< reco::PFBrem > & PFRecBrem() const
const CaloClusterRef & caloCluster() const
double phi() const
azimuthal angle of momentum vector
bool applySelection(const reco::GsfTrack &)
bool isNonnull() const
Checks for non-null.
key_type key() const
Accessor for product key.
bool momentumFromModeCartesian(const TrajectoryStateOnSurface tsos, GlobalVector &momentum) const
reco::GsfPFRecTrack secpftrack_
std::unique_ptr< ConvBremPFTrackFinder > convBremFinder_
void swap(Association< C > &lhs, Association< C > &rhs)
~PFElecTkProducer() override
Destructor.
edm::EDGetTokenT< reco::VertexCollection > primVtxLabel_
const MultiTrajectoryStateMode * mtsMode_
double mvaConvBremFinderIDBarrelLowPt_
double eta() const
pseudorapidity of momentum vector
void calculatePositionREP()
computes posrep_ once and for all
edm::EDGetTokenT< reco::PFV0Collection > pfV0_
const reco::GsfTrackRef & gsfTrackRef() const
recHitContainer::const_iterator const_iterator
std::vector< GsfTrack > GsfTrackCollection
collection of GsfTracks
double energy() const
cluster energy
edm::EDGetTokenT< reco::PFDisplacedTrackerVertexCollection > pfNuclear_
const reco::PFTrajectoryPoint & extrapolatedPoint(unsigned layerid) const
bool isSameEgSC(const reco::ElectronSeed &nSeed, const reco::ElectronSeed &iSeed, bool &bothGsfEcalDriven, float &SCEnergy)
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
static uint32_t getSubStructure(uint16_t pattern)
double energy() const
cluster energy
bool isInnerMostWithLostHits(const reco::GsfTrackRef &nGsfTrack, const reco::GsfTrackRef &iGsfTrack, bool &sameLayer)
PFElecTkProducer(const edm::ParameterSet &, const convbremhelpers::HeavyObjectCache *)
Constructor.
void endRun(const edm::Run &, const edm::EventSetup &) override
int FindPfRef(const reco::PFRecTrackCollection &PfRTkColl, const reco::GsfTrack &, bool)
bool resolveGsfTracks(const std::vector< reco::GsfPFRecTrack > &GsfPFVec, unsigned int ngsf, std::vector< unsigned int > &secondaries, const reco::PFClusterCollection &theEClus)
bool isValid() const
is this point valid ?
T const * product() const
XYZVectorD XYZVector
spatial vector with cartesian internal representation
double mvaConvBremFinderIDBarrelHighPt_
double mvaConvBremFinderIDEndcapsHighPt_
edm::EDGetTokenT< reco::PFConversionCollection > pfConv_
std::vector< Trajectory > TrajectoryCollection
void beginRun(const edm::Run &, const edm::EventSetup &) override
double etaMode() const
pseudorapidity of momentum vector from mode
bool useFifthStepForEcalDriven_
reco::GsfPFRecTrack pftrack_
void produce(edm::Event &, const edm::EventSetup &) override
Produce the PFRecTrack collection.
double phiMode() const
azimuthal angle of momentum vector from mode
bool useConvBremFinder_
Conv Brem Finder.
std::vector< PFCluster > PFClusterCollection
collection of PFCluster objects
A PFTrack holds several trajectory points, which basically contain the position and momentum of a tra...
std::unique_ptr< PFTrackTransformer > pfTransformer_
PFTrackTransformer.
std::vector< double > gsfInnerMomentumCache_
uint16_t getHitPattern(HitCategory category, int position) const
T const * product() const
static double testTrackAndClusterByRecHit(const reco::PFRecTrack &track, const reco::PFCluster &cluster, bool isBrem=false, bool debug=false)
float minTangDist(const reco::GsfPFRecTrack &primGsf, const reco::GsfPFRecTrack &secGsf)
std::vector< PFRecTrack > PFRecTrackCollection
collection of PFRecTrack objects
edm::EDGetTokenT< reco::PFClusterCollection > pfEcalClusters_
bool isSharingEcalEnergyWithEgSC(const reco::GsfPFRecTrack &nGsfPFRecTrack, const reco::GsfPFRecTrack &iGsfPFRecTrack, const reco::ElectronSeed &nSeed, const reco::ElectronSeed &iSeed, const reco::PFClusterCollection &theEClus, bool &bothGsfTrackerDriven, bool &nEcalDriven, bool &iEcalDriven, float &nEnergy, float &iEnergy)
bool applyAngularGsfClean_
TrackingRecHitCollection::base::const_iterator trackingRecHit_iterator
iterator over a vector of reference to TrackingRecHit in the same collection
MultiTrajectoryStateTransform mtsTransform_
bool isInnerMost(const reco::GsfTrackRef &nGsfTrack, const reco::GsfTrackRef &iGsfTrack, bool &sameLayer)