Skip to content

Commit

Permalink
add control histograms for SiStripLorentzAnglePCLHarvester
Browse files Browse the repository at this point in the history
  • Loading branch information
mmusich committed Feb 20, 2024
1 parent 2a5873a commit 1b12a17
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 9 deletions.
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 @@ -292,35 +340,83 @@ void SiStripLorentzAnglePCLHarvester::dqmEndJob(DQMStore::IBooker& iBooker, DQMS
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_));
isPayloadChanged = true;
} else {
OutLorentzAngle->putLorentzAngle(loc.first, iHists_.la_db_[loc.first]);
}
}

// 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_);
mydbservice->writeOneIOV(*OutLorentzAngle, mydbservice->currentTime(), recordName_);
} catch (const cond::Exception& er) {
edm::LogError("SiStripLorentzAngleDB") << er.what();
edm::LogError("SiStripLorentzAngleDB") << er.what();
} catch (const std::exception& er) {
edm::LogError("SiStripLorentzAngleDB") << "caught std::exception " << er.what();
edm::LogError("SiStripLorentzAngleDB") << "caught std::exception " << er.what();
}
} else {
edm::LogError("SiStripLorentzAngleDB") << "Service is unavailable";
edm::LogError("SiStripLorentzAngleDB") << "Service is unavailable!";
}
} else {
edm::LogPrint("SiStripLorentzAngleDB") << __PRETTY_FUNCTION__ << " there is no new valid measurement to append! ";
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

0 comments on commit 1b12a17

Please sign in to comment.