LCOV - code coverage report
Current view: top level - TPC/TPCbase - AliTPCExBFirst.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 121 169 71.6 %
Date: 2016-06-14 17:26:59 Functions: 6 12 50.0 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       7             :  * Permission to use, copy, modify and distribute this software and its   *
       8             :  * documentation strictly for non-commercial purposes is hereby granted   *
       9             :  * without fee, provided that the above copyright notice appears in all   *
      10             :  * copies and that both the copyright notice and this permission notice   *
      11             :  * appear in the supporting documentation. The authors make no claims     *
      12             :  * about the suitability of this software for any purpose. It is          *
      13             :  * provided "as is" without express or implied warranty.                  *
      14             :  **************************************************************************/
      15             : 
      16             : /// \class AliTPCExBFirst
      17             : /// \brief This implementation AliTPCExB is using an aproximate calculation of the ExB effect
      18             : ///
      19             : /// Therefore the drift ODE is Taylor expanded and only the first
      20             : /// order part is taken.
      21             : ///
      22             : /// The ExB correction map is stored in the calib DB
      23             : /// To test current version:
      24             : ///
      25             : /// ~~~
      26             : /// char *storage = "local://OCDBres"
      27             : /// Int_t RunNumber=0;
      28             : /// AliCDBManager::Instance()->SetDefaultStorage(storage);
      29             : /// AliCDBManager::Instance()->SetRun(RunNumber)
      30             : /// AliTPCExBFirst * exb = AliTPCcalibDB::Instance()->GetExB();
      31             : ///
      32             : /// //  exb->TestExB("exb.root");
      33             : /// // TFile f("exb.root");
      34             : /// //positions->Draw("drphi");
      35             : /// ~~~
      36             : 
      37             : 
      38             : 
      39             : #include "TMath.h"
      40             : //#include "AliFieldMap.h"
      41             : #include "AliMagF.h"
      42             : #include "TTreeStream.h"
      43             : #include "AliTPCExBFirst.h"
      44             : 
      45             : /// \cond CLASSIMP
      46          24 : ClassImp(AliTPCExBFirst)
      47             : /// \endcond
      48             : 
      49             : const Double_t AliTPCExBFirst::fgkEM=1.602176487e-19/9.10938215e-31;
      50             : const Double_t AliTPCExBFirst::fgkDriftField=-40.e3;
      51             : 
      52           0 : AliTPCExBFirst::AliTPCExBFirst()
      53           0 :   : fDriftVelocity(0),
      54           0 :     fkNX(0),fkNY(0),fkNZ(0),
      55           0 :     fkXMin(-250.),fkXMax(250.),fkYMin(-250.),fkYMax(250.),
      56           0 :     fkZMin(-250.),fkZMax(250.),
      57           0 :     fkNMean(0),
      58           0 :     fkMeanBx(0),fkMeanBy(0),fkMeanBz(0.) {
      59             :   /// purely for I/O
      60             : 
      61           0 :   SetInstance(this);
      62           0 : }
      63             : 
      64           3 : AliTPCExBFirst::AliTPCExBFirst(const AliMagF *bField,
      65             :                                Double_t driftVelocity,
      66             :                                Int_t nx,Int_t ny,Int_t nz)
      67           3 :   : fDriftVelocity(driftVelocity),
      68           3 :     fkNX(nx),fkNY(ny),fkNZ(nz),
      69           3 :     fkXMin(-250.),fkXMax(250.),fkYMin(-250.),fkYMax(250.),
      70           3 :     fkZMin(-250.),fkZMax(250.),
      71           3 :     fkNMean(0),
      72          18 :     fkMeanBx(0),fkMeanBy(0),fkMeanBz(0.) {
      73             :   /// The constructor. One has to supply a magnetic field and an (initial)
      74             :   /// drift velocity. Since some kind of lookuptable is created the
      75             :   /// number of its meshpoints can be supplied.
      76             :   ///
      77             :   ///  ConstructCommon(0,bField);
      78             : 
      79           3 :   ConstructCommon(bField);
      80           3 :   SetInstance(this);
      81           6 : }
      82             : 
      83             : /*
      84             : AliTPCExBFirst::AliTPCExBFirst(const AliFieldMap *bFieldMap,
      85             :                                Double_t driftVelocity)
      86             :   : fDriftVelocity(driftVelocity),
      87             :     fkNX(0),fkNY(0),fkNZ(0),
      88             :     fkXMin(-250.),fkXMax(250.),fkYMin(-250.),fkYMax(250.),
      89             :     fkZMin(-250.),fkZMax(250.),
      90             :     fkNMean(0),
      91             :     fkMeanBx(0),fkMeanBy(0),fkMeanBz(0.) {
      92             :   //
      93             :   // The constructor. One has to supply a field map and an (initial)
      94             :   // drift velocity.
      95             :   //
      96             :   SetInstance(this);
      97             :   fkXMin=bFieldMap->Xmin()
      98             :     -TMath::Ceil( (bFieldMap->Xmin()+250.0)/bFieldMap->DelX())
      99             :     *bFieldMap->DelX();
     100             :   fkXMax=bFieldMap->Xmax()
     101             :     -TMath::Floor((bFieldMap->Xmax()-250.0)/bFieldMap->DelX())
     102             :     *bFieldMap->DelX();
     103             :   fkYMin=bFieldMap->Ymin()
     104             :     -TMath::Ceil( (bFieldMap->Ymin()+250.0)/bFieldMap->DelY())
     105             :     *bFieldMap->DelY();
     106             :   fkYMax=bFieldMap->Ymax()
     107             :     -TMath::Floor((bFieldMap->Ymax()-250.0)/bFieldMap->DelY())
     108             :     *bFieldMap->DelY();
     109             :   fkZMin=bFieldMap->Zmin()
     110             :     -TMath::Ceil( (bFieldMap->Zmin()+250.0)/bFieldMap->DelZ())
     111             :     *bFieldMap->DelZ();
     112             :   fkZMax=bFieldMap->Zmax()
     113             :     -TMath::Floor((bFieldMap->Zmax()-250.0)/bFieldMap->DelZ())
     114             :     *bFieldMap->DelZ();
     115             : 
     116             :   fkNX=static_cast<Int_t>((fkXMax-fkXMin)/bFieldMap->DelX()+1.1);
     117             :   fkNY=static_cast<Int_t>((fkYMax-fkYMin)/bFieldMap->DelY()+1.1);
     118             :   fkNZ=static_cast<Int_t>((fkZMax-fkZMin)/bFieldMap->DelZ()+1.1);
     119             : 
     120             :   ConstructCommon(bFieldMap,0);
     121             : }
     122             : */
     123             : 
     124           0 : AliTPCExBFirst::~AliTPCExBFirst() {
     125             :   /// destruct the poor object.
     126             : 
     127           0 :   delete[] fkMeanBx;
     128           0 :   delete[] fkMeanBy;
     129           0 : }
     130             : 
     131             : void AliTPCExBFirst::Correct(const Double_t *position,Double_t *corrected) {
     132             :   /// correct for the distortion
     133             : 
     134     3642536 :   Double_t bx,by;
     135     1821268 :   GetMeanFields(position[0],position[1],position[2],&bx,&by);
     136     1821268 :   if (position[2]>0.) {
     137      855710 :     Double_t bxe,bye;
     138      855710 :     GetMeanFields(position[0],position[1],250.,&bxe,&bye);
     139     1711420 :     if (position[2]!=250.) {
     140     1711420 :       bx=(500.*bxe-(position[2]+250.)*bx)/(250.-position[2]);
     141      855710 :       by=(500.*bye-(position[2]+250.)*by)/(250.-position[2]);
     142      855710 :     }
     143             :     else {
     144           0 :       bx=bxe;
     145           0 :       by=bye;
     146             :     }
     147      855710 :   }
     148             : 
     149     1821268 :   Double_t mu=fDriftVelocity/fgkDriftField;
     150     1821268 :   Double_t wt=mu*fkMeanBz;
     151             : 
     152     1821268 :   corrected[0]=mu*(wt*bx-by)/(1.+wt*wt);
     153     1821268 :   corrected[1]=mu*(wt*by+bx)/(1.+wt*wt);
     154             : 
     155     1821268 :   if (position[2]>0.) {
     156      855710 :     corrected[0]*=(250.-position[2]);
     157      855710 :     corrected[1]*=(250.-position[2]);
     158      855710 :   }
     159             :   else {
     160      965558 :     corrected[0]*=(-250.-position[2]);
     161      965558 :     corrected[1]*=(-250.-position[2]);
     162             :   }
     163             : 
     164     1821268 :   corrected[0]=position[0]-corrected[0];
     165     1821268 :   corrected[1]=position[1]-corrected[1];
     166     1821268 :   corrected[2]=position[2];
     167     1821268 : }
     168             : 
     169             : void AliTPCExBFirst::TestThisBeautifulObject(const char* fileName) {
     170             :   /// well, as the name sais...
     171             : 
     172           0 :   TTreeSRedirector ts(fileName);
     173           0 :   Double_t x[3];
     174           0 :   for (x[0]=-250.;x[0]<=250.;x[0]+=10.)
     175           0 :     for (x[1]=-250.;x[1]<=250.;x[1]+=10.)
     176           0 :       for (x[2]=-250.;x[2]<=250.;x[2]+=10.) {
     177           0 :         Double_t d[3];
     178           0 :         Correct(x,d);
     179           0 :         Double_t r=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
     180           0 :         Double_t rd=TMath::Sqrt(d[0]*d[0]+d[1]*d[1]);
     181           0 :         Double_t dr=r-rd;
     182           0 :         Double_t phi=TMath::ATan2(x[0],x[1]);
     183           0 :         Double_t phid=TMath::ATan2(d[0],d[1]);
     184           0 :         Double_t dphi=phi-phid;
     185           0 :         if (dphi<0.) dphi+=TMath::TwoPi();
     186           0 :         if (dphi>TMath::Pi()) dphi=TMath::TwoPi()-dphi;
     187           0 :         Double_t drphi=r*dphi;
     188           0 :         Double_t dx=x[0]-d[0];
     189           0 :         Double_t dy=x[1]-d[1];
     190           0 :         Double_t dz=x[2]-d[2];
     191           0 :         ts<<"positions"
     192           0 :           <<"x0="<<x[0]
     193           0 :           <<"x1="<<x[1]
     194           0 :           <<"x2="<<x[2]
     195           0 :           <<"dx="<<dx
     196           0 :           <<"dy="<<dy
     197           0 :           <<"dz="<<dz
     198           0 :           <<"r="<<r
     199           0 :           <<"phi="<<phi
     200           0 :           <<"dr="<<dr
     201           0 :           <<"drphi="<<drphi
     202           0 :           <<"\n";
     203           0 :       }
     204           0 : }
     205             : 
     206             : 
     207             : void AliTPCExBFirst::ConstructCommon(//const AliFieldMap *bFieldMap,
     208             :                                      const AliMagF *bField) {
     209             :   /// THIS IS PRIVATE! (a helper for the constructor)
     210             : 
     211           6 :   fkNMean=fkNX*fkNY*fkNZ;
     212           3 :   fkMeanBx=new Double_t[fkNMean];
     213           3 :   fkMeanBy=new Double_t[fkNMean];
     214             : 
     215           3 :   Double_t x[3];
     216             :   Double_t nBz=0;
     217           3 :   fkMeanBz=0.;
     218         306 :   for (int i=0;i<fkNX;++i) {
     219         150 :     x[0]=fkXMin+i*(fkXMax-fkXMin)/(fkNX-1);
     220       15300 :     for (int j=0;j<fkNY;++j) {
     221        7500 :       x[1]=fkYMin+j*(fkYMax-fkYMin)/(fkNY-1);
     222        7500 :       Double_t r=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]);
     223             :       Double_t bx=0.,by=0.;
     224      765000 :       for (int k=0;k<fkNZ;++k) {
     225      375000 :         x[2]=fkZMin+k*(fkZMax-fkZMin)/(fkNZ-1);
     226      375000 :         Double_t b[3];
     227             :         // the x is not const in the Field function...
     228      375000 :         Double_t xt[3];
     229     3000000 :         for (int l=0;l<3;++l) xt[l]=x[l];
     230             :         // that happens due to the lack of a sophisticated class design:
     231             :         //      if (bFieldMap!=0)
     232             :         //        bFieldMap->Field(xt,b);
     233             :         //      else
     234      375000 :         ((AliMagF*)bField)->Field(xt,b);
     235      375000 :         bx+=b[0]/10.;
     236      375000 :         by+=b[1]/10.;
     237      375000 :         fkMeanBx[(k*fkNY+j)*fkNX+i]=bx;
     238      375000 :         fkMeanBy[(k*fkNY+j)*fkNX+i]=by;
     239      375000 :         if (90.<=r&&r<=250.) {
     240      244200 :           fkMeanBz+=b[2]/10.;
     241      244200 :           ++nBz;
     242      244200 :         }
     243      375000 :       }
     244             :     }
     245             :   }
     246           3 :   fkMeanBz/=nBz;
     247           3 : }
     248             : 
     249             : 
     250             : void AliTPCExBFirst::GetMeanFields(Double_t rx,Double_t ry,Double_t rz,
     251             :                                    Double_t *Bx,Double_t *By) const {
     252             :   /// THIS IS PRIVATE! (calculates the mean field utilising a lookup table)
     253             : 
     254     5353956 :   Double_t x=(fkNX-1)*(rx-fkXMin)/(fkXMax-fkXMin);
     255     2676978 :   Int_t xi1=static_cast<Int_t>(x);
     256     2676978 :   xi1=TMath::Max(TMath::Min(xi1,fkNX-2),0);
     257     2676978 :   Int_t xi2=xi1+1;
     258     2676978 :   Double_t dx=(x-xi1);
     259     2676978 :   Double_t dx1=(xi2-x);
     260             : 
     261     2676978 :   Double_t y=(fkNY-1)*(ry-fkYMin)/(fkYMax-fkYMin);
     262     2676978 :   Int_t yi1=static_cast<Int_t>(y);
     263     2676978 :   yi1=TMath::Max(TMath::Min(yi1,fkNY-2),0);
     264     2676978 :   Int_t yi2=yi1+1;
     265     2676978 :   Double_t dy=(y-yi1);
     266     2676978 :   Double_t dy1=(yi2-y);
     267             : 
     268     2676978 :   Double_t z=(fkNZ-1)*(rz-fkZMin)/(fkZMax-fkZMin);
     269     2676978 :   Int_t zi1=static_cast<Int_t>(z);
     270     2676978 :   zi1=TMath::Max(TMath::Min(zi1,fkNZ-2),0);
     271     2676978 :   Int_t zi2=zi1+1;
     272     2676978 :   Double_t dz=(z-zi1);
     273             : 
     274     2676978 :   double s0x=fkMeanBx[yi1*fkNX+xi1]*dx1*dy1
     275     2676978 :             +fkMeanBx[yi2*fkNX+xi1]*dx1*dy
     276     2676978 :             +fkMeanBx[yi1*fkNX+xi2]*dx *dy1
     277     2676978 :             +fkMeanBx[yi2*fkNX+xi2]*dx *dy;
     278     2676978 :   double s0y=fkMeanBy[yi1*fkNX+xi1]*dx1*dy1
     279     2676978 :             +fkMeanBy[yi2*fkNX+xi1]*dx1*dy
     280     2676978 :             +fkMeanBy[yi1*fkNX+xi2]*dx *dy1
     281     2676978 :             +fkMeanBy[yi2*fkNX+xi2]*dx *dy;
     282     2676978 :   Int_t zi0=zi1-1;
     283             :   double snmx,snmy;
     284     2676978 :   if (zi0>=0) {
     285     2669959 :     snmx=fkMeanBx[(zi0*fkNY+yi1)*fkNX+xi1]*dx1*dy1
     286     2669959 :         +fkMeanBx[(zi0*fkNY+yi2)*fkNX+xi1]*dx1*dy
     287     2669959 :         +fkMeanBx[(zi0*fkNY+yi1)*fkNX+xi2]*dx *dy1
     288     2669959 :         +fkMeanBx[(zi0*fkNY+yi2)*fkNX+xi2]*dx *dy;
     289     2669959 :     snmy=fkMeanBy[(zi0*fkNY+yi1)*fkNX+xi1]*dx1*dy1
     290     2669959 :         +fkMeanBy[(zi0*fkNY+yi2)*fkNX+xi1]*dx1*dy
     291     2669959 :         +fkMeanBy[(zi0*fkNY+yi1)*fkNX+xi2]*dx *dy1
     292     2669959 :         +fkMeanBy[(zi0*fkNY+yi2)*fkNX+xi2]*dx *dy;
     293     2669959 :   }
     294             :   else
     295             :     snmx=snmy=0.;
     296     2676978 :   double snx=fkMeanBx[(zi1*fkNY+yi1)*fkNX+xi1]*dx1*dy1
     297     2676978 :             +fkMeanBx[(zi1*fkNY+yi2)*fkNX+xi1]*dx1*dy
     298     2676978 :             +fkMeanBx[(zi1*fkNY+yi1)*fkNX+xi2]*dx *dy1
     299     2676978 :             +fkMeanBx[(zi1*fkNY+yi2)*fkNX+xi2]*dx *dy;
     300     2676978 :   double sny=fkMeanBy[(zi1*fkNY+yi1)*fkNX+xi1]*dx1*dy1
     301     2676978 :             +fkMeanBy[(zi1*fkNY+yi2)*fkNX+xi1]*dx1*dy
     302     2676978 :             +fkMeanBy[(zi1*fkNY+yi1)*fkNX+xi2]*dx *dy1
     303     2676978 :             +fkMeanBy[(zi1*fkNY+yi2)*fkNX+xi2]*dx *dy;
     304     2676978 :   double snpx=fkMeanBx[(zi2*fkNY+yi1)*fkNX+xi1]*dx1*dy1
     305     2676978 :              +fkMeanBx[(zi2*fkNY+yi2)*fkNX+xi1]*dx1*dy
     306     2676978 :              +fkMeanBx[(zi2*fkNY+yi1)*fkNX+xi2]*dx *dy1
     307     2676978 :              +fkMeanBx[(zi2*fkNY+yi2)*fkNX+xi2]*dx *dy;
     308     2676978 :   double snpy=fkMeanBy[(zi2*fkNY+yi1)*fkNX+xi1]*dx1*dy1
     309     2676978 :              +fkMeanBy[(zi2*fkNY+yi2)*fkNX+xi1]*dx1*dy
     310     2676978 :              +fkMeanBy[(zi2*fkNY+yi1)*fkNX+xi2]*dx *dy1
     311     2676978 :              +fkMeanBy[(zi2*fkNY+yi2)*fkNX+xi2]*dx *dy;
     312             : 
     313             : 
     314             : 
     315     2676978 :   *Bx=0.5*(((snpx-2.*snx+snmx)*dz+2.*(snx-snmx))*dz+snx-s0x+snmx);
     316     2676978 :   *By=0.5*(((snpy-2.*sny+snmy)*dz+2.*(sny-snmy))*dz+sny-s0y+snmy);
     317             :   //TODO: make this nice
     318     2676978 :   if (TMath::Abs(z)>0.001) {
     319     2676978 :     *Bx/=z;
     320     2676978 :     *By/=z;
     321     2676978 :   }
     322     2676978 : }

Generated by: LCOV version 1.11