Skip to content

Commit

Permalink
deal with b-field and APV mode in SiStripLorentzAnglePCL{Monitor/Harv…
Browse files Browse the repository at this point in the history
…ester}
  • Loading branch information
mmusich committed Aug 15, 2023
1 parent b531457 commit ca40f6c
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
#ifndef CalibTracker_SiStripLorentzAngle_SiStripLorentzAngleCalibrationHelper_h
#define CalibTracker_SiStripLorentzAngle_SiStripLorentzAngleCalibrationHelper_h

#include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
// user includes
#include "CondFormats/SiStripObjects/interface/SiStripLatency.h"
#include "DataFormats/SiStripDetId/interface/SiStripDetId.h"
#include "DataFormats/TrackerCommon/interface/TrackerTopology.h"

// system includes
#include <string>

// for ROOT
#include "TString.h"
#include "TFitResult.h"
#include "TF1.h"

namespace siStripLACalibration {

Expand All @@ -31,5 +38,47 @@ namespace siStripLACalibration {
return d_l_t;
}

// SiStripLatency::singleReadOutMode() returns
// 1: all in peak, 0: all in deco, -1: mixed state
enum { k_DeconvolutionMode = 0, k_PeakMode = 1 };

//_____________________________________________________________________
inline const std::string fieldAsString(const float& inputField) {
std::string theMagFieldStr = std::to_string(inputField);
size_t dotPosition = theMagFieldStr.find('.');
if (dotPosition != std::string::npos) {
theMagFieldStr = theMagFieldStr.substr(0, dotPosition + 2); // +2 to include one decimal place
}
return theMagFieldStr;
}

//_____________________________________________________________________
inline const std::string apvModeAsString(const SiStripLatency* latency) {
if (latency) {
switch (latency->singleReadOutMode()) {
case k_PeakMode:
return "PEAK"; // peak mode
case k_DeconvolutionMode:
return "DECO"; // deco mode
default:
return "UNDEF"; // undefined
}
} else {
return "UNDEF";
}
}

//_____________________________________________________________________
inline double fitFunction(double* x, double* par) {
double a = par[0];
double thetaL = par[1];
double b = par[2];

double tanThetaL = std::tan(thetaL);
double value = a * std::abs(std::tan(x[0]) - tanThetaL) + b;

//TF1::RejectPoint(); // Reject points outside the fit range
return value;
}
} // namespace siStripLACalibration
#endif
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
#ifndef CalibTracker_SiStripLorentzAngle_SiStripLorentzAngleCalibrationStruct_h
#define CalibTracker_SiStripLorentzAngle_SiStripLorentzAngleCalibrationStruct_h

#include "DQMServices/Core/interface/DQMStore.h"
// system includes
#include <map>
#include <vector>

// user includes
#include "DQMServices/Core/interface/DQMStore.h"

