LCOV - code coverage report
Current view: top level - TPC/TPCbase - AliTPCGGVoltError.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 97 0.0 %
Date: 2016-06-14 17:26:59 Functions: 0 11 0.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 AliTPCGGVoltError
      17             : /// \brief AliTPCGGVoltError class
      18             : 
      19             : 
      20             : #include "AliMagF.h"
      21             : #include "TGeoGlobalMagField.h"
      22             : #include "AliTPCcalibDB.h"
      23             : #include "AliTPCParam.h"
      24             : #include "AliLog.h"
      25             : 
      26             : #include "AliTPCGGVoltError.h"
      27             : #include <TMath.h>
      28             : 
      29             : AliTPCGGVoltError::AliTPCGGVoltError()
      30           0 :   : AliTPCCorrection("GGVoltError","GatingGrid (GG) Voltage Error"),
      31           0 :     fC0(0.),fC1(0.),
      32           0 :     fDeltaVGGA(0.),fDeltaVGGC(0.),
      33           0 :     fInitLookUp(kFALSE)
      34           0 : {
      35             :   /// default constructor
      36             : 
      37           0 : }
      38             : 
      39           0 : AliTPCGGVoltError::~AliTPCGGVoltError() {
      40             :   /// default destructor
      41             : 
      42           0 : }
      43             : 
      44             : void AliTPCGGVoltError::Init() {
      45             :   /// Init function
      46             : 
      47           0 :   AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
      48           0 :   if (!magF) AliError("Magneticd field - not initialized");
      49           0 :   Double_t bzField = magF->SolenoidField()/10.; //field in T
      50           0 :   AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
      51           0 :   if (!param) AliError("Parameters - not initialized");
      52           0 :   Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us]   // From dataBase: to be updated: per second (ideally)
      53             :   Double_t ezField = 400; // [V/cm]   // to be updated: never (hopefully)
      54           0 :   Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
      55             :   //
      56           0 :   SetOmegaTauT1T2(wt,fT1,fT2);
      57           0 :   InitGGVoltErrorDistortion();
      58             :   //SetDeltaVGGA(0.0);//  ideally from the database
      59             :   //SetDeltaVGGC(0.0);//  ideally from the database
      60           0 : }
      61             : 
      62             : void AliTPCGGVoltError::Update(const TTimeStamp &/*timeStamp*/) {
      63             :   /// Update function
      64             : 
      65           0 :   AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
      66           0 :   if (!magF) AliError("Magneticd field - not initialized");
      67           0 :   Double_t bzField = magF->SolenoidField()/10.; //field in T
      68           0 :   AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
      69           0 :   if (!param) AliError("Parameters - not initialized");
      70           0 :   Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us]   // From dataBase: to be updated: per second (ideally)
      71             :   Double_t ezField = 400; // [V/cm]   // to be updated: never (hopefully)
      72           0 :   Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
      73             : 
      74           0 :   SetOmegaTauT1T2(wt,fT1,fT2);
      75             :   //  InitGGVoltErrorDistortion(); // not necessary in here since the Voltage should not change!
      76           0 : }
      77             : 
      78             : 
      79             : 
      80             : void AliTPCGGVoltError::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
      81             : 
      82             :   /// Gated Grid Voltage Error
      83             :   ///
      84             :   /// Calculates the effect of having an incorrect voltage on the A or C end plate Gated Grids.
      85             :   ///
      86             :   /// Electrostatic Equations from StarNote SN0253 by Howard Wieman.
      87             : 
      88           0 :   if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");
      89             : 
      90             :   Int_t   order     = 1 ;               // FIXME: hardcoded? Linear interpolation = 1, Quadratic = 2
      91             : 
      92           0 :   Double_t intEr, intEphi ;
      93             :   Double_t r, phi, z ;
      94             :   Int_t    sign ;
      95             : 
      96             :   Double_t deltaVGG;
      97             : 
      98           0 :   r   = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
      99           0 :   phi = TMath::ATan2(x[1],x[0]);
     100           0 :   if ( phi < 0 ) phi += TMath::TwoPi();                   // Table uses phi from 0 to 2*Pi
     101           0 :   z   = x[2] ;
     102             : 
     103           0 :   if ( (roc%36) < 18 ) {
     104             :     sign =  1;
     105           0 :     deltaVGG = fDeltaVGGA;           // (TPC End A)
     106           0 :   } else {
     107             :     sign = -1;                       // (TPC End C)
     108           0 :     deltaVGG = fDeltaVGGC;
     109             :   }
     110             : 
     111           0 :   if ( sign==1  && z <  fgkZOffSet ) z =  fgkZOffSet;    // Protect against discontinuity at CE
     112           0 :   if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet;    // Protect against discontinuity at CE
     113             : 
     114           0 :   Interpolate2DEdistortion( order, r, z, fGGVoltErrorER, intEr );
     115             :   intEphi = 0.0;  // Efield is symmetric in phi
     116             : 
     117             :   // Calculate distorted position
     118           0 :   if ( r > 0.0 ) {
     119           0 :     phi =  phi + deltaVGG*( fC0*intEphi - fC1*intEr ) / r;
     120           0 :     r   =  r   + deltaVGG*( fC0*intEr   + fC1*intEphi );
     121           0 :   }
     122             : 
     123             :   // Calculate correction in cartesian coordinates
     124           0 :   dx[0] = r * TMath::Cos(phi) - x[0];
     125           0 :   dx[1] = r * TMath::Sin(phi) - x[1];
     126           0 :   dx[2] = 0.; // z distortion not implemented (1st order distortions) - see e.g. AliTPCBoundaryVoltError-class
     127             : 
     128             : 
     129             : 
     130           0 : }
     131             : 
     132             : 
     133             : Float_t AliTPCGGVoltError::GetIntErOverEz(const Float_t x[],const Short_t roc) {
     134             :   /// This function is purely for calibration purposes
     135             :   /// Calculates the integral (int Er/Ez dz) for the setted GG voltage offset
     136             : 
     137           0 :   if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");
     138             : 
     139             :   Int_t   order     = 1 ;     // FIXME: so far hardcoded? Linear interpolation = 1, Quadratic = 2
     140             : 
     141           0 :   Double_t intEr;
     142             :   Double_t r, phi, z ;
     143             :   Int_t    sign ;
     144             : 
     145             :   Double_t deltaVGG;
     146             : 
     147           0 :   r   = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
     148           0 :   phi = TMath::ATan2(x[1],x[0]);
     149           0 :   if ( phi < 0 ) phi += TMath::TwoPi();        // Table uses phi from 0 to 2*Pi
     150           0 :   z   = x[2] ;
     151             : 
     152           0 :   if ( (roc%36) < 18 ) {
     153             :     sign =  1;
     154           0 :     deltaVGG = fDeltaVGGA;           // (TPC End A)
     155           0 :   } else {
     156             :     sign = -1;                       // (TPC End C)
     157           0 :     deltaVGG = fDeltaVGGC;
     158             :   }
     159             : 
     160           0 :   if ( sign==1  && z <  fgkZOffSet ) z =  fgkZOffSet;    // Protect against discontinuity at CE
     161           0 :   if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet;    // Protect against discontinuity at CE
     162             : 
     163           0 :   Interpolate2DEdistortion(order, r, z, fGGVoltErrorER, intEr );
     164             : 
     165           0 :   return (intEr*deltaVGG);
     166             : 
     167           0 : }
     168             : 
     169             : void AliTPCGGVoltError::InitGGVoltErrorDistortion() {
     170             :   /// Initialization of the Lookup table which contains the solutions of the GG Error problem
     171             : 
     172             :   Double_t r,z;
     173             :   Int_t nterms = 100 ;
     174           0 :   for ( Int_t i = 0 ; i < kNZ ; ++i ) {
     175           0 :     z = fgkZList[i] ;
     176           0 :     for ( Int_t j = 0 ; j < kNR ; ++j ) {
     177           0 :       r = fgkRList[j] ;
     178           0 :       fGGVoltErrorER[i][j] = 0.0 ;
     179             :       Double_t intz = 0.0 ;
     180           0 :       for ( Int_t n = 1 ; n < nterms ; ++n ) {
     181           0 :         Double_t k    =  n * TMath::Pi() / fgkTPCZ0 ;
     182             :         Double_t ein  =  0 ;                    // Error potential on the IFC
     183             :         Double_t eout =  0 ;                    // Error potential on the OFC
     184           0 :         if ( z < 0 ) {
     185           0 :           ein   =  -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
     186             :           eout  =  -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
     187           0 :         }
     188           0 :         if ( z == 0 ) continue ;
     189           0 :         if ( z > 0 ) {
     190           0 :           ein   =  -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
     191             :           eout  =  -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
     192           0 :         }
     193           0 :         Double_t an   =  ein  * TMath::BesselK0( k*fgkOFCRadius ) - eout * TMath::BesselK0( k*fgkIFCRadius ) ;
     194           0 :         Double_t bn   =  eout * TMath::BesselI0( k*fgkIFCRadius ) - ein  * TMath::BesselI0( k*fgkOFCRadius ) ;
     195             :         Double_t numerator =
     196           0 :           an * TMath::BesselI1( k*r ) - bn * TMath::BesselK1( k*r ) ;
     197             :         Double_t denominator =
     198           0 :           TMath::BesselK0( k*fgkOFCRadius ) * TMath::BesselI0( k*fgkIFCRadius ) -
     199           0 :           TMath::BesselK0( k*fgkIFCRadius ) * TMath::BesselI0( k*fgkOFCRadius ) ;
     200           0 :         Double_t zterm = TMath::Cos( k*(fgkTPCZ0-TMath::Abs(z)) ) - 1 ;
     201           0 :         intz += zterm * numerator / denominator ;
     202             :         // Assume series converges, break if small terms
     203           0 :         if ( n>10 && TMath::Abs(intz)*1.e-10 > TMath::Abs(numerator/denominator) ) break;
     204           0 :       }
     205           0 :       fGGVoltErrorER[i][j] = (Double_t) intz ;
     206             : 
     207             :     }
     208             :   }
     209             : 
     210           0 :   fInitLookUp = kTRUE;
     211           0 : }
     212             : 
     213             : 
     214             : 
     215             : void AliTPCGGVoltError::Print(const Option_t* option) const {
     216             :   /// Print function to check the settings (e.g. voltage offsets)
     217             :   /// option=="a" prints the C0 and C1 coefficents for calibration purposes
     218             : 
     219           0 :   TString opt = option; opt.ToLower();
     220           0 :   printf("%s\n",GetTitle());
     221           0 :   printf(" - GG Voltage offset: A-side: %3.1f V, C-side: %3.1f V \n",fDeltaVGGA,fDeltaVGGC);
     222           0 :   if (opt.Contains("a")) { // Print all details
     223           0 :     printf(" - T1: %1.4f, T2: %1.4f \n",fT1,fT2);
     224           0 :     printf(" - C1: %1.4f, C0: %1.4f \n",fC1,fC0);
     225             :   }
     226             : 
     227           0 :   if (!fInitLookUp) AliError("Lookup table was not initialized! You should do InitGGVoltErrorDistortion() ...");
     228             : 
     229             : 
     230           0 : }

Generated by: LCOV version 1.11