// @(#) $Id$ // Author: Anders Vestbo , Uli Frankenfeld , Constantin Loizides //*-- Copyright © ALICE HLT Group #include "AliL3StandardIncludes.h" #include "dirent.h" #ifdef use_aliroot #include #include #include #include #include #endif #ifdef use_root #include #include #include #include #endif #include "AliL3Logging.h" #include "AliL3Transform.h" #if GCCVERSION == 3 using namespace std; #endif /** \class AliL3Transform
//_____________________________________________________________
// AliL3Transform
//
// Transformation class for ALICE TPC.
//
// Class which contains all detector specific parameters for the TPC,
// and different useful functions for coordinate transforms.
//
// The class is completely static, which means that no object needs
// to be instantiated. Function calls should then be done like, e.g.:
//
// Double_t eta = AliL3Transform::GetEta(xyz);
//
// IMPORTANT: If used as is, default detector parameters will be used,
//            and you really have to make sure that these correspond to
//            the AliROOT version you are currently working on!!
//            You should therefore always initialize the parameters by
//
//            AliL3Transform::Init(path);
// 
//            where path is a char*, giving the path to where file containing
//            the detector parameter is located. This file should be called
//            "l3transform.config", and can be created with the function MakeInitFile.
//            
//            You can also force reading the parameters from a AliTPCParam object
//            by setting the flag;
//
//            AliL3Transform::Init(path,kTRUE);
//
//            where path is a char* 
//            either providing the rootfile name containing the geometry or 
//            the path to the rootfile which should then be called alirunfile.root. 
//            Note that for both of these cases you have to
//            compile with USEPACKAGE=ALIROOT set (see level3code/Makefile.conf).
//
//            Currently, there are 4 versions of the Transformer:
//             fVersion==fV_aliroot: ALIROOT-head compatible
//             fVersion==fV_cosmics: Cosmics data run (2003) compatible
//             fVersion==fV_default: means no config file has been loaded
//             fVersion==fV_deprecated: dont use old (before July 2003) style of transformer
//
*/ ClassImp(AliL3Transform) const Double_t AliL3Transform::fAnodeWireSpacing = 0.25; //Taken from the TDR const Double_t AliL3Transform::fBFACT = 0.0029980; //Conversion Factor const Double_t AliL3Transform::fPi = 3.141592653589793; //Defined by HLT and GSI Int_t AliL3Transform::fNPatches = 6; Int_t AliL3Transform::fRows[6][2] = {{0,29},{30,62},{63,90},{91,116},{117,139},{140,158}}; Int_t AliL3Transform::fNRows[6] = {30,33,28,26,23,19}; // The following definition is generated by MakeInitFile function Double_t AliL3Transform::fBField = 0.2; Double_t AliL3Transform::fSolenoidBField = 2; Double_t AliL3Transform::fBFieldFactor = 1; Int_t AliL3Transform::fVersion = fV_default; Int_t AliL3Transform::fNTimeBins = 446; Int_t AliL3Transform::fNRowLow = 63; Int_t AliL3Transform::fNRowUp = 96; Int_t AliL3Transform::fNRowUp1 = 64; Int_t AliL3Transform::fNRowUp2 = 32; Int_t AliL3Transform::fNSectorLow = 36; Int_t AliL3Transform::fNSectorUp = 36; Int_t AliL3Transform::fNSector = 72; Double_t AliL3Transform::fPadPitchWidthLow = 0.4; Double_t AliL3Transform::fPadPitchWidthUp = 0.6; Double_t AliL3Transform::fZWidth = 0.5660; Double_t AliL3Transform::fZSigma = 0.2288; Double_t AliL3Transform::fZLength = 250.0000; Double_t AliL3Transform::fZOffset = 0.6864; Double_t AliL3Transform::fDiffT = 0.0220; Double_t AliL3Transform::fDiffL = 0.0220; Double_t AliL3Transform::fOmegaTau = 0.1450; Double_t AliL3Transform::fInnerPadLength = 0.75; Double_t AliL3Transform::fOuter1PadLength = 1.00; Double_t AliL3Transform::fOuter2PadLength = 1.50; Double_t AliL3Transform::fInnerPRFSigma = 0.203811; Double_t AliL3Transform::fOuter1PRFSigma = 0.299325; Double_t AliL3Transform::fOuter2PRFSigma = 0.299323; Double_t AliL3Transform::fTimeSigma = 0.228809; Int_t AliL3Transform::fADCSat = 1024; Int_t AliL3Transform::fZeroSup = 0; Int_t AliL3Transform::fNSlice = 36; Int_t AliL3Transform::fNRow = 159; Double_t AliL3Transform::fNRotShift = 0.5; Int_t AliL3Transform::fSlice2Sector[36][2] = { { 0, 36}, { 1, 37}, { 2, 38}, { 3, 39}, { 4, 40}, { 5, 41}, { 6, 42}, { 7, 43}, { 8, 44}, { 9, 45}, {10, 46}, {11, 47}, {12, 48}, {13, 49}, {14, 50}, {15, 51}, {16, 52}, {17, 53}, {18, 54}, {19, 55}, {20, 56}, {21, 57}, {22, 58}, {23, 59}, {24, 60}, {25, 61}, {26, 62}, {27, 63}, {28, 64}, {29, 65}, {30, 66}, {31, 67}, {32, 68}, {33, 69}, {34, 70}, {35, 71} }; Int_t AliL3Transform::fSector2Slice[72] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 }; Int_t AliL3Transform::fSectorLow[72] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; Double_t AliL3Transform::fX[159] = { 85.195, 85.945, 86.695, 87.445, 88.195, 88.945, 89.695, 90.445, 91.195, 91.945, 92.695, 93.445, 94.195, 94.945, 95.695, 96.445, 97.195, 97.945, 98.695, 99.445, 100.195, 100.945, 101.695, 102.445, 103.195, 103.945, 104.695, 105.445, 106.195, 106.945, 107.695, 108.445, 109.195, 109.945, 110.695, 111.445, 112.195, 112.945, 113.695, 114.445, 115.195, 115.945, 116.695, 117.445, 118.195, 118.945, 119.695, 120.445, 121.195, 121.945, 122.695, 123.445, 124.195, 124.945, 125.695, 126.445, 127.195, 127.945, 128.695, 129.445, 130.195, 130.945, 131.695, 135.180, 136.180, 137.180, 138.180, 139.180, 140.180, 141.180, 142.180, 143.180, 144.180, 145.180, 146.180, 147.180, 148.180, 149.180, 150.180, 151.180, 152.180, 153.180, 154.180, 155.180, 156.180, 157.180, 158.180, 159.180, 160.180, 161.180, 162.180, 163.180, 164.180, 165.180, 166.180, 167.180, 168.180, 169.180, 170.180, 171.180, 172.180, 173.180, 174.180, 175.180, 176.180, 177.180, 178.180, 179.180, 180.180, 181.180, 182.180, 183.180, 184.180, 185.180, 186.180, 187.180, 188.180, 189.180, 190.180, 191.180, 192.180, 193.180, 194.180, 195.180, 196.180, 197.180, 198.180, 199.430, 200.930, 202.430, 203.930, 205.430, 206.930, 208.430, 209.930, 211.430, 212.930, 214.430, 215.930, 217.430, 218.930, 220.430, 221.930, 223.430, 224.930, 226.430, 227.930, 229.430, 230.930, 232.430, 233.930, 235.430, 236.930, 238.430, 239.930, 241.430, 242.930, 244.430, 245.930 }; Int_t AliL3Transform::fNPads[159] = {67, 67, 69, 69, 69, 71, 71, 71, 73, 73, 73, 75, 75, 75, 77, 77, 77, 79, 79, 79, 81, 81, 81, 83, 83, 83, 85, 85, 85, 87, 87, 87, 89, 89, 89, 91, 91, 91, 93, 93, 93, 95, 95, 95, 97, 97, 97, 99, 99, 99, 99, 101, 101, 101, 103, 103, 103, 105, 105, 105, 107, 107, 107, 73, 75, 75, 75, 75, 77, 77, 77, 79, 79, 79, 81, 81, 81, 81, 83, 83, 83, 85, 85, 85, 85, 87, 87, 87, 89, 89, 89, 91, 91, 91, 91, 93, 93, 93, 95, 95, 95, 95, 97, 97, 97, 99, 99, 99, 101, 101, 101, 101, 103, 103, 103, 105, 105, 105, 105, 107, 107, 107, 109, 109, 109, 111, 111, 111, 113, 113, 113, 115, 115, 117, 117, 119, 119, 121, 121, 121, 123, 123, 125, 125, 127, 127, 127, 129, 129, 131, 131, 133, 133, 135, 135, 135, 137, 137, 139 }; Double_t AliL3Transform::fCos[36] = { 0.9848077297, 0.8660253882, 0.6427876353, 0.3420201540, 0.0000000000, -0.3420201540, -0.6427876353, -0.8660253882, -0.9848077297, -0.9848077297, -0.8660253882, -0.6427876353, -0.3420201540, -0.0000000000, 0.3420201540, 0.6427876353, 0.8660253882, 0.9848077297, 0.9848077297, 0.8660253882, 0.6427876353, 0.3420201540, 0.0000000000, -0.3420201540, -0.6427876353, -0.8660253882, -0.9848077297, -0.9848077297, -0.8660253882, -0.6427876353, -0.3420201540, -0.0000000000, 0.3420201540, 0.6427876353, 0.8660253882, 0.9848077297 }; Double_t AliL3Transform::fSin[36] = { 0.1736481786, 0.5000000000, 0.7660444379, 0.9396926165, 1.0000000000, 0.9396926165, 0.7660444379, 0.5000000000, 0.1736481786, -0.1736481786, -0.5000000000, -0.7660444379, -0.9396926165, -1.0000000000, -0.9396926165, -0.7660444379, -0.5000000000, -0.1736481786, 0.1736481786, 0.5000000000, 0.7660444379, 0.9396926165, 1.0000000000, 0.9396926165, 0.7660444379, 0.5000000000, 0.1736481786, -0.1736481786, -0.5000000000, -0.7660444379, -0.9396926165, -1.0000000000, -0.9396926165, -0.7660444379, -0.5000000000, -0.1736481786 }; Bool_t AliL3Transform::Init(Char_t* path,Bool_t UseAliTPCParam) { //Overwrite the parameters with values stored in file "l3transform.config" in path. //If file does not exist, old default values will be used. //If flag UseAliTPCParam is set, the parameters will be read from the the rootfile //which then has to be called path/digitfile.root if(fVersion != fV_default) LOG(AliL3Log::kWarning,"AliL3Transform::Init","Init values") <IsZombie()) { //ok assume its path to alirunfile file sprintf(filename,"%s/alirunfile.root",path); //create rootfile name } else { //path contains itself the rootfile name rootfile->Close(); sprintf(filename,"%s",path); } gErrorIgnoreLevel=saveErrIgLevel; //finally make dummy init file /tmp/$USER/l3transform.config-`date` Char_t tmppath[1024]; sprintf(tmppath,"/tmp/%s",gSystem->Getenv("USER")); gSystem->mkdir(tmppath); TTimeStamp time; Char_t tmpfile[1024]; sprintf(tmpfile,"%s/l3transform.config-%d",tmppath,(Int_t)time.GetSec()); return MakeInitFile(filename,tmpfile); #endif } Bool_t AliL3Transform::MakeInitFile(Char_t *rootfilename,Char_t *filename) { //Get the parameters from rootfile, and store it on the file "l3transform.config" //which is being read by Init. fVersion will be fV_aliroot! #ifndef use_aliroot LOG(AliL3Log::kError,"AliL3Transform::MakeInitFile","Version") <<"You have to compile with use_aliroot flag in order to use this function"<Get("gAlice"); if(!gAlice) { LOG(AliL3Log::kError,"AliL3Transform::MakeInitFile","File") <<"No gAlice in file: "<Get(GetParamName()); if(!param) { LOG(AliL3Log::kWarning,"AliL3Transform::MakeInitFile","File") <<"No TPC parameters found in \""<SetGauss(param->GetZSigma(),param->GetZWidth(),1.); rf->SetOffset(3*param->GetZSigma()); rf->Update(); TDirectory *savedir=gDirectory; TFile *prf_file = TFile::Open("$ALICE_ROOT/TPC/AliTPCprf2d.root"); if (!prf_file->IsOpen()) { LOG(AliL3Log::kError,"AliL3Transform::MakeInitFile","File") <<"Can't open $ALICE_ROOT/TPC/AliTPCprf2d.root !"<Read("prf_07504_Gati_056068_d02"); prfouter1->Read("prf_10006_Gati_047051_d03"); prfouter2->Read("prf_15006_Gati_047051_d03"); prf_file->Close(); savedir->cd(); param->SetInnerPRF(prfinner); param->SetOuter1PRF(prfouter1); param->SetOuter2PRF(prfouter2); param->SetTimeRF(rf); fNTimeBins = param->GetMaxTBin()+1; fNRowLow = param->GetNRowLow(); fNRowUp = param->GetNRowUp(); fNRowUp1 = param->GetNRowUp1(); fNRowUp2 = param->GetNRowUp2(); fNRow= fNRowLow + fNRowUp; if(fNRow!=159){ LOG(AliL3Log::kError,"AliL3Transform::MakeInitFile","fNRow") <<"Number of rows have changed in ALIROOT"<GetNInnerSector(); fNSectorUp = param->GetNOuterSector(); fNSector = fNSectorLow + fNSectorUp; //test whether they were changes to the rotation shift fNRotShift=0; Float_t irotshift = param->GetInnerAngleShift(); //shift angle Float_t orotshift = param->GetOuterAngleShift(); //shift angle const Float_t kDegtoRad = 0.01745329251994; Int_t shift1=TMath::Nint(irotshift/kDegtoRad); Int_t shift2=TMath::Nint(orotshift/kDegtoRad+0.1); if((shift1!=shift2) || (shift1!=10)){ LOG(AliL3Log::kError,"AliL3Transform::MakeInitFile","Rotshiftangle") <<"Rotation shift angle has changed in ALIROOT"<Field()->Factor()); SetSolenoidBField((Double_t)gAlice->Field()->SolenoidField()); fPadPitchWidthLow=param->GetInnerPadPitchWidth(); fPadPitchWidthUp=param->GetOuterPadPitchWidth(); fZWidth=param->GetZWidth(); fZSigma=param->GetZSigma(); fZLength=param->GetZLength(); fZOffset=param->GetZOffset(); fDiffT=param->GetDiffT(); fDiffL=param->GetDiffL(); fOmegaTau=param->GetOmegaTau(); fInnerPadLength=param->GetInnerPadLength(); fOuter1PadLength=param->GetOuter1PadLength(); fOuter2PadLength=param->GetOuter2PadLength(); fInnerPRFSigma=param->GetInnerPRF()->GetSigmaX(); fOuter1PRFSigma=param->GetOuter1PRF()->GetSigmaX(); fOuter2PRFSigma=param->GetOuter2PRF()->GetSigmaX(); fTimeSigma=param->GetTimeRF()->GetSigma(); fADCSat=param->GetADCSat(); fZeroSup=param->GetZeroSup(); fNSlice=fNSectorLow; //now do the arrays for(Int_t i=0;iGetPadRowRadii(sec,row); } for(Int_t i=0;iGetNPads(sec,row); } for(Int_t i=0;i= fNRow) { LOG(AliL3Log::kError,"AliL3Transform::GetNPads","Row") <= 6) { LOG(AliL3Log::kError,"AliL3Transform::GetFirstRow","Patch") <= 6) { LOG(AliL3Log::kError,"AliL3Transform::GetLastRow","Patch") <= 6) { LOG(AliL3Log::kError,"AliL3Transform::GetNRows","Patch") < 250) { LOG(AliL3Log::kError,"AliL3Transform::GetPadRow","X-value") < (Int_t)rint(fX[fNRow-2]*10)) return fNRow-1; else { Int_t padrow=1; //Of course, a more clever algorithm could help here while(padrow < fNRow-2) { if(x > (Int_t)rint(fX[padrow-1]*10) && x < (Int_t)rint(fX[padrow+1]*10)) break; padrow++; } return padrow; } } Int_t AliL3Transform::GetPatch(Int_t padrow) { if(padrow < 0 || padrow >= fNRow) { LOG(AliL3Log::kError,"AliL3Transform::GetPatch","Padrow") <= fRows[patch][0] && padrow <= fRows[patch][1]) break; patch++; } return patch; } Double_t AliL3Transform::GetPadLength(Int_t padrow) { if(padrow >= fNRow){ LOG(AliL3Log::kError,"AliL3Transform::GetPadLength","Padrow") <= fNRowLow && padrow < fNRowLow + fNRowUp1 - 1) return fOuter1PadLength; if(padrow >= fNRowLow + fNRowUp1 - 1) return fOuter2PadLength; //should never happen LOG(AliL3Log::kError,"AliL3Transform::GetPadLength","Padrow") < fNPatches) { LOG(AliL3Log::kError,"AliL3Transform::GetPadPitchWidth","patct") < 0) drift = fZLength - z; else drift = fZLength + z; Double_t t1 = GetPRFSigma(padrow)*GetPRFSigma(padrow); Double_t t2 = fDiffT*fDiffT*drift; Double_t t3 = GetPadLength(padrow)*GetPadLength(padrow)*tan(angle)*tan(angle)/12; Double_t t4 = fAnodeWireSpacing*fAnodeWireSpacing*(tan(angle) - fOmegaTau)*(tan(angle) - fOmegaTau)/12; return (t1 + t2 + t3 + t4); } Double_t AliL3Transform::GetParSigmaZ2(Int_t padrow,Float_t z,Float_t tgl) { //Calculate the expected longitudinal cluster width as a function of //drift distance and track crossing angle. //z = local z-coordinate of cluster //tgl = tan(dipangle) //return value = sigma^2 (cartesian coordinates) Double_t drift; if(z > 0) drift = AliL3Transform::GetZLength() - z; else drift = AliL3Transform::GetZLength() + z; Double_t t1 = fZSigma*fZSigma; Double_t t2 = fDiffL*fDiffL*drift; Double_t t3 = GetPadLength(padrow)*GetPadLength(padrow)*tgl*tgl/12; return (t1 + t2 + t3); } Double_t AliL3Transform::GetPRFSigma(Int_t padrow) { if(padrow >= fNRow){ LOG(AliL3Log::kError,"AliL3Transform::GetPRFSigma","Padrow") <= fNRowLow && padrow < fNRowLow + fNRowUp1 - 1) return fOuter1PRFSigma; if(padrow >= fNRowLow + fNRowUp1 - 1) return fOuter2PRFSigma; //should never happen LOG(AliL3Log::kError,"AliL3Transform::GetPRFSigma","Padrow") <=fNRow){ LOG(AliL3Log::kError,"AliL3Transform::Slice2Sector","Slicerow") <=fNSlice){ LOG(AliL3Log::kError,"AliL3Transform::Slice2Sector","Slice") <=fNSector){ LOG(AliL3Log::kError,"AliL3Transform::Sector2Slice","Sector") <=fNSector){ LOG(AliL3Log::kError,"AliL3Transform::Sector2Slice","Sector") <=fNRowLow){ LOG(AliL3Log::kError,"AliL3Transform::Sector2Slice","Row") <=fNRowUp){ LOG(AliL3Log::kError,"AliL3Transform::Sector2Slice","Row") <=fNRow){ LOG(AliL3Log::kError,"AliL3Transform::Row2X","Slicerow") <Exec(roottest); cout << "AliRoot Version: " << ALIROOTVERSION << " found " << flush; gSystem->Exec(aliroottest); #else cout << "ROOT version: -Duse_root was given." << endl; cout << "Root Version: " << ROOTVERSION << " found " << flush; gSystem->Exec(roottest); #endif #endif #ifdef do_mc cout << "Using Monte Carlo Info: -Ddo_mc was given." << endl; #else cout << "NOT using Monte Carlo Info: -Ddo_mc was not given." << endl; #endif #ifdef use_logging cout << "Using logging classes (MLUC): -Duse_logging was given." << endl; #else cout << "NOT using logging classes (MLUC): -Duse_logging not was given." << endl; #endif }