GEAR  1.9.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends Pages
TPCParametersImpl.cc
1 #include "gearimpl/TPCParametersImpl.h"
2 
3 #include "gearimpl/TPCModuleImpl.h"
4 #include <vector>
5 #include <sstream>
6 
7 namespace gear {
8 
14  TPCParametersImpl::TPCParametersImpl( double maxDriftLength, int coordinateType ) :
15  _maxDriftLength(maxDriftLength),
16  _coordinateType(coordinateType),
17  _cathodePosition(0.),
18  _driftVelocity(0)
19  {
20  if ( (maxDriftLength == -1.) || (coordinateType == -1) )
21  {
22 // std::cerr << "TPCParametersImpl::TPCParametersImpl: Warning: "
23 // << "deprecated use of constructor without parameters." << std::endl
24 // << " Please define maxDriftLength and coordinateType in constructor!"
25 // << std::endl;
26  _maxDriftLength = 0.;
27  _coordinateType = PadRowLayout2D::POLAR; // make polare (disk) the default
28  }
29 
30  _planeExtent.push_back(0.0);
31  _planeExtent.push_back(0.0);
32  _planeExtent.push_back(0.0);
33  _planeExtent.push_back(0.0);
34  }
35 
36  // The copy constructor. All modules are owned by the TPCParameters,
37  // and deleted in the destructor. So they have to be copied.
39  {
40  copy_and_assign( right);
41  }
42 
44  {
45  // create copies of all modules in the _TPCModules vector
46  std::vector<TPCModule *>::const_iterator itr;
47 
48  for(itr = right._TPCModules.begin();itr!=right._TPCModules.end();itr++)
49  {
50  _TPCModules.push_back( dynamic_cast<TPCModule *>((*itr)->clone()) );
51  // also copy the pointer to the negative or positive half TPC vectors
52  try
53  {
54  if ((*itr)->getZPosition() <= 0 )
55  {
56  _modulesNegativeHalfTPC.push_back( _TPCModules.back() );
57  }
58  else
59  {
60  _modulesPositiveHalfTPC.push_back( _TPCModules.back() );
61  }
62  }
64  {
65  // put the module to both half TPCs, so the module is always returned, whatever z is
66  _modulesPositiveHalfTPC.push_back( _TPCModules.back() );
67  _modulesNegativeHalfTPC.push_back( _TPCModules.back() );
68  }
69  }
70 
71  // copy all the other variables
72  _maxDriftLength = right._maxDriftLength;
73  _coordinateType = right._coordinateType;
74  _moduleIDMap = right._moduleIDMap;
75  _planeExtent = right._planeExtent;
78 
79  // call the assignment operator of the GearParametersImpl mother class:
80  // *dynamic_cast<GearParametersImpl*>(this) = *dynamic_cast<GearParametersImpl const *>(&right);
81  GearParametersImpl::operator = (right);
82  }
83 
86  {
87  cleanup();
88  }
89 
92  {
93  cleanup();
94  copy_and_assign( right );
95 
96  return *this;
97  }
98 
100  {
101  std::vector<TPCModule *>::iterator itr;
102 
103  for(itr = _TPCModules.begin();itr!=_TPCModules.end();itr++){
104  delete (*itr);
105  }
106 
107  // Empty all vectors which are filled with push_back.
108  // The map is overwritten in the copy_and_assign.
109  _TPCModules.clear();
110  _modulesPositiveHalfTPC.clear();
111  _modulesNegativeHalfTPC.clear();
112  }
113 
116  const TPCModule & TPCParametersImpl::getModule(int moduleID) const{
117  std::map<int,int>::const_iterator moduleIter = _moduleIDMap.find(moduleID);
118  if ( moduleIter == _moduleIDMap.end() )
119  {
120  std::stringstream message;
121  message << "TPCParameters::getModule: No module with ID " << moduleID
122  << " defined in the gear file! "<< std::endl;
123  throw gear::Exception(message.str());
124 
125  }
126  int temp = moduleIter->second;
127  TPCModule * tempMod = _TPCModules[temp];
128  return *tempMod;
129  }
130 
134  return _TPCModules.size();
135  }
136 
139  const TPCModule & TPCParametersImpl::getNearestModule(double c0, double c1,
140  std::vector<TPCModule *> const & modulesVector) const
141  {
142  const TPCModule * toReturn = NULL;
143  if(modulesVector.size()){
144  toReturn = modulesVector.at(0);
145  double distance = toReturn->getDistanceToModule(c0,c1);
146  std::vector<TPCModule *>::const_iterator itr;
147  double tempDistance;
148  for(itr = modulesVector.begin();itr!=modulesVector.end();itr++){
149  tempDistance =(*itr)->getDistanceToModule(c0,c1);
150  if(tempDistance < distance){
151  distance = tempDistance;
152  toReturn = (*itr);
153  }
154  }
155  }else{
156  throw gear::Exception("TPCParameters::GetNearsestModule: No Modules are defined, Cannot find Nearest");
157  }
158  return *toReturn;
159  }
160 
161  // the 2D version. Call the internal version with all modules
162  const TPCModule & TPCParametersImpl::getNearestModule(double c0, double c1) const
163  {
164  return getNearestModule(c0, c1, _TPCModules);
165  }
166 
167  // the 3D version. Call the internal version with the correct half TPC
168  const TPCModule & TPCParametersImpl::getNearestModule(double c0, double c1, double z) const{
169  if ( z <=_cathodePosition ){
170  return getNearestModule(c0, c1, _modulesNegativeHalfTPC);
171  }
172  else{
173  return getNearestModule(c0, c1, _modulesPositiveHalfTPC);
174  }
175  }
176 
180  return _maxDriftLength;
181  }
182 
187  bool TPCParametersImpl::isInsideModule(double c0, double c1) const{
188  return isInsideModule(c0, c1, _TPCModules);
189  }
190 
191  // the 3D version. Call the internal version with the correct half TPC
192  bool TPCParametersImpl::isInsideModule(double c0, double c1, double z) const{
193  if ( z <=_cathodePosition ){
194  return isInsideModule(c0, c1, _modulesNegativeHalfTPC);
195  }
196  else{
197  return isInsideModule(c0, c1, _modulesPositiveHalfTPC);
198  }
199  }
200 
201  bool TPCParametersImpl::isInsideModule(double c0, double c1,
202  std::vector<TPCModule *> const & modulesVector ) const{
203  bool toReturn = false;
204  std::vector<TPCModule *>::const_iterator itr;
205 
206  for(itr = modulesVector.begin();itr!=modulesVector.end();itr++){
207  toReturn = toReturn||(*itr)->isInsideModule(c0,c1);
208  }
209  return toReturn;
210  }
211 
215  bool TPCParametersImpl::isInsidePad(double c0, double c1) const{
216  return isInsidePad(c0, c1, _TPCModules);
217  }
218 
219  // the 3D version. Call the internal version with the correct half TPC
220  bool TPCParametersImpl::isInsidePad(double c0, double c1, double z) const{
221  if ( z <=_cathodePosition ){
222  return isInsidePad(c0, c1, _modulesNegativeHalfTPC);
223  }
224  else{
225  return isInsidePad(c0, c1, _modulesPositiveHalfTPC);
226  }
227  }
228 
229  bool TPCParametersImpl::isInsidePad(double c0, double c1,
230  std::vector<TPCModule *> const & modulesVector ) const{
231  bool toReturn = false;
232  std::vector<TPCModule *>::const_iterator itr;
233 
234  for(itr = modulesVector.begin();itr!=modulesVector.end();itr++){
235  toReturn = toReturn||(*itr)->isInsidePad(c0,c1);
236  }
237  return toReturn;
238  }
239 
244  return getNearestPad(c0, c1, _TPCModules);
245  }
246 
247  // the 3D version. Call the internal version with the correct half TPC
248  GlobalPadIndex TPCParametersImpl::getNearestPad(double c0, double c1, double z) const{
249  if ( z <=_cathodePosition ){
250  return getNearestPad(c0, c1, _modulesNegativeHalfTPC);
251  }
252  else{
253  return getNearestPad(c0, c1, _modulesPositiveHalfTPC);
254  }
255  }
256 
258  std::vector<TPCModule *> const & modulesVector ) const{
259 
260 
261  if(!modulesVector.size()) {
262  throw gear::Exception("TPCParametersImpl::getNearestPad: No Modules are defined, Cannot find Nearest");
263  }
264  //For each module, get distance to nearest pad, compare, return shortest.
265  std::vector<TPCModule *>::const_iterator itr, best_itr;
266  itr = modulesVector.begin();
267  best_itr = itr;
268 
269  GlobalPadIndex closest_pad( (*itr)->getNearestPad(c0, c1), (*itr)->getModuleID() );
270 
271  if( modulesVector.size() == 1 ) {
272 
273  return closest_pad;
274  }
275 
276  // initialize the distance
277  double shortest_distance = (*itr)->getDistanceToPad( c0, c1, closest_pad.getPadIndex() );
278 
279  // start at the second module
280  for( itr+1; itr!=modulesVector.end(); itr++) {
281 
282  GlobalPadIndex temp_pad( (*itr)->getNearestPad( c0, c1 ), (*itr)->getModuleID() );
283 
284  const double distance = (*itr)->getDistanceToPad( c0, c1, temp_pad.getPadIndex() );
285 
286  if( distance < shortest_distance ) {
287 
288  closest_pad = temp_pad;
289  shortest_distance = distance;
290  }
291  }
292 
293  return closest_pad;
294  }
295 
299  const std::vector<double> & TPCParametersImpl::getPlaneExtent() const{
300  if(!_TPCModules.size()) {
301  throw gear::Exception("TPCParametersImpl::getPlaneExtent: No Modules are defined, Bad User");
302  }
303 
304  return _planeExtent;
305  }
306 
310  return _coordinateType;
311  }
312 
314  if(TPCModule==NULL) {
315  throw gear::Exception("TPCParametersImpl::addModule: This Module is not defined, Bad User");
316  }
317 
318  // check whether module has correct mother coordinate type
319  if (TPCModule->getTPCCoordinateType() != _coordinateType)
320  {
321  throw gear::Exception("TPCParametersImpl::addModule: Module has wrong coordinate type, Bad User");
322  }
323 
324  int currentVectorSize = _TPCModules.size();
325 
326  if(_moduleIDMap.find(TPCModule->getModuleID())!=_moduleIDMap.end()) {
327  throw gear::Exception("TPCParametersImpl::addModule: This Module Number has already been used.");
328  }
329  _moduleIDMap[TPCModule->getModuleID()] = currentVectorSize;
330  _TPCModules.push_back(TPCModule);
331 
332  // also add module to correct positive and negative half TPC
333  try
334  {
335  if ( TPCModule->getZPosition() <= 0 )
336  {
337  _modulesNegativeHalfTPC.push_back(TPCModule);
338  }
339  else
340  {
341  _modulesPositiveHalfTPC.push_back(TPCModule);
342  }
343 
344  // internal helper function to avoid code duplication
345  setCathodePosition();
346 
347  }
348  catch ( TPCModule::NoZPositionException & e )
349  {
350  // put the module to both half TPCs, so the module is always returned, whatever z is
351  _modulesPositiveHalfTPC.push_back(TPCModule);
352  _modulesNegativeHalfTPC.push_back(TPCModule);
353 
354  // no need to do anything about the cathode position, it has no effect anyways
355  }
356 
357  if (_TPCModules.size() == 1 ) // there is only one module, copy the plane extent
358  {
359  _planeExtent = TPCModule->getModuleExtent();
360  }
361  else // check for each boundary
362  {
363  if(TPCModule->getModuleExtent().at(0) < _planeExtent.at(0)) {
364  _planeExtent.at(0)=TPCModule->getModuleExtent().at(0);
365  }
366  if(TPCModule->getModuleExtent().at(1) > _planeExtent.at(1)) {
367  _planeExtent.at(1)=TPCModule->getModuleExtent().at(1);
368  }
369  if(TPCModule->getModuleExtent().at(2) < _planeExtent.at(2)) {
370  _planeExtent.at(2)=TPCModule->getModuleExtent().at(2);
371  }
372  if(TPCModule->getModuleExtent().at(3) > _planeExtent.at(3)) {
373  _planeExtent.at(3)=TPCModule->getModuleExtent().at(3);
374  }
375  }// else (_TPCModules.size() == 1 )
376  }
377 
380  const std::vector<TPCModule *> & TPCParametersImpl::getModules() const{
381  return _TPCModules;
382  }
383 
394  {
395  //std::cout << "TPCParametersImpl::getPadLayout() : nModules = " << _TPCModules.size()
396  // << std::endl;
397  if (_TPCModules.size() > 1)
398  throw gear::Exception("You cannot use TPCParametersImpl::getPadLayout() with more than one module. Use getModule(moduleID) instead!");
399  if (_TPCModules.size() < 1)
400  throw gear::Exception("You cannot use TPCParametersImpl::getPadLayout() without a module. Set the module / pad layout first!");
401  //n.b. This ensures that there is at least one module,
402  // so it's save to use _TPCModules[0]
403 
404 // std::cerr << "TPCParametersImpl: Warning: "
405 // << "deprecated use of getPadLayout()." << std::endl
406 // << " Use getTPCModule( moduleID ) instead!"
407 // << std::endl;
408 
409  if ( (_TPCModules[0]->getAngle() != 0) || ((_TPCModules[0]->getOffset())[0] != 0)
410  || ((_TPCModules[0]->getOffset())[1] != 0) )
411  throw gear::Exception("Module coordinate system is not identical to coordinate system in pad plane. Use getModule(moduleID) instead!");
412 
413  return *(_TPCModules[0]);
414  }
415 
422  {
423 // std::cerr << "TPCParametersImpl: Warning: "
424 // << "deprecated use of getDriftVelocity()." << std::endl
425 // << " Drift velosity should come from conditions data!"
426 // << std::endl;
427 
428  return _driftVelocity ;
429  }
430 
439  {
440  if (_TPCModules.size() > 1)
441  throw gear::Exception("You cannot use TPCParametersImpl::getRadoutFreuqency() with more than one module. Use getModule(moduleID) instead!");
442  if (_TPCModules.size() < 1)
443  throw gear::Exception("You cannot use TPCParametersImpl::getRadoutFreuqency() without a module. Set the module / pad plane first!");
444  //n.b. This ensures that there is at least one module,
445  // so it's save to use _TPCModules[0]
446  return _TPCModules[0]->getReadoutFrequency();
447  }
448 
449  void TPCParametersImpl::setMaxDriftLength( double maxDriftLength )
450  {
451 // std::cerr << "TPCParametersImpl: Warning: "
452 // << "deprecated use of setMaxDriftLength()." << std::endl
453 // << " Please define maxDriftLength in constructor!"
454 // << std::endl;
455 
456  _maxDriftLength = maxDriftLength ;
457 
458  // we have to recalculate the cathode position since this depends on the drift length
459  setCathodePosition();
460  }
461 
462  void TPCParametersImpl::setDriftVelocity( double driftVelocity )
463  {
464 // std::cerr << "TPCParametersImpl: Warning: "
465 // << "deprecated use of setDriftVelocity()." << std::endl
466 // << " Drift velosity should come from conditions data!"
467 // << std::endl;
468 
469  _driftVelocity = driftVelocity ;
470  }
471 
472  void TPCParametersImpl::setReadoutFrequency( double readoutFrequency )
473  {
474 // std::cerr << "TPCParametersImpl: Warning: "
475 // << "deprecated use of setReadoutFrequency." << std::endl
476 // << " Readout frequency is property of a TPCModule!"
477 // << std::endl;
478 
479  if (_TPCModules.size() > 1)
480  throw gear::Exception("You cannot use TPCParametersImpl:::setReadoutFrequency() with more than one module. Use getModule(moduleID) instead!");
481  if (_TPCModules.size() < 1)
482  throw gear::Exception("You cannot use TPCParametersImpl:::setReadoutFrequency() without a module. Set the module / pad plane first!");
483  //n.b. This ensures that there is at least one module,
484  // so it's save to use _TPCModules[0]
485  dynamic_cast<TPCModuleImpl*>(_TPCModules[0])->setReadoutFrequency(readoutFrequency);
486  }
487 
489  {
490 // std::cerr << "TPCParametersImpl: Warning: "
491 // << "deprecated use of setPadLayout." << std::endl
492 // << " Please use addModule instead!"
493 // << std::endl;
494 
495  if (_TPCModules.size() != 0)
496  throw gear::Exception("There is already one module in TPCParametersImpl. Will not replace it!");
497 
498  // check whether the padLayout actually is a module
499  if ( padLayout->getPadLayoutImplType() == PadRowLayout2D::TPCMODULE )
500  throw gear::Exception("Wrong type: PadLayout is a module, cannot set this using setPadLayout. Use addModule()!");
501 
502  addModule( new TPCModuleImpl(0, padLayout, _coordinateType ));
503  }
504 
505  void TPCParametersImpl::setCathodePosition()
506  {
507  // Calculate the correct cathode position.
508  // This is called when a module is added and the drift length has changed
509  try
510  {
511  if ( ! _modulesNegativeHalfTPC.empty() )
512  {
513  if ( ! _modulesPositiveHalfTPC.empty() )
514  // There are modules in both half TPCs, take the middle between the anodes
515  {
516  // all modules in one half are assumed to be at the same z position
517  // otherwise only one drift length does not make sense
518  _cathodePosition = ( _modulesNegativeHalfTPC[0]->getZPosition()
519  + _modulesPositiveHalfTPC[0]->getZPosition() ) /2. ;
520  }
521  else // there is only the negative half TPC
522  {
523  _cathodePosition = _modulesNegativeHalfTPC[0]->getZPosition() + _maxDriftLength;
524  }
525  }
526  else if ( ! _modulesPositiveHalfTPC.empty() )
527  {
528  // there is only the positive half TPC
529  _cathodePosition = _modulesPositiveHalfTPC[0]->getZPosition() - _maxDriftLength;
530  }
531  // else: there are no modules, leave the cathode position where it is (should be 0. )
532  }
533  catch ( TPCModule::NoZPositionException & )
534  {
535  // leave the z position as is (should be 0.) The modules are in both end caps
536  // anyway, so you will always get the module you want
537  }
538 
539  }
540 
541 } // namespace gear
virtual ~TPCParametersImpl()
Copy constructor for base parameters.
double _driftVelocity
Drift velocity is deprecated, should come from conditions data.
virtual void setDriftVelocity(double driftVelocity)
virtual double getZPosition() const =0
Returns the z position of the module.
Abstract description of a planar subdetector with pads (cells) that are positioned in rows (circular ...
virtual double getReadoutFrequency() const
Kept for backward compatibility.
Base exception class for GEAR - all other exceptions extend this.
Definition: GEAR.h:41
virtual bool isInsideModule(double c0, double c1) const
True if coordinate (c0,c1) is within any module.
virtual const PadRowLayout2D & getPadLayout() const
Kept for backward compatibility.
virtual void setPadLayout(PadRowLayout2D *padLayout)
Global pad index implimentation .
virtual const std::vector< double > & getPlaneExtent() const
Extent of the sensitive plane - [xmin,xmax,ymin,ymax] CARTESIAN or [rmin,rmax,phimin,phimax] POLAR.
virtual int getNModules() const
Returns the number of modules in the TPC (endplate)
virtual double getMaxDriftLength() const
The maximum drift length in the TPC in mm.
virtual int getCoordinateType() const
Returns coordinate type as an int (see PadRowLayout2D::CARTESIAN, PadRowLayout2D::POLAR) ...
virtual const TPCModule & getModule(int moduleID) const
Returns module with the given module ID.
virtual int getPadLayoutImplType() const =0
The type of the row layout implementation: PadRowLayout2D.RECTANGULARPADROWLAYOUT, PadRowLayout2D.FIXEDPADSIZEDISKLAYOUT, PadRowLayout2D.FIXEDPADANGLEDISKLAYOUT or PadRowLayout2D.TPCMODULE.
virtual void setMaxDriftLength(double maxDriftLength)
std::map< int, int > _moduleIDMap
A map with the moduleID as key and the index in the _TPCModules vector as value.
virtual int getModuleID() const =0
Returns module ID.
virtual void setReadoutFrequency(double readoutFrequency)
virtual const std::vector< TPCModule * > & getModules() const
Returns vector of all modules in this TPC (endplate).
A Container for TPCModules which describe the geometry properties of a given TPC. ...
void cleanup()
function to delete all the objects pointed to and owned by the GearMgr.
TPCParametersImpl(double maxDriftLength=-1., int coordinateType=-1)
virtual GlobalPadIndex getNearestPad(double c0, double c1) const
Returns globalPadindex Object for nearest pad to given coordinates (2D).
virtual double getDriftVelocity() const
The electron drift velocity in the TPC in mm/s.
virtual void addModule(TPCModule *TPCModule)
Adds a Module to the vector of modules, or throws an exception.
TPCParametersImpl & operator=(const TPCParametersImpl &)
Assignment operator.
virtual const TPCModule & getNearestModule(double c0, double c1) const
Returns nearest module to given coordinates (2D).
double _cathodePosition
The cathode position is needed internally to distinguish the half TPCs.
virtual int getTPCCoordinateType() const =0
Returns the TPCs coordinate type.
An exception that is special for the TPCModule.
Definition: TPCModule.h:48
virtual const std::vector< double > & getModuleExtent() const =0
Maximal extent of the sensitive plane, defined relative to global origin - [xmin,xmax,ymin,ymax] CARTESIAN or [rmin,rmax,phimin,phimax] POLAR, may contain dead space due to conversion from local to global coordinate system.
void copy_and_assign(const TPCParametersImpl &)
function to copy all internal variables, incl.
A wrapper Class for PadRowLayout2D which converts between the actual pad layouts local coodinate syst...
Definition: TPCModule.h:41
A wrapper Class for PadRowLayout2D, allowing which converts between local and global coordinate syste...
Definition: TPCModuleImpl.h:23
virtual double getDistanceToModule(double c0, double c1) const =0
Returns distastance from a global coodinate (c0,c1), to the module&#39;s nearest boundery; (c0...
virtual bool isInsidePad(double c0, double c1) const
True if coordinate (c0,c1) is within any pad, on any module.