Skip to content

Commit 6311778

Browse files
committed
Introduce 'PFASimple', a fastHisto-like simplification of PFA (by using step functon PFA weights) that can be implemented with minimal changes to the existing FH code.
1 parent c0064f6 commit 6311778

File tree

5 files changed

+108
-5
lines changed

5 files changed

+108
-5
lines changed

L1Trigger/VertexFinder/interface/AlgoSettings.h

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace l1tVertexFinder {
1313
enum class Algorithm {
1414
PFA,
1515
PFASingleVertex,
16+
PFASimple,
1617
fastHisto,
1718
fastHistoEmulation,
1819
fastHistoLooseAssociation,

L1Trigger/VertexFinder/interface/VertexFinder.h

+2
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ namespace l1tVertexFinder {
141141
void PFA();
142142
/// Peak finding algorithm, single vertex
143143
void PFASingleVertex();
144+
/// Peak finding algorithm, single vertex, fastHisto-like simplification (by using step functon PFA weights)
145+
void PFASimple();
144146
/// DBSCAN algorithm
145147
void DBSCAN();
146148
/// High pT Vertex Algorithm

L1Trigger/VertexFinder/plugins/VertexProducer.cc

+6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ VertexProducer::VertexProducer(const edm::ParameterSet& iConfig)
2929
case Algorithm::PFASingleVertex:
3030
edm::LogInfo("VertexProducer") << "VertexProducer::Finding vertices using the PFASingleVertex algorithm";
3131
break;
32+
case Algorithm::PFASimple:
33+
edm::LogInfo("VertexProducer") << "VertexProducer::Finding vertices using the PFASimple algorithm";
34+
break;
3235
case Algorithm::fastHisto:
3336
edm::LogInfo("VertexProducer") << "VertexProducer::Finding vertices using the fastHisto binning algorithm";
3437
break;
@@ -122,6 +125,9 @@ void VertexProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::Event
122125
case Algorithm::PFASingleVertex:
123126
vf.PFASingleVertex();
124127
break;
128+
case Algorithm::PFASimple:
129+
vf.PFASimple();
130+
break;
125131
case Algorithm::fastHisto: {
126132
const TrackerTopology& tTopo = iSetup.getData(tTopoToken);
127133
vf.fastHisto(&tTopo);

L1Trigger/VertexFinder/src/AlgoSettings.cc

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ namespace l1tVertexFinder {
6767
const std::map<std::string, Algorithm> AlgoSettings::algoNameMap = {
6868
{"PFA", Algorithm::PFA},
6969
{"PFASingleVertex", Algorithm::PFASingleVertex},
70+
{"PFASimple", Algorithm::PFASimple},
7071
{"fastHisto", Algorithm::fastHisto},
7172
{"fastHistoEmulation", Algorithm::fastHistoEmulation},
7273
{"fastHistoLooseAssociation", Algorithm::fastHistoLooseAssociation},
@@ -82,6 +83,7 @@ namespace l1tVertexFinder {
8283
const std::map<Algorithm, Precision> AlgoSettings::algoPrecisionMap = {
8384
{Algorithm::PFA, Precision::Simulation},
8485
{Algorithm::PFASingleVertex, Precision::Simulation},
86+
{Algorithm::PFASimple, Precision::Simulation},
8587
{Algorithm::fastHisto, Precision::Simulation},
8688
{Algorithm::fastHistoEmulation, Precision::Emulation},
8789
{Algorithm::fastHistoLooseAssociation, Precision::Simulation},

L1Trigger/VertexFinder/src/VertexFinder.cc

+97-5
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ namespace l1tVertexFinder {
126126
double highestPt = 0.;
127127
unsigned int numHighPtTracks = 0;
128128

129+
const float sqrt0p5 = std::sqrt(0.5);
130+
129131
float SumZ = 0.;
132+
float SumZWeightPFA = 0.;
130133
float z0square = 0.;
131134
float trackPt = 0.;
132135

@@ -153,7 +156,46 @@ namespace l1tVertexFinder {
153156
}
154157

155158
pt += std::pow(trackPt, settings_->vx_weightedmean());
156-
if (bin_centers.empty() && counts.empty()) {
159+
if (settings_->vx_algo() == Algorithm::PFASimple && settings_->vx_pfa_weightedz0() > 0) {
160+
// Calculate weighted-average z0 for PFASimple
161+
// Note the next few lines recompute the PFA width parameter (GaussianWidth) previously computed in PFASimple(). This could instead be saved as a track property.
162+
float trackAbsEta = std::fabs(track->eta());
163+
// Hard-coded eta-dependent and constant parametrisations of the PFA Gaussian width parameter taken from Giovanna's thesis: https://cds.cern.ch/record/2909504
164+
float GaussianWidth = settings_->vx_pfa_etadependentresolution()
165+
? 0.09867 + 0.0007 * trackAbsEta + 0.0587 * trackAbsEta * trackAbsEta
166+
: 0.15;
167+
// Customise PFA width parameter (via multiplicative scale factor)
168+
GaussianWidth *= settings_->vx_pfa_resolutionSF();
169+
float deltaZ = std::fabs(track->z0() - vertex.z0());
170+
float zweight = 0.;
171+
172+
if (settings_->vx_pfa_weightedz0() == 1) {
173+
// Nominal PFA weight function. No need to include 1/sqrt(2pi) normalisation constant in weight function, as it cancels out in the weighted sum.
174+
float GaussianWeight = std::exp(-0.5 * std::pow(deltaZ / GaussianWidth, 2)) / GaussianWidth;
175+
// Gaussian- and pT-weighted sums for estimates of vertex z0 and z0square based on the points of highest cumulative density of the contributions from each track at a given z0 position
176+
zweight = GaussianWeight * std::pow(trackPt, settings_->vx_weightedmean());
177+
}
178+
179+
// Alternative definitions of PFA weights (added subsequent to Giovanna's thesis)
180+
// Redefine deltaZ as the distance of the track from the bin edge (zero if inside the bin)
181+
deltaZ = (deltaZ > 0.5 * settings_->vx_pfa_binwidth()) ? deltaZ - 0.5 * settings_->vx_pfa_binwidth() : 0;
182+
183+
if (settings_->vx_pfa_weightedz0() == 2) {
184+
// Use Erfc to reduce the weight based on the probability that a track from a vertex in this bin would be closer than deltaZ to the edge of the bin
185+
float ErfcWeight = std::erfc(sqrt0p5 * deltaZ / GaussianWidth);
186+
// Estimates of vertex z0 and z0square based on optimal combination (weighted by 1/variance) of the z0 of the tracks associated to the vertex, weighted also by pT and association probability
187+
// Note, all tracks in the bin have association probability 1 based on the definiton of deltaZ above, so this method won't work well for large bin widths. In that case, the ErfcWeight should really be iteratively recalculated at the best estimate point of z0 (and not subtracting half the bin width in deltaZ), but this would require a second loop over tracks.
188+
zweight = ErfcWeight * std::pow(trackPt, settings_->vx_weightedmean()) / GaussianWidth / GaussianWidth;
189+
} else if (settings_->vx_pfa_weightedz0() == 3) {
190+
// Step function that allows tracks at most 1 sigma from the bin edge
191+
float StepFunctionWeight = deltaZ > GaussianWidth ? 0 : 1;
192+
// Step function weight, to replicate fastHisto when used with settings_->vx_pfa_weightfunction() == 3
193+
zweight = StepFunctionWeight * std::pow(trackPt, settings_->vx_weightedmean());
194+
}
195+
SumZWeightPFA += zweight;
196+
SumZ += track->z0() * zweight;
197+
z0square += track->z0() * track->z0() * zweight;
198+
} else if (bin_centers.empty() && counts.empty()) {
157199
SumZ += track->z0() * std::pow(trackPt, settings_->vx_weightedmean());
158200
z0square += track->z0() * track->z0();
159201
} else {
@@ -165,11 +207,23 @@ namespace l1tVertexFinder {
165207
ibin++;
166208
}
167209
}
168-
}
210+
} // end loop over tracks
169211

170-
z0 = SumZ / ((settings_->vx_weightedmean() > 0) ? pt : vertex.numTracks());
171-
z0square /= vertex.numTracks();
172-
z0width = sqrt(std::abs(z0 * z0 - z0square));
212+
if (settings_->vx_algo() == Algorithm::PFASimple) {
213+
// Alternative z0 calculation when using PFASimple
214+
if (settings_->vx_pfa_weightedz0() > 0 && SumZWeightPFA > 0) {
215+
z0 = SumZ / SumZWeightPFA;
216+
z0square /= SumZWeightPFA;
217+
z0width = sqrt(std::abs(z0 * z0 - z0square));
218+
} else {
219+
z0 = vertex.z0();
220+
z0width = 0.;
221+
}
222+
} else {
223+
z0 = SumZ / ((settings_->vx_weightedmean() > 0) ? pt : vertex.numTracks());
224+
z0square /= vertex.numTracks();
225+
z0width = sqrt(std::abs(z0 * z0 - z0square));
226+
}
173227

174228
vertex.setParameters(pt, z0, z0width, highPt, numHighPtTracks, highestPt);
175229
}
@@ -717,6 +771,44 @@ namespace l1tVertexFinder {
717771
}
718772
}
719773

774+
void VertexFinder::PFASimple() {
775+
float vxPt = 0.;
776+
RecoVertex leading_vertex;
777+
778+
int nbins = std::ceil((settings_->vx_pfa_max() - settings_->vx_pfa_min()) / settings_->vx_pfa_binwidth());
779+
for (int i = 0; i <= nbins; ++i) {
780+
float z = settings_->vx_pfa_min() + i * settings_->vx_pfa_binwidth();
781+
RecoVertex vertex;
782+
vertex.setZ0(z);
783+
for (const L1Track& track : fitTracks_) {
784+
float trackAbsEta = std::fabs(track.eta());
785+
// Hard-coded eta-dependent and constant parametrisations of the PFA Gaussian width parameter taken from Giovanna's thesis: https://cds.cern.ch/record/2909504
786+
float GaussianWidth = settings_->vx_pfa_etadependentresolution()
787+
? 0.09867 + 0.0007 * trackAbsEta + 0.0587 * trackAbsEta * trackAbsEta
788+
: 0.15;
789+
// Customise PFA width parameter (via multiplicative scale factor)
790+
GaussianWidth *= settings_->vx_pfa_resolutionSF();
791+
if (std::abs(z - track.z0()) > GaussianWidth + 0.5 * settings_->vx_pfa_binwidth())
792+
continue;
793+
794+
if (settings_->vx_pfa_doqualitycuts() &
795+
(track.pt() <
796+
settings_->vx_TrackMinPt())) // minimal additional quality cut as done in fastHistoEmulation()
797+
continue;
798+
799+
vertex.insert(&track);
800+
} // end loop over tracks
801+
computeAndSetVertexParameters(vertex, {}, {});
802+
if (vertex.pt() > vxPt) {
803+
leading_vertex = vertex;
804+
vxPt = vertex.pt();
805+
}
806+
}
807+
808+
vertices_.emplace_back(leading_vertex);
809+
pv_index_ = 0;
810+
} // end of PFASimple
811+
720812
/**
721813
* @note This method is the same as PFA() when settings_->vx_nvtx()=1
722814
* @note This method does not support settings_->vx_pfa_usemultiplicitymaxima()=True (which requires a 2-step process).

0 commit comments

Comments
 (0)