File indexing completed on 2025-01-18 09:14:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include "DDRec/Surface.h"
0014 #include "DD4hep/detail/DetectorInterna.h"
0015 #include "DD4hep/Memory.h"
0016
0017 #include "DDRec/MaterialManager.h"
0018
0019 #include <cmath>
0020 #include <memory>
0021 #include <exception>
0022
0023 #include "TGeoMatrix.h"
0024 #include "TGeoShape.h"
0025 #include "TRotation.h"
0026
0027 #include "TGeoTrd1.h"
0028
0029 namespace dd4hep {
0030 namespace rec {
0031
0032 using namespace detail ;
0033
0034
0035
0036
0037 void VolSurfaceBase::setU(const Vector3D& u_val) { _u = u_val ; }
0038 void VolSurfaceBase::setV(const Vector3D& v_val) { _v = v_val ; }
0039 void VolSurfaceBase::setNormal(const Vector3D& n) { _n = n ; }
0040 void VolSurfaceBase::setOrigin(const Vector3D& o) { _o = o ; }
0041
0042 long64 VolSurfaceBase::id() const { return _id ; }
0043
0044 const SurfaceType& VolSurfaceBase::type() const { return _type ; }
0045 Vector3D VolSurfaceBase::u(const Vector3D& ) const { return _u ; }
0046 Vector3D VolSurfaceBase::v(const Vector3D& ) const { return _v ; }
0047 Vector3D VolSurfaceBase::normal(const Vector3D& ) const { return _n ; }
0048 const Vector3D& VolSurfaceBase::origin() const { return _o ;}
0049
0050 Vector2D VolSurfaceBase::globalToLocal( const Vector3D& point) const {
0051
0052 Vector3D p = point - origin() ;
0053
0054
0055
0056
0057 double uv = u() * v() ;
0058 Vector3D uprime = ( u() - uv * v() ).unit() ;
0059 Vector3D vprime = ( v() - uv * u() ).unit() ;
0060 double uup = u() * uprime ;
0061 double vvp = v() * vprime ;
0062
0063 return Vector2D( p*uprime / uup , p*vprime / vvp ) ;
0064 }
0065
0066 Vector3D VolSurfaceBase::localToGlobal( const Vector2D& point) const {
0067
0068 Vector3D g = origin() + point[0] * u() + point[1] * v() ;
0069
0070 return g ;
0071 }
0072
0073 const IMaterial& VolSurfaceBase::innerMaterial() const{ return _innerMat ; }
0074 const IMaterial& VolSurfaceBase::outerMaterial() const { return _outerMat ; }
0075 double VolSurfaceBase::innerThickness() const { return _th_i ; }
0076 double VolSurfaceBase::outerThickness() const { return _th_o ; }
0077
0078
0079 double VolSurfaceBase::length_along_u() const {
0080
0081 const Vector3D& o = this->origin() ;
0082 const Vector3D& u_val = this->u( o ) ;
0083 Vector3D um = -1. * u_val ;
0084
0085 double dist_p = 0. ;
0086 double dist_m = 0. ;
0087
0088
0089
0090
0091
0092
0093 if( volume()->GetShape()->Contains( o.const_array() ) ){
0094
0095 dist_p = volume()->GetShape()->DistFromInside( const_cast<double*> ( o.const_array() ) ,
0096 const_cast<double*> ( u_val.const_array() ) ) ;
0097 dist_m = volume()->GetShape()->DistFromInside( const_cast<double*> ( o.const_array() ) ,
0098 const_cast<double*> ( um.array() ) ) ;
0099
0100
0101
0102
0103
0104
0105
0106
0107 } else{
0108
0109 dist_p = volume()->GetShape()->DistFromOutside( const_cast<double*> ( o.const_array() ) ,
0110 const_cast<double*> ( u_val.const_array() ) ) ;
0111 dist_m = volume()->GetShape()->DistFromOutside( const_cast<double*> ( o.const_array() ) ,
0112 const_cast<double*> ( um.array() ) ) ;
0113
0114 dist_p *= 1.0001 ;
0115 dist_m *= 1.0001 ;
0116
0117
0118
0119
0120
0121
0122 Vector3D o_1 = this->origin() + dist_p * u_val ;
0123 Vector3D o_2 = this->origin() + dist_m * um ;
0124
0125 dist_p += volume()->GetShape()->DistFromInside( const_cast<double*> ( o_1.const_array() ) ,
0126 const_cast<double*> ( u_val.const_array() ) ) ;
0127
0128 dist_m += volume()->GetShape()->DistFromInside( const_cast<double*> ( o_2.const_array() ) ,
0129 const_cast<double*> ( um.array() ) ) ;
0130
0131
0132
0133
0134
0135 }
0136
0137 return dist_p + dist_m ;
0138
0139
0140 }
0141
0142 double VolSurfaceBase::length_along_v() const {
0143
0144 const Vector3D& o = this->origin() ;
0145 const Vector3D& v_val = this->v( o ) ;
0146 Vector3D vm = -1. * v_val ;
0147
0148 double dist_p = 0. ;
0149 double dist_m = 0. ;
0150
0151
0152
0153
0154
0155
0156 if( volume()->GetShape()->Contains( o.const_array() ) ){
0157
0158 dist_p = volume()->GetShape()->DistFromInside( const_cast<double*> ( o.const_array() ) ,
0159 const_cast<double*> ( v_val.const_array() ) ) ;
0160 dist_m = volume()->GetShape()->DistFromInside( const_cast<double*> ( o.const_array() ) ,
0161 const_cast<double*> ( vm.array() ) ) ;
0162
0163
0164
0165
0166
0167
0168
0169
0170 } else{
0171
0172 dist_p = volume()->GetShape()->DistFromOutside( const_cast<double*> ( o.const_array() ) ,
0173 const_cast<double*> ( v_val.const_array() ) ) ;
0174 dist_m = volume()->GetShape()->DistFromOutside( const_cast<double*> ( o.const_array() ) ,
0175 const_cast<double*> ( vm.array() ) ) ;
0176
0177 dist_p *= 1.0001 ;
0178 dist_m *= 1.0001 ;
0179
0180
0181
0182
0183
0184
0185 Vector3D o_1 = this->origin() + dist_p * v_val ;
0186 Vector3D o_2 = this->origin() + dist_m * vm ;
0187
0188 dist_p += volume()->GetShape()->DistFromInside( const_cast<double*> ( o_1.const_array() ) ,
0189 const_cast<double*> ( v_val.const_array() ) ) ;
0190
0191 dist_m += volume()->GetShape()->DistFromInside( const_cast<double*> ( o_2.const_array() ) ,
0192 const_cast<double*> ( vm.array() ) ) ;
0193
0194
0195
0196
0197
0198 }
0199
0200 return dist_p + dist_m ;
0201
0202 }
0203
0204
0205 double VolSurfaceBase::distance(const Vector3D& ) const { return 1.e99 ; }
0206
0207
0208 bool VolSurfaceBase::insideBounds(const Vector3D& point, double epsilon) const {
0209
0210 #if 0
0211
0212 bool inShape = ( type().isUnbounded() ? true : volume()->GetShape()->Contains( point.const_array() ) ) ;
0213
0214 double dist = std::abs ( distance( point ) ) ;
0215
0216 std::cout << " ** Surface::insideBound( " << point << " ) - distance = " << dist
0217 << " origin = " << origin() << " normal = " << normal()
0218 << " p * n = " << point * normal()
0219 << " isInShape : " << inShape << std::endl ;
0220
0221 return dist < epsilon && inShape ;
0222 #else
0223
0224 if( type().isUnbounded() ){
0225
0226 return std::abs ( distance( point ) ) < epsilon ;
0227
0228 } else {
0229
0230 return ( std::abs ( distance( point ) ) < epsilon && volume()->GetShape()->Contains( point.const_array() ) ) ;
0231 }
0232
0233 #endif
0234
0235 }
0236
0237
0238 std::vector< std::pair<Vector3D, Vector3D> > VolSurfaceBase::getLines(unsigned ) {
0239
0240 std::vector< std::pair<Vector3D, Vector3D> > lines ;
0241 return lines ;
0242 }
0243
0244
0245
0246
0247 long64 VolSurface::id() const { return _surf->id() ; }
0248 const SurfaceType& VolSurface::type() const { return _surf->type() ; }
0249 Vector3D VolSurface::u( const Vector3D& point ) const { return _surf->u(point) ; }
0250 Vector3D VolSurface::v(const Vector3D& point ) const { return _surf->v(point) ; }
0251 Vector3D VolSurface::normal(const Vector3D& point ) const { return _surf->normal(point) ; }
0252 const Vector3D& VolSurface::origin() const { return _surf->origin() ;}
0253 Vector2D VolSurface::globalToLocal( const Vector3D& point) const { return _surf->globalToLocal( point ) ; }
0254 Vector3D VolSurface::localToGlobal( const Vector2D& point) const { return _surf->localToGlobal( point) ; }
0255 const IMaterial& VolSurface::innerMaterial() const{ return _surf->innerMaterial() ; }
0256 const IMaterial& VolSurface::outerMaterial() const { return _surf->outerMaterial() ; }
0257 double VolSurface::innerThickness() const { return _surf->innerThickness() ; }
0258 double VolSurface::outerThickness() const { return _surf->outerThickness() ; }
0259 double VolSurface::length_along_u() const { return _surf->length_along_u() ; }
0260 double VolSurface::length_along_v() const { return _surf->length_along_v() ; }
0261 double VolSurface::distance(const Vector3D& point ) const { return _surf->distance( point ) ; }
0262 bool VolSurface::insideBounds(const Vector3D& point, double epsilon) const {
0263 return _surf->insideBounds( point, epsilon ) ;
0264 }
0265 std::vector< std::pair<Vector3D, Vector3D> > VolSurface::getLines(unsigned nMax) {
0266 return _surf->getLines(nMax) ;
0267 }
0268
0269
0270
0271
0272 double VolPlaneImpl::distance(const Vector3D& point ) const {
0273 return ( point - origin() ) * normal() ;
0274 }
0275
0276
0277 VolCylinderImpl::VolCylinderImpl( Volume vol, SurfaceType typ,
0278 double thickness_inner ,double thickness_outer, Vector3D o ) :
0279
0280 VolSurfaceBase(typ, thickness_inner, thickness_outer, Vector3D() , Vector3D() , Vector3D() , o , vol, 0) {
0281 Vector3D v_val( 0., 0., 1. ) ;
0282 Vector3D o_rphi( o.x() , o.y() , 0. ) ;
0283 Vector3D n = o_rphi.unit() ;
0284 Vector3D u_val = v_val.cross( n ) ;
0285
0286 setU( u_val ) ;
0287 setV( v_val ) ;
0288 setNormal( n ) ;
0289
0290 _type.setProperty( SurfaceType::Plane , false ) ;
0291 _type.setProperty( SurfaceType::Cylinder , true ) ;
0292 _type.setProperty( SurfaceType::Cone , false ) ;
0293 _type.checkParallelToZ( *this ) ;
0294 _type.checkOrthogonalToZ( *this ) ;
0295 }
0296
0297 Vector3D VolCylinderImpl::u(const Vector3D& point ) const {
0298
0299 Vector3D n( 1. , point.phi() , 0. , Vector3D::cylindrical ) ;
0300
0301 return v().cross( n ) ;
0302 }
0303
0304 Vector3D VolCylinderImpl::normal(const Vector3D& point ) const {
0305
0306
0307 return Vector3D( 1. , point.phi() , 0. , Vector3D::cylindrical ) ;
0308 }
0309
0310 Vector2D VolCylinderImpl::globalToLocal( const Vector3D& point) const {
0311
0312
0313 double phi = point.phi() - origin().phi() ;
0314
0315 while( phi < -M_PI ) phi += 2.*M_PI ;
0316 while( phi > M_PI ) phi -= 2.*M_PI ;
0317
0318 return Vector2D( origin().rho() * phi, point.z() - origin().z() ) ;
0319 }
0320
0321
0322 Vector3D VolCylinderImpl::localToGlobal( const Vector2D& point) const {
0323
0324 double z = point.v() + origin().z() ;
0325 double phi = point.u() / origin().rho() + origin().phi() ;
0326
0327 while( phi < -M_PI ) phi += 2.*M_PI ;
0328 while( phi > M_PI ) phi -= 2.*M_PI ;
0329
0330 return Vector3D( origin().rho() , phi, z , Vector3D::cylindrical ) ;
0331 }
0332
0333
0334
0335 double VolCylinderImpl::distance(const Vector3D& point ) const {
0336
0337 return point.rho() - origin().rho() ;
0338 }
0339
0340
0341 VolConeImpl::VolConeImpl( Volume vol, SurfaceType typ,
0342 double thickness_inner ,double thickness_outer, Vector3D v_val, Vector3D o_val ) :
0343
0344 VolSurfaceBase(typ, thickness_inner, thickness_outer, Vector3D() , v_val , Vector3D() , Vector3D() , vol, 0) {
0345
0346 Vector3D o_rphi( o_val.x() , o_val.y() , 0. ) ;
0347
0348
0349 double dphi = v_val.phi() - o_rphi.phi() ;
0350 while( dphi < -M_PI ) dphi += 2.*M_PI ;
0351 while( dphi > M_PI ) dphi -= 2.*M_PI ;
0352
0353 if( std::fabs( dphi ) > 1e-6 ){
0354 std::stringstream sst ; sst << "VolConeImpl::VolConeImpl() - incompatibel vector v and o given "
0355 << v_val << " - " << o_val ;
0356 throw std::runtime_error( sst.str() ) ;
0357 }
0358
0359 double theta = v_val.theta() ;
0360
0361 Vector3D n( 1. , v_val.phi() , ( theta + M_PI/2. ) , Vector3D::spherical ) ;
0362 Vector3D u_val = v_val.cross( n ) ;
0363
0364 setU( u_val ) ;
0365 setOrigin( o_rphi ) ;
0366 setNormal( n ) ;
0367
0368
0369 _tanTheta = std::tan( theta ) ;
0370 double tipoffset = o_val.rho() / _tanTheta ;
0371 _ztip = o_val.z() - tipoffset ;
0372
0373 double dist_p = vol->GetShape()->DistFromInside( const_cast<double*> ( o_val.const_array() ) ,
0374 const_cast<double*> ( v_val.const_array() ) ) ;
0375 Vector3D vm = -1. * v_val ;
0376 double dist_m = vol->GetShape()->DistFromInside( const_cast<double*> ( o_val.const_array() ) ,
0377 const_cast<double*> ( vm.array() ) ) ;
0378
0379 double costh = std::cos( theta) ;
0380 _zt0 = tipoffset - dist_m * costh ;
0381 _zt1 = tipoffset + dist_p * costh ;
0382
0383
0384 _type.setProperty( SurfaceType::Plane , false ) ;
0385 _type.setProperty( SurfaceType::Cylinder, false ) ;
0386 _type.setProperty( SurfaceType::Cone , true ) ;
0387 _type.setProperty( SurfaceType::ParallelToZ, true ) ;
0388 _type.setProperty( SurfaceType::OrthogonalToZ, false ) ;
0389 }
0390
0391
0392 Vector3D VolConeImpl::v(const Vector3D& point ) const {
0393
0394 Vector3D av( 1. , point.phi() , _v.theta() , Vector3D::spherical ) ;
0395 return av ;
0396 }
0397
0398 Vector3D VolConeImpl::u(const Vector3D& point ) const {
0399
0400 const Vector3D& av = this->v( point ) ;
0401 const Vector3D& n = normal( point ) ;
0402 return av.cross( n ) ;
0403 }
0404
0405 Vector3D VolConeImpl::normal(const Vector3D& point ) const {
0406
0407 Vector3D n( 1. , point.phi() , _n.theta() , Vector3D::spherical ) ;
0408 return n ;
0409 }
0410
0411 Vector2D VolConeImpl::globalToLocal( const Vector3D& point) const {
0412
0413
0414 double phi = point.phi() - origin().phi() ;
0415
0416 while( phi < -M_PI ) phi += 2.*M_PI ;
0417 while( phi > M_PI ) phi -= 2.*M_PI ;
0418
0419
0420 double r = ( point.z() - _ztip ) * _tanTheta ;
0421
0422 return Vector2D( r*phi, ( point.z() - origin().z() ) / cos( _v.theta() ) ) ;
0423 }
0424
0425
0426 Vector3D VolConeImpl::localToGlobal( const Vector2D& point) const {
0427
0428 double z = point.v() * cos( _v.theta() ) + origin().z() ;
0429
0430 double r = ( z - _ztip ) * _tanTheta ;
0431
0432 double phi = point.u() / r + origin().phi() ;
0433
0434 while( phi < -M_PI ) phi += 2.*M_PI ;
0435 while( phi > M_PI ) phi -= 2.*M_PI ;
0436
0437 return Vector3D( r , phi, z , Vector3D::cylindrical ) ;
0438 }
0439
0440
0441
0442 double VolConeImpl::distance(const Vector3D& point ) const {
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460 double zp = point.z() - _ztip ;
0461 double r = point.rho() - zp * _tanTheta ;
0462 return r * std::cos( _v.theta() ) ;
0463
0464 }
0465
0466
0467 std::vector< std::pair<Vector3D, Vector3D> > VolConeImpl::getLines(unsigned nMax){
0468
0469 std::vector< std::pair<Vector3D, Vector3D> > lines ;
0470
0471 lines.reserve( nMax ) ;
0472
0473 double theta = v().theta() ;
0474 double half_length = 0.5 * length_along_v() * cos( theta ) ;
0475
0476 Vector3D zv( 0. , 0. , half_length ) ;
0477
0478 double dr = half_length * tan( theta ) ;
0479
0480 double r0 = origin().rho() - dr ;
0481 double r1 = origin().rho() + dr ;
0482
0483
0484 unsigned n = nMax / 4 ;
0485 double dPhi = 2.* ROOT::Math::Pi() / double( n ) ;
0486
0487 for( unsigned i = 0 ; i < n ; ++i ) {
0488
0489 Vector3D r0v0( r0*sin( i *dPhi ) , r0*cos( i *dPhi ) , 0. ) ;
0490 Vector3D r0v1( r0*sin( (i+1)*dPhi ) , r0*cos( (i+1)*dPhi ) , 0. ) ;
0491
0492 Vector3D r1v0( r1*sin( i *dPhi ) , r1*cos( i *dPhi ) , 0. ) ;
0493 Vector3D r1v1( r1*sin( (i+1)*dPhi ) , r1*cos( (i+1)*dPhi ) , 0. ) ;
0494
0495 Vector3D pl0 = zv + r1v0 ;
0496 Vector3D pl1 = zv + r1v1 ;
0497 Vector3D pl2 = -zv + r0v1 ;
0498 Vector3D pl3 = -zv + r0v0 ;
0499
0500 lines.emplace_back( pl0, pl1 );
0501 lines.emplace_back( pl1, pl2 );
0502 lines.emplace_back( pl2, pl3 );
0503 lines.emplace_back( pl3, pl0 );
0504 }
0505 return lines;
0506 }
0507
0508
0509
0510
0511 VolSurfaceList::~VolSurfaceList(){
0512
0513
0514
0515
0516 }
0517
0518
0519 SurfaceList::~SurfaceList(){
0520 if( _isOwner ) {
0521
0522 std::for_each(begin(), end(), detail::deleteObject<ISurface>);
0523 }
0524 }
0525
0526
0527
0528 VolSurfaceList* volSurfaceList( DetElement& det ) {
0529 VolSurfaceList* list = det.extension< VolSurfaceList >(false);
0530 if ( !list ) {
0531 list = det.addExtension<VolSurfaceList >(new VolSurfaceList);
0532 }
0533 return list ;
0534 }
0535
0536
0537
0538
0539 bool findVolume( PlacedVolume pv, Volume theVol, std::list< PlacedVolume >& volList ) {
0540
0541
0542 volList.emplace_back( pv ) ;
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553 if( pv.volume().ptr() == theVol.ptr() ) {
0554
0555 return true ;
0556
0557 } else {
0558
0559
0560
0561 const TGeoNode* node = pv.ptr();
0562
0563 if ( !node ) {
0564
0565
0566
0567 throw std::runtime_error("*** findVolume: Invalid placement: - node pointer Null ! " + std::string( pv.name() ) );
0568 }
0569
0570
0571
0572
0573 for (Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau) {
0574
0575 TGeoNode* daughter = node->GetDaughter(idau);
0576 PlacedVolume placement( daughter );
0577
0578 if ( !placement.data() ) {
0579 throw std::runtime_error("*** findVolume: Invalid not instrumented placement:"+std::string(daughter->GetName())
0580 +" [Internal error -- bad detector constructor]");
0581 }
0582
0583 PlacedVolume pv_dau( daughter );
0584
0585 if( findVolume( pv_dau , theVol , volList ) ) {
0586
0587
0588
0589 return true ;
0590 }
0591 }
0592
0593
0594
0595 volList.pop_back() ;
0596
0597 return false ;
0598
0599
0600 }
0601 }
0602
0603
0604
0605 Surface::Surface( DetElement det, VolSurface volSurf ) : _det( det) , _volSurf( volSurf ),
0606 _wtM() , _id( 0) , _type( _volSurf.type() ) {
0607
0608 initialize() ;
0609 }
0610
0611 long64 Surface::id() const { return _id ; }
0612
0613 const SurfaceType& Surface::type() const { return _type ; }
0614
0615 Vector3D Surface::u(const Vector3D& ) const { return _u ; }
0616 Vector3D Surface::v(const Vector3D& ) const { return _v ; }
0617 Vector3D Surface::normal(const Vector3D& ) const { return _n ; }
0618 const Vector3D& Surface::origin() const { return _o ;}
0619 double Surface::innerThickness() const { return _volSurf.innerThickness() ; }
0620 double Surface::outerThickness() const { return _volSurf.outerThickness() ; }
0621 double Surface::length_along_u() const { return _volSurf.length_along_u() ; }
0622 double Surface::length_along_v() const { return _volSurf.length_along_v() ; }
0623
0624
0625
0626 const IMaterial& Surface::innerMaterial() const {
0627
0628 const IMaterial& mat = _volSurf.innerMaterial() ;
0629
0630 if( ! ( mat.Z() > 0 ) ) {
0631
0632 MaterialManager matMgr( _det.placement().volume() ) ;
0633
0634 Vector3D p = _o - innerThickness() * _n ;
0635
0636 const MaterialVec& materials = matMgr.materialsBetween( _o , p ) ;
0637
0638 _volSurf.setInnerMaterial( materials.size() > 1 ?
0639 matMgr.createAveragedMaterial( materials ) :
0640 materials[0].first ) ;
0641 }
0642 return mat ;
0643 }
0644
0645 const IMaterial& Surface::outerMaterial() const {
0646
0647 const IMaterial& mat = _volSurf.outerMaterial() ;
0648
0649 if( ! ( mat.Z() > 0 ) ) {
0650
0651 MaterialManager matMgr( _det.placement().volume() ) ;
0652
0653 Vector3D p = _o + outerThickness() * _n ;
0654
0655 const MaterialVec& materials = matMgr.materialsBetween( _o , p ) ;
0656
0657 _volSurf.setOuterMaterial( materials.size() > 1 ?
0658 matMgr.createAveragedMaterial( materials ) :
0659 materials[0].first ) ;
0660 }
0661 return mat ;
0662 }
0663
0664
0665 Vector2D Surface::globalToLocal( const Vector3D& point) const {
0666
0667 Vector3D p = point - origin() ;
0668
0669
0670
0671
0672 double uv = u() * v() ;
0673 Vector3D uprime = ( u() - uv * v() ).unit() ;
0674 Vector3D vprime = ( v() - uv * u() ).unit() ;
0675 double uup = u() * uprime ;
0676 double vvp = v() * vprime ;
0677
0678 return Vector2D( p*uprime / uup , p*vprime / vvp ) ;
0679 }
0680
0681
0682 Vector3D Surface::localToGlobal( const Vector2D& point) const {
0683
0684 Vector3D g = origin() + point[0] * u() + point[1] * v() ;
0685 return g ;
0686 }
0687
0688
0689 Vector3D Surface::volumeOrigin() const {
0690
0691 double o_array[3] ;
0692
0693 _wtM->LocalToMaster ( Vector3D() , o_array ) ;
0694
0695 Vector3D o(o_array) ;
0696
0697 return o ;
0698 }
0699
0700
0701 double Surface::distance(const Vector3D& point ) const {
0702
0703 double pa[3] ;
0704 _wtM->MasterToLocal( point , pa ) ;
0705 Vector3D localPoint( pa ) ;
0706
0707 return _volSurf.distance( localPoint ) ;
0708 }
0709
0710 bool Surface::insideBounds(const Vector3D& point, double epsilon) const {
0711
0712 double pa[3] ;
0713 _wtM->MasterToLocal( point , pa ) ;
0714 Vector3D localPoint( pa ) ;
0715
0716 return _volSurf.insideBounds( localPoint , epsilon) ;
0717 }
0718
0719 void Surface::initialize() {
0720
0721
0722 std::list< PlacedVolume > pVList ;
0723 PlacedVolume pv = _det.placement() ;
0724 Volume theVol = _volSurf.volume() ;
0725
0726 if( ! findVolume( pv, theVol , pVList ) ){
0727 theVol = _volSurf.volume() ;
0728 std::stringstream sst ; sst << " ***** ERROR: Volume " << theVol.name() << " not found for DetElement " << _det.name() << " with surface " ;
0729 throw std::runtime_error( sst.str() ) ;
0730 }
0731
0732
0733 Alignment nominal = _det.nominal();
0734 const TGeoHMatrix& wm = nominal.worldTransformation() ;
0735
0736 #if 0
0737 wm.Print() ;
0738 for( std::list<PlacedVolume>::iterator it= pVList.begin(), n = pVList.end() ; it != n ; ++it ){
0739 PlacedVolume pv = *it ;
0740 TGeoMatrix* m = pv->GetMatrix();
0741 std::cout << " +++ matrix for placed volume : " << std::endl ;
0742 m->Print() ;
0743 }
0744 #endif
0745
0746
0747
0748
0749 std::unique_ptr<TGeoHMatrix> wtI( new TGeoHMatrix( wm ) ) ;
0750
0751
0752
0753 for( std::list<PlacedVolume>::iterator it = ++( pVList.begin() ) , n = pVList.end() ; it != n ; ++it ){
0754
0755 PlacedVolume pvol = *it ;
0756 TGeoMatrix* m = pvol->GetMatrix();
0757
0758
0759
0760
0761 wtI->Multiply( m );
0762 }
0763
0764
0765
0766 #if 0
0767 dd4hep_ptr<TGeoHMatrix> wt( new TGeoHMatrix( wtI->Inverse() ) ) ;
0768 wt->Print() ;
0769
0770 _wtM = std::move(wtI);
0771 #else
0772
0773
0774 _wtM = std::move(wtI);
0775 #endif
0776
0777
0778
0779
0780 double ua[3], va[3], na[3], oa[3] ;
0781
0782 _wtM->LocalToMasterVect( _volSurf.u() , ua ) ;
0783 _wtM->LocalToMasterVect( _volSurf.v() , va ) ;
0784 _wtM->LocalToMasterVect( _volSurf.normal() , na ) ;
0785 _wtM->LocalToMaster ( _volSurf.origin() , oa ) ;
0786
0787 _u.fill( ua ) ;
0788 _v.fill( va ) ;
0789 _n.fill( na ) ;
0790 _o.fill( oa ) ;
0791
0792
0793
0794
0795
0796
0797
0798
0799
0800
0801 if( ! _type.isCone() ) {
0802
0803
0804
0805 _type.checkParallelToZ( *this ) ;
0806
0807 _type.checkOrthogonalToZ( *this ) ;
0808 }
0809
0810
0811
0812
0813
0814 _id = ( _volSurf.id()==0 ? _det.volumeID() : _volSurf.id() ) ;
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830 }
0831
0832
0833 std::vector< std::pair<Vector3D, Vector3D> > Surface::getLines(unsigned nMax) {
0834
0835
0836 const static double epsilon = 1e-6 ;
0837
0838 std::vector< std::pair<Vector3D, Vector3D> > lines ;
0839
0840
0841
0842 const std::vector< std::pair<Vector3D, Vector3D> >& local_lines = _volSurf.getLines() ;
0843
0844 if( local_lines.size() > 0 ) {
0845 unsigned n=local_lines.size() ;
0846 lines.reserve( n ) ;
0847
0848 for( unsigned i=0;i<n;++i){
0849
0850 Vector3D av,bv;
0851 _wtM->LocalToMaster( local_lines[i].first , av.array() ) ;
0852 _wtM->LocalToMaster( local_lines[i].second , bv.array() ) ;
0853
0854 lines.emplace_back( av, bv );
0855 }
0856
0857 return lines ;
0858 }
0859
0860
0861
0862
0863 const Vector3D& lu = _volSurf.u() ;
0864
0865 const Vector3D& ln = _volSurf.normal() ;
0866 Vector3D lo = _volSurf.origin() ;
0867
0868 Volume vol = volume() ;
0869 const TGeoShape* shape = vol->GetShape() ;
0870
0871
0872 if( type().isPlane() ) {
0873
0874 if( shape->IsA() == TGeoBBox::Class() ) {
0875
0876 TGeoBBox* box = ( TGeoBBox* ) shape ;
0877
0878 Vector3D boxDim( box->GetDX() , box->GetDY() , box->GetDZ() ) ;
0879
0880
0881 bool isYZ = std::fabs( ln.x() - 1.0 ) < epsilon ;
0882 bool isXZ = std::fabs( ln.y() - 1.0 ) < epsilon ;
0883 bool isXY = std::fabs( ln.z() - 1.0 ) < epsilon ;
0884
0885
0886 if( isYZ || isXZ || isXY ) {
0887
0888
0889 unsigned uidx = 1 ;
0890 unsigned vidx = 2 ;
0891
0892 Vector3D ubl( 0., 1., 0. ) ;
0893 Vector3D vbl( 0., 0., 1. ) ;
0894
0895 if( isXZ ) {
0896
0897 ubl.fill( 1., 0., 0. ) ;
0898 vbl.fill( 0., 0., 1. ) ;
0899 uidx = 0 ;
0900 vidx = 2 ;
0901
0902 } else if( isXY ) {
0903
0904 ubl.fill( 1., 0., 0. ) ;
0905 vbl.fill( 0., 1., 0. ) ;
0906 uidx = 0 ;
0907 vidx = 1 ;
0908 }
0909
0910 Vector3D ub ;
0911 Vector3D vb ;
0912 _wtM->LocalToMasterVect( ubl , ub.array() ) ;
0913 _wtM->LocalToMasterVect( vbl , vb.array() ) ;
0914
0915 lines.reserve(4) ;
0916
0917 lines.emplace_back(_o + boxDim[ uidx ] * ub + boxDim[ vidx ] * vb , _o - boxDim[ uidx ] * ub + boxDim[ vidx ] * vb );
0918 lines.emplace_back(_o - boxDim[ uidx ] * ub + boxDim[ vidx ] * vb , _o - boxDim[ uidx ] * ub - boxDim[ vidx ] * vb );
0919 lines.emplace_back(_o - boxDim[ uidx ] * ub - boxDim[ vidx ] * vb , _o + boxDim[ uidx ] * ub - boxDim[ vidx ] * vb );
0920 lines.emplace_back(_o + boxDim[ uidx ] * ub - boxDim[ vidx ] * vb , _o + boxDim[ uidx ] * ub + boxDim[ vidx ] * vb );
0921
0922 return lines ;
0923 }
0924
0925 } else if( shape->InheritsFrom("TGeoTube") || shape->InheritsFrom("TGeoCone") ) {
0926
0927
0928
0929 if( type().isZDisk() ) {
0930
0931 if( lo.rho() > epsilon ) {
0932
0933 lo.x() = 0. ;
0934 lo.y() = 0. ;
0935 }
0936
0937 double zhalf = 0 ;
0938 double rmax1 = 0 ;
0939 double rmax2 = 0 ;
0940 double rmin1 = 0 ;
0941 double rmin2 = 0 ;
0942 if( shape->InheritsFrom("TGeoTube") ) {
0943 TGeoTube* tube = ( TGeoTube* ) shape ;
0944 zhalf = tube->GetDZ() ;
0945 rmax1 = tube->GetRmax() ;
0946 rmax2 = tube->GetRmax() ;
0947 rmin1 = tube->GetRmin() ;
0948 rmin2 = tube->GetRmin() ;
0949 } else {
0950 TGeoCone* cone = ( TGeoCone* ) shape ;
0951 zhalf = cone->GetDZ() ;
0952 rmax1 = cone->GetRmax1() ;
0953 rmax2 = cone->GetRmax2() ;
0954 rmin1 = cone->GetRmin1() ;
0955 rmin2 = cone->GetRmin2() ;
0956 }
0957
0958
0959
0960 double r0 = rmin1 + ( rmin2 - rmin1 ) / ( 2. * zhalf ) * ( zhalf + lo.z() ) ;
0961 double r1 = rmax1 + ( rmax2 - rmax1 ) / ( 2. * zhalf ) * ( zhalf + lo.z() ) ;
0962
0963
0964 unsigned n = nMax / 4 ;
0965 double dPhi = 2.* ROOT::Math::Pi() / double( n ) ;
0966
0967 for( unsigned i = 0 ; i < n ; ++i ) {
0968
0969 Vector3D rv00( r0*sin( i *dPhi ) , r0*cos( i *dPhi ) , 0. ) ;
0970 Vector3D rv01( r0*sin( (i+1)*dPhi ) , r0*cos( (i+1)*dPhi ) , 0. ) ;
0971
0972 Vector3D rv10( r1*sin( i *dPhi ) , r1*cos( i *dPhi ) , 0. ) ;
0973 Vector3D rv11( r1*sin( (i+1)*dPhi ) , r1*cos( (i+1)*dPhi ) , 0. ) ;
0974
0975
0976 Vector3D pl0 = lo + rv00 ;
0977 Vector3D pl1 = lo + rv01 ;
0978
0979 Vector3D pl2 = lo + rv10 ;
0980 Vector3D pl3 = lo + rv11 ;
0981
0982
0983 Vector3D pg0,pg1,pg2,pg3 ;
0984
0985 _wtM->LocalToMaster( pl0, pg0.array() ) ;
0986 _wtM->LocalToMaster( pl1, pg1.array() ) ;
0987 _wtM->LocalToMaster( pl2, pg2.array() ) ;
0988 _wtM->LocalToMaster( pl3, pg3.array() ) ;
0989
0990 lines.emplace_back( pg0, pg1 );
0991 lines.emplace_back( pg2, pg3 );
0992 }
0993
0994
0995
0996 n = 4 ; dPhi = 2.* ROOT::Math::Pi() / double( n ) ;
0997
0998 for( unsigned i = 0 ; i < n ; ++i ) {
0999
1000 Vector3D rv0( r0*sin( i * dPhi ) , r0*cos( i * dPhi ) , 0. ) ;
1001 Vector3D rv1( r1*sin( i * dPhi ) , r1*cos( i * dPhi ) , 0. ) ;
1002
1003 Vector3D pl0 = lo + rv0 ;
1004 Vector3D pl1 = lo + rv1 ;
1005
1006 Vector3D pg0,pg1 ;
1007
1008 _wtM->LocalToMaster( pl0, pg0.array() ) ;
1009 _wtM->LocalToMaster( pl1, pg1.array() ) ;
1010
1011 lines.emplace_back(pg0, pg1);
1012 }
1013
1014 }
1015
1016 return lines ;
1017 }
1018
1019 else if(shape->IsA() == TGeoTrap::Class()) {
1020 TGeoTrap* trapezoid = ( TGeoTrap* ) shape;
1021
1022 double dx1 = trapezoid->GetBl1();
1023 double dx2 = trapezoid->GetTl1();
1024 double dz = trapezoid->GetH1();
1025
1026
1027
1028 Vector3D ubl( 1., 0., 0. ) ;
1029 Vector3D vbl( 0., 1., 0. ) ;
1030
1031
1032 Vector3D ub ;
1033 Vector3D vb ;
1034 _wtM->LocalToMasterVect( ubl , ub.array() ) ;
1035 _wtM->LocalToMasterVect( vbl , vb.array() ) ;
1036
1037
1038 lines.reserve(4) ;
1039
1040 lines.emplace_back( _o + dx1 * ub - dz * vb , _o + dx2 * ub + dz * vb);
1041 lines.emplace_back( _o + dx2 * ub + dz * vb , _o - dx2 * ub + dz * vb);
1042 lines.emplace_back( _o - dx2 * ub + dz * vb , _o - dx1 * ub - dz * vb);
1043 lines.emplace_back( _o - dx1 * ub - dz * vb , _o + dx1 * ub - dz * vb);
1044
1045 return lines;
1046 }
1047
1048 else if(shape->IsA() == TGeoTrd1::Class()){
1049 TGeoTrd1* trapezoid = ( TGeoTrd1* ) shape;
1050
1051 double dx1 = trapezoid->GetDx1();
1052 double dx2 = trapezoid->GetDx2();
1053
1054 double dz = trapezoid->GetDz();
1055
1056
1057
1058
1059 Vector3D ubl( 1., 0., 0. ) ;
1060 Vector3D vbl( 0., 0., 1. ) ;
1061
1062
1063 Vector3D ub ;
1064 Vector3D vb ;
1065 _wtM->LocalToMasterVect( ubl , ub.array() ) ;
1066 _wtM->LocalToMasterVect( vbl , vb.array() ) ;
1067
1068
1069 lines.reserve(4) ;
1070
1071 lines.emplace_back( _o + dx1 * ub - dz * vb , _o + dx2 * ub + dz * vb);
1072 lines.emplace_back( _o + dx2 * ub + dz * vb , _o - dx2 * ub + dz * vb);
1073 lines.emplace_back( _o - dx2 * ub + dz * vb , _o - dx1 * ub - dz * vb);
1074 lines.emplace_back( _o - dx1 * ub - dz * vb , _o + dx1 * ub - dz * vb);
1075
1076 return lines;
1077 }
1078
1079 else if(shape->IsA() == TGeoTrd2::Class()){
1080 TGeoTrd2* trapezoid = ( TGeoTrd2* ) shape;
1081
1082 double dx1 = trapezoid->GetDx1();
1083 double dx2 = trapezoid->GetDx2();
1084
1085
1086 double dz = trapezoid->GetDz();
1087
1088
1089
1090
1091 Vector3D ubl( 1., 0., 0. ) ;
1092 Vector3D vbl( 0., 0., 1. ) ;
1093
1094
1095 Vector3D ub ;
1096 Vector3D vb ;
1097 _wtM->LocalToMasterVect( ubl , ub.array() ) ;
1098 _wtM->LocalToMasterVect( vbl , vb.array() ) ;
1099
1100
1101 lines.reserve(4) ;
1102
1103 lines.emplace_back( _o + dx1 * ub - dz * vb , _o + dx2 * ub + dz * vb);
1104 lines.emplace_back( _o + dx2 * ub + dz * vb , _o - dx2 * ub + dz * vb);
1105 lines.emplace_back( _o - dx2 * ub + dz * vb , _o - dx1 * ub - dz * vb);
1106 lines.emplace_back( _o - dx1 * ub - dz * vb , _o + dx1 * ub - dz * vb);
1107
1108 return lines;
1109 }
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119 lines.reserve( nMax ) ;
1120
1121 double dAlpha = 2.* ROOT::Math::Pi() / double( nMax ) ;
1122
1123 TVector3 norm( ln.x() , ln.y() , ln.z() ) ;
1124
1125
1126 Vector3D first, previous ;
1127
1128 for(unsigned i=0 ; i< nMax ; ++i ){
1129
1130 double alpha = double(i) * dAlpha ;
1131
1132 TVector3 vec( lu.x() , lu.y() , lu.z() ) ;
1133
1134 TRotation rot ;
1135 rot.Rotate( alpha , norm );
1136
1137 TVector3 vecR = rot * vec ;
1138
1139 Vector3D luRot ;
1140 luRot.fill( vecR ) ;
1141
1142 double dist = shape->DistFromInside( const_cast<double*> (lo.const_array()) , const_cast<double*> (luRot.const_array()) , 3, 0.1 ) ;
1143
1144
1145 Vector3D lp = lo + dist * luRot ;
1146
1147 Vector3D gp ;
1148
1149 _wtM->LocalToMaster( lp , gp.array() ) ;
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159 if( i > 0 )
1160 lines.emplace_back(previous, gp);
1161 else
1162 first = gp ;
1163
1164 previous = gp ;
1165 }
1166 lines.emplace_back(previous, first);
1167
1168
1169 } else if( type().isCylinder() ) {
1170
1171 if( shape->InheritsFrom("TGeoTube") || shape->InheritsFrom("TGeoCone") ) {
1172
1173 lines.reserve( nMax ) ;
1174
1175 TGeoBBox* tube = ( TGeoBBox* ) shape ;
1176
1177 double zHalf = tube->GetDZ() ;
1178
1179 Vector3D zv( 0. , 0. , zHalf ) ;
1180
1181 double r = lo.rho() ;
1182
1183
1184 unsigned n = nMax / 4 ;
1185 double dPhi = 2.* ROOT::Math::Pi() / double( n ) ;
1186
1187 for( unsigned i = 0 ; i < n ; ++i ) {
1188
1189 Vector3D rv0( r*sin( i *dPhi ) , r*cos( i *dPhi ) , 0. ) ;
1190 Vector3D rv1( r*sin( (i+1)*dPhi ) , r*cos( (i+1)*dPhi ) , 0. ) ;
1191
1192
1193
1194 Vector3D pl0 = zv + rv0 ;
1195 Vector3D pl1 = zv + rv1 ;
1196 Vector3D pl2 = -zv + rv1 ;
1197 Vector3D pl3 = -zv + rv0 ;
1198
1199 Vector3D pg0,pg1,pg2,pg3 ;
1200
1201 _wtM->LocalToMaster( pl0, pg0.array() ) ;
1202 _wtM->LocalToMaster( pl1, pg1.array() ) ;
1203 _wtM->LocalToMaster( pl2, pg2.array() ) ;
1204 _wtM->LocalToMaster( pl3, pg3.array() ) ;
1205
1206 lines.emplace_back( pg0, pg1 );
1207 lines.emplace_back( pg1, pg2 );
1208 lines.emplace_back( pg2, pg3 );
1209 lines.emplace_back( pg3, pg0 );
1210 }
1211 }
1212 }
1213 return lines ;
1214
1215 }
1216
1217
1218
1219
1220 Vector3D CylinderSurface::u( const Vector3D& point ) const {
1221
1222 Vector3D lp , u_val ;
1223 _wtM->MasterToLocal( point , lp.array() ) ;
1224 const Vector3D& lu = _volSurf.u( lp ) ;
1225 _wtM->LocalToMasterVect( lu , u_val.array() ) ;
1226 return u_val ;
1227 }
1228
1229 Vector3D CylinderSurface::v(const Vector3D& point ) const {
1230 Vector3D lp , v_val ;
1231 _wtM->MasterToLocal( point , lp.array() ) ;
1232 const Vector3D& lv = _volSurf.v( lp ) ;
1233 _wtM->LocalToMasterVect( lv , v_val.array() ) ;
1234 return v_val ;
1235 }
1236
1237 Vector3D CylinderSurface::normal(const Vector3D& point ) const {
1238 Vector3D lp , n ;
1239 _wtM->MasterToLocal( point , lp.array() ) ;
1240 const Vector3D& ln = _volSurf.normal( lp ) ;
1241 _wtM->LocalToMasterVect( ln , n.array() ) ;
1242 return n ;
1243 }
1244
1245 Vector2D CylinderSurface::globalToLocal( const Vector3D& point) const {
1246
1247 Vector3D lp;
1248 _wtM->MasterToLocal( point , lp.array() ) ;
1249
1250 return _volSurf.globalToLocal( lp ) ;
1251 }
1252
1253
1254 Vector3D CylinderSurface::localToGlobal( const Vector2D& point) const {
1255
1256 Vector3D lp = _volSurf.localToGlobal( point ) ;
1257 Vector3D p ;
1258 _wtM->LocalToMaster( lp , p.array() ) ;
1259
1260 return p ;
1261 }
1262
1263 double CylinderSurface::radius() const { return _volSurf.origin().rho() ; }
1264
1265 Vector3D CylinderSurface::center() const { return volumeOrigin() ; }
1266
1267
1268
1269
1270
1271 double ConeSurface::radius0() const {
1272
1273 double theta = _volSurf.v().theta() ;
1274 double l = length_along_v() * cos( theta ) ;
1275
1276 return origin().rho() - 0.5 * l * tan( theta ) ;
1277 }
1278
1279 double ConeSurface::radius1() const {
1280
1281 double theta = _volSurf.v().theta() ;
1282 double l = length_along_v() * cos( theta ) ;
1283
1284 return origin().rho() + 0.5 * l * tan( theta ) ;
1285 }
1286
1287 double ConeSurface::z0() const {
1288
1289 double theta = _volSurf.v().theta() ;
1290 double l = length_along_v() * cos( theta ) ;
1291
1292 return origin().z() - 0.5 * l ;
1293 }
1294
1295 double ConeSurface::z1() const {
1296
1297 double theta = _volSurf.v().theta() ;
1298 double l = length_along_v() * cos( theta ) ;
1299
1300 return origin().z() + 0.5 * l ;
1301 }
1302
1303 Vector3D ConeSurface::center() const { return volumeOrigin() ; }
1304
1305
1306
1307
1308 }
1309 }
1310
1311