19 #include <fmt/format.h>
20 #include <fmt/printf.h>
45 namespace SiPixelLAHarvest {
102 std::unique_ptr<TF1>
f1;
116 newmodulelist_(iConfig.getParameter<std::
vector<std::
string>>(
"newmodulelist")),
117 dqmDir_(iConfig.getParameter<std::
string>(
"dqmDir")),
118 fitChi2Cut_(iConfig.getParameter<double>(
"fitChi2Cut")),
119 minHitsCut_(iConfig.getParameter<int>(
"minHitsCut")),
120 recordName_(iConfig.getParameter<std::
string>(
"record")) {
124 throw cms::Exception(
"SiPixelLorentzAnglePCLHarvester") <<
"PoolDBService required";
149 if (modulename.find(
"BPix_") != std::string::npos) {
151 const auto& detId = bn.
getDetId(tTopo);
156 }
else if (modulename.find(
"FPix_") != std::string::npos) {
158 const auto& detId = en.
getDetId(tTopo);
169 LogDebug(
"SiPixelLorentzAnglePCLHarvester") <<
id;
172 LogDebug(
"SiPixelLorentzAnglePCLHarvester") <<
"Stored a total of " << count <<
" new detIds.";
178 std::vector<uint32_t> treatedIndices;
180 for (
auto det : geom->
detsPXB()) {
193 if (
std::find(treatedIndices.begin(), treatedIndices.end(), i_index) != treatedIndices.end()) {
196 hists.
detIdsList.insert(std::pair<uint32_t, std::vector<uint32_t>>(i_index, {rawId}));
197 treatedIndices.push_back(i_index);
202 for (
const auto&
i : treatedIndices) {
204 LogDebug(
"SiPixelLorentzAnglePCLHarvester") <<
id;
208 LogDebug(
"SiPixelLorentzAnglePCLHarvester") <<
"Stored a total of " << count <<
" detIds.";
218 for (
int i_layer = 1; i_layer <=
hists.
nlay; i_layer++) {
219 const auto& prefix_ = fmt::sprintf(
"%s/BPix/BPixLayer%i",
dqmDir_, i_layer);
220 for (
int i_module = 1; i_module <=
hists.
nModules_[i_layer - 1]; i_module++) {
221 int i_index = i_module + (i_layer - 1) *
hists.
nModules_[i_layer - 1];
224 iGetter.
get(
fmt::format(
"{}/h_drift_depth_layer{}_module{}", prefix_, i_layer, i_module));
228 <<
"Failed to retrieve electron drift over depth for layer " << i_layer <<
", module " << i_module <<
".";
233 iGetter.
get(
fmt::format(
"{}/h_drift_depth_adc_layer{}_module{}", prefix_, i_layer, i_module));
236 iGetter.
get(
fmt::format(
"{}/h_drift_depth_adc2_layer{}_module{}", prefix_, i_layer, i_module));
239 iGetter.
get(
fmt::format(
"{}/h_drift_depth_noadc_layer{}_module{}", prefix_, i_layer, i_module));
278 edm::LogError(
"SiPixelLorentzAnglePCLHarvester") <<
"Failed to retrieve the hit on track occupancy.";
301 iBooker.
book1D(
"h_drift_depth_adc_slice",
"slice of adc histogram", hist_drift_, min_drift_, max_drift_);
305 "h_diffLA",
"difference in #mu_{H}; #Delta #mu_{H}/#mu_{H} (old-new)/old [%];n. modules", 100, -3., 3.);
309 const double lo = -0.5;
310 const double hi = maxSect + 0.5;
314 std::string repText =
"%s tan#theta_{LA}/B by sector;pixel sector;%s tan(#theta_{LA})/B [1/T]";
316 iBooker.
book1D(
"h_LAbySector_Measured", fmt::sprintf(repText,
"measured",
"measured"), maxSect, lo, hi);
318 iBooker.
book1D(
"h_LAbySector_Accepted", fmt::sprintf(repText,
"accepted",
"accepted"), maxSect, lo, hi);
320 iBooker.
book1D(
"h_LAbySector_Rejected", fmt::sprintf(repText,
"rejected",
"rejected"), maxSect, lo, hi);
321 hists.
h_bySectLA_ = iBooker.
book1D(
"h_LAbySector", fmt::sprintf(repText,
"payload",
"payload"), maxSect, lo, hi);
323 iBooker.
book1D(
"h_deltaLAbySector", fmt::sprintf(repText,
"#Delta",
"#Delta"), maxSect, lo, hi);
325 iBooker.
book1D(
"h_bySectorChi2",
"Fit #chi^{2}/ndf by sector;pixel sector; fit #chi^{2}/ndf", maxSect, lo, hi);
328 for (
int bin = 1;
bin < maxSect;
bin++) {
339 edm::LogPrint(
"LorentzAngle") <<
"module" <<
"\t" <<
"layer" <<
"\t"
340 <<
"offset" <<
"\t" <<
"e0" <<
"\t"
341 <<
"slope" <<
"\t" <<
"e1" <<
"\t"
342 <<
"rel.err" <<
"\t" <<
"pull" <<
"\t"
343 <<
"p2" <<
"\t" <<
"e2" <<
"\t"
344 <<
"p3" <<
"\t" <<
"e3" <<
"\t"
345 <<
"p4" <<
"\t" <<
"e4" <<
"\t"
346 <<
"p5" <<
"\t" <<
"e5" <<
"\t"
347 <<
"chi2" <<
"\t" <<
"prob" <<
"\t"
348 <<
"newDetId" <<
"\t" <<
"tan(LA)" <<
"\t"
353 std::shared_ptr<SiPixelLorentzAngle> LorentzAngle = std::make_shared<SiPixelLorentzAngle>();
356 double p1_simul_newmodule = 0.294044;
358 for (
int i_layer = 1; i_layer <=
hists.
nlay; i_layer++) {
359 for (
int i_module = 1; i_module <=
hists.
nModules_[i_layer - 1]; i_module++) {
361 p1_simul[i_layer - 1][i_module - 1] = 0.436848;
362 else if (i_layer == 2)
363 p1_simul[i_layer - 1][i_module - 1] = 0.25802;
364 else if (i_layer == 3 && i_module <= 4)
365 p1_simul[i_layer - 1][i_module - 1] = 0.29374;
366 else if (i_layer == 3 && i_module >= 5)
367 p1_simul[i_layer - 1][i_module - 1] = 0.31084;
368 else if (i_layer == 4 && i_module <= 4)
369 p1_simul[i_layer - 1][i_module - 1] = 0.29944;
371 p1_simul[i_layer - 1][i_module - 1] = 0.31426;
376 p1_simul[
hists.
nlay][i_module - 1] = p1_simul_newmodule;
385 for (
int i = 1;
i <= hist_depth_;
i++) {
386 findMean(h_drift_depth_adc_slice_,
i, new_index);
394 << std::setprecision(3) <<
"\t" << res.e1 <<
"\t" << res.e1 / res.p1 * 100.
395 <<
"\t" << (res.p1 - p1_simul[
hists.
nlay][0]) / res.e1 <<
"\t" << res.p2
396 <<
"\t" << res.e2 <<
"\t" << res.p3 <<
"\t" << res.e3 <<
"\t" << res.p4 <<
"\t"
397 << res.e4 <<
"\t" << res.p5 <<
"\t" << res.e5 <<
"\t" << res.chi2 <<
"\t"
403 for (
int i_layer = 1; i_layer <=
hists.
nlay; i_layer++) {
404 for (
int i_module = 1; i_module <=
hists.
nModules_[i_layer - 1]; i_module++) {
405 int i_index = i_module + (i_layer - 1) *
hists.
nModules_[i_layer - 1];
409 for (
int i = 1;
i <= hist_depth_;
i++) {
410 findMean(h_drift_depth_adc_slice_,
i, i_index);
414 const auto& res =
fitAndStore(LorentzAngle, i_index, i_layer, i_module);
417 << std::setprecision(4) << i_module <<
"\t" << i_layer <<
"\t" << res.p0 <<
"\t" << res.e0 <<
"\t" << res.p1
418 << std::setprecision(3) <<
"\t" << res.e1 <<
"\t" << res.e1 / res.p1 * 100. <<
"\t"
419 << (res.p1 - p1_simul[i_layer - 1][i_module - 1]) / res.e1 <<
"\t" << res.p2 <<
"\t" << res.e2 <<
"\t"
420 << res.p3 <<
"\t" << res.e3 <<
"\t" << res.p4 <<
"\t" << res.e4 <<
"\t" << res.p5 <<
"\t" << res.e5 <<
"\t"
421 << res.chi2 <<
"\t" << res.prob <<
"\t"
423 <<
"\t" << res.tan_LA <<
"\t" << res.error_LA;
429 const auto& newLAMap = LorentzAngle->getLorentzAngles();
430 std::vector<unsigned int> currentLADets;
431 std::vector<unsigned int> newLADets;
435 std::back_inserter(currentLADets),
440 std::back_inserter(newLADets),
443 std::vector<unsigned int> notCommon;
444 std::set_symmetric_difference(
445 currentLADets.begin(), currentLADets.end(), newLADets.begin(), newLADets.end(), std::back_inserter(notCommon));
447 for (
const auto&
id : notCommon) {
449 if (!LorentzAngle->putLorentzAngle(
id, fPixLorentzAnglePerTesla_)) {
451 <<
"[SiPixelLorentzAnglePCLHarvester::dqmEndRun] filling rest of payload: detid already exists";
455 for (
const auto&
id : newLADets) {
458 h_diffLA->
Fill(deltaMuHoverMuH);
469 edm::LogError(
"SiPixelLorentzAngleDB") <<
"caught std::exception " << er.what();
472 edm::LogError(
"SiPixelLorentzAngleDB") <<
"Service is unavailable";
479 h_drift_depth_adc_slice_->
Reset();
480 int hist_drift_ = h_drift_depth_adc_slice_->
getNbinsX();
484 for (
int j = 1;
j <= hist_drift_;
j++) {
504 double mean = h_drift_depth_adc_slice_->
getMean(1);
515 std::shared_ptr<SiPixelLorentzAngle> theLAPayload,
int i_index,
int i_layer,
int i_module) {
523 double half_width =
width_ * 10000 / 2;
525 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.);
526 f1->SetParName(0,
"offset");
527 f1->SetParName(1,
"tan#theta_{LA}");
528 f1->SetParName(2,
"quad term");
529 f1->SetParName(3,
"cubic term");
530 f1->SetParName(4,
"quartic term");
531 f1->SetParName(5,
"quintic term");
533 f1->SetParameter(0, 0);
534 f1->SetParError(0, 0);
535 f1->SetParameter(1, 0.4);
536 f1->SetParError(1, 0);
537 f1->SetParameter(2, 0.0);
538 f1->SetParError(2, 0);
539 f1->SetParameter(3, 0.0);
540 f1->SetParError(3, 0);
541 f1->SetParameter(4, 0.0);
542 f1->SetParError(4, 0);
543 f1->SetParameter(5, 0.0);
544 f1->SetParError(5, 0);
549 res.
p0 =
f1->GetParameter(0);
550 res.
e0 =
f1->GetParError(0);
551 res.
p1 =
f1->GetParameter(1);
552 res.
e1 =
f1->GetParError(1);
553 res.
p2 =
f1->GetParameter(2);
554 res.
e2 =
f1->GetParError(2);
555 res.
p3 =
f1->GetParameter(3);
556 res.
e3 =
f1->GetParError(3);
557 res.
p4 =
f1->GetParameter(4);
558 res.
e4 =
f1->GetParError(4);
559 res.
p5 =
f1->GetParameter(5);
560 res.
e5 =
f1->GetParError(5);
561 res.
chi2 =
f1->GetChisquare();
562 res.
ndf =
f1->GetNDF();
566 double f1_halfwidth = res.
p0 + res.
p1 * half_width + res.
p2 *
pow(half_width, 2) + res.
p3 *
pow(half_width, 3) +
567 res.
p4 *
pow(half_width, 4) + res.
p5 *
pow(half_width, 5);
569 double f1_zerowidth = res.
p0;
572 res.
tan_LA = (f1_halfwidth - f1_zerowidth) / half_width;
574 (
pow(res.
e1, 2) +
pow((half_width * res.
e2), 2) +
pow((half_width * half_width * res.
e3), 2) +
575 pow((half_width * half_width * half_width * res.
e4), 2) +
576 pow((half_width * half_width * half_width * half_width * res.
e5), 2));
588 LogDebug(
"SiPixelLorentzAnglePCLHarvester")
589 <<
" isNew: " << isNew <<
" i_index: " << i_index <<
" shift index: " << shiftIdx;
591 const auto& detIdsToFill =
594 LogDebug(
"SiPixelLorentzAnglePCLHarvester")
595 <<
"index: " << i_index <<
" i_module: " << i_module <<
" i_layer: " << i_layer;
596 for (
const auto&
id : detIdsToFill) {
597 LogDebug(
"SiPixelLorentzAnglePCLHarvester") <<
id <<
",";
600 float LorentzAnglePerTesla_;
604 LorentzAnglePerTesla_ = res.
tan_LA / theMagField;
610 const auto& deltaLA = (LorentzAnglePerTesla_ - currentLA);
613 for (
const auto&
id : detIdsToFill) {
614 if (!theLAPayload->putLorentzAngle(
id, LorentzAnglePerTesla_)) {
615 edm::LogError(
"SiPixelLorentzAnglePCLHarvester") <<
"[SiPixelLorentzAnglePCLHarvester::fitAndStore]: detid ("
616 << i_layer <<
"," << i_module <<
") already exists";
627 for (
const auto&
id : detIdsToFill) {
629 if (!theLAPayload->putLorentzAngle(
id, LorentzAnglePerTesla_)) {
630 edm::LogError(
"SiPixelLorentzAnglePCLHarvester") <<
"[SiPixelLorentzAnglePCLHarvester::fitAndStore]: detid ("
631 << i_layer <<
"," << i_module <<
") already exists";
642 desc.
setComment(
"Harvester module of the SiPixel Lorentz Angle PCL monitoring workflow");
643 desc.
add<std::vector<std::string>>(
"newmodulelist", {})->setComment(
"the list of DetIds for new sensors");
644 desc.
add<
std::string>(
"dqmDir",
"AlCaReco/SiPixelLorentzAngle")->setComment(
"the directory of PCL Worker output");
645 desc.
add<
double>(
"fitChi2Cut", 20.)->
setComment(
"cut on fit chi2/ndof to accept measurement");
646 desc.
add<
int>(
"minHitsCut", 10000)->setComment(
"cut on minimum number of on-track hits to accept measurement");
647 desc.
add<
std::string>(
"record",
"SiPixelLorentzAngleRcd")->setComment(
"target DB record");
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< std::string > FPixnewmodulename_
#define DEFINE_FWK_MODULE(type)
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
const Bounds & bounds() const
unsigned int pxbModule(const DetId &id) const
const std::string dqmDir_
std::vector< int > nModules_
SiPixelLorentzAngleCalibrationHistograms hists
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > topoEsToken_
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
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_
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_
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
edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magneticFieldToken_
PXBDetId getDetId()
return the DetId
std::vector< std::string > newmodulelist_
std::unique_ptr< TF1 > f1
Power< A, B >::type pow(const A &a, const B &b)
void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) override