File indexing completed on 2025-02-22 09:36:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <DDSegmentation/Segmentation.h>
0019
0020 #include <iostream>
0021 #include <sstream>
0022 #include <stdexcept>
0023 #include <cmath>
0024 #include <algorithm>
0025 #include <iomanip>
0026
0027 namespace dd4hep {
0028
0029 namespace DDSegmentation {
0030
0031 using std::cerr;
0032 using std::endl;
0033 using std::map;
0034 using std::runtime_error;
0035 using std::stringstream;
0036 using std::vector;
0037
0038
0039 Segmentation::Segmentation(const std::string& cellEncoding) :
0040 _name("Segmentation"), _type("Segmentation"), _decoder(new BitFieldCoder(cellEncoding)), _ownsDecoder(true) {
0041
0042 }
0043
0044
0045 Segmentation::Segmentation(const BitFieldCoder* newDecoder) :
0046 _name("Segmentation"), _type("Segmentation"), _decoder(newDecoder), _ownsDecoder(false) {
0047 }
0048
0049
0050 Segmentation::~Segmentation() {
0051 if (_ownsDecoder and _decoder != 0) {
0052 delete _decoder;
0053 }
0054 for (auto& p : _parameters) {
0055 if ( p.second ) delete p.second;
0056 }
0057 _parameters.clear();
0058 }
0059
0060
0061 void Segmentation::addSubsegmentation(long , long , Segmentation* ) {
0062 throw std::runtime_error("This segmentation type:"+_type+" does not support sub-segmentations.");
0063 }
0064
0065
0066 VolumeID Segmentation::volumeID(const CellID& cID) const {
0067 map<std::string, StringParameter>::const_iterator it;
0068 VolumeID vID = cID ;
0069 for (it = _indexIdentifiers.begin(); it != _indexIdentifiers.end(); ++it) {
0070 std::string identifier = it->second->typedValue();
0071 _decoder->set(vID,identifier,0);
0072 }
0073 return vID;
0074 }
0075
0076
0077 void Segmentation::neighbours(const CellID& cID, std::set<CellID>& cellNeighbours) const {
0078 map<std::string, StringParameter>::const_iterator it;
0079 for (it = _indexIdentifiers.begin(); it != _indexIdentifiers.end(); ++it) {
0080 const std::string& identifier = it->second->typedValue();
0081 CellID nID = cID ;
0082 int currentValue = _decoder->get(cID,identifier);
0083
0084 try {
0085 _decoder->set(nID,identifier,currentValue - 1);
0086 cellNeighbours.insert(nID);
0087 } catch (runtime_error& e) {
0088
0089 }
0090 try {
0091 _decoder->set(nID,identifier,currentValue + 1);
0092 cellNeighbours.insert(nID);
0093 } catch (runtime_error& e) {
0094
0095 }
0096 }
0097 }
0098
0099
0100 void Segmentation::setDecoder(const BitFieldCoder* newDecoder) {
0101 if ( _decoder == newDecoder )
0102 return;
0103 else if (_ownsDecoder)
0104 delete _decoder;
0105 _decoder = newDecoder;
0106 _ownsDecoder = false;
0107 }
0108
0109
0110 Parameter Segmentation::parameter(const std::string& parameterName) const {
0111 map<std::string, Parameter>::const_iterator it = _parameters.find(parameterName);
0112 if (it != _parameters.end()) {
0113 return it->second;
0114 }
0115 stringstream s;
0116 s << "Unknown parameter " << parameterName << " for segmentation type " << _type;
0117 throw std::runtime_error(s.str());
0118 }
0119
0120
0121 Parameters Segmentation::parameters() const {
0122 Parameters pars;
0123 for ( const auto& it : _parameters )
0124 pars.emplace_back(it.second);
0125 return pars;
0126 }
0127
0128
0129 void Segmentation::setParameters(const Parameters& pars) {
0130 for ( const auto* p : pars )
0131 parameter(p->name())->value() = p->value();
0132 }
0133
0134
0135 void Segmentation::registerIdentifier(const std::string& idName, const std::string& idDescription, std::string& identifier,
0136 const std::string& defaultValue) {
0137 StringParameter idParameter =
0138 new TypedSegmentationParameter<std::string>(idName, idDescription, identifier, defaultValue,
0139 SegmentationParameter::NoUnit, true);
0140 _parameters[idName] = idParameter;
0141 _indexIdentifiers[idName] = idParameter;
0142 }
0143
0144
0145 double Segmentation::binToPosition(FieldID bin, double cellSize, double offset) {
0146 return bin * cellSize + offset;
0147 }
0148
0149
0150 int Segmentation::positionToBin(double position, double cellSize, double offset) {
0151 if (cellSize <= 1e-10) {
0152 throw runtime_error("Invalid cell size: 0.0");
0153 }
0154 return int(floor((position + 0.5 * cellSize - offset) / cellSize));
0155 }
0156
0157
0158 double Segmentation::binToPosition(FieldID bin, std::vector<double> const& cellBoundaries, double offset) {
0159 return (cellBoundaries[bin+1] + cellBoundaries[bin])*0.5 + offset;
0160 }
0161
0162 int Segmentation::positionToBin(double position, std::vector<double> const& cellBoundaries, double offset) {
0163
0164
0165 if(fabs(position/cellBoundaries.front()-1.0) < 3e-12) return 0;
0166
0167
0168 if(fabs(position/cellBoundaries.back()-1.0) < 3e-12) return int(cellBoundaries.size()-2);
0169
0170
0171 if(position < cellBoundaries.front()) {
0172 std::stringstream err;
0173 err << std::setprecision(20) << std::scientific;
0174 err << "Hit Position (" << position << ") is below the acceptance"
0175 << " (" << cellBoundaries.front() << ") "
0176 << "of the segmentation";
0177 throw std::runtime_error(err.str());
0178 }
0179 if(position > cellBoundaries.back() ) {
0180 std::stringstream err;
0181 err << std::setprecision(20) << std::scientific;
0182 err << "Hit Position (" << position << ") is above the acceptance"
0183 << " (" << cellBoundaries.back() << ") "
0184 << "of the segmentation";
0185 throw std::runtime_error(err.str());
0186 }
0187 std::vector<double>::const_iterator bin = std::upper_bound(cellBoundaries.begin(),
0188 cellBoundaries.end(),
0189 position-offset);
0190
0191 return bin - cellBoundaries.begin() - 1 ;
0192
0193 }
0194
0195 std::vector<double> Segmentation::cellDimensions(const CellID&) const {
0196 std::stringstream errorMessage;
0197 errorMessage << __func__ << " is not implemented for " << _type;
0198 throw std::logic_error(errorMessage.str());
0199 }
0200
0201 }
0202 }