ATLAS Offline Software
Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | List of all members
Trk::GeoShapeConverter Class Reference

#include <GeoShapeConverter.h>

Inheritance diagram for Trk::GeoShapeConverter:
Collaboration diagram for Trk::GeoShapeConverter:

Public Member Functions

 GeoShapeConverter ()
 
std::unique_ptr< VolumetranslateGeoShape (const GeoShape *shape, const Amg::Transform3D &trf) const
 Convert an arbitrary GeoShape into Trk::Volume. More...
 
void decodeShape (const GeoShape *) const
 Decode and dump arbitrary GeoShape for visual inspection. More...
 
bool msgLvl (const MSG::Level lvl) const
 Test the output level. More...
 
MsgStream & msg () const
 The standard message stream. More...
 
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream. More...
 
void setLevel (MSG::Level lvl)
 Change the current logging level. More...
 

Static Public Member Functions

static std::unique_ptr< CylinderVolumeBoundsconvert (const GeoTubs *gtub)
 Convert a tubs. More...
 
static std::unique_ptr< CylinderVolumeBoundsconvert (const GeoTube *gtub)
 Convert a tube. More...
 
static std::unique_ptr< CylinderVolumeBoundsconvert (const GeoPcon *gtub, std::vector< double > &zbounds)
 Convert a Polygon into a CylinderVolume -> smooth it. More...
 
static std::unique_ptr< CuboidVolumeBoundsconvert (const GeoBox *gbox)
 Convert a Box. More...
 

Private Member Functions

void initMessaging () const
 Initialize our message level and MessageSvc. More...
 

Private Attributes

std::string m_nm
 Message source name. More...
 
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels) More...
 
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer. More...
 
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level. More...
 
std::atomic_flag m_initialized ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
 Messaging initialized (initMessaging) More...
 

Detailed Description

A Simple Helper Class that convertes the GeoShape object used in GeoModel full detector description to an appropriate Trk::VolumeBounds (factory type) object.

Author
Andre.nosp@m.as.S.nosp@m.alzbu.nosp@m.rger.nosp@m.@cern.nosp@m..ch generalization by Sarka.nosp@m..Tod.nosp@m.orova.nosp@m.@cer.nosp@m.n.ch

Definition at line 42 of file GeoShapeConverter.h.

Constructor & Destructor Documentation

◆ GeoShapeConverter()

Trk::GeoShapeConverter::GeoShapeConverter ( )

Definition at line 55 of file GeoShapeConverter.cxx.

55 : AthMessaging{"GeoShapeConverter"} {}

Member Function Documentation

◆ convert() [1/4]

std::unique_ptr< CuboidVolumeBounds > Trk::GeoShapeConverter::convert ( const GeoBox *  gbox)
static

Convert a Box.

Definition at line 95 of file GeoShapeConverter.cxx.

95  {
96  double halfX = gbox->getXHalfLength();
97  double halfY = gbox->getYHalfLength();
98  double halfZ = gbox->getZHalfLength();
99  return std::make_unique<CuboidVolumeBounds>(halfX, halfY, halfZ);
100 }

◆ convert() [2/4]

std::unique_ptr< CylinderVolumeBounds > Trk::GeoShapeConverter::convert ( const GeoPcon *  gtub,
std::vector< double > &  zbounds 
)
static

Convert a Polygon into a CylinderVolume -> smooth it.

Definition at line 75 of file GeoShapeConverter.cxx.

76  {
77 
78  // get the pcon igredients ...
79  unsigned int numberOfPlanes = gpcon->getNPlanes();
80  double rMin{10.e10}, rMax{-10.e10}, zMin{10.e10}, zMax{-10.e10};
81 
82  for (unsigned int iplane = 0; iplane < numberOfPlanes; ++iplane) {
83  zMin = std::min(gpcon->getZPlane(iplane), zMin);
84  zMax = std::max(gpcon->getZPlane(iplane), zMax);
85  rMin = std::min(gpcon->getRMinPlane(iplane), rMin);
86  rMax = std::max(gpcon->getRMaxPlane(iplane), rMax);
87  }
88  zbounds.push_back(zMin);
89  zbounds.push_back(zMax);
90 
91  return std::make_unique<CylinderVolumeBounds>(rMin, rMax,
92  0.5 * (zMax - zMin));
93 }

◆ convert() [3/4]

std::unique_ptr< CylinderVolumeBounds > Trk::GeoShapeConverter::convert ( const GeoTube *  gtub)
static

Convert a tube.

Definition at line 66 of file GeoShapeConverter.cxx.

66  {
67  // get the dimensions
68  double rMin = gtube->getRMin();
69  double rMax = gtube->getRMax();
70  double halflength = gtube->getZHalfLength();
71  // create the volumeBounds
72  return std::make_unique<CylinderVolumeBounds>(rMin, rMax, halflength);
73 }

◆ convert() [4/4]

std::unique_ptr< CylinderVolumeBounds > Trk::GeoShapeConverter::convert ( const GeoTubs *  gtub)
static

