1 |
dgele |
1.1 |
#include "PhysicsTools/RecoAlgos/interface/MuonSelector.h"
|
2 |
|
|
|
3 |
|
|
#include "DataFormats/TrackerRecHit2D/interface/SiPixelRecHit.h"
|
4 |
|
|
#include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2D.h"
|
5 |
|
|
#include "DataFormats/TrackerRecHit2D/interface/ProjectedSiStripRecHit2D.h"
|
6 |
|
|
#include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h"
|
7 |
|
|
|
8 |
|
|
#include <DataFormats/SiStripDetId/interface/SiStripDetId.h>
|
9 |
|
|
|
10 |
|
|
template<typename RecHitType, typename ClusterRefType>
|
11 |
|
|
void
|
12 |
|
|
helper::MuonCollectionStoreManager::ClusterHitRecord<RecHitType,ClusterRefType>::
|
13 |
|
|
rekey(const ClusterRefType &newRef) const
|
14 |
|
|
{
|
15 |
|
|
//std::cout << "Rekeying hit with vector " << hitVector_ << ", index " << index_ << ", detid = " << detid_ << std::endl;
|
16 |
|
|
TrackingRecHit & genericHit = (*hitVector_)[index_];
|
17 |
|
|
RecHitType * hit = 0;
|
18 |
|
|
if (genericHit.geographicalId().rawId() == detid_) { // a hit on this det, so it's simple
|
19 |
|
|
hit = static_cast<RecHitType *>(&genericHit);
|
20 |
|
|
} else { // projected or matched rechit
|
21 |
|
|
assert ( typeid(RecHitType) == typeid(SiStripRecHit2D) ); // must not happen for pixel
|
22 |
|
|
if (typeid(genericHit) == typeid(SiStripMatchedRecHit2D)) {
|
23 |
|
|
SiStripMatchedRecHit2D & mhit = static_cast<SiStripMatchedRecHit2D &>(genericHit);
|
24 |
|
|
// I need the reinterpret_cast because the compiler sees this code even if RecHitType = PixelRecHit
|
25 |
|
|
hit = reinterpret_cast<RecHitType *>(SiStripDetId(detid_).stereo() ? mhit.stereoHit() : mhit.monoHit());
|
26 |
|
|
} else {
|
27 |
|
|
assert (typeid(genericHit) == typeid(ProjectedSiStripRecHit2D)) ; // no option left, so this shoud be true
|
28 |
|
|
ProjectedSiStripRecHit2D &phit = static_cast<ProjectedSiStripRecHit2D &>(genericHit);
|
29 |
|
|
hit = reinterpret_cast<RecHitType *>(& phit.originalHit());
|
30 |
|
|
}
|
31 |
|
|
}
|
32 |
|
|
assert (hit != 0);
|
33 |
|
|
assert ( hit->cluster() == ref_ ); // otherwise something went wrong
|
34 |
|
|
hit->setClusterRef(newRef);
|
35 |
|
|
}
|
36 |
|
|
|
37 |
|
|
using namespace reco;
|
38 |
|
|
|
39 |
|
|
namespace helper
|
40 |
|
|
{
|
41 |
|
|
MuonCollectionStoreManager::
|
42 |
|
|
MuonCollectionStoreManager(const edm::Handle<reco::MuonCollection>&)
|
43 |
|
|
:
|
44 |
|
|
selMuons_( new reco::MuonCollection ),
|
45 |
|
|
selTracks_( new reco::TrackCollection ),
|
46 |
|
|
selTracksExtras_( new reco::TrackExtraCollection ),
|
47 |
|
|
selTracksHits_( new TrackingRecHitCollection ),
|
48 |
|
|
selGlobalMuonTracks_( new reco::TrackCollection ),
|
49 |
|
|
selGlobalMuonTracksExtras_( new reco::TrackExtraCollection ),
|
50 |
|
|
selGlobalMuonTracksHits_( new TrackingRecHitCollection ),
|
51 |
|
|
selStandAloneTracks_( new reco::TrackCollection ),
|
52 |
|
|
selStandAloneTracksExtras_( new reco::TrackExtraCollection ),
|
53 |
|
|
selStandAloneTracksHits_( new TrackingRecHitCollection ),
|
54 |
|
|
selStripClusters_( new edmNew::DetSetVector<SiStripCluster> ),
|
55 |
|
|
selPixelClusters_( new edmNew::DetSetVector<SiPixelCluster> ),
|
56 |
|
|
rMuons_(),
|
57 |
|
|
rTracks_(), rTrackExtras_(), rHits_(), rStripClusters_(), rPixelClusters_(),
|
58 |
|
|
rGBTracks_(), rGBTrackExtras_(), rGBHits_(),
|
59 |
|
|
rSATracks_(), rSATrackExtras_(), rSAHits_(),
|
60 |
|
|
id_(0), igbd_(0), isad_(0), idx_(0), igbdx_(0),
|
61 |
|
|
isadx_(0), hidx_(0), higbdx_(0), hisadx_(0),
|
62 |
|
|
cloneClusters_ (true)
|
63 |
|
|
{
|
64 |
|
|
}
|
65 |
|
|
|
66 |
|
|
|
67 |
|
|
//------------------------------------------------------------------
|
68 |
|
|
//! Process a single muon.
|
69 |
|
|
//------------------------------------------------------------------
|
70 |
|
|
void
|
71 |
|
|
MuonCollectionStoreManager::
|
72 |
|
|
processMuon( const Muon & mu )
|
73 |
|
|
{
|
74 |
|
|
if (this->cloneClusters()
|
75 |
|
|
&& ( (mu.globalTrack().isNonnull() && !this->clusterRefsOK(*mu.globalTrack()))
|
76 |
|
|
|| (mu.innerTrack() .isNonnull() && !this->clusterRefsOK(*mu.innerTrack() ))
|
77 |
|
|
// || (mu.outerTrack(). isNonnull() && !this->clusterRefsOK(*mu.outerTrack() ))
|
78 |
|
|
)) { // outer track is muon only and has no strip clusters...
|
79 |
|
|
// At least until CMSSW_2_1_8, global muon track reconstruction assigns wrong hits in
|
80 |
|
|
// case of a track from iterative tracking. These hits are fetched from Trajectories
|
81 |
|
|
// instead of from Tracks and therefore reference temporary cluster collections.
|
82 |
|
|
// As a hack we skip these muons here - they can anyway not be refitted.
|
83 |
|
|
edm::LogError("BadRef") << "@SUB=MuonCollectionStoreManager::processMuon"
|
84 |
|
|
<< "Skip muon: One of its tracks references "
|
85 |
|
|
<< "non-available clusters!";
|
86 |
|
|
return;
|
87 |
|
|
}
|
88 |
|
|
|
89 |
|
|
selMuons_->push_back( Muon( mu ) );
|
90 |
|
|
// only tracker Muon Track
|
91 |
|
|
selMuons_->back().setInnerTrack( TrackRef( rTracks_, id_ ++ ) );
|
92 |
|
|
TrackRef trkRef = mu.track();
|
93 |
|
|
if(trkRef.isNonnull()){
|
94 |
|
|
|
95 |
|
|
selTracks_->push_back(Track( *trkRef) );
|
96 |
|
|
|
97 |
|
|
Track & trk= selTracks_->back();
|
98 |
|
|
|
99 |
|
|
selTracksExtras_->push_back( TrackExtra( trk.outerPosition(), trk.outerMomentum(), trk.outerOk(),
|
100 |
|
|
trk.innerPosition(), trk.innerMomentum(), trk.innerOk(),
|
101 |
|
|
trk.outerStateCovariance(), trk.outerDetId(),
|
102 |
|
|
trk.innerStateCovariance(), trk.innerDetId(),
|
103 |
|
|
trk.seedDirection() ) );
|
104 |
|
|
|
105 |
|
|
TrackExtra & tx = selTracksExtras_->back();
|
106 |
|
|
|
107 |
|
|
for( trackingRecHit_iterator hit = trk.recHitsBegin(); hit != trk.recHitsEnd(); ++ hit ) {
|
108 |
|
|
selTracksHits_->push_back( (*hit)->clone() );
|
109 |
|
|
TrackingRecHit * newHit = & (selTracksHits_->back());
|
110 |
|
|
tx.add( TrackingRecHitRef( rHits_, hidx_ ++ ) );
|
111 |
|
|
if (cloneClusters()) processHit( newHit, *selTracksHits_ );
|
112 |
|
|
} // end of for loop over tracking rec hits on this track
|
113 |
|
|
|
114 |
|
|
trk.setExtra( TrackExtraRef( rTrackExtras_, idx_ ++ ) );
|
115 |
|
|
|
116 |
|
|
}// TO trkRef.isNonnull
|
117 |
|
|
|
118 |
|
|
// global Muon Track
|
119 |
|
|
selMuons_->back().setGlobalTrack( TrackRef( rGBTracks_, igbd_ ++ ) );
|
120 |
|
|
trkRef = mu.combinedMuon();
|
121 |
|
|
if(trkRef.isNonnull()){
|
122 |
|
|
selGlobalMuonTracks_->push_back(Track( *trkRef) );
|
123 |
|
|
Track & trk = selGlobalMuonTracks_->back();
|
124 |
|
|
|
125 |
|
|
selGlobalMuonTracksExtras_->push_back( TrackExtra( trk.outerPosition(), trk.outerMomentum(), trk.outerOk(),
|
126 |
|
|
trk.innerPosition(), trk.innerMomentum(), trk.innerOk(),
|
127 |
|
|
trk.outerStateCovariance(), trk.outerDetId(),
|
128 |
|
|
trk.innerStateCovariance(), trk.innerDetId(), trk.seedDirection() ) );
|
129 |
|
|
TrackExtra & tx = selGlobalMuonTracksExtras_->back();
|
130 |
|
|
for( trackingRecHit_iterator hit = trk.recHitsBegin(); hit != trk.recHitsEnd(); ++ hit ) {
|
131 |
|
|
selGlobalMuonTracksHits_->push_back( (*hit)->clone() );
|
132 |
|
|
TrackingRecHit * newHit = & (selGlobalMuonTracksHits_->back());
|
133 |
|
|
tx.add( TrackingRecHitRef( rGBHits_, higbdx_ ++ ) );
|
134 |
|
|
if (cloneClusters()) processHit( newHit, *selGlobalMuonTracksHits_ );
|
135 |
|
|
}
|
136 |
|
|
trk.setExtra( TrackExtraRef( rGBTrackExtras_, igbdx_ ++ ) );
|
137 |
|
|
|
138 |
|
|
} // GB trkRef.isNonnull()
|
139 |
|
|
|
140 |
|
|
// stand alone Muon Track
|
141 |
|
|
selMuons_->back().setOuterTrack( TrackRef( rSATracks_, isad_ ++ ) );
|
142 |
|
|
trkRef = mu.standAloneMuon();
|
143 |
|
|
if(trkRef.isNonnull()){
|
144 |
|
|
selStandAloneTracks_->push_back(Track( *trkRef) );
|
145 |
|
|
Track & trk = selStandAloneTracks_->back();
|
146 |
|
|
|
147 |
|
|
selStandAloneTracksExtras_->push_back( TrackExtra( trk.outerPosition(), trk.outerMomentum(), trk.outerOk(),
|
148 |
|
|
trk.innerPosition(), trk.innerMomentum(), trk.innerOk(),
|
149 |
|
|
trk.outerStateCovariance(), trk.outerDetId(),
|
150 |
|
|
trk.innerStateCovariance(), trk.innerDetId(), trk.seedDirection() ) );
|
151 |
|
|
TrackExtra & tx = selStandAloneTracksExtras_->back();
|
152 |
|
|
for( trackingRecHit_iterator hit = trk.recHitsBegin(); hit != trk.recHitsEnd(); ++ hit ) {
|
153 |
|
|
selStandAloneTracksHits_->push_back( (*hit)->clone() );
|
154 |
|
|
tx.add( TrackingRecHitRef( rSAHits_, hisadx_ ++ ) );
|
155 |
|
|
}
|
156 |
|
|
trk.setExtra( TrackExtraRef( rSATrackExtras_, isadx_ ++ ) );
|
157 |
|
|
|
158 |
|
|
} // SA trkRef.isNonnull()
|
159 |
|
|
}// end of track, and function
|
160 |
|
|
|
161 |
|
|
//------------------------------------------------------------------
|
162 |
|
|
//! Process a single hit.
|
163 |
|
|
//------------------------------------------------------------------
|
164 |
|
|
void
|
165 |
|
|
MuonCollectionStoreManager::
|
166 |
|
|
processHit( const TrackingRecHit * hit, edm::OwnVector<TrackingRecHit> &hits ) {
|
167 |
|
|
//--- Skip the rest for this hit if we don't want to clone the cluster.
|
168 |
|
|
//--- The copy constructer in the rec hit will copy the link properly.
|
169 |
|
|
//
|
170 |
|
|
|
171 |
|
|
//std::cout << "| I'm cloing clusters, hit vector = " << (&hits) << std::endl;
|
172 |
|
|
|
173 |
|
|
const DetId detId( hit->geographicalId() );
|
174 |
|
|
if (hit->isValid() && (detId.det() == DetId::Tracker)) {
|
175 |
|
|
//std::cout << "| It is a tracker hit" << std::endl;
|
176 |
|
|
|
177 |
|
|
const std::type_info & hit_type = typeid(*hit);
|
178 |
|
|
if (hit_type == typeid(SiPixelRecHit)) {
|
179 |
|
|
//std::cout << "| It is a Pixel hit !!" << std::endl;
|
180 |
|
|
pixelClusterRecords_.push_back( PixelClusterHitRecord( static_cast<const SiPixelRecHit &>(*hit), &hits, hits.size() - 1) );
|
181 |
|
|
} else if (hit_type == typeid(SiStripRecHit2D)) {
|
182 |
|
|
//std::cout << "| It is a SiStripRecHit2D hit !!" << std::endl;
|
183 |
|
|
stripClusterRecords_.push_back( StripClusterHitRecord( static_cast<const SiStripRecHit2D &>(*hit), &hits, hits.size() - 1) );
|
184 |
|
|
} else if (hit_type == typeid(SiStripMatchedRecHit2D)) {
|
185 |
|
|
//std::cout << "| It is a SiStripMatchedRecHit2D hit !!" << std::endl;
|
186 |
|
|
const SiStripMatchedRecHit2D & mhit = static_cast<const SiStripMatchedRecHit2D &>(*hit);
|
187 |
|
|
stripClusterRecords_.push_back( StripClusterHitRecord( *mhit.monoHit() , &hits, hits.size() - 1) );
|
188 |
|
|
stripClusterRecords_.push_back( StripClusterHitRecord( *mhit.stereoHit(), &hits, hits.size() - 1) );
|
189 |
|
|
} else if (hit_type == typeid(ProjectedSiStripRecHit2D)) {
|
190 |
|
|
//std::cout << "| It is a ProjectedSiStripRecHit2D hit !!" << std::endl;
|
191 |
|
|
const ProjectedSiStripRecHit2D & phit = static_cast<const ProjectedSiStripRecHit2D &>(*hit);
|
192 |
|
|
stripClusterRecords_.push_back( StripClusterHitRecord( phit.originalHit(), &hits, hits.size() - 1) );
|
193 |
|
|
} else {
|
194 |
|
|
//std::cout << "| It is a " << hit_type.name() << " hit !?" << std::endl;
|
195 |
|
|
// do nothing. We might end up here for FastSim hits.
|
196 |
|
|
} // end 'switch' on hit type
|
197 |
|
|
} // end if it was a tracker hit
|
198 |
|
|
|
199 |
|
|
}
|
200 |
|
|
|
201 |
|
|
void
|
202 |
|
|
MuonCollectionStoreManager::
|
203 |
|
|
processAllClusters()
|
204 |
|
|
{
|
205 |
|
|
if (!pixelClusterRecords_.empty()) {
|
206 |
|
|
processClusters<SiPixelRecHit, SiPixelCluster>(pixelClusterRecords_, *selPixelClusters_, rPixelClusters_ );
|
207 |
|
|
}
|
208 |
|
|
if (!stripClusterRecords_.empty()) {
|
209 |
|
|
processClusters<SiStripRecHit2D,SiStripCluster>(stripClusterRecords_, *selStripClusters_, rStripClusters_ );
|
210 |
|
|
}
|
211 |
|
|
}
|
212 |
|
|
|
213 |
|
|
template<typename HitType, typename ClusterType>
|
214 |
|
|
void
|
215 |
|
|
MuonCollectionStoreManager::
|
216 |
|
|
processClusters( std::vector<ClusterHitRecord<HitType> > & clusterRecords,
|
217 |
|
|
edmNew::DetSetVector<ClusterType> & dsv,
|
218 |
|
|
edm::RefProd< edmNew::DetSetVector<ClusterType> > & refprod )
|
219 |
|
|
{
|
220 |
|
|
std::sort(clusterRecords.begin(), clusterRecords.end()); // this sorts them by detid
|
221 |
|
|
typedef typename std::vector<ClusterHitRecord<HitType> >::const_iterator RIT;
|
222 |
|
|
RIT it = clusterRecords.begin(), end = clusterRecords.end();
|
223 |
|
|
size_t clusters = 0;
|
224 |
|
|
while (it != end) {
|
225 |
|
|
RIT it2 = it;
|
226 |
|
|
uint32_t detid = it->detid();
|
227 |
|
|
|
228 |
|
|
// first isolate all clusters on the same detid
|
229 |
|
|
while ( (it2 != end) && (it2->detid() == detid)) { ++it2; }
|
230 |
|
|
// now [it, it2] bracket one detid
|
231 |
|
|
|
232 |
|
|
// then prepare to copy the clusters
|
233 |
|
|
typename edmNew::DetSetVector<ClusterType>::FastFiller filler(dsv, detid);
|
234 |
|
|
typename HitType::ClusterRef lastRef, newRef;
|
235 |
|
|
for ( ; it != it2; ++it) { // loop on the detid
|
236 |
|
|
// first check if we need to clone the hit
|
237 |
|
|
if (it->clusterRef() != lastRef) {
|
238 |
|
|
lastRef = it->clusterRef();
|
239 |
|
|
// clone cluster
|
240 |
|
|
filler.push_back( *lastRef ); // this might throw if !clusterRefsOK(..) above...
|
241 |
|
|
// make new ref
|
242 |
|
|
newRef = typename HitType::ClusterRef( refprod, clusters++ );
|
243 |
|
|
}
|
244 |
|
|
// then fixup the reference
|
245 |
|
|
it->rekey( newRef );
|
246 |
|
|
|
247 |
|
|
} // end of the loop on a single detid
|
248 |
|
|
|
249 |
|
|
} // end of the loop on all clusters
|
250 |
|
|
|
251 |
|
|
clusterRecords.clear();
|
252 |
|
|
} // end of the function
|
253 |
|
|
|
254 |
|
|
|
255 |
|
|
//-------------------------------------------------------------------------
|
256 |
|
|
//! Check if all references to silicon strip/pixel clusters are available.
|
257 |
|
|
//-------------------------------------------------------------------------
|
258 |
|
|
bool
|
259 |
|
|
MuonCollectionStoreManager::
|
260 |
|
|
clusterRefsOK(const reco::Track &track) const
|
261 |
|
|
{
|
262 |
|
|
|
263 |
|
|
for (trackingRecHit_iterator hitIt = track.recHitsBegin(); hitIt != track.recHitsEnd(); ++hitIt) {
|
264 |
|
|
const TrackingRecHit &hit = **hitIt;
|
265 |
|
|
if (!hit.isValid() || hit.geographicalId().det() != DetId::Tracker) continue;
|
266 |
|
|
|
267 |
|
|
// So we are in the tracker - now check hit types and availability of cluster refs:
|
268 |
|
|
const std::type_info &hit_type = typeid(hit);
|
269 |
|
|
if (hit_type == typeid(SiPixelRecHit)) {
|
270 |
|
|
if (!static_cast<const SiPixelRecHit &>(hit).cluster().isAvailable()) return false;
|
271 |
|
|
} else if (hit_type == typeid(SiStripRecHit2D)) {
|
272 |
|
|
if (!static_cast<const SiStripRecHit2D &>(hit).cluster().isAvailable()) return false;
|
273 |
|
|
} else if (hit_type == typeid(SiStripMatchedRecHit2D)) {
|
274 |
|
|
const SiStripMatchedRecHit2D &mHit = static_cast<const SiStripMatchedRecHit2D &>(hit);
|
275 |
|
|
if (!mHit.monoHit()->cluster().isAvailable()) return false;
|
276 |
|
|
if (!mHit.stereoHit()->cluster().isAvailable()) return false;
|
277 |
|
|
} else if (hit_type == typeid(ProjectedSiStripRecHit2D)) {
|
278 |
|
|
const ProjectedSiStripRecHit2D &pHit = static_cast<const ProjectedSiStripRecHit2D &>(hit);
|
279 |
|
|
if (!pHit.originalHit().cluster().isAvailable()) return false;
|
280 |
|
|
} else {
|
281 |
|
|
// std::cout << "| It is a " << hit_type.name() << " hit !?" << std::endl;
|
282 |
|
|
// Do nothing. We might end up here for FastSim hits.
|
283 |
|
|
} // end 'switch' on hit type
|
284 |
|
|
}
|
285 |
|
|
|
286 |
|
|
// No tracker hit with bad cluster found, so all fine:
|
287 |
|
|
return true;
|
288 |
|
|
}
|
289 |
|
|
|
290 |
|
|
//------------------------------------------------------------------
|
291 |
|
|
//! Put Muons, tracks, track extras and hits+clusters into the event.
|
292 |
|
|
//------------------------------------------------------------------
|
293 |
|
|
edm::OrphanHandle<reco::MuonCollection>
|
294 |
|
|
MuonCollectionStoreManager::
|
295 |
|
|
put( edm::Event & evt ) {
|
296 |
|
|
edm::OrphanHandle<reco::MuonCollection> h;
|
297 |
|
|
h = evt.put( selMuons_ , "SelectedMuons");
|
298 |
|
|
evt.put( selTracks_ , "TrackerOnly");
|
299 |
|
|
evt.put( selTracksExtras_ , "TrackerOnly");
|
300 |
|
|
evt.put( selTracksHits_ ,"TrackerOnly");
|
301 |
|
|
evt.put( selGlobalMuonTracks_,"GlobalMuon" );
|
302 |
|
|
evt.put( selGlobalMuonTracksExtras_ ,"GlobalMuon");
|
303 |
|
|
evt.put( selGlobalMuonTracksHits_,"GlobalMuon" );
|
304 |
|
|
evt.put( selStandAloneTracks_ ,"StandAlone");
|
305 |
|
|
evt.put( selStandAloneTracksExtras_ ,"StandAlone");
|
306 |
|
|
evt.put( selStandAloneTracksHits_ ,"StandAlone");
|
307 |
|
|
if (cloneClusters()) {
|
308 |
|
|
evt.put( selStripClusters_ );
|
309 |
|
|
evt.put( selPixelClusters_ );
|
310 |
|
|
}
|
311 |
|
|
return h;
|
312 |
|
|
|
313 |
|
|
}
|
314 |
|
|
|
315 |
|
|
|
316 |
|
|
} // end of namespace helper
|