00001 #include "FWCore/Framework/interface/EDProducer.h"
00002 #include "FWCore/Framework/interface/Event.h"
00003 #include "FWCore/Framework/interface/EventSetup.h"
00004 #include "FWCore/Framework/interface/ESHandle.h"
00005
00006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00007 #include "FWCore/Utilities/interface/InputTag.h"
00008
00009 #include "DataFormats/Common/interface/View.h"
00010 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00011 #include "DataFormats/TrackReco/interface/Track.h"
00012 #include "DataFormats/TrackCandidate/interface/TrackCandidateCollection.h"
00013 #include "DataFormats/TrackingRecHit/interface/InvalidTrackingRecHit.h"
00014
00015 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00016 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00017 #include "MagneticField/Engine/interface/MagneticField.h"
00018 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00019 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00020 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00021
00022 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00023 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00024 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00025 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00026 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00027 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00028 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00029
00030
00031
00032 #include "Geometry/CommonDetUnit/interface/TrackingGeometry.h"
00033 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00034 #include "DataFormats/GeometrySurface/interface/Surface.h"
00035 #include "DataFormats/GeometrySurface/interface/GloballyPositioned.h"
00036 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00037 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00038
00039 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00040 #include "DataFormats/GeometrySurface/interface/Surface.h"
00041 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
00042 #include "DataFormats/Math/interface/Vector.h"
00043 #include "DataFormats/Math/interface/Error.h"
00044 #include "TrackingTools/TrajectoryState/interface/CopyUsingClone.h"
00045 #include "RecoVertex/VertexTools/interface/PerigeeLinearizedTrackState.h"
00046
00047 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00048
00049 #include "DataFormats/GeometryCommonDetAlgo/interface/ErrorFrameTransformer.h"
00050 #include "DataFormats/TrackingRecHit/interface/AlignmentPositionError.h"
00051
00052 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00053
00054 #include "FWCore/Framework/interface/ESHandle.h"
00055 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00056
00057
00058 #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h"
00059 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00060 #include "TrackingTools/TrackFitters/interface/TrajectoryStateCombiner.h"
00061
00062
00063 #include <boost/regex.hpp>
00064
00086 namespace reco { namespace modules {
00087 class CosmicTrackSplitter : public edm::EDProducer {
00088 public:
00089 CosmicTrackSplitter(const edm::ParameterSet &iConfig) ;
00090 virtual void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) ;
00091
00092 private:
00093 edm::InputTag tracks_;
00094 edm::InputTag tjTag_;
00095 int totalTracks_;
00096 size_t minimumHits_;
00097
00098 bool replaceWithInactiveHits_;
00099 bool stripFrontInvalidHits_;
00100 bool stripBackInvalidHits_;
00101 bool stripAllInvalidHits_;
00102 bool excludePixelHits_;
00103
00104 double dZcut_;
00105 double dXYcut_;
00106
00107 std::vector<uint32_t> detsToIgnore_;
00108
00109 edm::ESHandle<TrackerGeometry> theGeometry;
00110 edm::ESHandle<MagneticField> theMagField;
00111
00112 TrackCandidate makeCandidate(const reco::Track &tk, std::vector<TrackingRecHit *>::iterator hitsBegin, std::vector<TrackingRecHit *>::iterator hitsEnd) ;
00113
00114 };
00115
00116
00117 CosmicTrackSplitter::CosmicTrackSplitter(const edm::ParameterSet &iConfig) :
00118 tracks_(iConfig.getParameter<edm::InputTag>("tracks")),
00119 tjTag_(iConfig.getParameter<edm::InputTag>("tjTkAssociationMapTag") ),
00120 minimumHits_(iConfig.getParameter<uint32_t>("minimumHits")),
00121 replaceWithInactiveHits_(iConfig.getParameter<bool>("replaceWithInactiveHits")),
00122 stripFrontInvalidHits_(iConfig.getParameter<bool>("stripFrontInvalidHits")),
00123 stripBackInvalidHits_( iConfig.getParameter<bool>("stripBackInvalidHits") ),
00124 stripAllInvalidHits_( iConfig.getParameter<bool>("stripAllInvalidHits") ),
00125 excludePixelHits_( iConfig.getParameter<bool>("excludePixelHits") ),
00126 dZcut_(iConfig.getParameter<double>("dzCut") ),
00127 dXYcut_(iConfig.getParameter<double>("dxyCut") ),
00128 detsToIgnore_( iConfig.getParameter<std::vector<uint32_t> >("detsToIgnore") )
00129 {
00130
00131 if (stripAllInvalidHits_ && replaceWithInactiveHits_) {
00132 throw cms::Exception("Configuration") << "Inconsistent Configuration: you can't set both 'stripAllInvalidHits' and 'replaceWithInactiveHits' to true\n";
00133 }
00134
00135 LogDebug("CosmicTrackSplitter") << "sanity check";
00136
00137
00138 std::sort(detsToIgnore_.begin(), detsToIgnore_.end());
00139
00140 totalTracks_ = 0;
00141
00142
00143 produces<TrackCandidateCollection>();
00144 }
00145
00146 void
00147 CosmicTrackSplitter::produce(edm::Event &iEvent, const edm::EventSetup &iSetup)
00148 {
00149 LogDebug("CosmicTrackSplitter") << "IN THE SPLITTER!!!!!";
00150
00151
00152 edm::Handle<std::vector<reco::Track> > tracks;
00153 iEvent.getByLabel(tracks_, tracks);
00154
00155
00156
00157
00158 edm::Handle<TrajTrackAssociationCollection> m_TrajTracksMap;
00159 iEvent.getByLabel( tjTag_, m_TrajTracksMap );
00160
00161
00162 iSetup.get<TrackerDigiGeometryRecord>().get(theGeometry);
00163 iSetup.get<IdealMagneticFieldRecord>().get(theMagField);
00164
00165
00166 std::auto_ptr<TrackCandidateCollection> output(new TrackCandidateCollection());
00167 output->reserve(tracks->size());
00168
00169
00170 std::vector<TrackingRecHit *> hits;
00171
00172
00173
00174 LogDebug("CosmicTrackSplitter") << "size of map: " << m_TrajTracksMap->size();
00175 int HITTOSPLITFROM = 0;
00176 for ( TrajTrackAssociationCollection::const_iterator iPair = m_TrajTracksMap->begin(); iPair != m_TrajTracksMap->end(); iPair++ ){
00177 const Trajectory* trajFromMap = &(*(*iPair).key);
00178 const reco::Track* trackFromMap = &(*(*iPair).val);
00179
00180
00181 std::vector<TrajectoryMeasurement> measurements = trajFromMap->measurements();
00182 int totalNumberOfHits = measurements.size();
00183 int numberOfHits = 0;
00184 double previousDotProduct = 0;
00185 for (trackingRecHit_iterator ith = trackFromMap->recHitsBegin(), edh = trackFromMap->recHitsEnd(); ith != edh; ++ith) {
00186
00187 GlobalVector stateMomentum = measurements[numberOfHits].forwardPredictedState().globalMomentum();
00188 GlobalPoint statePosition = measurements[numberOfHits].forwardPredictedState().globalPosition();
00189 double dotProduct = stateMomentum.x()*statePosition.x() + stateMomentum.y()*statePosition.y();
00190 if ( dotProduct*previousDotProduct < 0 ){
00191
00192 HITTOSPLITFROM = numberOfHits;
00193 }
00194
00195 previousDotProduct = dotProduct;
00196 numberOfHits++;
00197
00198 }
00199 LogDebug("CosmicTrackSplitter") << "number of rechits: " << numberOfHits;
00200
00201
00202 trackingRecHit_iterator bIt = trackFromMap->recHitsBegin();
00203 trackingRecHit_iterator fIt = trackFromMap->recHitsEnd() - 1;
00204 const TrackingRecHit* bHit = bIt->get();
00205 const TrackingRecHit* fHit = fIt->get();
00206
00207 if( bHit->type() != 0 || bHit->isValid() != 1){
00208
00209 trackingRecHit_iterator ihit;
00210 for( ihit = trackFromMap->recHitsBegin();
00211 ihit != trackFromMap->recHitsEnd(); ++ihit){
00212 const TrackingRecHit* iHit = ihit->get();
00213 if( iHit->type() == 0 && iHit->isValid() == 1){
00214 bHit = iHit;
00215 break;
00216 }
00217 }
00218 }
00219 DetId bdetid = bHit->geographicalId();
00220 GlobalPoint bPosHit = theGeometry->idToDetUnit( bdetid)->surface().
00221 toGlobal(bHit->localPosition());
00222 if( fHit->type() != 0 || fHit->isValid() != 1){
00223
00224 trackingRecHit_iterator ihitf;
00225 for( ihitf = trackFromMap->recHitsEnd()-1;
00226 ihitf != trackFromMap->recHitsBegin(); --ihitf){
00227 const TrackingRecHit* iHit = ihitf->get();
00228 if( iHit->type() == 0 && iHit->isValid() == 1){
00229 fHit = iHit;
00230 break;
00231 }
00232 }
00233 }
00234 DetId fdetid = fHit->geographicalId();
00235 GlobalPoint fPosHit = theGeometry->
00236 idToDetUnit( fdetid )->surface().toGlobal(fHit->localPosition());
00237 GlobalPoint bPosState = measurements[0].updatedState().globalPosition();
00238 GlobalPoint fPosState = measurements[measurements.size()-1].
00239 updatedState().globalPosition();
00240 bool trajReversedFlag = false;
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 if (( (bPosHit - bPosState).mag() > (bPosHit - fPosState).mag() ) && ( (fPosHit - fPosState).mag() > (fPosHit - bPosState).mag() ) ){
00251 trajReversedFlag = true;
00252 }
00253 if (trajReversedFlag){ int temp = HITTOSPLITFROM; HITTOSPLITFROM = totalNumberOfHits - temp; }
00254 }
00255
00256 totalTracks_ = totalTracks_ + tracks->size();
00257
00258 for (std::vector<reco::Track>::const_iterator itt = tracks->begin(), edt = tracks->end(); itt != edt; ++itt) {
00259 hits.clear();
00260
00261 LogDebug("CosmicTrackSplitter") << "ntracks: " << tracks->size();
00262
00263
00264 math::XYZPoint refPoint = itt->referencePoint();
00265 GlobalPoint v( itt->vx(), itt->vy(), itt->vz() );
00266
00267
00268 bool continueWithTrack = true;
00269 if (fabs(v.z()) > dZcut_) continueWithTrack = false;
00270 if (v.perp() > dXYcut_) continueWithTrack = false;
00271 if (continueWithTrack == false) return;
00272
00273
00274 for (int i = 0; i < 2; ++i){
00275 hits.clear();
00276 LogDebug("CosmicTrackSplitter") << " loop on hits of track #" << (itt - tracks->begin());
00277 int usedHitCtr = 0;
00278 int hitCtr = 0;
00279 for (trackingRecHit_iterator ith = itt->recHitsBegin(), edh = itt->recHitsEnd(); ith != edh; ++ith) {
00280
00281 const TrackingRecHit * hit = ith->get();
00282 LogDebug("CosmicTrackSplitter") << " hit number " << (ith - itt->recHitsBegin());
00283
00284 if (hit->isValid()) {
00285 LogDebug("CosmicTrackSplitter") << " valid, detid = " << hit->geographicalId().rawId();
00286 DetId detid = hit->geographicalId();
00287
00288 if (detid.det() == DetId::Tracker) {
00289 LogDebug("CosmicTrackSplitter") << " valid, tracker ";
00290 bool verdict = false;
00291
00292
00293
00294
00295 const GlobalPoint pos = theGeometry->idToDetUnit( detid )->surface().toGlobal(hit->localPosition());
00296 LogDebug("CosmicTrackSplitter") << "hit pos: " << pos << ", dca pos: " << v;
00297
00298
00299 if ((i == 0)&&(hitCtr < HITTOSPLITFROM)){
00300 verdict = true;
00301 LogDebug("CosmicTrackSplitter") << "tophalf";
00302 }
00303
00304 if ((i == 1)&&(hitCtr >= HITTOSPLITFROM)){
00305 verdict = true;
00306 LogDebug("CosmicTrackSplitter") << "bottomhalf";
00307 }
00308
00309
00310 if ( verdict && std::binary_search(detsToIgnore_.begin(), detsToIgnore_.end(), detid.rawId())) {
00311 verdict = false;
00312 }
00313
00314
00315 if ( excludePixelHits_){
00316 if ((detid.det() == DetId::Tracker)&&((detid.subdetId() == 1)||(detid.subdetId() == 2))) {
00317 verdict = false;
00318 }
00319 }
00320
00321 LogDebug("CosmicTrackSplitter") << " verdict after module list: " << (verdict ? "ok" : "no");
00322 if (verdict == true) {
00323
00324 hits.push_back(hit->clone());
00325 usedHitCtr++;
00326 }
00327 else {
00328
00329 if (replaceWithInactiveHits_) {
00330 hits.push_back(new InvalidTrackingRecHit(detid, TrackingRecHit::inactive));
00331 }
00332 }
00333 }
00334 else {
00335 hits.push_back(hit->clone());
00336 }
00337 }
00338 else {
00339 if (!stripAllInvalidHits_) {
00340 hits.push_back(hit->clone());
00341 }
00342 }
00343 LogDebug("CosmicTrackSplitter") << " end of hit " << (ith - itt->recHitsBegin());
00344 hitCtr++;
00345 }
00346 LogDebug("CosmicTrackSplitter") << " end of loop on hits of track #" << (itt - tracks->begin());
00347
00348 std::vector<TrackingRecHit *>::iterator begin = hits.begin(), end = hits.end();
00349
00350 LogDebug("CosmicTrackSplitter") << " selected " << hits.size() << " hits ";
00351
00352
00353 if (stripFrontInvalidHits_) {
00354 while ( (begin != end) && ( (*begin)->isValid() == false ) ) ++begin;
00355 }
00356
00357 LogDebug("CosmicTrackSplitter") << " after front stripping we have " << (end - begin) << " hits ";
00358
00359
00360 if (stripBackInvalidHits_ && (begin != end)) {
00361 --end;
00362 while ( (begin != end) && ( (*end)->isValid() == false ) ) --end;
00363 ++end;
00364 }
00365
00366 LogDebug("CosmicTrackSplitter") << " after back stripping we have " << (end - begin) << " hits ";
00367
00368
00369
00370 if ( usedHitCtr >= int(minimumHits_)) {
00371 output->push_back( makeCandidate ( *itt, begin, end ) );
00372 LogDebug("CosmicTrackSplitter") << "we made a candidate of " << hits.size() << " hits!";
00373 }
00374
00375 for (begin = hits.begin(), end = hits.end(); begin != end; ++begin) {
00376 if (*begin) delete *begin;
00377 }
00378 LogDebug("CosmicTrackSplitter") << "loop: " << i << " has " << usedHitCtr << " active hits and " << hits.size() << " total hits...";
00379 hits.clear();
00380 }
00381 }
00382 LogDebug("CosmicTrackSplitter") << "totalTracks_ = " << totalTracks_;
00383 iEvent.put(output);
00384 }
00385
00386 TrackCandidate
00387 CosmicTrackSplitter::makeCandidate(const reco::Track &tk, std::vector<TrackingRecHit *>::iterator hitsBegin, std::vector<TrackingRecHit *>::iterator hitsEnd) {
00388
00389 LogDebug("CosmicTrackSplitter") << "Making a candidate!";
00390
00391 TrajectoryStateTransform transform;
00392 PropagationDirection pdir = tk.seedDirection();
00393 PTrajectoryStateOnDet *state;
00394 if ( pdir == anyDirection ) throw cms::Exception("UnimplementedFeature") << "Cannot work with tracks that have 'anyDirecton' \n";
00395
00396 if ( (pdir == alongMomentum) == ( (tk.outerPosition()-tk.innerPosition()).Dot(tk.momentum()) >= 0 ) ) {
00397
00398 TrajectoryStateOnSurface originalTsosIn(transform.innerStateOnSurface(tk, *theGeometry, &*theMagField));
00399 state = transform.persistentState( originalTsosIn, DetId(tk.innerDetId()) );
00400 } else {
00401
00402 TrajectoryStateOnSurface originalTsosOut(transform.outerStateOnSurface(tk, *theGeometry, &*theMagField));
00403 state = transform.persistentState( originalTsosOut, DetId(tk.outerDetId()) );
00404 }
00405
00406 TrajectorySeed seed(*state, TrackCandidate::RecHitContainer(), pdir);
00407
00408 TrackCandidate::RecHitContainer ownHits;
00409 ownHits.reserve(hitsEnd - hitsBegin);
00410 for ( ; hitsBegin != hitsEnd; ++hitsBegin) { ownHits.push_back( *hitsBegin ); }
00411
00412 TrackCandidate cand(ownHits, seed, *state, tk.seedRef());
00413 delete state;
00414
00415 LogDebug("CosmicTrackSplitter") << " dumping the hits now: ";
00416 for (TrackCandidate::range hitR = cand.recHits(); hitR.first != hitR.second; ++hitR.first) {
00417 LogTrace("CosmicTrackSplitter") << " hit detid = " << hitR.first->geographicalId().rawId() <<
00418 ", type = " << typeid(*hitR.first).name();
00419 }
00420
00421 return cand;
00422 }
00423
00424 }}
00425
00426
00427
00428 #include "FWCore/PluginManager/interface/ModuleDef.h"
00429 #include "FWCore/Framework/interface/MakerMacros.h"
00430
00431 using reco::modules::CosmicTrackSplitter;
00432 DEFINE_FWK_MODULE(CosmicTrackSplitter);