16 #include <fmt/format.h> 17 #include <fmt/printf.h> 96 void fill(uint32_t
id,
float inputLA,
float outputLA) {
102 const auto& allInputMaps =
hInputLA->getAllMaps();
104 for (
size_t i = 1;
i < allInputMaps.size();
i++) {
125 mismatchedBField_{
false},
126 mismatchedLatency_{
false},
127 debug_(iConfig.getParameter<
bool>(
"debugMode")),
128 dqmDir_(iConfig.getParameter<
std::string>(
"dqmDir")),
129 fitRange_(iConfig.getParameter<std::vector<double>>(
"fitRange")),
130 recordName_(iConfig.getParameter<
std::string>(
"record")) {
132 if (fitRange_.size() == 2) {
133 theFitRange_.first = fitRange_[0];
134 theFitRange_.second = fitRange_[1];
136 throw cms::Exception(
"SiStripLorentzAnglePCLHarvester") <<
"Too many fit range parameters specified";
142 throw cms::Exception(
"SiStripLorentzAnglePCLHarvester") <<
"PoolDBService required";
179 auto dets =
geom->detsTIB();
180 dets.insert(dets.end(),
geom->detsTID().begin(),
geom->detsTID().end());
181 dets.insert(dets.end(),
geom->detsTOB().begin(),
geom->detsTOB().end());
182 dets.insert(dets.end(),
geom->detsTEC().begin(),
geom->detsTEC().end());
184 for (
auto det : dets) {
185 auto detid = det->geographicalId().rawId();
207 throw cms::Exception(
"SiStripLorentzAnglePCLHarvester") <<
"Trying to harvest runs with different B-field values!";
211 throw cms::Exception(
"SiStripLorentzAnglePCLHarvester") <<
"Trying to harvest runs with diffent APV modes!";
227 std::vector<std::string>
MEtoHarvest = {
"tanthcosphtrk_nstrip",
229 "tanthcosphtrk_var2",
230 "tanthcosphtrk_var3",
237 for (
int l = 1;
l <=
layers.second; ++
l) {
240 if (
l > 2 &&
t ==
"s")
242 std::string locationtype = Form(
"%s_L%d%s", subdet.c_str(),
l,
t.c_str());
244 const char* address = Form(
245 "%s/%s/L%d/%s_%s", folderToHarvest.c_str(), subdet.c_str(),
l, locationtype.c_str(), toHarvest.c_str());
249 iHists_.
h2_[Form(
"%s_%s", locationtype.c_str(), toHarvest.c_str())] = iGetter.
get(address);
250 if (
iHists_.
h2_[Form(
"%s_%s", locationtype.c_str(), toHarvest.c_str())] ==
nullptr) {
252 <<
"could not retrieve: " << Form(
"%s_%s", locationtype.c_str(), toHarvest.c_str());
263 auto sumValues = [](
int accumulator,
const std::pair<std::string, int>& element) {
271 auto setHistoLabels = [](TH2F* histogram,
const std::map<std::string, int>&
nlayers) {
273 histogram->SetOption(
"colz1");
274 histogram->SetStats(
false);
275 histogram->GetYaxis()->SetLabelSize(0.05);
276 histogram->GetXaxis()->SetLabelSize(0.05);
279 histogram->GetXaxis()->SetBinLabel(1,
"r-#phi");
280 histogram->GetXaxis()->SetBinLabel(2,
"stereo");
284 for (
const auto& subdet : {
"TIB",
"TOB"}) {
287 histogram->GetYaxis()->SetBinLabel(binCounter++,
label.c_str());
290 histogram->GetXaxis()->LabelsOption(
"h");
294 std::string d_text =
"SiStrip tan#theta_{LA}/B;module type (r-#phi/stereo);layer number;tan#theta_{LA}/B [1/T]";
296 iBooker.
book2D(d_name.c_str(), d_text.c_str(), 2, -0.5, 1.5, totalLayers, -0.5, totalLayers - 0.5);
300 d_name =
"h2_byLayerSiStripLADiff";
301 d_text =
"SiStrip #Delta#mu_{H}/#mu_{H};module type (r-#phi/stereo);ladder number;#Delta#mu_{H}/#mu_{H} [%%]";
303 iBooker.
book2D(d_name.c_str(), d_text.c_str(), 2, -0.5, 1.5, totalLayers, -0.5, totalLayers - 0.5);
312 ME.second->setOption(
"colz");
313 TProfile*
hp = (TProfile*)
ME.second->getTH2F()->ProfileX();
316 iHists_.
p_[
hp->GetName()]->setAxisTitle(
ME.second->getAxisTitle(2), 2);
325 std::map<std::string, std::pair<double, double>> LAMap_;
330 if ((prof.first).find(
"thetatrk_nstrip") != std::string::npos) {
334 double low = prof.second->getAxisMin(1);
335 double high = prof.second->getAxisMax(1);
344 prof.second->getTProfile()->Fit(fitFunc,
"F");
347 Double_t a_fit = fitFunc->GetParameter(0);
348 Double_t thetaL_fit = fitFunc->GetParameter(1);
349 Double_t b_fit = fitFunc->GetParameter(2);
351 Double_t a_fitError = fitFunc->GetParError(0);
352 Double_t thetaL_fitError = fitFunc->GetParError(1);
353 Double_t b_fitError = fitFunc->GetParError(2);
357 << prof.first <<
" fit result: " 358 <<
" a=" << a_fit <<
" +/ " << a_fitError <<
" theta_L=" << thetaL_fit <<
" +/- " << thetaL_fitError
359 <<
" b=" << b_fit <<
" +/- " << b_fitError;
362 LAMap_[
getStem(prof.first,
false)] = std::make_pair(thetaL_fit, thetaL_fitError);
367 for (
const auto& element : LAMap_) {
369 << element.first <<
" thetaLA = " << element.second.first <<
"+/-" << element.second.second;
374 std::shared_ptr<SiStripLorentzAngle> OutLorentzAngle = std::make_shared<SiStripLorentzAngle>();
376 bool isPayloadChanged{
false};
377 std::vector<std::pair<int, int>> treatedIndices;
386 OutLorentzAngle->putLorentzAngle(loc.first,
iHists_.
la_db_[loc.first]);
390 if ((loc.second).empty()) {
395 LogDebug(
"SiStripLorentzAnglePCLHarvester")
396 << loc.first <<
" : " << loc.second <<
" index: " << index2D.first <<
"-" << index2D.second << std::endl;
399 if (index2D != std::make_pair(-1, -1)) {
402 auto it =
std::find(treatedIndices.begin(), treatedIndices.end(), index2D);
403 if (
it == treatedIndices.end()) {
405 LogTrace(
"SiStripLorentzAnglePCLHarvester") <<
"accepted " << loc.first <<
" : " << loc.second <<
" bin (" 406 << index2D.first <<
"," << index2D.second <<
")";
408 const auto& outputLA = OutLorentzAngle->getLorentzAngle(loc.first);
411 LogTrace(
"SiStripLorentzAnglePCLHarvester") <<
"inputLA: " << inputLA <<
" outputLA: " << outputLA;
415 float deltaMuHoverMuH = (inputLA != 0.f) ? (inputLA - outputLA) / inputLA : 0.f;
417 treatedIndices.emplace_back(index2D);
423 if (deltaMuHoverMuH != 0.
f && outputLA != 0.
f) {
424 isPayloadChanged =
true;
425 LogDebug(
"SiStripLorentzAnglePCLHarvester")
426 <<
"accepted " << loc.first <<
" : " << loc.second <<
" bin (" << index2D.first <<
"," << index2D.second
427 <<
") " << deltaMuHoverMuH;
430 <<
"Discarded " << loc.first <<
" : " << loc.second <<
" bin (" << index2D.first <<
"," << index2D.second
431 <<
") | delta muH/muH = " << deltaMuHoverMuH <<
" [1/T], output muH = " << outputLA <<
" [1/T]";
436 <<
"Trying to fill an inexistent module location from " << loc.second <<
"!";
441 const auto tkDetMapFolderIn = (
fmt::format(
"{}Harvesting/TkDetMaps_LAInput",
dqmDir_));
442 const auto tkDetMapFolderOut = (
fmt::format(
"{}Harvesting/TkDetMaps_LAOutput",
dqmDir_));
444 std::make_unique<TkHistoMap>(
tkDetMap_.get(), iBooker, tkDetMapFolderIn,
"inputLorentzAngle", 0,
false,
true),
445 std::make_unique<TkHistoMap>(
tkDetMap_.get(), iBooker, tkDetMapFolderOut,
"outputLorentzAngle", 0,
false,
true));
449 const auto& outputLA = OutLorentzAngle->getLorentzAngle(loc.first);
457 if (isPayloadChanged) {
466 edm::LogError(
"SiStripLorentzAngleDB") <<
"caught std::exception " << er.what();
469 edm::LogError(
"SiStripLorentzAngleDB") <<
"Service is unavailable!";
473 <<
"****** WARNING ******\n* " << __PRETTY_FUNCTION__
474 <<
"\n* There is no new valid measurement to append!\n* Will NOT update the DB!\n*********************";
480 std::vector<std::string> tokens;
487 while (std::getline(iss,
token,
'_')) {
489 tokens.push_back(
token);
493 output = tokens[0] +
"/" + tokens[1];
496 output = tokens[0] +
"_" + tokens[1];
504 desc.setComment(
"Harvester module of the SiStrip Lorentz Angle PCL monitoring workflow");
505 desc.add<
bool>(
"debugMode",
false)->setComment(
"determines if it's in debug mode");
506 desc.add<
std::string>(
"dqmDir",
"AlCaReco/SiStripLorentzAngle")->setComment(
"the directory of PCL Worker output");
507 desc.add<std::vector<double>>(
"fitRange", {0., 0.})->setComment(
"range of depths to perform the LA fit");
508 desc.add<
std::string>(
"record",
"SiStripLorentzAngleRcd")->setComment(
"target DB record");
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
std::vector< std::string > modtypes_
Base exception class for the object to relational access.
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > geomEsToken_
const std::vector< double > fitRange_
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
void beginRun(const edm::Run &, const edm::EventSetup &) override
virtual void setCurrentFolder(std::string const &fullpath)
ModuleDescription const & moduleDescription() const
const std::string recordName_
double fitFunction(double *x, double *par)
std::map< std::string, int > nlayers_
dqm::reco::MonitorElement * h2_byLayerLA_
Log< level::Error, false > LogError
std::unique_ptr< TkHistoMap > hOutputLA
std::pair< int, int > locationTypeIndex(const std::string &locType)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
static constexpr float teslaToInverseGeV_
static std::string const input
float inverseBzAtOriginInGeV() const
The inverse of field z component for this map in GeV.
std::map< std::string, dqm::reco::MonitorElement * > p_
SiStripLorentzAngleCalibrationHistograms iHists_
std::map< std::string, dqm::reco::MonitorElement * > h2_
std::map< uint32_t, std::string > moduleLocationType_
cond::Time_t currentTime() const
MonitorElement * bookProfile(TString const &name, TString const &title, int nchX, double lowX, double highX, int, double lowY, double highY, char const *option="s", FUNC onbooking=NOOP())
const std::string fieldAsString(const float &inputField)
Abs< T >::type abs(const T &t)
Hash writeOneIOV(const T &payload, Time_t time, const std::string &recordName)
static void fillDescriptions(edm::ConfigurationDescriptions &)
#define DEFINE_FWK_MODULE(type)
std::unique_ptr< TrackerTopology > theTrackerTopology_
const std::string apvModeAsString(const SiStripLatency *latency)
std::unique_ptr< TkDetMap > tkDetMap_
Log< level::Warning, true > LogPrint
Log< level::Info, false > LogInfo
const edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > topoEsTokenBR_
float getLorentzAngle(const uint32_t &) const
void fill(uint32_t id, float inputLA, float outputLA)
std::string getStem(const std::string &histoName, bool isFolder)
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magneticFieldToken_
virtual void setBinContent(int binx, double content)
set content of bin (1-D)
std::map< uint32_t, float > la_db_
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
std::pair< double, double > theFitRange_
void dqmEndJob(DQMStore::IBooker &, DQMStore::IGetter &) override
dqm::reco::MonitorElement * h2_byLayerDiff_
std::unique_ptr< TkHistoMap > hInputLA
const SiStripLorentzAngle * currentLorentzAngle_
virtual MonitorElement * get(std::string const &fullpath) const
SiStripLorentzAnglePCLHarvester(const edm::ParameterSet &)
void endRun(const edm::Run &, const edm::EventSetup &) override
~SiStripLorentzAnglePCLHarvester() override=default
Log< level::Warning, false > LogWarning
char const * what() const noexcept override
const std::string dqmDir_
LATkMap(std::unique_ptr< TkHistoMap > &&input, std::unique_ptr< TkHistoMap > &&output)
const edm::ESGetToken< TkDetMap, TrackerTopologyRcd > tkDetMapTokenER_
std::string moduleLocationType(const uint32_t &mod, const TrackerTopology *tTopo)
Generates a module location type string based on the detector ID and topology information.
const edm::ESGetToken< SiStripLorentzAngle, SiStripLorentzAngleDepRcd > siStripLAEsToken_
const edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > topoEsTokenER_
const edm::ESGetToken< SiStripLatency, SiStripLatencyRcd > latencyToken_