Convert a tubs.

Definition at line 57 of file GeoShapeConverter.cxx.

57  {
58  // get the dimensions
59  double rMin = gtubs->getRMin();
60  double rMax = gtubs->getRMax();
61  double halflength = gtubs->getZHalfLength();
62  // create the volumeBounds
63  return std::make_unique<CylinderVolumeBounds>(rMin, rMax, halflength);
64 }

◆ decodeShape()

void Trk::GeoShapeConverter::decodeShape ( const GeoShape *  sh) const

Decode and dump arbitrary GeoShape for visual inspection.

Definition at line 516 of file GeoShapeConverter.cxx.

516  {
517  ATH_MSG_DEBUG(" ");
518  ATH_MSG_DEBUG("decoding shape:" << sh->type());
519 
520  if (sh->type() == "Pgon") {
521  const GeoPgon* pgon = dynamic_cast<const GeoPgon*>(sh);
522  if (pgon)
523  ATH_MSG_DEBUG("polygon: " << pgon->getNPlanes() << " planes "
524  << pgon->getSPhi() << " "
525  << pgon->getDPhi() << " "
526  << pgon->getNSides());
527  else
528  ATH_MSG_DEBUG("polygon: WARNING: dynamic_cast failed!");
529  }
530 
531  if (sh->type() == "Trd") {
532  const GeoTrd* trd = dynamic_cast<const GeoTrd*>(sh);
533  ATH_MSG_DEBUG("dimensions:" << trd->getXHalfLength1() << ","
534  << trd->getXHalfLength2() << ","
535  << trd->getYHalfLength1() << ","
536  << trd->getYHalfLength2() << ","
537  << trd->getZHalfLength());
538  }
539  if (sh->type() == "Box") {
540  const GeoBox* box = dynamic_cast<const GeoBox*>(sh);
541  ATH_MSG_DEBUG("dimensions:" << box->getXHalfLength() << ","
542  << box->getYHalfLength() << ","
543  << box->getZHalfLength());
544  }
545 
546  if (sh->type() == "Tube") {
547  const GeoTube* tube = dynamic_cast<const GeoTube*>(sh);
548  ATH_MSG_DEBUG("dimensions:" << tube->getRMin() << "," << tube->getRMax()
549  << "," << tube->getZHalfLength());
550  }
551 
552  if (sh->type() == "Tubs") {
553  const GeoTubs* tubs = dynamic_cast<const GeoTubs*>(sh);
554  ATH_MSG_DEBUG("dimensions:" << tubs->getRMin() << "," << tubs->getRMax()
555  << "," << tubs->getZHalfLength() << ","
556  << tubs->getSPhi() << ","
557  << tubs->getDPhi());
558  }
559 
560  if (sh->type() == "Cons") {
561  const GeoCons* cons = dynamic_cast<const GeoCons*>(sh);
562  ATH_MSG_DEBUG("dimensions:"
563  << cons->getRMin1() << "," << cons->getRMin2() << ","
564  << cons->getRMax1() << "," << cons->getRMax2() << ","
565  << cons->getDZ() << "," << cons->getSPhi() << ","
566  << cons->getDPhi());
567  }
568 
569  if (sh->type() == "Subtraction") {
570  const GeoShapeSubtraction* sub =
571  dynamic_cast<const GeoShapeSubtraction*>(sh);
572  const GeoShape* sha = sub->getOpA();
573  const GeoShape* shs = sub->getOpB();
574  ATH_MSG_DEBUG("decoding subtracted shape:");
575  decodeShape(sha);
576  decodeShape(shs);
577  }
578 
579  if (sh->type() == "Union") {
580  const GeoShapeUnion* sub = dynamic_cast<const GeoShapeUnion*>(sh);
581  const GeoShape* shA = sub->getOpA();
582  const GeoShape* shB = sub->getOpB();
583  ATH_MSG_DEBUG("decoding shape A:");
584  decodeShape(shA);
585  ATH_MSG_DEBUG("decoding shape B:");
586  decodeShape(shB);
587  }
588  if (sh->type() == "Shift") {
589  const GeoShapeShift* shift = dynamic_cast<const GeoShapeShift*>(sh);
590  const GeoShape* shA = shift->getOp();
591  const GeoTrf::Transform3D& transf = shift->getX();
592  ATH_MSG_DEBUG("shifted by:transl:"
593  << transf.translation() << ", rot:" << transf(0, 0) << ","
594  << transf(1, 1) << "," << transf(2, 2));
595  decodeShape(shA);
596  }
597 }

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40 {
42  m_lvl = m_imsg ?
43  static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
44  MSG::INFO;
45 }

◆ msg() [1/2]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 164 of file AthMessaging.h.

165 {
166  MsgStream* ms = m_msg_tls.get();
167  if (!ms) {
168  if (!m_initialized.test_and_set()) initMessaging();
169  ms = new MsgStream(m_imsg,m_nm);
170  m_msg_tls.reset( ms );
171  }
172 
173  ms->setLevel (m_lvl);
174  return *ms;
175 }

