File indexing completed on 2024-04-06 12:11:38
0001 #include "TFile.h"
0002 #include "TTree.h"
0003 #include "TEveGeoNode.h"
0004 #include "TEveGeoShape.h"
0005 #include "TPRegexp.h"
0006 #include "TSystem.h"
0007 #include "TGeoArb8.h"
0008 #include "TObjArray.h"
0009 #include "TObjString.h"
0010 #include "TPRegexp.h"
0011
0012 #include "Fireworks/Core/interface/FWGeometry.h"
0013 #include "Fireworks/Core/interface/fwLog.h"
0014 #include "DataFormats/DetId/interface/DetId.h"
0015
0016
0017 #include "CalibTracker/StandaloneTrackerTopology/interface/StandaloneTrackerTopology.h"
0018
0019 #include <cassert>
0020 #include <iostream>
0021 #include <memory>
0022
0023 #include <sstream>
0024 #include <stdexcept>
0025 #include <algorithm>
0026
0027 FWGeometry::FWGeometry(void) : m_producerVersion(0) {}
0028
0029 FWGeometry::~FWGeometry(void) {}
0030
0031 bool FWGeometry::isEmpty() const {
0032
0033
0034
0035 return m_idToInfo.empty();
0036 }
0037
0038 TFile* FWGeometry::findFile(const char* fileName) {
0039 std::string searchPath = ".";
0040
0041 if (gSystem->Getenv("CMSSW_SEARCH_PATH")) {
0042 TString paths = gSystem->Getenv("CMSSW_SEARCH_PATH");
0043
0044 TObjArray* tokens = paths.Tokenize(":");
0045 for (int i = 0; i < tokens->GetEntries(); ++i) {
0046 TObjString* path = (TObjString*)tokens->At(i);
0047 searchPath += ":";
0048 searchPath += static_cast<const char*>(path->GetString());
0049 if (gSystem->Getenv("CMSSW_VERSION"))
0050 searchPath += "/Fireworks/Geometry/data/";
0051 }
0052 }
0053
0054 TString fn = fileName;
0055 const char* fp = gSystem->FindFile(searchPath.c_str(), fn, kFileExists);
0056 return fp ? TFile::Open(fp) : nullptr;
0057 }
0058
0059 void FWGeometry::applyGlobalTag(const std::string& globalTag) {
0060 const std::string fnRun2 = "cmsGeomRun2.root";
0061 const std::string fnRun3 = "cmsGeom2021.root";
0062 const std::string fnSLHC = "cmsGeom2026.root";
0063
0064 TPMERegexp year_re("^[^_]+_[a-zA-Z]*20(\\d\\d)_");
0065 TPMERegexp run_re("^[^_]+_[a-zA-Z]*Run(\\d)_");
0066
0067 TString test = globalTag.c_str();
0068 std::string cfn;
0069 if (year_re.Match(test)) {
0070 TString r = year_re[1];
0071 int year = atoi(r.Data());
0072 if (year < 18) {
0073 cfn = fnRun2;
0074 } else if (year < 21) {
0075 cfn = fnRun3;
0076 } else {
0077 cfn = fnSLHC;
0078 }
0079 } else if (run_re.Match(test)) {
0080 TString rn = run_re[1];
0081 if (rn == "1") {
0082 fwLog(fwlog::kWarning) << "Run1 geometry not included. Using Run2 geometry." << std::endl;
0083 cfn = fnRun2;
0084 } else if (rn == "2") {
0085 cfn = fnRun2;
0086 } else if (rn == "4") {
0087 cfn = fnSLHC;
0088 } else {
0089 fwLog(fwlog::kWarning) << "Detected Run" << rn << ". Using geometry scenario 2021.\n";
0090 cfn = fnRun3;
0091 }
0092 } else {
0093 fwLog(fwlog::kWarning) << "Could not guess geometry from global tag. Using geometry scenario 2021.\n";
0094 cfn = fnRun3;
0095 }
0096
0097 fwLog(fwlog::kInfo) << "Guessed geometry " << cfn << " from global tag " << globalTag << std::endl;
0098 if (cfn.compare(m_fileName)) {
0099 loadMap(cfn.c_str());
0100 }
0101 }
0102
0103 void FWGeometry::loadMap(const char* iFileName) {
0104 TFile* file = findFile(iFileName);
0105 if (!file) {
0106 throw std::runtime_error("ERROR: failed to find geometry file. Initialization failed.");
0107 return;
0108 }
0109 m_fileName = iFileName;
0110 TTree* tree = static_cast<TTree*>(file->Get("idToGeo"));
0111 if (!tree) {
0112 throw std::runtime_error("ERROR: cannot find detector id map in the file. Initialization failed.");
0113 return;
0114 }
0115
0116 unsigned int id;
0117 Float_t points[24];
0118 Float_t topology[9];
0119 Float_t shape[5];
0120 Float_t translation[3];
0121 Float_t matrix[9];
0122 bool loadPoints = tree->GetBranch("points") != nullptr;
0123 bool loadParameters = tree->GetBranch("topology") != nullptr;
0124 bool loadShape = tree->GetBranch("shape") != nullptr;
0125 bool loadTranslation = tree->GetBranch("translation") != nullptr;
0126 bool loadMatrix = tree->GetBranch("matrix") != nullptr;
0127 tree->SetBranchAddress("id", &id);
0128 if (loadPoints)
0129 tree->SetBranchAddress("points", &points);
0130 if (loadParameters)
0131 tree->SetBranchAddress("topology", &topology);
0132 if (loadShape)
0133 tree->SetBranchAddress("shape", &shape);
0134 if (loadTranslation)
0135 tree->SetBranchAddress("translation", &translation);
0136 if (loadMatrix)
0137 tree->SetBranchAddress("matrix", &matrix);
0138
0139
0140 m_idToInfo.clear();
0141 for (const auto& p : m_idToMatrix)
0142 delete p.second;
0143 m_trackerTopology.reset();
0144
0145 unsigned int treeSize = tree->GetEntries();
0146 if (m_idToInfo.size() != treeSize)
0147 m_idToInfo.resize(treeSize);
0148 for (unsigned int i = 0; i < treeSize; ++i) {
0149 tree->GetEntry(i);
0150
0151 m_idToInfo[i].id = id;
0152 if (loadPoints) {
0153 for (unsigned int j = 0; j < 24; ++j)
0154 m_idToInfo[i].points[j] = points[j];
0155 }
0156 if (loadParameters) {
0157 for (unsigned int j = 0; j < 9; ++j)
0158 m_idToInfo[i].parameters[j] = topology[j];
0159 }
0160 if (loadShape) {
0161 for (unsigned int j = 0; j < 5; ++j)
0162 m_idToInfo[i].shape[j] = shape[j];
0163 }
0164 if (loadTranslation) {
0165 for (unsigned int j = 0; j < 3; ++j)
0166 m_idToInfo[i].translation[j] = translation[j];
0167 }
0168 if (loadMatrix) {
0169 for (unsigned int j = 0; j < 9; ++j)
0170 m_idToInfo[i].matrix[j] = matrix[j];
0171 }
0172 }
0173
0174 m_versionInfo.productionTag = static_cast<TNamed*>(file->Get("tag"));
0175 m_versionInfo.cmsswVersion = static_cast<TNamed*>(file->Get("CMSSW_VERSION"));
0176 m_versionInfo.extraDetectors = static_cast<TObjArray*>(file->Get("ExtraDetectors"));
0177
0178 TString path = file->GetPath();
0179 if (path.EndsWith(":/"))
0180 path.Resize(path.Length() - 2);
0181
0182 if (m_versionInfo.productionTag)
0183 fwLog(fwlog::kInfo) << Form(
0184 "Load %s %s from %s\n", tree->GetName(), m_versionInfo.productionTag->GetTitle(), path.Data());
0185 else
0186 fwLog(fwlog::kInfo) << Form("Load %s from %s\n", tree->GetName(), path.Data());
0187
0188 TNamed* producerInfo = static_cast<TNamed*>(file->Get("PRODUCER_VERSION"));
0189 if (producerInfo) {
0190 m_producerVersion = atoi(producerInfo->GetTitle());
0191 }
0192
0193 TNamed* ttopology = static_cast<TNamed*>(file->Get("TrackerTopology"));
0194 if (ttopology) {
0195 std::string xml = ttopology->GetTitle();
0196 m_trackerTopology =
0197 std::make_unique<TrackerTopology>(StandaloneTrackerTopology::fromTrackerParametersXMLString(xml));
0198 }
0199
0200 file->Close();
0201 }
0202
0203 void FWGeometry::initMap(const FWRecoGeom::InfoMap& map) {
0204 FWRecoGeom::InfoMapItr begin = map.begin();
0205 FWRecoGeom::InfoMapItr end = map.end();
0206 unsigned int mapSize = map.size();
0207 if (m_idToInfo.size() != mapSize)
0208 m_idToInfo.resize(mapSize);
0209 unsigned int i = 0;
0210 for (FWRecoGeom::InfoMapItr it = begin; it != end; ++it, ++i) {
0211 m_idToInfo[i].id = it->id;
0212 for (unsigned int j = 0; j < 24; ++j)
0213 m_idToInfo[i].points[j] = it->points[j];
0214 for (unsigned int j = 0; j < 9; ++j)
0215 m_idToInfo[i].parameters[j] = it->topology[j];
0216 for (unsigned int j = 0; j < 5; ++j)
0217 m_idToInfo[i].shape[j] = it->shape[j];
0218 for (unsigned int j = 0; j < 3; ++j)
0219 m_idToInfo[i].translation[j] = it->translation[j];
0220 for (unsigned int j = 0; j < 9; ++j)
0221 m_idToInfo[i].matrix[j] = it->matrix[j];
0222 }
0223 }
0224
0225 const TGeoMatrix* FWGeometry::getMatrix(unsigned int id) const {
0226 std::map<unsigned int, TGeoMatrix*>::iterator mit = m_idToMatrix.find(id);
0227 if (mit != m_idToMatrix.end())
0228 return mit->second;
0229
0230 IdToInfoItr it = FWGeometry::find(id);
0231 if (it == m_idToInfo.end()) {
0232 fwLog(fwlog::kWarning) << "no reco geometry found for id " << id << std::endl;
0233 return nullptr;
0234 } else {
0235 const GeomDetInfo& info = *it;
0236 TGeoTranslation trans(info.translation[0], info.translation[1], info.translation[2]);
0237 TGeoRotation rotation;
0238 const Double_t matrix[9] = {info.matrix[0],
0239 info.matrix[1],
0240 info.matrix[2],
0241 info.matrix[3],
0242 info.matrix[4],
0243 info.matrix[5],
0244 info.matrix[6],
0245 info.matrix[7],
0246 info.matrix[8]};
0247 rotation.SetMatrix(matrix);
0248
0249 m_idToMatrix[id] = new TGeoCombiTrans(trans, rotation);
0250 return m_idToMatrix[id];
0251 }
0252 }
0253
0254 std::vector<unsigned int> FWGeometry::getMatchedIds(Detector det, SubDetector subdet) const {
0255 std::vector<unsigned int> ids;
0256 unsigned int mask = (det << 4) | (subdet);
0257 for (IdToInfoItr it = m_idToInfo.begin(), itEnd = m_idToInfo.end(); it != itEnd; ++it) {
0258 if (FWGeometry::match_id(*it, mask))
0259 ids.push_back((*it).id);
0260 }
0261
0262 return ids;
0263 }
0264
0265 std::vector<unsigned int> FWGeometry::getMatchedIds(Detector det) const {
0266 std::vector<unsigned int> ids;
0267 for (const auto& it : m_idToInfo) {
0268 if (((it.id >> kDetOffset) & 0xF) != det)
0269 continue;
0270
0271
0272
0273
0274 if (det == HGCalHSc) {
0275 ids.push_back(it.id);
0276 } else {
0277 auto key = 0x3FF;
0278 if ((it.id | key) == it.id) {
0279 ids.push_back(it.id);
0280 }
0281 }
0282 }
0283 return ids;
0284 }
0285
0286 TGeoShape* FWGeometry::getShape(unsigned int id) const {
0287 IdToInfoItr it = FWGeometry::find(id);
0288 if (it == m_idToInfo.end()) {
0289 fwLog(fwlog::kWarning) << "no reco geoemtry found for id " << id << std::endl;
0290 return nullptr;
0291 } else {
0292 return getShape(*it);
0293 }
0294 }
0295
0296 TGeoShape* FWGeometry::getShape(const GeomDetInfo& info) const {
0297 TEveGeoManagerHolder gmgr(TEveGeoShape::GetGeoMangeur());
0298 TGeoShape* geoShape = nullptr;
0299 if (info.shape[0] == 1) {
0300 geoShape = new TGeoTrap(info.shape[3],
0301 0,
0302 0,
0303 info.shape[4],
0304 info.shape[1],
0305 info.shape[2],
0306 0,
0307 info.shape[4],
0308 info.shape[1],
0309 info.shape[2],
0310 0);
0311 } else
0312 geoShape = new TGeoBBox(info.shape[1], info.shape[2], info.shape[3]);
0313
0314 return geoShape;
0315 }
0316
0317 TEveGeoShape* FWGeometry::getEveShape(unsigned int id) const {
0318 IdToInfoItr it = FWGeometry::find(id);
0319 if (it == m_idToInfo.end()) {
0320 fwLog(fwlog::kWarning) << "no reco geoemtry found for id " << id << std::endl;
0321 return nullptr;
0322 } else {
0323 const GeomDetInfo& info = *it;
0324 double array[16] = {info.matrix[0],
0325 info.matrix[3],
0326 info.matrix[6],
0327 0.,
0328 info.matrix[1],
0329 info.matrix[4],
0330 info.matrix[7],
0331 0.,
0332 info.matrix[2],
0333 info.matrix[5],
0334 info.matrix[8],
0335 0.,
0336 info.translation[0],
0337 info.translation[1],
0338 info.translation[2],
0339 1.};
0340 TEveGeoManagerHolder gmgr(TEveGeoShape::GetGeoMangeur());
0341 TEveGeoShape* shape = new TEveGeoShape(TString::Format("RecoGeom Id=%u", id));
0342 TGeoShape* geoShape = getShape(info);
0343 shape->SetShape(geoShape);
0344
0345 shape->SetTransMatrix(array);
0346 return shape;
0347 }
0348 }
0349
0350 TEveGeoShape* FWGeometry::getHGCSiliconEveShape(unsigned int id) const {
0351 IdToInfoItr it = FWGeometry::find(id);
0352 if (it == m_idToInfo.end()) {
0353 fwLog(fwlog::kWarning) << "no reco geometry found for id " << id << std::endl;
0354 return nullptr;
0355 }
0356
0357 GeomDetInfo info = *it;
0358
0359 TEveGeoManagerHolder gmgr(TEveGeoShape::GetGeoMangeur());
0360 TEveGeoShape* shape = new TEveGeoShape(TString::Format("RecoGeom Id=%u", id));
0361
0362 TGeoXtru* geoShape = new TGeoXtru(2);
0363 Double_t x[6];
0364 Double_t y[6];
0365 for (unsigned int i = 0; i < 6; ++i) {
0366 x[i] = info.points[i * 3];
0367 y[i] = info.points[3 * i + 1];
0368 }
0369 geoShape->DefinePolygon(6, x, y);
0370 geoShape->DefineSection(0, info.points[2] - 0.0150);
0371 geoShape->DefineSection(1, info.points[2] + 0.0150);
0372
0373 shape->SetShape(geoShape);
0374 double array[16] = {info.matrix[0],
0375 info.matrix[3],
0376 info.matrix[6],
0377 0.,
0378 info.matrix[1],
0379 info.matrix[4],
0380 info.matrix[7],
0381 0.,
0382 info.matrix[2],
0383 info.matrix[5],
0384 info.matrix[8],
0385 0.,
0386 0.,
0387 0.,
0388 0.,
0389 1.};
0390
0391 shape->SetTransMatrix(array);
0392 return shape;
0393 }
0394
0395 TEveGeoShape* FWGeometry::getHGCScintillatorEveShape(unsigned int id) const {
0396 IdToInfoItr it = FWGeometry::find(id);
0397 if (it == m_idToInfo.end()) {
0398 fwLog(fwlog::kWarning) << "no reco geometry found for id " << id << std::endl;
0399 return nullptr;
0400 }
0401
0402 GeomDetInfo info = *it;
0403
0404 TEveGeoManagerHolder gmgr(TEveGeoShape::GetGeoMangeur());
0405 TEveGeoShape* shape = new TEveGeoShape(TString::Format("RecoGeom Id=%u", id));
0406
0407 TGeoXtru* geoShape = new TGeoXtru(2);
0408 Double_t x[4] = {info.points[0], info.points[3], info.points[6], info.points[9]};
0409 Double_t y[4] = {info.points[1], info.points[4], info.points[7], info.points[10]};
0410
0411 bool isNeg = info.shape[3] < 0;
0412 geoShape->DefinePolygon(4, x, y);
0413 geoShape->DefineSection(0, isNeg * info.shape[3]);
0414 geoShape->DefineSection(1, !isNeg * info.shape[3]);
0415 info.translation[2] = info.points[2];
0416
0417 shape->SetShape(geoShape);
0418 double array[16] = {info.matrix[0],
0419 info.matrix[3],
0420 info.matrix[6],
0421 0.,
0422 info.matrix[1],
0423 info.matrix[4],
0424 info.matrix[7],
0425 0.,
0426 info.matrix[2],
0427 info.matrix[5],
0428 info.matrix[8],
0429 0.,
0430 info.translation[0],
0431 info.translation[1],
0432 info.translation[2],
0433 1.};
0434
0435 shape->SetTransMatrix(array);
0436 return shape;
0437 }
0438
0439 const float* FWGeometry::getCorners(unsigned int id) const {
0440
0441 IdToInfoItr it = FWGeometry::find(id);
0442 if (it == m_idToInfo.end()) {
0443 fwLog(fwlog::kWarning) << "no reco geometry found for id " << id << std::endl;
0444 return nullptr;
0445 } else {
0446 return (*it).points;
0447 }
0448 }
0449
0450 const float* FWGeometry::getParameters(unsigned int id) const {
0451
0452 IdToInfoItr it = FWGeometry::find(id);
0453 if (it == m_idToInfo.end()) {
0454 fwLog(fwlog::kWarning) << "no reco geometry found for id " << id << std::endl;
0455 return nullptr;
0456 } else {
0457 return (*it).parameters;
0458 }
0459 }
0460
0461 const float* FWGeometry::getShapePars(unsigned int id) const {
0462
0463 IdToInfoItr it = FWGeometry::find(id);
0464 if (it == m_idToInfo.end()) {
0465 fwLog(fwlog::kWarning) << "no reco geometry found for id " << id << std::endl;
0466 return nullptr;
0467 } else {
0468 return (*it).shape;
0469 }
0470 }
0471
0472 void FWGeometry::localToGlobal(unsigned int id, const float* local, float* global, bool translatep) const {
0473 IdToInfoItr it = FWGeometry::find(id);
0474 if (it == m_idToInfo.end()) {
0475 fwLog(fwlog::kWarning) << "no reco geometry found for id " << id << std::endl;
0476 } else {
0477 localToGlobal(*it, local, global, translatep);
0478 }
0479 }
0480
0481 void FWGeometry::localToGlobal(
0482 unsigned int id, const float* local1, float* global1, const float* local2, float* global2, bool translatep) const {
0483 IdToInfoItr it = FWGeometry::find(id);
0484 if (it == m_idToInfo.end()) {
0485 fwLog(fwlog::kWarning) << "no reco geometry found for id " << id << std::endl;
0486 } else {
0487 localToGlobal(*it, local1, global1, translatep);
0488 localToGlobal(*it, local2, global2, translatep);
0489 }
0490 }
0491
0492 FWGeometry::IdToInfoItr FWGeometry::find(unsigned int id) const {
0493 FWGeometry::IdToInfoItr begin = m_idToInfo.begin();
0494 FWGeometry::IdToInfoItr end = m_idToInfo.end();
0495 return std::lower_bound(begin, end, id);
0496 }
0497
0498 void FWGeometry::localToGlobal(const GeomDetInfo& info, const float* local, float* global, bool translatep) const {
0499 for (int i = 0; i < 3; ++i) {
0500 global[i] = translatep ? info.translation[i] : 0;
0501 global[i] += local[0] * info.matrix[3 * i] + local[1] * info.matrix[3 * i + 1] + local[2] * info.matrix[3 * i + 2];
0502 }
0503 }
0504
0505
0506
0507 bool FWGeometry::VersionInfo::haveExtraDet(const char* det) const {
0508 return (extraDetectors && extraDetectors->FindObject(det)) ? true : false;
0509 }