DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Segmentation.cpp
Go to the documentation of this file.
1 /*
2  * Segmentation.cpp
3  *
4  * Created on: Jun 27, 2013
5  * Author: Christian Grefe, CERN
6  */
7 
9 
10 #include <iostream>
11 #include <sstream>
12 #include <stdexcept>
13 #include <cmath>
14 #include <algorithm>
15 #include <iomanip>
16 
17 namespace DD4hep {
18  namespace DDSegmentation {
19 
20  using std::cerr;
21  using std::endl;
22  using std::map;
23  using std::runtime_error;
24  using std::stringstream;
25  using std::vector;
26 
28  Segmentation::Segmentation(const std::string& cellEncoding) :
29  _name("Segmentation"), _type("Segmentation"), _decoder(new BitField64(cellEncoding)), _ownsDecoder(true) {
30 
31  }
32 
35  _name("Segmentation"), _type("Segmentation"), _decoder(newDecoder), _ownsDecoder(false) {
36  }
37 
40  if (_ownsDecoder and _decoder != 0) {
41  delete _decoder;
42  }
43  map<std::string, SegmentationParameter*>::iterator it;
44  for (it = _parameters.begin(); it != _parameters.end(); ++it) {
45  SegmentationParameter* p = it->second;
46  if (p) {
47  delete p;
48  p = 0;
49  }
50  }
51  }
52 
54  void Segmentation::addSubsegmentation(long /* key_min */, long /* key_max */, Segmentation* /* entry */) {
55  throw std::runtime_error("This segmentation type:"+_type+" does not support sub-segmentations.");
56  }
57 
60  map<std::string, StringParameter>::const_iterator it;
61  _decoder->setValue(cID);
62  for (it = _indexIdentifiers.begin(); it != _indexIdentifiers.end(); ++it) {
63  std::string identifier = it->second->typedValue();
64  (*_decoder)[identifier] = 0;
65  }
66  return _decoder->getValue();
67  }
68 
70  void Segmentation::neighbours(const CellID& cID, std::set<CellID>& cellNeighbours) const {
71  map<std::string, StringParameter>::const_iterator it;
72  for (it = _indexIdentifiers.begin(); it != _indexIdentifiers.end(); ++it) {
73  const std::string& identifier = it->second->typedValue();
74  _decoder->setValue(cID);
75  int currentValue = (*_decoder)[identifier];
76  // add both neighbouring cell IDs, don't add out of bound indices
77  try {
78  (*_decoder)[identifier] = currentValue - 1;
79  cellNeighbours.insert(_decoder->getValue());
80  } catch (runtime_error& e) {
81  // nothing to do
82  }
83  try {
84  (*_decoder)[identifier] = currentValue + 1;
85  cellNeighbours.insert(_decoder->getValue());
86  } catch (runtime_error& e) {
87  // nothing to do
88  }
89  }
90  }
91 
94  if ( _decoder == newDecoder )
95  return; //self assignment
96  else if (_ownsDecoder)
97  delete _decoder;
98  _decoder = newDecoder;
99  _ownsDecoder = false;
100  }
101 
103  Parameter Segmentation::parameter(const std::string& parameterName) const {
104  map<std::string, Parameter>::const_iterator it;
105  it = _parameters.find(parameterName);
106  if (it != _parameters.end()) {
107  return it->second;
108  }
109  stringstream s;
110  s << "Unknown parameter " << parameterName << " for segmentation type " << _type;
111  throw std::runtime_error(s.str());
112  }
113 
116  Parameters pars;
117  map<std::string, Parameter>::const_iterator it;
118  for (it = _parameters.begin(); it != _parameters.end(); ++it) {
119  pars.push_back(it->second);
120  }
121  return pars;
122  }
123 
126  Parameters::const_iterator it;
127  for (it = pars.begin(); it != pars.end(); ++it) {
128  Parameter p = *it;
129  parameter(p->name())->value() = p->value();
130  }
131  }
132 
134  void Segmentation::registerIdentifier(const std::string& idName, const std::string& idDescription, std::string& identifier,
135  const std::string& defaultValue) {
136  StringParameter idParameter =
137  new TypedSegmentationParameter<std::string>(idName, idDescription, identifier, defaultValue,
139  _parameters[idName] = idParameter;
140  _indexIdentifiers[idName] = idParameter;
141  }
142 
144  double Segmentation::binToPosition(long64 bin, double cellSize, double offset) {
145  return bin * cellSize + offset;
146  }
147 
149  int Segmentation::positionToBin(double position, double cellSize, double offset) {
150  if (cellSize <= 1e-10) {
151  throw runtime_error("Invalid cell size: 0.0");
152  }
153  return int(floor((position + 0.5 * cellSize - offset) / cellSize));
154  }
155 
157  double Segmentation::binToPosition(CellID bin, std::vector<double> const& cellBoundaries, double offset) {
158  return (cellBoundaries[bin+1] + cellBoundaries[bin])*0.5 + offset;
159  }
161  int Segmentation::positionToBin(double position, std::vector<double> const& cellBoundaries, double offset) {
162 
163  // include the lower edge to the segmentation, deal with numerical issues
164  if(fabs(position/cellBoundaries.front()-1.0) < 3e-12) return 0;
165 
166  // include the upper edge of the last bin to the segmentation, deal with numerical issues
167  if(fabs(position/cellBoundaries.back()-1.0) < 3e-12) return int(cellBoundaries.size()-2);
168 
169  // hits outside cannot be treated
170  if(position < cellBoundaries.front()) {
171  std::stringstream err;
172  err << std::setprecision(20) << std::scientific;
173  err << "Hit Position (" << position << ") is below the acceptance"
174  << " (" << cellBoundaries.front() << ") "
175  << "of the segmentation";
176  throw std::runtime_error(err.str());
177  }
178  if(position > cellBoundaries.back() ) {
179  std::stringstream err;
180  err << std::setprecision(20) << std::scientific;
181  err << "Hit Position (" << position << ") is above the acceptance"
182  << " (" << cellBoundaries.back() << ") "
183  << "of the segmentation";
184  throw std::runtime_error(err.str());
185  }
186 
187 
188  std::vector<double>::const_iterator bin = std::upper_bound(cellBoundaries.begin(),
189  cellBoundaries.end(),
190  position-offset);
191 
192  // need to reduce found bin by one, because upper_bound works that way, lower_bound would not help
193  return bin - cellBoundaries.begin() - 1 ;
194 
195  }
196 
197  std::vector<double> Segmentation::cellDimensions(const CellID&) const {
198  std::stringstream errorMessage;
199  errorMessage << __func__ << " is not implemented for " << _type;
200  throw std::logic_error(errorMessage.str());
201  }
202 
203  } /* namespace DDSegmentation */
204 } /* namespace DD4hep */
long long int CellID
Useful typedefs to differentiate cell IDs and volume IDs.
Definition: Primitives.h:32
void registerIdentifier(const std::string &nam, const std::string &desc, std::string &ident, const std::string &defaultVal)
Add a cell identifier to this segmentation. Used by derived classes to define their required identifi...
virtual VolumeID volumeID(const CellID &cellID) const
Determine the volume ID from the full cell ID by removing all local fields.
std::map< std::string, StringParameter > _indexIdentifiers
The indices used for the encoding.
Definition: Segmentation.h:159
virtual void neighbours(const CellID &cellID, std::set< CellID > &neighbours) const
Calculates the neighbours of the given cell ID and adds them to the list of neighbours.
const std::string & name() const
Access to the parameter name.
virtual Parameters parameters() const
Access to all parameters.
BitField64 * _decoder
The cell ID encoder and decoder.
Definition: Segmentation.h:161
TGeoShape * s
Definition: Volumes.cpp:294
return e
Definition: Volumes.cpp:297
std::vector< Parameter > Parameters
Definition: Segmentation.h:25
virtual void setParameters(const Parameters &parameters)
Set all parameters from an existing set of parameters.
Segmentation(const std::string &cellEncoding="")
Default constructor used by derived classes passing the encoding string.
virtual std::vector< double > cellDimensions(const CellID &cellID) const
Returns a vector<double> of the cellDimensions of the given cell ID in natural order of dimensions...
bool _ownsDecoder
Keeps track of the decoder ownership.
Definition: Segmentation.h:163
std::map< std::string, Parameter > _parameters
The parameters for this segmentation.
Definition: Segmentation.h:157
virtual std::string value() const =0
Access to the parameter value in string representation.
Base class for all segmentations.
Definition: Segmentation.h:68
static int positionToBin(double position, double cellSize, double offset=0.)
Helper method to convert a 1D position to a cell ID.
virtual Parameter parameter(const std::string &parameterName) const
Access to parameter by name.
std::string _type
The segmentation type.
Definition: Segmentation.h:153
virtual void addSubsegmentation(long key_min, long key_max, Segmentation *entry)
Add subsegmentation. Call only valid for Multi-segmentations. Default implementation throws an except...
long long int VolumeID
Definition: Primitives.h:35
virtual void setDecoder(BitField64 *decoder)
Set the underlying decoder.
virtual ~Segmentation()
Destructor.
Class to hold a segmentation parameter with its description.
static double binToPosition(CellID bin, double cellSize, double offset=0.)
Helper method to convert a bin number to a 1D position.
long long int long64
Definition: BitField64.h:15