◆ msg() [2/2]

MsgStream & AthMessaging::msg ( const MSG::Level  lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 179 of file AthMessaging.h.

180 { return msg() << lvl; }

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level  lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152 {
153  if (!m_initialized.test_and_set()) initMessaging();
154  if (m_lvl <= lvl) {
155  msg() << lvl;
156  return true;
157  } else {
158  return false;
159  }
160 }

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level  lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29 {
30  m_lvl = lvl;
31 }

◆ translateGeoShape()

std::unique_ptr< Volume > Trk::GeoShapeConverter::translateGeoShape ( const GeoShape *  shape,
const Amg::Transform3D trf 
) const

Convert an arbitrary GeoShape into Trk::Volume.

divide volume into nStep cylinders

Definition at line 102 of file GeoShapeConverter.cxx.

103  {
104  std::unique_ptr<Volume> vol{};
105  double tol = 0.1;
106 
107  ATH_MSG_DEBUG(" translateGeoShape " << sh->type());
108 
109  if (sh->type() == "Trap") {
110  const GeoTrap* trap = dynamic_cast<const GeoTrap*>(sh);
111  std::unique_ptr<TrapezoidVolumeBounds> volBounds{};
112  if (trap->getDxdyndzp() < trap->getDxdyndzn()) {
113  volBounds = std::make_unique<TrapezoidVolumeBounds>(trap->getDxdyndzp(),
114  trap->getDxdyndzn(),
115  trap->getDydzn(),
116  trap->getZHalfLength());
117  } else {
118  volBounds = std::make_unique<TrapezoidVolumeBounds>(trap->getDxdyndzn(),
119  trap->getDxdyndzp(),
120  trap->getDydzn(),
121  trap->getZHalfLength());
122  }
123  return std::make_unique<Volume>(makeTransform(transf), volBounds.release());
124  } else if (sh->type() == "Pgon") {
125  const GeoPgon* pgon = dynamic_cast<const GeoPgon*>(sh);
126  double hlz = 0.5 * std::abs(pgon->getZPlane(1) - pgon->getZPlane(0));
127  double phiH = pgon->getDPhi() / (2. * pgon->getNSides());
128  double hly = 0.5 * std::cos(phiH) * (pgon->getRMaxPlane(0) - pgon->getRMinPlane(0));
129  double dly = 0.5 * std::cos(phiH) * (pgon->getRMaxPlane(0) + pgon->getRMinPlane(0));
130  double hlxmin = pgon->getRMinPlane(0) * std::sin(phiH);
131  double hlxmax = pgon->getRMaxPlane(0) * std::sin(phiH);
132  if (pgon->getDPhi() == 2 * M_PI) {
133 
134  auto volBounds = std::make_unique<CylinderVolumeBounds>(pgon->getRMaxPlane(0), hlz);
135  auto subBounds = std::make_unique<CuboidVolumeBounds>(hlxmax + tol, hlxmax + tol,
136  hlz + tol);
137  auto volume = std::make_unique<Volume>(makeTransform(transf), volBounds.release());
138  auto bVol = std::make_unique<Volume>(nullptr, subBounds.release());
139  const unsigned int nsides(pgon->getNSides());
140  const double twicePhiH(2.0 * phiH);
141  const double xTranslationDistance = hlxmax + std::cos(phiH) * (pgon->getRMaxPlane(0));
142 
143  const Amg::Translation3D xTranslation{xTranslationDistance, 0., 0.};
144  for (unsigned int i = 0; i < nsides; i++) {
145  const double angle = i * twicePhiH;
146  Amg::Transform3D totalTransform = transf * Amg::getRotateZ3D(angle) * xTranslation;
147  auto volS = std::make_unique<Volume>(*bVol, totalTransform);
148  auto combBounds =std::make_unique<SubtractedVolumeBounds>(volume.release(),
149  volS.release());
150  volume = std::make_unique<Volume>(nullptr, combBounds.release());
151  }
152  return volume;
153  }
154 
155  if (pgon->getNSides() == 1) {
156  auto volBounds = std::make_unique<TrapezoidVolumeBounds>(hlxmin, hlxmax, hly, hlz);
157  Amg::Transform3D totalTransform = transf *
158  Amg::getRotateZ3D(m90deg) *
159  Amg::Translation3D(0., dly, 0.);
160  return std::make_unique<Volume>(makeTransform(totalTransform),
161  volBounds.release());
162  }
163 
164  if (pgon->getNSides() == 2) {
165  auto cylBounds = std::make_unique<CylinderVolumeBounds>(0, dly + hly, hlz);
166  return std::make_unique<Volume>(makeTransform(transf),
167  cylBounds.release());
168  }
169  return vol;
170  } else if (sh->type() == "Trd") {
171  const GeoTrd* trd = dynamic_cast<const GeoTrd*>(sh);
172  //
173  double x1 = trd->getXHalfLength1();
174  double x2 = trd->getXHalfLength2();
175  double y1 = trd->getYHalfLength1();
176  double y2 = trd->getYHalfLength2();
177  double z = trd->getZHalfLength();
178  //
179  ATH_MSG_DEBUG(" Trd x1 " << x1 << " x2 " << x2 << " y1 " << y1 << " y2 "
180  << y2 << " z " << z);
181  // Note this flip comes from the y axis in Tracking -> z axis in
182  // Geomodel
183  if (y1 == y2) {
184  if (x1 <= x2) {
185  auto volBounds = std::make_unique<TrapezoidVolumeBounds>(x1, x2, z, y1);
186  Amg::Transform3D totalTransform = transf * Amg::getRotateX3D(p90deg);
187  ATH_MSG_DEBUG(" Trd new volume case 1 Trapezoid minHalflengthX "
188  << volBounds->minHalflengthX()
189  << " maxHalflengthX() "
190  << volBounds->maxHalflengthX());
191  vol = std::make_unique<Volume>(makeTransform(totalTransform),
192  volBounds.release());
193 
194 
195  } else {
196 
197  auto volBounds = std::make_unique<TrapezoidVolumeBounds>(x2, x1, z, y1);
198  Amg::Transform3D totalTransform = transf *
199  Amg::getRotateY3D(p180deg) *
200  Amg::getRotateZ3D(p180deg);
201 
202  if (msgLvl(MSG::DEBUG)) {
203  const Amg::Vector3D top{-x1, y1, z}, bottom{-x2, y1, -z},
204  top2{x1, y1, z}, bottom2{x2, y1, -z};
205  ATH_MSG_DEBUG(" Trd new volume case 2 Trapezoid minHalflengthX "
206  << volBounds->minHalflengthX() << " maxHalflengthX() "
207  << volBounds->maxHalflengthX());
208  ATH_MSG_DEBUG(" Original topLocal " << Amg::toString(top) << " Radius " << top.perp());
209  ATH_MSG_DEBUG(" Original bottomLocal "<< Amg::toString(bottom) << " Radius " << bottom.perp());
210  Amg::Vector3D topG{transf * top}, bottomG{transf * bottom};
211  ATH_MSG_DEBUG(" top Global " << Amg::toString(topG)<< " Radius " << topG.perp());
212  ATH_MSG_DEBUG(" bottom Global " << Amg::toString(bottomG)<< " Radius "<< bottomG.perp());
213  topG = transf * top2;
214  bottomG = transf * bottom2;
215  ATH_MSG_DEBUG(" top2 Global x " << Amg::toString(topG)<< " Radius " << topG.perp());
216  ATH_MSG_DEBUG(" bottom2 Global " << Amg::toString(bottomG) << " Radius: " << bottomG.perp());
217  const Amg::Vector3D topR{-x2, z, y1}, bottomR{-x1, -z, y1},
218  top2R{x2, z, y1}, bottom2R{x1, -z, y1};
219  topG = totalTransform * topR;
220  bottomG = totalTransform * bottomR;
221  ATH_MSG_DEBUG(" topR Global " << Amg::toString(topG)<< " Radius " << topG.perp());
222  ATH_MSG_DEBUG(" bottomR Global " << Amg::toString(bottomG)<< " Radius "<< bottomG.perp());
223  topG = totalTransform * top2R;
224  bottomG = totalTransform * bottom2R;
225  ATH_MSG_DEBUG(" top2R Global " << Amg::toString(topG) << " Radius "<< topG.perp());
226  ATH_MSG_DEBUG(" bottom2R Global " << Amg::toString(bottomG)<< " Radius "<< bottomG.perp());
227 
228  ATH_MSG_DEBUG(" Original bottomLocal "<< Amg::toString(bottom) << " Radius "<< bottom.perp());
229  ATH_MSG_DEBUG(" topLocal x " << Amg::toString(topR)<< " Radius " << topR.perp());
230  topG = Amg::getRotateY3D(p180deg) * topR;
231  ATH_MSG_DEBUG(" topLocal Y Flip " << Amg::toString(topG)<< " Radius " << topG.perp());
232  topG = Amg::getRotateY3D(p180deg) * topR;
233  ATH_MSG_DEBUG(" topLocal X Flip " << Amg::toString(topG) << " Radius "<< topG.perp());
234  topG = Amg::getRotateZ3D(p90deg) * topR;
235  ATH_MSG_DEBUG(" topLocal XY Flip " << Amg::toString(topG) << " Radius " << topG.perp());
236  topG = Amg::getRotateY3D(p180deg) * topR;
237  ATH_MSG_DEBUG(" topLocal YZ Flip " << Amg::toString(topG) << " Radius " << topG.perp());
238  topG = Amg::getRotateY3D(p90deg) * topR;
239  ATH_MSG_DEBUG(" topLocal XZ Flip " << Amg::toString(topG) << " Radius " << topG.perp());
240  topG = Amg::getRotateY3D(p180deg) * topR;
241  ATH_MSG_DEBUG(" topLocal XY sign Flip x "<< Amg::toString(topG) << " Radius " << topG.perp());
242  }
243  vol = std::make_unique<Volume>(makeTransform(totalTransform),
244  volBounds.release());
245  }
246  return vol;
247  } else if (x1 == x2) {
248  if (y1 < y2) {
249  std::unique_ptr<TrapezoidVolumeBounds> volBounds =
250  std::make_unique<TrapezoidVolumeBounds>(y1, y2, z, x1);
251  ATH_MSG_DEBUG(" Trd new volume case 3 Trapezoid minHalflengthX "
252  << volBounds->minHalflengthX()<< " maxHalflengthX() "
253  << volBounds->maxHalflengthX());
254  Amg::Transform3D totalTransform = transf *
255  Amg::getRotateZ3D(p90deg) *
256  Amg::getRotateX3D(p90deg);
257  vol = std::make_unique<Volume>(makeTransform(totalTransform),
258  volBounds.release());
259 
260  } else {
261  auto volBounds = std::make_unique<TrapezoidVolumeBounds>(y2, y1, z, x1);
262  ATH_MSG_DEBUG(" Trd new volume case 4 Trapezoid minHalflengthX "
263  << volBounds->minHalflengthX()
264  << " maxHalflengthX() "<< volBounds->maxHalflengthX());
265 
266  Amg::Transform3D totalTransform = transf *
267  Amg::getRotateX3D(p180deg) *
268  Amg::getRotateZ3D(p90deg) *
269  Amg::getRotateX3D(p90deg);
270  vol = std::make_unique<Volume>(makeTransform(totalTransform),
271  volBounds.release());
272  }
273  return vol;
274  } else {
275  ATH_MSG_WARNING("PROBLEM: translating trapezoid: not recognized:"
276  << x1 << "," << x2 << "," << y1 << "," << y2 << ","<< z);
277  }
278  } else if (sh->type() == "Box") {
279  const GeoBox* box = dynamic_cast<const GeoBox*>(sh);
280  //
281  double x = box->getXHalfLength();
282  double y = box->getYHalfLength();
283  double z = box->getZHalfLength();
284  std::unique_ptr<CuboidVolumeBounds> volBounds = std::make_unique<CuboidVolumeBounds>(x, y, z);
285  return std::make_unique<Volume>(makeTransform(transf), volBounds.release());
286  } else if (sh->type() == "Para") {
287  const GeoPara* para = dynamic_cast<const GeoPara*>(sh);
288  //
289  double x = para->getXHalfLength();
290  double y = para->getYHalfLength();
291  double z = para->getZHalfLength();
292  auto volBounds = std::make_unique<CuboidVolumeBounds>(x, y, z);
293  return std::make_unique<Volume>(makeTransform(transf), volBounds.release());
294  //
295  } else if (sh->type() == "Tube") {
296  const GeoTube* tube = dynamic_cast<const GeoTube*>(sh);
297  return std::make_unique<Volume>(makeTransform(transf), convert(tube).release());
298  } else if (sh->type() == "Tubs") { // non-trivial case - transform!
299  const GeoTubs* tubs = dynamic_cast<const GeoTubs*>(sh);
300  double rMin = tubs->getRMin();
301  double rMax = tubs->getRMax();
302  double z = tubs->getZHalfLength();
303  double aPhi = tubs->getSPhi();
304  double dPhi = tubs->getDPhi();
305  auto volBounds = std::make_unique<CylinderVolumeBounds>(rMin, rMax, 0.5 * dPhi, z);
306  Amg::Transform3D totalTransform(transf * Amg::getRotateZ3D(aPhi + 0.5 * dPhi));
307  return std::make_unique<Volume>(makeTransform(totalTransform), volBounds.release());
308  } else if (sh->type() == "Cons") {
309  const GeoCons* cons = dynamic_cast<const GeoCons*>(sh);
310  double rMin1 = cons->getRMin1();
311  double rMin2 = cons->getRMin2();
312  double rMax1 = cons->getRMax1();
313  double rMax2 = cons->getRMax2();
314  double z = cons->getDZ();
315  double aPhi = cons->getSPhi();
316  double dPhi = cons->getDPhi();
317  // translate into tube with average radius
318  if (dPhi == 2 * M_PI) {
319  auto volBounds =std::make_unique<CylinderVolumeBounds>(0.5 * (rMin1 + rMin2),
320  0.5 * (rMax1 + rMax2), z);
321  return std::make_unique<Volume>(makeTransform(transf),
322  volBounds.release());
323  } else {
324  auto volBounds =std::make_unique<CylinderVolumeBounds>(0.5 * (rMin1 + rMin2),
325  0.5 * (rMax1 + rMax2),
326  0.5 * dPhi, z);
327  Amg::Transform3D totalTransform = transf * Amg::getRotateZ3D(aPhi + 0.5 * dPhi);
328  return std::make_unique<Volume>(makeTransform(totalTransform),
329  volBounds.release());
330  }
331  } else if (sh->type() == "Pcon") {
332  const GeoPcon* con = dynamic_cast<const GeoPcon*>(sh);
333  std::unique_ptr<CylinderVolumeBounds> volBounds{};
334  double aPhi = con->getSPhi();
335  double dPhi = con->getDPhi();
336  double z1 = con->getZPlane(0);
337  double r1 = con->getRMinPlane(0);
338  double R1 = con->getRMaxPlane(0);
339  std::vector<std::unique_ptr<Volume>> cyls;
340  const unsigned int nPlanes = con->getNPlanes();
341  ATH_MSG_DEBUG(" convert pcon aPhi " << aPhi << " dPhi " << dPhi << " z1 " << z1 << " r1 "
342  << r1 << " R1 " << R1 << " nPlanes " << nPlanes);
343  for (unsigned int iv = 1; iv < nPlanes; iv++) {
344  double z2 = con->getZPlane(iv);
345  double r2 = con->getRMinPlane(iv);
346  double R2 = con->getRMaxPlane(iv);
347  double zshift = 0.5 * (z1 + z2);
348  double hz = 0.5 * std::abs(z1 - z2);
349  double rmin = std::max(r1, r2);
350  double rmax = std::sqrt((R1 * R1 + R1 * R2 + R2 * R2 - r1 * r1 - r1 * r2 - r2 * r2) / 3 + rmin * rmin);
351  ATH_MSG_DEBUG(" iPlane " << iv << " z2 " << z2 << " r2 " << r2 << " R2 " << R2 << " zshift " << zshift
352  << " hz " << hz << " rmin " << rmin << " rmax " << rmax);
353  double dz = con->getZPlane(iv) - con->getZPlane(iv - 1);
354  double drMin = con->getRMinPlane(iv) - con->getRMinPlane(iv - 1);
355  double drMax = con->getRMaxPlane(iv) - con->getRMaxPlane(iv - 1);
356  int nSteps = 1;
357  if (std::abs(dz) > 1 && (std::abs(drMin) > 0.1 * std::abs(dz) ||
358  std::abs(drMax) > 0.1 * std::abs(dz))) {
359  double dMax = std::abs(dz);
360  dMax = std::max(std::abs(drMin), dMax);
361  dMax = std::max(std::abs(drMax), dMax);
362  nSteps = std::clamp(dMax / 50., 2., 20.);
363  ATH_MSG_DEBUG(" Now "
364  << nSteps << " cylinders should be created " << dz
365  << " drMin " << drMin << " drMax " << drMax
366  << " splopeMin " << drMin / dz << " slopeMax "
367  << drMax / dz);
368  }
369  for (int j = 0; j < nSteps; j++) {
371  double zStep = (0.5 + j) * dz / nSteps;
372  if (nSteps > 1) {
373  hz = 0.5 * std::abs(z1 - z2) / nSteps;
374  zshift = z1 + zStep;
375  rmin = r1 + drMin * zStep / dz;
376  rmax = R1 + drMax * zStep / dz;
377  }
378  ATH_MSG_DEBUG(" cylinder " << j << " zshift " << zshift
379  << " rmin " << rmin << " rmax "
380  << rmax << " hz " << hz);
381  // translate into tube sector
382  if (dPhi == 2 * M_PI) {
383  volBounds = std::make_unique<CylinderVolumeBounds>(rmin, rmax, hz);
384  Amg::Transform3D totalTransform = transf * Amg::Translation3D{0., 0., zshift};
385  cyls.emplace_back(std::make_unique<Volume>(makeTransform(totalTransform),
386  volBounds.release()));
387  } else {
388  volBounds = std::make_unique<CylinderVolumeBounds>(rmin, rmax, 0.5 * dPhi, hz);
389  Amg::Transform3D totalTransform = transf * Amg::Translation3D{0., 0., zshift} *
390  Amg::getRotateZ3D(aPhi + 0.5 * dPhi);
391  cyls.emplace_back(std::make_unique<Volume>(makeTransform(totalTransform),
392  volBounds.release()));
393  }
394  } // end loop over steps
395  z1 = z2;
396  r1 = r2;
397  R1 = R2;
398  }
399 
400  if (cyls.size() < 2) {
401  return std::move(cyls[0]);
402  } else {
403  auto comb =std::make_unique<CombinedVolumeBounds>(cyls[0].release(), cyls[1].release(), false);
404  std::unique_ptr<Volume> combVol = std::make_unique<Volume>(nullptr, comb.release());
405  for (unsigned int ic = 2; ic < cyls.size(); ++ic) {
406  comb = std::make_unique<CombinedVolumeBounds>(combVol.release(), cyls[ic].release(), false);
407  combVol = std::make_unique<Volume>(nullptr, comb.release());
408  }
409  return combVol;
410  }
411  } else if (sh->type() == "SimplePolygonBrep") {
412  const GeoSimplePolygonBrep* spb = dynamic_cast<const GeoSimplePolygonBrep*>(sh);
413  unsigned int nv = spb->getNVertices();
414  std::vector<std::pair<double, double>> ivtx(nv);
415  for (unsigned int iv = 0; iv < nv; iv++) {
416  ivtx[iv] = std::make_pair(spb->getXVertex(iv), spb->getYVertex(iv));
417  ATH_MSG_DEBUG(" SimplePolygonBrep x "<< spb->getXVertex(iv) << " y " << spb->getYVertex(iv)
418  << " z " << spb->getDZ());
419  }
420  // translate into trapezoid or double trapezoid if possible
421  if (nv == 4 || nv == 6) {
422  std::vector<double> xstep;
423  std::vector<std::pair<double, double>> ystep;
424  bool trdlike = true;
425  for (unsigned int iv = 0; iv < nv; ++iv) {
426  if (ystep.empty() || spb->getYVertex(iv) > ystep.back().first)
427  ystep.emplace_back(spb->getYVertex(iv),
428  std::abs(spb->getXVertex(iv)));
429  else {
430  std::vector<std::pair<double, double>>::iterator iy = ystep.begin();
431  while (iy + 1 < ystep.end() &&
432  spb->getYVertex(iv) > (*iy).first + 1.e-3) {
433  ++iy;
434  }
435  if (spb->getYVertex(iv) < (*iy).first - 1.e-3) {
436  ystep.insert(iy, std::make_pair(spb->getYVertex(iv), std::abs(spb->getXVertex(iv))));
437  } else if (spb->getYVertex(iv) == (*iy).first &&
438  std::abs(spb->getXVertex(iv)) != (*iy).second) {
439  trdlike = false;
440  }
441  }
442  }
443 
444  if (trdlike) {
445  std::unique_ptr<VolumeBounds> volBounds{};
446  if (nv == 4) {
447  if (ystep[1].second >= ystep[0].second) { // expected ordering
448  volBounds = std::make_unique<TrapezoidVolumeBounds>(ystep[0].second,
449  ystep[1].second,
450  0.5 * (ystep[1].first - ystep[0].first),
451  spb->getDZ());
452  return std::make_unique<Volume>(makeTransform(transf),
453  volBounds.release());
454  }
455  }
456 
457  if (nv == 6) {
458  if (ystep[1].second >= ystep[0].second &&
459  ystep[2].second >= ystep[1].second) { // expected ordering
460  volBounds = std::make_unique<DoubleTrapezoidVolumeBounds>(ystep[0].second,
461  ystep[1].second,
462  ystep[2].second,
463  0.5 * (ystep[1].first - ystep[0].first),
464  0.5 * (ystep[2].first - ystep[1].first),
465  spb->getDZ());
466  return std::make_unique<Volume>(makeTransform(transf * Amg::Translation3D(0., ystep[1].first, 0.)),
467  volBounds.release());
468  }
469  }
470  } // not trd-like
471  }
472  auto newBounds = std::make_unique<SimplePolygonBrepVolumeBounds>(ivtx, spb->getDZ());
473  return std::make_unique<Volume>(makeTransform(transf),
474  newBounds.release());
475  }
476 
477  else if (sh->type() == "Subtraction") {
478  const GeoShapeSubtraction* sub = dynamic_cast<const GeoShapeSubtraction*>(sh);
479 
480  const GeoShape* shA = sub->getOpA();
481  const GeoShape* shB = sub->getOpB();
482  std::unique_ptr<Volume> volA = translateGeoShape(shA, transf);
483  std::unique_ptr<Volume> volB = translateGeoShape(shB, transf);
484  auto volBounds = std::make_unique<SubtractedVolumeBounds>(volA.release(),
485  volB.release());
486  return std::make_unique<Volume>(nullptr, volBounds.release());
487  } else if (sh->type() == "Union") {
488  const GeoShapeUnion* uni = dynamic_cast<const GeoShapeUnion*>(sh);
489  const GeoShape* shA = uni->getOpA();
490  const GeoShape* shB = uni->getOpB();
491  std::unique_ptr<Volume> volA = translateGeoShape(shA, transf);
492  std::unique_ptr<Volume> volB = translateGeoShape(shB, transf);
493  auto volBounds = std::make_unique<CombinedVolumeBounds>(volA.release(),
494  volB.release(), false);
495  return std::make_unique<Volume>(nullptr, volBounds.release());
496  } else if (sh->type() == "Intersection") {
497  const GeoShapeIntersection* intersect = dynamic_cast<const GeoShapeIntersection*>(sh);
498 
499  const GeoShape* shA = intersect->getOpA();
500  const GeoShape* shB = intersect->getOpB();
501  std::unique_ptr<Volume> volA{translateGeoShape(shA, transf)};
502  std::unique_ptr<Volume> volB{translateGeoShape(shB, transf)};
503  auto volBounds = std::make_unique<CombinedVolumeBounds>(volA.release(),
504  volB.release(), true);
505  return std::make_unique<Volume>(nullptr, volBounds.release());
506  }
507 
508  if (sh->type() == "Shift") {
509  const GeoShapeShift* shift = dynamic_cast<const GeoShapeShift*>(sh);
510  return translateGeoShape(shift->getOp(), transf * shift->getX());
511  }
512  ATH_MSG_WARNING("shape " << sh->type() << " not recognized, return 0");
513  return nullptr;
514 }

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::atomic_flag m_initialized AthMessaging::ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
mutableprivateinherited

Messaging initialized (initMessaging)

Definition at line 141 of file AthMessaging.h.

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels)

