--- /dev/null
+
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////
+// //
+// AliTPCComposedCorrection class //
+// //
+// This class is creating a correction that is composed out of smaller //
+// corrections. //
+// There are two ways the sub-corrections can be combined into this one: //
+// 1. kParallel: All corrections are applied at the given position x and //
+// the dx terms are summed up (this commutes). //
+// 2. kQueue: The corrections are called in order. The first one at the //
+// given position x resulting in dx1, the second one is called at //
+// the corrected position (x+dx1) resulting in dx2, the third one //
+// is then called at position (x+dx1+dx2) and so forth. dx=dx1+dx2+... //
+// is returned. //
+// For the inverse of the correction this is taken into account by reversing //
+// the order the corrections are applied in the kQueue case (no issue for //
+// kParallel). //
+// //
+// date: 27/04/2010 //
+// Authors: Magnus Mager, Stefan Rossegger, Jim Thomas //
+// //
+// Example usage: //
+// //
+// AliMagF mag("mag","mag"); //
+// AliTPCExBBShape exb; // B field shape distortions //
+// exb.SetBField(&mag); //
+// //
+// AliTPCExBTwist twist; // ExB Twist distortions //
+// twist.SetXTwist(0.001); //
+// //
+// TObjArray cs; cs.Add(&exb); cs.Add(&twist); //
+// //
+// AliTPCComposedCorrection cc; //
+// cc.SetCorrections(&cs); //
+// cc.SetOmegaTauT1T2(wt,T1,T2); //
+// cc.Print("DA"); //
+// cc.CreateHistoDRPhiinZR(0,100,100)->Draw("surf2"); //
+////////////////////////////////////////////////////////////////////////////////
+
+
+#include <TCollection.h>
+#include <TIterator.h>
+
+#include "AliTPCComposedCorrection.h"
+
+
+AliTPCComposedCorrection::AliTPCComposedCorrection()
+ : AliTPCCorrection("composed_correction",
+ "composition of corrections"),
+ fCorrections(0),
+ fMode(kParallel)
+{
+ //
+ // default constructor
+ //
+}
+
+AliTPCComposedCorrection::AliTPCComposedCorrection(TCollection *corrections,
+ AliTPCComposedCorrection::CompositionType mode)
+ : AliTPCCorrection("composed_correction",
+ "composition of corrections"),
+ fCorrections(corrections),
+ fMode(mode)
+{
+ //
+ // Constructor that defines the set of corrections, this one is composed of.
+ //
+}
+
+AliTPCComposedCorrection::~AliTPCComposedCorrection() {
+ //
+ // virtual destructor
+ //
+}
+
+
+void AliTPCComposedCorrection::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
+ //
+ // This applies all correction and the specified manner (see general
+ // class description for details).
+ //
+ TIterator *i=fCorrections->MakeIterator();
+ AliTPCCorrection *c;
+ switch (fMode) {
+ case kParallel:
+ Float_t dxi[3];
+ for (int j=0;j<3;++j) dx[j]=0.;
+ while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
+ c->GetCorrection(x,roc,dxi);
+ for (Int_t j=0;j<3;++j) dx[j]+=dxi[j];
+ }
+ break;
+ case kQueue:
+ Float_t xi[3];
+ for (Int_t j=0;j<3;++j) xi[j]=x[j];
+ while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
+ c->GetCorrection(xi,roc,dx);
+ for (Int_t j=0;j<3;++j) xi[j]+=dx[j];
+ }
+ for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
+ break;
+ }
+ delete i;
+}
+
+void AliTPCComposedCorrection::GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]) {
+ //
+ // This applies all distortions and the specified manner (see general
+ // class descxiption for details).
+ //
+
+ TIterator *i=fCorrections->MakeReverseIterator();
+ AliTPCCorrection *c;
+ switch (fMode) {
+ case kParallel:
+ Float_t dxi[3];
+ for (int j=0;j<3;++j) dx[j]=0.;
+ while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
+ c->GetDistortion(x,roc,dxi);
+ for (Int_t j=0;j<3;++j) dx[j]+=dxi[j];
+ }
+ break;
+ case kQueue:
+ Float_t xi[3];
+ for (Int_t j=0;j<3;++j) xi[j]=x[j];
+ while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
+ c->GetDistortion(xi,roc,dx);
+ for (Int_t j=0;j<3;++j) xi[j]+=dx[j];
+ }
+ for (Int_t j=0;j<3;++j) dx[j]=xi[j]-x[j];
+ break;
+ }
+ delete i;
+}
+
+
+void AliTPCComposedCorrection::Print(Option_t* option) const {
+ //
+ // Print function to check which correction classes are used
+ // option=="d" prints details regarding the setted magnitude
+ // option=="a" prints the C0 and C1 coefficents for calibration purposes
+ //
+
+ printf("Composed TPC spacepoint correction \"%s\" -- composed of:\n",GetTitle());
+ TString opt = option; opt.ToLower();
+ Int_t in=1;
+ TIterator *i=fCorrections->MakeIterator();
+ AliTPCCorrection *c;
+ while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
+ if (opt.Contains("d")) {
+ printf("%d. ",in);
+ c->Print(option);
+ } else {
+ printf("%d. %s\n",in,c->GetTitle());
+ }
+ ++in;
+ }
+ delete i;
+}
+
+
+void AliTPCComposedCorrection::SetOmegaTauT1T2(Float_t omegaTau,Float_t t1,Float_t t2) {
+ //
+ // Gives the possibility to set the OmegaTau plus Tensor corrections T1 and T2 (effective omega Tau)
+ // to each subcorrection (since they might become event specific due to changing drift velocity)
+ //
+ // The omegaTau comes idealy from the Database, since it is a function of drift velocity, B and E field
+ // e.g. omegaTau = -10.0 * Bz * vdrift / Ez ; // with Bz in kG and Ez in V/cm
+ // omegaTau = -0.325 for Bz=5kG, Ez=400V/cm and vdrift = 2.6cm/muSec
+ // The T1 and T2 tensors were measured in a dedicated calibration run
+ //
+ // Note: overwrites previously set values!
+ //
+
+ TIterator *i=fCorrections->MakeIterator();
+ AliTPCCorrection *c;
+ while (0!=(c=dynamic_cast<AliTPCCorrection*>(i->Next()))) {
+ c->SetOmegaTauT1T2(omegaTau,t1,t2);
+ }
+ delete i;
+}
+
+ClassImp(AliTPCComposedCorrection)
--- /dev/null
+#ifndef ALI_TPC_COMPOSED_CORRECTION_H
+#define ALI_TPC_COMPOSED_CORRECTION_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+////////////////////////////////////////////////////////////////////////////////
+// //
+// AliTPCComposedCorrection class //
+// //
+// This class is creating a correction that is composed out of smaller //
+// corrections. //
+// There are two ways the sub-corrections can be combined into this one: //
+// 1. kParallel: All corrections are applied at the given position x and //
+// the dx terms are summed up (this commutes). //
+// 2. kQueue: The corrections are called in order. The first one at the //
+// given position x resulting in dx1, the second one is called at //
+// the corrected position (x+dx1) resulting in dx2, the third one //
+// is then called at position (x+dx1+dx2) and so forth. dx=dx1+dx2+... //
+// is returned. //
+// For the inverse of the correction this is taken into account by reversing //
+// the order the corrections are applied in the kQueue case (no issue for //
+// kParallel). //
+// //
+// date: 27/04/2010 //
+// Authors: Magnus Mager, Stefan Rossegger, Jim Thomas //
+////////////////////////////////////////////////////////////////////////////////
+
+#include "AliTPCCorrection.h"
+
+class TCollection;
+
+class AliTPCComposedCorrection : public AliTPCCorrection {
+public:
+ enum CompositionType {kParallel,kQueue};
+
+ AliTPCComposedCorrection();
+ AliTPCComposedCorrection(TCollection *corrections,CompositionType mode);
+ virtual ~AliTPCComposedCorrection();
+
+ void SetOmegaTauT1T2(Float_t omegaTau,Float_t t1,Float_t t2);
+
+ TCollection* GetCorrections() const {return fCorrections;}
+ void SetCorrections(TCollection *corrections) {fCorrections=corrections;}
+ CompositionType GetMode() const {return fMode;}
+ void SetMode(CompositionType mode) {fMode=mode;}
+
+ virtual void GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]);
+ virtual void GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]);
+
+ virtual void Print(Option_t* option="") const;
+
+private:
+ TCollection *fCorrections; // The corrections this one is composed of.
+ CompositionType fMode; // The way to apply the corrections (see general class documentation)
+
+ AliTPCComposedCorrection & operator = (const AliTPCComposedCorrection);
+ AliTPCComposedCorrection(const AliTPCComposedCorrection&); //dummy copy contructor
+
+ ClassDef(AliTPCComposedCorrection,1);
+};
+
+#endif
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////
+// //
+// AliTPCCorrection class //
+// //
+// This class provides a general framework to deal with space point //
+// distortions. An correction class which inherits from here is for example //
+// AliTPCExBBShape or AliTPCExBTwist //
+// //
+// General functions are (for example): //
+// CorrectPoint(x,roc) where x is the vector of inital positions in //
+// cartesian coordinates and roc represents the Read Out chamber number //
+// according to the offline naming convention. The vector x is overwritten //
+// with the corrected coordinates. //
+// //
+// An alternative usage would be CorrectPoint(x,roc,dx), which leaves the //
+// vector x untouched, put returns the distortions via the vector dx //
+// //
+// The class allows "effective Omega Tau" corrections to be shifted to the //
+// single distortion classes. //
+// //
+// Note: This class is normally used via the class AliTPCComposedCorrection //
+// //
+// date: 27/04/2010 //
+// Authors: Magnus Mager, Stefan Rossegger, Jim Thomas //
+////////////////////////////////////////////////////////////////////////////////
+
+#include <TH2F.h>
+#include <TMath.h>
+#include <TROOT.h>
+
+#include "AliTPCCorrection.h"
+
+// FIXME: the following values should come from the database
+const Double_t AliTPCCorrection::fgkTPC_Z0 =249.7; // nominal gating grid position
+const Double_t AliTPCCorrection::fgkIFCRadius= 83.06; // Mean Radius of the Inner Field Cage ( 82.43 min, 83.70 max) (cm)
+const Double_t AliTPCCorrection::fgkOFCRadius=254.5; // Mean Radius of the Outer Field Cage (252.55 min, 256.45 max) (cm)
+const Double_t AliTPCCorrection::fgkZOffSet = 0.2; // Offset from CE: calculate all distortions closer to CE as if at this point
+const Double_t AliTPCCorrection::fgkCathodeV =-100000.0; // Cathode Voltage (volts)
+const Double_t AliTPCCorrection::fgkGG =-70.0; // Gating Grid voltage (volts)
+
+
+// FIXME: List of interpolation points (course grid in the middle, fine grid on the borders)
+const Double_t AliTPCCorrection::fgkRList[AliTPCCorrection::kNR] = {
+84.0, 84.5, 85.0, 85.5, 86.0, 87.0, 88.0,
+90.0, 92.0, 94.0, 96.0, 98.0, 100.0, 102.0, 104.0, 106.0, 108.0,
+110.0, 112.0, 114.0, 116.0, 118.0, 120.0, 122.0, 124.0, 126.0, 128.0,
+130.0, 132.0, 134.0, 136.0, 138.0, 140.0, 142.0, 144.0, 146.0, 148.0,
+150.0, 152.0, 154.0, 156.0, 158.0, 160.0, 162.0, 164.0, 166.0, 168.0,
+170.0, 172.0, 174.0, 176.0, 178.0, 180.0, 182.0, 184.0, 186.0, 188.0,
+190.0, 192.0, 194.0, 196.0, 198.0, 200.0, 202.0, 204.0, 206.0, 208.0,
+210.0, 212.0, 214.0, 216.0, 218.0, 220.0, 222.0, 224.0, 226.0, 228.0,
+230.0, 232.0, 234.0, 236.0, 238.0, 240.0, 242.0, 244.0, 246.0, 248.0,
+249.0, 249.5, 250.0, 251.5, 252.0 } ;
+
+const Double_t AliTPCCorrection::fgkZList[AliTPCCorrection::kNZ] = {
+-249.5, -249.0, -248.5, -248.0, -247.0, -246.0, -245.0, -243.0, -242.0, -241.0,
+-240.0, -238.0, -236.0, -234.0, -232.0, -230.0, -228.0, -226.0, -224.0, -222.0,
+-220.0, -218.0, -216.0, -214.0, -212.0, -210.0, -208.0, -206.0, -204.0, -202.0,
+-200.0, -198.0, -196.0, -194.0, -192.0, -190.0, -188.0, -186.0, -184.0, -182.0,
+-180.0, -178.0, -176.0, -174.0, -172.0, -170.0, -168.0, -166.0, -164.0, -162.0,
+-160.0, -158.0, -156.0, -154.0, -152.0, -150.0, -148.0, -146.0, -144.0, -142.0,
+-140.0, -138.0, -136.0, -134.0, -132.0, -130.0, -128.0, -126.0, -124.0, -122.0,
+-120.0, -118.0, -116.0, -114.0, -112.0, -110.0, -108.0, -106.0, -104.0, -102.0,
+-100.0, -98.0, -96.0, -94.0, -92.0, -90.0, -88.0, -86.0, -84.0, -82.0,
+-80.0, -78.0, -76.0, -74.0, -72.0, -70.0, -68.0, -66.0, -64.0, -62.0,
+-60.0, -58.0, -56.0, -54.0, -52.0, -50.0, -48.0, -46.0, -44.0, -42.0,
+-40.0, -38.0, -36.0, -34.0, -32.0, -30.0, -28.0, -26.0, -24.0, -22.0,
+-20.0, -18.0, -16.0, -14.0, -12.0, -10.0, -8.0, -6.0, -4.0, -2.0,
+-1.0, -0.5, -0.2, -0.1, -0.05, 0.05, 0.1, 0.2, 0.5, 1.0,
+ 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0,
+ 22.0, 24.0, 26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 38.0, 40.0,
+ 42.0, 44.0, 46.0, 48.0, 50.0, 52.0, 54.0, 56.0, 58.0, 60.0,
+ 62.0, 64.0, 66.0, 68.0, 70.0, 72.0, 74.0, 76.0, 78.0, 80.0,
+ 82.0, 84.0, 86.0, 88.0, 90.0, 92.0, 94.0, 96.0, 98.0, 100.0,
+102.0, 104.0, 106.0, 108.0, 110.0, 112.0, 114.0, 116.0, 118.0, 120.0,
+122.0, 124.0, 126.0, 128.0, 130.0, 132.0, 134.0, 136.0, 138.0, 140.0,
+142.0, 144.0, 146.0, 148.0, 150.0, 152.0, 154.0, 156.0, 158.0, 160.0,
+162.0, 164.0, 166.0, 168.0, 170.0, 172.0, 174.0, 176.0, 178.0, 180.0,
+182.0, 184.0, 186.0, 188.0, 190.0, 192.0, 194.0, 196.0, 198.0, 200.0,
+202.0, 204.0, 206.0, 208.0, 210.0, 212.0, 214.0, 216.0, 218.0, 220.0,
+222.0, 224.0, 226.0, 228.0, 230.0, 232.0, 234.0, 236.0, 238.0, 240.0,
+242.0, 243.0, 244.0, 245.0, 246.0, 247.0, 248.0, 248.5, 249.0, 249.5 } ;
+
+
+
+AliTPCCorrection::AliTPCCorrection()
+ : TNamed("correction_unity","unity"),fJLow(0),fKLow(0)
+{
+ //
+ // default constructor
+ //
+}
+
+AliTPCCorrection::AliTPCCorrection(const char *name,const char *title)
+ : TNamed(name,title),fJLow(0),fKLow(0)
+{
+ //
+ // default constructor, that set the name and title
+ //
+}
+
+AliTPCCorrection::~AliTPCCorrection() {
+ //
+ // virtual destructor
+ //
+}
+
+void AliTPCCorrection::CorrectPoint(Float_t x[],const Short_t roc) {
+ //
+ // Corrects the initial coordinates x (cartesian coordinates)
+ // according to the given effect (inherited classes)
+ // roc represents the TPC read out chamber (offline numbering convention)
+ //
+ Float_t dx[3];
+ GetCorrection(x,roc,dx);
+ for (Int_t j=0;j<3;++j) x[j]+=dx[j];
+}
+
+void AliTPCCorrection::CorrectPoint(const Float_t x[],const Short_t roc,Float_t xp[]) {
+ //
+ // Corrects the initial coordinates x (cartesian coordinates) and stores the new
+ // (distorted) coordinates in xp. The distortion is set according to the given effect (inherited classes)
+ // roc represents the TPC read out chamber (offline numbering convention)
+ //
+ Float_t dx[3];
+ GetCorrection(x,roc,dx);
+ for (Int_t j=0;j<3;++j) xp[j]=x[j]+dx[j];
+}
+
+void AliTPCCorrection::DistortPoint(Float_t x[],const Short_t roc) {
+ //
+ // Distorts the initial coordinates x (cartesian coordinates)
+ // according to the given effect (inherited classes)
+ // roc represents the TPC read out chamber (offline numbering convention)
+ //
+ Float_t dx[3];
+ GetDistortion(x,roc,dx);
+ for (Int_t j=0;j<3;++j) x[j]+=dx[j];
+}
+
+void AliTPCCorrection::DistortPoint(const Float_t x[],const Short_t roc,Float_t xp[]) {
+ //
+ // Distorts the initial coordinates x (cartesian coordinates) and stores the new
+ // (distorted) coordinates in xp. The distortion is set according to the given effect (inherited classes)
+ // roc represents the TPC read out chamber (offline numbering convention)
+ //
+ Float_t dx[3];
+ GetDistortion(x,roc,dx);
+ for (Int_t j=0;j<3;++j) xp[j]=x[j]+dx[j];
+}
+
+void AliTPCCorrection::GetCorrection(const Float_t /*x*/[],const Short_t /*roc*/,Float_t dx[]) {
+ //
+ // This function delivers the correction values dx in respect to the inital coordinates x
+ // roc represents the TPC read out chamber (offline numbering convention)
+ // Note: The dx is overwritten by the inherited effectice class ...
+ //
+ for (Int_t j=0;j<3;++j) { dx[j]=0.; }
+}
+
+void AliTPCCorrection::GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]) {
+ //
+ // This function delivers the distortion values dx in respect to the inital coordinates x
+ // roc represents the TPC read out chamber (offline numbering convention)
+ //
+ GetCorrection(x,roc,dx);
+ for (Int_t j=0;j<3;++j) dx[j]=-dx[j];
+}
+
+void AliTPCCorrection::Init() {
+ //
+ // Initialization funtion (not used at the moment)
+ //
+}
+
+void AliTPCCorrection::Print(Option_t* /*option*/) const {
+ //
+ // Print function to check which correction classes are used
+ // option=="d" prints details regarding the setted magnitude
+ // option=="a" prints the C0 and C1 coefficents for calibration purposes
+ //
+ printf("TPC spacepoint correction: \"%s\"\n",GetTitle());
+}
+
+void AliTPCCorrection:: SetOmegaTauT1T2(Float_t /*omegaTau*/,Float_t /*t1*/,Float_t /*t2*/) {
+ //
+ // Virtual funtion to pass the wt values (might become event dependent) to the inherited classes
+ // t1 and t2 represent the "effective omegaTau" corrections and were measured in a dedicated
+ // calibration run
+ //
+ // SetOmegaTauT1T2(omegaTau, t1, t2);
+}
+
+TH2F* AliTPCCorrection::CreateHistoDRinXY(Float_t z,Int_t nx,Int_t ny) {
+ //
+ // Simple plot functionality.
+ // Returns a 2d hisogram which represents the corrections in radial direction (dr)
+ // in respect to position z within the XY plane.
+ // The histogramm has nx times ny entries.
+ //
+
+ TH2F *h=CreateTH2F("dr_xy",GetTitle(),"x [cm]","y [cm]","dr [cm]",
+ nx,-250.,250.,ny,-250.,250.);
+ Float_t x[3],dx[3];
+ x[2]=z;
+ Int_t roc=z>0.?0:18; // FIXME
+ for (Int_t iy=1;iy<=ny;++iy) {
+ x[1]=h->GetYaxis()->GetBinCenter(iy);
+ for (Int_t ix=1;ix<=nx;++ix) {
+ x[0]=h->GetXaxis()->GetBinCenter(ix);
+ GetCorrection(x,roc,dx);
+ Float_t r0=TMath::Sqrt((x[0] )*(x[0] )+(x[1] )*(x[1] ));
+ if (90.<=r0 && r0<=250.) {
+ Float_t r1=TMath::Sqrt((x[0]+dx[0])*(x[0]+dx[0])+(x[1]+dx[1])*(x[1]+dx[1]));
+ h->SetBinContent(ix,iy,r1-r0);
+ }
+ else
+ h->SetBinContent(ix,iy,0.);
+ }
+ }
+ return h;
+}
+
+TH2F* AliTPCCorrection::CreateHistoDRPhiinXY(Float_t z,Int_t nx,Int_t ny) {
+ //
+ // Simple plot functionality.
+ // Returns a 2d hisogram which represents the corrections in rphi direction (drphi)
+ // in respect to position z within the XY plane.
+ // The histogramm has nx times ny entries.
+ //
+
+ TH2F *h=CreateTH2F("drphi_xy",GetTitle(),"x [cm]","y [cm]","drphi [cm]",
+ nx,-250.,250.,ny,-250.,250.);
+ Float_t x[3],dx[3];
+ x[2]=z;
+ Int_t roc=z>0.?0:18; // FIXME
+ for (Int_t iy=1;iy<=ny;++iy) {
+ x[1]=h->GetYaxis()->GetBinCenter(iy);
+ for (Int_t ix=1;ix<=nx;++ix) {
+ x[0]=h->GetXaxis()->GetBinCenter(ix);
+ GetCorrection(x,roc,dx);
+ Float_t r0=TMath::Sqrt((x[0] )*(x[0] )+(x[1] )*(x[1] ));
+ if (90.<=r0 && r0<=250.) {
+ Float_t phi0=TMath::ATan2(x[1] ,x[0] );
+ Float_t phi1=TMath::ATan2(x[1]+dx[1],x[0]+dx[0]);
+
+ Float_t dphi=phi1-phi0;
+ if (dphi<TMath::Pi()) dphi+=TMath::TwoPi();
+ if (dphi>TMath::Pi()) dphi-=TMath::TwoPi();
+
+ h->SetBinContent(ix,iy,r0*dphi);
+ }
+ else
+ h->SetBinContent(ix,iy,0.);
+ }
+ }
+ return h;
+}
+
+TH2F* AliTPCCorrection::CreateHistoDRinZR(Float_t phi,Int_t nz,Int_t nr) {
+ //
+ // Simple plot functionality.
+ // Returns a 2d hisogram which represents the corrections in r direction (dr)
+ // in respect to angle phi within the ZR plane.
+ // The histogramm has nx times ny entries.
+ //
+ TH2F *h=CreateTH2F("dr_zr",GetTitle(),"z [cm]","r [cm]","dr [cm]",
+ nz,-250.,250.,nr,85.,250.);
+ Float_t x[3],dx[3];
+ for (Int_t ir=1;ir<=nr;++ir) {
+ Float_t radius=h->GetYaxis()->GetBinCenter(ir);
+ x[0]=radius*TMath::Cos(phi);
+ x[1]=radius*TMath::Sin(phi);
+ for (Int_t iz=1;iz<=nz;++iz) {
+ x[2]=h->GetXaxis()->GetBinCenter(iz);
+ Int_t roc=x[2]>0.?0:18; // FIXME
+ GetCorrection(x,roc,dx);
+ Float_t r0=TMath::Sqrt((x[0] )*(x[0] )+(x[1] )*(x[1] ));
+ Float_t r1=TMath::Sqrt((x[0]+dx[0])*(x[0]+dx[0])+(x[1]+dx[1])*(x[1]+dx[1]));
+ h->SetBinContent(iz,ir,r1-r0);
+ }
+ }
+ printf("SDF\n");
+ return h;
+
+}
+
+TH2F* AliTPCCorrection::CreateHistoDRPhiinZR(Float_t phi,Int_t nz,Int_t nr) {
+ //
+ // Simple plot functionality.
+ // Returns a 2d hisogram which represents the corrections in rphi direction (drphi)
+ // in respect to angle phi within the ZR plane.
+ // The histogramm has nx times ny entries.
+ //
+ TH2F *h=CreateTH2F("drphi_zr",GetTitle(),"z [cm]","r [cm]","drphi [cm]",
+ nz,-250.,250.,nr,85.,250.);
+ Float_t x[3],dx[3];
+ for (Int_t iz=1;iz<=nz;++iz) {
+ x[2]=h->GetXaxis()->GetBinCenter(iz);
+ Int_t roc=x[2]>0.?0:18; // FIXME
+ for (Int_t ir=1;ir<=nr;++ir) {
+ Float_t radius=h->GetYaxis()->GetBinCenter(ir);
+ x[0]=radius*TMath::Cos(phi);
+ x[1]=radius*TMath::Sin(phi);
+ GetCorrection(x,roc,dx);
+ Float_t r0=TMath::Sqrt((x[0] )*(x[0] )+(x[1] )*(x[1] ));
+ Float_t phi0=TMath::ATan2(x[1] ,x[0] );
+ Float_t phi1=TMath::ATan2(x[1]+dx[1],x[0]+dx[0]);
+
+ Float_t dphi=phi1-phi0;
+ if (dphi<TMath::Pi()) dphi+=TMath::TwoPi();
+ if (dphi>TMath::Pi()) dphi-=TMath::TwoPi();
+
+ h->SetBinContent(iz,ir,r0*dphi);
+ }
+ }
+ return h;
+}
+
+TH2F* AliTPCCorrection::CreateTH2F(const char *name,const char *title,
+ const char *xlabel,const char *ylabel,const char *zlabel,
+ Int_t nbinsx,Double_t xlow,Double_t xup,
+ Int_t nbinsy,Double_t ylow,Double_t yup) {
+ //
+ // Helper function to create a 2d histogramm of given size
+ //
+
+ TString hname=name;
+ Int_t i=0;
+ if (gDirectory) {
+ while (gDirectory->FindObject(hname.Data())) {
+ hname =name;
+ hname+="_";
+ hname+=i;
+ ++i;
+ }
+ }
+ TH2F *h=new TH2F(hname.Data(),title,
+ nbinsx,xlow,xup,
+ nbinsy,ylow,yup);
+ h->GetXaxis()->SetTitle(xlabel);
+ h->GetYaxis()->SetTitle(ylabel);
+ h->GetZaxis()->SetTitle(zlabel);
+ h->SetStats(0);
+ return h;
+}
+
+
+// Simple Interpolation functions: e.g. with bi(tri)cubic interpolations (not yet in TH2 and TH3)
+
+void AliTPCCorrection::Interpolate2DEdistortion( const Int_t order, const Double_t r, const Double_t z,
+ const Double_t er[kNZ][kNR], Double_t &er_value )
+{
+ //
+ // Interpolate table - 2D interpolation
+ //
+ Double_t save_er[10] ;
+
+ Search( kNZ, fgkZList, z, fJLow ) ;
+ Search( kNR, fgkRList, r, fKLow ) ;
+ if ( fJLow < 0 ) fJLow = 0 ; // check if out of range
+ if ( fKLow < 0 ) fKLow = 0 ;
+ if ( fJLow + order >= kNZ - 1 ) fJLow = kNZ - 1 - order ;
+ if ( fKLow + order >= kNR - 1 ) fKLow = kNR - 1 - order ;
+
+ for ( Int_t j = fJLow ; j < fJLow + order + 1 ; j++ ) {
+ save_er[j-fJLow] = Interpolate( &fgkRList[fKLow], &er[j][fKLow], order, r ) ;
+ }
+ er_value = Interpolate( &fgkZList[fJLow], save_er, order, z ) ;
+
+}
+
+
+Double_t AliTPCCorrection::Interpolate( const Double_t xArray[], const Double_t yArray[],
+ const Int_t order, const Double_t x )
+{
+ //
+ // Interpolate function Y(x) using linear (order=1) or quadratic (order=2) interpolation.
+ //
+
+ Double_t y ;
+ if ( order == 2 ) { // Quadratic Interpolation = 2
+ y = (x-xArray[1]) * (x-xArray[2]) * yArray[0] / ( (xArray[0]-xArray[1]) * (xArray[0]-xArray[2]) ) ;
+ y += (x-xArray[2]) * (x-xArray[0]) * yArray[1] / ( (xArray[1]-xArray[2]) * (xArray[1]-xArray[0]) ) ;
+ y += (x-xArray[0]) * (x-xArray[1]) * yArray[2] / ( (xArray[2]-xArray[0]) * (xArray[2]-xArray[1]) ) ;
+ } else { // Linear Interpolation = 1
+ y = yArray[0] + ( yArray[1]-yArray[0] ) * ( x-xArray[0] ) / ( xArray[1] - xArray[0] ) ;
+ }
+
+ return (y);
+
+}
+
+
+void AliTPCCorrection::Search( const Int_t n, const Double_t xArray[], const Double_t x, Int_t &low )
+{
+ //
+ // Search an ordered table by starting at the most recently used point
+ //
+
+ Long_t middle, high ;
+ Int_t ascend = 0, increment = 1 ;
+
+ if ( xArray[n-1] >= xArray[0] ) ascend = 1 ; // Ascending ordered table if true
+
+ if ( low < 0 || low > n-1 ) {
+ low = -1 ; high = n ;
+ } else { // Ordered Search phase
+ if ( (Int_t)( x >= xArray[low] ) == ascend ) {
+ if ( low == n-1 ) return ;
+ high = low + 1 ;
+ while ( (Int_t)( x >= xArray[high] ) == ascend ) {
+ low = high ;
+ increment *= 2 ;
+ high = low + increment ;
+ if ( high > n-1 ) { high = n ; break ; }
+ }
+ } else {
+ if ( low == 0 ) { low = -1 ; return ; }
+ high = low - 1 ;
+ while ( (Int_t)( x < xArray[low] ) == ascend ) {
+ high = low ;
+ increment *= 2 ;
+ if ( increment >= high ) { low = -1 ; break ; }
+ else low = high - increment ;
+ }
+ }
+ }
+
+ while ( (high-low) != 1 ) { // Binary Search Phase
+ middle = ( high + low ) / 2 ;
+ if ( (Int_t)( x >= xArray[middle] ) == ascend )
+ low = middle ;
+ else
+ high = middle ;
+ }
+
+ if ( x == xArray[n-1] ) low = n-2 ;
+ if ( x == xArray[0] ) low = 0 ;
+
+}
+
+ClassImp(AliTPCCorrection)
--- /dev/null
+#ifndef ALI_TPC_CORRECTION_H
+#define ALI_TPC_CORRECTION_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+////////////////////////////////////////////////////////////////////////////////
+// //
+// AliTPCCorrection class //
+// //
+// This class provides a general framework to deal with space point //
+// distortions. An correction class which inherits from here is for example //
+// AliTPCExBBShape or AliTPCExBTwist //
+// //
+// General functions are (for example): //
+// CorrectPoint(x,roc) where x is the vector of inital positions in //
+// cartesian coordinates and roc represents the Read Out chamber number //
+// according to the offline naming convention. The vector x is overwritten //
+// with the corrected coordinates. //
+// //
+// An alternative usage would be CorrectPoint(x,roc,dx), which leaves the //
+// vector x untouched, put returns the distortions via the vector dx //
+// //
+// The class allows "effective Omega Tau" corrections to be shifted to the //
+// single distortion classes. //
+// //
+// Note: This class is normally used via the class AliTPCComposedCorrection //
+// //
+// date: 27/04/2010 //
+// Authors: Magnus Mager, Stefan Rossegger, Jim Thomas //
+////////////////////////////////////////////////////////////////////////////////
+
+
+#include <TNamed.h>
+class TH2F;
+class TCollection;
+
+class AliTPCCorrection : public TNamed {
+public:
+ enum CompositionType {kParallel,kQueue};
+
+ AliTPCCorrection();
+ AliTPCCorrection(const char *name,const char *title);
+ virtual ~AliTPCCorrection();
+
+
+ // functions to correct a space point
+ void CorrectPoint ( Float_t x[],const Short_t roc);
+ void CorrectPoint (const Float_t x[],const Short_t roc,Float_t xp[]);
+ virtual void GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]);
+
+ // functions to distort a space point
+ void DistortPoint ( Float_t x[],const Short_t roc);
+ void DistortPoint (const Float_t x[],const Short_t roc,Float_t xp[]);
+ virtual void GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]);
+
+ // initialization
+ virtual void Init();
+
+ // convenience functions
+ virtual void Print(Option_t* option="") const;
+
+ TH2F* CreateHistoDRinXY (Float_t z=10.,Int_t nx=100,Int_t ny=100);
+ TH2F* CreateHistoDRPhiinXY(Float_t z=10.,Int_t nx=100,Int_t nphi=100);
+ TH2F* CreateHistoDRinZR (Float_t phi=0.,Int_t nZ=100,Int_t nR=100);
+ TH2F* CreateHistoDRPhiinZR(Float_t phi=0.,Int_t nZ=100,Int_t nR=100);
+
+ // normally called directly in the correction classes which inherit from this class
+ virtual void SetOmegaTauT1T2(Float_t omegaTau,Float_t t1,Float_t t2);
+
+protected:
+ TH2F* CreateTH2F(const char *name,const char *title,
+ const char *xlabel,const char *ylabel,const char *zlabel,
+ Int_t nbinsx,Double_t xlow,Double_t xup,
+ Int_t nbinsy,Double_t ylow,Double_t yup);
+
+ static const Double_t fgkTPC_Z0; // nominal gating grid position
+ static const Double_t fgkIFCRadius; // Mean Radius of the Inner Field Cage ( 82.43 min, 83.70 max) (cm)
+ static const Double_t fgkOFCRadius; // Mean Radius of the Outer Field Cage (252.55 min, 256.45 max) (cm)
+ static const Double_t fgkZOffSet; // Offset from CE: calculate all distortions closer to CE as if at this point
+ static const Double_t fgkCathodeV; // Cathode Voltage (volts)
+ static const Double_t fgkGG; // Gating Grid voltage (volts)
+
+ enum {kNR= 92}; // Number of R points in the table for interpolating distortion data
+ enum {kNZ= 270}; // Number of Z points in the table for interpolating distortion data
+ static const Double_t fgkRList[kNR];
+ static const Double_t fgkZList[kNZ];
+
+ // Simple Interpolation functions: e.g. with tricubic interpolation (not yet in TH3)
+ Int_t fJLow;
+ Int_t fKLow;
+ void Interpolate2DEdistortion( const Int_t order, const Double_t r, const Double_t z,
+ const Double_t er[kNZ][kNR], Double_t &er_value );
+ Double_t Interpolate( const Double_t xArray[], const Double_t yArray[],
+ const Int_t order, const Double_t x );
+ void Search( const Int_t n, const Double_t xArray[], const Double_t x, Int_t &low );
+
+
+
+ ClassDef(AliTPCCorrection,1);
+};
+
+#endif
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////
+// //
+// AliExBBShape class //
+// The class calculates the space point distortions due to the B field //
+// shape imperfections using a second order technique based on integrals //
+// over Bz (e.g. int By/Bz) obtained via the AliMagF class //
+// The class allows "effective Omega Tau" corrections. //
+// //
+// date: 27/04/2010 //
+// Authors: Magnus Mager, Jim Thomas, Stefan Rossegger //
+// //
+// Example usage: //
+// AliMagF mag("mag","mag"); //
+// AliTPCExBBShape exb; //
+// exb.SetBField(&mag); // use Bfield from AliMagF //
+// exb.SetOmegaTauT1T2(0.32,1.,1.); // values ideally from OCDB //
+// // plot dRPhi distortions ... //
+// exb.CreateHistoDRPhiinZR(0,100,100)->Draw("surf2"); //
+////////////////////////////////////////////////////////////////////////////
+
+#include <AliMagF.h>
+
+#include "AliTPCExBBShape.h"
+
+AliTPCExBBShape::AliTPCExBBShape()
+ : AliTPCCorrection("exb_bshape","ExB B-shape"),
+ fC1(0.),fC2(0.),
+ fBField(0)
+{
+ //
+ // default constructor
+ //
+}
+
+AliTPCExBBShape::~AliTPCExBBShape() {
+ //
+ // virtual destructor
+ //
+}
+
+void AliTPCExBBShape::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
+ //
+ // Calculates the space point corrections of the B field inperfections (B field shape)
+ //
+
+ if (!fBField) {
+ for (Int_t j=0;j<3;++j) dx[j]=0.;
+ return;
+ }
+
+ const Double_t xStart[3]={ x[0], x[1], x[2] };
+ const Double_t xEnd[3]={ x[0], x[1], roc%36<18?fgkTPC_Z0:-fgkTPC_Z0 };
+
+ Double_t intBStart[3];
+ Double_t intBEnd[3];
+
+ fBField->GetTPCRatInt(xStart,intBStart);
+ fBField->GetTPCRatInt(xEnd, intBEnd );
+
+ const Float_t intBxOverBz=(intBEnd[0]-intBStart[0]);
+ const Float_t intByOverBz=(intBEnd[1]-intBStart[1]);
+
+ dx[0]=fC2*intBxOverBz-fC1*intByOverBz;
+ dx[1]=fC1*intBxOverBz+fC2*intByOverBz;
+ dx[2]=0.;
+
+
+}
+
+void AliTPCExBBShape::GetBxAndByOverBz(const Float_t x[],const Short_t roc,Float_t BxByOverBz[]) {
+ //
+ // This function is purely for calibration purposes
+ // Returns the via AliMagF obtaind B field integrals
+ //
+
+ if (!fBField) {
+ for (Int_t j=0;j<3;++j) BxByOverBz[j]=0.;
+ return;
+ }
+
+ const Double_t xStart[3]={ x[0], x[1], x[2] };
+ const Double_t xEnd[3]={ x[0], x[1], roc%36<18?fgkTPC_Z0:-fgkTPC_Z0 };
+
+ Double_t intBStart[3];
+ Double_t intBEnd[3];
+
+ fBField->GetTPCRatInt(xStart,intBStart);
+ fBField->GetTPCRatInt(xEnd, intBEnd );
+
+ const Float_t intBxOverBz=(intBEnd[0]-intBStart[0]);
+ const Float_t intByOverBz=(intBEnd[1]-intBStart[1]);
+
+ BxByOverBz[0]=intBxOverBz;
+ BxByOverBz[1]=intByOverBz;
+
+}
+
+void AliTPCExBBShape::Print(Option_t* option) const {
+ //
+ // Print function to check the settings (e.g. voltage offsets)
+ // option=="a" prints details of the B field settings and the
+ // C0 and C1 coefficents (for calibration purposes)
+ //
+ TString opt = option; opt.ToLower();
+ printf("%s\n - B field settings:\n",GetTitle());
+ fBField->Print(option);
+ // printf(" - B field: X-Twist: %1.5lf rad, Y-Twist: %1.5lf rad \n",fBField->Print(option));
+ if (opt.Contains("a")) { // Print all details
+ printf(" - C1: %1.4f, C2: %1.4f \n",fC1,fC2);
+ }
+
+}
--- /dev/null
+#ifndef ALI_TPC_EXB_B_SHAPE_H
+#define ALI_TPC_EXB_B_SHAPE_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+////////////////////////////////////////////////////////////////////////////
+// //
+// AliExBBShape class //
+// The class calculates the space point distortions due to the B field //
+// shape imperfections using a second order technique based on integrals //
+// over Bz (e.g. int By/Bz) obtained via the AliMagF class //
+// The class allows "effective Omega Tau" corrections. //
+// //
+// date: 27/04/2010 //
+// Authors: Magnus Mager, Jim Thomas, Stefan Rossegger //
+////////////////////////////////////////////////////////////////////////////
+
+#include "AliTPCCorrection.h"
+
+class AliMagF;
+
+class AliTPCExBBShape : public AliTPCCorrection {
+public:
+ AliTPCExBBShape();
+ virtual ~AliTPCExBBShape();
+
+ // common setters and getters for ExB
+ virtual void SetOmegaTauT1T2(Float_t omegaTau,Float_t t1,Float_t t2) {
+ const Float_t wt1=t1*omegaTau;
+ fC1=wt1/(1.+wt1*wt1);
+ const Float_t wt2=t2*omegaTau;
+ fC2=wt2*wt2/(1.+wt2*wt2);
+ };
+ void SetC1C2(Float_t c1,Float_t c2) {fC1=c1;fC2=c2;} // CAUTION: USE WITH CARE
+ Float_t GetC1() const {return fC1;}
+ Float_t GetC2() const {return fC2;}
+
+ // setters and getters for the magentic field map
+ void SetBField(AliMagF *bField) {fBField=bField;}
+ AliMagF* GetBField() const {return fBField;}
+
+ virtual void GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]);
+ void GetBxAndByOverBz(const Float_t x[],const Short_t roc,Float_t BxByOverBz[]);
+
+ virtual void Print(Option_t* option="") const;
+
+private:
+ Float_t fC1; // coefficient C1 (compare Jim Thomas's notes for definitions)
+ Float_t fC2; // coefficient C2 (compare Jim Thomas's notes for definitions)
+
+ AliMagF *fBField;
+
+ AliTPCExBBShape & operator =(const AliTPCExBBShape);
+ AliTPCExBBShape(const AliTPCExBBShape&); //dummy copy contructor
+
+ ClassDef(AliTPCExBBShape,1);
+};
+
+#endif
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////
+// //
+// AliTPCExBTwist class //
+// The class calculates the space point distortions due to a mismatch //
+// of the E and B field axis (original code from STAR) //
+// The class allows "effective Omega Tau" corrections. //
+// //
+// date: 27/04/2010 //
+// Authors: Jim Thomas, Magnus Mager, Stefan Rossegger //
+// //
+// Example usage: //
+// AliTPCExBTwist twist; //
+// twist.SetOmegaTauT1T2(0.32,1.,1.); // values ideally from OCDB //
+// twist.SetXTwist(0.001); // set twist in X direction (in rad) //
+// // plot dRPhi distortions ... //
+// twist.CreateHistoDRPhiinZR(1.,100,100)->Draw("surf2"); //
+////////////////////////////////////////////////////////////////////////////
+
+#include "AliTPCExBTwist.h"
+
+AliTPCExBTwist::AliTPCExBTwist()
+ : AliTPCCorrection("exb_twist","ExB twist"),
+ fC1(0.),fC2(0.),
+ fXTwist(0.),fYTwist(0.)
+{
+ //
+ // default constructor
+ //
+}
+
+AliTPCExBTwist::~AliTPCExBTwist() {
+ //
+ // default destructor
+ //
+}
+
+void AliTPCExBTwist::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
+ //
+ // Calculates the correction of a mismatch between the E and B field axis
+ //
+
+ const Float_t zstart=x[2];
+ const Float_t zend =(roc%36<18?fgkTPC_Z0:-fgkTPC_Z0);
+ const Float_t zdrift=zstart-zend;
+
+ dx[0]=(fC2*fXTwist-fC1*fYTwist)*zdrift;
+ dx[1]=(fC1*fXTwist+fC2*fYTwist)*zdrift;
+ dx[2]=0.;
+}
+
+void AliTPCExBTwist::Print(Option_t* option) const {
+ //
+ // Print function to check the settings (e.g. the twist in the X direction)
+ // option=="a" prints the C0 and C1 coefficents for calibration purposes
+ //
+
+ TString opt = option; opt.ToLower();
+ printf("%s\n",GetTitle());
+
+ printf(" - Twist settings: X-Twist: %1.5f rad, Y-Twist: %1.5f rad \n",fXTwist,fYTwist);
+ if (opt.Contains("a")) { // Print all details
+ printf(" - C1: %1.4f, C2: %1.4f \n",fC1,fC2);
+ }
+
+
+}
--- /dev/null
+#ifndef ALI_TPC_EXB_TWIST_H
+#define ALI_TPC_EXB_TWIST_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+////////////////////////////////////////////////////////////////////////////
+// //
+// AliTPCExBTwist class //
+// The class calculates the space point distortions due to a mismatch //
+// of the E and B field axis (original code from STAR) //
+// The class allows "effective Omega Tau" corrections. //
+// //
+// date: 27/04/2010 //
+// Authors: Jim Thomas, Magnus Mager, Stefan Rossegger //
+////////////////////////////////////////////////////////////////////////////
+
+#include "AliTPCCorrection.h"
+
+class AliTPCExBTwist : public AliTPCCorrection {
+public:
+ AliTPCExBTwist();
+ virtual ~AliTPCExBTwist();
+
+ // common setters and getters for ExB
+ virtual void SetOmegaTauT1T2(Float_t omegaTau,Float_t t1,Float_t t2) {
+ const Float_t wt1=t1*omegaTau;
+ fC1=wt1/(1.+wt1*wt1);
+ const Float_t wt2=t2*omegaTau;
+ fC2=wt2*wt2/(1.+wt2*wt2);
+ };
+ void SetC1C2(Float_t c1,Float_t c2) {fC1=c1;fC2=c2;} // CAUTION: USE WITH CARE
+ Float_t GetC1() const {return fC1;}
+ Float_t GetC2() const {return fC2;}
+
+ // setters and getters for twist
+ void SetXTwist(Float_t xTwist) {fXTwist=xTwist;}
+ void SetYTwist(Float_t yTwist) {fYTwist=yTwist;}
+ Float_t GetXTwist() const {return fXTwist;}
+ Float_t GetYTwist() const {return fYTwist;}
+
+ virtual void Print(Option_t* option="") const;
+
+protected:
+ virtual void GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]);
+
+private:
+ Float_t fC1; // coefficient C1 (compare Jim Thomas's notes for definitions)
+ Float_t fC2; // coefficient C2 (compare Jim Thomas's notes for definitions)
+
+ Float_t fXTwist; // Twist of E to B field in X-Z [rad]
+ Float_t fYTwist; // Twist of E to B field in Y-Z [rad]
+
+ ClassDef(AliTPCExBTwist,1);
+};
+
+#endif
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////
+// //
+// AliTPCGGVoltError class //
+// The class calculates the electric field and space point distortions //
+// due a Gating Grid (GG) Error voltage. It uses the exact calculation //
+// technique based on bessel functions. (original code from STAR) //
+// The class allows "effective Omega Tau" corrections. //
+// //
+// date: 27/04/2010 //
+// Authors: Jim Thomas, Stefan Rossegger, Magnus Mager //
+// //
+// Example usage: //
+// AliTPCGGVoltError GGerror; //
+// GGerror.SetOmegaTauT1T2(0.32,1.,1.); // values ideally from OCDB //
+// GGerror.SetDeltaVGGA(50.); // voltage offset A-side //
+// GGerror.SetDeltaVGGC(50.); // voltage offset C-side //
+// GGerror.InitGGVoltErrorDistortion(); // initialization of the look up //
+// // plot dRPhi distortions ... //
+// GGerror.CreateHistoDRPhiinZR(1.,100,100)->Draw("surf2"); //
+////////////////////////////////////////////////////////////////////////////
+
+
+
+#include "AliTPCGGVoltError.h"
+#include <TMath.h>
+
+AliTPCGGVoltError::AliTPCGGVoltError()
+ : AliTPCCorrection("GGVoltError","GatingGrid (GG) Voltage Error"),
+ fC0(0.),fC1(0.),
+ fDeltaVGGA(0.),fDeltaVGGC(0.)
+{
+ //
+ // default constructor
+ //
+}
+
+AliTPCGGVoltError::~AliTPCGGVoltError() {
+ //
+ // default destructor
+ //
+}
+
+void AliTPCGGVoltError::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
+
+ //
+ // Gated Grid Voltage Error
+ //
+ // Calculates the effect of having an incorrect voltage on the A or C end plate Gated Grids.
+ //
+ // Electrostatic Equations from StarNote SN0253 by Howard Wieman.
+ //
+
+ Int_t order = 1 ; // FIXME: hardcoded? Linear interpolation = 1, Quadratic = 2
+
+ Double_t intEr, intEphi ;
+ Double_t r, phi, z ;
+ Int_t sign ;
+
+ Double_t deltaVGG;
+
+ r = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
+ phi = TMath::ATan2(x[1],x[0]);
+ if ( phi < 0 ) phi += TMath::TwoPi(); // Table uses phi from 0 to 2*Pi
+ z = x[2] ;
+
+ if ( (roc%36) < 18 ) {
+ sign = 1;
+ deltaVGG = fDeltaVGGA; // (TPC End A)
+ } else {
+ sign = -1; // (TPC End C)
+ deltaVGG = fDeltaVGGC;
+ }
+
+ if ( sign==1 && z < fgkZOffSet ) z = fgkZOffSet; // Protect against discontinuity at CE
+ if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet; // Protect against discontinuity at CE
+
+ Interpolate2DEdistortion( order, r, z, fGGVoltErrorER, intEr );
+ intEphi = 0.0; // Efield is symmetric in phi
+
+ // Calculate distorted position
+ if ( r > 0.0 ) {
+ phi = phi + deltaVGG*( fC0*intEphi - fC1*intEr ) / r;
+ r = r + deltaVGG*( fC0*intEr + fC1*intEphi );
+ }
+
+ // Calculate correction in cartesian coordinates
+ dx[0] = r * TMath::Cos(phi) - x[0];
+ dx[1] = r * TMath::Sin(phi) - x[1];
+ dx[2] = 0.; // z distortion not implemented (1st order distortions)
+
+}
+
+
+Float_t AliTPCGGVoltError::GetIntErOverEz(const Float_t x[],const Short_t roc) {
+ //
+ // This function is purely for calibration purposes
+ // Calculates the integral (int Er/Ez dz) for the setted GG voltage offset
+ //
+
+ Int_t order = 1 ; // FIXME: so far hardcoded? Linear interpolation = 1, Quadratic = 2
+
+ Double_t intEr;
+ Double_t r, phi, z ;
+ Int_t sign ;
+
+ Double_t deltaVGG;
+
+ r = TMath::Sqrt( x[0]*x[0] + x[1]*x[1] );
+ phi = TMath::ATan2(x[1],x[0]);
+ if ( phi < 0 ) phi += TMath::TwoPi(); // Table uses phi from 0 to 2*Pi
+ z = x[2] ;
+
+ if ( (roc%36) < 18 ) {
+ sign = 1;
+ deltaVGG = fDeltaVGGA; // (TPC End A)
+ } else {
+ sign = -1; // (TPC End C)
+ deltaVGG = fDeltaVGGC;
+ }
+
+ if ( sign==1 && z < fgkZOffSet ) z = fgkZOffSet; // Protect against discontinuity at CE
+ if ( sign==-1 && z > -fgkZOffSet ) z = -fgkZOffSet; // Protect against discontinuity at CE
+
+ Interpolate2DEdistortion(order, r, z, fGGVoltErrorER, intEr );
+
+ return (intEr*deltaVGG);
+
+}
+
+void AliTPCGGVoltError::InitGGVoltErrorDistortion() {
+ //
+ // Initialization of the Lookup table which contains the solutions of the GG Error problem
+ //
+
+ Double_t r,z;
+ Int_t nterms = 100 ;
+ for ( Int_t i = 0 ; i < kNZ ; ++i ) {
+ z = fgkZList[i] ;
+ for ( Int_t j = 0 ; j < kNR ; ++j ) {
+ r = fgkRList[j] ;
+ fGGVoltErrorER[i][j] = 0.0 ;
+ Double_t intz = 0.0 ;
+ for ( Int_t n = 1 ; n < nterms ; ++n ) {
+ Double_t k = n * TMath::Pi() / fgkTPC_Z0 ;
+ Double_t ein = 0 ; // Error potential on the IFC
+ Double_t eout = 0 ; // Error potential on the OFC
+ if ( z < 0 ) {
+ ein = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
+ eout = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
+ }
+ if ( z == 0 ) continue ;
+ if ( z > 0 ) {
+ ein = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
+ eout = -2.0 / ( k * (fgkCathodeV - fgkGG) ) ;
+ }
+ Double_t an = ein * TMath::BesselK0( k*fgkOFCRadius ) - eout * TMath::BesselK0( k*fgkIFCRadius ) ;
+ Double_t bn = eout * TMath::BesselI0( k*fgkIFCRadius ) - ein * TMath::BesselI0( k*fgkOFCRadius ) ;
+ Double_t numerator =
+ an * TMath::BesselI1( k*r ) - bn * TMath::BesselK1( k*r ) ;
+ Double_t denominator =
+ TMath::BesselK0( k*fgkOFCRadius ) * TMath::BesselI0( k*fgkIFCRadius ) -
+ TMath::BesselK0( k*fgkIFCRadius ) * TMath::BesselI0( k*fgkOFCRadius ) ;
+ Double_t zterm = TMath::Cos( k*(fgkTPC_Z0-TMath::Abs(z)) ) - 1 ;
+ intz += zterm * numerator / denominator ;
+ // Assume series converges, break if small terms
+ if ( n>10 && fabs(intz)*1.e-10 > fabs(numerator/denominator) ) break;
+ }
+ fGGVoltErrorER[i][j] = (Double_t) intz ;
+
+ }
+ }
+}
+
+
+
+void AliTPCGGVoltError::Print(Option_t* option) const {
+ //
+ // Print function to check the settings (e.g. voltage offsets)
+ // option=="a" prints the C0 and C1 coefficents for calibration purposes
+ //
+
+ TString opt = option; opt.ToLower();
+ printf("%s\n",GetTitle());
+ printf(" - GG Voltage offset: A-side: %3.1f V, C-side: %3.1f V \n",fDeltaVGGA,fDeltaVGGC);
+ if (opt.Contains("a")) { // Print all details
+ printf(" - C1: %1.4f, C0: %1.4f \n",fC1,fC0);
+ }
+
+
+
+}
--- /dev/null
+#ifndef ALI_TPC_GG_VOLT_ERROR_H
+#define ALI_TPC_GG_VOLT_ERROR_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+////////////////////////////////////////////////////////////////////////////
+// //
+// AliTPCGGVoltError class //
+// The class calculates the electric field and space point distortions //
+// due a Gating Grid (GG) Error voltage. It uses the exact calculation //
+// technique based on bessel functions. (original code from STAR) //
+// The class allows "effective Omega Tau" corrections. //
+// //
+// date: 27/04/2010 //
+// Authors: Jim Thomas, Stefan Rossegger, Magnus Mager //
+////////////////////////////////////////////////////////////////////////////
+
+#include "AliTPCCorrection.h"
+
+class AliTPCGGVoltError : public AliTPCCorrection {
+public:
+ AliTPCGGVoltError();
+ virtual ~AliTPCGGVoltError();
+
+ // common setters and getters for ExB
+ virtual void SetOmegaTauT1T2(Float_t omegaTau,Float_t t1,Float_t t2) {
+ const Double_t wt0=t2*omegaTau;
+ fC0=1./(1.+wt0*wt0);
+ const Double_t wt1=t1*omegaTau;
+ fC1=wt1/(1.+wt1*wt1);
+ };
+
+ void SetC0C1(Double_t c0,Double_t c1) {fC0=c0;fC1=c1;} // CAUTION: USE WITH CARE
+ Float_t GetC0() const {return fC0;}
+ Float_t GetC1() const {return fC1;}
+
+ // setters and getters for GG
+ void SetDeltaVGGA(Double_t deltaVGGA) {fDeltaVGGA=deltaVGGA;}
+ void SetDeltaVGGC(Double_t deltaVGGC) {fDeltaVGGC=deltaVGGC;}
+ Double_t GetDeltaVGGA() const {return fDeltaVGGA;}
+ Double_t GetDeltaVGGC() const {return fDeltaVGGC;}
+
+ void InitGGVoltErrorDistortion();
+
+ Float_t GetIntErOverEz(const Float_t x[],const Short_t roc);
+
+ virtual void Print(Option_t* option="") const;
+
+protected:
+ virtual void GetCorrection(const Float_t x[],const Short_t roc, Float_t dx[]);
+private:
+
+ Float_t fC0; // coefficient C0 (compare Jim Thomas's notes for definitions)
+ Float_t fC1; // coefficient C1 (compare Jim Thomas's notes for definitions)
+
+ Double_t fDeltaVGGA; // Missmatch of gating grid voltage on A-side [V]
+ Double_t fDeltaVGGC; // Missmatch of gating grid voltage on C-side [V]
+ Double_t fGGVoltErrorER[kNZ][kNR]; // Array to store electric field for GGVoltError calculation
+
+ ClassDef(AliTPCGGVoltError,1);
+};
+
+#endif
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////
+// //
+// AliTPCInverseCorrection class //
+// //
+// This is a wrapper that inverts an AliTPCCorrection. This is done by //
+// swapping the CalculateCorrection and CalculateInverseCorrection functions. //
+// The wrapped correction is supplied as a pointer and the class relies //
+// on the fact, that this pointer keeps pointing to the right object. //
+// However, the ownership is not changed, i.e. the wrapped correction //
+// will not be deleted when this correction is destructed. //
+// //
+// date: 27/04/2010 //
+// Authors: Magnus Mager, Stefan Rossegger, Jim Thomas //
+////////////////////////////////////////////////////////////////////////////////
+
+#include <TString.h>
+#include "AliTPCInverseCorrection.h"
+
+AliTPCInverseCorrection::AliTPCInverseCorrection()
+ : fCorrection(0) {
+ //
+ // default constructor
+ // (only meant for ROOT I/O)
+ //
+}
+
+AliTPCInverseCorrection::AliTPCInverseCorrection(AliTPCCorrection *correction)
+ : fCorrection(correction) {
+ //
+ // Constructor that is creating the inverse of the supplied correction.
+ // It automatically sets the name ("inv_[correction name]") and tile
+ // ("Inverse of [correction title]").
+ //
+ TString name,title;
+ name ="inv_";
+ name +=correction->GetName();
+ title ="Inverse of ";
+ title+=correction->GetTitle();
+ SetName(name.Data());
+ SetTitle(title.Data());
+}
+
+AliTPCInverseCorrection::~AliTPCInverseCorrection() {
+ //
+ // virtual destructor
+ //
+}
+
+void AliTPCInverseCorrection::GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]) {
+ //
+ // This is just calling the CalculateInverseCorrection of the wrapped
+ // correction -- or puts dr=0 if the latter is 0.
+ //
+ if (fCorrection)
+ fCorrection->GetDistortion(x,roc,dx);
+ else
+ for (Int_t j=0;j<3;++j) dx[j]=0.;
+}
+
+void AliTPCInverseCorrection::GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]) {
+ //
+ // This is just calling the CalculateCorrection of the wrapped
+ // correction -- or puts dr=0 if the latter is 0.
+ //
+ if (fCorrection)
+ fCorrection->GetCorrection(x,roc,dx);
+ else
+ for (Int_t j=0;j<3;++j) dx[j]=0.;
+}
+
+ClassImp(AliTPCInverseCorrection)
--- /dev/null
+#ifndef ALI_TPC_INVERSE_CORRECTION_H
+#define ALI_TPC_INVERSE_CORRECTION_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+////////////////////////////////////////////////////////////////////////////////
+// //
+// AliTPCInverseCorrection class //
+// //
+// This is a wrapper that inverts an AliTPCCorrection. This is done by //
+// swapping the CalculateCorrection and CalculateInverseCorrection functions. //
+// The wrapped correction is supplied as a pointer and the class relies //
+// on the fact, that this pointer keeps pointing to the right object. //
+// However, the ownership is not changed, i.e. the wrapped correction //
+// will not be deleted when this correction is destructed. //
+// //
+// date: 27/04/2010 //
+// Authors: Magnus Mager, Stefan Rossegger, Jim Thomas //
+////////////////////////////////////////////////////////////////////////////////
+
+#include "AliTPCCorrection.h"
+
+class AliTPCInverseCorrection : public AliTPCCorrection {
+public:
+ AliTPCInverseCorrection();
+ AliTPCInverseCorrection(AliTPCCorrection *correction);
+ virtual ~AliTPCInverseCorrection();
+
+ void SetCorrection(AliTPCCorrection *correction) {fCorrection=correction;}
+ AliTPCCorrection* GetCorrection() const {return fCorrection;}
+ virtual void GetCorrection(const Float_t x[],const Short_t roc,Float_t dx[]);
+ virtual void GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]);
+private:
+ AliTPCCorrection *fCorrection; // The correction to be inverted.
+
+ AliTPCInverseCorrection & operator = (const AliTPCInverseCorrection);
+ AliTPCInverseCorrection(const AliTPCInverseCorrection&); //dummy copy contructor
+
+ ClassDef(AliTPCInverseCorrection,1);
+};
+
+#endif
--- /dev/null
+void AliTPCCorrectionDemo() {
+
+ //
+ // This is a Demo function of the general class AliTPCCorrection, which is used for
+ // general space point correction due to different effects.
+ // The effects used in this Demo are:
+ // 1. ExB twist - general offset of the TPC axis in comparison to the B field axis
+ // 2. GG error (Gating Grid volt. error) - not perfectly aligned GG voltage (in terms of voltage)
+ // 3. ExBBShape - B field shape correction of the secound order
+ //
+ // See class descriptions for further details
+ //
+ // Authors: Magnus Mager, Stefan Rossegger, Jim Thomas
+ //
+ //
+ // omegaTau (wt) of the langevin equation
+ // This is a function of the drift vel., the magnetic and electric field
+ // e.g. vd=2.6 cm/usc; Ez=400 V/cm; Bz=0.5 T
+ // wt = -10.0*(Bz*10)*vd/Ez = -0.325
+
+ Double_t vdrift = 2.6; // [cm/us] // to be updated: per second (ideally)
+ Double_t bzField = -0.5; // [Tesla] // to be updated: per run
+ Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
+ Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
+
+ // Correction Terms for effective omegaTau; obtained by a laser calibration run
+ Double_t T1 = 0.9;
+ Double_t T2 = 1.5;
+
+ AliMagF mag("mag","mag");
+
+ AliTPCExBTwist twist;
+ twist.SetXTwist(0.001);
+
+ AliTPCGGVoltError GGerror;
+ GGerror.SetDeltaVGGA(50.);
+ GGerror.SetDeltaVGGC(50.);
+ GGerror.InitGGVoltErrorDistortion();
+
+ AliTPCExBBShape exb;
+ exb.SetBField(&mag);
+
+ TObjArray cs;
+ cs.Add(&twist);
+ cs.Add(&GGerror);
+ cs.Add(&exb);
+
+ AliTPCComposedCorrection cc;
+ cc.SetCorrections(&cs);
+ cc.SetOmegaTauT1T2(wt,T1,T2);
+ cc.SetMode(1);
+
+ cc.Print("DA"); // Print used correction classes
+
+ TCanvas *c=new TCanvas; // Plots
+ c->Divide(2,2);
+ c->cd(1);twist.CreateHistoDRPhiinZR(1.,100,100)->Draw("surf2");
+ c->cd(2);GGerror.CreateHistoDRPhiinZR(1.,100,100)->Draw("surf2");
+ c->cd(3);exb.CreateHistoDRPhiinZR(1.)->Draw("surf2");
+ c->cd(4);cc.CreateHistoDRPhiinZR(1.)->Draw("surf2");
+}
AliTPCCalibRaw.cxx \
AliTPCPreprocessor.cxx AliTPCPreprocessorOnline.cxx \
AliTPCCalibViewer.cxx AliTPCCalibViewerGUI.cxx AliTPCCalibViewerGUItime.cxx \
- AliTPCCalibViewerGUIAlarms.cxx AliTPCCalibQAChecker.cxx \
+ AliTPCCalibViewerGUIAlarms.cxx AliTPCCalibQAChecker.cxx \
AliTPCGenDBTemp.cxx AliTPCGenDBConf.cxx \
AliTPCExB.cxx AliTPCExBExact.cxx AliTPCExBFirst.cxx \
AliTPCTempMap.cxx AliTPCCalibVdrift.cxx \
AliTransform.cxx AliTPCTransform.cxx AliTPCAlign.cxx AliTPCGoofieValues.cxx \
AliTPCdataQA.cxx AliTPCQAChecker.cxx AliTPCConfigDA.cxx AliTPCConfigParser.cxx AliExternalComparison.cxx \
AliTPCkalmanTime.cxx AliESDcosmic.cxx AliTPCPointCorrection.cxx AliTPCTransformation.cxx \
- AliTPCkalmanFit.cxx AliTPCLaserTrack.cxx AliTPCcalibBase.cxx
+ AliTPCkalmanFit.cxx AliTPCLaserTrack.cxx AliTPCcalibBase.cxx \
+ AliTPCCorrection.cxx AliTPCInverseCorrection.cxx AliTPCComposedCorrection.cxx \
+ AliTPCExBBShape.cxx AliTPCExBTwist.cxx AliTPCGGVoltError.cxx
HDRS:= $(SRCS:.cxx=.h)