Fork me on GitHub

Changeset 294 in svn for trunk


Ignore:
Timestamp:
Mar 9, 2009, 12:30:27 AM (16 years ago)
Author:
Xavier Rouby
Message:

bug free bfield?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/BFieldProp.cc

    r291 r294  
    3131
    3232#include "BFieldProp.h"
     33#include "SystemOfUnits.h"
     34#include "PhysicalConstants.h"
    3335#include<cmath>
    3436using namespace std;
     
    105107  // DET has been initialised in the constructors
    106108  // magnetic field parameters
    107    R_max = DET->TRACK_radius;
    108    z_max = DET->TRACK_length/2.;
    109    B_x = DET->TRACK_bfield_x;
    110    B_y = DET->TRACK_bfield_y;
     109   R_max = DET->TRACK_radius/100.; //[m]
     110   z_max = DET->TRACK_length/200.; //[m]
     111   B_x = DET->TRACK_bfield_x*tesla;
     112   B_y = DET->TRACK_bfield_y*tesla;
    111113   B_z = DET->TRACK_bfield_z;
    112114
     
    116118
    117119
    118 void TrackPropagation::Propagation(const TRootGenParticle *Part,TLorentzVector &momentum) {
    119 
    120   q  = ChargeVal(Part->PID);
     120
     121
     122
     123void TrackPropagation::bfield(TRootGenParticle *Part) {
     124
     125
     126  // initialisation, valid for z_max==0, R_max==0 and q==0
     127  Part->EtaCalo = Part->Eta;
     128  Part->PhiCalo = Part->Phi;//-atan2(Part->Px,Part->Py);
     129
     130  // trivial cases
     131  if (!DET->FLAG_bfield ) return;
     132
     133  q  = ChargeVal(Part->PID) *eplus; // in units of 'e'
    121134  if(q==0) return;
    122 
    123   if(R_max ==0) { cout << "ERROR: magnetic field has no lateral extention\n"; return;}
     135  if(R_max==0) { cout << "ERROR: magnetic field has no lateral extention\n"; return;}
    124136  if(z_max==0) { cout << "ERROR: magnetic field has no longitudinal extention\n"; return;}
     137
     138  double X  = Part->X/1000.;//[m]
     139  double Y  = Part->Y/1000.;//[m]
     140  double Z  = Part->Z/1000.;//[m]
     141
     142  // out of tracking coverage?
     143  if(sqrt(X*X+Y*Y) > R_max){return;}
     144  if(fabs(Z) > z_max){return;}
    125145
    126146  if (B_x== 0 && B_y== 0) { // faster if only B_z
    127147    if (B_z==0) return; // nothing to do
    128148
     149
     150     //in test mode, just run once
     151     if (loop_overflow_counter) return;
     152 
    129153    // initial conditions:
    130154      // p_X0 = Part->Px, p_Y0 = Part->Py, p_Z0 = Part->Pz, p_T0 = Part->PT;
     
    136160    //     giration frequency \omega = q/(gamma m) B_z
    137161    //     helix radius r = p_T0 / (omega gamma m)
    138       phi_0 = -atan2(Part->Px,Part->Py);
    139       gammam = Part->E; // here c==1
    140       //cout << "gammam" << gammam << "\t gamma" << gammam/Part->M << endl;
    141       omega = q * B_z /gammam;
    142       //r = Part->PT / (omega * gammam);
    143       r = fabs(Part->PT / (omega * gammam));
     162    double Px = Part->Px; // [GeV/c]
     163    double Py = Part->Py;
     164    double Pz = Part->Pz;
     165    double PT = Part->PT;
     166    double E  = Part->E;              // [GeV]
     167    double M  = Part->M;              // [GeV]/c²
     168      double Phi = UNDEFINED;
     169
     170      unsigned int method =2;
     171      gammam = E * 1E-9 ;                   // gammam in [eV]
     172      omega = q * e_SI * B_z *  2.99792458E+8* 2.99792458E+8 / gammam;  // omega is here in [rad/s] 
     173      r = PT * 1E-9 *  2.99792458E+8 / (omega * gammam );             // in [m]  m2 /( s)
     174
     175      // test mode
     176      bool test=false; if(test) loop_overflow_counter++;
     177
     178    // test -- point 1) // tests faciles: changer le signe de q et de Py
     179    if(test && false) {
     180      q = -e_SI; X = Y = Z = Px = Pz = M = 0;
     181      Py= R_max * (q*B_z);
     182      PT = sqrt(Px*Px + Py*Py + Pz*Pz);
     183      E = PT* 2.99792458E+8; gammam = PT/ 2.99792458E+8;
     184      omega = q/e_SI * 2.99792458E+8/R_max; // omega has a sign!
     185      r = PT / (omega * gammam );           // r has a sign!
     186    }
     187    // test -- point 2)
     188    if(test && false) {
     189      q = e_SI; X = R_max/2.; Y = Z = Px = Pz = M = 0;
     190      Py= -R_max * (q*B_z);
     191      PT = sqrt(Px*Px + Py*Py + Pz*Pz);
     192      E = PT* 2.99792458E+8; gammam = PT/ 2.99792458E+8;
     193      omega = q/e_SI * 2.99792458E+8/R_max;
     194      r = PT / (omega * gammam );
     195    }
     196    // test -- point 3)
     197    if(test && false) {
     198      q = -e_SI; X = 0; Y= -R_max/2.; Z = Px = Pz = M = 0;
     199      Py= R_max * (q*B_z);
     200      PT = sqrt(Px*Px + Py*Py + Pz*Pz);
     201      E = PT* 2.99792458E+8; gammam = PT/ 2.99792458E+8;
     202      omega = q/e_SI * 2.99792458E+8/R_max;
     203      r = PT / (omega * gammam );
     204    }
     205    // test -- point 4)
     206    if(test && false) {
     207      q = -e_SI; X = R_max/2.; Y = Z = Py = Pz = M = 0;
     208      Px= R_max * (q*B_z);
     209      PT = sqrt(Px*Px + Py*Py + Pz*Pz);
     210      E = PT* 2.99792458E+8; gammam = PT/ 2.99792458E+8;
     211      omega = q/e_SI * 2.99792458E+8/R_max;
     212      r = PT / (omega * gammam );
     213    }
     214    // test -- point 5)
     215    if(test && false) {
     216      q = e_SI; X = -R_max/2.; Y = Z = Px = Pz = M = 0;
     217      Py= -R_max * (q*B_z);
     218      PT = sqrt(Px*Px + Py*Py + Pz*Pz);
     219      E = PT* 2.99792458E+8; gammam = PT/ 2.99792458E+8;
     220      omega = q/e_SI * 2.99792458E+8/R_max;
     221      r = PT / (omega * gammam );
     222    }
     223    // test -- point 6)
     224    if(test && true) {
     225      q = e_SI; Y = -R_max/2.; X = Z = Py = Pz = M = 0;
     226      Px= -R_max * (q*B_z);
     227      PT = sqrt(Px*Px + Py*Py + Pz*Pz);
     228      E = PT* 2.99792458E+8; gammam = PT/ 2.99792458E+8;
     229      omega = q/e_SI * 2.99792458E+8/R_max;
     230      r = PT / (omega * gammam );
     231    }
     232
     233
     234double delta= UNDEFINED;
     235
     236if (method==1) {
     237
     238      phi_0 = -atan2(Px,Py);                // [rad]
     239      //if(phi_0<0)phi_0 = 2*pi+phi_0;        // [rad], in [0 - 2 pi]
    144240
    145241    // 2.  Helix parameters : center coordinates in transverse plane
    146242    //     x_c = x_0 - r*cos(phi_0) and y_c = y_0 - r*sin(phi_0)
    147243    //     R_c = \sqrt{x_c² + y_c²} and \Phi_c = atan{y_c/x_c}
    148       x_c = Part->X - r*cos(phi_0);  /// TEST !!
    149       y_c = Part->Y - r*sin(phi_0);
     244      x_c = X - r*cos(phi_0);
     245      y_c = Y - r*sin(phi_0);
    150246      R_c = sqrt(pow(x_c,2.) + pow(y_c,2.) );
    151247      Phi_c = atan2(y_c,x_c);
     248      //if(Phi_c<0)Phi_c = 2*pi+Phi_c;
     249      Phi = Phi_c;
     250      //r=fabs(r);
    152251
    153252    // 3. time evaluation t = min(t_T, t_z)
     
    157256    //    t_z = gamma * m /p_z0 \times (-z_0 + z_max * sign(p_z0))
    158257      rr = sqrt( pow(R_c,2.) + pow(r,2.) ); // temp variable
    159       t_T=0;
    160       int sign_pz= (Part->Pz >0) ? 1 : -1;
    161       t_z = gammam / Part->Pz * (-Part->Z + z_max*sign_pz ) ;
     258      t_T=0; //[ns]
     259      int sign_pz= (Pz >0) ? 1 : -1;
     260      if(Pz==0) t_z = 1E99;
     261      else t_z = gammam / (Pz*1E-9* 2.99792458E+8) * (-Z + z_max*sign_pz );
     262      if( t_z <0) cout << "ERROR: t_z <0 !" << endl;
     263
    162264      if ( fabs(R_c - r) > R_max || R_c + r  < R_max ) t = t_z;
    163265      else {
    164266         if(r==0|| R_c ==0) t_T=1E99;
    165          //else t_T = (Phi_c - phi_0 + atan2( (R_max + rr)*(R_max - rr) , 2*r*R_c ) ) / omega;
    166          else t_T = (Phi_c - phi_0 + acos( (R_max + rr)*(R_max - rr) / (2*r*R_c) ) ) / omega;
    167          t = min(t_T,t_z);
     267         else {
     268                //t_T = fabs((Phi_c - phi_0 - acos( (R_max + rr)*(R_max - rr) / (2*r*R_c) ))/omega) ;
     269                double A = fabs(acos( (R_max + rr)*(R_max - rr) / (2*r*R_c) )) ;
     270                double a = phi_0 + A;
     271       // validé si acos >0 , mais quid si acos < 0?
     272
     273                double tm = (Phi_c - a) / omega;
     274                double tp = (-Phi_c + a) / omega;
     275                //cout << "t- = " << tm << "\t t+ = " << tp << endl;
     276                if(tm<0) t_T = tp;
     277                else if(tp<0) t_T=tm;
     278                else t_T = min(tm,tp);
     279
     280                //cout << "t_T = " << t_T << "\t T_z = " << t_z << "\t r = " << r << endl;
     281                t = min(t_T,t_z); // t is output here in [ns], which is compatible with omega
     282         }
    168283      }
    169284
    170285    // 4. position in terms of x(t), y(t), z(t)
    171     //    x(t) = x_c + r cos (omega t + phi_0)
    172     //    y(t) = y_c + r sin (omega t + phi_0)
    173     //    z(t) = z_0 + (p_Z0/gammam) t
    174286      x_t = x_c + r * cos(omega * t + phi_0);
    175287      y_t = y_c + r * sin(omega * t + phi_0);
    176       z_t = Part->Z + Part->Pz / gammam * t;
     288      z_t = Z + Pz*1E-9* 2.99792458E+8 / gammam * t;
    177289
    178290    // 5. position in terms of Theta(t), Phi(t), R(t), Eta(t)
    179     //    R(t) = sqrt(x(t)² + y(t)²)
    180     //    Phi(t) = atan(y(t)/x(t))
    181     //    Theta(t) = atan(R(t)/z(t))
    182     //    Eta(t) = -ln tan (Theta(t)/2)
    183291      R_t   = sqrt( pow(x_t,2.) + pow(y_t,2.)  );
    184292      Phi_t = atan2( y_t, x_t);
     
    187295              Eta_t = - log(tan(Theta_t/2.));
    188296      } else{
    189                 Theta_t=0; Eta_t = 9999;
     297                Theta_t=0; Eta_t = UNDEFINED;
    190298      }
    191299
    192         Px_t = - Part->PT * sin(omega*t + phi_0);
    193         Py_t =   Part->PT * cos(omega*t + phi_0);
    194         Pz_t =   Part->Pz;
     300      //if(phi_0 <0 || phi_0 > 2*pi) cout <<"ERROR: phi_0 out of range: [0 ; 2pi] " << phi_0 << endl;
     301      //if(Phi_c <0 || Phi_c > 2*pi) cout <<"ERROR: Phi_c out of range: [0 ; 2pi] " << Phi_c << endl;
     302
     303} // method 1
     304else {
     305
     306      phi_0 = atan2(Py,Px); // [rad] in [-pi ; pi ]
     307      //if(phi_0<0)phi_0 = 2*pi+phi_0;        // [rad], in [0 - 2 pi]
     308
     309      x_c = X + r*sin(phi_0);
     310      y_c = Y - r*cos(phi_0);
     311      R_c = sqrt( pow(x_c,2.) + pow(y_c,2.) );
     312      Phi_c = atan2(y_c,x_c);
     313      Phi = Phi_c;
     314      if(x_c<0) Phi += pi;
     315      //if(Phi<0)Phi = 2*pi+Phi; // ne pas le mettre pour que le test1 fonctionne
     316
     317    // 3. time evaluation t = min(t_T, t_z)
     318    //    t_T : time to exit from the sides
     319    //    t_z : time to exit from the front or the back
     320      rr = sqrt( pow(R_c,2.) + pow(r,2.) ); // temp variable
     321      t_T=0; //[ns]
     322      int sign_pz= (Pz >0) ? 1 : -1;
     323      if(Pz==0) t_z = 1E99;
     324      else t_z = gammam / (Pz*1E-9* 2.99792458E+8) * (-Z + z_max*sign_pz );
     325      if( t_z <0) cout << "ERROR: t_z <0 !" << endl;
     326
     327      if ( fabs(R_c - fabs(r)) > R_max || R_c + fabs(r)  < R_max ) t = t_z;
     328      else {
     329         if(r==0) cout << "r ==0 !" << endl;
     330         if(R_c==0) cout << "R_c ==0 !" << endl;
     331         if(r==0|| R_c ==0) t_T=1E99;
     332         else {
     333                double asinrho = asin( (R_max + rr)*(R_max - rr) / (2*fabs(r)*R_c)  );
     334                delta = phi_0 - Phi;
     335                if(delta<-pi) delta += 2*pi;
     336                if(delta> pi) delta -= 2*pi;
     337                double t1 = (delta + asinrho) / omega;
     338                double t2 = (delta + pi - asinrho) / omega;
     339                double t3 = (delta + pi + asinrho) / omega;
     340                double t4 = (delta - asinrho) / omega;
     341                double t5 = (delta - pi - asinrho) / omega;
     342                double t6 = (delta - pi + asinrho) / omega;
     343
     344                if(test) {
     345                        cout << "t4 = " << t4 << "\t t5 = " << t5 << "\t t_6=" << t6 << "\t t_3 = " << t3 << endl;
     346                        cout << "t1 = " << t1 << "\t t2 = " << t2 << "\t t_T=" << t_T << "\t t_z = " << t_z << endl;
     347                        cout << "delta= " << delta << endl;
     348                }
     349                if(t1<0)t1=1E99;
     350                if(t2<0)t2=1E99;
     351                if(t3<0)t3=1E99;
     352                if(t4<0)t4=1E99;
     353                if(t5<0)t5=1E99;
     354                if(t6<0)t6=1E99;
     355
     356                double t_Ta = min(t1,min(t2,t3));
     357                double t_Tb = min(t4,min(t5,t6));
     358                t_T = min(t_Ta,t_Tb);
     359
     360                //if(t1<0) t_T = t2;
     361                //else if(t2<0) t_T = t1;
     362                //else {t_T = min(t1,t2); /*cout << "**";*/}
     363                //if (t1<0 && t2<0) {t_T = fabs(min(t1,t2)); cout << "\tbad!!\n";}
     364                t = min(t_T,t_z);
     365                if(test) {
     366                  // cout << "t4 = " << t4 << "\t t5 = " << t5 << "\t t_6=" << t6 << "\t t_3 = " << t3 << endl;
     367                  // cout << "t1 = " << t1 << "\t t2 = " << t2 << "\t t_T=" << t_T << "\t t_z = " << t_z << endl;
     368                }
     369         }
     370      }
     371//r = PT / (omega * gammam );
     372
     373    // 4. position in terms of x(t), y(t), z(t)
     374      x_t = x_c + r * sin(omega * t - phi_0);
     375      y_t = y_c + r * cos(omega * t - phi_0);
     376      z_t = Z + Pz*1E-9* 2.99792458E+8 / gammam * t;
     377
     378    // 5. position in terms of Theta(t), Phi(t), R(t), Eta(t)
     379      R_t   = sqrt( pow(x_t,2.) + pow(y_t,2.)  );
     380      Phi_t = atan2( y_t, x_t);
     381      if(R_t>0) {
     382                Theta_t = acos( z_t / sqrt(z_t*z_t+ R_t*R_t));
     383                Eta_t = - log(tan(Theta_t/2.));
     384      }
     385      else {
     386                Theta_t=0; Eta_t = UNDEFINED;
     387      }
     388} // method2
     389
     390     if(test) {
     391        cout << endl << endl;
     392        cout << "method " << method << "----------------\n";
     393        cout << "x0,y0,z0= " << X << ", " << Y << ", " << Z << endl;
     394        cout << "px0,py0,pz0= " << Px << ", " << Py << ", " << Pz << endl;
     395        cout << "r = " << r << "R_max = " << R_max << "\t phi_0=" << phi_0 << endl;
     396        cout << "gammam= " << gammam << "\t omega=" << omega << "\t PT = " << PT << endl;
     397        cout << "x_c = " << x_c << "\t y_c = " << y_c << "\t R_c = " << R_c << "\t Phi = " << Phi << endl;
     398        cout << "omega t = " << omega*t << "\t";
     399        cout << "cos(omega t -phi0)= " << cos(omega*t-phi_0) << "\t sin(omega t -phi0)= " << sin(omega*t-phi_0) << endl;
     400        cout << "t_T = " << t_T << "\t t_z = " << t_z << "\t r = " << r << endl;
     401        cout << "x_t = " << x_t << "\t y_t = " << y_t << "\t z_t = " << z_t << endl;
     402        cout << "R_t = " << R_t << "\t Phi_t = " << Phi_t << "\t";
     403        cout << "Theta_t = " << Theta_t << "\t Eta_t = " << Eta_t << endl;
     404     }
     405
     406     
     407/*      Not needed here. but these formulae are correct -------
     408        // method1
     409        Px_t = - PT * sin(omega*t + phi_0);
     410        Py_t =   PT * cos(omega*t + phi_0);
     411
     412        // method2
     413        Px_t =   PT * cos(phi_0 - omega*t); 
     414        Py_t =   PT * sin(phi_0 - omega*t);
     415
     416        Pz_t =   Pz;
    195417        PT_t =   sqrt(Px_t*Px_t + Py_t*Py_t);
    196418        p_t = sqrt(PT_t*PT_t + Pz_t*Pz_t);
    197         E_t=sqrt(Part->M*Part->M +p_t);
     419        E_t=sqrt(M*M +p_t*p_t);
    198420        //if(p_t != fabs(Pz_t) ) Eta_t = log( (p_t+Pz_t)/(p_t-Pz_t) )/2.;
    199         //if(p_t>0) Theta_t = acos(Pz_t/p_t);
     421        //if(p_t>0) Theta_t = acos(Pz_t/p_t)>;
    200422        momentum.SetPxPyPzE(Px_t,Py_t,Pz_t,E_t);
     423*/
     424
     425//cout << "R_c = " << R_c << " r " << r << " rr = " << rr << " R_t" << R_t << endl;
     426//cout << "x_t = " << x_t << " x_c = " << x_c <<  "\ty_t = " << y_t << " y_c = " << y_c << " z_t " << z_t << endl;
     427//cout << "Eta = " << Part->Eta << " Eta_t " << Eta_t << "Phi = " << Part->Phi << " Phi_t= " << Phi_t << "-----" << endl;
     428        Part->EtaCalo = Eta_t;
     429        Part->PhiCalo = Phi_t;
    201430
    202431// test zone ---
    203432/*
     433
     434        cout << "r = " << r << " et " << fabs(PT/(q*B_z)) << endl;
    204435        cout << cos(atan(R_t/z_t)) << "\t" << cos(Theta_t) << "\t" << cos(momentum.Theta()) << "\t" << Pz_t/temp_p << endl;
    205436        double Eta_t1 = log( (E+Pz_t)/(E-Pz_t) )/2.;
     
    232463   //cout << "tan(phi_p)= " << momentum.Py()/momentum.Px() << "\t -1/tan(phi_x)= " << -x_t/y_t << endl;
    233464*/
     465        return;
    234466
    235467  } else { // if B_x or B_y are non zero: longer computation
    236 
     468//cout << "bfield de loic\n";
    237469  float Xvertex1 = Part->X;
    238470  float Yvertex1 = Part->Y;
    239471  float Zvertex1 = Part->Z;
    240  
    241   //out of tracking coverage?
    242   if(sqrt(Xvertex1*Xvertex1+Yvertex1*Yvertex1) > R_max){return;}
    243   if(fabs(Zvertex1) > z_max){return;}
    244472 
    245473  double px = Part->Px / 0.003;
     
    254482  double vz = pz/M;
    255483  double qm = q/M;
    256 
    257   double ax =  qm*(B_z*vy - B_y*vz);
    258   double ay =  qm*(B_x*vz - B_z*vx);
    259   double az =  qm*(B_y*vx - B_x*vy);
    260   double dt = 1/p;
    261   if(pt<266 && vz < 0.0012)       dt = fabs(0.001/vz); // ?????
    262484 
    263   double xold=Xvertex1;         double x=xold;
    264   double yold=Yvertex1;         double y=yold;
    265   double zold=Zvertex1;         double z=zold;
    266 
    267   double VTold = pt/M; //=sqrt(vx*vx+vy*vy);
    268  
    269   unsigned int k = 0;
    270   double VTratio=0;
    271   double R_max2 = R_max*R_max;
    272   double r2=0; // will be x*x+y*y
    273 
    274   while(k < MAXITERATION){
    275         k++;
    276 
    277         vx += ax*dt;
    278         vy += ay*dt;
    279         vz += az*dt;
    280 
    281         VTratio = VTold/sqrt(vx*vx+vy*vy);
    282         vx *= VTratio;
    283         vy *= VTratio;
    284 
    285         ax = qm*(B_z*vy - B_y*vz);
    286         ay = qm*(B_x*vz - B_z*vx);
    287         az = qm*(B_y*vx - B_x*vy);
    288 
    289         x  += vx*dt;
    290         y  += vy*dt;
    291         z  += vz*dt;
    292         r2  = x*x + y*y;
    293 
    294        if( r2 > R_max2 ){
    295                 x /= r2/R_max2;
    296                 y /= r2/R_max2;
    297                 break;
    298        }
    299        if( fabs(z)>z_max)break;
    300 
    301        xold = x;
    302        yold = y;
    303        zold = z;
    304   } // while loop
    305 
    306   if(k == MAXITERATION) loop_overflow_counter++;
    307   //cout << "too short loop in " << loop_overflow_counter << " cases" << endl;
    308  
    309   if(x!=0 && y!=0 && z!=0) {
    310           float Theta = atan2(sqrt(r2),z);
    311           double eta  = -log(tan(Theta/2.));
    312           double phi = atan2(y,x);
    313           momentum.SetPtEtaPhiE(Part->PT,eta,phi,Part->E);
    314   }
    315    
    316  } // if b_x or b_y non zero
    317 }
    318 
    319 
    320 
    321 void TrackPropagation::bfield(TRootGenParticle *Part) {
    322 
    323   // initialisation, valid for z_max==0, R_max==0 and q==0
    324   Part->EtaCalo = Part->Eta;
    325   Part->PhiCalo = Part->Phi;//-atan2(Part->Px,Part->Py);
    326 
    327   if (!DET->FLAG_bfield ) return;
    328 
    329   q  = ChargeVal(Part->PID);
    330   if(q==0) return;
    331   if(R_max ==0) { cout << "ERROR: magnetic field has no lateral extention\n"; return;}
    332   if(z_max==0) { cout << "ERROR: magnetic field has no longitudinal extention\n"; return;}
    333 
    334   if (B_x== 0 && B_y== 0) { // faster if only B_z
    335     if (B_z==0) return; // nothing to do
    336 
    337     // initial conditions:
    338       // p_X0 = Part->Px, p_Y0 = Part->Py, p_Z0 = Part->Pz, p_T0 = Part->PT;
    339       // X_0 = Part->X, Y_0 = Part->Y, Z_0 = Part->Z;
    340 
    341     // 1.  initial transverse momentum p_{T0} : Part->PT
    342     //     initial transverse momentum direction \phi_0 = -atan(p_X0/p_Y0)
    343     //     relativistic gamma : gamma = E/mc² ; gammam = gamma \times m
    344     //     giration frequency \omega = q/(gamma m) B_z
    345     //     helix radius r = p_T0 / (omega gamma m)
    346       phi_0 = -atan2(Part->Px,Part->Py);
    347       gammam = Part->E; // here c==1
    348       //cout << "gammam" << gammam << "\t gamma" << gammam/Part->M << endl;
    349       omega = q * B_z /gammam;
    350       r = fabs(Part->PT / (omega * gammam));
    351 
    352     // 2.  Helix parameters : center coordinates in transverse plane
    353     //     x_c = x_0 - r*cos(phi_0) and y_c = y_0 - r*sin(phi_0)
    354     //     R_c = \sqrt{x_c² + y_c²} and \Phi_c = atan{y_c/x_c}
    355       x_c = Part->X - r*cos(phi_0);  /// TEST !!
    356       y_c = Part->Y - r*sin(phi_0);
    357       R_c = sqrt(pow(x_c,2.) + pow(y_c,2.) );
    358       Phi_c = atan2(y_c,x_c);
    359 
    360     // 3. time evaluation t = min(t_T, t_z)
    361     //    t_T : time to exit from the sides
    362     //    t_T= [ Phi_c - phi_0 + acos( (R_max^2 - (R_c^2 + r^2))/(2rR_c) )  ]/omega
    363     //    t_z : time to exit from the front or the back
    364     //    t_z = gamma * m /p_z0 \times (-z_0 + z_max * sign(p_z0))
    365       rr = sqrt( pow(R_c,2.) + pow(r,2.) ); // temp variable
    366       t_T=0;
    367       int sign_pz= (Part->Pz >0) ? 1 : -1;
    368       t_z = gammam / Part->Pz * (-Part->Z + z_max*sign_pz ) ;
    369       if ( fabs(R_c - r) > R_max || R_c + r  < R_max ) t = t_z;
    370       else {
    371          if(r==0|| R_c ==0) t_T=1E99;
    372          //else t_T = (Phi_c - phi_0 + atan2( (R_max + rr)*(R_max - rr) , 2*r*R_c ) ) / omega;
    373          else t_T = (Phi_c - phi_0 + acos( (R_max + rr)*(R_max - rr) / (2*r*R_c) ) ) / omega;
    374          t = min(t_T,t_z);
    375       }
    376 
    377     // 4. position in terms of x(t), y(t), z(t)
    378     //    x(t) = x_c + r cos (omega t + phi_0)
    379     //    y(t) = y_c + r sin (omega t + phi_0)
    380     //    z(t) = z_0 + (p_Z0/gammam) t
    381       x_t = x_c + r * cos(omega * t + phi_0);
    382       y_t = y_c + r * sin(omega * t + phi_0);
    383       z_t = Part->Z + Part->Pz / gammam * t;
    384 
    385     // 5. position in terms of Theta(t), Phi(t), R(t), Eta(t)
    386     //    R(t) = sqrt(x(t)² + y(t)²)
    387     //    Phi(t) = atan(y(t)/x(t))
    388     //    Theta(t) = atan(R(t)/z(t))
    389     //    Eta(t) = -ln tan (Theta(t)/2)
    390       R_t   = sqrt( pow(x_t,2.) + pow(y_t,2.)  );
    391       Phi_t = atan2( y_t, x_t);
    392       if(R_t>0) {
    393               Theta_t = acos( z_t / sqrt(z_t*z_t+ R_t*R_t));
    394               Eta_t = - log(tan(Theta_t/2.));
    395       } else{
    396                 Theta_t=0; Eta_t = UNDEFINED;
    397       }
    398 /*      Not needed here. but these formulae are correct -------
    399         Px_t = - Part->PT * sin(omega*t + phi_0);
    400         Py_t =   Part->PT * cos(omega*t + phi_0);
    401         Pz_t =   Part->Pz;
    402         PT_t =   sqrt(Px_t*Px_t + Py_t*Py_t);
    403         p_t = sqrt(PT_t*PT_t + Pz_t*Pz_t);
    404         E_t=sqrt(Part->M*Part->M +p_t);
    405         //if(p_t != fabs(Pz_t) ) Eta_t = log( (p_t+Pz_t)/(p_t-Pz_t) )/2.;
    406         //if(p_t>0) Theta_t = acos(Pz_t/p_t);
    407         momentum.SetPxPyPzE(Px_t,Py_t,Pz_t,E_t);
    408 */
    409         Part->EtaCalo = Eta_t;
    410         Part->PhiCalo = Phi_t;
    411         return;
    412 // test zone ---
    413 /*
    414         cout << cos(atan(R_t/z_t)) << "\t" << cos(Theta_t) << "\t" << cos(momentum.Theta()) << "\t" << Pz_t/temp_p << endl;
    415         double Eta_t1 = log( (E+Pz_t)/(E-Pz_t) )/2.;
    416         double Eta_t2 = log( (temp_p+Pz_t)/(temp_p-Pz_t) )/2.;
    417         if(0 &&  fabs(Eta_t -Eta_t2)>1e-310) {
    418                 cout << "ERROR-BUG: Eta_t != Eta_t2\n";
    419                 cout << "Eta_t= " << Eta_t << "\t Eta_t1= " << Eta_t1 << "\t Eta_t2= " << Eta_t2 << endl;
    420         }
    421 
    422         double R_t2  = sqrt( pow(R_c,2.) + pow(r,2.) + 2*r*R_c*cos(phi_0 + omega*t - Phi_c) ); // cross-check
    423         if(fabs(R_t - R_t2) > 1e-7)
    424                 cout << "ERROR-BUG: R_t != R_t2:  R_t=" << R_t << " R_t2=" << R_t2 << " R_t - R_t2 =" << R_t - R_t2 << endl;
    425         if( fabs(E - gammam) > 1e-3 ) {
    426                 cout << "ERROR-BUG: energy is not conserved in src/BFieldProp.cc\n";
    427                 cout << "E - momentum.E() = " <<  fabs(E - momentum.E()) <<  " gammam - E " << fabs(gammam -E) << endl; }
    428         if( fabs(PT_t - Part->PT) > 1e-10 ) {
    429                 cout << "ERROR-BUG: PT is not conversed in src/BFieldProp.cc. ";
    430                 cout << "(at " << 100*(PT_t - Part->PT) << "%)\n";
    431                 }
    432         if(momentum.Pz() != Pz_t)
    433                 cout << "ERROR-BUG: Pz is not conserved in src/BFieldProp.cc\n";
    434 
    435         double temp_p0=sqrt(Part->PT*Part->PT + Part->Pz*Part->Pz);
    436         if(fabs( (temp_p-temp_p0)*(temp_p+temp_p0) )>1e-10  ) {
    437                 cout << "ERROR-BUG: momentum |vec{p}| is not conserved in src/BFieldProp.cc\n";
    438                 cout << temp_p << "\t" << temp_p0 << endl;
    439         }
    440 
    441    // if x_c == y_c ==0 (set it by hand!), easy cross-check
    442    //cout << "tan(phi_p)= " << momentum.Py()/momentum.Px() << "\t -1/tan(phi_x)= " << -x_t/y_t << endl;
    443 */
    444 
    445   } else { // if B_x or B_y are non zero: longer computation
    446 //cout << "bfield de loic\n";
    447   float Xvertex1 = Part->X;
    448   float Yvertex1 = Part->Y;
    449   float Zvertex1 = Part->Z;
    450  
    451   //out of tracking coverage?
    452   if(sqrt(Xvertex1*Xvertex1+Yvertex1*Yvertex1) > R_max){return;}
    453   if(fabs(Zvertex1) > z_max){return;}
    454  
    455   double px = Part->Px / 0.003;
    456   double py = Part->Py / 0.003;
    457   double pz = Part->Pz / 0.003;
    458   double pt = Part->PT / 0.003; // sqrt(px*px+py*py);
    459   double p  = sqrt(pz*pz + pt*pt); //sqrt(px*px+py*py+pz*pz);
    460  
    461   double M  = Part->M;
    462   double vx = px/M;
    463   double vy = py/M;
    464   double vz = pz/M;
    465   double qm = q/M;
     485//double v = sqrt(vx*vx + vy*vy + vz*vz)/3E8;
     486//cout << "v = " << v;
     487//double gamma = 1./sqrt(1-v*v);
     488//cout << "gamma = " << gamma << endl;
    466489
    467490  double ax =  qm*(B_z*vy - B_y*vz);
Note: See TracChangeset for help on using the changeset viewer.