/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Reconstruction/KalFitAlg/KalFitAlg-00-07-55-p03/src/coil/Bfield.cxx

Go to the documentation of this file.
00001 //
00002 // Bfield class
00003 //
00004 // 27-Mar-1999 : KUNIYA Toshio
00005 //   Enabled QCS compornent
00006 //
00007 // 21-Feb-1999 : KUNIYA Toshio
00008 //   Keeping comatibility, Bfield class is modified.
00009 //   No longer fortran common block is used for bfield map.
00010 //   Access functions are prepared for fortran call.
00011 //
00012 
00013 
00014 #include "KalFitAlg/coil/Bfield.h"
00015 
00016 
00017 #include "CLHEP/Matrix/Vector.h"
00018 #include "CLHEP/Matrix/Matrix.h"
00019 #include "CLHEP/Matrix/SymMatrix.h"
00020 #include "CLHEP/Vector/ThreeVector.h"
00021 #include "CLHEP/Geometry/Point3D.h"
00022 #ifndef ENABLE_BACKWARDS_COMPATIBILITY
00023  typedef HepGeom::Point3D<double> HepPoint3D;
00024 #endif
00025 
00026 
00027 
00028 using CLHEP::HepVector; 
00029 using CLHEP::Hep3Vector;
00030 using CLHEP::HepMatrix;
00031 using CLHEP::HepSymMatrix;
00032 
00033 
00034 // prototype of file scoped function to call fortran routine
00035 // ... read B field map with ID = imap from a file
00036 /*wangdy
00037 extern "C" {
00038   extern void geo_coil_readmap_
00039     (int *imap, double (*bz)[399], double (*br)[399], double (*bphi)[399]);
00040   extern void geo_coil_readqcsrmap_
00041     (double (*bzqr)[163], double (*brqr)[163], double (*bphiqr)[163]);
00042   extern void geo_coil_readqcslmap_
00043     (double (*bzrl)[51][52], double (*brql)[51][52], double (*bphiqr)[51][52]);
00044 }
00045  */ 
00046 
00047 
00048 Bfield *
00049 Bfield::_field[200] = {0};   // All of 200 elements are initialized.
00050 
00051 Bfield *
00052 Bfield::getBfield(int imap) {
00053   if (! _field[imap]) _field[imap] = new Bfield(imap);
00054   return _field[imap];
00055 }
00056 
00057 
00058 Bfield::Bfield(int imap) {
00059   std::cout << std::endl;
00060   std::cout << "***********************************************" << std::endl;
00061   std::cout << "           Bfield class  MAP ID = " << imap << std::endl;
00062   std::cout << "    #### R < 174 cm, -152 < Z < 246 cm ####    " << std::endl;
00063   std::cout << "                C++ version 1.00               " << std::endl;
00064   std::cout << "***********************************************" << std::endl;
00065 
00066   const double uniformBz[10] = {0, 15, 14.5, 14, 13, 12.5, 12, 11, 10, 15.5};
00067 
00068   //...initialization
00069   for(int i=0; i<175; i++)
00070     for(int j=0; j<399; j++) {
00071       _Bz[i][j] = 0;
00072       _Br[i][j] = 0;
00073       _Bz[i][j] = 0;
00074       if(i<101 && j<163) {
00075         _BzQR[i][j] = 0;
00076         _BrQR[i][j] = 0;
00077         _BphiQR[i][j] = 0;
00078       }
00079     }
00080   for(int i=0; i<17; i++)
00081     for(int j=0; j<51; j++)
00082       for(int k=0; k<52; k++) {
00083         _BzQL[i][j][k] = 0;
00084         _BrQL[i][j][k] = 0;
00085         _BphiQL[i][j][k] =0;
00086       }
00087   
00088   //...
00089   _fieldID  = imap;
00090 
00091   //...read B field map 
00092 
00093   if(imap<10){
00094     //
00095     // uniform B field map
00096     //
00097     m_Bx = 0.;
00098     m_By = 0.;
00099     m_Bz = uniformBz[imap];
00100     m_Bfld.setX((double) m_Bx);
00101     m_Bfld.setY((double) m_By);
00102     m_Bfld.setZ((double) m_Bz);
00103     std::cout << "Bfield class >> creating uniform B field with id = " << imap;
00104     std::cout << ", (Bx,By,Bz) = "<<m_Bfld<<std::endl;
00105   } else {
00106     //
00107     // non-uniform B field map
00108     //
00109     std::cout << "Bfield class >> loading non-uniform B field map" << std::endl;
00110 /*wangdy
00111      geo_coil_readmap_(&imap, _Bz, _Br, _Bphi);
00112     if( _fieldID == 21 ) {
00113       std::cout << "Bfield class >> loading QCS" << std::endl;
00114       geo_coil_readqcsrmap_(_BzQR,_BrQR, _BphiQR);
00115       geo_coil_readqcslmap_(_BzQL,_BrQL, _BphiQL);
00116     }
00117  */ 
00118     updateCache(0., 0., 0.);
00119   }
00120   std::cout << std::endl;
00121 
00122 }
00123 
00124 //Bfield::~Bfield(){};
00125 
00126 const Hep3Vector &
00127 Bfield::fieldMap(double x, double y, double z) const {
00128 
00129   if(_fieldID > 10){
00130     if(x != m_x || y != m_y || z != m_z)  updateCache(x, y, z);
00131   }
00132 
00133   return m_Bfld;
00134 }
00135 
00136 const Hep3Vector &
00137 Bfield::fieldMap(const HepPoint3D &xyz) const{
00138 
00139   if(_fieldID > 10){
00140     double x = xyz.x();
00141     double y = xyz.y();
00142     double z = xyz.z();
00143     if(x != m_x || y != m_y || z != m_z)  updateCache(x, y, z);
00144   }
00145 
00146   return m_Bfld;
00147 }
00148 
00149 void
00150 Bfield::fieldMap(double *position, double *field) {
00151   if(_fieldID > 10){
00152     double x = position[0];
00153     double y = position[1];
00154     double z = position[2];
00155     if(x != m_x || y != m_y || z != m_z)  updateCache(x, y, z);
00156   }
00157   field[0] = m_Bx;
00158   field[1] = m_By;
00159   field[2] = m_Bz;
00160   return;
00161 }
00162 
00163 double
00164 Bfield::bx(double x, double y, double z) const {
00165 
00166   if(_fieldID > 10){
00167     if(x != m_x || y != m_y || z != m_z)  updateCache(x, y, z);
00168   }
00169 
00170   return m_Bx;
00171 }
00172 
00173 double
00174 Bfield::by(double x, double y, double z) const {
00175 
00176   if(_fieldID > 10){
00177     if(x != m_x || y != m_y || z != m_z)  updateCache(x, y, z);
00178   }
00179 
00180   return m_By;
00181 }
00182 
00183 double
00184 Bfield::bz(double x, double y, double z) const {
00185 
00186   if(_fieldID > 10){
00187     if(x != m_x || y != m_y || z != m_z)  updateCache(x, y, z);
00188   }
00189 
00190   return m_Bz;
00191 }
00192 
00193 double
00194 Bfield::bx(const HepPoint3D &xyz) const{
00195 
00196   if(_fieldID > 10){
00197     double x = xyz.x();
00198     double y = xyz.y();
00199     double z = xyz.z();
00200     if(x != m_x || y != m_y || z != m_z)  updateCache(x, y, z);
00201   }
00202 
00203   return m_Bx;
00204 }
00205 
00206 double
00207 Bfield::by(const HepPoint3D &xyz) const{
00208 
00209   if(_fieldID > 10){
00210     double x = xyz.x();
00211     double y = xyz.y();
00212     double z = xyz.z();
00213     if(x != m_x || y != m_y || z != m_z)  updateCache(x, y, z);
00214   }
00215 
00216   return m_By;
00217 }
00218 
00219 double
00220 Bfield::bz(const HepPoint3D &xyz) const{
00221 
00222   if(_fieldID > 10){
00223     double x = xyz.x();
00224     double y = xyz.y();
00225     double z = xyz.z();
00226     if(x != m_x || y != m_y || z != m_z)  updateCache(x, y, z);
00227   }
00228   return m_Bz;
00229 }
00230 
00231 void
00232 Bfield::updateCache(double x, double y, double z) const{
00233 
00234   // this function is only for non-uniform B field
00235 
00236   if( _fieldID <= 10 ) return;
00237 
00238       double PI = 3.14159;
00239 
00240       //...
00241       double  r   = (double)sqrt((double)x*(double)x + (double)y*(double)y);
00242       double  phi = (double)atan2((double)y, (double)x);
00243 
00244       //... [cm] --> [mm]
00245       double zmm = z * 10.;
00246       double rmm = r * 10.;
00247       //... make index
00248       int tz = (int) (( zmm + 1520.)/10.);
00249       int tr = (int) (rmm/10.);
00250 
00251       //... 
00252       double bz = 0., br = 0., bphi = 0.;
00253 
00254       if(zmm >= -1520. && zmm < 2460. && rmm >= 0. && rmm < 1740.){
00255         if(_Bz[tr][tz] && _Bz[tr][tz+1]){
00256             double pz = (zmm + 1520.)/10.- (double)tz;
00257             double pr =  rmm/10.- (double)tr;
00258 
00259             //...
00260             bz = (_Bz[tr][tz]*(1.- pz)+_Bz[tr][tz+1]*pz)*(1.-pr)+
00261                  (_Bz[tr+1][tz]*(1.-pz)+_Bz[tr+1][tz+1]*pz)*pr;
00262             //...
00263             br = (_Br[tr][tz]*(1.-pz)+_Br[tr][tz+1]*pz)*(1.-pr)+
00264                  (_Br[tr+1][tz]*(1.-pz)+_Br[tr+1][tz+1]*pz)*pr;
00265             //...
00266             bphi = (_Bphi[tr][tz]*(1.-pz)+_Bphi[tr][tz+1]*pz)*(1.-pr)+
00267                    (_Bphi[tr+1][tz]*(1.-pz)+_Bphi[tr+1][tz+1]*pz)*pr;
00268 
00269             if(_fieldID == 21) {
00270               //
00271               // QCS Right
00272               //
00273               if( zmm>=800. && zmm < 2420. && rmm < 1000. ) {
00274                 int tqz = (int)( (zmm-800.)/10. );
00275                 bz += (((_BzQR[tr][tqz]*(1.-pz)+_BzQR[tr][tqz+1]*pz)*(1.-pr)
00276                       +(_BzQR[tr+1][tqz]*(1.-pz)+_BzQR[tr+1][tqz+1]*pz)*pr)
00277                       *(double)sin((double)(2.*phi+2./180.*(double)PI)));
00278                 br += (((_BrQR[tr][tqz]*(1.-pz)+_BrQR[tr][tqz+1]*pz)*(1.-pr)
00279                       +(_BrQR[tr+1][tqz]*(1.-pz)+_BrQR[tr+1][tqz+1]*pz)*pr)
00280                       *(double)sin((double)(2.*phi+2./180.*(double)PI)));
00281                 bphi += (((_BphiQR[tr][tqz]*(1.-pz)
00282                         +_BphiQR[tr][tqz+1]*pz)*(1.-pr)
00283                         +(_BphiQR[tr+1][tqz]*(1.-pz)
00284                         +_BphiQR[tr+1][tqz+1]*pz)*pr)
00285                         *(double)cos((double)(2.*phi+2./180.*(double)PI)));
00286               }
00287               //
00288               // QCS Left
00289               //
00290               if(zmm<=-500. && zmm>-1520. && rmm<1000.) {
00291                 int tqz = (int)((-zmm-500.)/20.);
00292                 int tqr = (int)(tr/2.);
00293                 pz = (pz+(double)( tz-(int)(tz/2.)*2. ))/2.;
00294                 pr = ( pr + (double)(tr-tqr*2) )/2.;
00295                 double f = 1.;
00296                 //              if( phi < (PI/2.) && phi >= (-PI/2.) ) {
00297                 //                phi = PI-phi;
00298                 //                f =-1.;
00299                 //              } else if( phi < -PI/2. ) {
00300                 //                phi = 2.*PI+phi;
00301                 //              }
00302                 //              double pphi = ( phi-PI/2. )/(11.25/180.*PI);
00303                 double phi_tmp = phi;
00304                 if( phi_tmp < (PI/2.) && phi_tmp >= (-PI/2.) ) {
00305                   phi_tmp = PI-phi_tmp;
00306                   f =-1.;
00307                 } else if( phi_tmp < -PI/2. ) {
00308                   phi_tmp = 2.*PI+phi_tmp;
00309                 }
00310                 double pphi = ( phi_tmp-PI/2. )/(11.25/180.*PI);
00311                 int tphi = (int)pphi;
00312                 pphi -= (double)tphi;
00313                 if (tphi >= 16) tphi -= 16;
00314                 
00315                 bz += f*
00316                   (((_BzQL[tphi][tqr][tqz]*(1.-pz)+_BzQL[tphi][tqr][tqz+1]*pz)
00317                   *(1-pr)+(_BzQL[tphi][tqr+1][tqz]*(1.-pz)
00318                   +_BzQL[tphi][tqr+1][tqz+1]*pz)*pr)*(1.-pphi)
00319                   +((_BzQL[tphi+1][tqr][tqz]*(1.-pz)
00320                   +_BzQL[tphi+1][tqr][tqz+1]*pz)*(1.-pr)
00321                   +(_BzQL[tphi+1][tqr+1][tqz]*(1.-pz)
00322                   +_BzQL[tphi+1][tqr+1][tqz+1]*pz)*pr)*pphi);
00323                 br += f*
00324                   (((_BrQL[tphi][tqr][tqz]*(1.- pz)
00325                   +_BrQL[tphi][tqr][tqz+1]*pz)*(1.-pr)
00326                   +(_BrQL[tphi][tqr+1][tqz]*(1.-pz)
00327                   +_BrQL[tphi][tqr+1][tqz+1]*pz)*pr)*(1-pphi)
00328                   +((_BrQL[tphi+1][tqr][tqz]*(1.- pz)
00329                   +_BrQL[tphi+1][tqr][tqz+1]*pz)*(1.-pr)
00330                   +(_BrQL[tphi+1][tqr+1][tqz]*(1.-pz)
00331                   +_BrQL[tphi+1][tqr+1][tqz+1]*pz)*pr)*pphi);
00332                 bphi += f*
00333                   (((_BphiQL[tphi][tqr][tqz]*(1.- pz)
00334                   +_BphiQL[tphi][tqr][tqz+1]*pz)*(1.-pr)
00335                   +(_BphiQL[tphi][tqr+1][tqz]*(1.-pz)
00336                   +_BphiQL[tphi][tqr+1][tqz+1]*pz)*pr)*(1.-pphi)
00337                   +((_BphiQL[tphi+1][tqr][tqz]*(1.- pz)
00338                   +_BphiQL[tphi+1][tqr][tqz+1]*pz)*(1.-pr)
00339                   +(_BphiQL[tphi+1][tqr+1][tqz]*(1.-pz)
00340                   +_BphiQL[tphi+1][tqr+1][tqz+1]*pz)*pr)*pphi);
00341               }
00342             }
00343          }  else {
00344            bz=0.;
00345            br=0.;
00346            bphi=0.;
00347          }
00348       } else if(zmm>=-1520. && zmm<=2460. && rmm<=0. && rmm<=1740.){
00349         if(tz == 246) tz=tz-1;
00350         if(tr == 174) tr=tr-1;
00351         double pz= (zmm + 1520.)/10.- (double)tz;
00352         double pr=  rmm/10.- (double)tr;
00353         bz   = (_Bz[tr][tz]*(1.- pz)+_Bz[tr][tz+1]*pz)*(1.-pr)+
00354                (_Bz[tr+1][tz]*(1.-pz)+_Bz[tr+1][tz+1]*pz)*pr;
00355 
00356         br   = (_Br[tr][tz]*(1.-pz)+_Br[tr][tz+1]*pz)*(1.-pr)+
00357                (_Br[tr+1][tz]*(1.-pz)+_Br[tr+1][tz+1]*pz)*pr;
00358 
00359         bphi = (_Bphi[tr][tz]*(1.-pz)+_Bphi[tr][tz+1]*pz)*(1.-pr)+
00360                (_Bphi[tr+1][tz]*(1.-pz)+_Bphi[tr+1][tz+1]*pz)*pr;
00361       } else {
00362         bz =0.;
00363         br =0.;
00364         bphi =0.;
00365       }
00366       
00367 
00368       //... Set B field
00369       double Bmag_xy = (double)sqrt(br*br + bphi*bphi);
00370       double Bphi_rp = (double)atan2( (double)bphi, (double)br );
00371       m_Bx = Bmag_xy * (double)cos((double)phi + Bphi_rp)/1000.;
00372       m_By = Bmag_xy * (double)sin((double)phi + Bphi_rp)/1000.;   
00373       //m_Bx = br * (double)cos((double)phi)/1000.;
00374       //m_By = br * (double)sin((double)phi)/1000.;   
00375       m_Bz = bz/1000.;
00376       m_x = x;
00377       m_y = y;
00378       m_z = z;
00379       m_Bfld.setX((double) m_Bx);
00380       m_Bfld.setY((double) m_By);
00381       m_Bfld.setZ((double) m_Bz);
00382 }
00383 
00384 
00385 //
00386 //... Fortran callable access functions to Bfield class.
00387 //
00388 
00389 // initialize bfield map
00390 extern "C"
00391 void init_bfield_(int *imap) {
00392   // create Bfiled map ID = imap
00393   //  Bfield *thisMap = Bfield::getBfield(*imap);
00394   (void) Bfield::getBfield(*imap);
00395   // It is OK even though 'thisMap' losts its scope at here.
00396   // Because address of field map is not deleted from memory
00397   // due to static linkaged Bfield class.
00398   return;
00399 }
00400 
00401 // retrieving B field corresponding to the POSition
00402 extern "C"
00403 void get_bfield_(int *imap, double *pos, double *field, int *error) {
00404   Bfield *thisMap = Bfield::getBfield(*imap);
00405   // std::cout << " > accessing Bfield class from fortran routine." << std::endl;
00406   if( thisMap != 0 ) {
00407     thisMap->fieldMap(pos,field);
00408     *error = 0;
00409   }
00410   else *error = 1;
00411   return;
00412 }

Generated on Tue Nov 29 23:13:23 2016 for BOSS_7.0.2 by  doxygen 1.4.7