struct SiStripLorentzAngleCalibrationHistograms {
public:
SiStripLorentzAngleCalibrationHistograms() = default;

// B field
std::string bfield_;

// APV mode
std::string apvmode_;

std::map<uint32_t, int> orientation_;
std::map<uint32_t, float> la_db_;
std::map<uint32_t, std::string> moduleLocationType_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,6 @@
#include "MagneticField/Engine/interface/MagneticField.h"
#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"

// for ROOT fits
#include "TFitResult.h"
#include "TF1.h"

namespace siStripLACalibration {
double fitFunction(double* x, double* par) {
double a = par[0];
double thetaL = par[1];
double b = par[2];

double tanThetaL = std::tan(thetaL);
double value = a * std::abs(std::tan(x[0]) - tanThetaL) + b;

//TF1::RejectPoint(); // Reject points outside the fit range
return value;
}
} // namespace siStripLACalibration

//------------------------------------------------------------------------------
class SiStripLorentzAnglePCLHarvester : public DQMEDHarvester {
public:
Expand All @@ -77,11 +59,16 @@ class SiStripLorentzAnglePCLHarvester : public DQMEDHarvester {
// es tokens
const edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> geomEsToken_;
const edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> topoEsTokenBR_, topoEsTokenER_;
const edm::ESGetToken<SiStripLatency, SiStripLatencyRcd> latencyToken_;
const edm::ESGetToken<SiStripLorentzAngle, SiStripLorentzAngleDepRcd> siStripLAEsToken_;
const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> magneticFieldToken_;

// member data
bool debug_;

bool mismatchedBField_;
bool mismatchedLatency_;

const bool debug_;
SiStripLorentzAngleCalibrationHistograms iHists_;

const std::string dqmDir_;
Expand All @@ -102,8 +89,11 @@ SiStripLorentzAnglePCLHarvester::SiStripLorentzAnglePCLHarvester(const edm::Para
: geomEsToken_(esConsumes<edm::Transition::BeginRun>()),
topoEsTokenBR_(esConsumes<edm::Transition::BeginRun>()),
topoEsTokenER_(esConsumes<edm::Transition::EndRun>()),
latencyToken_(esConsumes<edm::Transition::BeginRun>()),
siStripLAEsToken_(esConsumes<edm::Transition::BeginRun>()),
magneticFieldToken_(esConsumes<edm::Transition::BeginRun>()),
mismatchedBField_{false},
mismatchedLatency_{false},
debug_(iConfig.getParameter<bool>("debugMode")),
dqmDir_(iConfig.getParameter<std::string>("dqmDir")),
fitRange_(iConfig.getParameter<std::vector<double>>("fitRange")),
Expand Down Expand Up @@ -139,6 +129,23 @@ void SiStripLorentzAnglePCLHarvester::beginRun(const edm::Run& iRun, const edm::

theMagField_ = 1.f / (magField->inverseBzAtOriginInGeV() * teslaToInverseGeV_);

if (iHists_.bfield_.empty()) {
iHists_.bfield_ = siStripLACalibration::fieldAsString(theMagField_);
} else {
if (iHists_.bfield_ != siStripLACalibration::fieldAsString(theMagField_)) {
mismatchedBField_ = true;
}
}

const SiStripLatency* apvlat = &iSetup.getData(latencyToken_);
if (iHists_.apvmode_.empty()) {
iHists_.apvmode_ = siStripLACalibration::apvModeAsString(apvlat);
} else {
if (iHists_.apvmode_ != siStripLACalibration::apvModeAsString(apvlat)) {
mismatchedLatency_ = true;
}
}

auto dets = geom->detsTIB();
dets.insert(dets.end(), geom->detsTID().begin(), geom->detsTID().end());
dets.insert(dets.end(), geom->detsTOB().begin(), geom->detsTOB().end());
Expand All @@ -163,9 +170,20 @@ void SiStripLorentzAnglePCLHarvester::endRun(edm::Run const& run, edm::EventSetu

//------------------------------------------------------------------------------
void SiStripLorentzAnglePCLHarvester::dqmEndJob(DQMStore::IBooker& iBooker, DQMStore::IGetter& iGetter) {
if (mismatchedBField_) {
throw cms::Exception("SiStripLorentzAnglePCLHarvester") << "Trying to harvest runs with different B-field values!";
}

if (mismatchedLatency_) {
throw cms::Exception("SiStripLorentzAnglePCLHarvester") << "Trying to harvest runs with diffent APV modes!";
}

// go in the right directory
iGetter.cd();
iGetter.setCurrentFolder(dqmDir_);
std::string bvalue = (iHists_.bfield_ == "3.8") ? "B-ON" : "B-OFF";
std::string folderToHarvest = fmt::format("{}/{}_{}", dqmDir_, bvalue, iHists_.apvmode_);
edm::LogPrint(moduleDescription().moduleName()) << "Harvesting in " << folderToHarvest;
iGetter.setCurrentFolder(folderToHarvest);

// fill in the module types
iHists_.nlayers_["TIB"] = 4;
Expand All @@ -190,8 +208,8 @@ void SiStripLorentzAnglePCLHarvester::dqmEndJob(DQMStore::IBooker& iBooker, DQMS
continue;
std::string locationtype = Form("%s_L%d%s", subdet.c_str(), l, t.c_str());
for (const auto& toHarvest : MEtoHarvest) {
const char* address =
Form("%s/%s/L%d/%s_%s", dqmDir_.c_str(), subdet.c_str(), l, locationtype.c_str(), toHarvest.c_str());
const char* address = Form(
"%s/%s/L%d/%s_%s", folderToHarvest.c_str(), subdet.c_str(), l, locationtype.c_str(), toHarvest.c_str());

LogDebug(moduleDescription().moduleName()) << "harvesting at: " << address << std::endl;

Expand All @@ -208,7 +226,7 @@ void SiStripLorentzAnglePCLHarvester::dqmEndJob(DQMStore::IBooker& iBooker, DQMS
// prepare the profiles
for (const auto& ME : iHists_.h2_) {
TProfile* hp = (TProfile*)ME.second->getTH2F()->ProfileX();
iBooker.setCurrentFolder(dqmDir_ + "/" + getStem(ME.first, /* isFolder = */ true));
iBooker.setCurrentFolder(folderToHarvest + "/" + getStem(ME.first, /* isFolder = */ true));
iHists_.p_[hp->GetName()] = iBooker.bookProfile(hp->GetName(), hp);
delete hp;
}
Expand All @@ -229,7 +247,7 @@ void SiStripLorentzAnglePCLHarvester::dqmEndJob(DQMStore::IBooker& iBooker, DQMS
high = theFitRange_.second;
}

TF1* fitFunc = new TF1("fitFunc", siStripLACalibration ::fitFunction, low, high, 3);
TF1* fitFunc = new TF1("fitFunc", siStripLACalibration::fitFunction, low, high, 3);

// Fit the function to the data
prof.second->getTProfile()->Fit(fitFunc, "F"); // "F" option performs a least-squares fit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@

// system includes
#include <string>
#include <fmt/format.h>
#include <fmt/printf.h>

// user include files
#include "CalibFormats/SiStripObjects/interface/SiStripHashedDetId.h"
#include "CalibTracker/Records/interface/SiStripDependentRecords.h"
#include "CalibTracker/SiStripCommon/interface/ShallowTools.h"
#include "CalibTracker/SiStripLorentzAngle/interface/SiStripLorentzAngleCalibrationHelpers.h"
#include "CalibTracker/SiStripLorentzAngle/interface/SiStripLorentzAngleCalibrationStruct.h"
#include "CondFormats/SiStripObjects/interface/SiStripLorentzAngle.h"
#include "CondFormats/SiStripObjects/interface/SiStripLatency.h"
#include "DQMServices/Core/interface/DQMEDAnalyzer.h"
#include "DQMServices/Core/interface/MonitorElement.h"
#include "DataFormats/SiStripCluster/interface/SiStripCluster.h"
Expand Down Expand Up @@ -73,12 +77,18 @@ class SiStripLorentzAnglePCLMonitor : public DQMEDAnalyzer {
SiStripLorentzAngleCalibrationHistograms iHists_;
SiStripHashedDetId m_hash;

// for magnetic field conversion
static constexpr float teslaToInverseGeV_ = 2.99792458e-3f;

bool mismatchedBField_;
bool mismatchedLatency_;
const std::string folder_;
const bool saveHistosMods_;
const edm::EDGetTokenT<edm::View<reco::Track>> m_tracks_token;
const edm::EDGetTokenT<TrajTrackAssociationCollection> m_association_token;
const edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> m_tkGeomToken;

const edm::ESGetToken<SiStripLatency, SiStripLatencyRcd> m_latencyTokenBR;
const edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> m_topoEsTokenBR;
const edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> m_tkGeomTokenBR;
const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> m_magFieldTokenBR;
Expand All @@ -101,11 +111,14 @@ class SiStripLorentzAnglePCLMonitor : public DQMEDAnalyzer {

SiStripLorentzAnglePCLMonitor::SiStripLorentzAnglePCLMonitor(const edm::ParameterSet& iConfig)
: m_clusterInfo(consumesCollector()),
mismatchedBField_{false},
mismatchedLatency_{false},
folder_(iConfig.getParameter<std::string>("folder")),
saveHistosMods_(iConfig.getParameter<bool>("saveHistoMods")),
m_tracks_token(consumes<edm::View<reco::Track>>(iConfig.getParameter<edm::InputTag>("Tracks"))),
m_association_token(consumes<TrajTrackAssociationCollection>(iConfig.getParameter<edm::InputTag>("Tracks"))),
m_tkGeomToken{esConsumes<>()},
m_latencyTokenBR{esConsumes<edm::Transition::BeginRun>()},
m_topoEsTokenBR{esConsumes<edm::Transition::BeginRun>()},
m_tkGeomTokenBR{esConsumes<edm::Transition::BeginRun>()},
m_magFieldTokenBR{esConsumes<edm::Transition::BeginRun>()},
Expand All @@ -120,6 +133,26 @@ void SiStripLorentzAnglePCLMonitor::dqmBeginRun(edm::Run const& run, edm::EventS
const auto& lorentzAngle = iSetup.getData(m_lorentzAngleTokenBR);
const TrackerTopology* tTopo = &iSetup.getData(m_topoEsTokenBR);

// fast cachecd access
const auto& theMagField = 1.f / (magField.inverseBzAtOriginInGeV() * teslaToInverseGeV_);

if (iHists_.bfield_.empty()) {
iHists_.bfield_ = siStripLACalibration::fieldAsString(theMagField);
} else {
if (iHists_.bfield_ != siStripLACalibration::fieldAsString(theMagField)) {
mismatchedBField_ = true;
}
}

const SiStripLatency* apvlat = &iSetup.getData(m_latencyTokenBR);
if (iHists_.apvmode_.empty()) {
iHists_.apvmode_ = siStripLACalibration::apvModeAsString(apvlat);
} else {
if (iHists_.apvmode_ != siStripLACalibration::apvModeAsString(apvlat)) {
mismatchedLatency_ = true;
}
}

std::vector<uint32_t> c_rawid;
std::vector<float> c_globalZofunitlocalY, c_localB, c_BdotY, c_driftx, c_drifty, c_driftz, c_lorentzAngle;

Expand Down Expand Up @@ -190,6 +223,13 @@ std::string SiStripLorentzAnglePCLMonitor::moduleLocationType(const uint32_t& mo
void SiStripLorentzAnglePCLMonitor::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
using namespace edm;

// return immediately if the field is not consistent!
if (mismatchedBField_)
return;

if (mismatchedLatency_)
return;

edm::Handle<edm::View<reco::Track>> tracks;
iEvent.getByToken(m_tracks_token, tracks);
edm::Handle<TrajTrackAssociationCollection> trajTrackAssociations;
Expand Down Expand Up @@ -318,8 +358,11 @@ void SiStripLorentzAnglePCLMonitor::analyze(const edm::Event& iEvent, const edm:
void SiStripLorentzAnglePCLMonitor::bookHistograms(DQMStore::IBooker& ibook,
edm::Run const& run,
edm::EventSetup const& iSetup) {
ibook.setCurrentFolder(folder_);
LogDebug(moduleDescription().moduleName()) << "booking in " << folder_ << std::endl;
std::string bvalue = (iHists_.bfield_ == "3.8") ? "B-ON" : "B-OFF";
std::string folderToBook = fmt::format("{}/{}_{}", folder_, bvalue, iHists_.apvmode_);

ibook.setCurrentFolder(folderToBook);
edm::LogPrint(moduleDescription().moduleName()) << "booking in " << folderToBook;

// prepare track histograms
iHists_.h1_["track_pt"] = ibook.book1D("track_pt", "track p_{T};track p_{T} [GeV];n. tracks", 2000, 0, 1000);
Expand Down Expand Up @@ -366,7 +409,7 @@ void SiStripLorentzAnglePCLMonitor::bookHistograms(DQMStore::IBooker& ibook,
for (auto& layers : iHists_.nlayers_) {
std::string subdet = layers.first;
for (int l = 1; l <= layers.second; ++l) {
ibook.setCurrentFolder(folder_ + Form("/%s/L%d", subdet.c_str(), l));
ibook.setCurrentFolder(folderToBook + Form("/%s/L%d", subdet.c_str(), l));
for (auto& t : iHists_.modtypes_) {
// do not fill stereo where there aren't
if (l > 2 && t == "s")
Expand Down Expand Up @@ -401,7 +444,7 @@ void SiStripLorentzAnglePCLMonitor::bookHistograms(DQMStore::IBooker& ibook,

// prepare module histograms
if (saveHistosMods_) {
ibook.setCurrentFolder(folder_ + "/modules");
ibook.setCurrentFolder(folderToBook + "/modules");
for (const auto& [mod, locationType] : iHists_.moduleLocationType_) {
// histograms for each module
iHists_.h1_[Form("%s_%d_nstrips", locationType.c_str(), mod)] =
Expand Down

0 comments on commit ca40f6c

Please sign in to comment.