Definition at line 132 of file AthMessaging.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.


The documentation for this class was generated from the following files:
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
AthMessaging::m_lvl
std::atomic< MSG::Level > m_lvl
Current logging level.
Definition: AthMessaging.h:138
Trk::y
@ y
Definition: ParamDefs.h:62
Muon::makeTransform
Amg::Transform3D * makeTransform(const Amg::Transform3D &trf)
Definition: MuonSpectrometer/MuonDetDescr/MuonTrackingGeometry/MuonTrackingGeometry/Utils.h:14
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
top
TopConfig A simple configuration that is NOT a singleton.
Definition: AnalysisTrackingHelper.cxx:58
max
#define max(a, b)
Definition: cfImp.cxx:41
Trk::z
@ z
global position (cartesian)
Definition: ParamDefs.h:63
plotBeamSpotCompare.x2
x2
Definition: plotBeamSpotCompare.py:218
M_PI
#define M_PI
Definition: ActiveFraction.h:11
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
MCP::ScaleSmearParam::r2
@ r2
AthMessaging::m_imsg
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
Definition: AthMessaging.h:135
python.SystemOfUnits.ms
int ms
Definition: SystemOfUnits.py:132
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
makeTRTBarrelCans.y1
tuple y1
Definition: makeTRTBarrelCans.py:15
Amg::getRotateZ3D
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Definition: GeoPrimitivesHelpers.h:270
Amg::getRotateX3D
Amg::Transform3D getRotateX3D(double angle)
get a rotation transformation around X-axis
Definition: GeoPrimitivesHelpers.h:252
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
TrigConf::MSGTC::Level
Level
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStream.h:21
AthMessaging::msgLvl
bool msgLvl(const MSG::Level lvl) const
Test the output level.
Definition: AthMessaging.h:151
FullCPAlgorithmsTest_eljob.sh
sh
Definition: FullCPAlgorithmsTest_eljob.py:98
lumiFormat.i
int i
Definition: lumiFormat.py:92
RCU::Shell
Definition: ShellExec.cxx:28
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
angle
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Definition: TRTDetectorFactory_Full.cxx:73
makeTRTBarrelCans.y2
tuple y2
Definition: makeTRTBarrelCans.py:18
TauGNNUtils::Variables::Track::dPhi
bool dPhi(const xAOD::TauJet &tau, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:530
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
checkCorrelInHIST.nSteps
int nSteps
Definition: checkCorrelInHIST.py:458
Trk::GeoShapeConverter::decodeShape
void decodeShape(const GeoShape *) const
Decode and dump arbitrary GeoShape for visual inspection.
Definition: GeoShapeConverter.cxx:516
AthMessaging::msg
MsgStream & msg() const
The standard message stream.
Definition: AthMessaging.h:164
min
#define min(a, b)
Definition: cfImp.cxx:40
grepfile.ic
int ic
Definition: grepfile.py:33
python.EventInfoMgtInit.release
release
Definition: EventInfoMgtInit.py:24
Amg::getRotateY3D
Amg::Transform3D getRotateY3D(double angle)
get a rotation transformation around Y-axis
Definition: GeoPrimitivesHelpers.h:261
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::GeoShapeConverter::translateGeoShape
std::unique_ptr< Volume > translateGeoShape(const GeoShape *shape, const Amg::Transform3D &trf) const
Convert an arbitrary GeoShape into Trk::Volume.
Definition: GeoShapeConverter.cxx:102
Trk::GeoShapeConverter::convert
static std::unique_ptr< CylinderVolumeBounds > convert(const GeoTubs *gtub)
Convert a tubs.
Definition: GeoShapeConverter.cxx:57
Amg::intersect
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the closest approach of two lines.
Definition: GeoPrimitivesHelpers.h:302
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
AthMessaging::m_nm
std::string m_nm
Message source name.
Definition: AthMessaging.h:129
DeMoScan.first
bool first
Definition: DeMoScan.py:534
DEBUG
#define DEBUG
Definition: page_access.h:11
Amg::Translation3D
Eigen::Translation< double, 3 > Translation3D
Definition: GeoPrimitives.h:44
fitman.hz
def hz
Definition: fitman.py:516
AthMessaging::initMessaging
void initMessaging() const
Initialize our message level and MessageSvc.
Definition: AthMessaging.cxx:39
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Trk::x
@ x
Definition: ParamDefs.h:61
MCP::ScaleSmearParam::r1
@ r1
AthMessaging::m_msg_tls
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels)
Definition: AthMessaging.h:132
calibdata.tube
tube
Definition: calibdata.py:31