diff --git a/DDRec/include/DDRec/CellIDPositionConverter.h b/DDRec/include/DDRec/CellIDPositionConverter.h index d13f69b361d5eee7c94511f22f453648ce6dc491..92365505e672aa6a68e69b0173a5104b2e931cbd 100644 --- a/DDRec/include/DDRec/CellIDPositionConverter.h +++ b/DDRec/include/DDRec/CellIDPositionConverter.h @@ -17,13 +17,10 @@ namespace DD4hep { typedef DDSegmentation::CellID CellID; typedef DDSegmentation::VolumeID VolumeID; - /** CellIDPositionConverter - utility class that - * combines functionality of the VolumeManager and Segmentation classes to provide a - * high level interface for position to cell ID and cell ID to position conversions - * and related information. + /** Utility for position to cell ID and cell ID to position conversions. + * (Correctly re-implements some of the functionality of the deprecated IDDecoder). * - * - * @author F.Gaede, DESY ( based on IDDecoder by C.Grefe, CERN) + * @author F.Gaede, DESY * @date May 2017 */ @@ -35,76 +32,52 @@ namespace DD4hep { public: - /// Default constructor + /// The constructor - takes the main lcdd object. CellIDPositionConverter( Geometry::LCDD& lcdd ) { _volumeManager = Geometry::VolumeManager::getVolumeManager(lcdd); - - std::cout << " VolumeManager: \n" << _volumeManager << std::endl ; } /// Destructor virtual ~CellIDPositionConverter(){} ; - /// Returns the cell ID from the local position in the given volume ID. - CellID cellIDFromLocal(const Geometry::Position& local, const VolumeID volumeID) const; - - /// Returns the global cell ID from a given global position + /// returns the global cell ID from a given global position CellID cellID(const Geometry::Position& global) const; - /// Returns the global position from a given cell ID - Geometry::Position position(const CellID& cellID) const; - - /// Returns the local position from a given cell ID - Geometry::Position localPosition(const CellID& cellID) const; + /** Return the nominal global position for a given cellID of a sensitive volume. + * No Alignment corrections are applied. + * If no sensitive volume is found, (0,0,0) is returned. + */ + Geometry::Position positionNominal(const CellID& cellID) const; - /// Returns the volume ID of a given cell ID - VolumeID volumeID(const CellID& cellID) const; - - /// Returns the volume ID of a given global position - VolumeID volumeID(const Geometry::Position& global) const; - - /// Returns the placement for a given cell ID - Geometry::PlacedVolume placement(const CellID& cellID) const; - - /// Returns the placement for a given global position - Geometry::PlacedVolume placement(const Geometry::Position& global) const; - - /// Returns the subdetector for a given cell ID - Geometry::DetElement subDetector(const CellID& cellID) const; - - /// Returns the subdetector for a given global position - Geometry::DetElement subDetector(const Geometry::Position& global) const; - - /// Returns the closest detector element in the hierarchy for a given cell ID - Geometry::DetElement detectorElement(const CellID& cellID) const; + /** Return the global position for a given cellID of a sensitive volume. + * Alignment corrections are applied (TO BE DONE). + * If no sensitive volume is found, (0,0,0) is returned. + */ + Geometry::Position position(const CellID& cellID) const; - /// Returns the closest detector element in the hierarchy for a given global position - Geometry::DetElement detectorElement(const Geometry::Position& global) const; + /** Find the context with DetElement, placements etc for a given cellID of a sensitive volume. + * Returns NULL if not found (e.g. if the cellID does not correspond to a sensitive volume). + */ + const Geometry::VolumeManagerContext* findContext(const CellID& cellID) const; - /// Access to the Readout object for a given cell ID - Geometry::Readout readout(const CellID& cellID) const; - /// Access to the Readout object for a given global position - Geometry::Readout readout(const Geometry::Position& global) const; + /** Find the readout object for the given DetElement. If the DetElement is sensitive the corresondig + * Readout is returned, else a recursive search in the daughter volumes (nodes) of this DetElement's + * volume is performed and the first Readout object is returned. + * + */ + Geometry::Readout findReadout(const Geometry::DetElement& det) const ; - /// Calculates the neighbours of the given cell ID and adds them to the list of neighbours - void neighbours(const CellID& cellID, std::set<CellID>& neighbours) const; - /// Checks if the given cell IDs are neighbours - bool areNeighbours(const CellID& cellID, const CellID& otherCellID) const; + /** Return this PlacedVolume's Readout or, if the volume is not sensitive, recursively search for + * a Readout object in the daughter nodes (volumes). + */ + Geometry::Readout findReadout(const Geometry::PlacedVolume& pv) const ; - /// find the context with DetElement, placements etc for a given cellID of a sensitive volume. - DD4hep::Geometry::VolumeManagerContext* findContext(const CellID& cellID) const; - protected: Geometry::VolumeManager _volumeManager{} ; - Geometry::Readout findReadout(const Geometry::DetElement& det) const ; - Geometry::DetElement getClosestDaughter(const Geometry:: DetElement& det, const Geometry::Position& position) const ; - Geometry::Readout findReadout(const Geometry::PlacedVolume& pv) const ; - - }; } /* namespace DDRec */ diff --git a/DDRec/src/CellIDPositionConverter.cpp b/DDRec/src/CellIDPositionConverter.cpp index f8c08230a2bfb81a27b9a757e8b503126b856449..21d3a324e3eee58dd7512e4e6e2d5114c0e77b34 100644 --- a/DDRec/src/CellIDPositionConverter.cpp +++ b/DDRec/src/CellIDPositionConverter.cpp @@ -1,6 +1,5 @@ #include "DDRec/CellIDPositionConverter.h" -#include "DDRec/API/Exceptions.h" #include "DD4hep/LCDD.h" #include "DD4hep/objects/VolumeManagerInterna.h" @@ -22,67 +21,51 @@ namespace DD4hep { - DD4hep::Geometry::VolumeManagerContext* CellIDPositionConverter::findContext(const CellID& cellID) const{ + const DD4hep::Geometry::VolumeManagerContext* + CellIDPositionConverter::findContext(const CellID& cellID) const { return _volumeManager.lookupContext( cellID ) ; } - CellID CellIDPositionConverter::cellIDFromLocal(const Position& local, const VolumeID volID) const { - double l[3]; - double g[3]; - local.GetCoordinates(l); + Position CellIDPositionConverter::position(const CellID& cell) const { - // DetElement det = this->detectorElement(volID); - // const TGeoMatrix& localToGlobal = det.nominal().worldTransformation(); - // localToGlobal.LocalToMaster(l, g); - // Position global(g[0], g[1], g[2]); - // return this->findReadout(det).segmentation().cellID(local, global, volID); - - PlacedVolume pv = placement( volID ) ; - Volume v = pv.volume() ; - SensitiveDetector sens = v.sensitiveDetector() ; - Readout r = sens.readout() ; + // untill we have the alignment map object, we return the nominal position - return r.segmentation().cellID( local, Position(), volID ) ; + return positionNominal( cell ) ; } - /** - * Returns the global cell ID from a given global position - */ - CellID CellIDPositionConverter::cellID(const Position& global) const { - VolumeID volID = volumeID(global); - double l[3]; - double g[3]; - global.GetCoordinates(g); - DetElement det = this->detectorElement(volID); - const TGeoMatrix& localToGlobal = det.nominal().worldTransformation(); - localToGlobal.MasterToLocal(g, l); - Position local(l[0], l[1], l[2]); - return this->findReadout(det).segmentation().cellID(local, global, volID); - } - - /** - * Returns the global position from a given cell ID - */ - Position CellIDPositionConverter::position(const CellID& cell) const { + Position CellIDPositionConverter::positionNominal(const CellID& cell) const { double l[3], e[3], g[3]; - DD4hep::Geometry::VolumeManagerContext* context = findContext( cell ) ; + const Geometry::VolumeManagerContext* context = findContext( cell ) ; if( context == NULL) return Position() ; DetElement det = context->element ; + + +#if 0 // this uses the deprected VolumeManagerContext::placement + PlacedVolume pv = context->placement ; if( ! pv.volume().isSensitive() ) return Position() ; - Geometry::SensitiveDetector sd = pv.volume().sensitiveDetector(); Readout r = sd.readout() ; + +#else + + // use a recursive search for the Readout + Readout r = findReadout( det ) ; + +#endif + + + Segmentation seg = r.segmentation() ; Position local = seg.position(cell); @@ -95,130 +78,18 @@ namespace DD4hep { elementToGlobal.LocalToMaster(e, g); - // std::cout << " local " << local << " , " - // << "cellid: " << cell - // << " : " << r.idSpec().str( cell ) - // << " pv: " << pv.name() - // << std::endl ; - - return Position(g[0], g[1], g[2]); } - /* - * Returns the local position from a given cell ID - */ - Position CellIDPositionConverter::localPosition(const CellID& cell) const { - DetElement det = this->detectorElement(cell); - return this->findReadout(det).segmentation().position(cell); - } - - /* - * Returns the volume ID of a given cell ID - */ - VolumeID CellIDPositionConverter::volumeID(const CellID& cell) const { - DetElement det = this->detectorElement(cell); - return this->findReadout(det).segmentation().volumeID(cell); - } - - /* - * Returns the volume ID of a given global position - */ - VolumeID CellIDPositionConverter::volumeID(const Position& pos) const { - DetElement det = this->detectorElement(pos); - return det.volumeID(); - } - - /* - * Returns the placement for a given cell ID - */ - PlacedVolume CellIDPositionConverter::placement(const CellID& cell) const { - return _volumeManager.lookupPlacement(cell); - } - - /* - * Returns the placement for a given global position - */ - PlacedVolume CellIDPositionConverter::placement(const Position& pos) const { - return placement(volumeID(pos)); - } - - /* - * Returns the subdetector for a given cell ID - */ - DetElement CellIDPositionConverter::subDetector(const CellID& cell) const { - return _volumeManager.lookupDetector(cell); - } - - /* - * Returns the subdetector for a given global position - */ - DetElement CellIDPositionConverter::subDetector(const Position& pos) const { - return subDetector(volumeID(pos)); - } - /* - * Returns the closest detector element in the hierarchy for a given cell ID - */ - DetElement CellIDPositionConverter::detectorElement(const CellID& cell) const { - return _volumeManager.lookupDetElement(cell); - } - - /* - * Returns the closest detector element in the hierarchy for a given global position - */ - DetElement CellIDPositionConverter::detectorElement(const Position& pos) const { - DetElement world = Geometry::LCDD::getInstance().world(); - DetElement det = getClosestDaughter(world, pos); - if (not det.isValid()) { - throw invalid_position("DD4hep::DDRec::CellIDPositionConverter::detectorElement", pos); - } - std::cout << det.name() << std::endl; - return det; - } - - /// Access to the Readout object for a given cell ID - Geometry::Readout CellIDPositionConverter::readout(const CellID& cell) const { - DetElement det = this->detectorElement(cell); - return this->findReadout(det); - } - /// Access to the Readout object for a given global position - Geometry::Readout CellIDPositionConverter::readout(const Position& global) const { - DetElement det = this->detectorElement(global); - return this->findReadout(det); - } + CellID CellIDPositionConverter::cellID(const Position& global) const { - /* - * Calculates the neighbours of the given cell ID and adds them to the list of neighbours - */ - void CellIDPositionConverter::neighbours(const CellID& cell, set<CellID>& neighbour_cells) const { - DetElement det = this->detectorElement(cell); - this->findReadout(det).segmentation().neighbours(cell, neighbour_cells); - } + //FIXME: how to best implement this ? - /* - * Checks if the given cell IDs are neighbours - */ - bool CellIDPositionConverter::areNeighbours(const CellID& cell, const CellID& otherCellID) const { - set<CellID> neighbour_cells; - DetElement det = this->detectorElement(cell); - this->findReadout(det).segmentation().neighbours(cell, neighbour_cells); - return neighbour_cells.count(otherCellID) != 0; + return 0 ; } - // long int CellIDPositionConverter::layerIndex(const CellID& cell) const { - // Readout r = this->readout(cell); - // return r.idSpec().field(this->layerIdentifier())->value(cell); - // } - - // /// Access to the system index - // long int CellIDPositionConverter::systemIndex(const CellID& cell) const { - // Readout r = this->readout(cell); - // return r.idSpec().field(this->systemIdentifier())->value(cell); - // } - - // helper method to find the corresponding Readout object to a DetElement Readout CellIDPositionConverter::findReadout(const Geometry::DetElement& det) const { @@ -239,31 +110,6 @@ namespace DD4hep { return Readout(); } - // Readout CellIDPositionConverter::findReadout(const Geometry::DetElement& det) const { - - // // first check if top level is a sensitive detector - // if (det.volume().isValid() and det.volume().isSensitive()) { - // Geometry::SensitiveDetector sd = det.volume().sensitiveDetector(); - // if (sd.isValid() and sd.readout().isValid()) { - // return sd.readout(); - // } - // } - - // // check all children recursively for the first valid Readout object - // const DetElement::Children& children = det.children(); - // DetElement::Children::const_iterator it = children.begin(); - // while (it != children.end()) { - // Readout r = findReadout(it->second); - // if (r.isValid()) { - // return r; - // } - // ++it; - // } - - // // neither this or any daughter is sensitive - // return Readout(); - // } - Readout CellIDPositionConverter::findReadout(const Geometry::PlacedVolume& pv) const { // first check if we are in a sensitive volume @@ -289,35 +135,8 @@ namespace DD4hep { return Readout() ; } - // helper method to get the closest daughter DetElement to the position starting from the given DetElement - DetElement CellIDPositionConverter::getClosestDaughter(const DetElement& det, const Position& position) const { - DetElement result; - - // check if we have a shape and see if we are inside - if (det.volume().isValid() and det.volume().solid().isValid()) { - double globalPosition[3] = { position.x(), position.y(), position.z() }; - double localPosition[3] = { 0., 0., 0. }; - det.nominal().worldTransformation().MasterToLocal(globalPosition, localPosition); - if (det.volume().solid()->Contains(localPosition)) { - result = det; - } else { - // assuming that any daughter shape would be inside this shape - return DetElement(); - } - } - const DetElement::Children& children = det.children(); - DetElement::Children::const_iterator it = children.begin(); - while (it != children.end()) { - DetElement daughterDet = getClosestDaughter(it->second, position); - if (daughterDet.isValid()) { - result = daughterDet; - break; - } - ++it; - } - return result; - } + } /* namespace DDRec */ } /* namespace DD4hep */