00001
00002
00003
00004
00005
00006 #include "GaudiKernel/ToolFactory.h"
00007 #include "GaudiKernel/IMagneticFieldSvc.h"
00008 #include "GaudiKernel/SystemOfUnits.h"
00009
00010
00011 #include "GaudiKernel/Point3DTypes.h"
00012 #include "GaudiKernel/Vector3DTypes.h"
00013
00014
00015 #include "BIntegrator.h"
00016
00017
00018
00019
00020
00021
00022
00023
00024 DECLARE_TOOL_FACTORY( BIntegrator );
00025
00026
00027
00028
00029 BIntegrator::BIntegrator( const std::string& type,
00030 const std::string& name,
00031 const IInterface* parent )
00032 : GaudiTool ( type, name , parent )
00033 {
00034 declareInterface<IBIntegrator>(this);
00035
00036 declareProperty( "NSteps", m_nSteps = 101 );
00037 declareProperty( "FirstZ", m_firstZ = 0.1*Gaudi::Units::mm );
00038 declareProperty( "LastZ", m_lastZ = 9400.*Gaudi::Units::mm );
00039 }
00040
00041
00042
00043 BIntegrator::~BIntegrator() {};
00044
00045
00046
00047
00048 StatusCode BIntegrator::initialize()
00049 {
00050 StatusCode sc = GaudiTool::initialize();
00051 if (sc.isFailure()) return sc;
00052
00053
00054 m_pIMF = svc<IMagneticFieldSvc>( "MagneticFieldSvc", true );
00055
00056 sc = calculateBdlCenter();
00057 info() << "Center of the field is at the z positions "
00058 << m_centerZ << endreq;
00059
00060 return sc;
00061 }
00062
00063
00064
00065
00066 StatusCode BIntegrator::calculateBdlAndCenter(const Gaudi::XYZPoint& beginPoint,
00067 const Gaudi::XYZPoint& endPoint,
00068 const double tX,
00069 const double tY,
00070 double& zCenter,
00071 Gaudi::XYZVector& Bdl ) const
00072 {
00073
00074 Gaudi::XYZPoint point(0.001,0.001,0.0001);
00075 Gaudi::XYZVector bField;
00076 Bdl.SetXYZ(0.,0.,0.);
00077
00078
00079 double zCen = m_centerZ.x();
00080 double xCen = endPoint.x() + tX*(zCen-endPoint.z());
00081 double yCen = endPoint.y() + tY*(zCen-endPoint.z());
00082 if (xCen/zCen>0.3) {
00083 xCen = 0.3*zCen;
00084 }
00085 else if (xCen/zCen< -0.3) {
00086 xCen = -0.3*zCen;
00087 }
00088 if( yCen/zCen>0.25) {
00089 yCen = 0.25*zCen;
00090 }
00091 else if (yCen/zCen< -0.25){
00092 yCen = -0.25*zCen;
00093 }
00094
00095 double angleX = xCen/zCen;
00096 double angleY = yCen/zCen;
00097 double stepSize = (endPoint.z()-beginPoint.z())/(double)m_nSteps;
00098 int iStep;
00099 StatusCode sc;
00100 for(iStep=0;iStep<m_nSteps;iStep++) {
00101
00102 if(point.z()>zCen) {
00103 angleX = tX;
00104 angleY = tY;
00105 }
00106 double dX = angleX*stepSize;
00107 double dY = angleY*stepSize;
00108 double dZ = stepSize;
00109 point.SetX( point.x()+ dX);
00110 point.SetY( point.y()+ dY);
00111 point.SetZ( point.z()+ dZ);
00112 sc = m_pIMF->fieldVector(point,bField);
00113 if( !sc.isSuccess() ) warning() << "field vector not calculated" << endmsg;
00114
00115
00116 Bdl.SetX( Bdl.x() + dY* bField.z()- dZ*bField.y() );
00117 Bdl.SetY( Bdl.y() + dZ*bField.x() -dX*bField.z());
00118 Bdl.SetZ( Bdl.z() + dX*bField.y() -dY*bField.x());
00119
00120 }
00121
00123
00124 double Bdlx_half =0.5*Bdl.x();
00125 double Bdly_half =0.5*Bdl.y();
00126 double Bdlz_half =0.5*Bdl.z();
00127
00128 Bdl.SetXYZ( 0., 0., 0. );
00129
00130 double min_Bdlx =10000.;
00131 double min_Bdly =10000.;
00132 double min_Bdlz =10000.;
00133 Gaudi::XYZPoint centerZ(0.,0.,0.);
00134
00135 angleX = xCen/zCen;
00136 angleY = yCen/zCen;
00137 point.SetXYZ( 0., 0., 0. );
00138 for(iStep=0;iStep<m_nSteps;iStep++) {
00139
00140 if(point.z()>zCen) {
00141 angleX = tX;
00142 angleY = tY;
00143 }
00144 double dX = angleX*stepSize;
00145 double dY = angleY*stepSize;
00146 double dZ = stepSize;
00147 point.SetX( point.x()+ dX);
00148 point.SetY( point.y()+ dY);
00149 point.SetZ( point.z()+ dZ);
00150 sc = m_pIMF->fieldVector(point,bField);
00151 if( !sc.isSuccess() ) warning() << "field vector not calculated" << endmsg;
00152
00153
00154 Bdl.SetX( Bdl.x() + dY* bField.z()- dZ*bField.y() );
00155 Bdl.SetY( Bdl.y() + dZ*bField.x() -dX*bField.z());
00156 Bdl.SetZ( Bdl.z() + dX*bField.y() -dY*bField.x());
00157
00158 if(fabs(Bdl.x()-Bdlx_half)< min_Bdlx){
00159 min_Bdlx=fabs(Bdl.x()-Bdlx_half);
00160 centerZ.SetX(point.z());
00161 }
00162 if(fabs(Bdl.y()-Bdly_half)< min_Bdly){
00163 min_Bdly=fabs(Bdl.y()-Bdly_half);
00164 centerZ.SetY(point.z());
00165 }
00166 if(fabs(Bdl.z()-Bdlz_half)< min_Bdlz){
00167 min_Bdlz=fabs(Bdl.z()-Bdlz_half);
00168 centerZ.SetZ(point.z());
00169 }
00170
00171 }
00172
00173
00174 zCenter = centerZ.x();
00175
00176 return StatusCode::SUCCESS;
00177 }
00178
00179
00180
00181
00182 StatusCode BIntegrator::calculateBdlCenter()
00183 {
00184
00185 Gaudi::XYZVector bField;
00186
00187 Gaudi::XYZVector BdlTotal(0.,0.,0.);
00188 Gaudi::XYZPoint position = Gaudi::XYZPoint(0.0,0.0,0.);
00189
00190 double stepSize = (m_lastZ-m_firstZ) / (double)m_nSteps;
00191
00192
00193 int iStep;
00194 StatusCode sc;
00195
00196 for( iStep=0;iStep < m_nSteps;iStep++) {
00197 position.SetXYZ( 0.1, 0.1, m_firstZ+((double)iStep+0.5)*stepSize );
00198 sc = m_pIMF -> fieldVector( position,bField );
00199 if( !sc.isSuccess() ) warning() << "field vector not calculated" << endmsg;
00200
00201
00202 BdlTotal.SetX( BdlTotal.x() - stepSize*bField.y() );
00203 BdlTotal.SetY( BdlTotal.y() + stepSize*bField.x() );
00204 BdlTotal.SetZ( BdlTotal.z() + 0.);
00205 }
00206
00207 double Bdlx_half = 0.5*BdlTotal.x();
00208 double Bdly_half = 0.5*BdlTotal.y();
00209 double Bdlz_half = 0.5*BdlTotal.z();
00210
00211 BdlTotal.SetXYZ( 0., 0., 0. );
00212
00213 double min_Bdlx = 10000.;
00214 double min_Bdly = 10000.;
00215 double min_Bdlz = 10000.;
00216
00217
00218 for ( iStep=0; iStep < m_nSteps; iStep++ ) {
00219 double z = m_firstZ+ (iStep+0.5)*stepSize;
00220 position.SetXYZ( 0.1, 0.1, z );
00221 sc = m_pIMF -> fieldVector( position,bField );
00222 if( !sc.isSuccess() ) warning() << "field vector not calculated" << endmsg;
00223
00224 BdlTotal.SetX( BdlTotal.x() - stepSize*bField.y() );
00225 BdlTotal.SetY( BdlTotal.y() + stepSize*bField.x() );
00226 BdlTotal.SetZ( BdlTotal.z() + 0.);
00227 if ( fabs(BdlTotal.x()-Bdlx_half) < min_Bdlx ) {
00228 min_Bdlx = fabs( BdlTotal.x()-Bdlx_half );
00229 m_centerZ.SetX(z);
00230 }
00231 if ( fabs(BdlTotal.y()-Bdly_half)< min_Bdly ) {
00232 min_Bdly = fabs( BdlTotal.y()-Bdly_half );
00233 m_centerZ.SetY(z);
00234 }
00235 if ( fabs(BdlTotal.z()-Bdlz_half)< min_Bdlz ) {
00236 min_Bdlz = fabs( BdlTotal.z()-Bdlz_half );
00237 m_centerZ.SetZ(z);
00238 }
00239 }
00240
00241 return StatusCode::SUCCESS;
00242 }
00243
00244