File indexing completed on 2023-10-25 09:35:25
0001 #include "FWCore/Framework/interface/global/EDProducer.h"
0002 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0003 #include "FWCore/Framework/interface/ConsumesCollector.h"
0004 #include "DataFormats/NanoAOD/interface/FlatTable.h"
0005
0006 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0007 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0008
0009 #include "MagneticField/Engine/interface/MagneticField.h"
0010 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0011 #include "CondFormats/SiStripObjects/interface/SiStripLorentzAngle.h"
0012 #include "CalibTracker/Records/interface/SiStripDependentRecords.h"
0013 #include "Geometry/TrackerGeometryBuilder/interface/StripGeomDetUnit.h"
0014 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0015 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
0016
0017 #include "CalibTracker/SiStripCommon/interface/ShallowTools.h"
0018
0019 class SiStripLorentzAngleRunInfoTableProducer : public edm::global::EDProducer<edm::BeginRunProducer> {
0020 public:
0021 explicit SiStripLorentzAngleRunInfoTableProducer(const edm::ParameterSet& params)
0022 : m_name{params.getParameter<std::string>("name")},
0023 m_magFieldName{params.getParameter<std::string>("magFieldName")},
0024 m_doc{params.existsAs<std::string>("doc") ? params.getParameter<std::string>("doc") : ""},
0025 m_tkGeomToken{esConsumes<edm::Transition::BeginRun>()},
0026 m_magFieldToken{esConsumes<edm::Transition::BeginRun>()},
0027 m_lorentzAngleToken{esConsumes<edm::Transition::BeginRun>()} {
0028 produces<nanoaod::FlatTable, edm::Transition::BeginRun>();
0029 produces<nanoaod::FlatTable, edm::Transition::BeginRun>("magField");
0030 }
0031
0032 void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {}
0033
0034 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0035 edm::ParameterSetDescription desc;
0036 desc.add<std::string>("name", "Det");
0037 desc.add<std::string>("magFieldName", "magField");
0038 desc.add<std::string>("doc", "Run info for the Lorentz angle measurement");
0039 descriptions.add("siStripLorentzAngleRunInfoTable", desc);
0040 }
0041
0042 void globalBeginRunProduce(edm::Run& iRun, edm::EventSetup const& iSetup) const override;
0043
0044 private:
0045 const std::string m_name, m_magFieldName;
0046 const std::string m_doc;
0047 edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> m_tkGeomToken;
0048 edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> m_magFieldToken;
0049 edm::ESGetToken<SiStripLorentzAngle, SiStripLorentzAngleDepRcd> m_lorentzAngleToken;
0050 };
0051
0052 namespace {
0053 template <typename VALUES>
0054 void addColumn(nanoaod::FlatTable* table, const std::string& name, VALUES&& values, const std::string& doc) {
0055 using value_type = typename std::remove_reference<VALUES>::type::value_type;
0056 table->template addColumn<value_type>(name, values, doc);
0057 }
0058 }
0059
0060 void SiStripLorentzAngleRunInfoTableProducer::globalBeginRunProduce(edm::Run& iRun,
0061 edm::EventSetup const& iSetup) const {
0062 const auto& tkGeom = iSetup.getData(m_tkGeomToken);
0063 const auto& magField = iSetup.getData(m_magFieldToken);
0064 const auto& lorentzAngle = iSetup.getData(m_lorentzAngleToken);
0065 std::vector<uint32_t> c_rawid;
0066 std::vector<float> c_globalZofunitlocalY, c_localB, c_BdotY, c_driftx, c_drifty, c_driftz, c_lorentzAngle;
0067
0068 auto dets = tkGeom.detsTIB();
0069 dets.insert(dets.end(), tkGeom.detsTID().begin(), tkGeom.detsTID().end());
0070 dets.insert(dets.end(), tkGeom.detsTOB().begin(), tkGeom.detsTOB().end());
0071 dets.insert(dets.end(), tkGeom.detsTEC().begin(), tkGeom.detsTEC().end());
0072 for (auto det : dets) {
0073 auto detid = det->geographicalId().rawId();
0074 const StripGeomDetUnit* stripDet = dynamic_cast<const StripGeomDetUnit*>(tkGeom.idToDet(det->geographicalId()));
0075 if (stripDet) {
0076 c_rawid.push_back(detid);
0077 c_globalZofunitlocalY.push_back(stripDet->toGlobal(LocalVector(0, 1, 0)).z());
0078 const auto locB = magField.inTesla(stripDet->surface().position());
0079 c_localB.push_back(locB.mag());
0080 c_BdotY.push_back(stripDet->surface().toLocal(locB).y());
0081 const auto drift = shallow::drift(stripDet, magField, lorentzAngle);
0082 c_driftx.push_back(drift.x());
0083 c_drifty.push_back(drift.y());
0084 c_driftz.push_back(drift.z());
0085 c_lorentzAngle.push_back(lorentzAngle.getLorentzAngle(detid));
0086 }
0087 }
0088 auto out = std::make_unique<nanoaod::FlatTable>(c_rawid.size(), m_name, false, false);
0089 addColumn(out.get(), "rawid", c_rawid, "DetId");
0090 addColumn(out.get(), "globalZofunitlocalY", c_globalZofunitlocalY, "z component of a local unit vector along y");
0091 addColumn(out.get(), "localB", c_localB, "Local magnitude of the magnetic field");
0092 addColumn(out.get(), "BdotY", c_BdotY, "Magnetic field projection on the local y axis");
0093 addColumn(out.get(), "driftx", c_driftx, "x component of the drift vector");
0094 addColumn(out.get(), "drifty", c_drifty, "y component of the drift vector");
0095 addColumn(out.get(), "driftz", c_driftz, "z component of the drift vector");
0096 addColumn(out.get(), "lorentzAngle", c_lorentzAngle, "Lorentz angle from database");
0097 iRun.put(std::move(out));
0098
0099 auto out2 = std::make_unique<nanoaod::FlatTable>(1, m_magFieldName, true, false);
0100 out2->addColumnValue<float>(
0101 "origin", magField.inTesla(GlobalPoint(0, 0, 0)).z(), "z-component of the magnetic field at (0,0,0) in Tesla");
0102 iRun.put(std::move(out2), "magField");
0103 }
0104
0105 #include "FWCore/PluginManager/interface/ModuleDef.h"
0106 #include "FWCore/Framework/interface/MakerMacros.h"
0107 DEFINE_FWK_MODULE(SiStripLorentzAngleRunInfoTableProducer);