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