22 #include "TGeoMatrix.h"
23 #include "TGeoShape.h"
24 #include "TRotation.h"
31 using namespace detail ;
56 double uv = u() *
v() ;
57 Vector3D uprime = ( u() - uv *
v() ).unit() ;
58 Vector3D vprime = (
v() - uv * u() ).unit() ;
59 double uup = u() * uprime ;
60 double vvp =
v() * vprime ;
62 return Vector2D( p*uprime / uup , p*vprime / vvp ) ;
67 Vector3D g = origin() + point[0] * u() + point[1] *
v() ;
81 const Vector3D& u_val = this->u( o ) ;
92 if( volume()->GetShape()->Contains( o.
const_array() ) ){
94 dist_p = volume()->GetShape()->DistFromInside(
const_cast<double*
> ( o.
const_array() ) ,
96 dist_m = volume()->GetShape()->DistFromInside(
const_cast<double*
> ( o.
const_array() ) ,
97 const_cast<double*
> ( um.
array() ) ) ;
108 dist_p = volume()->GetShape()->DistFromOutside(
const_cast<double*
> ( o.
const_array() ) ,
110 dist_m = volume()->GetShape()->DistFromOutside(
const_cast<double*
> ( o.
const_array() ) ,
111 const_cast<double*
> ( um.
array() ) ) ;
121 Vector3D o_1 = this->origin() + dist_p * u_val ;
122 Vector3D o_2 = this->origin() + dist_m * um ;
124 dist_p += volume()->GetShape()->DistFromInside(
const_cast<double*
> ( o_1.
const_array() ) ,
125 const_cast<double*
> ( u_val.const_array() ) ) ;
127 dist_m += volume()->GetShape()->DistFromInside(
const_cast<double*
> ( o_2.
const_array() ) ,
128 const_cast<double*
> ( um.array() ) ) ;
136 return dist_p + dist_m ;
143 const Vector3D& o = this->origin() ;
155 if( volume()->GetShape()->Contains( o.
const_array() ) ){
157 dist_p = volume()->GetShape()->DistFromInside(
const_cast<double*
> ( o.
const_array() ) ,
159 dist_m = volume()->GetShape()->DistFromInside(
const_cast<double*
> ( o.
const_array() ) ,
160 const_cast<double*
> ( vm.
array() ) ) ;
171 dist_p = volume()->GetShape()->DistFromOutside(
const_cast<double*
> ( o.
const_array() ) ,
173 dist_m = volume()->GetShape()->DistFromOutside(
const_cast<double*
> ( o.
const_array() ) ,
174 const_cast<double*
> ( vm.
array() ) ) ;
184 Vector3D o_1 = this->origin() + dist_p * v_val ;
185 Vector3D o_2 = this->origin() + dist_m * vm ;
187 dist_p += volume()->GetShape()->DistFromInside(
const_cast<double*
> ( o_1.
const_array() ) ,
188 const_cast<double*
> ( v_val.const_array() ) ) ;
190 dist_m += volume()->GetShape()->DistFromInside(
const_cast<double*
> ( o_2.
const_array() ) ,
191 const_cast<double*
> ( vm.array() ) ) ;
199 return dist_p + dist_m ;
211 bool inShape = ( type().isUnbounded() ? true : volume()->GetShape()->Contains( point.
const_array() ) ) ;
213 double dist = std::abs ( distance( point ) ) ;
215 std::cout <<
" ** Surface::insideBound( " << point <<
" ) - distance = " <<
dist
216 <<
" origin = " << origin() <<
" normal = " << normal()
217 <<
" p * n = " << point * normal()
218 <<
" isInShape : " << inShape << std::endl ;
223 if( type().isUnbounded() ){
225 return std::abs ( distance( point ) ) <
epsilon ;
229 return ( std::abs ( distance( point ) ) <
epsilon && volume()->GetShape()->Contains( point.
const_array() ) ) ;
239 std::vector< std::pair<Vector3D, Vector3D> > lines ;
262 return _surf->insideBounds( point,
epsilon ) ;
265 return _surf->getLines(nMax) ;
272 return ( point - origin() ) * normal() ;
277 double thickness_inner ,
double thickness_outer,
Vector3D o ) :
314 while( phi < -
M_PI ) phi += 2.*
M_PI ;
315 while( phi >
M_PI ) phi -= 2.*
M_PI ;
323 double z = point.
v() +
origin().
z() ;
326 while( phi < -
M_PI ) phi += 2.*
M_PI ;
327 while( phi >
M_PI ) phi -= 2.*
M_PI ;
341 double thickness_inner ,
double thickness_outer,
Vector3D v_val,
Vector3D o_val ) :
345 Vector3D o_rphi( o_val.
x() , o_val.
y() , 0. ) ;
348 double dphi = v_val.
phi() - o_rphi.
phi() ;
349 while( dphi < -
M_PI ) dphi += 2.*
M_PI ;
350 while( dphi >
M_PI ) dphi -= 2.*
M_PI ;
352 if( std::fabs( dphi ) > 1e-6 ){
353 std::stringstream sst ; sst <<
"VolConeImpl::VolConeImpl() - incompatibel vector v and o given "
354 << v_val <<
" - " << o_val ;
355 throw std::runtime_error( sst.str() ) ;
358 double theta = v_val.
theta() ;
370 _ztip = o_val.
z() - tipoffset ;
372 double dist_p = vol->GetShape()->DistFromInside(
const_cast<double*
> ( o_val.
const_array() ) ,
375 double dist_m = vol->GetShape()->DistFromInside(
const_cast<double*
> ( o_val.
const_array() ) ,
376 const_cast<double*
> ( vm.
array() ) ) ;
378 double costh = std::cos( theta) ;
379 _zt0 = tipoffset - dist_m * costh ;
380 _zt1 = tipoffset + dist_p * costh ;
401 return av.
cross( n ) ;
415 while( phi < -
M_PI ) phi += 2.*
M_PI ;
416 while( phi >
M_PI ) phi -= 2.*
M_PI ;
433 while( phi < -
M_PI ) phi += 2.*
M_PI ;
434 while( phi >
M_PI ) phi -= 2.*
M_PI ;
459 double zp = point.
z() -
_ztip ;
461 return r * std::cos(
_v.
theta() ) ;
468 std::vector< std::pair<Vector3D, Vector3D> > lines ;
470 lines.reserve( nMax ) ;
472 double theta =
v().
theta() ;
475 Vector3D zv( 0. , 0. , half_length ) ;
477 double dr = half_length * tan( theta ) ;
483 unsigned n = nMax / 4 ;
484 double dPhi = 2.* ROOT::Math::Pi() / double( n ) ;
486 for(
unsigned i = 0 ; i < n ; ++i ) {
488 Vector3D r0v0( r0*sin( i *dPhi ) , r0*cos( i *dPhi ) , 0. ) ;
489 Vector3D r0v1( r0*sin( (i+1)*dPhi ) , r0*cos( (i+1)*dPhi ) , 0. ) ;
491 Vector3D r1v0( r1*sin( i *dPhi ) , r1*cos( i *dPhi ) , 0. ) ;
492 Vector3D r1v1( r1*sin( (i+1)*dPhi ) , r1*cos( (i+1)*dPhi ) , 0. ) ;
499 lines.emplace_back( pl0, pl1 );
500 lines.emplace_back( pl1, pl2 );
501 lines.emplace_back( pl2, pl3 );
502 lines.emplace_back( pl3, pl0 );
512 std::for_each(begin(), end(), detail::deleteObject<ISurface>);
532 volList.emplace_back( pv ) ;
551 const TGeoNode* node = pv.
ptr();
557 throw std::runtime_error(
"*** findVolume: Invalid placement: - node pointer Null ! " + std::string( pv.
name() ) );
563 for (Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau) {
565 TGeoNode* daughter = node->GetDaughter(idau);
568 if ( !placement.
data() ) {
569 throw std::runtime_error(
"*** findVolume: Invalid not instrumented placement:"+std::string(daughter->GetName())
570 +
" [Internal error -- bad detector constructor]");
575 if(
findVolume( pv_dau , theVol , volList ) ) {
596 _wtM() , _id( 0) , _type( _volSurf.type() ) {
630 materials[0].first ) ;
649 materials[0].first ) ;
662 double uv =
u() *
v() ;
665 double uup =
u() * uprime ;
666 double vvp =
v() * vprime ;
668 return Vector2D( p*uprime / uup , p*vprime / vvp ) ;
694 _wtM->MasterToLocal( point , pa ) ;
703 _wtM->MasterToLocal( point , pa ) ;
712 std::list< PlacedVolume > pVList ;
718 std::stringstream sst ; sst <<
" ***** ERROR: Volume " << theVol.
name() <<
" not found for DetElement " <<
_det.
name() <<
" with surface " ;
719 throw std::runtime_error( sst.str() ) ;
728 for( std::list<PlacedVolume>::iterator it= pVList.begin(), n = pVList.end() ; it != n ; ++it ){
730 TGeoMatrix* m = pv->GetMatrix();
731 std::cout <<
" +++ matrix for placed volume : " << std::endl ;
739 std::unique_ptr<TGeoHMatrix> wtI(
new TGeoHMatrix( wm ) ) ;
743 for(
auto it = std::next(pVList.begin()) ; it != pVList.end() ; ++it ) {
746 TGeoMatrix* m = pvol->GetMatrix();
756 #if 0 //fixme: which convention to use here - the correct should be wtI, however it is the inverse of what is stored in DetElement ???
760 _wtM = std::move(wtI);
764 _wtM = std::move(wtI);
770 double ua[3], va[3], na[3], oa[3] ;
826 const static double epsilon = 1e-6 ;
828 std::vector< std::pair<Vector3D, Vector3D> > lines ;
832 const std::vector< std::pair<Vector3D, Vector3D> >& local_lines =
_volSurf.
getLines() ;
834 if( local_lines.size() > 0 ) {
835 unsigned n=local_lines.size() ;
838 for(
unsigned i=0;i<n;++i){
841 _wtM->LocalToMaster( local_lines[i].first , av.
array() ) ;
842 _wtM->LocalToMaster( local_lines[i].second , bv.
array() ) ;
844 lines.emplace_back( av, bv );
859 const TGeoShape* shape = vol->GetShape() ;
862 if(
type().isPlane() ) {
864 if( shape->IsA() == TGeoBBox::Class() ) {
866 TGeoBBox* box = ( TGeoBBox* ) shape ;
868 Vector3D boxDim( box->GetDX() , box->GetDY() , box->GetDZ() ) ;
871 bool isYZ = std::fabs( ln.
x() - 1.0 ) <
epsilon ;
872 bool isXZ = std::fabs( ln.
y() - 1.0 ) <
epsilon ;
873 bool isXY = std::fabs( ln.
z() - 1.0 ) <
epsilon ;
876 if( isYZ || isXZ || isXY ) {
887 ubl.
fill( 1., 0., 0. ) ;
888 vbl.
fill( 0., 0., 1. ) ;
894 ubl.
fill( 1., 0., 0. ) ;
895 vbl.
fill( 0., 1., 0. ) ;
902 _wtM->LocalToMasterVect( ubl , ub.
array() ) ;
903 _wtM->LocalToMasterVect( vbl , vb.
array() ) ;
907 lines.emplace_back(
_o + boxDim[ uidx ] * ub + boxDim[ vidx ] * vb ,
_o - boxDim[ uidx ] * ub + boxDim[ vidx ] * vb );
908 lines.emplace_back(
_o - boxDim[ uidx ] * ub + boxDim[ vidx ] * vb ,
_o - boxDim[ uidx ] * ub - boxDim[ vidx ] * vb );
909 lines.emplace_back(
_o - boxDim[ uidx ] * ub - boxDim[ vidx ] * vb ,
_o + boxDim[ uidx ] * ub - boxDim[ vidx ] * vb );
910 lines.emplace_back(
_o + boxDim[ uidx ] * ub - boxDim[ vidx ] * vb ,
_o + boxDim[ uidx ] * ub + boxDim[ vidx ] * vb );
915 }
else if( shape->InheritsFrom(
"TGeoTube") || shape->InheritsFrom(
"TGeoCone") ) {
919 if(
type().isZDisk() ) {
932 if( shape->InheritsFrom(
"TGeoTube") ) {
933 TGeoTube* tube = ( TGeoTube* ) shape ;
934 zhalf = tube->GetDZ() ;
935 rmax1 = tube->GetRmax() ;
936 rmax2 = tube->GetRmax() ;
937 rmin1 = tube->GetRmin() ;
938 rmin2 = tube->GetRmin() ;
940 TGeoCone* cone = ( TGeoCone* ) shape ;
941 zhalf = cone->GetDZ() ;
942 rmax1 = cone->GetRmax1() ;
943 rmax2 = cone->GetRmax2() ;
944 rmin1 = cone->GetRmin1() ;
945 rmin2 = cone->GetRmin2() ;
950 double r0 = rmin1 + ( rmin2 - rmin1 ) / ( 2. * zhalf ) * ( zhalf + lo.
z() ) ;
951 double r1 = rmax1 + ( rmax2 - rmax1 ) / ( 2. * zhalf ) * ( zhalf + lo.
z() ) ;
954 unsigned n = nMax / 4 ;
955 double dPhi = 2.* ROOT::Math::Pi() / double( n ) ;
957 for(
unsigned i = 0 ; i < n ; ++i ) {
959 Vector3D rv00( r0*sin( i *dPhi ) , r0*cos( i *dPhi ) , 0. ) ;
960 Vector3D rv01( r0*sin( (i+1)*dPhi ) , r0*cos( (i+1)*dPhi ) , 0. ) ;
962 Vector3D rv10( r1*sin( i *dPhi ) , r1*cos( i *dPhi ) , 0. ) ;
963 Vector3D rv11( r1*sin( (i+1)*dPhi ) , r1*cos( (i+1)*dPhi ) , 0. ) ;
975 _wtM->LocalToMaster( pl0, pg0.
array() ) ;
976 _wtM->LocalToMaster( pl1, pg1.
array() ) ;
977 _wtM->LocalToMaster( pl2, pg2.
array() ) ;
978 _wtM->LocalToMaster( pl3, pg3.
array() ) ;
980 lines.emplace_back( pg0, pg1 );
981 lines.emplace_back( pg2, pg3 );
986 n = 4 ; dPhi = 2.* ROOT::Math::Pi() / double( n ) ;
988 for(
unsigned i = 0 ; i < n ; ++i ) {
990 Vector3D rv0( r0*sin( i * dPhi ) , r0*cos( i * dPhi ) , 0. ) ;
991 Vector3D rv1( r1*sin( i * dPhi ) , r1*cos( i * dPhi ) , 0. ) ;
998 _wtM->LocalToMaster( pl0, pg0.
array() ) ;
999 _wtM->LocalToMaster( pl1, pg1.
array() ) ;
1001 lines.emplace_back(pg0, pg1);
1009 else if(shape->IsA() == TGeoTrap::Class()) {
1010 TGeoTrap* trapezoid = ( TGeoTrap* ) shape;
1012 double dx1 = trapezoid->GetBl1();
1013 double dx2 = trapezoid->GetTl1();
1014 double dz = trapezoid->GetH1();
1024 _wtM->LocalToMasterVect( ubl , ub.
array() ) ;
1025 _wtM->LocalToMasterVect( vbl , vb.
array() ) ;
1030 lines.emplace_back(
_o + dx1 * ub - dz * vb ,
_o + dx2 * ub + dz * vb);
1031 lines.emplace_back(
_o + dx2 * ub + dz * vb ,
_o - dx2 * ub + dz * vb);
1032 lines.emplace_back(
_o - dx2 * ub + dz * vb ,
_o - dx1 * ub - dz * vb);
1033 lines.emplace_back(
_o - dx1 * ub - dz * vb ,
_o + dx1 * ub - dz * vb);
1038 else if(shape->IsA() == TGeoTrd1::Class()){
1039 TGeoTrd1* trapezoid = ( TGeoTrd1* ) shape;
1041 double dx1 = trapezoid->GetDx1();
1042 double dx2 = trapezoid->GetDx2();
1043 double dy = trapezoid->GetDy();
1044 double dz = trapezoid->GetDz();
1046 bool isYZ = std::fabs( ln.
x() - 1.0 ) <
epsilon ;
1047 bool isXZ = std::fabs( ln.
y() - 1.0 ) <
epsilon ;
1048 bool isXY = std::fabs( ln.
z() - 1.0 ) <
epsilon ;
1050 if(not (isYZ || isXZ || isXY)) {
1051 std::stringstream sst ;
1052 sst <<
" ***** ERROR: Trapezoid surface cannot be defined, normal not parallel to x, y, or z axis";
1053 throw std::runtime_error( sst.str() ) ;
1059 ubl.
fill( 0., 1., 0. ) ;
1060 vbl.
fill( 0., 0., 1. ) ;
1062 ubl.
fill( 1., 0., 0. ) ;
1063 vbl.
fill( 0., 0., 1. ) ;
1065 ubl.
fill( 1., 0., 0. ) ;
1066 vbl.
fill( 0., 1., 0. ) ;
1071 _wtM->LocalToMasterVect( ubl , ub.
array() ) ;
1072 _wtM->LocalToMasterVect( vbl , vb.
array() ) ;
1078 lines.emplace_back(
_o + dy * ub - dz * vb ,
_o + dy * ub + dz * vb);
1079 lines.emplace_back(
_o + dy * ub + dz * vb ,
_o - dy * ub + dz * vb);
1080 lines.emplace_back(
_o - dy * ub + dz * vb ,
_o - dy * ub - dz * vb);
1081 lines.emplace_back(
_o - dy * ub - dz * vb ,
_o + dy * ub - dz * vb);
1083 lines.emplace_back(
_o + dx1 * ub - dz * vb ,
_o + dx2 * ub + dz * vb);
1084 lines.emplace_back(
_o + dx2 * ub + dz * vb ,
_o - dx2 * ub + dz * vb);
1085 lines.emplace_back(
_o - dx2 * ub + dz * vb ,
_o - dx1 * ub - dz * vb);
1086 lines.emplace_back(
_o - dx1 * ub - dz * vb ,
_o + dx1 * ub - dz * vb);
1088 lines.emplace_back(
_o + dx1 * ub - dy * vb ,
_o + dx2 * ub + dy * vb);
1089 lines.emplace_back(
_o + dx2 * ub + dy * vb ,
_o - dx2 * ub + dy * vb);
1090 lines.emplace_back(
_o - dx2 * ub + dy * vb ,
_o - dx1 * ub - dy * vb);
1091 lines.emplace_back(
_o - dx1 * ub - dy * vb ,
_o + dx1 * ub - dy * vb);
1096 else if(shape->IsA() == TGeoTrd2::Class()){
1097 TGeoTrd2* trapezoid = ( TGeoTrd2* ) shape;
1099 double dx1 = trapezoid->GetDx1();
1100 double dx2 = trapezoid->GetDx2();
1103 double dz = trapezoid->GetDz();
1114 _wtM->LocalToMasterVect( ubl , ub.
array() ) ;
1115 _wtM->LocalToMasterVect( vbl , vb.
array() ) ;
1120 lines.emplace_back(
_o + dx1 * ub - dz * vb ,
_o + dx2 * ub + dz * vb);
1121 lines.emplace_back(
_o + dx2 * ub + dz * vb ,
_o - dx2 * ub + dz * vb);
1122 lines.emplace_back(
_o - dx2 * ub + dz * vb ,
_o - dx1 * ub - dz * vb);
1123 lines.emplace_back(
_o - dx1 * ub - dz * vb ,
_o + dx1 * ub - dz * vb);
1136 lines.reserve( nMax ) ;
1138 double dAlpha = 2.* ROOT::Math::Pi() / double( nMax ) ;
1140 TVector3 norm( ln.
x() , ln.
y() , ln.
z() ) ;
1145 for(
unsigned i=0 ; i< nMax ; ++i ){
1147 double alpha = double(i) * dAlpha ;
1149 TVector3 vec( lu.
x() , lu.
y() , lu.
z() ) ;
1152 rot.Rotate( alpha , norm );
1154 TVector3 vecR = rot * vec ;
1157 luRot.
fill( vecR ) ;
1159 double dist = shape->DistFromInside(
const_cast<double*
> (lo.
const_array()) ,
const_cast<double*
> (luRot.
const_array()) , 3, 0.1 ) ;
1166 _wtM->LocalToMaster( lp , gp.
array() ) ;
1177 lines.emplace_back(previous, gp);
1183 lines.emplace_back(previous, first);
1186 }
else if(
type().isCylinder() ) {
1188 if( shape->InheritsFrom(
"TGeoTube") || shape->InheritsFrom(
"TGeoCone") ) {
1190 lines.reserve( nMax ) ;
1192 TGeoBBox* tube = ( TGeoBBox* ) shape ;
1194 double zHalf = tube->GetDZ() ;
1198 double r = lo.
rho() ;
1201 unsigned n = nMax / 4 ;
1202 double dPhi = 2.* ROOT::Math::Pi() / double( n ) ;
1204 for(
unsigned i = 0 ; i < n ; ++i ) {
1206 Vector3D rv0( r*sin( i *dPhi ) , r*cos( i *dPhi ) , 0. ) ;
1207 Vector3D rv1( r*sin( (i+1)*dPhi ) , r*cos( (i+1)*dPhi ) , 0. ) ;
1218 _wtM->LocalToMaster( pl0, pg0.
array() ) ;
1219 _wtM->LocalToMaster( pl1, pg1.
array() ) ;
1220 _wtM->LocalToMaster( pl2, pg2.
array() ) ;
1221 _wtM->LocalToMaster( pl3, pg3.
array() ) ;
1223 lines.emplace_back( pg0, pg1 );
1224 lines.emplace_back( pg1, pg2 );
1225 lines.emplace_back( pg2, pg3 );
1226 lines.emplace_back( pg3, pg0 );
1240 _wtM->MasterToLocal( point , lp.
array() ) ;
1242 _wtM->LocalToMasterVect( lu , u_val.
array() ) ;
1248 _wtM->MasterToLocal( point , lp.
array() ) ;
1250 _wtM->LocalToMasterVect( lv , v_val.
array() ) ;
1256 _wtM->MasterToLocal( point , lp.
array() ) ;
1258 _wtM->LocalToMasterVect( ln , n.
array() ) ;
1265 _wtM->MasterToLocal( point , lp.
array() ) ;
1293 return origin().
rho() - 0.5 * l * tan( theta ) ;
1301 return origin().
rho() + 0.5 * l * tan( theta ) ;
1309 return origin().
z() - 0.5 * l ;
1317 return origin().
z() + 0.5 * l ;