CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/RecoEgamma/EgammaPhotonAlgos/src/InOutConversionSeedFinder.cc

Go to the documentation of this file.
00001 #include "RecoEgamma/EgammaPhotonAlgos/interface/InOutConversionSeedFinder.h"
00002 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionBarrelEstimator.h"
00003 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionForwardEstimator.h"
00004 
00005 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionFastHelix.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 
00008 // Field
00009 #include "MagneticField/Engine/interface/MagneticField.h"
00010 //
00011 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
00012 // Geometry
00013 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00014 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00015 //
00016 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
00017 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00018 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00019 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00020 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h"
00021 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00022 //
00023 //
00024 #include "FWCore/Framework/interface/EventSetup.h"
00025 //
00026 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00027 #include "CLHEP/Geometry/Point3D.h"
00028 
00029 InOutConversionSeedFinder::InOutConversionSeedFinder( const edm::ParameterSet& conf ):
00030   ConversionSeedFinder( conf ), conf_(conf)  
00031 {
00032   
00033   
00034   // std::cout << " InOutConversionSeedFinder CTOR " << "\n";      
00035     
00036   maxNumberOfInOutSeedsPerInputTrack_ =  conf_.getParameter<int>("maxNumOfSeedsInOut");
00037   //the2ndHitdphi_ = 0.008; 
00038   the2ndHitdphi_ = 0.01; 
00039   the2ndHitdzConst_ = 5.;
00040   the2ndHitdznSigma_ = 2.;
00041  
00042   
00043 }
00044 
00045 
00046 
00047 InOutConversionSeedFinder::~InOutConversionSeedFinder() {
00048  //std::cout << " InOutConversionSeedFinder DTOR " << "\n";
00049 }
00050 
00051 
00052 
00053 void InOutConversionSeedFinder::makeSeeds( const edm::Handle<edm::View<reco::CaloCluster> > &  allBC )  const  {
00054   
00055 
00056   //std::cout << "  InOutConversionSeedFinder::makeSeeds() " << "\n";
00057   theSeeds_.clear();
00058   //std::cout << " Check Calo cluster collection size " << allBC->size() << "\n";  
00059   bcCollection_= allBC;
00060   
00061   
00062   findLayers();
00063   
00064   
00065   fillClusterSeeds();
00066   //std::cout << "Built vector of seeds of size  " << theSeeds_.size() <<  "\n" ;
00067   
00068   
00069   theOutInTracks_.clear();
00070   inputTracks_.clear();
00071   theFirstMeasurements_.clear();
00072   
00073 }
00074 
00075 
00076 void InOutConversionSeedFinder::fillClusterSeeds() const {
00077   
00078   std::vector<Trajectory>::const_iterator outInTrackItr;
00079   
00080  //std::cout << "  InOutConversionSeedFinder::fillClusterSeeds outInTracks_.size " << theOutInTracks_.size() << "\n";
00081   //Start looking for seeds for both of the 2 best tracks from the inward tracking
00082   
00084   /*
00085   for(outInTrackItr = theOutInTracks_.begin(); outInTrackItr != theOutInTracks_.end();  ++outInTrackItr) {
00086 
00087 
00088    //std::cout << " InOutConversionSeedFinder::fillClusterSeeds out in input track hits " << (*outInTrackItr).foundHits() << "\n";
00089     DetId tmpId = DetId( (*outInTrackItr).seed().startingState().detId());
00090     const GeomDet* tmpDet  = this->getMeasurementTracker()->geomTracker()->idToDet( tmpId );
00091     GlobalVector gv = tmpDet->surface().toGlobal( (*outInTrackItr).seed().startingState().parameters().momentum() );
00092 
00093 
00094    //std::cout << " InOutConversionSeedFinder::fillClusterSeed was built from seed position " <<gv   <<  " charge " << (*outInTrackItr).seed().startingState().parameters().charge() << "\n";
00095 
00096     Trajectory::DataContainer m=  outInTrackItr->measurements();
00097     int nHit=0;
00098     for (Trajectory::DataContainer::iterator itm = m.begin(); itm != m.end(); ++itm) {
00099       if ( itm->recHit()->isValid()  ) {
00100         nHit++;
00101         //std::cout << nHit << ")  Valid RecHit global position " << itm->recHit()->globalPosition() << " R " <<  itm->recHit()->globalPosition().perp() << " phi " << itm->recHit()->globalPosition().phi() << " eta " << itm->recHit()->globalPosition().eta() << "\n";
00102       } 
00103 
00104     }
00105 
00106   }
00107 
00108   */
00109 
00110 
00111   //Start looking for seeds for both of the 2 best tracks from the inward tracking
00112   for(outInTrackItr = theOutInTracks_.begin(); outInTrackItr != theOutInTracks_.end();  ++outInTrackItr) {
00113    //std::cout << " InOutConversionSeedFinder::fillClusterSeeds out in input track hits " << (*outInTrackItr).foundHits() << "\n";
00114     nSeedsPerInputTrack_=0;    
00115     
00116     //Find the first valid hit of the track
00117     // Measurements are ordered according to the direction in which the trajectories were built
00118     std::vector<TrajectoryMeasurement> measurements = (*outInTrackItr).measurements();
00119     
00120     std::vector<const DetLayer*> allLayers=layerList();
00121     
00122     //std::cout << "  InOutConversionSeedFinder::fill clusterSeed allLayers.size " <<  allLayers.size() << "\n";
00123     for(unsigned int i = 0; i < allLayers.size(); ++i) {
00124       //std::cout <<  " allLayers " << allLayers[i] << "\n"; 
00125       printLayer(i);
00126      }
00127     
00128     
00129     
00130     std::vector<const DetLayer*> myLayers;
00131     myLayers.clear();    
00132     std::vector<TrajectoryMeasurement>::reverse_iterator measurementItr;    
00133     std::vector<TrajectoryMeasurement*> myItr;
00134     // TrajectoryMeasurement* myPointer=0;
00135     myPointer=0;
00136     //std::cout << "  InOutConversionSeedFinder::fillClusterSeeds measurements.size " << measurements.size() <<"\n";
00137     
00138     for(measurementItr = measurements.rbegin() ; measurementItr != measurements.rend();  ++measurementItr) {
00139     
00140 
00141       if( (*measurementItr).recHit()->isValid()) {
00142         
00143         //std::cout << "  InOutConversionSeedFinder::fillClusterSeeds measurement on  layer  " << measurementItr->layer() <<   " " <<&(*measurementItr) <<  " position " << measurementItr->recHit()->globalPosition() <<   " R " << sqrt( measurementItr->recHit()->globalPosition().x()*measurementItr->recHit()->globalPosition().x() + measurementItr->recHit()->globalPosition().y()*measurementItr->recHit()->globalPosition().y() ) << " Z " << measurementItr->recHit()->globalPosition().z() << " phi " <<  measurementItr->recHit()->globalPosition().phi() << "\n";
00144         
00145         
00146         myLayers.push_back( measurementItr->layer() ) ; 
00147         myItr.push_back( &(*measurementItr) );
00148         
00149         
00150       }
00151     }
00152     
00153     
00154     
00155    //std::cout << " InOutConversionSeedFinder::fillClusterSeed myLayers.size " <<  myLayers.size() << "\n";
00156     //    for( unsigned int i = 0; i < myLayers.size(); ++i) {
00158     // }
00159     
00160     
00161     if ( myItr.size()==0 ) {
00162       //std::cout << "HORRENDOUS ERROR!  No meas on track!" << "\n";
00163     }      
00164     unsigned int ilayer;
00165     for(ilayer = 0; ilayer < allLayers.size(); ++ilayer) {
00166       //std::cout <<  " allLayers in the search loop  " << allLayers[ilayer] <<  " " << myLayers[0] <<  "\n"; 
00167       if ( allLayers[ilayer] == myLayers[0]) {
00168         
00169         myPointer=myItr[0];
00170         
00171         //std::cout <<  " allLayers in the search loop   allLayers[ilayer] == myLayers[0])  " << allLayers[ilayer] <<  " " << myLayers[0] <<  " myPointer " << myPointer << "\n"; 
00172         
00173         //std::cout  << "Layer " << ilayer << "  contains the first valid measurement " << "\n";        
00174         printLayer(ilayer);     
00175         
00176         if ( (myLayers[0])->location() == GeomDetEnumerators::barrel ) {
00177           //      const BarrelDetLayer * barrelLayer = dynamic_cast<const BarrelDetLayer*>(myLayers[0]);
00178          //std::cout << " InOutConversionSeedFinder::fillClusterSeeds  **** firstHit found in Barrel on layer " << ilayer  << " R= " << barrelLayer->specificSurface().radius() <<   "\n";
00179         } else {
00180           //const ForwardDetLayer * forwardLayer = dynamic_cast<const ForwardDetLayer*>(myLayers[0]);
00181          //std::cout << " InOutwardConversionSeedFinder::fillClusterSeeds  **** firstHit found in Forw on layer " << ilayer  << " Z= " << forwardLayer->specificSurface().position().z() <<  "\n";
00182         }
00183         
00184         
00185         break;
00186         
00187       } else if ( allLayers[ilayer] == myLayers[1] )  {
00188         myPointer=myItr[1];
00189         
00190         //std::cout <<  " allLayers in the search loop   allLayers[ilayer] == myLayers[1])  " << allLayers[ilayer] <<  " " << myLayers[1] <<  " myPointer " << myPointer << "\n"; 
00191         
00192         //std::cout << "Layer " << ilayer << "  contains the first innermost  valid measurement " << "\n";      
00193         if ( (myLayers[1])->location() == GeomDetEnumerators::barrel ) {
00194           //      const BarrelDetLayer * barrelLayer = dynamic_cast<const BarrelDetLayer*>(myLayers[1]);
00195          //std::cout << " InOutConversionSeedFinder::fillClusterSeeds  **** 2ndHit found in Barrel on layer " << ilayer  << " R= " << barrelLayer->specificSurface().radius() <<   "\n"; 
00196         } else {
00197           //const ForwardDetLayer * forwardLayer = dynamic_cast<const ForwardDetLayer*>(myLayers[1]);
00198          //std::cout << " InOutwardConversionSeedFinder::fillClusterSeeds  ****  2ndHitfound on forw layer " << ilayer  << " Z= " << forwardLayer->specificSurface().position().z() <<  "\n";
00199         }
00200         
00201         
00202         
00203         break;
00204         
00205       }
00206     }
00207     
00208     
00209     
00210     if(ilayer == allLayers.size()) {
00211      //std::cout << "InOutConversionSeedFinder::fillClusterSeeds ERROR could not find layer on list" <<  "\n"; 
00212       return;
00213     }
00214     
00215     //PropagatorWithMaterial reversePropagator(oppositeToMomentum, 0.000511, &(*theMF_) );
00216     FreeTrajectoryState * fts = myPointer->updatedState().freeTrajectoryState();
00217     
00218    //std::cout << " InOutConversionSeedFinder::fillClusterSeeds First FTS charge " << fts->charge() << " Position " << fts->position() << " momentum " << fts->momentum() << " R " << sqrt(fts->position().x()*fts->position().x() + fts->position().y()* fts->position().y() ) << " Z " << fts->position().z() << " phi " << fts->position().phi() << " fts parameters " << fts->parameters() << "\n";
00219     
00220     
00221     while (ilayer > 0) {
00222       
00223       //std::cout << " InOutConversionSeedFinder::fillClusterSeeds looking for 2nd seed from layer " << ilayer << "\n";
00224       
00225       //   if ( (allLayers[ilayer])->location() == GeomDetEnumerators::barrel ) {const BarrelDetLayer * barrelLayer = dynamic_cast<const BarrelDetLayer*>(allLayers[ilayer]);
00226       //std::cout <<  " InOutConversionSeedFinder::fillClusterSeeds  ****  Barrel on layer " << ilayer  << " R= " << barrelLayer->specificSurface().radius() <<  "\n";     
00227       // } else {
00228         //const ForwardDetLayer * forwardLayer = dynamic_cast<const ForwardDetLayer*>(allLayers[ilayer]);
00229         //std::cout <<  " InOutConversionSeedFinder::fillClusterSeeds  ****  Forw on layer " << ilayer  << " Z= " << forwardLayer->specificSurface().position().z() << "\n";
00230       //      }
00231       
00232      
00233      const DetLayer * previousLayer = allLayers[ilayer];
00234      TrajectoryStateOnSurface  stateAtPreviousLayer;
00235      //std::cout << " InOutConversionSeedFinder::fillClusterSeeds previousLayer->surface() position before  " <<allLayers[ilayer] << " " <<  previousLayer->surface().position() << " layer location " << previousLayer->location() << "\n";   
00236      // Propagate to the previous layer
00237      // The present layer is actually included in the loop so that a partner can be searched for
00238      // Applying the propagator to the same layer does not do any harm. It simply does nothing
00239      
00240      //     const Propagator& newProp=thePropagatorOppositeToMomentum_;  
00241      //std::cout << " InOutConversionSeedFinder::fillClusterSeeds reversepropagator direction " << thePropagatorOppositeToMomentum_->propagationDirection()  << "\n";
00242      if (ilayer-1>0) { 
00243        
00244        if ( allLayers[ilayer] == myLayers[0] ) {
00245          //std::cout << " innermost hit R " << myPointer->recHit()->globalPosition().perp() << " Z " << myPointer->recHit()->globalPosition().z() << " phi " <<myPointer->recHit()->globalPosition().phi() << "\n";
00246          //std::cout << " surface R " << theTrackerGeom_->idToDet(  myPointer->recHit() ->geographicalId())->surface().position().perp() <<  " Z " <<  theTrackerGeom_->idToDet(  myPointer->recHit() ->geographicalId())->surface().position().z() << " phi " << theTrackerGeom_->idToDet(  myPointer->recHit() ->geographicalId())->surface().position().phi() << "\n";
00247          
00248          stateAtPreviousLayer= thePropagatorOppositeToMomentum_->propagate(*fts,   theTrackerGeom_->idToDet(  myPointer->recHit() ->geographicalId())->surface()   );
00249          
00250        } else {
00251          
00252          stateAtPreviousLayer= thePropagatorOppositeToMomentum_->propagate(*fts, previousLayer->surface() );
00253          //std::cout << " InOutConversionSeedFinder::fillClusterSeeds previousLayer->surface() position after " << previousLayer->surface().position() << " layer location " << previousLayer->location() <<   "\n";
00254          
00255        }
00256        
00257      } else if ( ilayer-1==0) {
00258        
00259        
00262        
00263        //stateAtPreviousLayer= thePropagatorOppositeToMomentum_->propagate(*fts,   theTrackerGeom_->idToDet(  myPointer->recHit() ->geographicalId())->surface()   );
00264        stateAtPreviousLayer= thePropagatorOppositeToMomentum_->propagate(*fts, previousLayer->surface() );      
00265        
00266      }
00267      
00268      if(!stateAtPreviousLayer.isValid()) {
00269        //std::cout << "InOutConversionSeedFinder::fillClusterSeeds ERROR:could not propagate back to layer "  << ilayer << "\n";
00271      } else {
00272        //std::cout << "InOutConversionSeedFinder::fillClusterSeeds  stateAtPreviousLayer is valid.  Propagating back to layer "  << ilayer << "\n";
00273        //std::cout << "InOutConversionSeedFinder::fillClusterSeeds stateAtPreviousLayer R  " << stateAtPreviousLayer.globalPosition().perp()  << " Z " << stateAtPreviousLayer.globalPosition().z() << " phi " <<  stateAtPreviousLayer.globalPosition().phi() << "\n";
00274        
00275        startSeed(fts,  stateAtPreviousLayer, -1, ilayer ); 
00276        
00277        
00278      }      
00279      
00280      --ilayer;
00281      
00282     }
00283     
00284     if ( ilayer == 0) {
00285       
00286 
00287       //     if ( (allLayers[ilayer])->location() == GeomDetEnumerators::barrel ) {const BarrelDetLayer * barrelLayer = dynamic_cast<const BarrelDetLayer*>(allLayers[ilayer]);
00288       // //std::cout <<  " InOutConversionSeedFinder::fillClusterSeeds  ****  Barrel on layer " << ilayer  << " R= " << barrelLayer->specificSurface().radius() <<  "\n";     
00289       // } else {
00290       //const ForwardDetLayer * forwardLayer = dynamic_cast<const ForwardDetLayer*>(allLayers[ilayer]);
00291        //std::cout <<  " InOutConversionSeedFinder::fillClusterSeeds  ****  Forw on layer " << ilayer  << " Z= " << forwardLayer->specificSurface().position().z() << "\n";
00292       // }
00293      const DetLayer * previousLayer = allLayers[ilayer];
00294      TrajectoryStateOnSurface  stateAtPreviousLayer;
00295      stateAtPreviousLayer= thePropagatorOppositeToMomentum_->propagate(*fts, previousLayer->surface() );
00296 
00297      if(!stateAtPreviousLayer.isValid()) {
00298        //std::cout << "InOutConversionSeedFinder::fillClusterSeeds ERROR:could not propagate back to layer "  << ilayer << "\n";
00300      } else {
00301        //std::cout << "InOutConversionSeedFinder::fillClusterSeeds  stateAtPreviousLayer is valid.  Propagating back to layer "  << ilayer << "\n";
00302        //std::cout << "InOutConversionSeedFinder::fillClusterSeeds stateAtPreviousLayer R  " << stateAtPreviousLayer.globalPosition().perp()  << " Z " << stateAtPreviousLayer.globalPosition().z() << " phi " <<  stateAtPreviousLayer.globalPosition().phi() << "\n";
00303        
00304        startSeed(fts,  stateAtPreviousLayer, -1, ilayer ); 
00305      }     
00306        
00307      
00308    }
00309 
00310     
00311     
00312     
00313   }  // End loop over Out In tracks
00314   
00315   
00316   
00317 }
00318 
00319 
00320 
00321 void InOutConversionSeedFinder::startSeed( FreeTrajectoryState * fts, const TrajectoryStateOnSurface & stateAtPreviousLayer, int charge, int ilayer  )  const {
00322   
00323   //std::cout << "InOutConversionSeedFinder::startSeed ilayer " << ilayer <<  "\n";
00324   // Get a list of basic clusters that are consistent with a track 
00325   // starting at the assumed conversion point with opp. charge to the 
00326   // inward track.  Loop over these basic clusters.
00327   track2Charge_ = charge*fts->charge();
00328   std::vector<const reco::CaloCluster*> bcVec;
00329  //std::cout << "InOutConversionSeedFinder::startSeed charge assumed for the in-out track  " << track2Charge_ <<  "\n";
00330   
00331   Geom::Phi<float> theConvPhi( stateAtPreviousLayer.globalPosition().phi());
00332  //std::cout << "InOutConversionSeedFinder::startSeed  stateAtPreviousLayer phi " << stateAtPreviousLayer.globalPosition().phi() << " R " <<  stateAtPreviousLayer.globalPosition().perp() << " Z " << stateAtPreviousLayer.globalPosition().z() << "\n";
00333   
00334   bcVec = getSecondCaloClusters(stateAtPreviousLayer.globalPosition(),track2Charge_);
00335   
00336   std::vector<const reco::CaloCluster*>::iterator bcItr;
00337  //std::cout << "InOutConversionSeedFinder::startSeed bcVec.size " << bcVec.size() << "\n";
00338   
00339   // debug
00340   //  for(bcItr = bcVec.begin(); bcItr != bcVec.end(); ++bcItr) {
00341   //  //std::cout << "InOutConversionSeedFinder::startSeed list of  bc eta " << (*bcItr)->position().eta() << " phi " << (*bcItr)->position().phi() << " x " << (*bcItr)->position().x() << " y " << (*bcItr)->position().y() << " z " << (*bcItr)->position().z() << "\n";
00342   // }
00343   
00344 
00345   for(bcItr = bcVec.begin(); bcItr != bcVec.end(); ++bcItr) {
00346     
00347     theSecondBC_ = **bcItr;
00348     GlobalPoint bcPos((theSecondBC_.position()).x(),
00349                       (theSecondBC_.position()).y(),
00350                       (theSecondBC_.position()).z());
00351     
00352    //std::cout << "InOutConversionSeedFinder::startSeed for  bc position x " << bcPos.x() << " y " <<  bcPos.y() << " z  " <<  bcPos.z() << " eta " <<  bcPos.eta() << " phi " <<  bcPos.phi() << "\n";
00353     GlobalVector dir = stateAtPreviousLayer.globalDirection();
00354     GlobalPoint back1mm = stateAtPreviousLayer.globalPosition();
00355    //std::cout << "InOutConversionSeedFinder::startSeed   stateAtPreviousLayer.globalPosition() " << back1mm << "\n";
00356     
00357     back1mm -= dir.unit()*0.1;
00358     //std::cout << " InOutConversionSeedFinder:::startSeed going to make the helix using back1mm " << back1mm <<"\n";
00359     ConversionFastHelix helix(bcPos, stateAtPreviousLayer.globalPosition(), back1mm, &(*theMF_));
00360     helix.stateAtVertex();    
00361     
00362     //std::cout << " InOutConversionSeedFinder:::startSeed helix status " <<helix.isValid() << std::endl; 
00363     if ( !helix.isValid()  ) continue;
00364     findSeeds(stateAtPreviousLayer, helix.stateAtVertex().transverseCurvature(), ilayer);
00365     
00366     
00367   }
00368   
00369   
00370   
00371 }
00372 
00373 
00374 
00375 std::vector<const reco::CaloCluster*> InOutConversionSeedFinder::getSecondCaloClusters(const GlobalPoint & conversionPosition, float charge) const {
00376   
00377   
00378   std::vector<const reco::CaloCluster*> result;
00379   
00380  //std::cout << "InOutConversionSeedFinder::getSecondCaloClusters" <<  "\n"; 
00381   
00382   Geom::Phi<float> theConvPhi(conversionPosition.phi() );
00383 
00384   for (unsigned i = 0; i < bcCollection_->size(); ++i ) {
00385     
00386     Geom::Phi<float> theBcPhi( bcCollection_->ptrAt(i)->position().phi()   );
00387    //std::cout<< "InOutConversionSeedFinder::getSecondCaloClusters  BC energy " <<  bcCollection_->ptrAt(i)->energy() << " Calo cluster phi " << theBcPhi << " " <<  bcCollection_->ptrAt(i)->position().phi()<<  " theConvPhi " << theConvPhi << "\n";
00388     
00389     // Require phi of cluster to be consistent with the conversion 
00390     // position and the track charge
00391     
00392     
00393     if (fabs(theBcPhi-theConvPhi ) < .5 &&
00394         ((charge<0 && theBcPhi-theConvPhi >-.5) || 
00395          (charge>0 && theBcPhi-theConvPhi <.5))){
00397       
00398       //result.push_back(&(*bcItr));
00399 
00400       result.push_back(&(*(bcCollection_->ptrAt(i))  ));
00401 
00402     }
00403     
00404     
00405     
00406     
00407   }
00408   
00409   
00410   
00411   return result;
00412   
00413   
00414 }
00415 
00416 
00417 
00418 void InOutConversionSeedFinder::findSeeds(const TrajectoryStateOnSurface & startingState,
00419                                           float transverseCurvature, 
00420                                           unsigned int startingLayer) const {
00421   
00422   
00423   std::vector<const DetLayer*> allLayers=layerList();
00424  //std::cout << "InOutConversionSeedFinder::findSeeds starting forward propagation from  startingLayer " << startingLayer <<  "\n"; 
00425   
00426   
00427   // create error matrix
00428   AlgebraicSymMatrix55 m = AlgebraicMatrixID();
00429   m(0,0) = 0.1; m(1,1) = 0.0001 ; m(2,2) = 0.0001 ;
00430   m(3,3) = 0.0001 ; m(4,4) = 0.001;
00431 
00432   // Make an FTS consistent with the start point, start direction and curvature
00433   FreeTrajectoryState fts(GlobalTrajectoryParameters(startingState.globalPosition(), 
00434                                                      startingState.globalDirection(),
00435                                                      double(transverseCurvature), 0, &(*theMF_) ),
00436                           CurvilinearTrajectoryError(m));
00437  //std::cout << " InOutConversionSeedFinder::findSeeds startingState R "<< startingState.globalPosition().perp() << " Z " << startingState.globalPosition().z() << " phi " <<  startingState.globalPosition().phi() <<  " position " << startingState.globalPosition() << "\n";
00438  //std::cout << " InOutConversionSeedFinder::findSeeds Initial FTS charge " << fts.charge() << " curvature " <<  transverseCurvature << "\n";  
00439  //std::cout << " InOutConversionSeedFinder::findSeeds Initial FTS parameters " << fts <<  "\n"; 
00440     
00441   
00442   //float dphi = 0.01;
00443   float dphi = 0.03;
00444   float zrange = 5.;
00445   for( unsigned int ilayer = startingLayer; ilayer <= startingLayer+1 && (ilayer < allLayers.size()-2); ++ilayer) {
00446     const DetLayer * layer = allLayers[ilayer];
00447     
00448     
00449     
00451     //    if ( layer->location() == GeomDetEnumerators::barrel ) {const BarrelDetLayer * barrelLayer = dynamic_cast<const BarrelDetLayer*>(layer);
00452     // //std::cout << "InOutConversionSeedFinder::findSeeds  ****  Barrel on layer " << ilayer  << " R= " << barrelLayer->specificSurface().radius() <<  "\n";     
00453     // } else {
00454     // const ForwardDetLayer * forwardLayer = dynamic_cast<const ForwardDetLayer*>(layer);
00456     // }
00457     // // end debug
00458     
00459     
00460 
00461     MeasurementEstimator * newEstimator=0;
00462     if (layer->location() == GeomDetEnumerators::barrel ) {
00463      //std::cout << "InOutConversionSeedFinder::findSeeds Barrel ilayer " << ilayer <<  "\n"; 
00464       newEstimator = new ConversionBarrelEstimator(-dphi, dphi, -zrange, zrange);
00465     }
00466     else {
00467      //std::cout << "InOutConversionSeedFinder::findSeeds Forward  ilayer " << ilayer <<  "\n"; 
00468       newEstimator = new ConversionForwardEstimator(-dphi, dphi, 15.);
00469     }
00470     
00471     
00472     theFirstMeasurements_.clear();
00473     // Get measurements compatible with the FTS and Estimator
00474     TSOS tsos(fts, layer->surface() );
00475     
00476    //std::cout << "InOutConversionSeedFinder::findSeed propagationDirection " << int(thePropagatorAlongMomentum_->propagationDirection() ) << "\n";               
00478     LayerMeasurements theLayerMeasurements_(this->getMeasurementTracker() );
00479 
00480     theFirstMeasurements_ = theLayerMeasurements_.measurements( *layer, tsos, *thePropagatorAlongMomentum_, *newEstimator);
00481     
00482     delete newEstimator;
00483     //std::cout <<  "InOutConversionSeedFinder::findSeeds  Found " << theFirstMeasurements_.size() << " first hits" << "\n";
00484     
00485     if ( theFirstMeasurements_.size() == 1 ) {      // only dummy hit found: start finding the seed from the innermost hit of the OutIn track
00486 
00487       
00488       GlobalPoint bcPos((theSecondBC_.position()).x(),(theSecondBC_.position()).y(),(theSecondBC_.position()).z());
00489       GlobalVector dir = startingState.globalDirection();
00490       GlobalPoint back1mm = myPointer->recHit()->globalPosition();
00491       
00492       back1mm -= dir.unit()*0.1;
00493       //std::cout << " InOutConversionSeedFinder:::findSeeds going to make the helix using back1mm " << back1mm << "\n";
00494       ConversionFastHelix helix(bcPos,  myPointer->recHit()->globalPosition(), back1mm, &(*theMF_));
00495       
00496       helix.stateAtVertex();
00497       //std::cout << " InOutConversionSeedFinder:::findSeeds helix status " <<helix.isValid() << std::endl; 
00498       if ( !helix.isValid()  ) continue;
00499       
00500       track2InitialMomentum_= helix.stateAtVertex().momentum();
00501                   
00502       // Make a new FTS
00503       FreeTrajectoryState newfts(GlobalTrajectoryParameters(
00504                                                             myPointer->recHit()->globalPosition(), startingState.globalDirection(),
00505                                                             helix.stateAtVertex().transverseCurvature(), 0, &(*theMF_)), 
00506                                  CurvilinearTrajectoryError(m));
00507       
00508       
00509       completeSeed(*myPointer, newfts,  thePropagatorAlongMomentum_, ilayer+1);
00510       completeSeed(*myPointer, newfts,  thePropagatorAlongMomentum_, ilayer+2);
00511       
00512       
00513     } else { 
00514       
00515       
00516       
00517       //Loop over compatible hits
00518       int mea=0;
00519       for(std::vector<TrajectoryMeasurement>::iterator tmItr = theFirstMeasurements_.begin(); tmItr !=theFirstMeasurements_.end();  ++tmItr) {
00520         
00521         mea++;
00522         
00523         
00524         if (tmItr->recHit()->isValid() ) {
00525           // Make a new helix as in fillClusterSeeds() but using the hit position
00526           //std::cout << "InOutConversionSeedFinder::findSeeds hit  R " << tmItr->recHit()->globalPosition().perp() << " Z " <<  tmItr->recHit()->globalPosition().z() << " " <<  tmItr->recHit()->globalPosition() << "\n";
00527           GlobalPoint bcPos((theSecondBC_.position()).x(),(theSecondBC_.position()).y(),(theSecondBC_.position()).z());
00528           GlobalVector dir = startingState.globalDirection();
00529           GlobalPoint back1mm = tmItr->recHit()->globalPosition();
00530           
00531           back1mm -= dir.unit()*0.1;
00532           //std::cout << " InOutConversionSeedFinder:::findSeeds going to make the helix using back1mm " << back1mm << "\n";
00533           ConversionFastHelix helix(bcPos,  tmItr->recHit()->globalPosition(), back1mm, &(*theMF_));
00534           
00535           helix.stateAtVertex();
00536           //std::cout << " InOutConversionSeedFinder:::findSeeds helix status " <<helix.isValid() << std::endl; 
00537           if ( !helix.isValid()  ) continue;
00538           
00539           track2InitialMomentum_= helix.stateAtVertex().momentum();
00540           
00541           //std::cout << "InOutConversionSeedFinder::findSeeds Updated estimatedPt = " << helix.stateAtVertex().momentum().perp()  << " curvature "  << helix.stateAtVertex().transverseCurvature() << "\n";
00542           //     << ", bcet = " << theBc->Et() 
00543           //     << ", estimatedPt/bcet = " << estimatedPt/theBc->Et() << endl;
00544           
00545           
00546           // Make a new FTS
00547           FreeTrajectoryState newfts(GlobalTrajectoryParameters(
00548                                                                 tmItr->recHit()->globalPosition(), startingState.globalDirection(),
00549                                                                 helix.stateAtVertex().transverseCurvature(), 0, &(*theMF_)), 
00550                                      CurvilinearTrajectoryError(m));
00551           
00552           //std::cout <<  "InOutConversionSeedFinder::findSeeds  new FTS charge " << newfts.charge() << "\n";
00553           
00554           
00555           /*
00556           // Soome diagnostic output
00557           // may be useful - comparission of the basic cluster position 
00558           // with the ecal impact position of the track
00559           TrajectoryStateOnSurface stateAtECAL
00560           = forwardPropagator.propagate(newfts, ECALSurfaces::barrel());
00561           if (!stateAtECAL.isValid() || abs(stateAtECAL.globalPosition().eta())>1.479) {
00562           if (startingState.globalDirection().eta() > 0.) {
00563           stateAtECAL = forwardPropagator.propagate(newfts, 
00564           ECALSurfaces::positiveEtaEndcap());
00565           } else {
00566           stateAtECAL = forwardPropagator.propagate(newfts, 
00567           ECALSurfaces::negativeEtaEndcap());
00568           }
00569           }
00570           GlobalPoint ecalImpactPosition = stateAtECAL.isValid() ? stateAtECAL.globalPosition() : GlobalPoint(0.,0.,0.);
00571           cout << "Projected fts positon at ECAL surface: " << 
00572           ecalImpactPosition << " bc position: " << theBc->Position() << endl;
00573           */
00574           
00575           
00576           completeSeed(*tmItr, newfts,  thePropagatorAlongMomentum_, ilayer+1);
00577           completeSeed(*tmItr, newfts,  thePropagatorAlongMomentum_, ilayer+2);
00578           
00579           
00580         }
00581         
00582       }
00583       
00584     }    
00585     
00586     
00587   }
00588   
00589   
00590   
00591 }
00592 
00593 
00594 
00595 
00596 
00597 void InOutConversionSeedFinder::completeSeed(const TrajectoryMeasurement & m1,
00598                                              FreeTrajectoryState & fts, const Propagator* propagator, int ilayer) const {
00599   
00600  //std::cout<<  "InOutConversionSeedFinder::completeSeed ilayer " << ilayer <<  "\n";
00601   // A seed is made from 2 Trajectory Measuremennts.  The 1st is the input
00602   // argument m1.  This routine looks for the 2nd measurement in layer ilayer
00603   // Begin by making a new much stricter MeasurementEstimator based on the
00604   // position errors of the 1st hit.
00605   printLayer(ilayer);
00606   
00607   MeasurementEstimator * newEstimator;
00608   std::vector<const DetLayer*> allLayers=layerList();
00609   const DetLayer * layer = allLayers[ilayer];
00610   
00612   //  if ( layer->location() == GeomDetEnumerators::barrel ) {const BarrelDetLayer * barrelLayer = dynamic_cast<const BarrelDetLayer*>(layer);
00613   // //std::cout << "InOutConversionSeedFinder::completeSeed  ****  Barrel on layer " << ilayer  << " R= " << barrelLayer->specificSurface().radius() <<  "\n";     
00614   // } else {
00615   // const ForwardDetLayer * forwardLayer = dynamic_cast<const ForwardDetLayer*>(layer);
00616   //  //std::cout << "InOutConversionSeedFinder::completeSeed ****  Forw on layer " << ilayer  << " Z= " << forwardLayer->specificSurface().position().z() <<  "\n"; 
00619   
00620   
00621 
00622 
00623   if (layer->location() == GeomDetEnumerators::barrel ) {
00624     
00625     float dz = sqrt(the2ndHitdznSigma_*the2ndHitdznSigma_*m1.recHit()->globalPositionError().czz()
00626                     + the2ndHitdzConst_*the2ndHitdzConst_);
00627     newEstimator = new ConversionBarrelEstimator(-the2ndHitdphi_, the2ndHitdphi_, -dz, dz);
00628     
00629   }
00630   else {
00631     float m1dr = sqrt(m1.recHit()->localPositionError().yy());
00632     float dr = sqrt(the2ndHitdznSigma_*the2ndHitdznSigma_*m1dr*m1dr
00633                     + the2ndHitdzConst_*the2ndHitdznSigma_);
00634     
00635     newEstimator =  new ConversionForwardEstimator(-the2ndHitdphi_, the2ndHitdphi_, dr);
00636   }
00637   
00638 
00639  //std::cout << "InOutConversionSeedFinder::completeSeed fts For the TSOS " << fts << "\n";   
00640   
00641   TSOS tsos(fts, layer->surface() );
00642 
00643   if ( !tsos.isValid() ) {
00644    //std::cout  << "InOutConversionSeedFinder::completeSeed TSOS is not valid " <<  "\n"; 
00645   } 
00646 
00647  //std::cout << "InOutConversionSeedFinder::completeSeed TSOS " << tsos << "\n";   
00648  //std::cout << "InOutConversionSeedFinder::completeSeed propagationDirection  " << int(propagator->propagationDirection() ) << "\n";               
00649  //std::cout << "InOutConversionSeedFinder::completeSeed pointer to estimator " << newEstimator << "\n";
00650   LayerMeasurements theLayerMeasurements_(this->getMeasurementTracker() );
00651   std::vector<TrajectoryMeasurement> measurements = theLayerMeasurements_.measurements( *layer, tsos, *propagator, *newEstimator);
00652  //std::cout << "InOutConversionSeedFinder::completeSeed Found " << measurements.size() << " second hits " <<  "\n"; 
00653   delete newEstimator;
00654   
00655   for(unsigned int i = 0; i < measurements.size(); ++i) {
00656     if( measurements[i].recHit()->isValid()  ) {
00657       createSeed(m1, measurements[i]);
00658     }
00659   }
00660   
00661   
00662   
00663   
00664   
00665   
00666 }
00667 
00668 
00669 
00670 void InOutConversionSeedFinder::createSeed(const TrajectoryMeasurement & m1,  const TrajectoryMeasurement & m2) const {
00671   
00672  //std::cout << "InOutConversionSeedFinder::createSeed " << "\n";
00673 
00674   if (  m1.predictedState().isValid() ) {  
00675   GlobalTrajectoryParameters newgtp(  m1.recHit()->globalPosition(), track2InitialMomentum_, track2Charge_, &(*theMF_) );
00676   CurvilinearTrajectoryError errors = m1.predictedState().curvilinearError();
00677   FreeTrajectoryState fts(newgtp, errors);
00678 
00679   TrajectoryStateOnSurface state1 = thePropagatorAlongMomentum_->propagate(fts,  m1.recHit()->det()->surface());
00680   
00681   /*
00682    //std::cout << "hit surface " <<  m1.recHit()->det()->surface().position() << "\n";
00683    //std::cout << "prop to " << typeid( m1.recHit()->det()->surface() ).name() <<"\n";
00684    //std::cout << "prop to first hit " << state1 << "\n"; 
00685    //std::cout << "update to " <<  m1.recHit()->globalPosition() << "\n";
00686   */
00687   
00688   
00689   
00690   
00691   if ( state1.isValid() ) {
00692     
00693     TrajectoryStateOnSurface updatedState1 = theUpdator_.update(state1,  *m1.recHit() );
00694     
00695     if ( updatedState1.isValid() ) {
00696       
00697       TrajectoryStateOnSurface state2 = thePropagatorAlongMomentum_->propagate(*updatedState1.freeTrajectoryState(),  m2.recHit()->det()->surface());
00698       
00699       if ( state2.isValid() ) {
00700         
00701         TrajectoryStateOnSurface updatedState2 = theUpdator_.update(state2, *m2.recHit() );
00702         TrajectoryMeasurement meas1(state1, updatedState1,  m1.recHit()  , m1.estimate(), m1.layer());
00703         TrajectoryMeasurement meas2(state2, updatedState2,  m2.recHit()  , m2.estimate(), m2.layer());
00704         
00705         edm::OwnVector<TrackingRecHit> myHits;
00706         myHits.push_back(meas1.recHit()->hit()->clone());
00707         myHits.push_back(meas2.recHit()->hit()->clone());
00708         
00709         //std::cout << "InOutConversionSeedFinder::createSeed new seed " << "\n";
00710         if ( nSeedsPerInputTrack_ >= maxNumberOfInOutSeedsPerInputTrack_ ) return;
00711         
00712 
00713         TrajectoryStateTransform tsTransform;
00714         PTrajectoryStateOnDet* ptsod= tsTransform.persistentState(state2, meas2.recHit()->hit()->geographicalId().rawId()  );
00715         //std::cout << "  InOutConversionSeedFinder::createSeed New seed parameters " << state2 << "\n";
00716        
00717         
00718        
00719         theSeeds_.push_back(TrajectorySeed( *ptsod, myHits, alongMomentum ));
00720         nSeedsPerInputTrack_++;
00721 
00722         delete ptsod;
00723        
00724         //std::cout << "InOutConversionSeedFinder::createSeed New seed hit 1 R " << m1.recHit()->globalPosition().perp() << "\n";
00725         //std::cout << "InOutConversionSeedFinder::createSeed New seed hit 2 R " << m2.recHit()->globalPosition().perp() << "\n";
00726         
00727         
00728         
00729         
00730       }
00731     }
00732   }
00733   }
00734 
00735   
00736 }