/************************************************************************** * 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. * **************************************************************************/ /* $Id$ */ /////////////////////////////////////////////////////////////////////////////////// // // // Wrapper for the set of mag.field parameterizations by Chebyshev polinomials // // To obtain the field in cartesian coordinates/components use // // Field(float* xyz, float* bxyz); // // For cylindrical coordinates/components: // // FieldCyl(float* rphiz, float* brphiz) // // // // For the moment only the solenoid part is parameterized in the volume defined // // by R<500, -550AddAtAndExpand(new AliCheb3D(*pr),i); } } if (src.fParamsDip) { fParamsDip = new TObjArray(fNParamsDip); for (int i=0;iAddAtAndExpand(new AliCheb3D(*pr),i); } } // } AliMagFCheb& AliMagFCheb::operator=(const AliMagFCheb& rhs) { // Assignment operator if (this != &rhs) { Clear(); SetName(rhs.GetName()); SetTitle(rhs.GetTitle()); fNParamsSol = rhs.fNParamsSol; fNSegZSol = rhs.fNSegZSol; fMinZSol = rhs.fMinZSol; fMaxZSol = rhs.fMaxZSol; fMaxRSol = rhs.fMaxRSol; fNParamsDip = rhs.fNParamsDip; fSegZSol = fSegRSol = 0; fNSegRSol = fSegZIdSol = 0; fParamsSol = fParamsDip = 0; // if (rhs.fSegZSol) { fSegZSol = new Float_t[fNSegZSol]; for (int i=fNSegZSol;i--;) fSegZSol[i] = rhs.fSegZSol[i]; } if (rhs.fSegRSol) { fSegRSol = new Float_t[fNParamsSol]; for (int i=fNParamsSol;i--;) fSegRSol[i] = rhs.fSegRSol[i]; } if (rhs.fNSegRSol) { fNSegRSol = new Int_t[fNSegZSol]; for (int i=fNSegZSol;i--;) fNSegRSol[i] = rhs.fNSegRSol[i]; } if (rhs.fSegZIdSol) { fSegZIdSol = new Int_t[fNSegZSol]; for (int i=fNSegZSol;i--;) fSegZIdSol[i] = rhs.fSegZIdSol[i]; } if (rhs.fParamsSol) { fParamsSol = new TObjArray(fNParamsSol); for (int i=0;iAddAtAndExpand(new AliCheb3D(*pr),i); } } if (rhs.fParamsDip) { fParamsDip = new TObjArray(fNParamsDip); for (int i=0;iAddAtAndExpand(new AliCheb3D(*pr),i); } } } return *this; // } //__________________________________________________________________________________________ AliMagFCheb::~AliMagFCheb() { if (fNParamsSol) { delete fParamsSol; delete[] fSegZSol; delete[] fSegRSol; delete[] fNSegRSol; delete[] fSegZIdSol; } // // Dipole part ... if (fNParamsDip) { delete fParamsDip; } } //__________________________________________________________________________________________ void AliMagFCheb::Init0() { // Solenoid part fNParamsSol = 0; fNSegZSol = 0; // fSegZSol = 0; fSegRSol = 0; // fNSegRSol = 0; fSegZIdSol = 0; // fMinZSol = fMaxZSol = fMaxRSol = fMaxRSol = 0; fParamsSol = 0; // // Dipole part ... fNParamsDip = 0; fParamsDip = 0; // } //__________________________________________________________________________________________ void AliMagFCheb::AddParamSol(AliCheb3D* param) { // adds new parameterization piece for Sol // NOTE: pieces must be added strictly in increasing R then increasing Z order // if (!fParamsSol) fParamsSol = new TObjArray(); fParamsSol->Add(param); fNParamsSol++; // } //__________________________________________________________________________________________ void AliMagFCheb::AddParamDip(AliCheb3D* param) { // adds new parameterization piece for Dipole // if (!fParamsDip) fParamsDip = new TObjArray(); fParamsDip->Add(param); fNParamsDip++; // } //__________________________________________________________________________________________ void AliMagFCheb::BuildTableSol() { // build the indexes for each parameterization of Solenoid // const float kSafety=0.001; // fSegRSol = new Float_t[fNParamsSol]; float *tmpbufF = new float[fNParamsSol+1]; int *tmpbufI = new int[fNParamsSol+1]; int *tmpbufI1 = new int[fNParamsSol+1]; // // count number of Z slices and number of R slices in each Z slice for (int ip=0;ipGetBoundMax(2)-GetParamSol(ip-1)->GetBoundMax(2))>kSafety) { // new Z slice tmpbufF[fNSegZSol] = GetParamSol(ip)->GetBoundMax(2); // tmpbufI[fNSegZSol] = 0; tmpbufI1[fNSegZSol++] = ip; } fSegRSol[ip] = GetParamSol(ip)->GetBoundMax(0); // upper R tmpbufI[fNSegZSol-1]++; } // fSegZSol = new Float_t[fNSegZSol]; fSegZIdSol = new Int_t[fNSegZSol]; fNSegRSol = new Int_t[fNSegZSol]; for (int iz=0;izGetBoundMin(2); fMaxZSol = GetParamSol(fNParamsSol-1)->GetBoundMax(2); fMaxRSol = GetParamSol(fNParamsSol-1)->GetBoundMax(0); // delete[] tmpbufF; delete[] tmpbufI; delete[] tmpbufI1; // // } //__________________________________________________________________________________________ void AliMagFCheb::Field(Float_t *xyz, Float_t *b) const { // compute field in cartesian coordinates float rphiz[3]; if (xyz[2]>GetMaxZSol() || xyz[2]GetMaxRSol()) {for (int i=3;i--;) b[i]=0; return;} // FieldCylSol(rphiz,b); // // convert field to cartesian system float btr = TMath::Sqrt(b[0]*b[0]+b[1]*b[1]); float psiPLUSphi = rphiz[1] + TMath::ATan2(b[1],b[0]); b[0] = btr*TMath::Cos(psiPLUSphi); b[1] = btr*TMath::Sin(psiPLUSphi); // } //__________________________________________________________________________________________ void AliMagFCheb::FieldCylSol(Float_t *rphiz, Float_t *b) const { // compute Solenoid field in Cylindircal coordinates // note: the check for the point being inside the parameterized region is done outside float &r = rphiz[0]; float &z = rphiz[2]; int SolZId = 0; while (z>fSegZSol[SolZId]) ++SolZId; // find Z segment int SolRId = fSegZIdSol[SolZId]; // first R segment for this Z while (r>fSegRSol[SolRId]) ++SolRId; // find R segment GetParamSol( SolRId )->Eval(rphiz,b); // } //__________________________________________________________________________________________ void AliMagFCheb::Print(Option_t *) const { printf("Alice magnetic field parameterized by Chebyshev polynomials\n"); printf("Segmentation for Solenoid (%+.2fGetBoundMin(2),param->GetBoundMax(2)); for (int ir=0;irGetBoundMin(0),param->GetBoundMax(0), param->GetPrecision(),fSegZIdSol[iz]+ir); } } } //_______________________________________________ #ifdef _INC_CREATION_ALICHEB3D_ void AliMagFCheb::SaveData(const char* outfile) const { // writes coefficients data to output text file TString strf = outfile; gSystem->ExpandPathName(strf); FILE* stream = fopen(strf,"w+"); // // Sol part fprintf(stream,"# Set of Chebyshev parameterizations for ALICE magnetic field\nSTART %s\n",GetName()); fprintf(stream,"START SOLENOID\n#Number of pieces\n%d\n",fNParamsSol); for (int ip=0;ipSaveData(stream); fprintf(stream,"#\nEND SOLENOID\n"); // // Dip part fprintf(stream,"START DIPOLE\n#Number of pieces\n%d\n",fNParamsDip); for (int ip=0;ipSaveData(stream); fprintf(stream,"#\nEND DIPOLE\n"); // fprintf(stream,"#\nEND %s\n",GetName()); // fclose(stream); // } #endif //_______________________________________________ void AliMagFCheb::LoadData(const char* inpfile) { // read coefficients data from the text file // TString strf = inpfile; gSystem->ExpandPathName(strf); FILE* stream = fopen(strf,"r"); if (!stream) { printf("Did not find input file %s\n",strf.Data()); return; } // TString buffs; AliCheb3DCalc::ReadLine(buffs,stream); if (!buffs.BeginsWith("START")) {Error("LoadData","Expected: \"START \", found \"%s\"\nStop\n",buffs.Data());exit(1);} if (buffs.First(' ')>0) SetName(buffs.Data()+buffs.First(' ')+1); // // Solenoid part AliCheb3DCalc::ReadLine(buffs,stream); if (!buffs.BeginsWith("START SOLENOID")) {Error("LoadData","Expected: \"START SOLENOID\", found \"%s\"\nStop\n",buffs.Data());exit(1);} AliCheb3DCalc::ReadLine(buffs,stream); // nparam int nparSol = buffs.Atoi(); // for (int ip=0;ipLoadData(stream); AddParamSol(cheb); } // AliCheb3DCalc::ReadLine(buffs,stream); if (!buffs.BeginsWith("END SOLENOID")) {Error("LoadData","Expected \"END SOLENOID\", found \"%s\"\nStop\n",buffs.Data());exit(1);} // // Dipole part AliCheb3DCalc::ReadLine(buffs,stream); if (!buffs.BeginsWith("START DIPOLE")) {Error("LoadData","Expected: \"START DIPOLE\", found \"%s\"\nStop\n",buffs.Data());exit(1);} AliCheb3DCalc::ReadLine(buffs,stream); // nparam int nparDip = buffs.Atoi(); // for (int ip=0;ipLoadData(stream); AddParamDip(cheb); } // AliCheb3DCalc::ReadLine(buffs,stream); if (!buffs.BeginsWith("END DIPOLE")) {Error("LoadData","Expected \"END DIPOLE\", found \"%s\"\nStop\n",GetName(),buffs.Data());exit(1);} // AliCheb3DCalc::ReadLine(buffs,stream); if (!buffs.BeginsWith("END") || !buffs.Contains(GetName())) {Error("LoadData","Expected: \"END %s\", found \"%s\"\nStop\n",GetName(),buffs.Data());exit(1);} // fclose(stream); BuildTableSol(); // BuildDipTable(); printf("Loaded magnetic field \"%s\" from %s\n",GetName(),strf.Data()); // }