/************************************************************************** * 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$ */ /////////////////////////////////////////////////////////////////////////////// // // // fast TPC cluster simulation // // // /////////////////////////////////////////////////////////////////////////////// #include #include "AliRunLoader.h" #include "AliRun.h" #include "AliMC.h" #include "AliTPC.h" #include "AliTPCParam.h" #include "AliTPCClustersArray.h" #include "AliTPCClustersRow.h" #include "AliTPCcluster.h" #include "AliComplexCluster.h" #include "AliTPCFast.h" #include "AliLog.h" ClassImp(AliTPCFast) //_____________________________________________________________________________ void AliTPCFast::Hits2Clusters(AliRunLoader* runLoader) const { //-------------------------------------------------------- // TPC simple cluster generator from hits // obtained from the TPC Fast Simulator // The point errors are taken from the parametrization //-------------------------------------------------------- //----------------------------------------------------------------- // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl //----------------------------------------------------------------- // Adopted to Marian's cluster data structure by I.Belikov, CERN, // Jouri.Belikov@cern.ch //---------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////// // //--------------------------------------------------------------------- // ALICE TPC Cluster Parameters //-------------------------------------------------------------------- // Cluster width in rphi const Float_t kACrphi=0.18322; const Float_t kBCrphi=0.59551e-3; const Float_t kCCrphi=0.60952e-1; // Cluster width in z const Float_t kACz=0.19081; const Float_t kBCz=0.55938e-3; const Float_t kCCz=0.30428; AliLoader* loader = runLoader->GetLoader("TPCLoader"); if (!loader) { AliError("No TPC loader found"); return; } if (!runLoader->GetAliRun()) runLoader->LoadgAlice(); AliRun* aliRun = runLoader->GetAliRun(); if (!aliRun) { AliError("Couldn't get AliRun object"); return; } AliTPC* tpc = (AliTPC*) aliRun->GetDetector("TPC"); if (!tpc) { AliError("Couldn't get TPC detector"); return; } AliTPCParam* param = tpc->GetParam(); if (!param) { AliError("No TPC parameters available"); return; } //if(fDefaults == 0) SetDefaults(); Float_t sigmaRphi,sigmaZ,clRphi,clZ; // TParticle *particle; // pointer to a given particle AliTPChit *tpcHit; // pointer to a sigle TPC hit Int_t sector; Int_t ipart; Float_t xyz[5]; Float_t pl,pt,tanth,rpad,ratio; Float_t cph,sph; //--------------------------------------------------------------- // Get the access to the tracks //--------------------------------------------------------------- TTree *tH = loader->TreeH(); if (tH == 0x0) AliFatal("Can not find TreeH in folder"); tpc->SetTreeAddress(); Stat_t ntracks = tH->GetEntries(); //Switch to the output file if (loader->TreeR() == 0x0) loader->MakeTree("R"); AliDebug(1,Form("param->GetTitle() = %s",param->GetTitle())); runLoader->CdGAFile(); //param->Write(param->GetTitle()); AliTPCClustersArray carray; carray.Setup(param); carray.SetClusterType("AliTPCcluster"); carray.MakeTree(loader->TreeR()); Int_t nclusters=0; //cluster counter //------------------------------------------------------------ // Loop over all sectors (72 sectors for 20 deg // segmentation for both lower and upper sectors) // Sectors 0-35 are lower sectors, 0-17 z>0, 17-35 z<0 // Sectors 36-71 are upper sectors, 36-53 z>0, 54-71 z<0 // // First cluster for sector 0 starts at "0" //------------------------------------------------------------ for(Int_t isec=0;isecGetNSector();isec++){ //MI change param->AdjustCosSin(isec,cph,sph); //------------------------------------------------------------ // Loop over tracks //------------------------------------------------------------ for(Int_t track=0;trackResetHits(); tH->GetEvent(track); // // Get number of the TPC hits // tpcHit = (AliTPChit*)tpc->FirstHit(-1); // Loop over hits // while(tpcHit){ if (tpcHit->fQ == 0.) { tpcHit = (AliTPChit*) tpc->NextHit(); continue; //information about track (I.Belikov) } sector=tpcHit->fSector; // sector number if(sector != isec){ tpcHit = (AliTPChit*) tpc->NextHit(); continue; } ipart=tpcHit->Track(); particle=aliRun->GetMCApp()->Particle(ipart); pl=particle->Pz(); pt=particle->Pt(); if(pt < 1.e-9) pt=1.e-9; tanth=pl/pt; tanth = TMath::Abs(tanth); rpad=TMath::Sqrt(tpcHit->X()*tpcHit->X() + tpcHit->Y()*tpcHit->Y()); ratio=0.001*rpad/pt; // pt must be in MeV/c - historical reason // space-point resolutions sigmaRphi=AliTPCcluster::SigmaY2(rpad,tanth,pt); sigmaZ =AliTPCcluster::SigmaZ2(rpad,tanth ); // cluster widths clRphi=kACrphi-kBCrphi*rpad*tanth+kCCrphi*ratio*ratio; clZ=kACz-kBCz*rpad*tanth+kCCz*tanth*tanth; // temporary protection if(sigmaRphi < 0.) sigmaRphi=0.4e-3; if(sigmaZ < 0.) sigmaZ=0.4e-3; if(clRphi < 0.) clRphi=2.5e-3; if(clZ < 0.) clZ=2.5e-5; // // // smearing --> rotate to the 1 (13) or to the 25 (49) sector, // then the inaccuracy in a X-Y plane is only along Y (pad row)! // Float_t xprim= tpcHit->X()*cph + tpcHit->Y()*sph; Float_t yprim=-tpcHit->X()*sph + tpcHit->Y()*cph; xyz[0]=gRandom->Gaus(yprim,TMath::Sqrt(sigmaRphi)); // y Float_t alpha=(isec < param->GetNInnerSector()) ? param->GetInnerAngle() : param->GetOuterAngle(); Float_t ymax=xprim*TMath::Tan(0.5*alpha); if (TMath::Abs(xyz[0])>ymax) xyz[0]=yprim; xyz[1]=gRandom->Gaus(tpcHit->Z(),TMath::Sqrt(sigmaZ)); // z if (TMath::Abs(xyz[1])>param->GetZLength()) xyz[1]=tpcHit->Z(); xyz[2]=sigmaRphi; // fSigmaY2 xyz[3]=sigmaZ; // fSigmaZ2 xyz[4]=tpcHit->fQ; // q AliTPCClustersRow *clrow=carray.GetRow(sector,tpcHit->fPadRow); if (!clrow) clrow=carray.CreateRow(sector,tpcHit->fPadRow); Int_t tracks[3]={tpcHit->Track(), -1, -1}; AliTPCcluster cluster(tracks,xyz); clrow->InsertCluster(&cluster); nclusters++; tpcHit = (AliTPChit*)tpc->NextHit(); } // end of loop over hits } // end of loop over tracks Int_t nrows=param->GetNRow(isec); for (Int_t irow=0; irowWriteRecPoints("OVERWRITE"); } // end of function //_________________________________________________________________ void AliTPCFast::Hits2ExactClustersSector(AliRunLoader* runLoader, AliTPCClustersArray* clustersArray, Int_t isec) const { //-------------------------------------------------------- //calculate exact cross point of track and given pad row //resulting values are expressed in "digit" coordinata //-------------------------------------------------------- //----------------------------------------------------------------- // Origin: Marian Ivanov GSI Darmstadt, m.ivanov@gsi.de //----------------------------------------------------------------- // if (clustersArray==0){ return; } AliLoader* loader = runLoader->GetLoader("TPCLoader"); if (!loader) { AliError("No TPC loader found"); return; } if (!runLoader->GetAliRun()) runLoader->LoadgAlice(); AliRun* aliRun = runLoader->GetAliRun(); if (!aliRun) { AliError("Couldn't get AliRun object"); return; } AliTPC* tpc = (AliTPC*) aliRun->GetDetector("TPC"); if (!tpc) { AliError("Couldn't get TPC detector"); return; } AliTPCParam* param = tpc->GetParam(); if (!param) { AliError("No TPC parameters available"); return; } // TParticle *particle; // pointer to a given particle AliTPChit *tpcHit; // pointer to a sigle TPC hit // Int_t sector,nhits; Int_t ipart; const Int_t kcmaxhits=30000; TVector * xxxx = new TVector(kcmaxhits*4); TVector & xxx = *xxxx; Int_t maxhits = kcmaxhits; //construct array for each padrow for (Int_t i=0; iGetNRow(isec);i++) clustersArray->CreateRow(isec,i); //--------------------------------------------------------------- // Get the access to the tracks //--------------------------------------------------------------- TTree *tH = loader->TreeH(); if (tH == 0x0) AliFatal("Can not find TreeH in folder"); tpc->SetTreeAddress(); Stat_t ntracks = tH->GetEntries(); Int_t npart = aliRun->GetMCApp()->GetNtrack(); //MI change TBranch * branch=0; if (tpc->GetHitType()>1) branch = tH->GetBranch("TPC2"); else branch = tH->GetBranch("TPC"); //------------------------------------------------------------ // Loop over tracks //------------------------------------------------------------ for(Int_t track=0;trackResetHits(); isInSector = tpc->TrackInVolume(isec,track); if (!isInSector) continue; //MI change branch->GetEntry(track); // get next track // // Get number of the TPC hits and a pointer // to the particles // Loop over hits // Int_t currentIndex=0; Int_t lastrow=-1; //last writen row //M.I. changes tpcHit = (AliTPChit*)tpc->FirstHit(-1); while(tpcHit){ Int_t sector=tpcHit->fSector; // sector number if(sector != isec){ tpcHit = (AliTPChit*) tpc->NextHit(); continue; } ipart=tpcHit->Track(); if (ipartGetMCApp()->Particle(ipart); //find row number Float_t x[3]={tpcHit->X(),tpcHit->Y(),tpcHit->Z()}; Int_t index[3]={1,isec,0}; Int_t currentrow = param->GetPadRow(x,index) ; if (currentrow<0) {tpcHit = (AliTPChit*)tpc->NextHit(); continue;} if (lastrow<0) lastrow=currentrow; if (currentrow==lastrow){ if ( currentIndex>=maxhits){ maxhits+=kcmaxhits; xxx.ResizeTo(4*maxhits); } xxx(currentIndex*4)=x[0]; xxx(currentIndex*4+1)=x[1]; xxx(currentIndex*4+2)=x[2]; xxx(currentIndex*4+3)=tpcHit->fQ; currentIndex++; } else if (currentIndex>2){ Float_t sumx=0; Float_t sumx2=0; Float_t sumx3=0; Float_t sumx4=0; Float_t sumy=0; Float_t sumxy=0; Float_t sumx2y=0; Float_t sumz=0; Float_t sumxz=0; Float_t sumx2z=0; Float_t sumq=0; for (Int_t index=0;indexGetNPads(isec,lastrow)-1)/2; Float_t det=currentIndex*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumx*sumx4-sumx2*sumx3)+ sumx2*(sumx*sumx3-sumx2*sumx2); Float_t detay=sumy*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxy*sumx4-sumx2y*sumx3)+ sumx2*(sumxy*sumx3-sumx2y*sumx2); Float_t detaz=sumz*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxz*sumx4-sumx2z*sumx3)+ sumx2*(sumxz*sumx3-sumx2z*sumx2); Float_t detby=currentIndex*(sumxy*sumx4-sumx2y*sumx3)-sumy*(sumx*sumx4-sumx2*sumx3)+ sumx2*(sumx*sumx2y-sumx2*sumxy); Float_t detbz=currentIndex*(sumxz*sumx4-sumx2z*sumx3)-sumz*(sumx*sumx4-sumx2*sumx3)+ sumx2*(sumx*sumx2z-sumx2*sumxz); if (TMath::Abs(det)<0.00001){ tpcHit = (AliTPChit*)tpc->NextHit(); continue; } Float_t y=detay/det+centralPad; Float_t z=detaz/det; Float_t by=detby/det; //y angle Float_t bz=detbz/det; //z angle sumy/=Float_t(currentIndex); sumz/=Float_t(currentIndex); AliTPCClustersRow * row = (clustersArray->GetRow(isec,lastrow)); if (row!=0) { AliComplexCluster* cl = new((AliComplexCluster*)row->Append()) AliComplexCluster ; // AliComplexCluster cl; cl->fX=z; cl->fY=y; cl->fQ=sumq; cl->fSigmaX2=bz; cl->fSigmaY2=by; cl->fTracks[0]=ipart; } currentIndex=0; lastrow=currentrow; } //end of calculating cluster for given row tpcHit = (AliTPChit*)tpc->NextHit(); } // end of loop over hits } // end of loop over tracks //write padrows to tree for (Int_t ii=0; iiGetNRow(isec);ii++) { clustersArray->StoreRow(isec,ii); clustersArray->ClearRow(isec,ii); } xxxx->Delete(); } void AliTPCFast::FindTrackHitsIntersection(AliRunLoader* runLoader, AliTPCClustersArray* clustersArray) const { // //fill clones array with intersection of current point with the //middle of the row AliLoader* loader = runLoader->GetLoader("TPCLoader"); if (!loader) { AliError("No TPC loader found"); return; } if (!runLoader->GetAliRun()) runLoader->LoadgAlice(); AliRun* aliRun = runLoader->GetAliRun(); if (!aliRun) { AliError("Couldn't get AliRun object"); return; } AliTPC* tpc = (AliTPC*) aliRun->GetDetector("TPC"); if (!tpc) { AliError("Couldn't get TPC detector"); return; } AliTPCParam* param = tpc->GetParam(); if (!param) { AliError("No TPC parameters available"); return; } Int_t sector; Int_t ipart; const Int_t kcmaxhits=30000; TVector * xxxx = new TVector(kcmaxhits*4); TVector & xxx = *xxxx; Int_t maxhits = kcmaxhits; // AliTPChit * tpcHit=0; tpcHit = (AliTPChit*)tpc->FirstHit2(-1); Int_t currentIndex=0; Int_t lastrow=-1; //last writen row while (tpcHit){ if (tpcHit==0) continue; sector=tpcHit->fSector; // sector number ipart=tpcHit->Track(); //find row number Float_t x[3]={tpcHit->X(),tpcHit->Y(),tpcHit->Z()}; Int_t index[3]={1,sector,0}; Int_t currentrow = param->GetPadRow(x,index) ; if (currentrow<0) continue; if (lastrow<0) lastrow=currentrow; if (currentrow==lastrow){ if ( currentIndex>=maxhits){ maxhits+=kcmaxhits; xxx.ResizeTo(4*maxhits); } xxx(currentIndex*4)=x[0]; xxx(currentIndex*4+1)=x[1]; xxx(currentIndex*4+2)=x[2]; xxx(currentIndex*4+3)=tpcHit->fQ; currentIndex++; } else if (currentIndex>2){ Float_t sumx=0; Float_t sumx2=0; Float_t sumx3=0; Float_t sumx4=0; Float_t sumy=0; Float_t sumxy=0; Float_t sumx2y=0; Float_t sumz=0; Float_t sumxz=0; Float_t sumx2z=0; Float_t sumq=0; for (Int_t index=0;indexGetNPads(sector,lastrow)-1)/2; Float_t det=currentIndex*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumx*sumx4-sumx2*sumx3)+ sumx2*(sumx*sumx3-sumx2*sumx2); Float_t detay=sumy*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxy*sumx4-sumx2y*sumx3)+ sumx2*(sumxy*sumx3-sumx2y*sumx2); Float_t detaz=sumz*(sumx2*sumx4-sumx3*sumx3)-sumx*(sumxz*sumx4-sumx2z*sumx3)+ sumx2*(sumxz*sumx3-sumx2z*sumx2); Float_t detby=currentIndex*(sumxy*sumx4-sumx2y*sumx3)-sumy*(sumx*sumx4-sumx2*sumx3)+ sumx2*(sumx*sumx2y-sumx2*sumxy); Float_t detbz=currentIndex*(sumxz*sumx4-sumx2z*sumx3)-sumz*(sumx*sumx4-sumx2*sumx3)+ sumx2*(sumx*sumx2z-sumx2*sumxz); Float_t y=detay/det+centralPad; Float_t z=detaz/det; Float_t by=detby/det; //y angle Float_t bz=detbz/det; //z angle sumy/=Float_t(currentIndex); sumz/=Float_t(currentIndex); AliComplexCluster cl; cl.fX=z; cl.fY=y; cl.fQ=sumq; cl.fSigmaX2=bz; cl.fSigmaY2=by; cl.fTracks[0]=ipart; AliTPCClustersRow * row = (clustersArray->GetRow(sector,lastrow)); if (row!=0) row->InsertCluster(&cl); currentIndex=0; lastrow=currentrow; } //end of calculating cluster for given row } // end of loop over hits xxxx->Delete(); }