Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14.0.X] Update SiStripLorentzAnglePCLHarvester to avoid writing useless payloads and more control plots #44030

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "CondFormats/SiStripObjects/interface/SiStripLatency.h"
#include "DataFormats/SiStripDetId/interface/SiStripDetId.h"
#include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"

// system includes
#include <string>
Expand All @@ -16,6 +17,19 @@

namespace siStripLACalibration {

/**
* @brief Generates a module location type string based on the detector ID and topology information.
*
* Given a module ID and the corresponding TrackerTopology, this function constructs a module
* location type string in the format "subdet_LlayerType", where subdet is the subdetector name (TIB or TOB),
* layer is the layer number, and Type is 'a' for axial or 's' for stereo.
*
* @param mod The module ID.
* @param tTopo Pointer to the TrackerTopology object providing information about the detector.
* @return A module location type string.
*/

//_____________________________________________________________________
inline std::string moduleLocationType(const uint32_t& mod, const TrackerTopology* tTopo) {
const SiStripDetId detid(mod);
std::string subdet = "";
Expand All @@ -36,6 +50,50 @@ namespace siStripLACalibration {
return d_l_t;
}

/**
* @brief Process a string in the format "subdet_LlayerType" and compute values.
*
* This function takes a string in the format "subdet_LlayerType" and parses it to extract
* information about the layer and type. It then computes and returns a std::pair<int, int> where
* the first element is 1 if type is "a" and 2 if type is "s",
* and the second element is the processed value of layer if subdet is "TIB" or layer + 4 if subdet is "TOB".
*
* @param locType The input string in the format "subdet_LlayerType".
* @return A std::pair<int, int> containing the processed values. If the input format is invalid,
* the pair (-1, -1) is returned.
*
* @example
* std::string d_l_t = "TIB_L3a";
* std::pair<int, int> result = processString(d_l_t);
* // The result will contain processed values based on the input.
*/

//_____________________________________________________________________
inline std::pair<int, int> locationTypeIndex(const std::string& locType) {
// Assuming input format is "subdet_LlayerType"
// Example: "TIB_L3a"

std::string subdet, layerType;
int layer;

// Parse the input string
if (sscanf(locType.c_str(), "%3s_L%d%1[a-zA-Z]", &subdet[0], &layer, &layerType[0]) == 3) {
// Process subdet and layerType to compute the values
LogTrace("locationTypeIndex") << "subdet " << &subdet[0] << ") layer " << layer << " type " << layerType[0]
<< std::endl;

int firstElement = (layerType[0] == 'a') ? 1 : 2;
int secondElement = (std::string(&subdet[0]) == "TIB") ? layer : (layer + 4);

return std::make_pair(firstElement, secondElement);
} else {
// Handle invalid input format
// FIXME use MessageLogger
std::cerr << "Invalid input format: " << locType << std::endl;
return std::make_pair(-1, -1); // Indicates error
}
}

// SiStripLatency::singleReadOutMode() returns
// 1: all in peak, 0: all in deco, -1: mixed state
enum { k_DeconvolutionMode = 0, k_PeakMode = 1 };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ struct SiStripLorentzAngleCalibrationHistograms {

std::map<std::string, dqm::reco::MonitorElement*> hp_;

dqm::reco::MonitorElement* h2_byLayerLA_;
dqm::reco::MonitorElement* h2_byLayerDiff_;

// info
std::map<std::string, int> nlayers_;
std::vector<std::string> modtypes_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <fmt/printf.h>
#include <fstream>
#include <iostream>
#include <numeric>
#include <sstream>
#include <string>
#include <vector>
Expand Down Expand Up @@ -78,7 +79,6 @@ class SiStripLorentzAnglePCLHarvester : public DQMEDHarvester {
static constexpr float teslaToInverseGeV_ = 2.99792458e-3f;
std::pair<double, double> theFitRange_{0., 0.};

SiStripLorentzAngleCalibrationHistograms hists_;
const SiStripLorentzAngle* currentLorentzAngle_;
std::unique_ptr<TrackerTopology> theTrackerTopology_;
};
Expand Down Expand Up @@ -222,6 +222,54 @@ void SiStripLorentzAnglePCLHarvester::dqmEndJob(DQMStore::IBooker& iBooker, DQMS
}
}

// book the summary output histograms
iBooker.setCurrentFolder(fmt::format("{}Harvesting/LorentzAngleMaps", dqmDir_));

// Define a lambda function to extract the second element and add it to the accumulator
auto sumValues = [](int accumulator, const std::pair<std::string, int>& element) {
return accumulator + element.second;
};

// Use std::accumulate to sum the values
int totalLayers = std::accumulate(iHists_.nlayers_.begin(), iHists_.nlayers_.end(), 0, sumValues);

// Lambda expression to set bin labels for a TH2F histogram
auto setHistoLabels = [](TH2F* histogram, const std::map<std::string, int>& nlayers) {
// Set common options
histogram->SetOption("colz1"); // don't fill empty bins
histogram->SetStats(false);
histogram->GetYaxis()->SetLabelSize(0.05);
histogram->GetXaxis()->SetLabelSize(0.05);

// Set bin labels for the X-axis
histogram->GetXaxis()->SetBinLabel(1, "r-#phi");
histogram->GetXaxis()->SetBinLabel(2, "stereo");

// Set bin labels for the Y-axis
int binCounter = 1;
for (const auto& subdet : {"TIB", "TOB"}) {
for (int layer = 1; layer <= nlayers.at(subdet); ++layer) {
std::string label = Form("%s L%d", subdet, layer);
histogram->GetYaxis()->SetBinLabel(binCounter++, label.c_str());
}
}
histogram->GetXaxis()->LabelsOption("h");
};

std::string d_name = "h2_byLayerSiStripLA";
std::string d_text = "SiStrip tan#theta_{LA}/B;module type (r-#phi/stereo);layer number;tan#theta_{LA}/B [1/T]";
iHists_.h2_byLayerLA_ =
iBooker.book2D(d_name.c_str(), d_text.c_str(), 2, -0.5, 1.5, totalLayers, -0.5, totalLayers - 0.5);

setHistoLabels(iHists_.h2_byLayerLA_->getTH2F(), iHists_.nlayers_);

d_name = "h2_byLayerSiStripLADiff";
d_text = "SiStrip #Delta#mu_{H}/#mu_{H};module type (r-#phi/stereo);ladder number;#Delta#mu_{H}/#mu_{H} [%%]";
iHists_.h2_byLayerDiff_ =
iBooker.book2D(d_name.c_str(), d_text.c_str(), 2, -0.5, 1.5, totalLayers, -0.5, totalLayers - 0.5);

setHistoLabels(iHists_.h2_byLayerDiff_->getTH2F(), iHists_.nlayers_);

// prepare the profiles
for (const auto& ME : iHists_.h2_) {
if (!ME.second)
Expand Down Expand Up @@ -291,29 +339,84 @@ void SiStripLorentzAnglePCLHarvester::dqmEndJob(DQMStore::IBooker& iBooker, DQMS
// now prepare the output LA
std::shared_ptr<SiStripLorentzAngle> OutLorentzAngle = std::make_shared<SiStripLorentzAngle>();

bool isPayloadChanged{false};
std::vector<std::pair<int, int>> treatedIndices;
for (const auto& loc : iHists_.moduleLocationType_) {
if (debug_) {
edm::LogInfo(moduleDescription().moduleName()) << "modId: " << loc.first << " " << loc.second;
}

if (!(loc.second).empty()) {
if (!(loc.second).empty() && theMagField_ != 0.f) {
OutLorentzAngle->putLorentzAngle(loc.first, std::abs(LAMap_[loc.second].first / theMagField_));
} else {
OutLorentzAngle->putLorentzAngle(loc.first, iHists_.la_db_[loc.first]);
}
}

edm::Service<cond::service::PoolDBOutputService> mydbservice;
if (mydbservice.isAvailable()) {
try {
mydbservice->writeOneIOV(*OutLorentzAngle, mydbservice->currentTime(), recordName_);
} catch (const cond::Exception& er) {
edm::LogError("SiStripLorentzAngleDB") << er.what();
} catch (const std::exception& er) {
edm::LogError("SiStripLorentzAngleDB") << "caught std::exception " << er.what();
// if the location is not assigned (e.g. TID or TEC) continue
if ((loc.second).empty()) {
continue;
}

const auto& index2D = siStripLACalibration::locationTypeIndex(loc.second);
LogDebug("SiStripLorentzAnglePCLHarvester")
<< loc.first << " : " << loc.second << " index: " << index2D.first << "-" << index2D.second << std::endl;

// check if the location exists, otherwise throw!
if (index2D != std::make_pair(-1, -1)) {
// Check if index2D is in treatedIndices
// Do not fill the control plots more than necessary (i.e. 1 entry per "partition")
auto it = std::find(treatedIndices.begin(), treatedIndices.end(), index2D);
if (it == treatedIndices.end()) {
// control plots
LogTrace("SiStripLorentzAnglePCLHarvester") << "accepted " << loc.first << " : " << loc.second << " bin ("
<< index2D.first << "," << index2D.second << ")";

const auto& outputLA = OutLorentzAngle->getLorentzAngle(loc.first);
const auto& inputLA = currentLorentzAngle_->getLorentzAngle(loc.first);

LogTrace("SiStripLorentzAnglePCLHarvester") << "inputLA: " << inputLA << " outputLA: " << outputLA;

iHists_.h2_byLayerLA_->setBinContent(index2D.first, index2D.second, outputLA);

float deltaMuHoverMuH = (inputLA != 0.f) ? (inputLA - outputLA) / inputLA : 0.f;
iHists_.h2_byLayerDiff_->setBinContent(index2D.first, index2D.second, deltaMuHoverMuH * 100.f);
treatedIndices.emplace_back(index2D);

// Check if the delta is different from zero
// if none of the locations has a non-zero diff
// will not write out the payload.
if (deltaMuHoverMuH != 0.f) {
isPayloadChanged = true;
LogDebug("SiStripLorentzAnglePCLHarvester")
<< "accepted " << loc.first << " : " << loc.second << " bin (" << index2D.first << "," << index2D.second
<< ") " << deltaMuHoverMuH;
}

} // if the index has not been treated already
} else {
throw cms::Exception("SiStripLorentzAnglePCLHarvester")
<< "Trying to fill an inexistent module location from " << loc.second << "!";
} //
} // ends loop on location types

if (isPayloadChanged) {
// fill the DB object record
edm::Service<cond::service::PoolDBOutputService> mydbservice;
if (mydbservice.isAvailable()) {
try {
mydbservice->writeOneIOV(*OutLorentzAngle, mydbservice->currentTime(), recordName_);
} catch (const cond::Exception& er) {
edm::LogError("SiStripLorentzAngleDB") << er.what();
} catch (const std::exception& er) {
edm::LogError("SiStripLorentzAngleDB") << "caught std::exception " << er.what();
}
} else {
edm::LogError("SiStripLorentzAngleDB") << "Service is unavailable!";
}
} else {
edm::LogError("SiStripLorentzAngleDB") << "Service is unavailable";
edm::LogPrint("SiStripLorentzAngleDB")
<< "****** WARNING ******\n* " << __PRETTY_FUNCTION__
<< "\n* There is no new valid measurement to append!\n* Will NOT update the DB!\n*********************";
}
}

Expand Down