diff --git a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h index f900065ad738a..ee6f5f33fc9fe 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h +++ b/Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h @@ -93,6 +93,23 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache int getModule(int index) const; int getChip(int index) const; + void defineMLOTSensors(); + int getBarrelLayer(int) const; + + // sensor ref X and alpha for ML & OT + void extractSensorXAlphaMLOT(int, float&, float&); + + // cache for tracking frames (ML & OT) + bool isTrackingFrameCachedMLOT() const { return !mCacheRefXMLOT.empty(); } + void fillTrackingFramesCacheMLOT(); + + float getSensorRefAlphaMLOT(int index) const { return mCacheRefAlphaMLOT[index]; } + float getSensorXMLOT(int index) const { return mCacheRefXMLOT[index]; } + + // create matrix for tracking to local frame for MLOT + TGeoHMatrix& createT2LMatrixMLOT(int); + + /// This routine computes the chip index number from the subDetID, petal, disk, layer, stave /// TODO: retrieve also from chip when chips will be available /// This routine computes the chip index number from the subDetID, petal, disk, layer, stave, half stave, module, chip /// \param int subDetID The subdetector ID, 0 for VD, 1 for MLOT /// \param int petalcase The petal case number for VD, from 0 to 3 @@ -200,10 +217,14 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache bool mOwner = true; //! is it owned by the singleton? + std::vector sensorsMLOT; + std::vector mCacheRefXMLOT; /// cache for X of ML and OT + std::vector mCacheRefAlphaMLOT; /// cache for sensor ref alpha ML and OT + private: static std::unique_ptr sInstance; }; } // namespace trk } // namespace o2 -#endif \ No newline at end of file +#endif diff --git a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx index 3eadeed4b56f3..72caf1f4d5e20 100644 --- a/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx +++ b/Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx @@ -12,6 +12,7 @@ #include #include #include "TRKBase/SegmentationChip.h" +#include #include @@ -123,6 +124,8 @@ void GeometryTGeo::Build(int loadTrans) setSize(numberOfChipsTotal); fillMatrixCache(loadTrans); + defineMLOTSensors(); + fillTrackingFramesCacheMLOT(); } //__________________________________________________________________________ @@ -466,6 +469,32 @@ TGeoHMatrix* GeometryTGeo::extractMatrixSensor(int index) const return &matTmp; } +//__________________________________________________________________________ +void GeometryTGeo::defineMLOTSensors() +{ + for (int i = 0; i < mSize; i++) { + if (getSubDetID(i) == 0) { + continue; + } + sensorsMLOT.push_back(i); + } +} + +//__________________________________________________________________________ +void GeometryTGeo::fillTrackingFramesCacheMLOT() +{ + // fill for every sensor of ML & OT its tracking frame parameters + if (!isTrackingFrameCachedMLOT() && !sensorsMLOT.empty()) { + size_t newSize = sensorsMLOT.size(); + mCacheRefXMLOT.resize(newSize); + mCacheRefAlphaMLOT.resize(newSize); + for (int i = 0; i < newSize; i++) { + int sensorId = sensorsMLOT[i]; + extractSensorXAlphaMLOT(sensorId, mCacheRefXMLOT[i], mCacheRefAlphaMLOT[i]); + } + } +} + //__________________________________________________________________________ void GeometryTGeo::fillMatrixCache(int mask) { @@ -488,6 +517,21 @@ void GeometryTGeo::fillMatrixCache(int mask) } } + // build T2L matrices for ML & OT !! VD is yet to be implemented once its geometry will be more refined + if ((mask & o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L)) && !getCacheT2L().isFilled()) { + LOGP(info, "Loading {} T2L matrices from TGeo for ML & OT", getName()); + if (sensorsMLOT.size()) { + int m_Size = sensorsMLOT.size(); + auto& cacheT2L = getCacheT2L(); + cacheT2L.setSize(m_Size); + for (int i = 0; i < m_Size; i++) { + int sensorID = sensorsMLOT[i]; + TGeoHMatrix& hm = createT2LMatrixMLOT(sensorID); + cacheT2L.setMatrix(Mat3D(hm), i); // here, sensorIDs from 0 to 374, sensorIDs shifted to 36 ! + } + } + } + // TODO: build matrices for the cases T2L, T2G and T2GRot when needed } @@ -1109,5 +1153,87 @@ void GeometryTGeo::Print(Option_t*) const std::cout << "]" << std::endl; } +//__________________________________________________________________________ +int GeometryTGeo::getBarrelLayer(int chipID) const +{ + // for barrel layers only, + // so it would be consistent with number of layers i.e. from 0 to 10, + // starting from VD0 to OT10; + // skip the disks; + + int subDetID = getSubDetID(chipID); + int subLayerID = getLayer(chipID); + + if (subDetID < 0 || subDetID > 1) { + LOG(error) << "getBarrelLayer(): Invalid subDetID for barrel: " << subDetID + << ". Expected values are 0 or 1."; + return -1; + } + + if (subLayerID < 0 || subLayerID > 7) { + LOG(error) << "getBarrelLayer(): Invalid subLayerID for barrel: " << subDetID + << ". Expected values are between 0 and 7."; + return -1; + } + + const int baseOffsets[] = {0, 3}; + + return baseOffsets[subDetID] + subLayerID; +} + +//__________________________________________________________________________ +void GeometryTGeo::extractSensorXAlphaMLOT(int chipID, float& x, float& alp) +{ + // works for ML and OT only, a.k.a flat sensors !!! + double locA[3] = {-100., 0., 0.}, locB[3] = {100., 0., 0.}, gloA[3], gloB[3]; + double xp{0}, yp{0}; + + if (getSubDetID(chipID) == 0) { + + LOG(error) << "extractSensorXAlphaMLOT(): VD layers are not supported yet! chipID = " << chipID; + return; + + } else { // flat sensors, ML and OT + const TGeoHMatrix* matL2G = extractMatrixSensor(chipID); + matL2G->LocalToMaster(locA, gloA); + matL2G->LocalToMaster(locB, gloB); + double dx = gloB[0] - gloA[0], dy = gloB[1] - gloA[1]; + double t = (gloB[0] * dx + gloB[1] * dy) / (dx * dx + dy * dy); + xp = gloB[0] - dx * t; + yp = gloB[1] - dy * t; + } + + alp = std::atan2(yp, xp); + x = std::hypot(xp, yp); + o2::math_utils::bringTo02Pi(alp); + + /// TODO: + // once the VD segmentation is done, VD should be added +} + +//__________________________________________________________________________ +TGeoHMatrix& GeometryTGeo::createT2LMatrixMLOT(int chipID) +{ + // works only for ML & OT + // for VD is yet to be implemented once we have more refined geometry + if (getSubDetID(chipID) == 0) { + + LOG(error) << "createT2LMatrixMLOT(): VD layers are not supported yet! chipID = " << chipID + << "returning dummy values! "; + static TGeoHMatrix dummy; + return dummy; + + } else { + static TGeoHMatrix t2l; + t2l.Clear(); + float alpha = getSensorRefAlphaMLOT(chipID); + t2l.RotateZ(alpha * TMath::RadToDeg()); + const TGeoHMatrix* matL2G = extractMatrixSensor(chipID); + const TGeoHMatrix& matL2Gi = matL2G->Inverse(); + t2l.MultiplyLeft(&matL2Gi); + return t2l; + } +} + } // namespace trk } // namespace o2