19 #include <fmt/format.h>
20 #include <fmt/printf.h>
45 namespace SiPixelLAHarvest {
103 std::unique_ptr<TF1>
f1;
119 newmodulelist_(iConfig.getParameter<std::
vector<std::
string>>(
"newmodulelist")),
120 dqmDir_(iConfig.getParameter<std::
string>(
"dqmDir")),
121 fitChi2Cut_(iConfig.getParameter<double>(
"fitChi2Cut")),
122 minHitsCut_(iConfig.getParameter<int>(
"minHitsCut")),
123 recordName_(iConfig.getParameter<std::
string>(
"record")) {
127 throw cms::Exception(
"SiPixelLorentzAnglePCLHarvester") <<
"PoolDBService required";
154 if (modulename.find(
"BPix_") != std::string::npos) {
156 const auto& detId = bn.
getDetId(tTopo);
161 }
else if (modulename.find(
"FPix_") != std::string::npos) {
163 const auto& detId = en.
getDetId(tTopo);
174 LogDebug(
"SiPixelLorentzAnglePCLHarvester") <<
id;
177 LogDebug(
"SiPixelLorentzAnglePCLHarvester") <<
"Stored a total of " << count <<
" new detIds.";
183 std::vector<uint32_t> treatedIndices;
185 for (
auto det : geom->
detsPXB()) {
198 if (
std::find(treatedIndices.begin(), treatedIndices.end(), i_index) != treatedIndices.end()) {
201 hists.
detIdsList.insert(std::pair<uint32_t, std::vector<uint32_t>>(i_index, {rawId}));
202 treatedIndices.push_back(i_index);
207 for (
const auto&
i : treatedIndices) {
209 LogDebug(
"SiPixelLorentzAnglePCLHarvester") <<
id;
213 LogDebug(
"SiPixelLorentzAnglePCLHarvester") <<
"Stored a total of " << count <<
" detIds.";
230 for (
int i_layer = 1; i_layer <=
hists.
nlay; i_layer++) {
231 const auto& prefix_ = fmt::sprintf(
"%s/BPix/BPixLayer%i",
dqmDir_, i_layer);
232 for (
int i_module = 1; i_module <=
hists.
nModules_[i_layer - 1]; i_module++) {
233 int i_index = i_module + (i_layer - 1) *
hists.
nModules_[i_layer - 1];
236 iGetter.
get(
fmt::format(
"{}/h_drift_depth_layer{}_module{}", prefix_, i_layer, i_module));
240 <<
"Failed to retrieve electron drift over depth for layer " << i_layer <<
", module " << i_module <<
".";
245 iGetter.
get(
fmt::format(
"{}/h_drift_depth_adc_layer{}_module{}", prefix_, i_layer, i_module));
248 iGetter.
get(
fmt::format(
"{}/h_drift_depth_adc2_layer{}_module{}", prefix_, i_layer, i_module));
251 iGetter.
get(
fmt::format(
"{}/h_drift_depth_noadc_layer{}_module{}", prefix_, i_layer, i_module));
290 edm::LogError(
"SiPixelLorentzAnglePCLHarvester") <<
"Failed to retrieve the hit on track occupancy.";
313 iBooker.
book1D(
"h_drift_depth_adc_slice",
"slice of adc histogram", hist_drift_, min_drift_, max_drift_);
317 "h_diffLA",
"difference in #mu_{H}; #Delta #mu_{H}/#mu_{H} (old-new)/old [%];n. modules", 100, -150, 150);
321 const double lo = -0.5;
322 const double hi = maxSect - 0.5;
326 std::string repText =
"%s tan#theta_{LA}/B by sector;pixel sector;%s tan(#theta_{LA})/B [1/T]";
328 iBooker.
book1D(
"h_LAbySector_Measured", fmt::sprintf(repText,
"measured",
"measured"), maxSect, lo, hi);
330 iBooker.
book1D(
"h_LAbySector_Accepted", fmt::sprintf(repText,
"accepted",
"accepted"), maxSect, lo, hi);
332 iBooker.
book1D(
"h_LAbySector_Rejected", fmt::sprintf(repText,
"rejected",
"rejected"), maxSect, lo, hi);
333 hists.
h_bySectLA_ = iBooker.
book1D(
"h_LAbySector", fmt::sprintf(repText,
"payload",
"payload"), maxSect, lo, hi);
335 iBooker.
book1D(
"h_deltaLAbySector", fmt::sprintf(repText,
"#Delta",
"#Delta"), maxSect, lo, hi);
337 iBooker.
book1D(
"h_bySectorChi2",
"Fit #chi^{2}/ndf by sector;pixel sector; fit #chi^{2}/ndf", maxSect, lo, hi);
340 for (
int bin = 1;
bin <= maxSect;
bin++) {
354 std::string repText =
"BPix Layer %i tan#theta_{LA}/B;module number;ladder number;tan#theta_{LA}/B [1/T]";
357 fmt::sprintf(repText,
i + 1),
365 repName =
"h2_byLayerDiff_%i";
366 repText =
"BPix Layer %i #Delta#mu_{H}/#mu_{H};module number;ladder number;#Delta#mu_{H}/#mu_{H} [%%]";
368 fmt::sprintf(repText,
i + 1),
378 edm::LogPrint(
"LorentzAngle") <<
"module" <<
"\t" <<
"layer" <<
"\t"
379 <<
"offset" <<
"\t" <<
"e0" <<
"\t"
380 <<
"slope" <<
"\t" <<
"e1" <<
"\t"
381 <<
"rel.err" <<
"\t" <<
"pull" <<
"\t"
382 <<
"p2" <<
"\t" <<
"e2" <<
"\t"
383 <<
"p3" <<
"\t" <<
"e3" <<
"\t"
384 <<
"p4" <<
"\t" <<
"e4" <<
"\t"
385 <<
"p5" <<
"\t" <<
"e5" <<
"\t"
386 <<
"chi2" <<
"\t" <<
"prob" <<
"\t"
387 <<
"newDetId" <<
"\t" <<
"tan(LA)" <<
"\t"
392 std::shared_ptr<SiPixelLorentzAngle> LorentzAngle = std::make_shared<SiPixelLorentzAngle>();
395 double p1_simul_newmodule = 0.294044;
397 for (
int i_layer = 1; i_layer <=
hists.
nlay; i_layer++) {
398 for (
int i_module = 1; i_module <=
hists.
nModules_[i_layer - 1]; i_module++) {
400 p1_simul[i_layer - 1][i_module - 1] = 0.436848;
401 else if (i_layer == 2)
402 p1_simul[i_layer - 1][i_module - 1] = 0.25802;
403 else if (i_layer == 3 && i_module <= 4)
404 p1_simul[i_layer - 1][i_module - 1] = 0.29374;
405 else if (i_layer == 3 && i_module >= 5)
406 p1_simul[i_layer - 1][i_module - 1] = 0.31084;
407 else if (i_layer == 4 && i_module <= 4)
408 p1_simul[i_layer - 1][i_module - 1] = 0.29944;
410 p1_simul[i_layer - 1][i_module - 1] = 0.31426;
415 p1_simul[
hists.
nlay][i_module - 1] = p1_simul_newmodule;
424 for (
int i = 1;
i <= hist_depth_;
i++) {
425 findMean(h_drift_depth_adc_slice_,
i, new_index);
433 << std::setprecision(3) <<
"\t" << res.e1 <<
"\t" << res.e1 / res.p1 * 100.
434 <<
"\t" << (res.p1 - p1_simul[
hists.
nlay][0]) / res.e1 <<
"\t" << res.p2
435 <<
"\t" << res.e2 <<
"\t" << res.p3 <<
"\t" << res.e3 <<
"\t" << res.p4 <<
"\t"
436 << res.e4 <<
"\t" << res.p5 <<
"\t" << res.e5 <<
"\t" << res.chi2 <<
"\t"
442 for (
int i_layer = 1; i_layer <=
hists.
nlay; i_layer++) {
443 for (
int i_module = 1; i_module <=
hists.
nModules_[i_layer - 1]; i_module++) {
444 int i_index = i_module + (i_layer - 1) *
hists.
nModules_[i_layer - 1];
448 for (
int i = 1;
i <= hist_depth_;
i++) {
449 findMean(h_drift_depth_adc_slice_,
i, i_index);
453 const auto& res =
fitAndStore(LorentzAngle, i_index, i_layer, i_module);
456 << std::setprecision(4) << i_module <<
"\t" << i_layer <<
"\t" << res.p0 <<
"\t" << res.e0 <<
"\t" << res.p1
457 << std::setprecision(3) <<
"\t" << res.e1 <<
"\t" << res.e1 / res.p1 * 100. <<
"\t"
458 << (res.p1 - p1_simul[i_layer - 1][i_module - 1]) / res.e1 <<
"\t" << res.p2 <<
"\t" << res.e2 <<
"\t"
459 << res.p3 <<
"\t" << res.e3 <<
"\t" << res.p4 <<
"\t" << res.e4 <<
"\t" << res.p5 <<
"\t" << res.e5 <<
"\t"
460 << res.chi2 <<
"\t" << res.prob <<
"\t"
462 <<
"\t" << res.tan_LA <<
"\t" << res.error_LA;
468 const auto& newLAMap = LorentzAngle->getLorentzAngles();
469 std::vector<unsigned int> currentLADets;
470 std::vector<unsigned int> newLADets;
474 std::back_inserter(currentLADets),
479 std::back_inserter(newLADets),
482 std::vector<unsigned int> notCommon;
483 std::set_symmetric_difference(
484 currentLADets.begin(), currentLADets.end(), newLADets.begin(), newLADets.end(), std::back_inserter(notCommon));
486 for (
const auto&
id : notCommon) {
488 if (!LorentzAngle->putLorentzAngle(
id, fPixLorentzAnglePerTesla_)) {
490 <<
"[SiPixelLorentzAnglePCLHarvester::dqmEndJob] filling rest of payload: detid already exists";
494 for (
const auto&
id : newLADets) {
497 h_diffLA->
Fill(deltaMuHoverMuH * 100.
f);
501 for (
const auto& [
id,
value] : LorentzAngle->getLorentzAngles()) {
509 float deltaMuHoverMuH =
523 edm::LogError(
"SiPixelLorentzAngleDB") <<
"caught std::exception " << er.what();
526 edm::LogError(
"SiPixelLorentzAngleDB") <<
"Service is unavailable";
533 h_drift_depth_adc_slice_->
Reset();
534 int hist_drift_ = h_drift_depth_adc_slice_->
getNbinsX();
538 for (
int j = 1;
j <= hist_drift_;
j++) {
558 double mean = h_drift_depth_adc_slice_->
getMean(1);
569 std::shared_ptr<SiPixelLorentzAngle> theLAPayload,
int i_index,
int i_layer,
int i_module) {
577 double half_width =
width_ * 10000 / 2;
579 f1 = std::make_unique<TF1>(
"f1",
"[0] + [1]*x + [2]*x*x + [3]*x*x*x + [4]*x*x*x*x + [5]*x*x*x*x*x", 5., 280.);
580 f1->SetParName(0,
"offset");
581 f1->SetParName(1,
"tan#theta_{LA}");
582 f1->SetParName(2,
"quad term");
583 f1->SetParName(3,
"cubic term");
584 f1->SetParName(4,
"quartic term");
585 f1->SetParName(5,
"quintic term");
587 f1->SetParameter(0, 0);
588 f1->SetParError(0, 0);
589 f1->SetParameter(1, 0.4);
590 f1->SetParError(1, 0);
591 f1->SetParameter(2, 0.0);
592 f1->SetParError(2, 0);
593 f1->SetParameter(3, 0.0);
594 f1->SetParError(3, 0);
595 f1->SetParameter(4, 0.0);
596 f1->SetParError(4, 0);
597 f1->SetParameter(5, 0.0);
598 f1->SetParError(5, 0);
603 res.
p0 =
f1->GetParameter(0);
604 res.
e0 =
f1->GetParError(0);
605 res.
p1 =
f1->GetParameter(1);
606 res.
e1 =
f1->GetParError(1);
607 res.
p2 =
f1->GetParameter(2);
608 res.
e2 =
f1->GetParError(2);
609 res.
p3 =
f1->GetParameter(3);
610 res.
e3 =
f1->GetParError(3);
611 res.
p4 =
f1->GetParameter(4);
612 res.
e4 =
f1->GetParError(4);
613 res.
p5 =
f1->GetParameter(5);
614 res.
e5 =
f1->GetParError(5);
615 res.
chi2 =
f1->GetChisquare();
616 res.
ndf =
f1->GetNDF();
620 double f1_halfwidth = res.
p0 + res.
p1 * half_width + res.
p2 *
pow(half_width, 2) + res.
p3 *
pow(half_width, 3) +
621 res.
p4 *
pow(half_width, 4) + res.
p5 *
pow(half_width, 5);
623 double f1_zerowidth = res.
p0;
626 res.
tan_LA = (f1_halfwidth - f1_zerowidth) / half_width;
628 (
pow(res.
e1, 2) +
pow((half_width * res.
e2), 2) +
pow((half_width * half_width * res.
e3), 2) +
629 pow((half_width * half_width * half_width * res.
e4), 2) +
630 pow((half_width * half_width * half_width * half_width * res.
e5), 2));
642 LogDebug(
"SiPixelLorentzAnglePCLHarvester")
643 <<
" isNew: " << isNew <<
" i_index: " << i_index <<
" shift index: " << shiftIdx;
645 const auto& detIdsToFill =
648 LogDebug(
"SiPixelLorentzAnglePCLHarvester")
649 <<
"index: " << i_index <<
" i_module: " << i_module <<
" i_layer: " << i_layer;
650 for (
const auto&
id : detIdsToFill) {
651 LogDebug(
"SiPixelLorentzAnglePCLHarvester") <<
id <<
",";
654 float LorentzAnglePerTesla_;
658 LorentzAnglePerTesla_ = res.
tan_LA / theMagField;
664 const auto& deltaLA = (LorentzAnglePerTesla_ - currentLA);
667 for (
const auto&
id : detIdsToFill) {
668 if (!theLAPayload->putLorentzAngle(
id, LorentzAnglePerTesla_)) {
669 edm::LogError(
"SiPixelLorentzAnglePCLHarvester") <<
"[SiPixelLorentzAnglePCLHarvester::fitAndStore]: detid ("
670 << i_layer <<
"," << i_module <<
") already exists";
681 for (
const auto&
id : detIdsToFill) {
683 if (!theLAPayload->putLorentzAngle(
id, LorentzAnglePerTesla_)) {
684 edm::LogError(
"SiPixelLorentzAnglePCLHarvester") <<
"[SiPixelLorentzAnglePCLHarvester::fitAndStore]: detid ("
685 << i_layer <<
"," << i_module <<
") already exists";
696 desc.
setComment(
"Harvester module of the SiPixel Lorentz Angle PCL monitoring workflow");
697 desc.
add<std::vector<std::string>>(
"newmodulelist", {})->setComment(
"the list of DetIds for new sensors");
698 desc.
add<
std::string>(
"dqmDir",
"AlCaReco/SiPixelLorentzAngle")->setComment(
"the directory of PCL Worker output");
699 desc.
add<
double>(
"fitChi2Cut", 20.)->
setComment(
"cut on fit chi2/ndof to accept measurement");
700 desc.
add<
int>(
"minHitsCut", 10000)->setComment(
"cut on minimum number of on-track hits to accept measurement");
701 desc.
add<
std::string>(
"record",
"SiPixelLorentzAngleRcd")->setComment(
"target DB record");
std::vector< dqm::reco::MonitorElement * > h2_byLayerLA_
std::vector< int > BPixnewModule_
void setComment(std::string const &value)
const std::map< unsigned int, float > & getLorentzAngles() const
dqm::reco::MonitorElement * h_bySectSetLA_
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
dqm::reco::MonitorElement * h_bySectLA_
Base exception class for the object to relational access.
uint16_t *__restrict__ id
virtual void setCurrentFolder(std::string const &fullpath)
int moduleName() const
module id (index in z)
int nominalValue() const
The nominal field value for this map in kGauss.
void beginRun(const edm::Run &, const edm::EventSetup &) override
std::vector< int > nLadders_
std::vector< std::string > FPixnewmodulename_
#define DEFINE_FWK_MODULE(type)
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > topoEsTokenBR_
void findMean(MonitorElement *h_drift_depth_adc_slice_, int i, int i_ring)
SiPixelLorentzAnglePCLHarvester(const edm::ParameterSet &)
SiPixelLAHarvest::fitResults fitAndStore(std::shared_ptr< SiPixelLorentzAngle > theLA, int i_idx, int i_lay, int i_mod)
constexpr uint32_t rawId() const
get the raw id
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > topoEsTokenER_
const Bounds & bounds() const
unsigned int pxbModule(const DetId &id) const
const std::string dqmDir_
std::vector< int > nModules_
SiPixelLorentzAngleCalibrationHistograms hists
Log< level::Error, false > LogError
MonitorMap h_drift_depth_
static void fillDescriptions(edm::ConfigurationDescriptions &)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
const Plane & surface() const
The nominal surface of the GeomDet.
std::vector< int > FPixnewDetIds_
unsigned int numberOfLayers(int subdet) const
std::vector< unsigned int > BPixnewDetIds_
constexpr std::array< uint8_t, layerIndexSize > layer
MonitorMap h_drift_depth_noadc_
virtual float thickness() const =0
bool getData(T &iHolder) const
~SiPixelLorentzAnglePCLHarvester() override=default
virtual void Reset()
Remove all data from the ME, keept the empty histogram with all its settings.
dqm::reco::MonitorElement * h_bySectChi2_
edm::ESGetToken< SiPixelLorentzAngle, SiPixelLorentzAngleRcd > siPixelLAEsToken_
int bladeName() const
blade id
void setComment(std::string const &value)
Container::value_type value_type
virtual int getNbinsX() const
get # of bins in X-axis
const unsigned getPXBModules(unsigned int lay) const
std::unordered_map< uint32_t, std::vector< uint32_t > > detIdsList
if(conf_.getParameter< bool >("UseStripCablingDB"))
virtual MonitorElement * get(std::string const &fullpath) const
const DetContainer & detsPXB() const
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector's numbering enum) ...
edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > geomEsToken_
char const * what() const noexceptoverride
Hash writeOneIOV(const T &payload, Time_t time, const std::string &recordName)
DetId geographicalId() const
The label of this GeomDet.
dqm::reco::MonitorElement * h_bySectOccupancy_
std::unique_ptr< TrackerTopology > theTrackerTopology
ParameterDescriptionBase * add(U const &iLabel, T const &value)
virtual void setBinLabel(int bin, const std::string &label, int axis=1)
set bin label for x, y or z axis (axis=1, 2, 3 respectively)
virtual double getBinContent(int binx) const
get content of bin (1-D)
Log< level::Warning, true > LogPrint
PXFDetId getDetId()
return DetId
const MagneticField * magField
unsigned int pxbLayer(const DetId &id) const
virtual double getMean(int axis=1) const
get mean value of histogram along x, y or z axis (axis=1, 2, 3 respectively)
const std::string recordName_
virtual void setBinContent(int binx, double content)
set content of bin (1-D)
dqm::reco::MonitorElement * h_bySectMeasLA_
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
virtual double getRMS(int axis=1) const
get RMS of histogram along x, y or z axis (axis=1, 2, 3 respectively)
int layerName() const
layer id
MonitorMap h_drift_depth_adc_
std::vector< int > FPixnewBlade_
MonitorMap h_drift_depth_adc2_
cond::Time_t currentTime() const
float getLorentzAngle(const uint32_t &) const
std::vector< std::string > BPixnewmodulename_
int diskName() const
disk id
dqm::reco::MonitorElement * h_bySectRejectLA_
virtual void setBinError(int binx, double error)
set uncertainty on content of bin (1-D)
dqm::reco::MonitorElement * h_bySectDeltaLA_
std::vector< int > FPixnewDisk_
std::vector< int > BPixnewLayer_
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
const SiPixelLorentzAngle * currentLorentzAngle
const unsigned getPXBLadders(unsigned int lay) const
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magneticFieldToken_
PXBDetId getDetId()
return the DetId
std::vector< dqm::reco::MonitorElement * > h2_byLayerDiff_
std::vector< std::string > newmodulelist_
std::unique_ptr< TF1 > f1
Power< A, B >::type pow(const A &a, const B &b)
void endRun(const edm::Run &, const edm::EventSetup &) override
void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) override