1 #include "gearimpl/ZPlanarParametersImpl.h"
5 #define _EPSILON 0.0001
18 (
int type,
double shellInnerRadius,
double shellOuterRadius,
double shellHalfLength,
double shellGap,
double shellRadLength ) :
20 _shellInnerRadius( shellInnerRadius ) ,
21 _shellOuterRadius( shellOuterRadius ) ,
22 _shellHalfLength( shellHalfLength ) ,
23 _shellGap( shellGap ) ,
24 _shellRadLength( shellRadLength ) {}
32 if( fabs( _shellHalfLength ) > 1e-3 ) {
33 if( fabs( p[2] ) > ( _shellHalfLength + _shellGap/2 ) ) {
37 if( fabs( p[2] ) < ( _shellGap/2 ) ) {
44 double pRadius = sqrt( p[0]*p[0] + p[1]*p[1] ) ;
47 double pPhi = getPhiPoint( p ) ;
49 for(
int possibleLayer = 0 ; possibleLayer < _layer.
getNLayers() ; possibleLayer++ ) {
53 if( ( ( !sensitive ) && ( pRadius < ( _layer.
getLadderDistance( possibleLayer ) - _EPSILON ) ) )
54 ||( ( sensitive ) && ( pRadius < ( _layer.
getSensitiveDistance( possibleLayer ) - _EPSILON ) ) ) ) {
61 if( pRadius > ( _layer.
getMaxRadius( possibleLayer , sensitive ) + _EPSILON ) ) {
68 if( ( ( !sensitive ) && ( fabs( p[2] ) > ( _layer.
getLadderLength( possibleLayer ) + _shellGap/2 + _EPSILON ) ) )
69 ||( ( sensitive ) && ( fabs( p[2] ) > (_layer.
getSensitiveLength( possibleLayer ) + _shellGap/2 + _EPSILON ) ) ) ) {
76 double zStart, zEnd, left, right, thick, d ;
92 zStart = _shellGap/2 ;
95 double deltaPhi = ( 2 * M_PI ) / _layer.
getNLadders( possibleLayer ) ;
97 double endPhi = _layer.
getEndInnerPhi( possibleLayer , sensitive ) ;
100 int nLadders = _layer.
getNLadders( possibleLayer ) ;
101 for(
int i = 0 ; i < nLadders ; i++ ) {
103 double phi = _layer.getInternalPhi0( possibleLayer ) + i*deltaPhi ;
104 phi = correctPhiRange( phi ) ;
107 double sPhi = correctPhiRange( startPhi + i*deltaPhi - _EPSILON ) ;
108 double ePhi = correctPhiRange( endPhi + i*deltaPhi + _EPSILON ) ;
112 ( ( sPhi <= pPhi ) && ( pPhi <= ePhi ) )
113 ||( ( sPhi > ePhi ) && ( pPhi <= ePhi ) )
114 ||( ( sPhi > ePhi ) && ( pPhi >= sPhi ) ) ;
122 Vector3D nBase, nSide, nZ ;
124 nBase[0] = sin( phi ) ;
125 nBase[1] = cos( phi ) ;
128 nSide[0] = cos( phi ) ;
129 nSide[1] = -sin( phi ) ;
140 Vector3D r( d * nBase[0] , d * nBase[1] , d * nBase[2] ) ;
142 Vector3D thisVector = distanceToPlane( p, r, nBase, nSide, nZ, left, right, zStart, zEnd ) ;
146 double c = sqrt( thisVector[0] * thisVector[0] + thisVector[1] * thisVector[1] + thisVector[2] * thisVector[2] ) ;
161 if ( ( differsLess( nBase[0] , thisVector[0] ) || isEqual( thisVector[0] , -c*nBase[0] ) )
162 && ( differsLess( nBase[1] , thisVector[1] ) || isEqual( thisVector[1] , -c*nBase[1] ) )
163 && ( differsLess( nBase[2] , thisVector[2] ) || isEqual( thisVector[2] , -c*nBase[2] ) )
164 && ( ( c <= thick ) || isEqual( c , thick ) ) ) {
170 sensorID->layer = possibleLayer ;
171 sensorID->side = ( p.
z() >= 0. ? +1 : -1 ) ;
174 sensorID->module = ( i ? nLadders - i : 0 ) ;
176 sensorID->sensor = 0 ;
196 Vector3D origin( 0,0,0 ) ;
206 if( origin.x() == p.x() && origin.y() == p.y() && origin.z() == p.z() ) {
212 return Vector3D( _layer.
getLadderDistance(0) , -_layer.getInternalPhi0(0) , _shellGap/2 , Vector3D::cylindrical ) ;
222 double pPhi = getPhiPoint( p ) ;
225 Vector3D vPointPlane ;
226 double minDistance = 99999.99 ;
229 for (
int nearestLayer=0 ; nearestLayer < _layer.
getNLayers() ; nearestLayer++ ) {
232 double deltaPhi = ( 2 * M_PI ) / _layer.
getNLadders( nearestLayer ) ;
235 double dist, zStart, zEnd, left, right, thick ;
251 zStart = _shellGap/2 ;
254 for(
int i = 0 ; i < _layer.
getNLadders( nearestLayer ) ; i++ ) {
256 double phi = _layer.getInternalPhi0( nearestLayer ) + i*deltaPhi ;
257 phi = correctPhiRange( phi ) ;
260 double sPhi = correctPhiRange( phi - deltaPhi ) ;
261 double ePhi = correctPhiRange( phi + deltaPhi ) ;
265 ( ( sPhi <= pPhi ) && ( pPhi <= ePhi ) )
266 ||( ( sPhi > ePhi ) && ( pPhi <= ePhi ) )
267 ||( ( sPhi > ePhi ) && ( pPhi >= sPhi ) ) ;
300 Vector3D nBase( sin( phi ), cos( phi ), 0.0 ) ;
301 Vector3D nSide( cos( phi ), -sin( phi ), 0.0 ) ;
303 Vector3D nZ( 0. , 0. , 1. ) ;
307 Vector3D spacePoint = dist * nBase ;
315 for (
int j = 1 ; j<=2 ; j ++ ) {
327 Vector3D r = spacePoint + d * nBase ;
331 Vector3D myVec = distanceToPlane( p, r, nBase, nSide, nZ, left, right, zStart, zEnd ) ;
341 double thisDistance = sqrt( myVec[0] * myVec[0] + myVec[1] * myVec[1] + myVec[2] * myVec[2] ) ;
342 if ( thisDistance <= minDistance ) {
343 minDistance = thisDistance ;
344 vPointPlane = myVec ;
361 for (
int j = 1 ; j<=2 ; j ++ ) {
364 if ( (!sensitive) and ( j == 1 ) ) {
367 if( (!sensitive) and ( j == 2 ) ) {
370 if( (sensitive) and ( j == 1 ) ) {
373 if( (sensitive) and ( j == 2 ) ) {
379 r[0] = spacePoint[0] + d * nSide[0] ;
380 r[1] = spacePoint[1] + d * nSide[1] ;
381 r[2] = spacePoint[2] + d * nSide[2] ;
383 Vector3D myVec = distanceToPlane( p, r, nSide, nBase, nZ, 0, thick, zStart, zEnd ) ;
385 double thisDistance = sqrt( myVec[0] * myVec[0] + myVec[1] * myVec[1] + myVec[2] * myVec[2] ) ;
386 if ( thisDistance < minDistance ) {
387 minDistance = thisDistance ;
388 vPointPlane = myVec ;
397 for(
int j = 1 ; j <= 2 ; j++ ) {
410 r[0] = spacePoint[0] + d * nZ[0] ;
411 r[1] = spacePoint[1] + d * nZ[1] ;
412 r[2] = spacePoint[2] + d * nZ[2] ;
414 Vector3D myVec = distanceToPlane( p, r, nZ, nBase, nSide, 0, thick, left, right ) ;
416 double thisDistance = sqrt( myVec[0] * myVec[0] + myVec[1] * myVec[1] + myVec[2] * myVec[2] ) ;
418 if ( thisDistance < minDistance ) {
419 minDistance = thisDistance ;
420 vPointPlane = myVec ;
443 double currentLength = 99999 ;
444 Vector3D currentPoint (0. , 0. , 0. ) ;
446 for (
int takeLayer=0 ; takeLayer < _layer.
getNLayers() ; takeLayer++ ) {
449 double deltaPhi = ( 2 * M_PI ) / _layer.
getNLadders( takeLayer ) ;
452 double zStart, zEnd, left, right, thick ;
467 for(
int side = 0 ; side <2 ; side++ ) {
469 zStart = _shellGap /2 ;
473 zStart = - _shellGap/2 ;
477 for(
int i = 0 ; i < _layer.
getNLadders( takeLayer ) ; i++ ) {
479 double phi = _layer.getInternalPhi0( takeLayer ) + i*deltaPhi ;
480 phi = correctPhiRange( phi ) ;
483 Vector3D nBase, nSide, nZ, spacePoint;
485 nBase[0] = sin( phi ) ;
486 nBase[1] = cos( phi ) ;
489 nSide[0] = cos( phi ) ;
490 nSide[1] = -sin( phi ) ;
499 for (
int j = 1 ; j<=2 ; j ++ ) {
502 if ( (!sensitive) and ( j == 1 ) ) {
505 if( (!sensitive) and ( j == 2 ) ) {
508 if( (sensitive) and ( j == 1 ) ) {
511 if( (sensitive) and ( j == 2 ) ) {
514 Vector3D r( d * nBase[0] , d * nBase[1] , d * nBase[2] ) ;
517 if ( j == 1 ) spacePoint = r ;
520 Vector3D interSection = planeLineIntersection( r, nBase, p, v ) ;
524 vip[0] = interSection[0] - p[0] ;
525 vip[1] = interSection[1] - p[1] ;
526 vip[2] = interSection[2] - p[2] ;
530 vn[0] = interSection[0] - spacePoint[0] ;
531 vn[1] = interSection[1] - spacePoint[1] ;
532 vn[2] = interSection[2] - spacePoint[2] ;
535 Vector3D inBorder = correctToBorderPoint( vn, nSide, nZ, left, right, zStart, zEnd ) ;
538 if ( isEqual( inBorder , vn ) ) {
541 double thisLength = sqrt( vip[0]*vip[0] + vip[1]*vip[1] +vip[2]*vip[2] ) ;
542 if( thisLength < currentLength ) {
543 currentPoint = interSection ;
544 currentLength = thisLength ;
554 for (
int j = 1 ; j<=2 ; j ++ ) {
557 if ( (!sensitive) and ( j == 1 ) ) {
560 if( (!sensitive) and ( j == 2 ) ) {
563 if( (sensitive) and ( j == 1 ) ) {
566 if( (sensitive) and ( j == 2 ) ) {
572 r[0] = spacePoint[0] + d * nSide[0] ;
573 r[1] = spacePoint[1] + d * nSide[1] ;
574 r[2] = spacePoint[2] + d * nSide[2] ;
577 Vector3D interSection = planeLineIntersection( r, nSide, p, v ) ;
581 vip[0] = interSection[0] - p[0] ;
582 vip[1] = interSection[1] - p[1] ;
583 vip[2] = interSection[2] - p[2] ;
587 vn[0] = interSection[0] - spacePoint[0] ;
588 vn[1] = interSection[1] - spacePoint[1] ;
589 vn[2] = interSection[2] - spacePoint[2] ;
592 Vector3D inBorder = correctToBorderPoint( vn, nBase, nZ, 0, thick, zStart, zEnd ) ;
594 if ( isEqual( inBorder , vn )) {
596 double thisLength = sqrt( vip[0]*vip[0] + vip[1]*vip[1] + vip[2]*vip[2] ) ;
597 if( thisLength < currentLength ) {
598 currentPoint = interSection ;
599 currentLength = thisLength ;
610 for(
int j = 1 ; j <= 2 ; j++ ) {
623 r[0] = spacePoint[0] + d * nZ[0] ;
624 r[1] = spacePoint[1] + d * nZ[1] ;
625 r[2] = spacePoint[2] + d * nZ[2] ;
628 Vector3D interSection = planeLineIntersection( r, nZ, p, v ) ;
632 vip[0] = interSection[0] - p[0] ;
633 vip[1] = interSection[1] - p[1] ;
634 vip[2] = interSection[2] - p[2] ;
638 vn[0] = interSection[0] - spacePoint[0] ;
639 vn[1] = interSection[1] - spacePoint[1] ;
640 vn[2] = interSection[2] - spacePoint[2] ;
643 Vector3D inBorder = correctToBorderPoint( vn, nBase, nSide, 0, thick, left, right ) ;
645 if ( isEqual( inBorder , vn ) ) {
647 double thisLength = sqrt( vip[0]*vip[0] + vip[1]*vip[1] + vip[2]*vip[2] ) ;
648 if( thisLength < currentLength ) {
649 currentPoint = interSection ;
650 currentLength = thisLength ;
663 return currentPoint ;
669 Vector3D ZPlanarParametersImpl::distanceToPlane( Vector3D p, Vector3D r, Vector3D n, Vector3D u, Vector3D v,
float minU,
float maxU,
float minV,
float maxV )
const {
673 if ( n[0]==0 && n[1]==0 && n[2]==0 ) {
675 std::cout <<
"\ndistanceToPlane - Fatal error!" << std::endl ;
676 std::cout <<
"normal vector (0,0,0)" << std::endl ;
677 return Vector3D (0,0,0) ;
681 if ( !isEqual( n[0]*( u[0]+v[0] ) + n[1]*( u[1]+v[1] ) + n[2]*( u[2]+v[2] ) , 0 ) ){
682 std::cout <<
"\ndistanceToPlan - Fatal error! "
683 <<
"n not normal to u and v " << std::endl ;
684 return Vector3D (0,0,0) ;
710 double d = ( r[0] * n[0] + r[1] * n[1] + r[2] * n[2] ) ;
712 double t = - ( n[0] * p[0] + n[1] * p[1] + n[2] * p[2] - d ) ;
716 pn[0] = p[0] + n[0] * t;
717 pn[1] = p[1] + n[1] * t;
718 pn[2] = p[2] + n[2] * t;
722 vn[0] = pn[0] - r[0] ;
723 vn[1] = pn[1] - r[1] ;
724 vn[2] = pn[2] - r[2] ;
727 Vector3D vCor = correctToBorderPoint( vn , u, v, minU, maxU, minV, maxV ) ;
731 final[0] = r[0] + vCor[0] - p[0] ;
732 final[1] = r[1] + vCor[1] - p[1] ;
733 final[2] = r[2] + vCor[2] - p[2] ;
741 Vector3D ZPlanarParametersImpl::planeLineIntersection( Vector3D r, Vector3D n, Vector3D linePoint, Vector3D lineDir)
const {
744 double distance = ( r[0]*n[0] + r[1]*n[1] + r[2]*n[2] ) / ( sqrt( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] ) ) ;
750 double numerator = distance - n[0]*linePoint[0] - n[1]*linePoint[1] - n[2]*linePoint[2] ;
751 double denominator = n[0]*lineDir[0] + n[1]*lineDir[1] + n[2]*lineDir[2] ;
753 if ( denominator == 0 ) {
755 return Vector3D ( 0. , 0. , 0. ) ;
758 double t = numerator/denominator ;
762 return Vector3D ( 0. , 0. , 0. ) ;
766 final[0] = linePoint[0] + t * lineDir[0] ;
767 final[1] = linePoint[1] + t * lineDir[1] ;
768 final[2] = linePoint[2] + t * lineDir[2] ;
776 Vector3D ZPlanarParametersImpl::correctToBorderPoint( Vector3D vPlane , Vector3D u, Vector3D v,
float minU,
float maxU,
float minV,
float maxV )
const {
779 double neededUs = vPlane[0] * u[0] + vPlane[1] * u[1] + vPlane[2] * u[2] ;
780 double neededVs = vPlane[0] * v[0] + vPlane[1] * v[1] + vPlane[2] * v[2] ;
783 double goUs = neededUs, goVs = neededVs ;
784 bool changed = false ;
786 if( neededUs < minU ) {
790 if( neededUs > maxU ) {
794 if( neededVs < minV ) {
798 if( neededVs > maxV ) {
803 if( !changed )
return vPlane ;
806 final[0] = goUs * u[0] + goVs * v[0] ;
807 final[1] = goUs * u[1] + goVs * v[1] ;
808 final[2] = goUs * u[2] + goVs * v[2] ;
815 double ZPlanarParametersImpl::correctPhiRange(
double Phi )
const {
818 return ( Phi - 2 * M_PI ) ;
821 return ( Phi + 2 * M_PI ) ;
829 double ZPlanarParametersImpl::getPhiPoint( Vector3D p )
const {
836 if( ( p[0] >= 0 ) && ( p[1] == 0 ) )
839 if( ( p[0] < 0 ) && ( p[1] == 0 ) )
842 if( ( p[0] == 0 ) && ( p[1] < 0 ) )
845 if( ( p[0] != 0 ) && ( p[1] < 0 ) )
846 pPhi = atan( p[0] / p[1] ) + M_PI ;
849 pPhi = atan( p[0] / p[1] ) ;
851 pPhi = correctPhiRange( pPhi ) ;
859 bool ZPlanarParametersImpl::isEqual(
double valueOne,
double valueTwo )
const
863 if ( valueOne == valueTwo )
return true ;
867 if( valueOne * valueTwo == 0.0 )
869 return fabs( valueOne - valueTwo ) < _EPSILON ;
873 if ( fabs(valueOne) < _EPSILON && fabs(valueTwo) < _EPSILON )
879 return fabs( 2 * (valueOne - valueTwo) ) / (fabs(valueOne) + fabs(valueTwo) ) < _EPSILON ;
884 bool ZPlanarParametersImpl::isEqual( Vector3D p1 , Vector3D p2 )
const
886 for(
int i=0 ; i<3 ; i++ ) {
887 if( !( p1[i] == p2[i] ) ) {
895 bool ZPlanarParametersImpl::differsLess(
double valueOne,
double valueTwo )
const
898 return ( ( fabs( valueOne ) + fabs( valueTwo ) ) < _EPSILON ) ;
virtual int getNLadders(int layerIndex) const
The number of ladders in the layer layerIndex - layer indexing starts at 0 for the layer closest to I...
virtual double getSensitiveThickness(int layerIndex) const
The thickness in mm of the sensitive area in ladders in layer layerIndex.
virtual double getSensitiveOffset(int layerIndex) const
Same as getLadderOffset() except for the sensitive part of the ladder.
virtual double getMaxRadius(int layerIndex, bool sensitive=false) const
returns maximum radius for a given layer
virtual double getLadderDistance(int layerIndex) const
The distance of ladders in layer layerIndex from the IP - layer indexing starts at 0 for the layer cl...
virtual double getSensitiveWidth(int layerIndex) const
The width of the sensitive area in ladders in layer layerIndex in mm.
virtual double getSensitiveDistance(int layerIndex) const
The distance of sensitive area in ladders in layer layerIndex from the IP.
Simple three dimensional vector providing the components for cartesian, cylindrical and spherical coo...
virtual double getLadderWidth(int layerIndex) const
The width of the ladder in layer in mm for ladders in layer layerIndex - layer indexing starting at 0...
double z()
Cartesian cartesian z coordinate.
virtual int getNLayers() const
The total number of layers.
virtual double getLadderThickness(int layerIndex) const
The thickness in mm of the ladders in layerIndex - layer indexing starting at 0 for the layer closest...
virtual double getLadderOffset(int layerIndex) const
The offset of the ladder in mm defines the shift of the ladder in the direction of increasing phi per...
virtual double getSensitiveLength(int layerIndex) const
The length of the sensitive area in ladders in z direction in mm for ladders in layer layerIndex...
virtual Vector3D distanceToNearestLadder(Vector3D p) const
returns vector from given point p to nearest ladder
virtual Vector3D intersectionLadder(Vector3D p, Vector3D v) const
returns the first point where a given strainght line (parameters point p and direction v) crosses a l...
Helper struct for decoding a sensor ID.
virtual double getEndInnerPhi(int layerIndex, bool sensitive=false) const
returns ending phi for first ladder in layer layerIndex (on side facing IP)
virtual double getLadderLength(int layerIndex) const
The (half) length of the ladder in z direction in mm for ladders in layer layerIndex - layer indexing...
virtual bool isPointInLadder(Vector3D p) const
returns whether a point is inside a ladder
ZPlanarParametersImpl(int type, double shellInnerRadius, double shellOuterRadius, double shellHalfLength, double shellGap, double shellRadLength)
C'tor.
virtual double getStartInnerPhi(int layerIndex, bool sensitive=false) const
returns starting phi for first ladder in layer layerIndex (on side facing IP)