34 #include "Minuit2/FCNBase.h"
35 #include "Minuit2/FunctionMinimum.h"
36 #include "Minuit2/MnMigrad.h"
37 #include "Minuit2/MnPrint.h"
39 #include "TDirectory.h"
40 #include "TMinuitMinimizer.h"
59 TMinuitMinimizer::UseStaticMinuit(
false);
63 .getUntrackedParameter<edm::InputTag>(
"VertexCollection",
edm::InputTag(
"offlinePrimaryVertices")));
91 hPVx->SetDirectory(
nullptr);
92 hPVy->SetDirectory(
nullptr);
103 pvFitter.
addUntracked<
unsigned int>(
"maxNrStoredVertices");
104 pvFitter.
addUntracked<
unsigned int>(
"minNrVerticesForFit");
107 pvFitter.
addUntracked<
unsigned int>(
"minVertexNTracks");
131 for (reco::VertexCollection::const_iterator
pv = PVCollection->begin();
pv != PVCollection->end(); ++
pv) {
133 if (
pv != PVCollection->begin())
138 if (
pv->isFake() ||
pv->tracksSize() == 0)
147 const auto& testTrack =
pv->trackRefAt(0);
148 if (testTrack.isNull() || !testTrack.isAvailable()) {
149 edm::LogInfo(
"") <<
"Track collection not found. Skipping cut on sumPt.";
152 for (
auto iTrack =
pv->tracks_begin(); iTrack !=
pv->tracks_end(); ++iTrack) {
153 const auto pt = (*iTrack)->pt();
187 pvData.
posCorr[0] =
pv->covariance(0, 1) /
pv->xError() /
pv->yError();
188 pvData.
posCorr[1] =
pv->covariance(0, 2) /
pv->xError() /
pv->zError();
189 pvData.
posCorr[2] =
pv->covariance(1, 2) /
pv->yError() /
pv->zError();
212 using namespace ROOT::Minuit2;
213 edm::LogInfo(
"PVFitter") <<
" Number of bunch crossings: " <<
bxMap_.size() << std::endl;
217 for (std::map<
int, std::vector<BeamSpotFitPVData> >::const_iterator pvStore =
bxMap_.begin(); pvStore !=
bxMap_.end();
223 edm::LogInfo(
"PVFitter") <<
" Number of PVs collected for PVFitter: " << (pvStore->second).
size()
224 <<
" in bx: " << pvStore->first << std::endl;
227 edm::LogWarning(
"PVFitter") <<
" not enough PVs, continue" << std::endl;
232 edm::LogInfo(
"PVFitter") <<
"Calculating beam spot with PVs ..." << std::endl;
241 MnUserParameters upar;
242 upar.Add(
"x", 0., 0.02, -10., 10.);
243 upar.Add(
"y", 0., 0.02, -10., 10.);
244 upar.Add(
"z", 0., 0.20, -30., 30.);
245 upar.Add(
"ex", 0.015, 0.01, 0., 10.);
246 upar.Add(
"corrxy", 0., 0.02, -1., 1.);
247 upar.Add(
"ey", 0.015, 0.01, 0., 10.);
248 upar.Add(
"dxdz", 0., 0.0002, -0.1, 0.1);
249 upar.Add(
"dydz", 0., 0.0002, -0.1, 0.1);
250 upar.Add(
"ez", 1., 0.1, 0., 30.);
252 MnMigrad migrad(fcn, upar);
261 FunctionMinimum ierr = migrad(0, 1.);
262 if (!ierr.IsValid()) {
263 edm::LogInfo(
"PVFitter") <<
"3D beam spot fit failed in 1st iteration" << std::endl;
271 upar.Value(0) +
sigmaCut_ * upar.Value(3),
272 upar.Value(1) -
sigmaCut_ * upar.Value(5),
273 upar.Value(1) +
sigmaCut_ * upar.Value(5),
274 upar.Value(2) -
sigmaCut_ * upar.Value(8),
275 upar.Value(2) +
sigmaCut_ * upar.Value(8));
276 ierr = migrad(0, 1.);
277 if (!ierr.IsValid()) {
278 edm::LogInfo(
"PVFitter") <<
"3D beam spot fit failed in 2nd iteration" << std::endl;
288 ierr = migrad(0, 1.);
289 if (!ierr.IsValid()) {
290 edm::LogInfo(
"PVFitter") <<
"3D beam spot fit failed in 3rd iteration" << std::endl;
323 edm::LogInfo(
"PVFitter") <<
"3D PV fit done for this bunch crossing." << std::endl;
324 fit_ok = fit_ok &
true;
331 using namespace ROOT::Minuit2;
332 edm::LogInfo(
"PVFitter") <<
" Number of PVs collected for PVFitter: " <<
pvStore_.size() << std::endl;
339 TDirectory::TContext guard{
nullptr};
340 std::ostringstream
str;
342 std::unique_ptr<TH1D> h1PVx{
hPVx->ProjectionX((
std::string(
"h1PVx") +
str.str()).c_str(), 0, -1,
"e")};
343 std::unique_ptr<TH1D> h1PVy{
hPVy->ProjectionX((
std::string(
"h1PVy") +
str.str()).c_str(), 0, -1,
"e")};
344 std::unique_ptr<TH1D> h1PVz{
hPVx->ProjectionY((
std::string(
"h1PVz") +
str.str()).c_str(), 0, -1,
"e")};
348 TF1 gausx(
"localGausX",
"gaus", 0., 1., TF1::EAddToList::kNo);
349 TF1 gausy(
"localGausY",
"gaus", 0., 1., TF1::EAddToList::kNo);
350 TF1 gausz(
"localGausZ",
"gaus", 0., 1., TF1::EAddToList::kNo);
352 h1PVx->Fit(&gausx,
"QLMN0 SERIAL");
353 h1PVy->Fit(&gausy,
"QLMN0 SERIAL");
354 h1PVz->Fit(&gausz,
"QLMN0 SERIAL");
356 fwidthX = gausx.GetParameter(2);
357 fwidthY = gausy.GetParameter(2);
358 fwidthZ = gausz.GetParameter(2);
363 double estX = gausx.GetParameter(1);
364 double estY = gausy.GetParameter(1);
365 double estZ = gausz.GetParameter(1);
372 matrix(2, 2) = gausz.GetParError(1) * gausz.GetParError(1);
395 MnUserParameters upar;
396 upar.Add(
"x", estX, errX, -10., 10.);
397 upar.Add(
"y", estY, errY, -10., 10.);
398 upar.Add(
"z", estZ, errZ, -30., 30.);
399 upar.Add(
"ex", 0.015, 0.01, 0., 10.);
400 upar.Add(
"corrxy", 0., 0.02, -1., 1.);
401 upar.Add(
"ey", 0.015, 0.01, 0., 10.);
402 upar.Add(
"dxdz", 0., 0.0002, -0.1, 0.1);
403 upar.Add(
"dydz", 0., 0.0002, -0.1, 0.1);
404 upar.Add(
"ez", 1., 0.1, 0., 30.);
406 MnMigrad migrad(fcn, upar);
414 FunctionMinimum ierr = migrad(0, 1.);
415 if (!ierr.IsValid()) {
416 edm::LogWarning(
"PVFitter") <<
"3D beam spot fit failed in 1st iteration" << std::endl;
424 vector<double> errors;
425 results = ierr.UserParameters().Params();
426 errors = ierr.UserParameters().Errors();
434 ierr = migrad(0, 1.);
435 if (!ierr.IsValid()) {
436 edm::LogWarning(
"PVFitter") <<
"3D beam spot fit failed in 2nd iteration" << std::endl;
445 ierr = migrad(0, 1.);
446 if (!ierr.IsValid()) {
447 edm::LogWarning(
"PVFitter") <<
"3D beam spot fit failed in 3rd iteration" << std::endl;
451 results = ierr.UserParameters().Params();
452 errors = ierr.UserParameters().Errors();
463 edm::LogWarning(
"PVFitter") <<
"3D beam spot fit returns nan in 3rd iteration" << std::endl;
505 unsigned int iwrite(0);
506 for (
unsigned int i = 0; i <
pvStore_.size(); ++
i) {
515 <<
" ; new dynamic quality cut = " << dynamicQualityCut_ << std::endl;
std::vector< double > pvQualities_
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
math::Error< dimension >::type CovarianceMatrix
void setTree(TTree *tree)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
void initialize(const edm::ParameterSet &iConfig, edm::ConsumesCollector &iColl)
void run(unsigned int run)
std::map< int, std::vector< BeamSpotFitPVData > > bxMap_
void compressStore()
reduce size of primary vertex cache by increasing quality limit
bool getByToken(EDGetToken token, Handle< PROD > &result) const
constexpr bool isNotFinite(T x)
int bunchCrossing() const
edm::LuminosityBlockNumber_t luminosityBlock() const
std::vector< Vertex > VertexCollection
collection of Vertex objects
math::XYZPoint Point
point in the space
double covariance(int i, int j) const
(i, j)-th element of error matrix, i, j = 0, ... 2
double dynamicQualityCut_
void setType(BeamType type)
set beam type
void bunchCrossing(unsigned int bunchCrossing)
void lumi(unsigned int lumi)
std::vector< BeamSpotFitPVData > pvStore_
void readEvent(const edm::Event &iEvent)
void setBeamWidthY(double v)
std::unique_ptr< TH2F > hPVx
BeamSpotTreeData theBeamSpotTreeData_
bool fFitPerBunchCrossing
void pvData(const BeamSpotFitPVData &pvData)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
edm::EDGetTokenT< reco::VertexCollection > vertexToken_
double pvQuality(const reco::Vertex &pv) const
vertex quality measure
std::map< int, reco::BeamSpot > fbspotMap
unsigned int maxNrVertices_
Log< level::Info, false > LogInfo
static void fillDescription(edm::ParameterSetDescription &)
unsigned int minVtxTracks_
std::unique_ptr< TH2F > hPVy
void fcn(int &, double *, double &, double *, int)
T getParameter(std::string const &) const
unsigned int minNrVertices_
void setLimits(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax)
void setBeamWidthX(double v)
Log< level::Warning, false > LogWarning
tuple size
Write out results.
Power< A, B >::type pow(const A &a, const B &b)