00001
00002
00003
00004
00005 #include <vector>
00006 #include <iostream>
00007 #include <cmath>
00008
00009 #include "RecoTracker/SingleTrackPattern/interface/CosmicTrajectoryBuilder.h"
00010 #include "DataFormats/Common/interface/OwnVector.h"
00011 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h"
00012 #include "TrackingTools/TrajectoryState/interface/BasicSingleTrajectoryState.h"
00013 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00014 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00015 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00018 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00019 #include "TrackingTools/TrackFitters/interface/TrajectoryStateWithArbitraryError.h"
00020 using namespace std;
00021 CosmicTrajectoryBuilder::CosmicTrajectoryBuilder(const edm::ParameterSet& conf) : conf_(conf) {
00022
00023
00024 theMinHits=conf_.getParameter<int>("MinHits");
00025
00026 chi2cut=conf_.getParameter<double>("Chi2Cut");
00027 edm::LogInfo("CosmicTrackFinder")<<"Minimum number of hits "<<theMinHits<<" Cut on Chi2= "<<chi2cut;
00028
00029 geometry=conf_.getUntrackedParameter<std::string>("GeometricStructure","STANDARD");
00030 }
00031
00032
00033 CosmicTrajectoryBuilder::~CosmicTrajectoryBuilder() {
00034 }
00035
00036
00037 void CosmicTrajectoryBuilder::init(const edm::EventSetup& es, bool seedplus){
00038
00039
00040
00041 es.get<IdealMagneticFieldRecord>().get(magfield);
00042 es.get<TrackerDigiGeometryRecord>().get(tracker);
00043
00044
00045
00046 if (seedplus) {
00047 seed_plus=true;
00048 thePropagator= new PropagatorWithMaterial(alongMomentum,0.1057,&(*magfield) );
00049 thePropagatorOp= new PropagatorWithMaterial(oppositeToMomentum,0.1057,&(*magfield) );}
00050 else {
00051 seed_plus=false;
00052 thePropagator= new PropagatorWithMaterial(oppositeToMomentum,0.1057,&(*magfield) );
00053 thePropagatorOp= new PropagatorWithMaterial(alongMomentum,0.1057,&(*magfield) );
00054 }
00055
00056 theUpdator= new KFUpdator();
00057 theEstimator= new Chi2MeasurementEstimator(chi2cut);
00058
00059
00060 edm::ESHandle<TransientTrackingRecHitBuilder> theBuilder;
00061 std::string builderName = conf_.getParameter<std::string>("TTRHBuilder");
00062 es.get<TransientRecHitRecord>().get(builderName,theBuilder);
00063
00064
00065 RHBuilder= theBuilder.product();
00066
00067
00068
00069
00070 theFitter= new KFTrajectoryFitter(*thePropagator,
00071 *theUpdator,
00072 *theEstimator) ;
00073
00074
00075 theSmoother= new KFTrajectorySmoother(*thePropagatorOp,
00076 *theUpdator,
00077 *theEstimator);
00078
00079 }
00080
00081 void CosmicTrajectoryBuilder::run(const TrajectorySeedCollection &collseed,
00082 const SiStripRecHit2DCollection &collstereo,
00083 const SiStripRecHit2DCollection &collrphi ,
00084 const SiStripMatchedRecHit2DCollection &collmatched,
00085 const SiPixelRecHitCollection &collpixel,
00086 const edm::EventSetup& es,
00087 edm::Event& e,
00088 vector<Trajectory> &trajoutput)
00089 {
00090
00091
00092
00093
00094 std::vector<Trajectory> trajSmooth;
00095 std::vector<Trajectory>::iterator trajIter;
00096
00097 TrajectorySeedCollection::const_iterator iseed;
00098 unsigned int IS=0;
00099 for(iseed=collseed.begin();iseed!=collseed.end();iseed++){
00100 bool seedplus=((*iseed).direction()==alongMomentum);
00101 init(es,seedplus);
00102 hits.clear();
00103 trajFit.clear();
00104 trajSmooth.clear();
00105
00106 vector<const TrackingRecHit*> allHits= SortHits(collstereo,collrphi,collmatched,collpixel,*iseed);
00107 Trajectory startingTraj = createStartingTrajectory(*iseed);
00108 AddHit(startingTraj,allHits);
00109 for (trajIter=trajFit.begin(); trajIter!=trajFit.end();trajIter++){
00110 trajSmooth=theSmoother->trajectories((*trajIter));
00111 }
00112 for (trajIter= trajSmooth.begin(); trajIter!=trajSmooth.end();trajIter++){
00113 if((*trajIter).isValid()){
00114 trajoutput.push_back((*trajIter));
00115 }
00116 }
00117 delete theUpdator;
00118 delete theEstimator;
00119 delete thePropagator;
00120 delete thePropagatorOp;
00121 delete theFitter;
00122 delete theSmoother;
00123
00124 if (IS>30) return;
00125 IS++;
00126
00127 }
00128 }
00129
00130 Trajectory CosmicTrajectoryBuilder::createStartingTrajectory( const TrajectorySeed& seed) const
00131 {
00132 Trajectory result( seed, seed.direction());
00133 std::vector<TM> seedMeas = seedMeasurements(seed);
00134 if ( !seedMeas.empty()) {
00135 for (std::vector<TM>::const_iterator i=seedMeas.begin(); i!=seedMeas.end(); i++){
00136 result.push(*i);
00137 }
00138 }
00139
00140 return result;
00141 }
00142
00143
00144 std::vector<TrajectoryMeasurement>
00145 CosmicTrajectoryBuilder::seedMeasurements(const TrajectorySeed& seed) const
00146 {
00147 std::vector<TrajectoryMeasurement> result;
00148 TrajectorySeed::range hitRange = seed.recHits();
00149 for (TrajectorySeed::const_iterator ihit = hitRange.first;
00150 ihit != hitRange.second; ihit++) {
00151
00152 TransientTrackingRecHit::RecHitPointer recHit = RHBuilder->build(&(*ihit));
00153 const GeomDet* hitGeomDet = (&(*tracker))->idToDet( ihit->geographicalId());
00154 TSOS invalidState( new BasicSingleTrajectoryState( hitGeomDet->surface()));
00155
00156 if (ihit == hitRange.second - 1) {
00157 TSOS updatedState=startingTSOS(seed);
00158 result.push_back(TM( invalidState, updatedState, recHit));
00159
00160 }
00161 else {
00162 result.push_back(TM( invalidState, recHit));
00163 }
00164
00165 }
00166
00167 return result;
00168 }
00169
00170
00171
00172
00173
00174 vector<const TrackingRecHit*>
00175 CosmicTrajectoryBuilder::SortHits(const SiStripRecHit2DCollection &collstereo,
00176 const SiStripRecHit2DCollection &collrphi ,
00177 const SiStripMatchedRecHit2DCollection &collmatched,
00178 const SiPixelRecHitCollection &collpixel,
00179 const TrajectorySeed &seed){
00180
00181
00182
00183
00184
00185 vector<const TrackingRecHit*> allHits;
00186
00187 SiStripRecHit2DCollection::DataContainer::const_iterator istrip;
00188 TrajectorySeed::range hRange= seed.recHits();
00189 TrajectorySeed::const_iterator ihit;
00190 float yref=0.;
00191 for (ihit = hRange.first;
00192 ihit != hRange.second; ihit++) {
00193 yref=RHBuilder->build(&(*ihit))->globalPosition().y();
00194 hits.push_back((RHBuilder->build(&(*ihit))));
00195 LogDebug("CosmicTrackFinder")<<"SEED HITS"<<RHBuilder->build(&(*ihit))->globalPosition();
00196 }
00197
00198
00199 if ((&collpixel)!=0){
00200 SiPixelRecHitCollection::DataContainer::const_iterator ipix;
00201 for(ipix=collpixel.data().begin();ipix!=collpixel.data().end();ipix++){
00202 float ych= RHBuilder->build(&(*ipix))->globalPosition().y();
00203 if ((seed_plus && (ych<yref)) || (!(seed_plus) && (ych>yref)))
00204 allHits.push_back(&(*ipix));
00205 }
00206 }
00207
00208
00209
00210 if ((&collrphi)!=0){
00211 for(istrip=collrphi.data().begin();istrip!=collrphi.data().end();istrip++){
00212 float ych= RHBuilder->build(&(*istrip))->globalPosition().y();
00213 if ((seed_plus && (ych<yref)) || (!(seed_plus) && (ych>yref)))
00214 allHits.push_back(&(*istrip));
00215 }
00216 }
00217
00218
00219
00220
00221 if ((&collstereo)!=0){
00222 for(istrip=collstereo.data().begin();istrip!=collstereo.data().end();istrip++){
00223 float ych= RHBuilder->build(&(*istrip))->globalPosition().y();
00224 if ((seed_plus && (ych<yref)) || (!(seed_plus) && (ych>yref)))
00225 allHits.push_back(&(*istrip));
00226 }
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 if (seed_plus){
00239 stable_sort(allHits.begin(),allHits.end(),CompareHitY_plus(*tracker));
00240 }
00241 else {
00242 stable_sort(allHits.begin(),allHits.end(),CompareHitY(*tracker));
00243 }
00244
00245 return allHits;
00246 }
00247
00248 TrajectoryStateOnSurface
00249 CosmicTrajectoryBuilder::startingTSOS(const TrajectorySeed& seed)const
00250 {
00251 PTrajectoryStateOnDet pState( seed.startingState());
00252 const GeomDet* gdet = (&(*tracker))->idToDet(DetId(pState.detId()));
00253 TSOS State= tsTransform.transientState( pState, &(gdet->surface()),
00254 &(*magfield));
00255 return State;
00256
00257 }
00258
00259 void CosmicTrajectoryBuilder::AddHit(Trajectory &traj,
00260 vector<const TrackingRecHit*>Hits){
00261
00262
00263 unsigned int icosm2;
00264 unsigned int ibestdet;
00265 float chi2min;
00266 for (unsigned int icosmhit=0;icosmhit<Hits.size();icosmhit++){
00267 GlobalPoint gphit=RHBuilder->build(Hits[icosmhit])->globalPosition();
00268 unsigned int iraw= Hits[icosmhit]->geographicalId().rawId();
00269 LogDebug("CosmicTrackFinder")<<" HIT POSITION "<< gphit;
00270
00271 TransientTrackingRecHit::RecHitPointer tmphit=RHBuilder->build(Hits[icosmhit]);
00272 TSOS prSt= thePropagator->propagate(traj.lastMeasurement().updatedState(),
00273 tracker->idToDet(Hits[icosmhit]->geographicalId())->surface());
00274
00275
00276
00277 chi2min=20000000;
00278 ibestdet=1000;
00279 if (prSt.isValid()){
00280 LocalPoint prLoc = prSt.localPosition();
00281 LogDebug("CosmicTrackFinder") <<"STATE PROPAGATED AT DET "<<iraw<<" "<<prSt;
00282 for(icosm2=icosmhit;icosm2<Hits.size();icosm2++){
00283
00284 if (iraw==Hits[icosm2]->geographicalId().rawId()){
00285 TransientTrackingRecHit::RecHitPointer tmphit=RHBuilder->build(Hits[icosm2]);
00286 float contr= theEstimator->estimate(prSt, *tmphit).second;
00287 if (contr<chi2min) {
00288 chi2min=contr;
00289 ibestdet=icosm2;
00290 }
00291 if (icosm2!=icosmhit) icosmhit++;
00292
00293 }
00294 else icosm2=Hits.size();
00295 }
00296
00297 if(chi2min<chi2cut)
00298 LogDebug("CosmicTrackFinder")<<"Chi2 contribution for hit at "
00299 <<RHBuilder->build(Hits[ibestdet])->globalPosition()
00300 <<" is "<<chi2min;
00301
00302 if(traj.foundHits()<3 &&(chi2min<chi2cut)){
00303
00304 GlobalVector ck=RHBuilder->build(Hits[ibestdet])->globalPosition()-
00305 traj.firstMeasurement().updatedState().globalPosition();
00306 if ((abs(ck.x()/ck.y())>2)||(abs(ck.z()/ck.y())>2)) chi2min=300;
00307 }
00308 if (chi2min<chi2cut){
00309 if ( abs(prLoc.x()) < 25 && abs(prLoc.y()) < 25 ){
00310 TransientTrackingRecHit::RecHitPointer tmphitbestdet=RHBuilder->build(Hits[ibestdet]);
00311 TSOS UpdatedState= theUpdator->update( prSt, *tmphitbestdet);
00312 if (UpdatedState.isValid()){
00313
00314 traj.push(TM(prSt,UpdatedState,RHBuilder->build(Hits[ibestdet])
00315 , chi2min));
00316 LogDebug("CosmicTrackFinder") <<
00317 "STATE UPDATED WITH HIT AT POSITION "
00318 <<tmphitbestdet->globalPosition()
00319 <<UpdatedState<<" "
00320 <<traj.chiSquared();
00321
00322 hits.push_back(&(*tmphitbestdet));
00323 }
00324 }else LogDebug("CosmicTrackFinder")<<" Hits outside module surface "<< prLoc;
00325 }else LogDebug("CosmicTrackFinder")<<" State can not be updated with hit at position " <<gphit;
00326 }else LogDebug("CosmicTrackFinder")<<" State can not be propagated at det "<< iraw;
00327 }
00328
00329
00330
00331 if ( qualityFilter( traj)){
00332 const TrajectorySeed& tmpseed=traj.seed();
00333 if (thePropagatorOp->propagate(traj.lastMeasurement().updatedState(),
00334 tracker->idToDet((*hits.begin())->geographicalId())->surface()).isValid()){
00335 TSOS startingState=
00336 thePropagatorOp->propagate(traj.lastMeasurement().updatedState(),
00337 tracker->idToDet((*hits.begin())->geographicalId())->surface());
00338
00339 trajFit = theFitter->fit(tmpseed,hits, startingState );
00340 }
00341 }
00342
00343 }
00344
00345
00346 bool
00347 CosmicTrajectoryBuilder::qualityFilter(Trajectory traj){
00348 int ngoodhits=0;
00349 if(geometry=="MTCC"){
00350 std::vector< ConstReferenceCountingPointer< TransientTrackingRecHit> > hits= traj.recHits();
00351 std::vector< ConstReferenceCountingPointer< TransientTrackingRecHit> >::const_iterator hit;
00352 for(hit=hits.begin();hit!=hits.end();hit++){
00353 unsigned int iid=(*hit)->hit()->geographicalId().rawId();
00354
00355 if(((iid>>0)&0x3)!=1) ngoodhits++;
00356 }
00357 }
00358 else ngoodhits=traj.foundHits();
00359
00360 if ( ngoodhits >= theMinHits) {
00361 return true;
00362 }
00363 else {
00364 return false;
00365 }
00366 }