CMS 3D CMS Logo

PackedCandidate.cc
Go to the documentation of this file.
6 
8 using namespace logintpack;
9 
12 
13 void pat::PackedCandidate::pack(bool unpackAfterwards) {
14  packedPt_ = MiniFloatConverter::float32to16(p4_.load()->Pt());
15  packedEta_ = int16_t(std::round(p4_.load()->Eta()/6.0f*std::numeric_limits<int16_t>::max()));
16  packedPhi_ = int16_t(std::round(p4_.load()->Phi()/3.2f*std::numeric_limits<int16_t>::max()));
17  packedM_ = MiniFloatConverter::float32to16(p4_.load()->M());
18  if (unpackAfterwards) {
19  delete p4_.exchange(nullptr);
20  delete p4c_.exchange(nullptr);
21  unpack(); // force the values to match with the packed ones
22  }
23 }
24 
25 void pat::PackedCandidate::packVtx(bool unpackAfterwards) {
26  reco::VertexRef pvRef = vertexRef();
27  Point pv = pvRef.isNonnull() ? pvRef->position() : Point();
28  float dxPV = vertex_.load()->X() - pv.X(), dyPV = vertex_.load()->Y() - pv.Y(); //, rPV = std::hypot(dxPV, dyPV);
29  float s = std::sin(float(p4_.load()->Phi())+dphi_), c = std::cos(float(p4_.load()->Phi()+dphi_)); // not the fastest option, but we're in reduced precision already, so let's avoid more roundoffs
30  dxy_ = - dxPV * s + dyPV * c;
31  // if we want to go back to the full x,y,z we need to store also
32  // float dl = dxPV * c + dyPV * s;
33  // float xRec = - dxy_ * s + dl * c, yRec = dxy_ * c + dl * s;
34  float pzpt = p4_.load()->Pz()/p4_.load()->Pt();
35  dz_ = vertex_.load()->Z() - pv.Z() - (dxPV*c + dyPV*s) * pzpt;
36  packedDxy_ = MiniFloatConverter::float32to16(dxy_*100);
37  packedDz_ = pvRef.isNonnull() ? MiniFloatConverter::float32to16(dz_*100) : int16_t(std::round(dz_/40.f*std::numeric_limits<int16_t>::max()));
38  packedDPhi_ = int16_t(std::round(dphi_/3.2f*std::numeric_limits<int16_t>::max()));
39  packedDEta_ = MiniFloatConverter::float32to16(deta_);
40  packedDTrkPt_ = MiniFloatConverter::float32to16(dtrkpt_);
41 
42  if (unpackAfterwards) {
43  delete vertex_.exchange(nullptr);
44  unpackVtx();
45  }
46 }
47 
49  float pt = MiniFloatConverter::float16to32(packedPt_);
50  double shift = (pt<1. ? 0.1*pt : 0.1/pt); // shift particle phi to break degeneracies in angular separations
51  double sign = ( ( int(pt*10) % 2 == 0 ) ? 1 : -1 ); // introduce a pseudo-random sign of the shift
52  double phi = int16_t(packedPhi_)*3.2f/std::numeric_limits<int16_t>::max() + sign*shift*3.2/std::numeric_limits<int16_t>::max();
53  auto p4 = std::make_unique<PolarLorentzVector>(pt,
54  int16_t(packedEta_)*6.0f/std::numeric_limits<int16_t>::max(),
55  phi,
57  auto p4c = std::make_unique<LorentzVector>( *p4 );
58  PolarLorentzVector* expectp4= nullptr;
59  if( p4_.compare_exchange_strong(expectp4,p4.get()) ) {
60  p4.release();
61  }
62 
63  //p4c_ works as the guard for unpacking so it
64  // must be set last
65  LorentzVector* expectp4c = nullptr;
66  if(p4c_.compare_exchange_strong(expectp4c, p4c.get()) ) {
67  p4c.release();
68  }
69 }
70 
72  packedCovariance_.dptdpt = packCovarianceElement(m,0,0);
73  packedCovariance_.detadeta = packCovarianceElement(m,1,1);
74  packedCovariance_.dphidphi = packCovarianceElement(m,2,2);
75  packedCovariance_.dxydxy =packCovarianceElement(m,3,3);
76  packedCovariance_.dzdz = packCovarianceElement(m,4,4);
77  packedCovariance_.dxydz = packCovarianceElement(m,3,4);
78  packedCovariance_.dlambdadz = packCovarianceElement(m,1,4);
79  packedCovariance_.dphidxy = packCovarianceElement(m,2,3);
80  //unpack afterwards
81  if(unpackAfterwards) unpackCovariance();
82 }
83 
85  const CovarianceParameterization & p=covarianceParameterization();
86  if(p.isValid())
87  {
88  auto m = std::make_unique<reco::TrackBase::CovarianceMatrix>() ;
89  for(int i=0;i<5;i++)
90  for(int j=0;j<5;j++){
91  (*m)(i,j)=0;
92  }
93  unpackCovarianceElement(*m,packedCovariance_.dptdpt,0,0);
94  unpackCovarianceElement(*m,packedCovariance_.detadeta,1,1);
95  unpackCovarianceElement(*m,packedCovariance_.dphidphi,2,2);
96  unpackCovarianceElement(*m,packedCovariance_.dxydxy,3,3);
97  unpackCovarianceElement(*m,packedCovariance_.dzdz,4,4);
98  unpackCovarianceElement(*m,packedCovariance_.dxydz,3,4);
99  unpackCovarianceElement(*m,packedCovariance_.dlambdadz,1,4);
100  unpackCovarianceElement(*m,packedCovariance_.dphidxy,2,3);
101  reco::TrackBase::CovarianceMatrix* expected = nullptr;
102  if( m_.compare_exchange_strong(expected,m.get()) ) {
103  m.release();
104  }
105 
106  } else {
108  << "You do not have a valid track parameters file loaded. "
109  << "Please check that the release version is compatible with your input data"
110  <<"or avoid accessing track parameter uncertainties. ";
111  }
112 }
113 
115  reco::VertexRef pvRef = vertexRef();
116  dphi_ = int16_t(packedDPhi_)*3.2f/std::numeric_limits<int16_t>::max(),
117  deta_ = MiniFloatConverter::float16to32(packedDEta_);
118  dtrkpt_ = MiniFloatConverter::float16to32(packedDTrkPt_);
119  dxy_ = MiniFloatConverter::float16to32(packedDxy_)/100.;
120  dz_ = pvRef.isNonnull() ? MiniFloatConverter::float16to32(packedDz_)/100. : int16_t(packedDz_)*40.f/std::numeric_limits<int16_t>::max();
121  Point pv = pvRef.isNonnull() ? pvRef->position() : Point();
122  float phi = p4_.load()->Phi()+dphi_, s = std::sin(phi), c = std::cos(phi);
123  auto vertex = std::make_unique<Point>(pv.X() - dxy_ * s,
124  pv.Y() + dxy_ * c,
125  pv.Z() + dz_ ); // for our choice of using the PCA to the PV, by definition the remaining term -(dx*cos(phi) + dy*sin(phi))*(pz/pt) is zero
126 
127 
128 
129 
130  Point* expected = nullptr;
131  if( vertex_.compare_exchange_strong(expected,vertex.get()) ) {
132  vertex.release();
133  }
134 }
135 
137  delete p4_.load();
138  delete p4c_.load();
139  delete vertex_.load();
140  delete track_.load();
141  delete m_.load();
142 }
143 
144 
145 float pat::PackedCandidate::dxy(const Point &p) const {
146  maybeUnpackBoth();
147  const float phi = float(p4_.load()->Phi())+dphi_;
148  return -(vertex_.load()->X()-p.X()) * std::sin(phi) + (vertex_.load()->Y()-p.Y()) * std::cos(phi);
149 }
150 float pat::PackedCandidate::dz(const Point &p) const {
151  maybeUnpackBoth();
152  const float phi = float(p4_.load()->Phi())+dphi_;
153  return (vertex_.load()->Z()-p.Z()) - ((vertex_.load()->X()-p.X()) * std::cos(phi) + (vertex_.load()->Y()-p.Y()) * std::sin(phi)) * p4_.load()->Pz()/p4_.load()->Pt();
154 }
155 
157  maybeUnpackBoth();
158  math::RhoEtaPhiVector p3(ptTrk(),etaAtVtx(),phiAtVtx());
159  maybeUnpackCovariance();
160  int numberOfStripLayers = stripLayersWithMeasurement(), numberOfPixelLayers = pixelLayersWithMeasurement();
161  int numberOfPixelHits = this->numberOfPixelHits();
162  int numberOfHits = this->numberOfHits();
163 
164  int ndof = numberOfHits+numberOfPixelHits-5;
165  reco::HitPattern hp, hpExpIn;
166  int i=0;
167  LostInnerHits innerLost = lostInnerHits();
168 
169  auto track = std::make_unique<reco::Track>(normalizedChi2_*ndof,ndof,*vertex_,math::XYZVector(p3.x(),p3.y(),p3.z()),charge(),*(m_.load()),reco::TrackBase::undefAlgorithm,reco::TrackBase::loose);
170 
171  // add hits to match the number of laters and validHitInFirstPixelBarrelLayer
172  if(innerLost == validHitInFirstPixelBarrelLayer){
173  // first we add one hit on the first barrel layer
174  track->appendTrackerHitPattern(PixelSubdetector::PixelBarrel, 1, 0, TrackingRecHit::valid);
175  // then to encode the number of layers, we add more hits on distinct layers (B2, B3, B4, F1, ...)
176  for(i++; i<numberOfPixelLayers; i++) {
177  if (i <= 3) {
178  track->appendTrackerHitPattern(PixelSubdetector::PixelBarrel, i+1, 0, TrackingRecHit::valid);
179  } else {
180  track->appendTrackerHitPattern(PixelSubdetector::PixelEndcap, i-3, 0, TrackingRecHit::valid);
181  }
182  }
183  } else {
184  // to encode the information on the layers, we add one valid hits per layer but skipping PXB1
185  for(;i<numberOfPixelLayers; i++) {
186  if (i <= 2 ) {
187  track->appendTrackerHitPattern(PixelSubdetector::PixelBarrel, i+2, 0, TrackingRecHit::valid);
188  } else {
189  track->appendTrackerHitPattern(PixelSubdetector::PixelEndcap, i-3, 0, TrackingRecHit::valid);
190  }
191  }
192  }
193  // add extra hits (overlaps, etc), all on the first layer with a hit - to avoid increasing the layer count
194  for(;i<numberOfPixelHits; i++) {
195  track->appendTrackerHitPattern(PixelSubdetector::PixelBarrel, (innerLost == validHitInFirstPixelBarrelLayer ? 1 : 2), 0, TrackingRecHit::valid);
196  }
197  // now start adding strip layers, putting one hit on each layer so that the hitPattern.stripLayersWithMeasurement works.
198  // we don't know what the layers where, so we just start with TIB (4 layers), then TOB (6 layers), then TEC (9)
199  // and then TID(3), so that we can get a number of valid strip layers up to 4+6+9+3
200  for(int sl = 0; sl < numberOfStripLayers; ++sl, ++i) {
201  if (sl < 4) track->appendTrackerHitPattern(StripSubdetector::TIB, sl +1, 1, TrackingRecHit::valid);
202  else if (sl < 4+6) track->appendTrackerHitPattern(StripSubdetector::TOB, (sl- 4)+1, 1, TrackingRecHit::valid);
203  else if (sl < 10+9) track->appendTrackerHitPattern(StripSubdetector::TEC, (sl-10)+1, 1, TrackingRecHit::valid);
204  else if (sl < 19+3) track->appendTrackerHitPattern(StripSubdetector::TID, (sl-13)+1, 1, TrackingRecHit::valid);
205  else break; // wtf?
206  }
207  // finally we account for extra strip hits beyond the one-per-layer added above. we put them all on TIB1,
208  // to avoid incrementing the number of layersWithMeasurement.
209  for(;i<numberOfHits;i++) {
210  track->appendTrackerHitPattern(StripSubdetector::TIB, 1, 1, TrackingRecHit::valid);
211  }
212 
213 
214  switch (innerLost) {
215  case validHitInFirstPixelBarrelLayer:
216  break;
217  case noLostInnerHits:
218  break;
219  case oneLostInnerHit:
220  track->appendTrackerHitPattern(PixelSubdetector::PixelBarrel, 1, 0, TrackingRecHit::missing_inner);
221  break;
222  case moreLostInnerHits:
223  track->appendTrackerHitPattern(PixelSubdetector::PixelBarrel, 1, 0, TrackingRecHit::missing_inner);
224  track->appendTrackerHitPattern(PixelSubdetector::PixelBarrel, 2, 0, TrackingRecHit::missing_inner);
225  break;
226  };
227 
228  if (trackHighPurity()) track->setQuality(reco::TrackBase::highPurity);
229 
230  reco::Track* expected = nullptr;
231  if( track_.compare_exchange_strong(expected,track.get()) ) {
232  track.release();
233  }
234 
235 
236 }
237 
239 
241  throw cms::Exception("Invalid Reference")
242  << "this Candidate has no master clone reference."
243  << "Can't call masterClone() method.\n";
244 }
245 
247  return false;
248 }
249 
251  return false;
252 }
253 
254 
256  throw cms::Exception("Invalid Reference")
257  << "this Candidate has no master clone ptr."
258  << "Can't call masterClonePtr() method.\n";
259 }
260 
262  return 0;
263 }
264 
266  return 0;
267 }
268 
270  return p4() == o.p4() && vertex() == o.vertex() && charge() == o.charge();
271 // return p4() == o.p4() && charge() == o.charge();
272 }
273 
275  return 0;
276 }
277 
279  return 0;
280 }
281 
284  << "This Candidate type does not implement daughter(std::string). "
285  << "Please use CompositeCandidate or NamedCompositeCandidate.\n";
286 }
287 
290  << "This Candidate type does not implement daughter(std::string). "
291  << "Please use CompositeCandidate or NamedCompositeCandidate.\n";
292 }
293 
294 
295 
297  return 0;
298 }
299 
301  return 0;
302 }
303 
305  return 0;
306 }
307 
309  return 0;
310 }
311 
312 double pat::PackedCandidate::vertexCovariance(int i, int j) const {
314  << "reco::ConcreteCandidate does not implement vertex covariant matrix.\n";
315 }
316 
319  << "reco::ConcreteCandidate does not implement vertex covariant matrix.\n";
320 }
321 
322 
323 bool pat::PackedCandidate::longLived() const {return false;}
324 
325 bool pat::PackedCandidate::massConstraint() const {return false;}
326 
327 // puppiweight
328 void pat::PackedCandidate::setPuppiWeight(float p, float p_nolep) {
329  // Set both weights at once to avoid misconfigured weights if called in the wrong order
330  packedPuppiweight_ = pack8logClosed((p-0.5)*2,-2,0,64);
331  packedPuppiweightNoLepDiff_ = pack8logClosed((p_nolep-0.5)*2,-2,0,64) - packedPuppiweight_;
332 }
333 
334 float pat::PackedCandidate::puppiWeight() const { return unpack8logClosed(packedPuppiweight_,-2,0,64)/2. + 0.5;}
335 
336 float pat::PackedCandidate::puppiWeightNoLep() const { return unpack8logClosed(packedPuppiweightNoLepDiff_+packedPuppiweight_,-2,0,64)/2. + 0.5;}
337 
340  rawCaloFraction_ = std::numeric_limits<uint8_t>::max(); // Set to overflow value
341  else
342  rawCaloFraction_ = 100*p;
343 }
344 
346  hcalFraction_ = 100*p;
347 }
348 
350  isIsolatedChargedHadron_ = p;
351 }
float puppiWeight() const
Set both weights at once (with option for only full PUPPI)
virtual float dz(size_t ipv=0) const
dz with respect to the PV[ipv]
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:252
virtual size_t numberOfMothers() const
number of mothers
virtual bool hasMasterClonePtr() const
float puppiWeightNoLep() const
Weight from full PUPPI.
void setPuppiWeight(float p, float p_nolep=0.0)
size_t size_type
Definition: Candidate.h:30
virtual void fillVertexCovariance(CovarianceMatrix &v) const
fill SMatrix
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
virtual double vertexNdof() const
void setRawCaloFraction(float p)
Weight from PUPPI removing leptons.
virtual bool overlap(const reco::Candidate &) const
check overlap with another Candidate
std::pair< double, double > Point
Definition: CaloEllipse.h:18
RhoEtaPhiVectorD RhoEtaPhiVector
spatial vector with cylindrical internal representation using pseudorapidity
Definition: Vector3D.h:32
static float float16to32(uint16_t h)
Definition: libminifloat.h:10
virtual const reco::Candidate * daughter(size_type) const
return daughter at a given position (throws an exception)
int8_t pack8logClosed(double x, double lmin, double lmax, uint8_t base=128)
void setHcalFraction(float p)
Raw ECAL+HCAL energy over candidate energy for isolated charged hadrons.
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector
susybsm::HSCParticleRefProd hp
Definition: classes.h:27
double p4[4]
Definition: TauolaWrapper.h:92
static uint16_t float32to16(float x)
Definition: libminifloat.h:15
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
virtual const reco::CandidateBaseRef & masterClone() const
static CovarianceParameterization covarianceParameterization_
def pv(vc)
Definition: MetAnalyzer.py:6
double f[11][100]
virtual double vertexNormalizedChi2() const
chi-squared divided by n.d.o.f.
virtual const reco::CandidatePtr & masterClonePtr() const
LostInnerHits
Enumerator specifying the.
virtual bool massConstraint() const
do mass constraint?
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
static std::once_flag covariance_load_flag
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
virtual size_t numberOfDaughters() const
number of daughters
void unpackCovariance() const
virtual int charge() const =0
electric charge
CovarianceMatrix vertexCovariance() const
return SMatrix
double unpack8logClosed(int8_t i, double lmin, double lmax, uint8_t base=128)
reverse of pack8logClosed
virtual bool longLived() const
is long lived?
virtual const reco::Candidate * mother(size_type) const
return mother at a given position (throws an exception)
void packVtx(bool unpackAfterwards=true)
static unsigned int const shift
void setIsIsolatedChargedHadron(bool p)
Fraction of Ecal and Hcal for HF and neutral hadrons and isolated charged hadrons.
math::XYZPoint Point
point in the space
Definition: Candidate.h:41
virtual const Point & vertex() const =0
vertex position
void pack(bool unpackAfterwards=true)
void packCovariance(const reco::TrackBase::CovarianceMatrix &m, bool unpackAfterwards=true)
virtual float dxy() const
dxy with respect to the PV ref
virtual double vertexChi2() const
chi-squares
virtual ~PackedCandidate()
destructor
math::Error< dimension >::type CovarianceMatrix
5 parameter covariance matrix
Definition: TrackBase.h:77
virtual bool hasMasterClone() const
double p3[4]
Definition: TauolaWrapper.h:91
math::PtEtaPhiMLorentzVector PolarLorentzVector
Lorentz vector.
Definition: Candidate.h:39