Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Zfluk.cxx

Go to the documentation of this file.
00001 // $Author: zarko $ 
00002 //
00003 // $Revision: 1.12 $
00004 // 
00005 // $Name:  $
00006 //
00007 // $Id: Zfluk.cxx,v 1.12 2008/03/15 17:23:31 zarko Exp $
00008 //
00009 // $Log: Zfluk.cxx,v $
00010 // Revision 1.12  2008/03/15 17:23:31  zarko
00011 //
00012 // Renamed the old GetWeight functions in Zfluk to
00013 // GetWeightPRL and GetWeightBoston to avoid confusion between
00014 // different functional forms used for those fits.
00015 // Updated SKZPWeightCalculator to reflect the changes.
00016 //
00017 // Revision 1.11  2007/12/20 21:29:14  zarko
00018 // *** empty log message ***
00019 //
00020 // Revision 1.10  2007/03/03 21:27:05  zarko
00021 // Version used for PiMinus fits.
00022 //
00023 // Revision 1.9  2007/02/14 22:58:07  zarko
00024 // In this version of zfluk GetWeight(ptype,pt,pz) returns a weight using
00025 // 16 parameters (6 for pi+, 6 for K+, 2 for pi- and 2 for K-)
00026 //
00027 // Revision 1.8  2006/11/10 19:13:17  zarko
00028 // Changed the way kaon weights are calculated so that K/pi ratio is
00029 // preserved. Added K0L reweighting based on K+ and K- weights.
00030 // To get these weights use SetParameters(vector<double>) and
00031 // GetWeight(ptype, pT, pz) functions.
00032 //
00033 // Revision 1.7  2006/10/03 16:00:56  zarko
00034 // Updated code to reweight numus and numubars
00035 //
00036 // Revision 1.6  2006/06/02 04:37:53  zarko
00037 // Use arrays instead of histograms in GetPTshift to speed up the code.
00038 //
00039 // Revision 1.5  2006/04/14 02:37:31  zarko
00040 // Zfluk now looks into SRT_PUBLIC_CONTEXT if the data cannot be found in SRT_PRIVATE_CONTEXT
00041 //
00042 // Revision 1.4  2006/03/13 23:58:32  zarko
00043 // Updated SKZP parameterization. Now using 7 parameters.
00044 // One for kaons and 6 to parameterize pt-xf weights.
00045 //
00046 // Revision 1.3  2006/02/21 00:04:24  zarko
00047 // Modified Files:
00048 //      Zfluk.cxx Zfluk.h
00049 //
00050 // Added function GetPTshift(par). This uses the fluka05ptxf.root file that should
00051 // be in MCReweight/data. This function returns shift in mean pT for a given set
00052 // of parameters, for a parameterization that was set with UseParameterization.
00053 //
00054 // Revision 1.2  2006/01/30 20:57:56  zarko
00055 // Removed one parameter from SKZP (par[2])
00056 // Redefined par[3] (low pT) and par[4] (kaons) in SKZP,
00057 // and par[5] (kaons) in TV, so that they are just numbers.
00058 // They are not multiplicative factors of sigma distortions any more.
00059 //
00060 //
00061 
00062 #include "MCReweight/Zfluk.h"
00063 #include "MessageService/MsgService.h"
00064 
00065 #include <string>
00066 #include <iostream>
00067 #include <cmath>
00068 #include <cstdlib>
00069 #include <cassert>
00070 #include "TFile.h"
00071 #include "TH2F.h"
00072 #include "TSystem.h"
00073 ClassImp(Zfluk)
00074 
00075 CVSID("$Id: Zfluk.cxx,v 1.12 2008/03/15 17:23:31 zarko Exp $");
00076 
00077 Zfluk::Zfluk(const char* dir) 
00078   :fPar(0)
00079 { 
00080   whichParameterization=0; //by default using SKZP parameterization
00081 
00082   // topDir is where the fluka05 pt-xf histogram file is
00083   std::string topDir=dir; // user may set location of input data
00084   if(topDir=="") { // by default, this code looks in a standard place
00085     topDir="MCReweight/data";
00086     std::string base="";
00087     base=getenv("SRT_PRIVATE_CONTEXT");
00088     if (base!="" && base!=".")
00089       {
00090         // check if directory exists in SRT_PRIVATE_CONTEXT
00091         std::string path = base + "/" + topDir;
00092         void *dir_ptr = gSystem -> OpenDirectory(path.c_str());
00093         if(!dir_ptr) base=getenv("SRT_PUBLIC_CONTEXT"); // if it doesn't exist then use SRT_PUBLIC_CONTEXT
00094         gSystem->FreeDirectory(dir_ptr);
00095       }
00096     else base=getenv("SRT_PUBLIC_CONTEXT");
00097     
00098     if(base=="") {
00099       MSG("MCReweight",Msg::kFatal)<<"No SRT_PUBLIC_CONTEXT set"<<std::endl;
00100       assert(false);
00101     }
00102     topDir = base+ "/" + topDir;
00103   }
00104 
00105   MSG("Zfluk",Msg::kDebug) <<"Zfluk reading data from: "<<topDir<<std::endl;
00106   std::string fileName =topDir+"/fluka05ptxf.root";
00107 
00108   TFile* hFile=new TFile(fileName.c_str());
00109   
00110   fPlist.push_back(kPiPlus);
00111   fPlist.push_back(kPiMinus);
00112   fPlist.push_back(kKPlus);
00113   fPlist.push_back(kKMinus);
00114   fPlist.push_back(kK0L);
00115   
00116   for (std::vector<ParticleType_t>::iterator itPlist=fPlist.begin();itPlist!=fPlist.end(); itPlist++)
00117     {
00118       TH2F* hist=dynamic_cast <TH2F*> (hFile->Get(Form("hF05ptxf%s",GetParticleName(*itPlist).c_str()))->Clone());
00119       hist->SetDirectory(0);
00120       TH2F* hist2=dynamic_cast <TH2F*> (hist->Clone(Form("hWeightedPTXF%s",GetParticleName(*itPlist).c_str())));
00121       hist2->SetDirectory(0);
00122       hist2->SetTitle(Form("%s weighted pt-pz",GetParticleName(*itPlist).c_str()));
00123       fWeightHist[*itPlist]=dynamic_cast<TH2F*> (hist->Clone(Form("hWeight%s",GetParticleName(*itPlist).c_str())));
00124 
00125       fWeightHist[*itPlist]->Divide(hist2);
00126       fWeightHist[*itPlist]->SetDirectory(0);
00127 
00128       std::pair<Zfluk::ParticleType_t, TH2F* > p(*itPlist, hist);
00129       std::pair<Zfluk::ParticleType_t, TH2F* > p2(*itPlist, hist2);
00130       fPTXF.insert(p);
00131       fWeightedPTXF.insert(p2);
00132 
00133       fPTXF[*itPlist]->SetDirectory(0);
00134       fWeightedPTXF[*itPlist]->SetDirectory(0);
00135 
00136       fMeanPT[*itPlist]=fPTXF[*itPlist]->ProjectionY()->GetMean()*1000.;
00137       fWeightedMeanPT[*itPlist]=fWeightedPTXF[*itPlist]->ProjectionY()->GetMean()*1000.;
00138             
00139       double N=fPTXF[*itPlist]->ProjectionY()->GetSumOfWeights();
00140       double wN=fWeightedPTXF[*itPlist]->ProjectionY()->GetSumOfWeights();
00141 
00142       fN[*itPlist]=N;
00143       fNWeighted[*itPlist]=wN;
00144     }
00145   hFile->Close();
00146   delete hFile;
00147   hFile=0;
00148 }
00149 
00150 Zfluk::~Zfluk() {
00151  for (std::vector<ParticleType_t>::iterator itPlist=fPlist.begin();itPlist!=fPlist.end(); itPlist++)
00152     {
00153       delete fWeightHist[*itPlist];
00154       delete fPTXF[*itPlist];
00155       delete fWeightedPTXF[*itPlist];
00156     }
00157  fWeightHist.clear();
00158  fPTXF.clear();
00159  fWeightedPTXF.clear();
00160  fMeanPT.clear();
00161  fWeightedMeanPT.clear();
00162  fN.clear();
00163  fNWeighted.clear();
00164  fPlist.clear();
00165  fPar.clear();
00166  fNBinsX.clear();
00167  fNBinsY.clear();
00168 }
00169 
00170 double Zfluk::GetWeightPRL(int ptype, double pT, double pz, double* par)
00171 {
00172   //this was used for PRL in 2006 (par was an array of 7 parameters
00173   std::vector<double> parVec;
00174   int npar=0;
00175 
00176   if (whichParameterization==0) npar=7;
00177   else npar=6;
00178   
00179   for (int i=0;i<npar;i++) parVec.push_back(par[i]);
00180   //this fit same as Boston for pi+ and K+, 
00181   //unlike in Boston fit, pi- and K- are not weighted here 
00182   //need 16 parameters to call GetWeightBoston(ptype,pT,pz,parVec)
00183   // fill rest of the parameters so that weights for pi- and K- are 1
00184   for (int i=7;i<16;i++) parVec.push_back(double((i-1)%2));
00185   return GetWeightBoston(ptype,pT,pz,parVec);
00186 }
00187 
00188 double Zfluk::GetWeightBoston(int tpType, double pT, double tpz, std::vector<double> par)
00189 {
00190   double xF;
00191   double weight=1.;
00192   if (tpz<0.) return weight;
00193   double A,B,C;
00194   double Ap,Bp,Cp;
00195   xF=tpz/120.;
00196 
00197   // This is SKZP parameterization
00198   if (whichParameterization==0)
00199     {
00200       if (tpType==211||tpType==8)
00201         {
00202           //Calculate weight for pions
00203           if (pT>=0.05)
00204             {
00205               // calculate the A, B and C in SKZP parameterization
00206               // A, B and C are best fit to Fluka 05
00207               
00208               A=-0.00761*pow((1.-xF),4.045)*(1.+9620.*xF)*pow(xF,-2.975);
00209               B=0.05465*pow((1.-xF),2.675)*(1.+69590.*xF)*pow(xF,-3.144);
00210               
00211               if (xF<0.22){
00212                 C=-7.058/pow(xF,-0.1419)+9.188;
00213               }
00214               else{
00215                 C = (3.008/exp((xF-0.1984)*3.577)) + 2.616*xF+0.1225;
00216               }
00217               // scale/skew A, B and C
00218               Ap=(par[0]+par[1]*xF)*A;
00219               Bp=(par[2]+par[3]*xF)*B;
00220               Cp=(par[4]+par[5]*xF)*C;
00221               
00222               weight=(Ap+Bp*pT)/(A+B*pT)*exp(-(Cp-C)*pow(pT,3./2.));
00223             }
00224           else weight=GetWeightBoston(tpType,0.051,tpz,par);  // for low pT
00225         }
00226       else if (tpType==321||tpType==11)
00227         {
00228           //for kaons
00229           weight=par[6]+par[7]*xF;
00230         }
00231       else if (tpType==-211||tpType==9)
00232         {
00233           // calculate the A, B and C in SKZP parameterization
00234           // A, B and C are best fit to Fluka 05
00235           if (pT>=0.05)
00236             {
00237               A=-0.006327*pow((1.-xF),5.734)*(1.+13660.*xF)*pow(xF,-2.898);
00238               B=0.04605*pow((1.-xF),3.291)*(1.+58610.*xF)*pow(xF,-3.209);
00239               
00240               if (xF<0.22){
00241                 C=-16.02/pow(xF,-0.06456)+17.61;
00242               }
00243               else{
00244                 C = (2.963/exp((xF-0.1774)*2.265)) + 1.732*xF+0.03925;
00245               }
00246               
00247               // scale/skew A, B and C
00248               Ap=(par[8]+par[9]*xF)*A;
00249               Bp=(par[10]+par[11]*xF)*B;
00250               Cp=(par[12]+par[13]*xF)*C;
00251               
00252               weight=(Ap+Bp*pT)/(A+B*pT)*exp(-(Cp-C)*pow(pT,3./2.));
00253             }
00254           else weight=GetWeightBoston(tpType,0.051,tpz,par);  // for low pT
00255           
00256         }
00257       else if (tpType==-321||tpType==12)
00258         {
00259           //for kaons
00260           weight=par[14]+par[15]*xF;
00261         }
00262     }
00263   else if (whichParameterization==1)
00264     {
00265       // This is TV parameterization
00266       if (tpType==211||tpType==8){
00267  
00268         weight=par[0]*(1.+par[1]*pT)/(1.+par[2]*pT)*
00269                exp(-par[3]*tpz*pow(pT,par[4]));
00270  
00271       }
00272       else if (tpType==321||tpType==11) {
00273         weight=par[5];
00274       }
00275       
00276     }
00277   else
00278     {
00279       MSG("MCReweight",Msg::kError) << "Please select one of the two hadron production"<<std::endl;
00280       MSG("MCReweight",Msg::kError) << " parameterizations (SKZP (default) or TV)"<<std::endl;
00281       return 0.;;
00282     }
00283   return weight;
00284 }
00285 
00286 double Zfluk::GetWeight(int ptype, double pT, double pz)
00287 {
00288   double weight=1.;
00289 
00290   if (fPar.size()==0) 
00291     {
00292       MAXMSG("MCReweight",Msg::kWarning,10)
00293         <<"You need to set the parameters before calling "
00294         <<"Zfluk::GetWeight (use SetParameters(vector<double>))"<<std::endl
00295         <<"Returning weight = "<<weight<<std::endl;
00296       return weight;
00297     }
00298 
00299   double xF=pz/120.;
00300   double A,B,C;
00301   double Ap,Bp,Cp;
00302   Zfluk::ParticleType_t eptype=GetParticleEnum(ptype);
00303 
00304   // This is SKZP parameterization
00305   if (xF>1.||xF<0.) return weight;
00306   if (pT>1.||pT<0.) return weight;
00307 
00308   if (eptype==kPiPlus)
00309     {
00310       //Calculate weight for pions
00311       if (pT>=0.03)
00312         {
00313           // calculate the A, B and C in SKZP parameterization
00314           // A, B and C are best fit to Fluka 05
00315           
00316           A=-0.00761*pow((1.-xF),4.045)*(1.+9620.*xF)*pow(xF,-2.975);
00317           B=0.05465*pow((1.-xF),2.675)*(1.+69590.*xF)*pow(xF,-3.144);
00318           
00319           if (xF<0.22){
00320             C=-7.058/pow(xF,-0.1419)+9.188;
00321           }
00322           else{
00323             C = (3.008/exp((xF-0.1984)*3.577)) + 2.616*xF+0.1225;
00324           }
00325           
00326           // scale/skew A, B and C
00327           Ap=(fPar[0]+fPar[1]*xF)*A;
00328           Bp=(fPar[2]+fPar[3]*xF)*B;
00329           Cp=(fPar[4]+fPar[5]*xF)*C;
00330             
00331           weight=(Ap+Bp*pT)/(A+B*pT)*exp(-(Cp-C)*pow(pT,3./2.));
00332         }
00333       else weight=GetWeight(ptype,0.031,pz);  // for low pT
00334     }
00335   else if (eptype==kKPlus)
00336     {
00337       if (pT>=0.05)
00338         {
00339           // calculate the A, B and C in SKZP parameterization
00340           // A, B and C are best fit to Fluka 05
00341           
00342           A=-0.005187*pow((1.-xF),4.119)*(1.+2170.*xF)*pow(xF,-2.767);
00343           B=0.4918*pow((1.-xF),2.672)*(1.+1373.*xF)*pow(xF,-2.927);
00344           
00345           if (xF<0.22){
00346             C=-16.10/pow(xF,-0.04582)+17.92;
00347           }
00348           else{
00349             C = (6.905/exp((xF+0.163)*6.718)) - 0.4257*xF + 2.486;
00350           }
00351           
00352           // scale/skew A, B and C
00353           Ap=(fPar[6]+fPar[7]*xF)*A;
00354           Bp=(fPar[8]+fPar[9]*xF)*B;
00355           Cp=(fPar[10]+fPar[11]*xF)*C;
00356 
00357           weight=(Ap+Bp*pT)/(A+B*pT)*exp(-(Cp-C)*pow(pT,3./2.));
00358         }
00359       else 
00360         weight=GetWeight(ptype,0.051,pz);  // for low pT
00361     }
00362   else if (eptype==kPiMinus)
00363     {
00364       weight=GetWeight(kPiPlus,pT,pz);
00365       if ( pz > 4. ) weight *= ( fPar[12] + fPar[13] * xF );
00366     }
00367   else if (eptype==kKMinus)
00368     {
00369       weight=GetWeight(kKPlus,pT,pz)*(fPar[14]+fPar[15]*xF);
00370     }
00371   else if (eptype==kK0L)
00372     {
00373       //N(K0L) approximately given with (N(K+)+3*N(K-))/4
00374       weight= ((fNWeighted[kKPlus]+3.*fNWeighted[kKMinus])
00375                /(fN[kKPlus]+3.*fN[kKMinus]));
00376     }
00377   if (weight>10.) weight=10.;
00378   return weight;
00379 }
00380 
00381 void Zfluk::RecalculateWeights()
00382 {
00383   
00384   for (std::vector<ParticleType_t>::iterator itPlist=fPlist.begin();
00385        itPlist!=fPlist.end(); itPlist++)
00386     {
00387       double xf,pt;
00388       double meanpt(0.);
00389       double sum(0.);
00390       for (int i=0;i<fPTXF[*itPlist]->GetNbinsX()+1;i++)
00391         {
00392           for (int j=0;j<fPTXF[*itPlist]->GetNbinsY()+1;j++)
00393             {
00394               xf=fPTXF[*itPlist]->GetXaxis()->GetBinCenter(i);
00395               pt=fPTXF[*itPlist]->GetYaxis()->GetBinCenter(j);
00396               fWeightedPTXF[*itPlist]
00397                 ->SetBinContent(i,j,(fPTXF[*itPlist]->GetBinContent(i,j)
00398                                      *GetWeight(*itPlist,pt,xf)));
00399               fWeightHist[*itPlist]->SetBinContent(i,j,GetWeight(*itPlist,pt,xf));
00400               meanpt+=fWeightedPTXF[*itPlist]->GetBinContent(i,j)*pt;
00401               sum+=fWeightedPTXF[*itPlist]->GetBinContent(i,j);
00402             }
00403         }
00404       meanpt/=sum;
00405       fWeightedMeanPT[*itPlist]=meanpt*1000.; //GeV to MeV
00406       fNWeighted[*itPlist]=sum;
00407       meanpt=0.;
00408       sum=0.;
00409     }
00410 }
00411 
00412 double Zfluk::GetPTshift(int ptype, double pz_low, double pz_up)
00413 {
00414   //returns the pT shift for ptype particle due to reweighting in xf slice
00415   //given by pz_low and pz_up
00416   //this function returns correct ptshift only if the parameters were set using SetParameters
00417 
00418   Zfluk::ParticleType_t eptype=GetParticleEnum(ptype);
00419 
00420   if (fPTXF.find(eptype)==fPTXF.end())
00421     {
00422       return 0.;
00423     }
00424   if (pz_low==0.&&pz_up==120.) return fWeightedMeanPT[eptype]-fMeanPT[eptype];
00425  
00426   int xlow=int(pz_low+1.);
00427   int xup=int(pz_up+1.);
00428  
00429   double pt;
00430   double meanpt(0.);
00431   double sum(0.);
00432   for (int i=xlow;i<xup;i++)
00433     {
00434       for (int j=1;j<51;j++)
00435         {
00436           pt=0.02*j-0.01;
00437           meanpt+=fWeightedPTXF[eptype]->GetBinContent(i,j)*pt;
00438           sum+=fWeightedPTXF[eptype]->GetBinContent(i,j);
00439         }
00440     }
00441   meanpt/=sum;
00442   meanpt*=1000.;  //GeV to MeV
00443 
00444   return meanpt-fMeanPT[eptype];
00445 
00446 }
00447 double Zfluk::GetNFrac(int ptype, double pz_low, double pz_up, double pt_low, double pt_up)
00448 {
00449   //returns the fractional change in number of particles due to reweighting in xf-pt region 
00450   //given by pz_low, pz_up and pt_low, pt_up
00451   
00452   Zfluk::ParticleType_t eptype=GetParticleEnum(ptype);
00453   if (fPTXF.find(eptype)==fPTXF.end())
00454     {
00455       return 1.;
00456     }
00457   int xlow=int(pz_low+1.);
00458   int xup=int(pz_up+1.);
00459   int ylow=int(50.*pt_low+1.);
00460   int yup=int(50.*pt_up+1.);
00461   
00462   double wsum(0.);
00463   double sum(0.);
00464   for (int i=xlow;i<xup;i++)
00465     {
00466       for (int j=ylow;j<yup;j++)
00467         {
00468           sum+=fPTXF[eptype]->GetBinContent(i,j);
00469           wsum+=fWeightedPTXF[eptype]->GetBinContent(i,j);
00470         }
00471     }
00472 
00473   return wsum/sum;
00474 }
00475 
00476 std::string Zfluk::GetParticleName(Zfluk::ParticleType_t ptype)
00477 {
00478 switch (ptype)
00479    {
00480    case kPiPlus:          return "PiPlus";    break;
00481    case kPiMinus:         return "PiMinus";   break;
00482    case kKPlus:           return "KPlus";     break;
00483    case kKMinus:          return "KMinus";    break;
00484    case kK0L:             return "K0L";       break;
00485    case kUnknown:         return "Unknown";   break;
00486    default:               return "Unknown";   break;
00487    }
00488  
00489    return "Unknown";
00490 }
00491 
00492 Zfluk::ParticleType_t Zfluk::GetParticleEnum(int ptype)
00493 {
00494   switch (ptype)
00495     {
00496     case 8   :       return kPiPlus;      break;
00497     case 211 :       return kPiPlus;      break;    
00498     case 9   :       return kPiMinus;     break;
00499     case -211:       return kPiMinus;     break;
00500     case 11  :       return kKPlus;       break;
00501     case 321 :       return kKPlus;       break;
00502     case 12  :       return kKMinus;      break;
00503     case -321:       return kKMinus;      break;
00504     case 10  :       return kK0L;         break;
00505     case 130 :       return kK0L;         break;
00506     default:         return kUnknown;     break;
00507     }
00508   return kUnknown;
00509 
00510 }

Generated on Mon Feb 15 11:07:51 2010 for loon by  doxygen 1.3.9.1