From: fca Date: Fri, 30 Jul 1999 10:53:20 +0000 (+0000) Subject: New version of MUON from M.Bondila & A.Morsch X-Git-Url: http://git.uio.no/git/?p=u%2Fmrichter%2FAliRoot.git;a=commitdiff_plain;h=a897a37a5855b839f1f4ff403bebaa1d4641bbcd New version of MUON from M.Bondila & A.Morsch --- diff --git a/MUON/AliMUON.cxx b/MUON/AliMUON.cxx index 9606ca821d2..2ce4bf43680 100644 --- a/MUON/AliMUON.cxx +++ b/MUON/AliMUON.cxx @@ -3,24 +3,112 @@ //////////////////////////////////////////////// #include +#include +#include #include +#include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "AliMUON.h" +#include "TTUBE.h" +#include "AliMUONClusterFinder.h" #include "AliRun.h" #include "AliMC.h" #include "iostream.h" #include "AliCallf77.h" +#ifndef WIN32 +# define reco_init reco_init_ +# define cutpxz cutpxz_ +# define sigmacut sigmacut_ +# define xpreci xpreci_ +# define ypreci ypreci_ +# define reconstmuon reconstmuon_ +# define trackf_read_geant trackf_read_geant_ +# define trackf_read_spoint trackf_read_spoint_ +# define chfill chfill_ +# define chfill2 chfill2_ +# define chf1 chf1_ +# define chfnt chfnt_ +# define hist_create hist_create_ +# define hist_closed hist_closed_ +# define rndm rndm_ +# define fcn fcn_ +# define trackf_fit trackf_fit_ +# define prec_fit prec_fit_ +# define fcnfit fcnfit_ +# define reco_term reco_term_ +#else +# define reco_init RECO_INIT +# define cutpxz CUTPXZ +# define sigmacut SIGMACUT +# define xpreci XPRECI +# define ypreci YPRECI +# define reconstmuon RECONSTMUON +# define trackf_read_geant TRACKF_READ_GEANT +# define trackf_read_spoint TRACKF_READ_SPOINT +# define chfill CHFILL +# define chfill2 CHFILL2 +# define chf1 CHF1 +# define chfnt CHFNT +# define hist_create HIST_CREATE +# define hist_closed HIST_CLOSED +# define rndm RNDM +# define fcn FCN +# define trackf_fit TRACKF_FIT +# define prec_fit PREC_FIT +# define fcnfit FCNFIT +# define reco_term RECO_TERM +#endif + +extern "C" +{ +void type_of_call reco_init(Double_t &, Double_t &, Double_t &); +void type_of_call reco_term(); +void type_of_call cutpxz(Double_t &); +void type_of_call sigmacut(Double_t &); +void type_of_call xpreci(Double_t &); +void type_of_call ypreci(Double_t &); +void type_of_call reconstmuon(Int_t &, Int_t &, Int_t &, Int_t &, Int_t &); +void type_of_call trackf_read_geant(Int_t *, Double_t *, Double_t *, Double_t *, Int_t *, Int_t *, Double_t *, Double_t *, Double_t *, Double_t *,Int_t &, Double_t *, Double_t *, Double_t *, Int_t &, Int_t &, Double_t *, Double_t *, Double_t *, Double_t *); +void type_of_call trackf_read_spoint(Int_t *, Double_t *, Double_t *, Double_t *, Int_t *, Int_t *, Double_t *, Double_t *, Double_t *, Double_t *,Int_t &, Double_t *, Double_t *, Double_t *, Int_t &, Int_t &, Double_t *, Double_t *, Double_t *, Double_t *); +void type_of_call chfill(Int_t &, Float_t &, Float_t &, Float_t &); +void type_of_call chfill2(Int_t &, Float_t &, Float_t &, Float_t &); +void type_of_call chf1(Int_t &, Float_t &, Float_t &); +void type_of_call chfnt(Int_t &, Int_t &, Int_t *, Int_t *, Float_t *, Float_t *, Float_t *, Float_t *, Float_t *, Float_t *, Float_t *, Float_t *); +void type_of_call hist_create(); +void type_of_call hist_closed(); +void type_of_call fcnf(Int_t &, Double_t *, Double_t &, Double_t *, Int_t); +void type_of_call fcn(Int_t &, Double_t *, Double_t &, Double_t *, Int_t &, Int_t &); +void type_of_call trackf_fit(Int_t &, Double_t *, Double_t *, Double_t &, Double_t &, Double_t &, Double_t &, Double_t &); +void type_of_call prec_fit(Double_t &, Double_t &, Double_t &, Double_t &, Double_t&, Double_t &, Double_t &, Double_t &, Double_t &, Double_t &, Double_t &, Double_t &, Double_t &, Double_t &, Double_t &); +void type_of_call fcnfitf(Int_t &, Double_t *, Double_t &, Double_t *, Int_t); +void type_of_call fcnfit(Int_t &, Double_t *, Double_t &, Double_t *, Int_t &, Int_t &); +Float_t type_of_call rndm() {return gRandom->Rndm();} +} + // Static variables for the pad-hit iterator routines static Int_t sMaxIterPad=0; static Int_t sCurIterPad=0; - +static TTree *TH1; +static TTree *TK1; +static TClonesArray *fHits2; //Listof hits for one track only +static TClonesArray *fClusters2; //List of clusters for one track only +static TClonesArray *fParticles2; //List of particles in the Kine tree ClassImp(AliMUON) - //___________________________________________ AliMUON::AliMUON() { @@ -29,8 +117,24 @@ AliMUON::AliMUON() fClusters = 0; fNclusters = 0; fDchambers = 0; - fRecClusters= 0; + // fRecClusters= 0; fNdch = 0; + fRawClusters= 0; + fNrawch = 0; + fCathCorrel= 0; + fNcorch = 0; + fTreeC = 0; + + // modifs perso + fSPxzCut = 0; + fSSigmaCut = 0; + fSXPrec = 0; + fSYPrec = 0; + /* + fSSigmaCut = 4.0; + fSXPrec = 0.006; + fSYPrec = 0.12; + */ } //___________________________________________ @@ -39,29 +143,43 @@ AliMUON::AliMUON(const char *name, const char *title) { //Begin_Html /* - + */ //End_Html - fHits = new TClonesArray("AliMUONhit",1000 ); + fHits = new TClonesArray("AliMUONhit",1000); fClusters = new TClonesArray("AliMUONcluster",10000); fNclusters = 0; fIshunt = 0; - fNdch = new Int_t[11]; + fNdch = new Int_t[10]; - fDchambers = new TObjArray(11); + fDchambers = new TObjArray(10); Int_t i; - for (i=0; i<11 ;i++) { + for (i=0; i<10 ;i++) { (*fDchambers)[i] = new TClonesArray("AliMUONdigit",10000); fNdch[i]=0; } - fRecClusters=new TObjArray(20); - for (i=0; i<20;i++) - (*fRecClusters)[i] = new TObjArray(1000); + fNrawch = new Int_t[10]; + + fRawClusters = new TObjArray(10); + + for (i=0; i<10 ;i++) { + (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000); + fNrawch[i]=0; + } + + fNcorch = new Int_t[10]; + fCathCorrel = new TObjArray(10); + for (i=0; i<10 ;i++) { + (*fCathCorrel)[i] = new TClonesArray("AliMUONcorrelation",1000); + fNcorch[i]=0; + } + + fTreeC = 0; // // Transport angular cut @@ -69,24 +187,47 @@ AliMUON::AliMUON(const char *name, const char *title) fAccMin=2; fAccMax=9; + // modifs perso + fSPxzCut = 3.0; + fSSigmaCut = 1.0; + fSXPrec = 0.01; + fSYPrec = 0.144; + /* + fSSigmaCut = 4.0; + fSXPrec = 0.006; + fSYPrec = 0.12; + */ SetMarkerColor(kRed); } //___________________________________________ AliMUON::~AliMUON() { + + printf("Calling AliMUON destructor !!!\n"); + fIshunt = 0; delete fHits; delete fClusters; -// for (Int_t i=0;i<10;i++) { -// delete (*fDchambers)[i]; -// fNdch[i]=0; -// } -// delete fDchambers; - for (Int_t i=0;i<20;i++) - delete (*fRecClusters)[i]; - delete fRecClusters; + delete fTreeC; + for (Int_t i=0;i<10;i++) { + delete (*fDchambers)[i]; + fNdch[i]=0; + } + delete fDchambers; + + for (Int_t i=0;i<10;i++) { + delete (*fRawClusters)[i]; + fNrawch[i]=0; + } + delete fRawClusters; + + for (Int_t i=0;i<10;i++) { + delete (*fCathCorrel)[i]; + fNcorch[i]=0; + } + delete fCathCorrel; } //___________________________________________ @@ -112,6 +253,27 @@ void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits) new(ldigits[fNdch[id]++]) AliMUONdigit(tracks,charges,digits); } +//_____________________________________________________________________________ +void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c) +{ + // + // Add a MUON digit to the list + // + + TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]); + new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c); +} +//_____________________________________________________________________________ +void AliMUON::AddCathCorrel(Int_t id, Int_t *idx, Float_t *x, Float_t *y) +{ + // + // Add a MUON digit to the list + // + + TClonesArray &lcorrel = *((TClonesArray*)(*fCathCorrel)[id]); + new(lcorrel[fNcorch[id]++]) AliMUONcorrelation(idx,x,y); +} + //_____________________________________________________________________________ void AliMUON::AddRecCluster(Int_t iCh, Int_t iCat, AliMUONRecCluster* Cluster) @@ -119,116 +281,93 @@ void AliMUON::AddRecCluster(Int_t iCh, Int_t iCat, AliMUONRecCluster* Cluster) // // Add a MUON reconstructed cluster to the list // + /* TObjArray* ClusterList = RecClusters(iCh,iCat); ClusterList->Add(Cluster); + */ } //___________________________________________ void AliMUON::BuildGeometry() { - TNode *Node, *Top; - const int kColorMUON = kBlue; - // - Top=gAlice->GetGeometry()->GetNode("alice"); - - // MUON - const float cz[10] = { 511, 519, 686, 694, 971, 979, 1245, 1253, 1445, 1453}; - const float acc_min = TMath::Tan( 2*.0174532925199432958); - const float acc_max = TMath::Tan(9*.0174532925199432958); - float rmin, rmax; - - // Chamber 1 - rmin = (cz[0]+0.25)*acc_min; - rmax = cz[0]*acc_max; - new TTUBE("S_MUON1","MUON chamber 1","void",rmin,rmax,0.25); - Top->cd(); - Node = new TNode("MUON1","MUON chamber 1","S_MUON1",0,0,cz[0],""); - Node->SetLineColor(kColorMUON); - fNodes->Add(Node); - - // Chamber 2 - rmin = (cz[1]+0.25)*acc_min; - rmax = cz[1]*acc_max; - new TTUBE("S_MUON2","MUON chamber 2","void",rmin,rmax,0.25); - Top->cd(); - Node = new TNode("MUON2","MUON chamber 2","S_MUON2",0,0,cz[1],""); - fNodes->Add(Node); - Node->SetLineColor(kColorMUON); - - // Chamber 3 - rmin = (cz[2]+0.25)*acc_min; - rmax = cz[2]*acc_max; - new TTUBE("S_MUON3","MUON chamber 3","void",rmin,rmax,0.25); - Top->cd(); - Node = new TNode("MUON3","MUON chamber 3","S_MUON3",0,0,cz[2],""); - Node->SetLineColor(kColorMUON); - fNodes->Add(Node); - - // Chamber 4 - rmin = (cz[3]+0.25)*acc_min; - rmax = cz[3]*acc_max; - new TTUBE("S_MUON4","MUON chamber 4","void",rmin,rmax,0.25); - Top->cd(); - Node = new TNode("MUON4","MUON chamber 4","S_MUON4",0,0,cz[3],""); - Node->SetLineColor(kColorMUON); - fNodes->Add(Node); - - // Chamber 5 - rmin = 30; - rmax = cz[4]*acc_max; - new TTUBE("S_MUON5","MUON chamber 5","void",rmin,rmax,0.25); - Top->cd(); - Node = new TNode("MUON5","MUON chamber 5","S_MUON5",0,0,cz[4],""); - Node->SetLineColor(kColorMUON); - fNodes->Add(Node); - - // Chamber 6 - rmin = 30; - rmax = cz[5]*acc_max; - new TTUBE("S_MUON6","MUON chamber 6","void",rmin,rmax,0.25); - Top->cd(); - Node = new TNode("MUON6","MUON chamber 6","S_MUON6",0,0,cz[5],""); - fNodes->Add(Node); - Node->SetLineColor(kColorMUON); - - // Chamber 7 - rmin = 30; - rmax = cz[6]*acc_max; - new TTUBE("S_MUON7","MUON chamber 7","void",rmin,rmax,0.25); - Top->cd(); - Node = new TNode("MUON7","MUON chamber 7","S_MUON7",0,0,cz[6],""); - Node->SetLineColor(kColorMUON); - fNodes->Add(Node); - - // Chamber 8 - rmin = 30; - rmax = cz[7]*acc_max; - new TTUBE("S_MUON8","MUON chamber 8","void",rmin,rmax,0.25); - Top->cd(); - Node = new TNode("MUON8","MUON chamber 8","S_MUON8",0,0,cz[7],""); - Node->SetLineColor(kColorMUON); - fNodes->Add(Node); - - // Chamber 9 - rmin = 30; - rmax = cz[8]*acc_max; - new TTUBE("S_MUON9","MUON chamber 9","void",rmin,rmax,0.25); - Top->cd(); - Node = new TNode("MUON9","MUON chamber 9","S_MUON9",0,0,cz[8],""); - Node->SetLineColor(kColorMUON); - fNodes->Add(Node); - - // Chamber 10 - rmin = 30; - rmax = cz[9]*acc_max; - new TTUBE("S_MUON10","MUON chamber 10","void",rmin,rmax,0.25); - Top->cd(); - Node = new TNode("MUON10","MUON chamber 10","S_MUON10",0,0,cz[9],""); - Node->SetLineColor(kColorMUON); - fNodes->Add(Node); - + TNode *Node, *NodeF, *Top; + const int kColorMUON = kBlue; + // + Top=gAlice->GetGeometry()->GetNode("alice"); +// MUON +// +// z-Positions of Chambers + const Float_t cz[5]={511., 686., 971., 1245., 1445.}; +// +// inner diameter + const Float_t dmi[5]={ 35., 47., 67., 86., 100.}; +// +// outer diameter + const Float_t dma[5]={183., 245., 346., 520., 520.}; + + TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0); + TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0); + TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0); + TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0); + + + float rmin, rmax, dx, dy, dz, dr, zpos; + float dzc=4.; + char NameChamber[9], NameSense[9], NameFrame[9], NameNode[7]; + for (Int_t i=0; i<5; i++) { + for (Int_t j=0; j<2; j++) { + Int_t id=2*i+j+1; + if (j==0) { + zpos=cz[i]-dzc; + } else { + zpos=cz[i]+dzc; + } + + + sprintf(NameChamber,"C_MUON%d",id); + sprintf(NameSense,"S_MUON%d",id); + sprintf(NameFrame,"F_MUON%d",id); + rmin = dmi[i]/2.-3; + rmax = dma[i]/2.+3; + new TTUBE(NameChamber,"Mother","void",rmin,rmax,0.25,1.); + rmin = dmi[i]/2.; + rmax = dma[i]/2.; + new TTUBE(NameSense,"Sens. region","void",rmin,rmax,0.25, 1.); + dx=(rmax-rmin)/2; + dy=3.; + dz=0.25; + TBRIK* FMUON = new TBRIK(NameFrame,"Frame","void",dx,dy,dz); + Top->cd(); + sprintf(NameNode,"MUON%d",100+id); + Node = new TNode(NameNode,"ChamberNode",NameChamber,0,0,zpos,""); + Node->SetLineColor(kColorMUON); + fNodes->Add(Node); + Node->cd(); + sprintf(NameNode,"MUON%d",200+id); + Node = new TNode(NameNode,"Sens. Region Node",NameSense,0,0,0,""); + Node->SetLineColor(kColorMUON); + Node->cd(); + dr=dx+rmin; + sprintf(NameNode,"MUON%d",300+id); + NodeF = new TNode(NameNode,"Frame0",FMUON,dr, 0, 0,rot000,""); + NodeF->SetLineColor(kColorMUON); + Node->cd(); + sprintf(NameNode,"MUON%d",400+id); + NodeF = new TNode(NameNode,"Frame1",FMUON,0 ,dr,0,rot090,""); + NodeF->SetLineColor(kColorMUON); + Node->cd(); + sprintf(NameNode,"MUON%d",500+id); + NodeF = new TNode(NameNode,"Frame2",FMUON,-dr,0,0,rot180,""); + NodeF->SetLineColor(kColorMUON); + Node ->cd(); + sprintf(NameNode,"MUON%d",600+id); + NodeF = new TNode(NameNode,"Frame3",FMUON,0,-dr,0,rot270,""); + NodeF->SetLineColor(kColorMUON); + } + } } + //___________________________________________ Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t ) { @@ -241,7 +380,7 @@ void AliMUON::MakeBranch(Option_t* option) // Create Tree branches for the MUON. const Int_t buffersize = 4000; - char branchname[20]; + char branchname[30]; sprintf(branchname,"%sCluster",GetName()); AliDetector::MakeBranch(option); @@ -262,7 +401,21 @@ void AliMUON::MakeBranch(Option_t* option) printf("Making Branch %s for digits in chamber %d\n",branchname,i+1); } } -// one branch for rec clusters + + printf("Make Branch - TreeR address %p\n",gAlice->TreeR()); + +// one branch for raw clusters per chamber + for (i=0; i<10 ;i++) { + sprintf(branchname,"%sRawClusters%d",GetName(),i+1); + + if (fRawClusters && gAlice->TreeR()) { + gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), buffersize); + printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1); + } + } + +// Emmanuel's stuff - one branch for rec clusters + /* for (i=0; i<20; i++) { sprintf(branchname,"%sRecClus%d",GetName(),i+1); if (fRecClusters && gAlice->TreeD()) { @@ -273,18 +426,21 @@ void AliMUON::MakeBranch(Option_t* option) branchname,i+1); } } + */ + } //___________________________________________ void AliMUON::SetTreeAddress() { // Set branch address for the Hits and Digits Tree. - char branchname[20]; + char branchname[30]; AliDetector::SetTreeAddress(); TBranch *branch; TTree *treeH = gAlice->TreeH(); TTree *treeD = gAlice->TreeD(); + TTree *treeR = gAlice->TreeR(); if (treeH) { if (fClusters) { @@ -302,6 +458,31 @@ void AliMUON::SetTreeAddress() } } } + + // printf("SetTreeAddress --- treeR address %p \n",treeR); + + if (treeR) { + for (int i=0; i<10; i++) { + sprintf(branchname,"%sRawClusters%d",GetName(),i+1); + if (fRawClusters) { + branch = treeR->GetBranch(branchname); + if (branch) branch->SetAddress(&((*fRawClusters)[i])); + } + } + } + + // Emmanuel's stuff + /* + if (treeR) { + for (int i=0; i<20; i++) { + sprintf(branchname,"%sRecClus%d",GetName(),i+1); + if (fRecClusters) { + branch = treeR->GetBranch(branchname); + if (branch) branch->SetAddress(&((*fRecClusters)[i])); + } + } + } + */ } //___________________________________________ void AliMUON::ResetHits() @@ -319,19 +500,45 @@ void AliMUON::ResetDigits() // Reset number of digits and the digits array for this detector // for ( int i=0;i<10;i++ ) { - if ((*fDchambers)[i]) (*fDchambers)[i]->Clear(); + if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear(); if (fNdch) fNdch[i]=0; } } +//____________________________________________ +void AliMUON::ResetRawClusters() +{ + // + // Reset number of raw clusters and the raw clust array for this detector + // + for ( int i=0;i<10;i++ ) { + if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear(); + if (fNrawch) fNrawch[i]=0; + } +} +//____________________________________________ +void AliMUON::ResetCorrelation() +{ + // + // Reset number of correl clusters and the correl clust array for + // this detector + // + for ( int i=0;i<10;i++ ) { + if ((*fCathCorrel)[i]) ((TClonesArray*)(*fCathCorrel)[i])->Clear(); + if (fNcorch) fNcorch[i]=0; + } +} + //____________________________________________ void AliMUON::ResetRecClusters() { // // Reset the rec clusters // + /* for ( int i=0;i<20;i++ ) { if ((*fRecClusters)[i]) (*fRecClusters)[i]->Clear(); } + */ } //___________________________________________ @@ -343,62 +550,62 @@ void AliMUON::SetPADSIZ(Int_t id, Int_t isec, Float_t p1, Float_t p2) } //___________________________________________ -void AliMUON::SetMUCHSP(Int_t id, Float_t p1) +void AliMUON::SetChargeSlope(Int_t id, Float_t p1) { Int_t i=2*(id-1); - ((AliMUONchamber*) (*fChambers)[i])->SetMUCHSP(p1); - ((AliMUONchamber*) (*fChambers)[i+1])->SetMUCHSP(p1); + ((AliMUONchamber*) (*fChambers)[i])->SetChargeSlope(p1); + ((AliMUONchamber*) (*fChambers)[i+1])->SetChargeSlope(p1); } //___________________________________________ -void AliMUON::SetMUSIGM(Int_t id, Float_t p1, Float_t p2) +void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2) { Int_t i=2*(id-1); - ((AliMUONchamber*) (*fChambers)[i])->SetMUSIGM(p1,p2); - ((AliMUONchamber*) (*fChambers)[i+1])->SetMUSIGM(p1,p2); + ((AliMUONchamber*) (*fChambers)[i])->SetChargeSpread(p1,p2); + ((AliMUONchamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2); } //___________________________________________ -void AliMUON::SetRSIGM(Int_t id, Float_t p1) +void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1) { Int_t i=2*(id-1); - ((AliMUONchamber*) (*fChambers)[i])->SetRSIGM(p1); - ((AliMUONchamber*) (*fChambers)[i+1])->SetRSIGM(p1); + ((AliMUONchamber*) (*fChambers)[i])->SetSigmaIntegration(p1); + ((AliMUONchamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1); } //___________________________________________ -void AliMUON::SetMAXADC(Int_t id, Float_t p1) +void AliMUON::SetMaxAdc(Int_t id, Float_t p1) { Int_t i=2*(id-1); - ((AliMUONchamber*) (*fChambers)[i])->SetMAXADC(p1); - ((AliMUONchamber*) (*fChambers)[i+1])->SetMAXADC(p1); + ((AliMUONchamber*) (*fChambers)[i])->SetMaxAdc(p1); + ((AliMUONchamber*) (*fChambers)[i+1])->SetMaxAdc(p1); } //___________________________________________ -void AliMUON::SetSMAXAR(Float_t p1) +void AliMUON::SetMaxStepGas(Float_t p1) { fMaxStepGas=p1; } //___________________________________________ -void AliMUON::SetSMAXAL(Float_t p1) +void AliMUON::SetMaxStepAlu(Float_t p1) { fMaxStepAlu=p1; } //___________________________________________ -void AliMUON::SetDMAXAR(Float_t p1) +void AliMUON::SetMaxDestepGas(Float_t p1) { fMaxDestepGas=p1; } //___________________________________________ -void AliMUON::SetDMAXAL(Float_t p1) +void AliMUON::SetMaxDestepAlu(Float_t p1) { fMaxDestepAlu=p1; } //___________________________________________ -void AliMUON::SetMUONACC(Bool_t acc, Float_t angmin, Float_t angmax) +void AliMUON::SetMuonAcc(Bool_t acc, Float_t angmin, Float_t angmax) { fAccCut=acc; fAccMin=angmin; @@ -416,6 +623,11 @@ void AliMUON::SetResponseModel(Int_t id, AliMUONresponse *response) ((AliMUONchamber*) (*fChambers)[id])->ResponseModel(response); } +void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinder *reconst) +{ + ((AliMUONchamber*) (*fChambers)[id])->ReconstructionModel(reconst); +} + void AliMUON::SetNsec(Int_t id, Int_t nsec) { ((AliMUONchamber*) (*fChambers)[id])->SetNsec(nsec); @@ -428,139 +640,990 @@ void AliMUON::StepManager() { printf("Dummy version of muon step -- it should never happen!!\n"); const Float_t kRaddeg = 180/TMath::Pi(); + AliMC* pMC = AliMC::GetMC(); Int_t nsec, ipart; Float_t x[4], p[4]; - Float_t pt, th0, th1; + Float_t pt, th0, th2; char proc[5]; if(fAccCut) { - if((nsec=gMC->NSecondaries())>0) { - gMC->ProdProcess(proc); - if((gMC->TrackPid()==113 || gMC->TrackPid()==114) && !strcmp(proc,"DCAY")) { + if((nsec=pMC->NSecondaries())>0) { + pMC->ProdProcess(proc); + if((pMC->TrackPid()==443 || pMC->TrackPid()==553) && !strcmp(proc,"DCAY")) { // // Check angular acceptance //* --- and have muons from resonance decays in the wanted window --- if(nsec != 2) { printf(" AliMUON::StepManager: Strange resonance Decay into %d particles\n",nsec); - gMC->StopEvent(); + pMC->StopEvent(); } else { - gMC->GetSecondary(0,ipart,x,p); + pMC->GetSecondary(0,ipart,x,p); pt = TMath::Sqrt(p[0]*p[0]+p[1]*p[1]); th0 = TMath::ATan2(pt,p[2])*kRaddeg; - gMC->GetSecondary(1,ipart,x,p); + pMC->GetSecondary(1,ipart,x,p); pt = TMath::Sqrt(p[0]*p[0]+p[1]*p[1]); - th1 = TMath::ATan2(pt,p[2])*kRaddeg; + th2 = TMath::ATan2(pt,p[2])*kRaddeg; if(!(fAccMin < th0 && th0 < fAccMax) || - !(fAccMin < th1 && th1 < fAccMax)) - gMC->StopEvent(); + !(fAccMin < th2 && th2 < fAccMax)) + pMC->StopEvent(); } } } } } -void AliMUON::ReconstructClusters() + +void AliMUON::MakePadHits(Float_t xhit,Float_t yhit,Float_t eloss, Int_t idvol) { // -// Initialize the necessary correspondance table +// Calls the charge disintegration method of the current chamber and adds +// the simulated cluster to the root treee // - static const Int_t kMaxNpadx = 600; - static const Int_t kMaxNpady = 600; - Int_t elem[kMaxNpadx*2][kMaxNpady*2]; + Int_t clhits[7]; + Float_t newclust[6][500]; + Int_t nnew; + + // -// Loop on chambers and on cathode planes +// Integrated pulse height on chamber + + + clhits[0]=fNhits+1; // - for (Int_t ich=0;ich<10;ich++) - for (Int_t icat=0;icat<2;icat++) { - // - // Get ready the current chamber stuff - // - AliMUONchamber* iChamber= &(this->Chamber(ich)); - AliMUONsegmentation* segmentation = - iChamber->GetSegmentationModel(icat+1); - if (!segmentation) - continue; - TClonesArray *MUONdigits = this->DigitsAddress(ich); - if (MUONdigits == 0) - continue; - cout << "Npx " << segmentation->Npx() - << " Npy " << segmentation->Npy() << endl; - // - // Ready the digits - // - gAlice->ResetDigits(); - gAlice->TreeD()->GetEvent(icat+1); // spurious +1 ... - Int_t ndigits = MUONdigits->GetEntriesFast(); - if (ndigits == 0) +// + ((AliMUONchamber*) (*fChambers)[idvol])->DisIntegration(eloss, xhit, yhit, nnew, newclust); +// printf("\n Add new clusters %d %f \n", nnew, eloss*1.e9); + Int_t ic=0; + +// +// Add new clusters + for (Int_t i=0; i 0) { + ic++; +// Cathode plane + clhits[1] = Int_t(newclust[5][i]); +// Cluster Charge + clhits[2] = Int_t(newclust[0][i]); +// Pad: ix + clhits[3] = Int_t(newclust[1][i]); +// Pad: iy + clhits[4] = Int_t(newclust[2][i]); +// Pad: charge + clhits[5] = Int_t(newclust[3][i]); +// Pad: chamber sector + clhits[6] = Int_t(newclust[4][i]); + + AddCluster(clhits); + } + } +// printf("\n %d new clusters added", ic); +} + +void AliMUON::Digitise(Int_t nev,Int_t bgr_ev,Option_t *option,Option_t *opt,Text_t *filename) +{ + // keep galice.root for signal and name differently the file for + // background when add! otherwise the track info for signal will be lost ! + + static Bool_t first=true; +// static TTree *TH1; + static TFile *File; + char *Add = strstr(option,"Add"); + //char *listoftracks = strstr(opt,"listoftracks"); + + AliMUONchamber* iChamber; + AliMUONsegmentation* segmentation; + + + Int_t trk[50]; + Int_t chtrk[50]; + TObjArray *list=new TObjArray; + static TClonesArray *p_adr=0; + if(!p_adr) p_adr=new TClonesArray("TVector",1000); + Int_t digits[5]; + + AliMUON *MUON = (AliMUON *) gAlice->GetModule("MUON"); + AliMUONHitMap * HitMap[10]; + for (Int_t i=0; i<10; i++) {HitMap[i]=0;} + if (Add ) { + if(first) { + fFileName=filename; + cout<<"filename"<cd(); + //File->ls(); + // Get Hits Tree header from file + if(fHits2) fHits2->Clear(); + if(fClusters2) fClusters2->Clear(); + if(TH1) delete TH1; + TH1=0; + + char treeName[20]; + sprintf(treeName,"TreeH%d",bgr_ev); + TH1 = (TTree*)gDirectory->Get(treeName); + //printf("TH1 %p of treename %s for event %d \n",TH1,treeName,bgr_ev); + + if (!TH1) { + printf("ERROR: cannot find Hits Tree for event:%d\n",bgr_ev); + } + // Set branch addresses + TBranch *branch; + char branchname[20]; + sprintf(branchname,"%s",GetName()); + if (TH1 && fHits2) { + branch = TH1->GetBranch(branchname); + if (branch) branch->SetAddress(&fHits2); + } + if (TH1 && fClusters2) { + branch = TH1->GetBranch("MUONCluster"); + if (branch) branch->SetAddress(&fClusters2); + } +// test + //Int_t ntracks1 =(Int_t)TH1->GetEntries(); + //printf("background - ntracks1 - %d\n",ntracks1); + } + // + // loop over cathodes + // + AliMUONHitMap* hm; + Int_t countadr=0; + for (int icat=0; icat<2; icat++) { +/* + for (Int_t i=0; i<10; i++) { + if (HitMap[i]) { + hm=HitMap[i]; + delete hm; + HitMap[i]=0; + } + } +*/ + + Int_t counter=0; + for (Int_t i =0; i<10; i++) { + iChamber=(AliMUONchamber*) (*fChambers)[i]; + if (iChamber->Nsec()==1 && icat==1) { continue; - printf("Found %d digits for cathode %d in chamber %d \n", - ndigits,icat,ich+1); - AliMUONdigit *mdig; - AliMUONRecCluster *Cluster; - // - // Build the correspondance table - // - memset(elem,0,sizeof(Int_t)*kMaxNpadx*kMaxNpady*4); - Int_t digit; - for (digit=0; digitUncheckedAt(digit); - elem[kMaxNpadx+mdig->fPadX][kMaxNpady+mdig->fPadY] = digit+1; - // because default is 0 + } else { + segmentation=iChamber->GetSegmentationModel(icat+1); } - // - // Declare some useful variables - // - Int_t Xlist[10]; - Int_t Ylist[10]; - Int_t Nlist; - Int_t nclust=0; - // - // loop over digits - // - for (digit=0;digitUncheckedAt(digit); - // - // if digit still available, start clustering - // - if (elem[kMaxNpadx+mdig->fPadX][kMaxNpady+mdig->fPadY]) { - Cluster = new AliMUONRecCluster(digit, ich, icat); - elem[kMaxNpadx+mdig->fPadX][kMaxNpady+mdig->fPadY]=0; - // - // loop over the current list of digits - // and look for neighbours - // - for(Int_t clusDigit=Cluster->FirstDigitIndex(); - clusDigit!=Cluster->InvalidDigitIndex(); - clusDigit=Cluster->NextDigitIndex()) { - AliMUONdigit* pDigit=(AliMUONdigit*)MUONdigits - ->UncheckedAt(clusDigit); - segmentation->Neighbours(pDigit->fPadX,pDigit->fPadY, - &Nlist, Xlist, Ylist); - for (Int_t Ilist=0;IlistAddDigit(elem[kMaxNpadx+Xlist[Ilist]][kMaxNpady+Ylist[Ilist]]-1); - elem[kMaxNpadx+Xlist[Ilist]][kMaxNpady - +Ylist[Ilist]] =0; - } // if elem - } // for Ilist - } // for pDigit - // - // Store the cluster (good time to do Cluster polishing) - // - segmentation->FitXY(Cluster,MUONdigits); - nclust ++; - AddRecCluster(ich,icat,Cluster); + HitMap[i] = new AliMUONHitMapA1(segmentation, list); + } + //printf("Start loop over tracks \n"); +// +// Loop over tracks +// + + TTree *TH = gAlice->TreeH(); + Int_t ntracks =(Int_t) TH->GetEntries(); + //printf("signal - ntracks %d\n",ntracks); + Int_t nmuon[10]={0,0,0,0,0,0,0,0,0,0}; + Float_t xhit[10][2]; + Float_t yhit[10][2]; + + for (Int_t track=0; trackResetHits(); + TH->GetEvent(track); + +// +// Loop over hits + for(AliMUONhit* mHit=(AliMUONhit*)MUON->FirstHit(-1); + mHit; + mHit=(AliMUONhit*)MUON->NextHit()) + { + Int_t nch = mHit->fChamber-1; // chamber number + if (nch >9) continue; + iChamber = &(MUON->Chamber(nch)); + Int_t rmin = (Int_t)iChamber->RInner(); + Int_t rmax = (Int_t)iChamber->ROuter(); + // new 17.07.99 + if (Add) { + + if (mHit->fParticle == kMuonPlus || mHit->fParticle == kMuonMinus) { + xhit[nch][nmuon[nch]]=mHit->fX; + yhit[nch][nmuon[nch]]=mHit->fY; + nmuon[nch]++; + if (nmuon[nch] >2) printf("nmuon %d\n",nmuon[nch]); + + } } + + + + +// +// Loop over pad hits + for (AliMUONcluster* mPad= + (AliMUONcluster*)MUON->FirstPad(mHit,fClusters); + mPad; + mPad=(AliMUONcluster*)MUON->NextPad(fClusters)) + { + Int_t cathode = mPad->fCathode; // cathode number + Int_t ipx = mPad->fPadX; // pad number on X + Int_t ipy = mPad->fPadY; // pad number on Y + Int_t iqpad = Int_t(mPad->fQpad*kScale);// charge per pad +// Int_t iqpad = mPad->fQpad; // charge per pad +// +// + + if (cathode != (icat+1)) continue; + // fill the info array + Float_t thex, they; + segmentation=iChamber->GetSegmentationModel(cathode); + segmentation->GetPadCxy(ipx,ipy,thex,they); + Float_t rpad=TMath::Sqrt(thex*thex+they*they); + if (rpad < rmin || iqpad ==0 || rpad > rmax) continue; + + new((*p_adr)[countadr++]) TVector(2); + TVector &trinfo=*((TVector*) (*p_adr)[countadr-1]); + trinfo(0)=(Float_t)track; + trinfo(1)=(Float_t)iqpad; + + digits[0]=ipx; + digits[1]=ipy; + digits[2]=iqpad; + digits[3]=iqpad; + if (mHit->fParticle == kMuonPlus || mHit->fParticle == kMuonMinus) { + digits[4]=mPad->fHitNumber; + } else digits[4]=-1; + + AliMUONlist* pdigit; + // build the list of fired pads and update the info + if (!HitMap[nch]->TestHit(ipx, ipy)) { + + list->AddAtAndExpand( + new AliMUONlist(nch,digits),counter); + + HitMap[nch]->SetHit(ipx, ipy, counter); + counter++; + pdigit=(AliMUONlist*)list->At(list->GetLast()); + // list of tracks + TObjArray *trlist=(TObjArray*)pdigit->TrackList(); + trlist->Add(&trinfo); + } else { + pdigit=(AliMUONlist*) HitMap[nch]->GetHit(ipx, ipy); + // update charge + (*pdigit).fSignal+=iqpad; + (*pdigit).fPhysics+=iqpad; + // update list of tracks + TObjArray* trlist=(TObjArray*)pdigit->TrackList(); + Int_t last_entry=trlist->GetLast(); + TVector *ptrk_p=(TVector*)trlist->At(last_entry); + TVector &ptrk=*ptrk_p; + Int_t last_track=Int_t(ptrk(0)); + Int_t last_charge=Int_t(ptrk(1)); + if (last_track==track) { + last_charge+=iqpad; + trlist->RemoveAt(last_entry); + trinfo(0)=last_track; + trinfo(1)=last_charge; + trlist->AddAt(&trinfo,last_entry); + } else { + trlist->Add(&trinfo); + } + // check the track list + Int_t nptracks=trlist->GetEntriesFast(); + if (nptracks > 2) { + for (Int_t tr=0;trAt(tr); + TVector &pptrk=*pptrk_p; + trk[tr]=Int_t(pptrk(0)); + chtrk[tr]=Int_t(pptrk(1)); + } + } // end if nptracks + } // end if pdigit + } //end loop over clusters + } // hit loop + } // track loop + + //Int_t nentr1=list->GetEntriesFast(); + //printf(" \n counter, nentr1 %d %d\n",counter,nentr1); + + // open the file with background + + if (Add ) { + ntracks =(Int_t)TH1->GetEntries(); + //printf("background - icat,ntracks1 %d %d\n",icat,ntracks); + //printf("background - Start loop over tracks \n"); +// +// Loop over tracks +// + for (Int_t track=0; trackClear(); + if (fClusters2) fClusters2->Clear(); + + TH1->GetEvent(track); +// +// Loop over hits + AliMUONhit* mHit; + for(int i=0;iGetEntriesFast();++i) + { + mHit=(AliMUONhit*) (*fHits2)[i]; + Int_t nch = mHit->fChamber-1; // chamber number + if (nch >9) continue; + iChamber = &(MUON->Chamber(nch)); + Int_t rmin = (Int_t)iChamber->RInner(); + Int_t rmax = (Int_t)iChamber->ROuter(); + Float_t xbgr=mHit->fX; + Float_t ybgr=mHit->fY; + Bool_t cond=false; + + for (Int_t imuon =0; imuon < nmuon[nch]; imuon++) { + Float_t dist= (xbgr-xhit[nch][imuon])*(xbgr-xhit[nch][imuon]) + +(ybgr-yhit[nch][imuon])*(ybgr-yhit[nch][imuon]); + if (dist<100) cond=true; + } + if (!cond) continue; + +// +// Loop over pad hits + //for(int j=0;jGetEntriesFast();++j) + for (AliMUONcluster* mPad= + (AliMUONcluster*)MUON->FirstPad(mHit,fClusters2); + mPad; + mPad=(AliMUONcluster*)MUON->NextPad(fClusters2)) + { + // mPad = (AliMUONcluster*) (*fClusters2)[j]; + Int_t cathode = mPad->fCathode; // cathode number + Int_t ipx = mPad->fPadX; // pad number on X + Int_t ipy = mPad->fPadY; // pad number on Y + Int_t iqpad = Int_t(mPad->fQpad*kScale);// charge per pad +// Int_t iqpad = mPad->fQpad; // charge per pad + + if (cathode != (icat+1)) continue; +// if (!HitMap[nch]->CheckBoundary()) continue; + // fill the info array + Float_t thex, they; + segmentation=iChamber->GetSegmentationModel(cathode); + segmentation->GetPadCxy(ipx,ipy,thex,they); + Float_t rpad=TMath::Sqrt(thex*thex+they*they); + if (rpad < rmin || iqpad ==0 || rpad > rmax) continue; + + new((*p_adr)[countadr++]) TVector(2); + TVector &trinfo=*((TVector*) (*p_adr)[countadr-1]); + trinfo(0)=-1; // tag background + trinfo(1)=-1; + + digits[0]=ipx; + digits[1]=ipy; + digits[2]=iqpad; + digits[3]=0; + digits[4]=-1; + + AliMUONlist* pdigit; + // build the list of fired pads and update the info + if (!HitMap[nch]->TestHit(ipx, ipy)) { + list->AddAtAndExpand(new AliMUONlist(nch,digits),counter); + + HitMap[nch]->SetHit(ipx, ipy, counter); + counter++; + + pdigit=(AliMUONlist*)list->At(list->GetLast()); + // list of tracks + TObjArray *trlist=(TObjArray*)pdigit-> + TrackList(); + trlist->Add(&trinfo); + } else { + pdigit=(AliMUONlist*) HitMap[nch]->GetHit(ipx, ipy); + // update charge + (*pdigit).fSignal+=iqpad; + + // update list of tracks + TObjArray* trlist=(TObjArray*)pdigit-> + TrackList(); + Int_t last_entry=trlist->GetLast(); + TVector *ptrk_p=(TVector*)trlist-> + At(last_entry); + TVector &ptrk=*ptrk_p; + Int_t last_track=Int_t(ptrk(0)); + if (last_track==-1) { + continue; + } else { + trlist->Add(&trinfo); + } + // check the track list + Int_t nptracks=trlist->GetEntriesFast(); + if (nptracks > 0) { + for (Int_t tr=0;trAt(tr); + TVector &pptrk=*pptrk_p; + trk[tr]=Int_t(pptrk(0)); + chtrk[tr]=Int_t(pptrk(1)); + } + } // end if nptracks + } // end if pdigit + } //end loop over clusters + } // hit loop + } // track loop + //Int_t nentr2=list->GetEntriesFast(); + //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2); + TTree *fAli=gAlice->TreeK(); + TFile *file; + + if (fAli) file =fAli->GetCurrentFile(); + file->cd(); + } // if Add + + Int_t tracks[10]; + Int_t charges[10]; + //cout<<"start filling digits \n "<GetEntriesFast(); + //printf(" \n \n nentries %d \n",nentries); + // start filling the digits + + for (Int_t nent=0;nentAt(nent); + if (address==0) continue; + Int_t ich=address->fChamber; + Int_t q=address->fSignal; + iChamber=(AliMUONchamber*) (*fChambers)[ich]; + AliMUONresponse * response=iChamber->GetResponseModel(); + Int_t adcmax= (Int_t) response->MaxAdc(); + // add white noise and do zero-suppression and signal truncation + Float_t MeanNoise = gRandom->Gaus(1, 0.2); + Float_t Noise = gRandom->Gaus(0, MeanNoise); + q+=(Int_t)Noise; + if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise; + if ( q <= zero_supm ) continue; + if ( q > adcmax) q=adcmax; + digits[0]=address->fPadX; + digits[1]=address->fPadY; + digits[2]=q; + digits[3]=address->fPhysics; + digits[4]=address->fHit; + //printf("fSignal, fPhysics fTrack %d %d %d \n",digits[2],digits[3],digits[4]); + + TObjArray* trlist=(TObjArray*)address->TrackList(); + Int_t nptracks=trlist->GetEntriesFast(); + //printf("nptracks, trlist %d %p\n",nptracks,trlist); + + // this was changed to accomodate the real number of tracks + if (nptracks > 10) { + cout<<"Attention - nptracks > 10 "< 2) { + printf("Attention - nptracks > 2 %d \n",nptracks); + printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q); + } + for (Int_t tr=0;trAt(tr); + if(!pp_p ) printf("pp_p - %p\n",pp_p); + TVector &pp =*pp_p; + tracks[tr]=Int_t(pp(0)); + charges[tr]=Int_t(pp(1)); + //printf("tracks, charges - %d %d\n",tracks[tr],charges[tr]); + } //end loop over list of tracks for one pad + // Sort list of tracks according to charge + if (nptracks > 1) { + SortTracks(tracks,charges,nptracks); + } + if (nptracks < 10 ) { + for (Int_t i=nptracks; i<10; i++) { + tracks[i]=0; + charges[i]=0; + } + } + + // fill digits + MUON->AddDigits(ich,tracks,charges,digits); + // delete trlist; +// delete address; + } + //cout<<"I'm out of the loops for digitisation"<GetEvent(nev); + gAlice->TreeD()->Fill(); + //TTree *TD=gAlice->TreeD(); + /* + Stat_t ndig=TD->GetEntries(); + cout<<"number of digits "<DigitsAddress(i); + int ndig=fDch->GetEntriesFast(); + printf (" i, ndig %d %d \n",i,ndig); + } + */ + MUON->ResetDigits(); + list->Delete(); + //printf("Here\n"); + for(Int_t i=0;i<10;++i) { + if (HitMap[i]) { + hm=HitMap[i]; + delete hm; + HitMap[i]=0; } - printf("===> %d Clusters\n",nclust); - } // for icat + } + + } //end loop over cathodes + + char hname[30]; + sprintf(hname,"TreeD%d",nev); + gAlice->TreeD()->Write(hname); + // reset tree + gAlice->TreeD()->Reset(); + delete list; + //Int_t nadr=p_adr->GetEntriesFast(); + // printf(" \n \n nadr %d \n",nadr); + + // start filling the digits + /* + for (Int_t nent=0;nentAt(nent); + pv->Delete(); + //delete pv; + } + */ + p_adr->Clear(); + // gObjectTable->Print(); + +} + +void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr) +{ + // + // Sort the list of tracks contributing to a given digit + // Only the 3 most significant tracks are acctually sorted + // + + // + // Loop over signals, only 3 times + // + + Int_t qmax; + Int_t jmax; + Int_t idx[3] = {-2,-2,-2}; + Int_t jch[3] = {-2,-2,-2}; + Int_t jtr[3] = {-2,-2,-2}; + Int_t i,j,imax; + + if (ntr<3) imax=ntr; + else imax=3; + for(i=0;i qmax) { + qmax = charges[j]; + jmax=j; + } + } + + if(qmax > 0) { + idx[i]=jmax; + jch[i]=charges[jmax]; + jtr[i]=tracks[jmax]; + } + + } + + for(i=0;i<3;i++){ + if (jtr[i] == -2) { + charges[i]=0; + tracks[i]=0; + } else { + charges[i]=jch[i]; + tracks[i]=jtr[i]; + } + } + } +void AliMUON::FindClusters(Int_t nev,Int_t last_entry) +{ + +// +// Loop on chambers and on cathode planes +// + for (Int_t icat=0;icat<2;icat++) { + gAlice->ResetDigits(); + gAlice->TreeD()->GetEvent(last_entry+icat); // spurious +1 ... + if (nev < 10) printf("last_entry , icat - %d %d \n",last_entry,icat); + //gAlice->TreeD()->GetEvent(icat+1); // spurious +1 ... + + for (Int_t ich=0;ich<10;ich++) { + AliMUONchamber* iChamber=(AliMUONchamber*) (*fChambers)[ich]; + TClonesArray *MUONdigits = this->DigitsAddress(ich); + if (MUONdigits == 0) continue; + // + // Get ready the current chamber stuff + // + AliMUONresponse* response = iChamber->GetResponseModel(); + AliMUONsegmentation* seg = iChamber->GetSegmentationModel(icat+1); + AliMUONClusterFinder* rec = iChamber->GetReconstructionModel(); +// if (icat==1 && (ich==4 || ich==5)) continue; +// printf("icat, ich, seg - %d %d %p\n",icat,ich,seg); + if (seg) { + rec->SetSegmentation(seg); + rec->SetResponse(response); + rec->SetDigits(MUONdigits); + rec->SetChamber(ich); + if (nev==0) rec->CalibrateCOG(); +// rec->CalibrateCOG(); + rec->FindRawClusters(); + } + //printf("Finish FindRawClusters for cathode %d in chamber %d\n",icat,ich); + + TClonesArray *fRch; + fRch=RawClustAddress(ich); + fRch->Sort(); + // it seems to work + + + } // for ich + // fill the tree + //TTree *TR=gAlice->TreeR(); + + gAlice->TreeR()->Fill(); + /* + Stat_t nent=TR->GetEntries(); + cout<<"number of entries "<GetEntriesFast(); + printf (" i, nraw %d %d \n",i,nraw); + } + */ + ResetRawClusters(); + + } // for icat + + char hname[30]; + sprintf(hname,"TreeR%d",nev); + gAlice->TreeR()->Write(hname); + gAlice->TreeR()->Reset(); + + //gObjectTable->Print(); + +} //______________________________________________________________________________ +//_____________________________________________________________________________ +void AliMUON::CathodeCorrelation(Int_t nev) +{ + +// Correlates the clusters on the two cathode planes and build a list of +// other possible combinations (potential ghosts) - for the moment use the +// criteria of minimum distance between the CoGs of the two correlated +// clusters + + +// +// Loop on chambers and on clusters on the cathode plane with the highest +// number of clusters + + static Bool_t first=true; + + AliMUONRawCluster *mRaw1; + AliMUONRawCluster *mRaw2; + AliMUONchamber *iChamber; + AliMUONsegmentation *seg; + TArrayF x1, y1, x2, y2, q1, q2; + x1.Set(5000); + x2.Set(5000); + y1.Set(5000); + y2.Set(5000); + q1.Set(5000); + q2.Set(5000); + +// Get pointers to Alice detectors and Digits containers + TTree *TR = gAlice->TreeR(); + Int_t nent=(Int_t)TR->GetEntries(); + if (nev < 10) printf("Found %d entries in the tree (must be one per cathode per event! + 1empty)\n",nent); + + + Int_t idx[4]; + Float_t xc2[4],yc2[4]; + Float_t xrec2, yrec2; + Float_t xd0, xdif, ydif; + Float_t ysrch,xd,xmax,ymax; + Int_t ilow, iup, iraw1; + // + Float_t xarray[50]; + Float_t xdarray[50]; + Float_t yarray[50]; + Float_t qarray[50]; + Int_t idx2[50]; + + // Int_t nraw[2], entry,cathode; + + for (int i=0;i<50;i++) { + xdarray[i]=1100.; + xarray[i]=0.; + yarray[i]=0.; + qarray[i]=0.; + idx2[i]=-1; + } + for (int i=0;i<4;i++) { + idx[i]=-1; + xc2[i]=0.; + yc2[i]=0.; + } + + // access to the Raw Clusters tree + for (Int_t ich=0;ich<10;ich++) { + iChamber = &(Chamber(ich)); + TClonesArray *MUONrawclust = RawClustAddress(ich); + ResetRawClusters(); + TR->GetEvent(nent-2); + //TR->GetEvent(1); + Int_t nrawcl1 = MUONrawclust->GetEntries(); + // printf("Found %d raw clusters for cathode 1 in chamber %d \n" + // ,nrawcl1,ich+1); + if (!nrawcl1) continue; + + seg = iChamber->GetSegmentationModel(1); + // loop over raw clusters of first cathode + for (iraw1=0; iraw1UncheckedAt(iraw1); + x1[iraw1]=mRaw1->fX; + y1[iraw1]=mRaw1->fY; + q1[iraw1]=(Float_t)mRaw1->fQ; //maybe better fPeakSignal + } // rawclusters cathode 1 +// + // Get information from 2nd cathode + ResetRawClusters(); + TR->GetEvent(nent-1); + //TR->GetEvent(2); + Int_t nrawcl2 = MUONrawclust->GetEntries(); + if (!nrawcl2) { + for (iraw1=0; iraw1UncheckedAt(iraw2); + x2[iraw2]=mRaw2->fX; + y2[iraw2]=mRaw2->fY; + q2[iraw2]=(Float_t)mRaw2->fQ; + } // rawclusters cathode 2 +// +// Initalisation finished + for (iraw1=0; iraw1GetPadIxy(x1[iraw1],y1[iraw1],ix,iy); + Int_t isec=seg->Sector(ix,iy); + // range to look for ghosts ?! + if (ich < 5) { + ymax = seg->Dpy(isec)*7/2; + xmax = seg->Dpx(isec)*7/2; + } else { + ymax = seg->Dpy(isec)*13/2; + xmax = seg->Dpx(isec)*3/2; + } + ysrch=ymax+y1[iraw1]; + + ilow = AliMUONRawCluster:: + BinarySearch(ysrch-2*ymax,y2,0,nrawcl2+1); + iup= AliMUONRawCluster:: + BinarySearch(ysrch,y2,ilow,nrawcl2+1); + if (ilow<0 || iup <0 || iup>nrawcl2) continue; + Int_t counter=0; + for (Int_t iraw2=ilow; iraw2<=iup; iraw2++) { + xrec2=x2[iraw2]; + yrec2=y2[iraw2]; + xdif=x1[iraw1]-xrec2; + ydif=y1[iraw1]-yrec2; + xd=TMath::Sqrt(xdif*xdif+ydif*ydif); + if (iraw2==ilow) { + if (ilow==iup) + xd0=TMath:: + Sqrt(2*xmax*2*xmax+2*ymax*2*ymax); + else xd0=101.; + } + Float_t qdif=TMath::Abs(q1[iraw1]-q2[iraw2])/q1[iraw1]; + + if (x1[iraw1]*xrec2 > 0) { + if (xd <= xd0 ) { +// printf("q1, q2 qdif % f %f %f \n",q1[iraw1],q2[iraw2],qdif); +// printf("x1, x2 y1 y2 % f %f %f %f \n",x1[iraw1],xrec2,y1[iraw1],yrec2); + //if (qdif <0.3) { //check this number + + xd0=xd; + idx2[counter]=iraw2; + xdarray[counter]=xd; + xarray[counter]=xdif; + yarray[counter]=ydif; + qarray[counter]=qdif; + counter++; + // } + + } + } // check for same quadrant + } // loop over 2nd cathode range + + + if (counter >=2) { + AliMUONRawCluster:: + SortMin(idx2,xdarray,xarray,yarray,qarray,counter); + if (xdarray[0]Dpx(isec) && xdarray[1]Dpx(isec)) { + if (qarray[0]>qarray[1]){ + Int_t swap=idx2[0]; + idx2[0]=idx2[1]; + idx2[1]=swap; + } + } + } + int imax; + if (counter <3) imax=counter; + else imax=3; + + for (int i=0;i= 0 && idx2[i] < nrawcl2) { + if (xarray[i] > xmax || yarray[i] > 2*ymax) + continue; + idx[i]=idx2[i]; + xc2[i]=x2[idx2[i]]; + yc2[i]=y2[idx2[i]]; + } + } + // add info about the cluster on the 'starting' cathode + + idx[3]=iraw1; + xc2[3]=x1[iraw1]; + yc2[3]=y1[iraw1]; + //if (idx[0] <0) printf("iraw1 imax idx2[0] idx[0] %d %d %d %d\n",iraw1,imax,idx2[0],idx[0]); + AddCathCorrel(ich,idx,xc2,yc2); + // reset + for (int i=0;iFill(); + //Int_t nentries=(Int_t)TC->GetEntries(); + //cout<<"number entries in tree of correlated clusters "<GetEntriesFast(); + printf (" i, ncor %d %d \n",i,ncor); + if (ncor>=2) countch++; + } + + // write + char hname[30]; + sprintf(hname,"TreeC%d",nev); + TC->Write(hname); + // reset tree + ResetCorrelation(); + TC->Reset(); + + if (countch==10) countev++; + printf("countev - %d\n",countev); + +// gObjectTable->Print(); + + +} + + +//_____________________________________________________________________________ + +void AliMUON::MakeTreeC(Option_t *option) +{ + char *C = strstr(option,"C"); + if (C && !fTreeC) fTreeC = new TTree("TC","CathodeCorrelation"); + +// Create a branch for correlation + + const Int_t buffersize = 4000; + char branchname[30]; + +// one branch for correlation per chamber + for (int i=0; i<10 ;i++) { + sprintf(branchname,"%sCorrelation%d",GetName(),i+1); + + if (fCathCorrel && fTreeC) { + TreeC()->Branch(branchname,&((*fCathCorrel)[i]), buffersize); + printf("Making Branch %s for correlation in chamber %d\n",branchname,i+1); + } + } +} + +//_____________________________________________________________________________ +void AliMUON::GetTreeC(Int_t event) +{ + + // set the branch address + char treeName[20]; + char branchname[30]; + + ResetCorrelation(); + if (fTreeC) { + delete fTreeC; + } + + sprintf(treeName,"TreeC%d",event); + fTreeC = (TTree*)gDirectory->Get(treeName); + + + TBranch *branch; + if (fTreeC) { + for (int i=0; i<10; i++) { + sprintf(branchname,"%sCorrelation%d",GetName(),i+1); + if (fCathCorrel) { + branch = fTreeC->GetBranch(branchname); + if (branch) branch->SetAddress(&((*fCathCorrel)[i])); + } + } + } else { + printf("ERROR: cannot find CathodeCorrelation Tree for event:%d\n",event); + } + + // gObjectTable->Print(); + +} + + void AliMUON::Streamer(TBuffer &R__b) { // Stream an object of class AliMUON. @@ -568,6 +1631,9 @@ void AliMUON::Streamer(TBuffer &R__b) AliMUONsegmentation *segmentation; AliMUONresponse *response; TClonesArray *digitsaddress; + TClonesArray *rawcladdress; + TClonesArray *corcladdress; + // TObjArray *clustaddress; if (R__b.IsReading()) { Version_t R__v = R__b.ReadVersion(); if (R__v) { } @@ -575,12 +1641,23 @@ void AliMUON::Streamer(TBuffer &R__b) R__b >> fNclusters; R__b >> fClusters; // diff R__b >> fDchambers; + R__b >> fRawClusters; + R__b >> fCathCorrel; R__b.ReadArray(fNdch); + R__b.ReadArray(fNrawch); + R__b.ReadArray(fNcorch); + // R__b >> fRecClusters; // R__b >> fAccCut; R__b >> fAccMin; R__b >> fAccMax; // + // modifs perso + R__b >> fSPxzCut; + R__b >> fSSigmaCut; + R__b >> fSXPrec; + R__b >> fSYPrec; + // R__b >> fChambers; // Stream chamber related information for (Int_t i =0; i<10; i++) { @@ -599,6 +1676,10 @@ void AliMUON::Streamer(TBuffer &R__b) response->Streamer(R__b); digitsaddress=(TClonesArray*) (*fDchambers)[i]; digitsaddress->Streamer(R__b); + rawcladdress=(TClonesArray*) (*fRawClusters)[i]; + rawcladdress->Streamer(R__b); + corcladdress=(TClonesArray*) (*fCathCorrel)[i]; + corcladdress->Streamer(R__b); } } else { @@ -607,14 +1688,31 @@ void AliMUON::Streamer(TBuffer &R__b) R__b << fNclusters; R__b << fClusters; // diff R__b << fDchambers; + R__b << fRawClusters; + R__b << fCathCorrel; R__b.WriteArray(fNdch, 10); + R__b.WriteArray(fNrawch, 10); + R__b.WriteArray(fNcorch, 10); + // R__b << fRecClusters; // R__b << fAccCut; R__b << fAccMin; R__b << fAccMax; // + // modifs perso + R__b << fSPxzCut; + R__b << fSSigmaCut; + R__b << fSXPrec; + R__b << fSYPrec; + // R__b << fChambers; // Stream chamber related information + /* + for (Int_t i =0; i<20; i++) { + clustaddress=(TObjArray*) (*fRecClusters)[i]; + clustaddress->Streamer(R__b); + } + */ for (Int_t i =0; i<10; i++) { iChamber=(AliMUONchamber*) (*fChambers)[i]; iChamber->Streamer(R__b); @@ -629,38 +1727,1298 @@ void AliMUON::Streamer(TBuffer &R__b) } response=iChamber->GetResponseModel(); response->Streamer(R__b); - digitsaddress=(TClonesArray*) (*fDchambers)[i]; digitsaddress->Streamer(R__b); + rawcladdress=(TClonesArray*) (*fRawClusters)[i]; + rawcladdress->Streamer(R__b); + corcladdress=(TClonesArray*) (*fCathCorrel)[i]; + corcladdress->Streamer(R__b); } } } -AliMUONcluster* AliMUON::FirstPad(AliMUONhit* hit) +AliMUONcluster* AliMUON::FirstPad(AliMUONhit* hit, TClonesArray *clusters) { // // Initialise the pad iterator // Return the address of the first padhit for hit - TClonesArray *theClusters = Clusters(); + TClonesArray *theClusters = clusters; Int_t nclust = theClusters->GetEntriesFast(); if (nclust && hit->fPHlast > 0) { sMaxIterPad=hit->fPHlast; sCurIterPad=hit->fPHfirst; - return (AliMUONcluster*) fClusters->UncheckedAt(sCurIterPad-1); + return (AliMUONcluster*) clusters->UncheckedAt(sCurIterPad-1); } else { return 0; } } -AliMUONcluster* AliMUON::NextPad() +AliMUONcluster* AliMUON::NextPad(TClonesArray *clusters) { sCurIterPad++; if (sCurIterPad <= sMaxIterPad) { - return (AliMUONcluster*) fClusters->UncheckedAt(sCurIterPad-1); + return (AliMUONcluster*) clusters->UncheckedAt(sCurIterPad-1); } else { return 0; } } +//////////////////////////// modifs perso /////////////// + +static TTree *ntuple_global; +static TFile *hfile_global; + +// variables of the tracking ntuple +struct { + Int_t ievr; // number of event + Int_t ntrackr; // number of tracks per event + Int_t istatr[500]; // 1 = good muon, 2 = ghost, 0 = something else + Int_t isignr[500]; // sign of the track + Float_t pxr[500]; // x momentum of the reconstructed track + Float_t pyr[500]; // y momentum of the reconstructed track + Float_t pzr[500]; // z momentum of the reconstructed track + Float_t zvr[500]; // z vertex + Float_t chi2r[500]; // chi2 of the fit of the track with the field map + Float_t pxv[500]; // x momentum at vertex + Float_t pyv[500]; // y momentum at vertex + Float_t pzv[500]; // z momentum at vertex +} ntuple_st; + +AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster) +{ + TClonesArray *MUONrawclust = RawClustAddress(ichamber); + ResetRawClusters(); + TTree *TR = gAlice->TreeR(); + Int_t nent=(Int_t)TR->GetEntries(); + TR->GetEvent(nent-2+icathod-1); + //TR->GetEvent(icathod); + //Int_t nrawcl = (Int_t)MUONrawclust->GetEntriesFast(); + + AliMUONRawCluster * mRaw = (AliMUONRawCluster*)MUONrawclust->UncheckedAt(icluster); + //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw); + + return mRaw; +} + +void AliMUON::Reconst(Int_t &ifit, Int_t &idebug, Int_t bgd_ev, Int_t &nev, Int_t &idres, Int_t &ireadgeant, Option_t *option,Text_t *filename) +{ + // + // open kine and hits tree of background file for reconstruction of geant hits + // call tracking fortran program + static Bool_t first=true; + static TFile *File; + char *Add = strstr(option,"Add"); + + if (Add ) { // only in case of background with geant hits + if(first) { + fFileName=filename; + cout<<"filename "<cd(); + if(fHits2) fHits2->Clear(); + if(fParticles2) fParticles2->Clear(); + if(TH1) delete TH1; + TH1=0; + if(TK1) delete TK1; + TK1=0; + // Get Hits Tree header from file + char treeName[20]; + sprintf(treeName,"TreeH%d",bgd_ev); + TH1 = (TTree*)gDirectory->Get(treeName); + if (!TH1) { + printf("ERROR: cannot find Hits Tree for event:%d\n",bgd_ev); + } + // set branch addresses + TBranch *branch; + char branchname[30]; + sprintf(branchname,"%s",GetName()); + if (TH1 && fHits2) { + branch = TH1->GetBranch(branchname); + if (branch) branch->SetAddress(&fHits2); + } + TH1->GetEntries(); + // get the Kine tree + sprintf(treeName,"TreeK%d",bgd_ev); + TK1 = (TTree*)gDirectory->Get(treeName); + if (!TK1) { + printf("ERROR: cannot find Kine Tree for event:%d\n",bgd_ev); + } + // set branch addresses + if (TK1) + TK1->SetBranchAddress("Particles", &fParticles2); + TK1->GetEvent(0); + + // get back to the first file + TTree *TK = gAlice->TreeK(); + TFile *file1 = 0; + if (TK) file1 = TK->GetCurrentFile(); + file1->cd(); + + } // end if Add + + // call tracking fortran program + reconstmuon(ifit,idebug,nev,idres,ireadgeant); +} + + +void AliMUON::Init(Double_t &seff, Double_t &sb0, Double_t &sbl3) +{ + // + // introduce in fortran program somme parameters and cuts for tracking + // create output file "reconst.root" (histos + ntuple) + cutpxz(fSPxzCut); // Pxz cut (GeV/c) to begin the track finding + sigmacut(fSSigmaCut); // Number of sigmas delimiting the searching areas + xpreci(fSXPrec); // Chamber precision in X (cm) + ypreci(fSYPrec); // Chamber precision in Y (cm) + reco_init(seff,sb0,sbl3); +} + +void AliMUON::FinishEvent() +{ + TTree *TK = gAlice->TreeK(); + TFile *file1 = 0; + if (TK) file1 = TK->GetCurrentFile(); + file1->cd(); +} + +void AliMUON::Close() +{ + // + // write histos and ntuple to "reconst.root" file + reco_term(); +} + +void chfill(Int_t &id, Float_t &x, Float_t &y, Float_t &w) +{ + // + // fill histo like hfill in fortran + char name[5]; + sprintf(name,"h%d",id); + TH1F *h1 = (TH1F*) gDirectory->Get(name); + h1->Fill(x); +} + +void chfill2(Int_t &id, Float_t &x, Float_t &y, Float_t &w) +{ + // + // fill histo like hfill2 in fortran + char name[5]; + sprintf(name,"h%d",id); + TH2F *h2 = (TH2F*) gDirectory->Get(name); + h2->Fill(x,y,w); +} + +void chf1(Int_t &id, Float_t &x, Float_t &w) +{ + // + // fill histo like hf1 in fortran + char name[5]; + sprintf(name,"h%d",id); + TH1F *h1 = (TH1F*) gDirectory->Get(name); + h1->Fill(x,w); +} + +void hist_create() +{ + // + // Create an output file ("reconst.root") + // Create some histograms and an ntuple + + hfile_global = new TFile("reconst.root","RECREATE","Ntuple - reconstruction"); + + ntuple_global = new TTree("ntuple","Reconst ntuple"); + ntuple_global->Branch("ievr",&ntuple_st.ievr,"ievr/I"); + ntuple_global->Branch("ntrackr",&ntuple_st.ntrackr,"ntrackr/I"); + ntuple_global->Branch("istatr",&ntuple_st.istatr[0],"istatr[500]/I"); + ntuple_global->Branch("isignr",&ntuple_st.isignr[0],"isignr[500]/I"); + ntuple_global->Branch("pxr",&ntuple_st.pxr[0],"pxr[500]/F"); + ntuple_global->Branch("pyr",&ntuple_st.pyr[0],"pyr[500]/F"); + ntuple_global->Branch("pzr",&ntuple_st.pzr[0],"pzr[500]/F"); + ntuple_global->Branch("zvr",&ntuple_st.zvr[0],"zvr[500]/F"); + ntuple_global->Branch("chi2r",&ntuple_st.chi2r[0],"chi2r[500]/F"); + ntuple_global->Branch("pxv",&ntuple_st.pxv[0],"pxv[500]/F"); + ntuple_global->Branch("pyv",&ntuple_st.pyv[0],"pyv[500]/F"); + ntuple_global->Branch("pzv",&ntuple_st.pzv[0],"pzv[500]/F"); + + // test aliroot + + new TH1F("h100","particule id du hit geant",20,0.,20.); + new TH1F("h101","position en x du hit geant",100,-200.,200.); + new TH1F("h102","position en y du hit geant",100,-200.,200.); + new TH1F("h103","chambre de tracking concernee",15,0.,14.); + new TH1F("h104","moment ptot du hit geant",50,0.,100.); + new TH1F("h105","px au vertex",50,0.,20.); + new TH1F("h106","py au vertex",50,0.,20.); + new TH1F("h107","pz au vertex",50,0.,20.); + new TH1F("h108","position zv",50,-15.,15.); + new TH1F("h109","position en x du hit reconstruit",100,-300.,300.); + new TH1F("h110","position en y du hit reconstruit",100,-300.,300.); + new TH1F("h111","delta x ",100,-0.4,0.4); + new TH1F("h112","delta y ",100,-0.4,0.4); + + char hname[30]; + char hname1[30]; + for (int i=0;i<10;i++) { + sprintf(hname,"deltax%d",i); + sprintf(hname1,"h12%d",i); + new TH1F(hname1,hname ,100,-0.4,0.4); + sprintf(hname,"deltay%d",i); + sprintf(hname1,"h13%d",i); + new TH1F(hname1,hname ,100,-0.4,0.4); + } + new TH2F("h2000","VAR X st. 5",30,3.0,183.0,100,0.,25.); + new TH2F("h2001","VAR Y st. 5",30,3.0,183.0,100,0.,25.); + + new TH2F("h2500","P vs X HHIT",30,3.0,183.0,200,0.,200.); + new TH2F("h2501","P vs X HHIT**2",30,3.0,183.0,200,0.,5000.); + new TH2F("h2502","P vs X EPH2 st. 5",30,3.0,183.0,100,0.,0.000005); + new TH2F("h2503","P vs X EAL2 st. 5",30,3.0,183.0,100,0.,0.01); + //new TH2F("h2504","P vs X EXM2 st. 5",30,3.0,183.0,100,0.,1.5); + new TH2F("h2504","P vs X EXM2 st. 5",30,3.0,183.0,100,0.,0.1); + new TH2F("h2505","P vs X EYM2 st. 5",30,3.0,183.0,100,0.,30.); + + new TH2F("h2507","P vs X EPH st. 5",30,3.0,183.0,100,0.,0.003); + new TH2F("h2508","P vs X EAL st. 5",30,3.0,183.0,100,0.,0.3); + //new TH2F("h2509","P vs X EXM st. 5",30,3.0,183.0,100,0.,1.5); + new TH2F("h2509","P vs X EXM st. 5",30,3.0,183.0,100,0.,0.4); + new TH2F("h2510","P vs X EYM st. 5",30,3.0,183.0,100,0.,30.); + + new TH2F("h2511","P vs X EPH cut st. 5",30,3.0,183.0,100,0.,0.01); + new TH2F("h2512","P vs X EAL cut st. 5",30,3.0,183.0,100,0.,0.3); + //new TH2F("h2513","P vs X EXM cut st. 5",30,3.0,183.0,100,0.,1.5); + new TH2F("h2513","P vs X EXM cut st. 5",30,3.0,183.0,100,0.,0.4); + new TH2F("h2514","P vs X EYM cut st. 5",30,3.0,183.0,100,0.,30.); + // 4 + new TH2F("h2400","P vs X HHIT",30,3.0,183.0,200,0.,200.); + new TH2F("h2401","P vs X HHIT**2",30,3.0,183.0,200,0.,5000.); + new TH2F("h2402","P vs X EPH2 st. 4",30,3.0,183.0,100,0.,0.000005); + new TH2F("h2403","P vs X EAL2 st. 4",30,3.0,183.0,100,0.,0.05); + //new TH2F("h2404","P vs X EXM2 st. 4",30,3.0,183.0,100,0.,1.5); + new TH2F("h2404","P vs X EXM2 st. 4",30,3.0,183.0,100,0.,0.1); + new TH2F("h2405","P vs X EYM2 st. 4",30,3.0,183.0,100,0.,30.); + + new TH2F("h2407","P vs X EPH st. 4",30,3.0,183.0,100,0.,0.003); + new TH2F("h2408","P vs X EAL st. 4",30,3.0,183.0,100,0.,0.3); + //new TH2F("h2409","P vs X EXM st. 4",30,3.0,183.0,100,0.,1.5); + new TH2F("h2409","P vs X EXM st. 4",30,3.0,183.0,100,0.,0.1); + new TH2F("h2410","P vs X EYM st. 4",30,3.0,183.0,100,0.,30.); + + new TH2F("h2411","P vs X EPH cut st. 4",30,3.0,183.0,100,0.,0.01); + new TH2F("h2412","P vs X EAL cut st. 4",30,3.0,183.0,100,0.,0.3); + //new TH2F("h2413","P vs X EXM cut st. 4",30,3.0,183.0,100,0.,1.5); + new TH2F("h2413","P vs X EXM cut st. 4",30,3.0,183.0,100,0.,0.1); + new TH2F("h2414","P vs X EYM cut st. 4",30,3.0,183.0,100,0.,30.); + // 3 + new TH1F("h2301","P2",30,3.0,183.0); + new TH2F("h2302","P2 vs X EPH2 st. 3",30,3.0,183.0,100,0.,0.0006); + new TH2F("h2303","P2 vs X EAL2 st. 3",30,3.0,183.0,100,0.,0.0005); + //new TH2F("h2304","P2 vs X EXM2 st. 3",30,3.0,183.0,100,0.,1.5); + new TH2F("h2304","P2 vs X EXM2 st. 3",30,3.0,183.0,100,0.,2.); + new TH2F("h2305","P2 vs X EYM2 st. 3",30,3.0,183.0,100,0.,3.); + + new TH2F("h2307","P vs X EPH2 st. 3",30,3.0,183.0,100,0.,0.0006); + new TH2F("h2308","P vs X EAL2 st. 3",30,3.0,183.0,100,0.,0.005); + //new TH2F("h2309","P vs X EXM2 st. 3",30,3.0,183.0,100,0.,1.5); + new TH2F("h2309","P vs X EXM2 st. 3",30,3.0,183.0,100,0.,2.); + new TH2F("h2310","P vs X EYM2 st. 3",30,3.0,183.0,100,0.,3.); + + new TH2F("h2311","P vs X EPH cut st. 3",30,3.0,183.0,100,0.,0.06); + new TH2F("h2312","P vs X EAL cut st. 3",30,3.0,183.0,100,0.,0.05); + //new TH2F("h2313","P vs X EXM cut st. 3",30,3.0,183.0,100,0.,1.5); + new TH2F("h2313","P vs X EXM cut st. 3",30,3.0,183.0,100,0.,6.); + new TH2F("h2314","P vs X EYM cut st. 3",30,3.0,183.0,100,0.,7.); + + new TH2F("h2315","P2 vs X EPH cut st. 3",30,3.0,183.0,100,0.,0.06); + new TH2F("h2316","P2 vs X EAL cut st. 3",30,3.0,183.0,100,0.,0.05); + //new TH2F("h2317","P2 vs X EXM cut st. 3",30,3.0,183.0,100,0.,1.5); + new TH2F("h2317","P2 vs X EXM cut st. 3",30,3.0,183.0,100,0.,6.); + new TH2F("h2318","P2 vs X EYM cut st. 3",30,3.0,183.0,100,0.,7.); + + // 2 + new TH1F("h2201","P2",30,3.0,183.0); + new TH2F("h2202","P2 vs X EPH2 st. 2",30,3.0,183.0,100,0.,0.0006); + new TH2F("h2203","P2 vs X EAL2 st. 2",30,3.0,183.0,100,0.,0.005); + //new TH2F("h2204","P2 vs X EXM2 st. 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2204","P2 vs X EXM2 st. 2",30,3.0,183.0,100,0.,7.); + new TH2F("h2205","P2 vs X EYM2 st. 2",30,3.0,183.0,100,0.,5.); + + new TH2F("h2207","P vs X EPH2 st. 2",30,3.0,183.0,100,0.,0.0006); + new TH2F("h2208","P vs X EAL2 st. 2",30,3.0,183.0,100,0.,0.005); + //new TH2F("h2209","P vs X EXM2 st. 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2209","P vs X EXM2 st. 2",30,3.0,183.0,100,0.,7.); + new TH2F("h2210","P vs X EYM2 st. 2",30,3.0,183.0,100,0.,5.); + + new TH2F("h2211","P vs X EPH cut st. 2",30,3.0,183.0,100,0.,0.05); + new TH2F("h2212","P vs X EAL cut st. 2",30,3.0,183.0,100,0.,0.2); + //new TH2F("h2213","P vs X EXM cut st. 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2213","P vs X EXM cut st. 2",30,3.0,183.0,100,0.,11.); + new TH2F("h2214","P vs X EYM cut st. 2",30,3.0,183.0,100,0.,10.); + + new TH2F("h2215","P2 vs X EPH cut st. 2",30,3.0,183.0,100,0.,0.05); + new TH2F("h2216","P2 vs X EAL cut st. 2",30,3.0,183.0,100,0.,0.2); + //new TH2F("h2217","P2 vs X EXM cut st. 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2217","P2 vs X EXM cut st. 2",30,3.0,183.0,100,0.,11.); + new TH2F("h2218","P2 vs X EYM cut st. 2",30,3.0,183.0,100,0.,10.); + + // 1 + new TH2F("h2102","P2 vs X EPH2 st. 2",30,3.0,183.0,100,0.,0.0006); + new TH2F("h2103","P2 vs X EAL2 st. 2",30,3.0,183.0,100,0.,0.005); + //new TH2F("h2104","P2 vs X EXM2 st. 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2104","P2 vs X EXM2 st. 2",30,3.0,183.0,100,0.,7.); + new TH2F("h2105","P2 vs X EYM2 st. 2",30,3.0,183.0,100,0.,7.); + + new TH2F("h2107","P vs X EPH2 st. 2",30,3.0,183.0,100,0.,0.0006); + new TH2F("h2108","P vs X EAL2 st. 2",30,3.0,183.0,100,0.,0.005); + //new TH2F("h2109","P vs X EXM2 st. 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2109","P vs X EXM2 st. 2",30,3.0,183.0,100,0.,7.); + new TH2F("h2110","P vs X EYM2 st. 2",30,3.0,183.0,100,0.,7.); + + new TH2F("h2111","P vs X EPH cut st. 2",30,3.0,183.0,100,0.,0.1); + new TH2F("h2112","P vs X EAL cut st. 2",30,3.0,183.0,100,0.,0.2); + //new TH2F("h2113","P vs X EXM cut st. 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2113","P vs X EXM cut st. 2",30,3.0,183.0,100,0.,11.); + new TH2F("h2114","P vs X EYM cut st. 2",30,3.0,183.0,100,0.,11.); + + new TH2F("h2115","P2 vs X EPH cut st. 2",30,3.0,183.0,100,0.,0.1); + new TH2F("h2116","P2 vs X EAL cut st. 2",30,3.0,183.0,100,0.,0.2); + //new TH2F("h2117","P2 vs X EXM cut st. 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2117","P2 vs X EXM cut st. 2",30,3.0,183.0,100,0.,11.); + new TH2F("h2118","P2 vs X EYM cut st. 2",30,3.0,183.0,100,0.,11.); + + // 2,3,4,5 + new TH1F("h2701","P2 fit 2",30,3.0,183.0); + new TH2F("h2702","P2 vs X EPH2 st. 1 fit 2",30,3.0,183.0,100,0.,0.0006); + new TH2F("h2703","P2 vs X EAL2 st. 1 fit 2",30,3.0,183.0,100,0.,0.005); + // new TH2F("h2704","P2 vs X EXM2 st. 1 fit 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2704","P2 vs X EXM2 st. 1 fit 2",30,3.0,183.0,100,0.,2.); + new TH2F("h2705","P2 vs X EYM2 st. 1 fit 2",30,3.0,183.0,100,0.,3.); + + new TH2F("h2707","P vs X EPH2 st. 1 fit 2",30,3.0,183.0,100,0.,0.0006); + new TH2F("h2708","P vs X EAL2 st. 1 fit 2",30,3.0,183.0,100,0.,0.005); + //new TH2F("h2709","P vs X EXM2 st. 1 fit 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2709","P vs X EXM2 st. 1 fit 2",30,3.0,183.0,100,0.,2.); + new TH2F("h2710","P vs X EYM2 st. 1 fit 2",30,3.0,183.0,100,0.,3.); + + new TH2F("h2711","P vs X EPH cut st. 1 fit 2",30,3.0,183.0,100,0.,0.07); + new TH2F("h2712","P vs X EAL cut st. 1 fit 2",30,3.0,183.0,100,0.,0.2); + //new TH2F("h2713","P vs X EXM cut st. 1 fit 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2713","P vs X EXM cut st. 1 fit 2",30,3.0,183.0,100,0.,6.); + new TH2F("h2714","P vs X EYM cut st. 1 fit 2",30,3.0,183.0,100,0.,7.); + + new TH2F("h2715","P2 vs X EPH cut st. 1 fit 2",30,3.0,183.0,100,0.,0.07); + new TH2F("h2716","P2 vs X EAL cut st. 1 fit 2",30,3.0,183.0,100,0.,0.2); + //new TH2F("h2717","P2 vs X EXM cut st. 1 fit 2",30,3.0,183.0,100,0.,1.5); + new TH2F("h2717","P2 vs X EXM cut st. 1 fit 2",30,3.0,183.0,100,0.,6.); + new TH2F("h2718","P2 vs X EYM cut st. 1 fit 2",30,3.0,183.0,100,0.,7.); + + // 1,3,4,5 + new TH1F("h2801","P2 fit 1",30,3.0,183.0); + new TH2F("h2802","P2 vs X EPH2 st. 2 fit 1",30,3.0,183.0,100,0.,0.0006); + new TH2F("h2803","P2 vs X EAL2 st. 2 fit 1",30,3.0,183.0,100,0.,0.005); + //new TH2F("h2804","P2 vs X EXM2 st. 2 fit 1",30,3.0,183.0,100,0.,1.5); + new TH2F("h2804","P2 vs X EXM2 st. 2 fit 1",30,3.0,183.0,100,0.,2.); + new TH2F("h2805","P2 vs X EYM2 st. 2 fit 1",30,3.0,183.0,100,0.,3.); + + new TH2F("h2807","P vs X EPH2 st. 2 fit 1",30,3.0,183.0,100,0.,0.0006); + new TH2F("h2808","P vs X EAL2 st. 2 fit 1",30,3.0,183.0,100,0.,0.005); + //new TH2F("h2809","P vs X EXM2 st. 2 fit 1",30,3.0,183.0,100,0.,1.5); + new TH2F("h2809","P vs X EXM2 st. 2 fit 1",30,3.0,183.0,100,0.,2.); + new TH2F("h2810","P vs X EYM2 st. 2 fit 1",30,3.0,183.0,100,0.,3.); + + new TH2F("h2811","P vs X EPH cut st. 2 fit 1",30,3.0,183.0,100,0.,0.05); + new TH2F("h2812","P vs X EAL cut st. 2 fit 1",30,3.0,183.0,100,0.,0.2); + //new TH2F("h2813","P vs X EXM cut st. 2 fit 1",30,3.0,183.0,100,0.,1.5); + new TH2F("h2813","P vs X EXM cut st. 2 fit 1",30,3.0,183.0,100,0.,5.); + new TH2F("h2814","P vs X EYM cut st. 2 fit 1",30,3.0,183.0,100,0.,7.); + + new TH2F("h2815","P2 vs X EPH cut st. 2 fit 1",30,3.0,183.0,100,0.,0.05); + new TH2F("h2816","P2 vs X EAL cut st. 2 fit 1",30,3.0,183.0,100,0.,0.2); + //new TH2F("h2817","P2 vs X EXM cut st. 2 fit 1",30,3.0,183.0,100,0.,1.5); + new TH2F("h2817","P2 vs X EXM cut st. 2 fit 1",30,3.0,183.0,100,0.,5.); + new TH2F("h2818","P2 vs X EYM cut st. 2 fit 1",30,3.0,183.0,100,0.,7.); + // fin de test + + new TH1F("h500","Acceptance en H st. 4",500,0.,500.); + new TH1F("h600","Acceptance en H st. 5",500,0.,500.); + new TH1F("h700","X vertex track found",200,-10.,10.); + new TH1F("h701","Y vertex track found",200,-10.,10.); + new TH1F("h800","Rap. muon gen.",100,0.,5.); + new TH1F("h801","Rap. muon gen. recons.",100,0.,5.); + new TH1F("h802","Rap. muon gen. ghost ",100,0.,5.); + new TH1F("h900","Pt muon gen.",100,0.,20.); + new TH1F("h901","Pt muon gen. recons.",100,0.,20.); + new TH1F("h902","Pt muon gen. ghost",100,0.,20.); + new TH1F("h910","phi muon gen.",100,-10.,10.); + new TH1F("h911","phi muon gen. recons.",100,-10.,10.); + new TH1F("h912","phi muon gen. ghost",100,-10.,10.); + new TH2F("h1001","Y VS X hit st. 1",300,-300.,300.,300,-300.,300.); + new TH2F("h1002","Y VS X hit st. 2",300,-300.,300.,300,-300.,300.); + new TH2F("h1003","Y VS X hit st. 3",300,-300.,300.,300,-300.,300.); + new TH2F("h1004","Y VS X hit st. 4",300,-300.,300.,300,-300.,300.); + new TH2F("h1005","Y VS X hit st. 5",300,-300.,300.,300,-300.,300.); + // Histos variance dans 4 + new TH2F("h11","VAR X st. 4",30,3.0,183.0,100,0.,2.); + new TH2F("h12","VAR Y st. 4",30,3.0,183.0,100,0.,600.); + new TH2F("h13","VAR PHI st. 4",30,3.0,183.0,100,0.,0.0001); + new TH2F("h14","VAR ALM st. 4",30,3.0,183.0,100,0.,0.05); + new TH1F("h15","P",30,3.0,183.0); + new TH1F("h411","VAR X st. 4",100,-1.42,1.42); + new TH1F("h412","VAR Y st. 4",100,-25.,25.); + new TH1F("h413","VAR PHI st. 4",100,-0.01,0.01); + new TH1F("h414","VAR ALM st. 4",100,-0.23,0.23); + // histo2 + new TH2F("h211","histo2-VAR X st. 4",30,3.0,183.0,100,0.,2.); + new TH2F("h212","histo2-VAR Y st. 4",30,3.0,183.0,100,0.,600.); + new TH1F("h213","histo2-VAR X st. 4",100,-1.42,1.42); + new TH1F("h214","histo2-VAR Y st. 4",100,-25.,25.); + new TH1F("h215","histo2-P",30,3.0,183.0); + + // Histos variance dans 2 + new TH2F("h21","VAR X st. 2",30,3.0,183.0,100,0.,3.); + new TH2F("h22","VAR Y st. 2",30,3.0,183.0,100,0.,7.); + new TH2F("h23","VAR PHI st. 2",30,3.0,183.0,100,0.,0.006); + new TH2F("h24","VAR ALM st. 2",30,3.0,183.0,100,0.,0.005); + new TH1F("h25","P",30,3.0,183.0); + new TH1F("h421","VAR X st. 2",100,-1.72,1.72); + new TH1F("h422","VAR Y st. 2",100,-2.7,2.7); + new TH1F("h423","VAR PHI st. 2",100,-0.08,0.08); + new TH1F("h424","VAR ALM st. 2",100,-0.072,0.072); + // histo2 + new TH2F("h221","histo2-VAR X st. 2",30,3.0,183.0,100,0.,3.); + new TH2F("h222","histo2-VAR Y st. 2",30,3.0,183.0,100,0.,7.); + new TH1F("h223","histo2-VAR X st. 2",100,-1.72,1.72); + new TH1F("h224","histo2-VAR Y st. 2",100,-2.7,2.7); + new TH1F("h225","histo2-P",30,3.0,183.0); + + // Histos variance dans 1 + new TH2F("h31","VAR X st. 1",30,3.0,183.0,100,0.,2.); + new TH2F("h32","VAR Y st. 1",30,3.0,183.0,100,0.,0.5); + new TH2F("h33","VAR PHI st. 1",30,3.0,183.0,100,0.,0.006); + new TH2F("h34","VAR ALM st. 1",30,3.0,183.0,100,0.,0.005); + new TH1F("h35","P",30,3.0,183.0); + new TH1F("h431","VAR X st. 1",100,-1.42,1.42); + new TH1F("h432","VAR Y st. 1",100,-0.72,0.72); + new TH1F("h433","VAR PHI st. 1",100,-0.08,0.08); + new TH1F("h434","VAR ALM st. 1",100,-0.072,0.072); + // Histos variance dans 1 + new TH2F("h41","VAR X st. 1 fit 5,4,3,2,V",30,3.0,183.0,100,0.,4.); + new TH2F("h42","VAR Y st. 1 fit 5,4,3,2,V",30,3.0,183.0,100,0.,20.); + new TH2F("h43","VAR PHI st. 1 fit 5,4,3,2,V",30,3.0,183.0,100,0.,0.005); + new TH2F("h44","VAR ALM st. 1 fit 5,4,3,2,V",30,3.0,183.0,100,0.,0.005); + new TH1F("h45","P",30,3.0,183.0); + new TH1F("h441","VAR X st. 1 fit 5,4,3,2,V",100,-2.,2.); + new TH1F("h442","VAR Y st. 1 fit 5,4,3,2,V",100,-4.5,4.5); + new TH1F("h443","VAR PHI st. 1 fit 5,4,3,2,V",100,-0.072,0.072); + new TH1F("h444","VAR ALM st. 1 fit 5,4,3,2,V",100,-0.072,0.072); + // histo2 + new TH2F("h241","histo2-VAR X st. 1 fit 5,4,3,2,V",30,3.0,183.0,100,0.,4.); + new TH2F("h242","histo2-VAR Y st. 1 fit 5,4,3,2,V",30,3.0,183.0,100,0.,20.); + new TH1F("h243","histo2-VAR X st. 1 fit 5,4,3,2,V",100,-2.,2.); + new TH1F("h244","histo2-VAR Y st. 1 fit 5,4,3,2,V",100,-4.5,4.5); + new TH1F("h245","histo2-P",30,3.0,183.0); + + // Histos variance dans 2 + new TH2F("h51","VAR X st. 2 fit 5,4,3,1,V",30,3.0,183.0,100,0.,0.5); + new TH2F("h52","VAR Y st. 2 fit 5,4,3,1,V",30,3.0,183.0,100,0.,2.); + new TH2F("h53","VAR PHI st. 2 fit 5,4,3,1,V",30,3.0,183.0,100,0.,0.005); + new TH2F("h54","VAR ALM st. 2 fit 5,4,3,1,V",30,3.0,183.0,100,0.,0.01); + new TH1F("h55","P",30,3.0,183.0); + new TH1F("h451","VAR X st. 2 fit 5,4,3,1,V",100,-0.72,0.72); + new TH1F("h452","VAR Y st. 2 fit 5,4,3,1,V",100,-1.42,1.42); + new TH1F("h453","VAR PHI st. 2 fit 5,4,3,1,V",100,-0.072,0.072); + new TH1F("h454","VAR ALM st. 2 fit 5,4,3,1,V",100,-0.1,0.1); + new TH1F("h999","PTOT",30,3.0,183.0); + // histo2 + new TH2F("h251","histo2-VAR X st. 2 fit 5,4,3,1,V",30,3.0,183.0,100,0.,0.5); + new TH2F("h252","histo2-VAR Y st. 2 fit 5,4,3,1,V",30,3.0,183.0,100,0.,2.); + new TH1F("h253","histo2-VAR X st. 2 fit 5,4,3,1,V",100,-0.72,0.72); + new TH1F("h254","histo2-VAR Y st. 2 fit 5,4,3,1,V",100,-1.42,1.42); + new TH1F("h255","histo2-P",30,3.0,183.0); + // Histos variance dans 3 + new TH2F("h61","VAR X st. 3 fit 4,5,V",30,3.0,183.0,100,0.,5.); + new TH2F("h62","VAR Y st. 3 fit 4,5,V",30,3.0,183.0,100,0.,2.); + new TH2F("h63","VAR PHI st. 3 fit 4,5,V",30,3.0,183.0,100,0.,0.0006); + new TH2F("h64","VAR ALM st. 3 fit 4,5,V",30,3.0,183.0,100,0.,0.0006); + new TH1F("h65","P",30,3.0,183.0); + new TH1F("h461","VAR X st. 3 fit 4,5,V",100,-2.25,2.25); + new TH1F("h462","VAR Y st. 3 fit 4,5,V",100,-1.42,1.42); + new TH1F("h463","VAR PHI st. 3 fit 4,5,V",100,-0.024,0.024); + new TH1F("h464","VAR ALM st. 3 fit 4,5,V",100,-0.024,0.024); + // histo2 + new TH2F("h261","histo2-VAR X st. 3 fit 4,5,V",30,3.0,183.0,100,0.,5.); + new TH2F("h262","histo2-VAR Y st. 3 fit 4,5,V",30,3.0,183.0,100,0.,2.); + new TH1F("h263","histo2-VAR X st. 3 fit 4,5,V",100,-2.25,2.25); + new TH1F("h264","histo2-VAR Y st. 3 fit 4,5,V",100,-1.42,1.42); + new TH1F("h265","Phisto2-",30,3.0,183.0); + // Histos dx,dy distribution between chambers inside stations + new TH1F("h71","DX in st. ID-70",100,-5.,5.); + new TH1F("h81","DY in st. ID-80",100,-5.,5.); + new TH1F("h72","DX in st. ID-70",100,-5.,5.); + new TH1F("h82","DY in st. ID-80",100,-5.,5.); + new TH1F("h73","DX in st. ID-70",100,-5.,5.); + new TH1F("h83","DY in st. ID-80",100,-5.,5.); + new TH1F("h74","DX in st. ID-70",100,-5.,5.); + new TH1F("h84","DY in st. ID-80",100,-5.,5.); + new TH1F("h75","DX in st. ID-70",100,-5.,5.); + new TH1F("h85","DY in st. ID-80",100,-5.,5.); +} + +void chfnt(Int_t &ievr, Int_t &ntrackr, Int_t *istatr, Int_t *isignr, Float_t *pxr, Float_t *pyr, Float_t *pzr, Float_t *zvr, Float_t *chi2r, Float_t *pxv, Float_t *pyv, Float_t *pzv) +{ + // + // fill the ntuple + ntuple_st.ievr = ievr; + ntuple_st.ntrackr = ntrackr; + for (Int_t i=0; i<500; i++) { + ntuple_st.istatr[i] = istatr[i]; + ntuple_st.isignr[i] = isignr[i]; + ntuple_st.pxr[i] = pxr[i]; + ntuple_st.pyr[i] = pyr[i]; + ntuple_st.pzr[i] = pzr[i]; + ntuple_st.zvr[i] = zvr[i]; + ntuple_st.chi2r[i] = chi2r[i]; + ntuple_st.pxv[i] = pxv[i]; + ntuple_st.pyv[i] = pyv[i]; + ntuple_st.pzv[i] = pzv[i]; + } + ntuple_global->Fill(); +} + +void hist_closed() +{ + // + // write histos and ntuple to "reconst.root" file + hfile_global->Write(); +} + +void trackf_read_geant(Int_t *itypg, Double_t *xtrg, Double_t *ytrg, Double_t *ptotg, Int_t *idg, Int_t *izch, Double_t *pvert1g, Double_t *pvert2g, Double_t *pvert3g, Double_t *zvertg, Int_t &nhittot1, Double_t *cx, Double_t *cy, Double_t *cz, Int_t &ievr,Int_t &nev,Double_t *xgeant, Double_t *ygeant,Double_t *clsize1, Double_t *clsize2) +{ + // + // introduce aliroot variables in fortran common + // tracking study from geant hits + // + + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); + + // TTree *TK = gAlice->TreeK(); + TTree *TH = gAlice->TreeH(); + Int_t ntracks = (Int_t)TH->GetEntries(); + cout<<"ntrack="<ResetHits(); + TH->GetEvent(track); + + if (MUON) { +// +// Loop over hits +// + for(AliMUONhit* mHit=(AliMUONhit*)MUON->FirstHit(-1); + mHit; + mHit=(AliMUONhit*)MUON->NextHit()) + { + if (maxidg<=20000) { + + if (mHit->fChamber > 10) continue; + TClonesArray *fPartArray = gAlice->Particles(); + TParticle *Part; + Int_t ftrack = mHit->fTrack; + Int_t id = ((TParticle*) fPartArray->UncheckedAt(ftrack))->GetPdgCode(); + + if (id==kMuonPlus||id==kMuonMinus) { + + // inversion de x et y car le champ est inverse dans le programme tracking + xtrg[maxidg] = 0; + ytrg[maxidg] = 0; + xgeant[maxidg] = mHit->fY; // x-pos of hit + ygeant[maxidg] = mHit->fX; // y-pos of hit + clsize1[maxidg] = 0; // cluster size on 1-st cathode + clsize2[maxidg] = 0; // cluster size on 2-nd cathode + cx[maxidg] = mHit->fCyHit; // Px/P of hit + cy[maxidg] = mHit->fCxHit; // Py/P of hit + cz[maxidg] = mHit->fCzHit; // Pz/P of hit + izch[maxidg] = mHit->fChamber; + /* + Int_t pdgtype = Int_t(mHit->fParticle); // particle number + itypg[maxidg] = gMC->IdFromPDG(pdgtype); + + */ + if (id==kMuonPlus) itypg[maxidg] = 5; + else itypg[maxidg] = 6; + + + + //printf("ich, itypg[maxidg] %d %d\n",izch[maxidg],itypg[maxidg]); + + ptotg[maxidg] = mHit->fPTot; // P of hit + + Part = (TParticle*) fPartArray->UncheckedAt(ftrack); + Float_t thet = Part->Theta(); + thet = thet*180./3.1416; + + //cout<<"chambre "<UncheckedAt(iparent))->GetPdgCode(); + + if (id2==443) id2=114; + else id2=116; + + if (id2==116) { + nres++; + } + //printf("id2 %d\n",id2); + idg[maxidg] = 30000*id1+10000*idum+id2; + + pvert1g[maxidg] = Part->Py(); // Px vertex + pvert2g[maxidg] = Part->Px(); // Py vertex + pvert3g[maxidg] = Part->Pz(); // Pz vertex + zvertg[maxidg] = Part->Vz(); // z vertex + + // cout<<"x="<Clear(); + TH1->GetEvent(track); + + // Loop over hits + for (int i=0;iGetEntriesFast();i++) + { + AliMUONhit *mHit=(AliMUONhit*) (*fHits2)[i]; + + if (mHit->fChamber > 10) continue; + + if (maxidg<=20000) { + + // inversion de x et y car le champ est inverse dans le programme tracking !!!! + xtrg[maxidg] = 0; // only for reconstructed point + ytrg[maxidg] = 0; // only for reconstructed point + xgeant[maxidg] = mHit->fY; // x-pos of hit + ygeant[maxidg] = mHit->fX; // y-pos of hit + clsize1[maxidg] = 0; // cluster size on 1-st cathode + clsize2[maxidg] = 0; // cluster size on 2-nd cathode + cx[maxidg] = mHit->fCyHit; // Px/P of hit + cy[maxidg] = mHit->fCxHit; // Py/P of hit + cz[maxidg] = mHit->fCzHit; // Pz/P of hit + izch[maxidg] = mHit->fChamber; // chamber number + ptotg[maxidg] = mHit->fPTot; // P of hit + + Int_t ftrack = mHit->fTrack; + Int_t id1 = ftrack; // track number + Int_t idum = track+1; + + TClonesArray *fPartArray = fParticles2; + TParticle *Part; + Int_t id = ((TParticle*) fPartArray->UncheckedAt(ftrack))->GetPdgCode(); + if (id==kMuonPlus||id==kMuonMinus) { + if (id==kMuonPlus) itypg[maxidg] = 5; + else itypg[maxidg] = 6; + } else itypg[maxidg]=0; + + Int_t id2=0; // set parent to 0 for background !! + idg[maxidg] = 30000*id1+10000*idum+id2; + + pvert1g[maxidg] = Part->Py(); // Px vertex + pvert2g[maxidg] = Part->Px(); // Py vertex + pvert3g[maxidg] = Part->Pz(); // Pz vertex + zvertg[maxidg] = Part->Vz(); // z vertex + + maxidg ++; + + } // check limits (maxidg) + } // hit loop + } // track loop + } // if TH1 + + ievr = nev; + nhittot1 = maxidg ; + cout<<"nhittot1="<=19) nbres++; + printf("nres, nbres %d %d \n",nres,nbres); + + hfile_global->cd(); + +} + + + +void trackf_read_spoint(Int_t *itypg, Double_t *xtrg, Double_t *ytrg, Double_t *ptotg, Int_t *idg, Int_t *izch, Double_t *pvert1g, Double_t *pvert2g, Double_t *pvert3g, Double_t *zvertg, Int_t &nhittot1, Double_t *cx, Double_t *cy, Double_t *cz, Int_t &ievr,Int_t &nev,Double_t *xgeant, Double_t *ygeant,Double_t *clsize1, Double_t *clsize2) + +{ + // + // introduce aliroot variables in fortran common + // tracking study from reconstructed points + // + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); + + cout<<"numero de l'evenement "<GetTreeC(nev); + TTree *TC=MUON->TreeC(); + TC->GetEntries(); + + Int_t maxidg = 0; + Int_t nres=0; + Int_t nncor=0; + static Int_t nuncor=0; + static Int_t nbadcor=0; + AliMUONRawCluster * mRaw; + AliMUONRawCluster * mRaw1; + TTree *TH = gAlice->TreeH(); + + Int_t ihit; + Int_t mult1, mult2; + if (MUON) { + for (Int_t ich=0;ich<10;ich++) { + TClonesArray *MUONcorrel = MUON->CathCorrelAddress(ich); + MUON->ResetCorrelation(); + TC->GetEvent(); + Int_t ncor = (Int_t)MUONcorrel->GetEntries(); + if (ncor>=2) nncor++; + if (!ncor) continue; + + // Loop over correlated clusters + for (Int_t icor=0;icorUncheckedAt(icor); + + Int_t flag=0; // = 1 if no information in the second cathode + Int_t index = mCor->fCorrelIndex[0]; // for the second cathode + if (index >= 0) { + Int_t index1 = mCor->fCorrelIndex[3]; // for the 1-st cathode + mRaw1 = MUON->RawCluster(ich,1,index1); + mult1=mRaw1->fMultiplicity; + mRaw = MUON->RawCluster(ich,2,index); + mult2=mRaw->fMultiplicity; + } else { + index = mCor->fCorrelIndex[3]; + mRaw = MUON->RawCluster(ich,1,index); + mult1=mRaw->fMultiplicity; + mult2=0; + flag=1; + nuncor++; + } + if (!mRaw) continue; + + Int_t ftrack1 = mRaw->fTracks[1]; // qui doit etre le meme pour + // la cathode 1 et 2 + ihit= mRaw->fTracks[0]; + //printf("icor, ftrack1 ihit %d %d %d\n",icor,ftrack1,ihit); + + if (mRaw->fClusterType == 0 ) { + + if (maxidg<=20000) { + if (flag == 0) { + xtrg[maxidg] = (Double_t) mCor->fY[3]; + ytrg[maxidg] = (Double_t) mCor->fX[0]; + Int_t index1 = mCor->fCorrelIndex[3]; + mRaw1 = MUON->RawCluster(ich,1,index1); + if (mRaw1->fClusterType==1 || mRaw1->fClusterType==2) { + Float_t xclust=mCor->fX[3]; + Float_t yclust=mCor->fY[3]; + AliMUONchamber *iChamber=&(MUON->Chamber(ich)); + AliMUONsegmentation *seg = iChamber->GetSegmentationModel(1); + Int_t ix,iy; + seg->GetPadIxy(xclust,yclust,ix,iy); + Int_t isec=seg->Sector(ix,iy); + printf("nev, CORRELATION with pure background in chamber sector %d %d %d !!!!!!!!!!!!!!!!!!!!!\n",nev,ich+1,isec); + nbadcor++; + + } // end if cluster type on cathode 1 + }else { + xtrg[maxidg] = (Double_t) mCor->fY[3]; + ytrg[maxidg] = (Double_t) mCor->fX[3]; + } // if iflag + izch[maxidg] = ich+1; + xgeant[maxidg] = 0; + ygeant[maxidg] = 0; + clsize1[maxidg] = mult1; + clsize2[maxidg] = mult2; + + cx[maxidg] = 0; // Px/P of hit + cy[maxidg] = 0; // Py/P of hit + cz[maxidg] = 0; // Pz/P of hit + itypg[maxidg] = 0; // particle number + ptotg[maxidg] = 0; // P of hit + idg[maxidg] = 0; + pvert1g[maxidg] = 0; // Px vertex + pvert2g[maxidg] = 0; // Py vertex + pvert3g[maxidg] = 0; // Pz vertex + zvertg[maxidg] = 0; // z vertex + maxidg++; + + }// fin maxidg + + } else if (mRaw->fClusterType ==1 && ftrack1 < 0) // background + resonance + { + nres++; + // get indexmap and loop over digits to find the signal + Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); + gAlice->ResetDigits(); + if (flag==0) { + //gAlice->TreeD()->GetEvent(2); // cathode 2 + gAlice->TreeD()->GetEvent(nent-1); // cathode 2 + } else { + //gAlice->TreeD()->GetEvent(1); // cathode 1 + gAlice->TreeD()->GetEvent(nent-2); // cathode 1 + } + + TClonesArray *MUONdigits = MUON->DigitsAddress(ich); + Int_t mul=mRaw->fMultiplicity; + Int_t trsign; + for (int i=0;ifIndexMap[i]; + AliMUONdigit *dig= (AliMUONdigit*)MUONdigits->UncheckedAt(idx); + trsign=dig->fTracks[0]; + ihit=dig->fHit-1; + if (trsign > 0 && ihit >= 0) break; + + } // loop over indexmap + + //printf("trsign, ihit %d %d\n",trsign,ihit); + //printf("signal+background : trsign %d\n",trsign); + + if (trsign < 0 || ihit < 0) { // no signal muon was found + + if (maxidg<=20000) { + if (flag == 0) { + xtrg[maxidg] = (Double_t) mCor->fY[3]; + ytrg[maxidg] = (Double_t) mCor->fX[0]; + }else { + xtrg[maxidg] = (Double_t) mCor->fY[3]; + ytrg[maxidg] = (Double_t) mCor->fX[3]; + } + + izch[maxidg] = ich+1; + + // initialisation of informations which + // can't be reached for background + + xgeant[maxidg] = 0; // only for resonances + ygeant[maxidg] = 0; // only for resonances + clsize1[maxidg] = mult1; + clsize2[maxidg] = mult2; + + cx[maxidg] = 0; // Px/P of hit + cy[maxidg] = 0; // Py/P of hit + cz[maxidg] = 0; // Pz/P of hit + itypg[maxidg] = 0; // particle number + ptotg[maxidg] = 0; // P of hit + idg[maxidg] = 0; + pvert1g[maxidg] = 0; // Px vertex + pvert2g[maxidg] = 0; // Py vertex + pvert3g[maxidg] = 0; // Pz vertex + zvertg[maxidg] = 0; + maxidg++; + + }// fin maxidg + } else { // signal muon - retrieve info + //printf("inside trsign, ihit %d %d\n",trsign,ihit); + if (maxidg<=20000) { + if (flag == 0) { + xtrg[maxidg] = (Double_t) mCor->fY[3]; + ytrg[maxidg] = (Double_t) mCor->fX[0]; + }else { + xtrg[maxidg] = (Double_t) mCor->fY[3]; + ytrg[maxidg] = (Double_t) mCor->fX[3]; + } + izch[maxidg] = ich+1; + clsize1[maxidg] = mult1; + clsize2[maxidg] = mult2; + + // initialise and set to the correct values + // if signal muons + + xgeant[maxidg] = 0; // only for resonances + ygeant[maxidg] = 0; // only for resonances + + cx[maxidg] = 0; // Px/P of hit + cy[maxidg] = 0; // Py/P of hit + cz[maxidg] = 0; // Pz/P of hit + itypg[maxidg] = 0; // particle number + ptotg[maxidg] = 0; // P of hit + idg[maxidg] = 0; + pvert1g[maxidg] = 0; // Px vertex + pvert2g[maxidg] = 0; // Py vertex + pvert3g[maxidg] = 0; // Pz vertex + zvertg[maxidg] = 0; + // try to retrieve info about signal muons + gAlice->ResetHits(); + TH->GetEvent(trsign); + + TClonesArray *MUONhits = MUON->Hits(); + AliMUONhit *mHit= (AliMUONhit*)MUONhits-> + UncheckedAt(ihit); + TClonesArray *fPartArray = gAlice->Particles(); + TParticle *Part; + Int_t nch=mHit->fChamber-1; + //printf("sig+bgr ich, nch %d %d \n",ich,nch); + if (nch==ich) { + Int_t ftrack = mHit->fTrack; + Int_t id = ((TParticle*) fPartArray-> + UncheckedAt(ftrack))->GetPdgCode(); + if (id==kMuonPlus||id==kMuonMinus) { + xgeant[maxidg] = (Double_t) mHit->fY; + ygeant[maxidg] = (Double_t) mHit->fX; + cx[maxidg] = (Double_t) mHit->fCyHit; + cy[maxidg] = (Double_t) mHit->fCxHit; + cz[maxidg] = (Double_t) mHit->fCzHit; + + if (id==kMuonPlus) { + itypg[maxidg] = 5; + } else if (id==kMuonMinus) { + itypg[maxidg] = 6; + } else itypg[maxidg] = 0; + + ptotg[maxidg] = (Double_t) mHit->fPTot; + Part = (TParticle*) fPartArray-> + UncheckedAt(ftrack); + Int_t iparent = Part->GetFirstMother(); + Int_t id2; + id2 = ((TParticle*) fPartArray-> + UncheckedAt(ftrack))->GetPdgCode(); + + if (iparent >= 0) { + Int_t ip; + while(1) { + ip=((TParticle*) fPartArray-> + UncheckedAt(iparent))->GetFirstMother(); + if (ip < 0) { + id2 = ((TParticle*) fPartArray-> + UncheckedAt(iparent))->GetPdgCode(); + break; + } else { + iparent = ip; + id2 = ((TParticle*) fPartArray-> + UncheckedAt(iparent))->GetPdgCode(); + } // ip<0 + } // while + }// iparent + Int_t id1 = ftrack; + Int_t idum = trsign+1; + + if (id2==443 || id2==553) { + nres++; + if (id2==443) id2=114; + else id2=116; + } + + idg[maxidg] = 30000*id1+10000*idum+id2; + pvert1g[maxidg] = (Double_t) Part->Py(); + pvert2g[maxidg] = (Double_t) Part->Px(); + pvert3g[maxidg] = (Double_t) Part->Pz(); + zvertg[maxidg] = (Double_t) Part->Vz(); + } //if muon + } //if nch + maxidg++; + } // check limits + } // sign+bgr, highest bgr + } + //pure resonance or mixed cluster with the highest + //contribution coming from resonance + if (mRaw->fClusterType >= 1 && ftrack1>=0) + { + if (maxidg<=20000) { + if (flag == 0) { + xtrg[maxidg] = (Double_t) mCor->fY[3]; + ytrg[maxidg] = (Double_t) mCor->fX[0]; + }else { + xtrg[maxidg] = (Double_t) mCor->fY[3]; + ytrg[maxidg] = (Double_t) mCor->fX[3]; + } + clsize1[maxidg] = mult1; + clsize2[maxidg] = mult2; + izch[maxidg] = ich+1; + + Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); + gAlice->ResetDigits(); + if (flag==0) { + //gAlice->TreeD()->GetEvent(2); // cathode 2 + gAlice->TreeD()->GetEvent(nent-1); // cathode 2 + } else { + //gAlice->TreeD()->GetEvent(1); // cathode 1 + gAlice->TreeD()->GetEvent(nent-2); // cathode 1 + } + + TClonesArray *MUONdigits = MUON->DigitsAddress(ich); + Int_t mul=mRaw->fMultiplicity; + for (int i=0;ifIndexMap[i]; + AliMUONdigit *dig= (AliMUONdigit*)MUONdigits->UncheckedAt(idx); + ihit=dig->fHit-1; + if (ihit >= 0) break; + + } // loop over indexmap + //printf("fClusterType, ihit %d %d \n",mRaw->fClusterType,ihit); + if (ihit < 0) { + xgeant[maxidg] = 0; // only for resonances + ygeant[maxidg] = 0; // only for resonances + + cx[maxidg] = 0; // Px/P of hit + cy[maxidg] = 0; // Py/P of hit + cz[maxidg] = 0; // Pz/P of hit + itypg[maxidg] = 0; // particle number + ptotg[maxidg] = 0; // P of hit + idg[maxidg] = 0; + pvert1g[maxidg] = 0; // Px vertex + pvert2g[maxidg] = 0; // Py vertex + pvert3g[maxidg] = 0; // Pz vertex + zvertg[maxidg] = 0; + } else { + gAlice->ResetHits(); + TH->GetEvent(ftrack1); + TClonesArray *MUONhits = MUON->Hits(); + AliMUONhit *mHit= (AliMUONhit*)MUONhits-> + UncheckedAt(ihit); + TClonesArray *fPartArray = gAlice->Particles(); + TParticle *Part; + Int_t nch=mHit->fChamber-1; + //printf("signal ich, nch %d %d \n",ich,nch); + if (nch==ich) { + Int_t ftrack = mHit->fTrack; + Int_t id = ((TParticle*) fPartArray-> + UncheckedAt(ftrack))->GetPdgCode(); + //printf("id %d \n",id); + if (id==kMuonPlus||id==kMuonMinus) { + xgeant[maxidg] = (Double_t) mHit->fY; + ygeant[maxidg] = (Double_t) mHit->fX; + cx[maxidg] = (Double_t) mHit->fCyHit; + cy[maxidg] = (Double_t) mHit->fCxHit; + cz[maxidg] = (Double_t) mHit->fCzHit; + + if (id==kMuonPlus) { + itypg[maxidg] = 5; + } else if (id==kMuonMinus) { + itypg[maxidg] = 6; + } else itypg[maxidg] = 0; + + ptotg[maxidg] = (Double_t) mHit->fPTot; + Part = (TParticle*) fPartArray-> + UncheckedAt(ftrack); + Int_t iparent = Part->GetFirstMother(); + Int_t id2; + id2 = ((TParticle*) fPartArray-> + UncheckedAt(ftrack))->GetPdgCode(); + + if (iparent >= 0) { + Int_t ip; + while(1) { + ip=((TParticle*) fPartArray-> + UncheckedAt(iparent))->GetFirstMother(); + if (ip < 0) { + id2 = ((TParticle*) fPartArray-> + UncheckedAt(iparent))->GetPdgCode(); + break; + } else { + iparent = ip; + id2 = ((TParticle*) fPartArray-> + UncheckedAt(iparent))->GetPdgCode(); + } // ip<0 + } // while + }// iparent + Int_t id1 = ftrack; + Int_t idum = ftrack1+1; + + if (id2==443 || id2==553) { + nres++; + if (id2==443) id2=114; + else id2=116; + } + // printf("id2 %d\n",id2); + idg[maxidg] = 30000*id1+10000*idum+id2; + pvert1g[maxidg] = (Double_t) Part->Py(); + pvert2g[maxidg] = (Double_t) Part->Px(); + pvert3g[maxidg] = (Double_t) Part->Pz(); + zvertg[maxidg] = (Double_t) Part->Vz(); + } //if muon + } //if nch + } // ihit + maxidg++; + } // check limits + } // if cluster type + } // icor loop + } // ich loop + }// if MUON + + + ievr = nev; + cout<<"evenement "<=20) nbcor++; + printf("nbcor - %d\n",nbcor); + printf("nuncor - %d\n",nuncor); + printf("nbadcor - %d\n",nbadcor); + + TC->Reset(); + + hfile_global->cd(); + +} + +void trackf_fit(Int_t &ivertex, Double_t *pest, Double_t *pstep, Double_t &pxzinv, Double_t &tphi, Double_t &talam, Double_t &xvert, Double_t &yvert) +{ + // + // Fit a track candidate with the following input parameters: + // INPUT : IVERTEX : vertex flag, if IVERTEX=1 (XVERT,YVERT) are free paramaters + // if IVERTEX=1 (XVERT,YVERT)=(0.,0.) + // PEST(5) : starting value of parameters (minuit) + // PSTEP(5) : step size for parameters (minuit) + // OUTPUT : PXZINV,TPHI,TALAM,XVERT,YVERT : fitted value of the parameters + + static Double_t arglist[10]; + static Double_t c[5] = {0.4, 0.45, 0.45, 90., 90.}; + static Double_t b1, b2, epxz, efi, exs, exvert, eyvert; + TString chname; + Int_t ierflg = 0; + + TMinuit *gMinuit = new TMinuit(5); + gMinuit->mninit(5,10,7); + gMinuit->SetFCN(fcnf); // constant m.f. + + arglist[0] = -1; + + gMinuit->mnexcm("SET PRINT", arglist, 1, ierflg); + // gMinuit->mnseti('track fitting'); + + gMinuit->mnparm(0, "invmom", pest[0], pstep[0], -c[0], c[0], ierflg); + gMinuit->mnparm(1, "azimuth", pest[1], pstep[1], -c[1], c[1], ierflg); + gMinuit->mnparm(2, "deep", pest[2], pstep[2], -c[2], c[2], ierflg); + if (ivertex==1) { + gMinuit->mnparm(3, "x ", pest[3], pstep[3], -c[3], c[3], ierflg); + gMinuit->mnparm(4, "y ", pest[4], pstep[4], -c[4], c[4], ierflg); + } + + gMinuit->mnexcm("SET NOGR", arglist, 0, ierflg); + gMinuit->mnexcm("MINIMIZE", arglist, 0, ierflg); + gMinuit->mnexcm("EXIT" , arglist, 0, ierflg); + + gMinuit->mnpout(0, chname, pxzinv, epxz, b1, b2, ierflg); + gMinuit->mnpout(1, chname, tphi, efi, b1, b2, ierflg); + gMinuit->mnpout(2, chname, talam, exs, b1, b2, ierflg); + if (ivertex==1) { + gMinuit->mnpout(3, chname, xvert, exvert, b1, b2, ierflg); + gMinuit->mnpout(4, chname, yvert, eyvert, b1, b2, ierflg); + } + + delete gMinuit; + +} + +void fcnf(Int_t &npar, Double_t *grad, Double_t &fval, Double_t *pest, Int_t iflag) +{ + // + // function called by trackf_fit + Int_t futil = 0; + fcn(npar,grad,fval,pest,iflag,futil); +} + +void prec_fit(Double_t &pxzinv, Double_t &fis, Double_t &alams, Double_t &xvert, Double_t &yvert, Double_t &pxzinvf, Double_t &fif, Double_t &alf, Double_t &xvertf, Double_t &yvertf, Double_t &epxzinv, Double_t &efi, Double_t &exs, Double_t &exvert, Double_t &eyvert) +{ + // + // minuit fits for tracking finding + + static Double_t arglist[10]; + static Double_t c1[5] = {0.001, 0.001, 0.001, 1., 1.}; + static Double_t c2[5] = {0.5, 0.5, 0.5, 120., 120.}; + static Double_t emat[9]; + static Double_t b1, b2; + Double_t fmin, fedm, errdef; + Int_t npari, nparx, istat; + + TString chname; + Int_t ierflg = 0; + + TMinuit *gMinuit = new TMinuit(5); + gMinuit->mninit(5,10,7); + gMinuit->SetFCN(fcnfitf); + + arglist[0] = -1.; + gMinuit->mnexcm("SET PRINT", arglist, 1, ierflg); + + // gMinuit->mnseti('track fitting'); + + gMinuit->mnparm(0,"invmom", pxzinv, c1[0], -c2[0], c2[0], ierflg); // 0.003, 0.5 + gMinuit->mnparm(1,"azimuth ", fis, c1[1], -c2[1], c2[1], ierflg); + gMinuit->mnparm(2,"deep ", alams, c1[2], -c2[2], c2[2], ierflg); + gMinuit->mnparm(3,"xvert", xvert, c1[3], -c2[3], c2[3], ierflg); + gMinuit->mnparm(4,"yvert", yvert, c1[4], -c2[4], c2[4], ierflg); + + gMinuit->mnexcm("SET NOGR", arglist, 0, ierflg); + arglist[0] = 2.; + gMinuit->mnexcm("MINIMIZE", arglist, 0, ierflg); + gMinuit->mnexcm("EXIT", arglist, 0, ierflg); + + gMinuit->mnpout(0, chname, pxzinvf, epxzinv, b1, b2, ierflg); + gMinuit->mnpout(1, chname, fif, efi, b1, b2, ierflg); + gMinuit->mnpout(2, chname, alf, exs, b1, b2, ierflg); + gMinuit->mnpout(3, chname, xvertf, exvert, b1, b2, ierflg); + gMinuit->mnpout(4, chname, yvertf, eyvert, b1, b2, ierflg); + + gMinuit->mnemat(emat, 3); + gMinuit->mnstat(fmin, fedm, errdef, npari, nparx, istat); + + delete gMinuit; +} + +void fcnfitf(Int_t &npar, Double_t *grad, Double_t &fval, Double_t *xval, Int_t iflag) +{ + // + // function called by prec_fit + Int_t futil = 0; + fcnfit(npar,grad,fval,xval,iflag,futil); +} + +///////////////////// fin modifs perso ////////////////////// + ClassImp(AliMUONcluster) //___________________________________________ @@ -681,9 +3039,11 @@ AliMUONdigit::AliMUONdigit(Int_t *digits) // // Creates a MUON digit object to be updated // - fPadX = digits[0]; - fPadY = digits[1]; - fSignal = digits[2]; + fPadX = digits[0]; + fPadY = digits[1]; + fSignal = digits[2]; + fPhysics = digits[3]; + fHit = digits[4]; } //_____________________________________________________________________________ @@ -695,28 +3055,33 @@ AliMUONdigit::AliMUONdigit(Int_t *tracks, Int_t *charges, Int_t *digits) fPadX = digits[0]; fPadY = digits[1]; fSignal = digits[2]; + fPhysics = digits[3]; + fHit = digits[4]; for(Int_t i=0; i<10; i++) { fTcharges[i] = charges[i]; fTracks[i] = tracks[i]; } } +AliMUONdigit::~AliMUONdigit() +{ + +} + ClassImp(AliMUONlist) //____________________________________________________________________________ - AliMUONlist::AliMUONlist(Int_t rpad, Int_t *digits): + AliMUONlist::AliMUONlist(Int_t ich, Int_t *digits): AliMUONdigit(digits) { // // Creates a MUON digit list object // - fRpad = rpad; + fChamber = ich; fTrackList = new TObjArray; } -//_____________________________________________________________________________ - ClassImp(AliMUONhit) @@ -725,7 +3090,7 @@ ClassImp(AliMUONhit) AliHit(shunt, track) { fChamber=vol[0]; - fParticle=(Int_t) hits[0]; + fParticle=hits[0]; fX=hits[1]; fY=hits[2]; fZ=hits[3]; @@ -735,78 +3100,154 @@ ClassImp(AliMUONhit) fEloss=hits[7]; fPHfirst=(Int_t) hits[8]; fPHlast=(Int_t) hits[9]; -} -ClassImp(AliMUONreccluster) - -ClassImp(AliMUONRecCluster) -//_____________________________________________________________________ -AliMUONRecCluster::AliMUONRecCluster() + // modifs perso + fPTot=hits[10]; + fCxHit=hits[11]; + fCyHit=hits[12]; + fCzHit=hits[13]; +} +ClassImp(AliMUONcorrelation) +//___________________________________________ +//_____________________________________________________________________________ +AliMUONcorrelation::AliMUONcorrelation(Int_t *idx, Float_t *x, Float_t *y) +{ + // + // Creates a MUON correlation object + // + for(Int_t i=0; i<4; i++) { + fCorrelIndex[i] = idx[i]; + fX[i] = x[i]; + fY[i] = y[i]; + } +} +ClassImp(AliMUONRawCluster) +Int_t AliMUONRawCluster::Compare(TObject *obj) { - fDigits=0; - fNdigit=-1; + /* + AliMUONRawCluster *raw=(AliMUONRawCluster *)obj; + Float_t r=GetRadius(); + Float_t ro=raw->GetRadius(); + if (r>ro) return 1; + else if (rfY; + if (y>yo) return 1; + else if (y1) { + half=(high+low)/2; + if(y>coord[half]) low=half; + else high=half; + } + return low; } -void AliMUONRecCluster::AddDigit(Int_t Digit) +void AliMUONRawCluster::SortMin(Int_t *idx,Float_t *xdarray,Float_t *xarray,Float_t *yarray,Float_t *qarray, Int_t ntr) { - if (fNdigit==fDigits->GetSize()) { - //enlarge the list by hand! - Int_t *array= new Int_t[fNdigit*2]; - for(Int_t i=0;iAt(i); - fDigits->Adopt(fNdigit*2,array); + // + // Get the 3 closest points(cog) one can find on the second cathode + // starting from a given cog on first cathode + // + + // + // Loop over deltax, only 3 times + // + + Float_t xmin; + Int_t jmin; + Int_t id[3] = {-2,-2,-2}; + Float_t jx[3] = {0.,0.,0.}; + Float_t jy[3] = {0.,0.,0.}; + Float_t jq[3] = {0.,0.,0.}; + Int_t jid[3] = {-2,-2,-2}; + Int_t i,j,imax; + + if (ntr<3) imax=ntr; + else imax=3; + for(i=0;iAddAt(Digit,fNdigit); - fNdigit++; + } -AliMUONRecCluster::~AliMUONRecCluster() +Int_t AliMUONRawCluster::PhysicsContribution() { - if (fDigits) - delete fDigits; + Int_t iPhys=0; + Int_t iBg=0; + Int_t iMixed=0; + for (Int_t i=0; iAt(fCurrentDigit); -} + +ClassImp(AliMUONreccluster) +ClassImp(AliMUONsegmentation) +ClassImp(AliMUONresponse) + + + + + -Int_t AliMUONRecCluster::NextDigitIndex() -{ - fCurrentDigit++; - if (fCurrentDigitAt(fCurrentDigit); - else - return InvalidDigitIndex(); -} -Int_t AliMUONRecCluster::NDigits() -{ - return fNdigit; -} -void AliMUONRecCluster::Finish() -{ - // In order to reconstruct coordinates, one has to - // get back to the digits which is not trivial here, - // because we don't know where digits are stored! - // Center Of Gravity, or other method should be - // a property of AliMUON class! -} diff --git a/MUON/AliMUON.h b/MUON/AliMUON.h index c755a5b3c32..3e32f6f3a91 100644 --- a/MUON/AliMUON.h +++ b/MUON/AliMUON.h @@ -6,204 +6,26 @@ #include "AliDetector.h" #include "AliHit.h" #include "AliMUONConst.h" -#include "AliDigit.h" +#include "AliDigit.h" +#include "AliMUONchamber.h" +#include "AliMUONSegRes.h" #include #include - +#include +#include +#include +typedef enum {simple, medium, big} Cluster_t; static const int NCH=14; class AliMUONcluster; -class AliMUONchamber; class AliMUONRecCluster; -//---------------------------------------------- -class AliMUONgeometry -{ - public: - AliMUONgeometry(){} - virtual ~AliMUONgeometry(){} - void InitGeo(Float_t z); - Float_t fdGas; // half gaz gap - Float_t fdAlu; // half Alu width - Float_t frMin; // innermost sensitive radius - Float_t frMax; // outermost sensitive radius - ClassDef(AliMUONgeometry,1) -}; -//---------------------------------------------- -// -// Chamber segmentation virtual base class -// -class AliMUONsegmentation : -public TObject { - - public: +class AliMUONRawCluster; +class AliMUONClusterFinder; +class AliMUONcorrelation; - // Set Chamber Segmentation Parameters - virtual void SetPADSIZ(Float_t p1, Float_t p2) =0; - virtual void SetDAnod(Float_t D) =0; - // Transform from pad (wire) to real coordinates and vice versa - virtual Float_t GetAnod(Float_t xhit) =0; - virtual void GetPadIxy(Float_t x ,Float_t y ,Int_t &ix,Int_t &iy)=0; - virtual void GetPadCxy(Int_t ix,Int_t iy,Float_t &x ,Float_t &y )=0; - // - // Initialisation - virtual void Init(AliMUONchamber*) =0; - // - // Get member data - virtual Float_t Dpx() =0; - virtual Float_t Dpy() =0; - virtual Int_t Npx() =0; - virtual Int_t Npy() =0; - // - // Iterate over pads - virtual void FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) =0; - virtual void NextPad()=0; - virtual Int_t MorePads() =0; - // Get next neighbours - virtual void Neighbours - (Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) =0; - // Provisory RecCluster coordinates reconstructor - virtual void FitXY(AliMUONRecCluster* Cluster,TClonesArray* MUONdigits) =0; - // - // Current pad cursor during disintegration - virtual Int_t Ix() =0; - virtual Int_t Iy() =0; - virtual Int_t ISector() =0; - // - // Signal Generation Condition during Stepping - virtual Int_t SigGenCond(Float_t x, Float_t y, Float_t z) = 0; - virtual void SigGenInit(Float_t x, Float_t y, Float_t z) = 0; - virtual void IntegrationLimits - (Float_t& x1, Float_t& x2, Float_t& y1, Float_t& y2) = 0; - // - // Identification - ClassDef(AliMUONsegmentation,1) -}; -//---------------------------------------------- -// -// Chamber response virtual base class -// -class AliMUONresponse : -public TObject { - public: - // - // Configuration methods - virtual void SetRSIGM(Float_t p1) =0; - virtual void SetMUCHSP(Float_t p1) =0; - virtual void SetMUSIGM(Float_t p1, Float_t p2) =0; - virtual void SetMAXADC(Float_t p1) =0; - // - // Get member data - virtual Float_t Chslope() =0; - virtual Float_t ChwX() =0; - virtual Float_t ChwY() =0; - virtual Float_t Nsigma() =0; - virtual Float_t adc_satm() =0; - // - // Chamber response methods - // Pulse height from scored quantity (eloss) - virtual Float_t IntPH(Float_t eloss) =0; - // Charge disintegration - virtual Float_t IntXY(AliMUONsegmentation *) =0; - // - // Identification - ClassDef(AliMUONresponse,1) -}; //---------------------------------------------- -class AliMUONchamber : -public TObject, -public AliMUONgeometry{ - public: - AliMUONchamber(); - ~AliMUONchamber(){} -// -// Set and get GEANT id - Int_t GetGid() {return fGid;} - void SetGid(Int_t id) {fGid=id;} -// -// Initialisation and z-Position - void Init(); - void SetZPOS(Float_t p1) {fzPos=p1;} - Float_t ZPosition() {return fzPos;} -// -// Configure response model - void ResponseModel(AliMUONresponse* thisResponse) {fResponse=thisResponse;} -// -// Configure segmentation model - void SegmentationModel(Int_t i, AliMUONsegmentation* thisSegmentation) { - (*fSegmentation)[i-1] = thisSegmentation; - } -// -// Get reference to response model - AliMUONresponse* &GetResponseModel(){return fResponse;} -// -// Get reference to segmentation model - AliMUONsegmentation* GetSegmentationModel(Int_t isec) { - return (AliMUONsegmentation *) (*fSegmentation)[isec-1]; - } - Int_t Nsec() {return fnsec;} - void SetNsec(Int_t nsec) {fnsec=nsec;} -// -// Member function forwarding to the segmentation and response models -// -// Calculate pulse height from energy loss - Float_t IntPH(Float_t eloss) {return fResponse->IntPH(eloss);} -// -// Ask segmentation if signal should be generated - Int_t SigGenCond(Float_t x, Float_t y, Float_t z) - { - if (fnsec==1) { - return ((AliMUONsegmentation*) (*fSegmentation)[0]) - ->SigGenCond(x, y, z) ; - } else { - return (((AliMUONsegmentation*) (*fSegmentation)[0]) - ->SigGenCond(x, y, z)) || - (((AliMUONsegmentation*) (*fSegmentation)[1]) - ->SigGenCond(x, y, z)) ; - } - } -// -// Initialisation of segmentation for hit - void SigGenInit(Float_t x, Float_t y, Float_t z) - { - - if (fnsec==1) { - ((AliMUONsegmentation*) (*fSegmentation)[0])->SigGenInit(x, y, z) ; - } else { - ((AliMUONsegmentation*) (*fSegmentation)[0])->SigGenInit(x, y, z) ; - ((AliMUONsegmentation*) (*fSegmentation)[1])->SigGenInit(x, y, z) ; - } - } - -// Configuration forwarding -// - void SetRSIGM(Float_t p1) {fResponse->SetRSIGM(p1);} - void SetMUCHSP(Float_t p1) {fResponse->SetMUCHSP(p1);} - void SetMUSIGM(Float_t p1, Float_t p2) {fResponse->SetMUSIGM(p1,p2);} - void SetMAXADC(Float_t p1) {fResponse->SetMAXADC(p1);} - - void SetPADSIZ(Int_t isec, Float_t p1, Float_t p2) { - ((AliMUONsegmentation*) (*fSegmentation)[isec-1])->SetPADSIZ(p1,p2); - } -// -// Cluster formation method - void DisIntegration(Float_t, Float_t, Float_t, Int_t&x, Float_t newclust[6][500]); - ClassDef(AliMUONchamber,1) - - private: -// GEANT volume if for sensitive volume of this chamber - Int_t fGid; -// z-position of this chamber - Float_t fzPos; -// The segmentation models for the cathode planes -// fnsec=1: one plane segmented, fnsec=2: both planes are segmented. - Int_t fnsec; - TObjArray *fSegmentation; - AliMUONresponse *fResponse; - -}; - class AliMUONcluster : public TObject { @@ -236,11 +58,11 @@ public: Int_t fQ ; // Q of cluster (in ADC counts) Float_t fX ; // X of cluster Float_t fY ; // Y of cluster - + public: AliMUONreccluster() { fTracks[0]=fTracks[1]=fTracks[2]=0; - fQ=0; fX=fY=0; + fQ=0; fX=fY=0; } virtual ~AliMUONreccluster() {;} @@ -254,10 +76,10 @@ class AliMUONdigit : public TObject { Int_t fPadX; // Pad number along x Int_t fPadY ; // Pad number along y Int_t fSignal; // Signal amplitude - - - Int_t fTcharges[10]; // charge per track making this digit (up to 10) - Int_t fTracks[10]; // tracks making this digit (up to 10) + Int_t fTcharges[10]; // charge per track making this digit (up to 10) + Int_t fTracks[10]; // primary tracks making this digit (up to 10) + Int_t fPhysics; // physics contribution to signal + Int_t fHit; // hit number - temporary solution @@ -265,28 +87,21 @@ class AliMUONdigit : public TObject { AliMUONdigit() {} AliMUONdigit(Int_t *digits); AliMUONdigit(Int_t *tracks, Int_t *charges, Int_t *digits); - virtual ~AliMUONdigit() {} - - + virtual ~AliMUONdigit(); + ClassDef(AliMUONdigit,1) //Digits for set:MUON }; //_____________________________________________________________________________ class AliMUONlist : public AliMUONdigit { public: - - Int_t fRpad; // r_pos of pad - + Int_t fChamber; // chamber number of pad TObjArray *fTrackList; - - public: AliMUONlist() {fTrackList=0;} AliMUONlist(Int_t rpad, Int_t *digits); - virtual ~AliMUONlist() {} - + virtual ~AliMUONlist() {delete fTrackList;} TObjArray *TrackList() {return fTrackList;} - ClassDef(AliMUONlist,1) //Digits for set:MUON }; //___________________________________________ @@ -297,13 +112,20 @@ class AliMUONlist : public AliMUONdigit { class AliMUONhit : public AliHit { public: Int_t fChamber; // Chamber number - Int_t fParticle; // PDG particle type + Float_t fParticle; // Geant3 particle type Float_t fTheta ; // Incident theta angle in degrees Float_t fPhi ; // Incident phi angle in degrees Float_t fTlength; // Track length inside the chamber Float_t fEloss; // ionisation energy loss in gas Int_t fPHfirst; // first padhit Int_t fPHlast; // last padhit + +// modifs perso + Float_t fPTot; // hit momentum P + Float_t fCxHit; // Px/P + Float_t fCyHit; // Py/P + Float_t fCzHit; // Pz/P + public: AliMUONhit() {} AliMUONhit(Int_t fIshunt, Int_t track, Int_t *vol, Float_t *hits); @@ -320,8 +142,10 @@ class AliMUON : public AliDetector { virtual void AddHit(Int_t, Int_t*, Float_t*); virtual void AddCluster(Int_t*); virtual void AddDigits(Int_t, Int_t*, Int_t*, Int_t*); + virtual void AddRawCluster(Int_t, const AliMUONRawCluster&); virtual void AddRecCluster(Int_t iCh, Int_t iCat, AliMUONRecCluster* Cluster); + virtual void AddCathCorrel(Int_t, Int_t*, Float_t*, Float_t*); virtual void BuildGeometry(); virtual void CreateGeometry() {} virtual void CreateMaterials() {} @@ -330,13 +154,36 @@ class AliMUON : public AliDetector { virtual Int_t IsVersion() const =0; // TClonesArray *Clusters() {return fClusters;} + virtual void MakeTreeC(Option_t *option="C"); + void GetTreeC(Int_t); virtual void MakeBranch(Option_t *opt=" "); void SetTreeAddress(); virtual void ResetHits(); virtual void ResetDigits(); + virtual void ResetRawClusters(); virtual void ResetRecClusters(); - virtual void ReconstructClusters(); -// + virtual void ResetCorrelation(); + virtual void FindClusters(Int_t,Int_t); + virtual void Digitise(Int_t,Int_t,Option_t *opt=" ",Option_t *opt=" ",Text_t *name=" "); + virtual void CathodeCorrelation(Int_t); + virtual void SortTracks(Int_t *,Int_t *,Int_t); +// +// modifs perso + + void Init(Double_t &, Double_t &, Double_t &); + void Reconst(Int_t &,Int_t &,Int_t,Int_t &,Int_t&,Int_t&, Option_t *option,Text_t *filename); + void FinishEvent(); + void Close(); + void SetCutPxz(Double_t p) {fSPxzCut=p;} + void SetSigmaCut(Double_t p) {fSSigmaCut=p;} + void SetXPrec(Double_t p) {fSXPrec=p;} + void SetYPrec(Double_t p) {fSYPrec=p;} + Double_t GetCutPxz() {return fSPxzCut;} + Double_t GetSigmaCut() {return fSSigmaCut;} + Double_t GetXPrec() {return fSXPrec;} + Double_t GetYPrec() {return fSYPrec;} +// fin modifs perso + // Configuration Methods (per station id) // // Set Chamber Segmentation Parameters @@ -344,43 +191,72 @@ class AliMUON : public AliDetector { virtual void SetPADSIZ(Int_t id, Int_t isec, Float_t p1, Float_t p2); // Set Signal Generation Parameters - virtual void SetRSIGM(Int_t id, Float_t p1); - virtual void SetMUCHSP(Int_t id, Float_t p1); - virtual void SetMUSIGM(Int_t id, Float_t p1, Float_t p2); - virtual void SetMAXADC(Int_t id, Float_t p1); + virtual void SetSigmaIntegration(Int_t id, Float_t p1); + virtual void SetChargeSlope(Int_t id, Float_t p1); + virtual void SetChargeSpread(Int_t id, Float_t p1, Float_t p2); + virtual void SetMaxAdc(Int_t id, Float_t p1); // Set Segmentation and Response Model virtual void SetSegmentationModel(Int_t id, Int_t isec, AliMUONsegmentation *segmentation); virtual void SetResponseModel(Int_t id, AliMUONresponse *response); virtual void SetNsec(Int_t id, Int_t nsec); +// Set Reconstruction Model + virtual void SetReconstructionModel(Int_t id, AliMUONClusterFinder *reconstruction); // Set Stepping Parameters - virtual void SetSMAXAR(Float_t p1); - virtual void SetSMAXAL(Float_t p1); - virtual void SetDMAXAR(Float_t p1); - virtual void SetDMAXAL(Float_t p1); - virtual void SetMUONACC(Bool_t acc=0, Float_t angmin=2, Float_t angmax=9); + virtual void SetMaxStepGas(Float_t p1); + virtual void SetMaxStepAlu(Float_t p1); + virtual void SetMaxDestepGas(Float_t p1); + virtual void SetMaxDestepAlu(Float_t p1); + virtual void SetMuonAcc(Bool_t acc=0, Float_t angmin=2, Float_t angmax=9); // Response Simulation virtual void MakePadHits(Float_t xhit,Float_t yhit,Float_t eloss,Int_t id); // Return reference to Chamber #id virtual AliMUONchamber& Chamber(Int_t id) {return *((AliMUONchamber *) (*fChambers)[id]);} // Retrieve pad hits for a given Hit - virtual AliMUONcluster* FirstPad(AliMUONhit *); - virtual AliMUONcluster* NextPad(); + virtual AliMUONcluster* FirstPad(AliMUONhit *, TClonesArray *); + virtual AliMUONcluster* NextPad(TClonesArray *); // Return pointers to digits TObjArray *Dchambers() {return fDchambers;} Int_t *Ndch() {return fNdch;} virtual TClonesArray *DigitsAddress(Int_t id) {return ((TClonesArray *) (*fDchambers)[id]);} // Return pointers to reconstructed clusters - virtual TObjArray *RecClusters(Int_t iCh, Int_t iCat) - {return ( (TObjArray*) (*fRecClusters)[iCh+iCat*10]);} + // virtual TObjArray *RecClusters(Int_t iCh, Int_t iCat) + // {return ( (TObjArray*) (*fRecClusters)[iCh+iCat*10]);} - + TObjArray *RawClusters() {return fRawClusters;} + Int_t *Nrawch() {return fNrawch;} + virtual TClonesArray *RawClustAddress(Int_t id) {return ((TClonesArray *) (*fRawClusters)[id]);} + +// modifs perso + AliMUONRawCluster *RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster); + + + // Return pointers to list of correlated clusters + TObjArray *CathCorrel() {return fCathCorrel;} + Int_t *Ncorch() {return fNcorch;} + virtual TClonesArray *CathCorrelAddress(Int_t id) + {return ((TClonesArray *) (*fCathCorrel)[id]);} + +// modifs perso +// virtual TClonesArray *CathCorrelAddress2(Int_t id) +// {return ((TClonesArray *) (*fCathCorrel2)[id]);} + +// Return pointer to TreeC + TTree *TreeC() {return fTreeC;} protected: TObjArray *fChambers; // List of Tracking Chambers Int_t fNclusters; // Number of clusters TClonesArray *fClusters; // List of clusters TObjArray *fDchambers; // List of digits - TObjArray *fRecClusters; // List of clusters Int_t *fNdch; // Number of digits + + // TObjArray *fRecClusters; // List of clusters + + TObjArray *fRawClusters; // List of raw clusters + Int_t *fNrawch; // Number of raw clusters + TObjArray *fCathCorrel; // List of correlated clusters + Int_t *fNcorch; // Number of correl clusters + TTree *fTreeC; // Cathode correl index tree + // Bool_t fAccCut; //Transport acceptance cut Float_t fAccMin; //Minimum acceptance cut used during transport @@ -392,6 +268,15 @@ class AliMUON : public AliDetector { Float_t fMaxStepAlu; // Maximum step size inside the chamber aluminum Float_t fMaxDestepGas; // Maximum relative energy loss in gas Float_t fMaxDestepAlu; // Maximum relative energy loss in aluminum +// +// modifs perso +// Parameters for reconstruction program + Double_t fSPxzCut; // Pxz cut (GeV/c) to begin the track finding + Double_t fSSigmaCut; // Number of sig. delimiting the searching areas + Double_t fSXPrec; // Chamber precision in X (cm) + Double_t fSYPrec; // Chamber precision in Y (cm) + + Text_t *fFileName; protected: @@ -427,6 +312,69 @@ protected: ClassDef(AliMUONRecCluster,1) //Cluster object for set:MUON }; //___________________________________________ + +class AliMUONRawCluster : public TObject { +public: + + Int_t fTracks[3]; //labels of overlapped tracks + Int_t fQ ; // Q of cluster (in ADC counts) + Float_t fX ; // X of cluster + Float_t fY ; // Y of cluster + Int_t fPeakSignal; + Int_t fIndexMap[50]; //indeces of digits + Int_t fOffsetMap[50]; //Emmanuel special + Float_t fContMap[50]; //Contribution from digit + Int_t fPhysicsMap[50]; + Int_t fMultiplicity; //cluster multiplicity + Int_t fNcluster[2]; + Int_t fClusterType; + public: + AliMUONRawCluster() { + fTracks[0]=fTracks[1]=fTracks[2]=-1; + fQ=0; fX=fY=0; fMultiplicity=0; + for (int k=0;k<50;k++) { + fIndexMap[k]=-1; + fOffsetMap[k]=0; + fContMap[k]=0; + fPhysicsMap[k]=-1; + } + fNcluster[0]=fNcluster[1]=-1; + } + virtual ~AliMUONRawCluster() {} + + Float_t GetRadius() {return TMath::Sqrt(fX*fX+fY*fY);} + + Bool_t IsSortable() const {return true;} + Int_t Compare(TObject *obj); + Int_t PhysicsContribution(); + static Int_t BinarySearch(Float_t r, TArrayF, Int_t from, Int_t upto); + static void SortMin(Int_t *,Float_t *,Float_t *,Float_t *,Float_t *,Int_t); + + ClassDef(AliMUONRawCluster,1) //Cluster object for set:MUON +}; + +//___________________________________________ +class AliMUONcorrelation : public TObject { +public: + + // correlation starts from the 1-st cathode + // last number in arrays corresponds to cluster on 1-st cathode + + Int_t fCorrelIndex[4]; // entry number in TreeR for the associated + // cluster candidates on the 2-nd cathode + Float_t fX[4] ; // X of clusters on the 2-nd cathode + Float_t fY[4] ; // Y of clusters + +public: + AliMUONcorrelation() { + fCorrelIndex[0]=fCorrelIndex[1]=fCorrelIndex[2]=fCorrelIndex[3]=0; + fX[0]=fX[1]=fX[2]=fX[3]=0; fY[0]=fY[1]=fY[2]=fY[3]=0; + } + AliMUONcorrelation(Int_t *idx, Float_t *x, Float_t *y); + virtual ~AliMUONcorrelation() {} + ClassDef(AliMUONcorrelation,1) //Cathode correlation object for set:MUON +}; + #endif diff --git a/MUON/AliMUONClusterFinder.cxx b/MUON/AliMUONClusterFinder.cxx new file mode 100644 index 00000000000..687559a8ec0 --- /dev/null +++ b/MUON/AliMUONClusterFinder.cxx @@ -0,0 +1,1110 @@ +#include "AliMUONClusterFinder.h" +#include "TTree.h" +#include "AliRun.h" +#include +#include +#include +#include +#include +#include + +ClassImp(AliMUONRecCluster) +//_____________________________________________________________________ +static AliMUONsegmentation* gSegmentation; +static AliMUONresponse* gResponse; +static Int_t gix[500]; +static Int_t giy[500]; +static Float_t gCharge[500]; +static Int_t gNbins; +static Int_t gFirst=kTRUE; +static TMinuit *gMyMinuit ; +void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag); +static Int_t gChargeTot; + + +AliMUONRecCluster::AliMUONRecCluster() + +{ + fDigits=0; + fNdigit=-1; +} + +AliMUONRecCluster:: +AliMUONRecCluster(Int_t FirstDigit,Int_t Ichamber, Int_t Icathod) +{ + fX = 0.; + fY = 0.; + fDigits = new TArrayI(10); + fNdigit=0; + AddDigit(FirstDigit); + fChamber=Ichamber; + fCathod=Icathod; +} + +void AliMUONRecCluster::AddDigit(Int_t Digit) +{ + if (fNdigit==fDigits->GetSize()) { + //enlarge the list by hand! + Int_t *array= new Int_t[fNdigit*2]; + for(Int_t i=0;iAt(i); + fDigits->Adopt(fNdigit*2,array); + } + fDigits->AddAt(Digit,fNdigit); + fNdigit++; +} + + +AliMUONRecCluster::~AliMUONRecCluster() +{ + if (fDigits) + delete fDigits; +} + +Int_t AliMUONRecCluster::FirstDigitIndex() +{ + fCurrentDigit=0; + return fDigits->At(fCurrentDigit); +} + +Int_t AliMUONRecCluster::NextDigitIndex() +{ + fCurrentDigit++; + if (fCurrentDigitAt(fCurrentDigit); + else + return InvalidDigitIndex(); +} + +Int_t AliMUONRecCluster::NDigits() +{ + return fNdigit; +} +void AliMUONRecCluster::Finish() +{ + // In order to reconstruct coordinates, one has to + // get back to the digits which is not trivial here, + // because we don't know where digits are stored! + // Center Of Gravity, or other method should be + // a property of AliMUON class! +} + + +//---------------------------------------------------------- +ClassImp(AliMUONClusterFinder) + + AliMUONClusterFinder::AliMUONClusterFinder +(AliMUONsegmentation *segmentation, AliMUONresponse *response, + TClonesArray *digits, Int_t chamber) +{ + fSegmentation=segmentation; + fResponse=response; + + fDigits=digits; + fNdigits = fDigits->GetEntriesFast(); + fChamber=chamber; + fRawClusters=new TClonesArray("AliMUONRawCluster",10000); + fNRawClusters=0; + fCogCorr = 0; + SetNperMax(); + SetClusterSize(); + SetDeclusterFlag(); + fNPeaks=-1; +} + + AliMUONClusterFinder::AliMUONClusterFinder() +{ + fSegmentation=0; + fResponse=0; + + fDigits=0; + fNdigits = 0; + fChamber=-1; + fRawClusters=new TClonesArray("AliMUONRawCluster",10000); + fNRawClusters=0; + fHitMap = 0; + fCogCorr = 0; + SetNperMax(); + SetClusterSize(); + SetDeclusterFlag(); + fNPeaks=-1; +} + +void AliMUONClusterFinder::AddRawCluster(const AliMUONRawCluster c) +{ + // + // Add a raw cluster copy to the list + // + AliMUON *MUON=(AliMUON*)gAlice->GetModule("MUON"); + MUON->AddRawCluster(fChamber,c); + fNRawClusters++; +} + + + +void AliMUONClusterFinder::Decluster(AliMUONRawCluster *cluster) +{ +// AliMUONdigit *dig; +// Int_t q; + + + Int_t mul = cluster->fMultiplicity; +// printf("Decluster - multiplicity %d \n",mul); + + if (mul == 1 || mul ==2) { +// printf("\n Nothing special for 1- and 2-clusters \n"); +// +// Nothing special for 1- and 2-clusters + if (fNPeaks != 0) { + cluster->fNcluster[0]=fNPeaks; + cluster->fNcluster[1]=0; + } + AddRawCluster(*cluster); + fNPeaks++; + } else if (mul ==3) { +// +// 3-cluster, check topology +// printf("\n 3-cluster, check topology \n"); + if (fDeclusterFlag) { + if (Centered(cluster)) { + // ok, cluster is centered + // printf("\n ok, cluster is centered \n"); + } else { + // cluster is not centered, split into 2+1 + // printf("\n cluster is not centered, split into 2+1 \n"); + } + } else { + if (fNPeaks != 0) { + cluster->fNcluster[0]=fNPeaks; + cluster->fNcluster[1]=0; + } + AddRawCluster(*cluster); + fNPeaks++; + } + } else { + //if (mul < 12) { + // printf("Decluster - multiplicity > 45 %d \n",mul); + //printf("Decluster - multiplicity < 25 %d \n",mul); +// +// 4-and more-pad clusters +// + if (mul <= fClusterSize) { + if (fDeclusterFlag) { + SplitByLocalMaxima(cluster); + } else { + if (fNPeaks != 0) { + cluster->fNcluster[0]=fNPeaks; + cluster->fNcluster[1]=0; + } + AddRawCluster(*cluster); + fNPeaks++; + } + } + //} + } // multiplicity +} + + +Bool_t AliMUONClusterFinder::Centered(AliMUONRawCluster *cluster) +{ + AliMUONdigit* dig; + dig= (AliMUONdigit*)fDigits->UncheckedAt(cluster->fIndexMap[0]); + Int_t ix=dig->fPadX; + Int_t iy=dig->fPadY; + Int_t nn; + Int_t X[kMaxNeighbours], Y[kMaxNeighbours], XN[kMaxNeighbours], YN[kMaxNeighbours]; + + fSegmentation->Neighbours(ix,iy,&nn,X,Y); + Int_t nd=0; + for (Int_t i=0; iTestHit(X[i],Y[i]) == used) { + XN[nd]=X[i]; + YN[nd]=Y[i]; + nd++; + } + } + if (nd==2) { +// +// cluster is centered ! + if (fNPeaks != 0) { + cluster->fNcluster[0]=fNPeaks; + cluster->fNcluster[1]=0; + } + AddRawCluster(*cluster); + fNPeaks++; + return kTRUE; + } else if (nd ==1) { +// +// Highest signal on an edge, split cluster into 2+1 +// +// who is the neighbour ? + Int_t nind=fHitMap->GetHitIndex(XN[0], YN[0]); + Int_t i1= (nind==cluster->fIndexMap[1]) ? 1:2; + Int_t i2= (nind==cluster->fIndexMap[1]) ? 2:1; +// +// 2-cluster + AliMUONRawCluster cnew; + if (fNPeaks == 0) { + cnew.fNcluster[0]=-1; + cnew.fNcluster[1]=fNRawClusters; + } else { + cnew.fNcluster[0]=fNPeaks; + cnew.fNcluster[1]=0; + } + cnew.fMultiplicity=2; + cnew.fIndexMap[0]=cluster->fIndexMap[0]; + cnew.fIndexMap[1]=cluster->fIndexMap[i1]; + FillCluster(&cnew); + cnew.fClusterType=cnew.PhysicsContribution(); + AddRawCluster(cnew); + fNPeaks++; +// +// 1-cluster + cluster->fMultiplicity=1; + cluster->fIndexMap[0]=cluster->fIndexMap[i2]; + cluster->fIndexMap[1]=0; + cluster->fIndexMap[2]=0; + FillCluster(cluster); + if (fNPeaks != 0) { + cluster->fNcluster[0]=fNPeaks; + cluster->fNcluster[1]=0; + } + cluster->fClusterType=cluster->PhysicsContribution(); + AddRawCluster(*cluster); + fNPeaks++; + return kFALSE; + } else { + printf("\n Completely screwed up %d !! \n",nd); + + } + + return kFALSE; +} +void AliMUONClusterFinder::SplitByLocalMaxima(AliMUONRawCluster *c) +{ + AliMUONdigit* dig[100], *digt; + Int_t ix[100], iy[100], q[100]; + Float_t x[100], y[100]; + Int_t i; // loops over digits + Int_t j; // loops over local maxima + // Float_t xPeak[2]; + // Float_t yPeak[2]; + // Int_t threshold=500; + Int_t mul=c->fMultiplicity; +// +// dump digit information into arrays +// + for (i=0; iUncheckedAt(c->fIndexMap[i]); + ix[i]= dig[i]->fPadX; + iy[i]= dig[i]->fPadY; + q[i] = dig[i]->fSignal; + fSegmentation->GetPadCxy(ix[i], iy[i], x[i], y[i]); + } +// +// Find local maxima +// + Bool_t IsLocal[100]; + Int_t NLocal=0; + Int_t AssocPeak[100]; + Int_t IndLocal[100]; + Int_t nn; + Int_t X[kMaxNeighbours], Y[kMaxNeighbours]; + for (i=0; iNeighbours(ix[i], iy[i], &nn, X, Y); + IsLocal[i]=kTRUE; + for (j=0; jTestHit(X[j], Y[j])==empty) continue; + digt=(AliMUONdigit*) fHitMap->GetHit(X[j], Y[j]); + if (digt->fSignal > q[i]) { + IsLocal[i]=kFALSE; + break; +// +// handle special case of neighbouring pads with equal signal + } else if (digt->fSignal == q[i]) { + if (NLocal >0) { + for (Int_t k=0; k12) { + Int_t nnew=0; + for (i=0; iSetFCN(fcn); + gMyMinuit->mninit(5,10,7); + Double_t arglist[20]; + Int_t ierflag=0; + arglist[0]=1; +// gMyMinuit->mnexcm("SET ERR",arglist,1,ierflag); +// Set starting values + static Double_t vstart[5]; + vstart[0]=x[IndLocal[0]]; + vstart[1]=y[IndLocal[0]]; + vstart[2]=x[IndLocal[1]]; + vstart[3]=y[IndLocal[1]]; + vstart[4]=Float_t(q[IndLocal[0]])/ + Float_t(q[IndLocal[0]]+q[IndLocal[1]]); +// lower and upper limits + static Double_t lower[5], upper[5]; + Int_t isec=fSegmentation->Sector(ix[IndLocal[0]], iy[IndLocal[0]]); + lower[0]=vstart[0]-fSegmentation->Dpx(isec)/2; + lower[1]=vstart[1]-fSegmentation->Dpy(isec)/2; +// lower[1]=vstart[1]; + + upper[0]=lower[0]+fSegmentation->Dpx(isec); + upper[1]=lower[1]+fSegmentation->Dpy(isec); +// upper[1]=vstart[1]; + + isec=fSegmentation->Sector(ix[IndLocal[1]], iy[IndLocal[1]]); + lower[2]=vstart[2]-fSegmentation->Dpx(isec)/2; + lower[3]=vstart[3]-fSegmentation->Dpy(isec)/2; +// lower[3]=vstart[3]; + + upper[2]=lower[2]+fSegmentation->Dpx(isec); + upper[3]=lower[3]+fSegmentation->Dpy(isec); +// upper[3]=vstart[3]; + + lower[4]=0.; + upper[4]=1.; +// step sizes + static Double_t step[5]={0.005, 0.03, 0.005, 0.03, 0.01}; + + gMyMinuit->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag); + gMyMinuit->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag); + gMyMinuit->mnparm(2,"x2",vstart[2],step[2],lower[2],upper[2],ierflag); + gMyMinuit->mnparm(3,"y2",vstart[3],step[3],lower[3],upper[3],ierflag); + gMyMinuit->mnparm(4,"a0",vstart[4],step[4],lower[4],upper[4],ierflag); +// ready for minimisation + gMyMinuit->SetPrintLevel(-1); + gMyMinuit->mnexcm("SET OUT", arglist, 0, ierflag); + arglist[0]= -1; + arglist[1]= 0; + + gMyMinuit->mnexcm("SET NOGR", arglist, 0, ierflag); + gMyMinuit->mnexcm("SCAN", arglist, 0, ierflag); + gMyMinuit->mnexcm("EXIT" , arglist, 0, ierflag); +// Print results +// Double_t amin,edm,errdef; +// Int_t nvpar,nparx,icstat; +// gMyMinuit->mnstat(amin,edm,errdef,nvpar,nparx,icstat); +// gMyMinuit->mnprin(3,amin); +// Get fitted parameters + + Double_t xrec[2], yrec[2], qfrac; + TString chname; + Double_t epxz, b1, b2; + Int_t ierflg; + gMyMinuit->mnpout(0, chname, xrec[0], epxz, b1, b2, ierflg); + gMyMinuit->mnpout(1, chname, yrec[0], epxz, b1, b2, ierflg); + gMyMinuit->mnpout(2, chname, xrec[1], epxz, b1, b2, ierflg); + gMyMinuit->mnpout(3, chname, yrec[1], epxz, b1, b2, ierflg); + gMyMinuit->mnpout(4, chname, qfrac, epxz, b1, b2, ierflg); + printf("\n %f %f %f %f %f\n", xrec[0], yrec[0], xrec[1], yrec[1],qfrac); +// delete gMyMinuit; + + + // + // One cluster for each maximum + // + for (j=0; j<2; j++) { + AliMUONRawCluster cnew; + if (fNPeaks == 0) { + cnew.fNcluster[0]=-1; + cnew.fNcluster[1]=fNRawClusters; + } else { + cnew.fNcluster[0]=fNPeaks; + cnew.fNcluster[1]=0; + } + cnew.fMultiplicity=0; + cnew.fX=Float_t(xrec[j]); + cnew.fY=Float_t(yrec[j]); + if (j==0) { + cnew.fQ=static_cast(gChargeTot*qfrac); + } else { + cnew.fQ=static_cast(gChargeTot*(1-qfrac)); + } + gSegmentation->SetHit(xrec[j],yrec[j]); + for (i=0; ifIndexMap[i]; + gSegmentation->SetPad(gix[i], giy[i]); + Float_t q1=gResponse->IntXY(gSegmentation); + cnew.fContMap[cnew.fMultiplicity]=Float_t(q[i])/(q1*cnew.fQ); + cnew.fMultiplicity++; + } + FillCluster(&cnew,0); + //printf("\n x,y %f %f ", cnew.fX, cnew.fY); + cnew.fClusterType=cnew.PhysicsContribution(); + AddRawCluster(cnew); + fNPeaks++; + } + } + + Bool_t fitted=true; + + if (NLocal !=2 || !fitted) { + // Check if enough local clusters have been found, + // if not add global maxima to the list + // + Int_t nPerMax; + if (NLocal!=0) { + nPerMax=mul/NLocal; + } else { + printf("\n Warning, no local maximum found \n"); + nPerMax=fNperMax+1; + } + + if (nPerMax > fNperMax) { + Int_t nGlob=mul/fNperMax-NLocal+1; + if (nGlob > 0) { + Int_t nnew=0; + for (i=0; iqmax) { + dmin=d; + qmax=ql; + AssocPeak[i]=j; + } + } + } + } + + + // + // One cluster for each maximum + // + for (j=0; jfIndexMap[IndLocal[j]]; + cnew.fMultiplicity=1; + for (i=0; ifIndexMap[i]; + cnew.fMultiplicity++; + } + } + FillCluster(&cnew); + cnew.fClusterType=cnew.PhysicsContribution(); + AddRawCluster(cnew); + fNPeaks++; + } + } + +} + + +void AliMUONClusterFinder::FillCluster(AliMUONRawCluster* c, Int_t flag) +{ +// +// Completes cluster information starting from list of digits +// + AliMUONdigit* dig; + Float_t x, y; + Int_t ix, iy; + Float_t frac=0; + + c->fPeakSignal=0; + if (flag) { + c->fX=0; + c->fY=0; + c->fQ=0; + } + //c->fQ=0; + + + for (Int_t i=0; ifMultiplicity; i++) + { + dig= (AliMUONdigit*)fDigits->UncheckedAt(c->fIndexMap[i]); + ix=dig->fPadX+c->fOffsetMap[i]; + iy=dig->fPadY; + Int_t q=dig->fSignal; + if (dig->fPhysics >= dig->fSignal) { + c->fPhysicsMap[i]=2; + } else if (dig->fPhysics == 0) { + c->fPhysicsMap[i]=0; + } else c->fPhysicsMap[i]=1; +// +// +// peak signal and track list + if (flag) { + if (q>c->fPeakSignal) { + c->fPeakSignal=q; +/* + c->fTracks[0]=dig->fTracks[0]; + c->fTracks[1]=dig->fTracks[1]; + c->fTracks[2]=dig->fTracks[2]; +*/ + //c->fTracks[0]=dig->fTrack; + c->fTracks[0]=dig->fHit; + c->fTracks[1]=dig->fTracks[0]; + c->fTracks[2]=dig->fTracks[1]; + } + } else { + if (c->fContMap[i] > frac) { + frac=c->fContMap[i]; + c->fPeakSignal=q; +/* + c->fTracks[0]=dig->fTracks[0]; + c->fTracks[1]=dig->fTracks[1]; + c->fTracks[2]=dig->fTracks[2]; +*/ + //c->fTracks[0]=dig->fTrack; + c->fTracks[0]=dig->fHit; + c->fTracks[1]=dig->fTracks[0]; + c->fTracks[2]=dig->fTracks[1]; + } + } +// + if (flag) { + fSegmentation->GetPadCxy(ix, iy, x, y); + c->fX += q*x; + c->fY += q*y; + c->fQ += q; + } + + } // loop over digits + + if (flag) { + + c->fX/=c->fQ; + c->fX=fSegmentation->GetAnod(c->fX); + c->fY/=c->fQ; +// +// apply correction to the coordinate along the anode wire +// + x=c->fX; + y=c->fY; + fSegmentation->GetPadIxy(x, y, ix, iy); + fSegmentation->GetPadCxy(ix, iy, x, y); + Int_t isec=fSegmentation->Sector(ix,iy); + TF1* CogCorr = fSegmentation->CorrFunc(isec-1); + + if (CogCorr) { + Float_t YonPad=(c->fY-y)/fSegmentation->Dpy(isec); + c->fY=c->fY-CogCorr->Eval(YonPad, 0, 0); + } + } +} + + +void AliMUONClusterFinder::FindCluster(Int_t i, Int_t j, AliMUONRawCluster &c){ +// +// Find clusters +// +// +// Add i,j as element of the cluster +// + + Int_t idx = fHitMap->GetHitIndex(i,j); + AliMUONdigit* dig = (AliMUONdigit*) fHitMap->GetHit(i,j); + Int_t q=dig->fSignal; + if (q > TMath::Abs(c.fPeakSignal)) { + c.fPeakSignal=q; +/* + c.fTracks[0]=dig->fTracks[0]; + c.fTracks[1]=dig->fTracks[1]; + c.fTracks[2]=dig->fTracks[2]; +*/ + //c.fTracks[0]=dig->fTrack; + c.fTracks[0]=dig->fHit; + c.fTracks[1]=dig->fTracks[0]; + c.fTracks[2]=dig->fTracks[1]; + } +// +// Make sure that list of digits is ordered +// + Int_t mu=c.fMultiplicity; + c.fIndexMap[mu]=idx; + + if (dig->fPhysics >= dig->fSignal) { + c.fPhysicsMap[mu]=2; + } else if (dig->fPhysics == 0) { + c.fPhysicsMap[mu]=0; + } else c.fPhysicsMap[mu]=1; + + if (mu > 0) { + for (Int_t ind=mu-1; ind>=0; ind--) { + Int_t ist=(c.fIndexMap)[ind]; + Int_t ql=((AliMUONdigit*)fDigits + ->UncheckedAt(ist))->fSignal; + if (q>ql) { + c.fIndexMap[ind]=idx; + c.fIndexMap[ind+1]=ist; + } else { + break; + } + } + } + + c.fMultiplicity++; + + if (c.fMultiplicity >= 50 ) { + printf("FindCluster - multiplicity >50 %d \n",c.fMultiplicity); + c.fMultiplicity=49; + } + +// Prepare center of gravity calculation + Float_t x, y; + fSegmentation->GetPadCxy(i, j, x, y); + c.fX += q*x; + c.fY += q*y; + c.fQ += q; +// Flag hit as taken + fHitMap->FlagHit(i,j); +// +// Now look recursively for all neighbours +// + Int_t nn; + Int_t Xlist[kMaxNeighbours], Ylist[kMaxNeighbours]; + fSegmentation->Neighbours(i,j,&nn,Xlist,Ylist); + for (Int_t in=0; inTestHit(ix,iy)==unused) FindCluster(ix, iy, c); + } +} + +//_____________________________________________________________________________ + +void AliMUONClusterFinder::FindRawClusters() +{ + // + // simple MUON cluster finder from digits -- finds neighbours and + // fill the tree with raw clusters + // + if (!fNdigits) return; + + fHitMap = new AliMUONHitMapA1(fSegmentation, fDigits); + + AliMUONdigit *dig; + + Int_t ndig; + Int_t nskip=0; + Int_t ncls=0; + fHitMap->FillHits(); + for (ndig=0; ndigUncheckedAt(ndig); + Int_t i=dig->fPadX; + Int_t j=dig->fPadY; + if (fHitMap->TestHit(i,j)==used ||fHitMap->TestHit(i,j)==empty) { + nskip++; + continue; + } + AliMUONRawCluster c; + c.fMultiplicity=0; + c.fPeakSignal=dig->fSignal; +/* + c.fTracks[0]=dig->fTracks[0]; + c.fTracks[1]=dig->fTracks[1]; + c.fTracks[2]=dig->fTracks[2]; +*/ + //c.fTracks[0]=dig->fTrack; + c.fTracks[0]=dig->fHit; + c.fTracks[1]=dig->fTracks[0]; + c.fTracks[2]=dig->fTracks[1]; + // tag the beginning of cluster list in a raw cluster + c.fNcluster[0]=-1; + FindCluster(i,j, c); + // center of gravity + c.fX /= c.fQ; + c.fX=fSegmentation->GetAnod(c.fX); + c.fY /= c.fQ; +// +// apply correction to the coordinate along the anode wire +// + Int_t ix,iy; + Float_t x=c.fX; + Float_t y=c.fY; + fSegmentation->GetPadIxy(x, y, ix, iy); + fSegmentation->GetPadCxy(ix, iy, x, y); + Int_t isec=fSegmentation->Sector(ix,iy); + TF1* CogCorr=fSegmentation->CorrFunc(isec-1); + if (CogCorr) { + Float_t YonPad=(c.fY-y)/fSegmentation->Dpy(isec); + c.fY=c.fY-CogCorr->Eval(YonPad,0,0); + } + +// +// Analyse cluster and decluster if necessary +// + ncls++; + c.fNcluster[1]=fNRawClusters; + c.fClusterType=c.PhysicsContribution(); + Decluster(&c); + fNPeaks=0; +// +// +// +// reset Cluster object + for (int k=0;kGiveTestPoints(n, x, y); + for (i=0; iSetCorrFunc(i, new TF1(func)); + } + } +} + + +void AliMUONClusterFinder:: +SinoidalFit(Float_t x, Float_t y, TF1 &func) +{ +// + static Int_t count=0; + char canvasname[3]; + count++; + sprintf(canvasname,"c%d",count); + + Int_t ns=101; + Float_t xg[ns], yg[ns], xrg[ns], yrg[ns]; + Float_t xsig[ns], ysig[ns]; + + AliMUONsegmentation *segmentation=fSegmentation; + + Int_t ix,iy; + segmentation->GetPadIxy(x,y,ix,iy); + segmentation->GetPadCxy(ix,iy,x,y); + Int_t isec=segmentation->Sector(ix,iy); +// Pad Limits + Float_t xmin = x-segmentation->Dpx(isec)/2; + Float_t ymin = y-segmentation->Dpy(isec)/2; +// +// Integration Limits + Float_t dxI=fResponse->SigmaIntegration()*fResponse->ChargeSpreadX(); + Float_t dyI=fResponse->SigmaIntegration()*fResponse->ChargeSpreadY(); + +// +// Scanning +// + Int_t i; + Float_t qp; +// +// y-position + Float_t yscan=ymin; + Float_t dy=segmentation->Dpy(isec)/(ns-1); + + for (i=0; iSigGenInit(x, yscan, 0); + + for (segmentation->FirstPad(x, yscan, dxI, dyI); + segmentation->MorePads(); + segmentation->NextPad()) + { + qp=fResponse->IntXY(segmentation); + qp=TMath::Abs(qp); +// +// + if (qp > 1.e-4) { + qcheck+=qp; + Int_t ixs=segmentation->Ix(); + Int_t iys=segmentation->Iy(); + Float_t xs,ys; + segmentation->GetPadCxy(ixs,iys,xs,ys); + sum+=qp*ys; + } + } // Pad loop + Float_t ycog=sum/qcheck; + yg[i]=(yscan-y)/segmentation->Dpy(isec); + yrg[i]=(ycog-y)/segmentation->Dpy(isec); + ysig[i]=ycog-yscan; + yscan+=dy; + } // scan loop +// +// x-position + Float_t xscan=xmin; + Float_t dx=segmentation->Dpx(isec)/(ns-1); + + for (i=0; iSigGenInit(xscan, y, 0); + + for (segmentation->FirstPad(xscan, y, dxI, dyI); + segmentation->MorePads(); + segmentation->NextPad()) + { + qp=fResponse->IntXY(segmentation); + qp=TMath::Abs(qp); +// +// + if (qp > 1.e-2) { + qcheck+=qp; + Int_t ixs=segmentation->Ix(); + Int_t iys=segmentation->Iy(); + Float_t xs,ys; + segmentation->GetPadCxy(ixs,iys,xs,ys); + sum+=qp*xs; + } + } // Pad loop + Float_t xcog=sum/qcheck; + xcog=segmentation->GetAnod(xcog); + + xg[i]=(xscan-x)/segmentation->Dpx(isec); + xrg[i]=(xcog-x)/segmentation->Dpx(isec); + xsig[i]=xcog-xscan; + xscan+=dx; + } +// +// Creates a Root function based on function sinoid above +// and perform the fit +// + // TGraph *graphx = new TGraph(ns,xg ,xsig); + // TGraph *graphxr= new TGraph(ns,xrg,xsig); + // TGraph *graphy = new TGraph(ns,yg ,ysig); + TGraph *graphyr= new TGraph(ns,yrg,ysig); + + Double_t sinoid(Double_t *x, Double_t *par); + new TF1("sinoidf",sinoid,0.5,0.5,5); + graphyr->Fit("sinoidf","Q"); + func = *((TF1*)((graphyr->GetListOfFunctions())->At(0))); +/* + + TCanvas *c1=new TCanvas(canvasname,canvasname,400,10,600,700); + TPad* pad11 = new TPad("pad11"," ",0.01,0.51,0.49,0.99); + TPad* pad12 = new TPad("pad12"," ",0.51,0.51,0.99,0.99); + TPad* pad13 = new TPad("pad13"," ",0.01,0.01,0.49,0.49); + TPad* pad14 = new TPad("pad14"," ",0.51,0.01,0.99,0.49); + pad11->SetFillColor(11); + pad12->SetFillColor(11); + pad13->SetFillColor(11); + pad14->SetFillColor(11); + pad11->Draw(); + pad12->Draw(); + pad13->Draw(); + pad14->Draw(); + +// + pad11->cd(); + graphx->SetFillColor(42); + graphx->SetMarkerColor(4); + graphx->SetMarkerStyle(21); + graphx->Draw("AC"); + graphx->GetHistogram()->SetXTitle("x on pad"); + graphx->GetHistogram()->SetYTitle("xcog-x"); + + + pad12->cd(); + graphxr->SetFillColor(42); + graphxr->SetMarkerColor(4); + graphxr->SetMarkerStyle(21); + graphxr->Draw("AP"); + graphxr->GetHistogram()->SetXTitle("xcog on pad"); + graphxr->GetHistogram()->SetYTitle("xcog-x"); + + + pad13->cd(); + graphy->SetFillColor(42); + graphy->SetMarkerColor(4); + graphy->SetMarkerStyle(21); + graphy->Draw("AF"); + graphy->GetHistogram()->SetXTitle("y on pad"); + graphy->GetHistogram()->SetYTitle("ycog-y"); + + + + pad14->cd(); + graphyr->SetFillColor(42); + graphyr->SetMarkerColor(4); + graphyr->SetMarkerStyle(21); + graphyr->Draw("AF"); + graphyr->GetHistogram()->SetXTitle("ycog on pad"); + graphyr->GetHistogram()->SetYTitle("ycog-y"); + + c1->Update(); +*/ +} + +Double_t sinoid(Double_t *x, Double_t *par) +{ + Double_t arg = -2*TMath::Pi()*x[0]; + Double_t fitval= par[0]*TMath::Sin(arg)+ + par[1]*TMath::Sin(2*arg)+ + par[2]*TMath::Sin(3*arg)+ + par[3]*TMath::Sin(4*arg)+ + par[4]*TMath::Sin(5*arg); + return fitval; + } + + +Double_t DoubleGauss(Double_t *x, Double_t *par) +{ + Double_t arg1 = (x[0]-par[1])/0.18; + Double_t arg2 = (x[0]-par[3])/0.18; + Double_t fitval= par[0]*TMath::Exp(-arg1*arg1/2) + +par[2]*TMath::Exp(-arg2*arg2/2); + return fitval; + } + +Float_t DiscrCharge(Int_t i,Double_t *par) +{ +// par[0] x-position of first cluster +// par[1] y-position of first cluster +// par[2] x-position of second cluster +// par[3] y-position of second cluster +// par[4] charge fraction of first cluster +// 1-par[4] charge fraction of second cluster + + static Float_t qtot; + if (gFirst) { + qtot=0; + for (Int_t jbin=0; jbin(qtot); + + } + gSegmentation->SetPad(gix[i], giy[i]); +// First Cluster + gSegmentation->SetHit(par[0],par[1]); + Float_t q1=gResponse->IntXY(gSegmentation); + +// Second Cluster + gSegmentation->SetHit(par[2],par[3]); + Float_t q2=gResponse->IntXY(gSegmentation); + + Float_t value = qtot*(par[4]*q1+(1.-par[4])*q2); + return value; +} + +// +// Minimisation function +void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag) +{ + Int_t i; + Float_t delta; + Float_t chisq=0; + Float_t qcont=0; + Float_t qtot=0; + + for (i=0; iGetEntriesFast(); + } + + virtual void SetChamber(Int_t ich){ + fChamber=ich; + } + + virtual void AddRawCluster(const AliMUONRawCluster); + // Search for raw clusters + virtual void FindRawClusters(); + virtual void FindCluster(Int_t i, Int_t j, AliMUONRawCluster &c); + // Decluster + virtual void Decluster(AliMUONRawCluster *cluster); + // Set max. Number of pads per local cluster + virtual void SetNperMax(Int_t npermax=5) {fNperMax = npermax;} + // Decluster ? + virtual void SetDeclusterFlag(Int_t flag=1) {fDeclusterFlag =flag;} + // Set max. cluster size ; bigger clusters will be rejected + virtual void SetClusterSize(Int_t clsize=5) {fClusterSize = clsize;} + // Self Calibration of COG + virtual void CalibrateCOG(); + virtual void SinoidalFit(Float_t x, Float_t y, TF1 &func); + // + virtual void CorrectCOG(){;} + + // + virtual Bool_t Centered(AliMUONRawCluster *cluster); + virtual void SplitByLocalMaxima(AliMUONRawCluster *cluster); + virtual void FillCluster(AliMUONRawCluster *cluster, Int_t); + virtual void FillCluster(AliMUONRawCluster *cluster) { + FillCluster(cluster,1);} + TClonesArray* RawClusters(){return fRawClusters;} + ClassDef(AliMUONClusterFinder,1) //Class for clustering and reconstruction of space points +}; +#endif + + + + + + + diff --git a/MUON/AliMUONClusterFinderv0.cxx b/MUON/AliMUONClusterFinderv0.cxx new file mode 100644 index 00000000000..64b138fd8f0 --- /dev/null +++ b/MUON/AliMUONClusterFinderv0.cxx @@ -0,0 +1,766 @@ +#include "AliMUONClusterFinderv0.h" +#include "AliMUONSegResV1.h" +//#include "TTree.h" +//#include "AliRun.h" +//#include +//#include +//#include +//#include + +//---------------------------------------------------------- +ClassImp(AliMUONClusterFinderv0) + + AliMUONClusterFinderv0::AliMUONClusterFinderv0 +(AliMUONsegmentation *segmentation, AliMUONresponse *response, + TClonesArray *digits, Int_t chamber) : AliMUONClusterFinder(segmentation,response,digits,chamber) +{;} + + AliMUONClusterFinderv0::AliMUONClusterFinderv0():AliMUONClusterFinder() +{;} + +/* +void AliMUONClusterFinder::AddRawCluster(const AliMUONRawCluster c) +{ + // + // Add a raw cluster copy to the list + // + AliMUON *MUON=(AliMUON*)gAlice->GetModule("MUON"); + MUON->AddRawCluster(fChamber,c); + fNRawClusters++; +} +*/ + + + +void AliMUONClusterFinderv0::Decluster(AliMUONRawCluster *cluster) +{ +// AliMUONdigit *dig; +// Int_t q; + static int done=0; + if (!done) { + printf("Calling decluster\n"); + done=1; + } + + + + Int_t mul = cluster->fMultiplicity; +// printf("Decluster - multiplicity %d \n",mul); + + if (mul == 1) { +// printf("\n Nothing special for 1-clusters \n"); +// +// Nothing special for 1-clusters +// + AddRawCluster(*cluster); + } else if (mul ==2) { +// +// 2-cluster, compute offset +// + SetOffset(cluster); + FillCluster(cluster); + AddRawCluster(*cluster); + } else if (mul ==3) { +// +// 3-cluster, check topology +// printf("\n 3-cluster, check topology \n"); +// + if (Centered(cluster)) { +// +// ok, cluster is centered +// printf("\n ok, cluster is centered \n"); + } else { +// +// cluster is not centered, split into 2+1 +// printf("\n cluster is not centered, split into 2+1 \n"); + } + + } else { + if (mul >(50-5)) printf("Decluster - multiplicity %d approaching 50\n",mul); +// +// 4-and more-pad clusters +// + SplitByLocalMaxima(cluster); + } // multiplicity +} + +Int_t AliMUONClusterFinderv0::PeakOffsetAndCoordinates(Int_t DigitIndex, Float_t *X, Float_t *Y) +// +// Computes for which allowed offsets the digit has the highest neighbouring charge +// Returns the value of the offset, and sets the pyisical coordinates of that pad +// Loop on physical neighbours is specific to AliMUONsegmentationV1 +{ +Int_t nPara, offset, returnOffset=0 ; +AliMUONdigit* dig= (AliMUONdigit*)fDigits->UncheckedAt(DigitIndex); +AliMUONsegmentationV1* seg = (AliMUONsegmentationV1*) fSegmentation; +seg->GetNParallelAndOffset(dig->fPadX,dig->fPadY,&nPara,&offset); +if (nPara>1) + { + Float_t qMax=0; + for (Int_t i=0;ifPadY+dy; + Int_t padX=seg->Ix((Int_t) (dig->fPadX+dx+i*offset) , padY); + if (fHitMap->TestHit(padX, padY)==empty) + continue; + AliMUONdigit* digt = (AliMUONdigit*) fHitMap->GetHit(padX,padY); + q += digt->fSignal; + } + if (q>qMax) + { + returnOffset=i*offset; + qMax=q; + } + } + } +fSegmentation->GetPadCxy(dig->fPadX+returnOffset,dig->fPadY,*X,*Y); +return returnOffset; +} + + +void AliMUONClusterFinderv0::SetOffset(AliMUONRawCluster *cluster) +// compute the offsets assuming that there is only one peak ! +{ +//DumpCluster(cluster); +Float_t X,Y; +cluster->fOffsetMap[0]=PeakOffsetAndCoordinates(cluster->fIndexMap[0],&X,&Y); +for (Int_t i=1;ifMultiplicity;i++) { + AliMUONdigit* dig= (AliMUONdigit*)fDigits->UncheckedAt(cluster->fIndexMap[i]); + fSegmentation->Distance2AndOffset(dig->fPadX,dig->fPadY,X,Y,&(cluster->fOffsetMap[i])); + } +} + +void AliMUONClusterFinderv0::DumpCluster(AliMUONRawCluster *cluster) +{ +printf ("other cluster\n"); +for (Int_t i=0; ifMultiplicity; i++) + { + AliMUONdigit* dig= (AliMUONdigit*)fDigits->UncheckedAt(cluster->fIndexMap[i]); + Int_t nPara, offset; + fSegmentation->GetNParallelAndOffset(dig->fPadX,dig->fPadY,&nPara,&offset); + + printf("X %d Y %d Q %d NPara %d \n",dig->fPadX, dig->fPadY,dig->fSignal, nPara); + } +} + +Bool_t AliMUONClusterFinderv0::Centered(AliMUONRawCluster *cluster) +{ + AliMUONdigit* dig; + dig= (AliMUONdigit*)fDigits->UncheckedAt(cluster->fIndexMap[0]); + Int_t ix=dig->fPadX; + Int_t iy=dig->fPadY; + Int_t nn; + Int_t X[kMaxNeighbours], Y[kMaxNeighbours], XN[kMaxNeighbours], YN[kMaxNeighbours]; + fSegmentation->Neighbours(ix,iy,&nn,X,Y); + + Int_t nd=0; + for (Int_t i=0; iTestHit(X[i],Y[i]) == used) { + XN[nd]=X[i]; + YN[nd]=Y[i]; + nd++; + } + } + if (nd==2) { +// +// cluster is centered ! + SetOffset(cluster); + FillCluster(cluster); + AddRawCluster(*cluster); + return kTRUE; + } else if (nd ==1) { +// +// Highest signal on an edge, split cluster into 2+1 +// +// who is the neighbour ? + Int_t nind=fHitMap->GetHitIndex(XN[0], YN[0]); + Int_t i1= (nind==cluster->fIndexMap[1]) ? 1:2; + Int_t i2= (nind==cluster->fIndexMap[1]) ? 2:1; +// +// 2-cluster + AliMUONRawCluster cnew; + cnew.fMultiplicity=2; + cnew.fIndexMap[0]=cluster->fIndexMap[0]; + cnew.fIndexMap[1]=cluster->fIndexMap[i1]; + SetOffset(&cnew); + FillCluster(&cnew); + AddRawCluster(cnew); +// +// 1-cluster + cluster->fMultiplicity=1; + cluster->fIndexMap[0]=cluster->fIndexMap[i2]; + cluster->fIndexMap[1]=0; + cluster->fIndexMap[2]=0; + FillCluster(cluster); + AddRawCluster(*cluster); + return kFALSE; + } else { + printf("\n Completely screwed up %d !! \n",nd); + + } + + return kFALSE; +} + + +void AliMUONClusterFinderv0::SplitByLocalMaxima(AliMUONRawCluster *c) +{ + AliMUONdigit* dig[50], *digt; + Int_t ix[50], iy[50], q[50]; + Float_t x[50], y[50]; + Int_t i; // loops over digits + Int_t j; // loops over local maxima + + Int_t mul=c->fMultiplicity; +// +// dump digit information into arrays +// + for (i=0; iUncheckedAt(c->fIndexMap[i]); + ix[i]= dig[i]->fPadX; + iy[i]= dig[i]->fPadY; + q[i] = dig[i]->fSignal; + fSegmentation->GetPadCxy(ix[i], iy[i], x[i], y[i]); + } +// +// Find local maxima +// + Bool_t IsLocal[50]; + Int_t NLocal=0; + Int_t AssocPeak[50]; + Int_t IndLocal[50]; + Int_t nn; + Int_t X[kMaxNeighbours], Y[kMaxNeighbours]; + for (i=0; iNeighbours(ix[i], iy[i], &nn, X, Y); + IsLocal[i]=kTRUE; + for (j=0; jTestHit(X[j], Y[j])==empty) continue; + digt=(AliMUONdigit*) fHitMap->GetHit(X[j], Y[j]); + if (digt->fSignal > q[i]) { + IsLocal[i]=kFALSE; + break; +// +// handle special case of neighbouring pads with equal signal + } else if (digt->fSignal == q[i]) { + if (NLocal >0) { + for (Int_t k=0; kfOffsetMap[i]=PeakOffsetAndCoordinates(c->fIndexMap[i], &(x[i]), &(y[i])); + NLocal++; + } + } // loop over all digits +// printf("Found %d local Maxima",NLocal); +// +// Check if enough local clusters have been found, +// if not add global maxima to the list +// +// But what the hell is that ? (Manu) +// +// Int_t nPerMax=mul/NLocal; +// if (nPerMax > 5) { +// Int_t nGlob=mul/5-NLocal+1; +// if (nGlob > 0) { +// Int_t nnew=0; +// for (i=0; iDistance2AndOffset(ix[i],iy[i],x[il],y[il], &offset); + Float_t ql=q[il]; +// +// Select nearest peak +// + if (dfOffsetMap[i]=offset; + } else if (d==dmin) { +// +// If more than one take highest peak +// + if (ql>qmax) { + dmin=d; + qmax=ql; + AssocPeak[i]=j; + c->fOffsetMap[i]=offset; + } + } // end if + } // End loop on peaks + } // end loop on digits +// +// One cluster for each maximum +// + for (j=0; jfIndexMap[IndLocal[j]]; + cnew.fOffsetMap[0]=c->fOffsetMap[IndLocal[j]]; + cnew.fMultiplicity=1; + for (i=0; ifIndexMap[i]; + cnew.fOffsetMap[cnew.fMultiplicity]=c->fOffsetMap[i]; + cnew.fMultiplicity++; + } + } + FillCluster(&cnew); + AddRawCluster(cnew); + } +} + +/* +void AliMUONClusterFinderv0::FillCluster(AliMUONRawCluster* c) +{ +// +// Completes cluster information starting from list of digits +// + AliMUONdigit* dig; + Float_t x, y; + Int_t ix, iy; + + c->fPeakSignal=0; + c->fX=0; + c->fY=0; + c->fQ=0; + for (Int_t i=0; ifMultiplicity; i++) + { + dig= (AliMUONdigit*)fDigits->UncheckedAt(c->fIndexMap[i]); + ix=dig->fPadX + c.fOffsetMap[i]; // should be 0 for non-LYON + iy=dig->fPadY; + Int_t q=dig->fSignal; +// +// +// peak signal and track list + if (q>c->fPeakSignal) { + c->fPeakSignal=0; + c->fTracks[0]=dig->fTracks[0]; + c->fTracks[1]=dig->fTracks[1]; + c->fTracks[2]=dig->fTracks[2]; + } +// +// centre of gravity + fSegmentation->GetPadCxy(ix, iy, x, y); + c->fX += q*x; + c->fY += q*y; + c->fQ += q; + } + c->fX/=c->fQ; +// Not valid for inclined tracks in X !!! (Manu) +// c->fX=fSegmentation->GetAnod(c->fX); + c->fY/=c->fQ; +// +// apply correction to the coordinate along the anode wire +// + if (fCogCorr) { + x=c->fX; + y=c->fY; + fSegmentation->GetPadIxy(x, y, ix, iy); + fSegmentation->GetPadCxy(ix, iy, x, y); + Float_t YonPad=(c->fY-y)/fSegmentation->Dpy(); + c->fY=y-fCogCorr->Eval(YonPad, 0, 0); + } + +} +*/ +/* +void AliMUONClusterFinder::FindCluster(Int_t i, Int_t j, AliMUONRawCluster &c){ +// +// Find clusters +// +// +// Add i,j as element of the cluster +// + + Int_t idx = fHitMap->GetHitIndex(i,j); + AliMUONdigit* dig = (AliMUONdigit*) fHitMap->GetHit(i,j); + Int_t q=dig->fSignal; + if (q > TMath::Abs(c.fPeakSignal)) { + c.fPeakSignal=q; + c.fTracks[0]=dig->fTracks[0]; + c.fTracks[1]=dig->fTracks[1]; + c.fTracks[2]=dig->fTracks[2]; + } +// +// Make sure that list of digits is ordered +// + Int_t mu=c.fMultiplicity; + c.fIndexMap[mu]=idx; + + if (mu > 0) { + for (Int_t ind=mu-1; ind>=0; ind--) { + Int_t ist=(c.fIndexMap)[ind]; + Int_t ql=((AliMUONdigit*)fDigits + ->UncheckedAt(ist))->fSignal; + if (q>ql) { + c.fIndexMap[ind]=idx; + c.fIndexMap[ind+1]=ist; + } else { + break; + } + } + } + + c.fMultiplicity++; + + if (c.fMultiplicity >= 50 ) { + printf("FindCluster - multiplicity >50 %d \n",c.fMultiplicity); + c.fMultiplicity=50-1; + } + +// Prepare center of gravity calculation + Float_t x, y; + fSegmentation->GetPadCxy(i, j, x, y); + c.fX += q*x; + c.fY += q*y; + c.fQ += q; +// Flag hit as taken + fHitMap->FlagHit(i,j); +// +// Now look recursively for all neighbours +// + Int_t nn; + Int_t Xlist[kMaxNeighbours], Ylist[kMaxNeighbours]; + fSegmentation->Neighbours(i,j,&nn,Xlist,Ylist); + for (Int_t in=0; inTestHit(ix,iy)==unused) FindCluster(ix, iy, c); + } +} +*/ + +//_____________________________________________________________________________ + +void AliMUONClusterFinderv0::FindRawClusters() +{ + // + // simple MUON cluster finder from digits -- finds neighbours and + // fill the tree with raw clusters + // + if (!fNdigits) return; + + fHitMap = new AliMUONHitMapA1(fSegmentation, fDigits); + + AliMUONdigit *dig; + + int ndig; + int nskip=0; + + fHitMap->FillHits(); + for (ndig=0; ndigUncheckedAt(ndig); + Int_t i=dig->fPadX; + Int_t j=dig->fPadY; + if (fHitMap->TestHit(i,j)==used ||fHitMap->TestHit(i,j)==empty) { + nskip++; + continue; + } + AliMUONRawCluster c; + c.fMultiplicity=0; +// c.fPeakSignal=dig->fSignal; +// c.fTracks[0]=dig->fTracks[0]; +// c.fTracks[1]=dig->fTracks[1]; +// c.fTracks[2]=dig->fTracks[2]; + c.fPeakSignal=0; + FindCluster(i,j, c); + // center of gravity + c.fX /= c.fQ; + c.fX=fSegmentation->GetAnod(c.fX); + c.fY /= c.fQ; +// +// apply correction to the coordinate along the anode wire +// + + + if (fCogCorr) { + Int_t ix,iy; + Float_t x=c.fX; + Float_t y=c.fY; + fSegmentation->GetPadIxy(x, y, ix, iy); + fSegmentation->GetPadCxy(ix, iy, x, y); + Float_t YonPad=(c.fY-y)/fSegmentation->Dpy(); + c.fY=y-fCogCorr->Eval(YonPad,0,0); + } +// +// Analyse cluster and decluster if necessary +// + Decluster(&c); +// +// +// +// reset Cluster object + for (int k=0;kGiveTestPoints(n, x, y); + for (i=0; iGetPadIxy(x,y,ix,iy); + segmentation->GetPadCxy(ix,iy,x,y); + Int_t isec=segmentation->Sector(ix,iy); +// Pad Limits + Float_t xmin = x-segmentation->GetRealDpx(isec)/2; + Float_t ymin = y-segmentation->Dpy()/2; +// +// Integration Limits + Float_t dxI=fResponse->Nsigma()*fResponse->ChwX(); + Float_t dyI=fResponse->Nsigma()*fResponse->ChwY(); + +// +// Scanning +// + Int_t i; + Float_t qp; +// +// y-position + Float_t yscan=ymin; + Float_t dy=segmentation->Dpy()/(ns-1); + + for (i=0; iSigGenInit(x, yscan, 0); + + for (segmentation->FirstPad(x, yscan, dxI, dyI); + segmentation->MorePads(); + segmentation->NextPad()) + { + qp=fResponse->IntXY(segmentation); + qp=TMath::Abs(qp); +// +// + if (qp > 1.e-4) { + qcheck+=qp; + Int_t ixs=segmentation->Ix(); + Int_t iys=segmentation->Iy(); + Float_t xs,ys; + segmentation->GetPadCxy(ixs,iys,xs,ys); + sum+=qp*ys; + } + } // Pad loop + Float_t ycog=sum/qcheck; + yg[i]=(yscan-y)/segmentation->Dpy(); + yrg[i]=(ycog-y)/segmentation->Dpy(); + ysig[i]=ycog-yscan; + yscan+=dy; + } // scan loop +// +// x-position + Float_t xscan=xmin; + Float_t dx=segmentation->GetRealDpx(isec)/(ns-1); + + for (i=0; iSigGenInit(xscan, y, 0); + + for (segmentation->FirstPad(xscan, y, dxI, dyI); + segmentation->MorePads(); + segmentation->NextPad()) + { + qp=fResponse->IntXY(segmentation); + qp=TMath::Abs(qp); +// +// + if (qp > 1.e-2) { + qcheck+=qp; + Int_t ixs=segmentation->Ix(); + Int_t iys=segmentation->Iy(); + Float_t xs,ys; + segmentation->GetPadCxy(ixs,iys,xs,ys); + sum+=qp*xs; + } + } // Pad loop + Float_t xcog=sum/qcheck; + xcog=segmentation->GetAnod(xcog); + + xg[i]=(xscan-x)/segmentation->GetRealDpx(isec); + xrg[i]=(xcog-x)/segmentation->GetRealDpx(isec); + xsig[i]=xcog-xscan; + xscan+=dx; + } + + TCanvas *c1=new TCanvas(canvasname,canvasname,400,10,600,700); + TPad* pad11 = new TPad("pad11"," ",0.01,0.51,0.49,0.99); + TPad* pad12 = new TPad("pad12"," ",0.51,0.51,0.99,0.99); + TPad* pad13 = new TPad("pad13"," ",0.01,0.01,0.49,0.49); + TPad* pad14 = new TPad("pad14"," ",0.51,0.01,0.99,0.49); + pad11->SetFillColor(11); + pad12->SetFillColor(11); + pad13->SetFillColor(11); + pad14->SetFillColor(11); + pad11->Draw(); + pad12->Draw(); + pad13->Draw(); + pad14->Draw(); + TGraph *graphx = new TGraph(ns,xg ,xsig); + TGraph *graphxr= new TGraph(ns,xrg,xsig); + TGraph *graphy = new TGraph(ns,yg ,ysig); + TGraph *graphyr= new TGraph(ns,yrg,ysig); +// +// Creates a Root function based on function sinoid above +// and perform the fit +// + Double_t sinoid(Double_t *x, Double_t *par); + TF1 *sinoidf = new TF1("sinoidf",sinoid,0.5,0.5,5); + graphyr->Fit("sinoidf","V"); + sinoidf->Copy(func); + func.Eval(0,0,0); +// + pad11->cd(); + graphx->SetFillColor(42); + graphx->SetMarkerColor(4); + graphx->SetMarkerStyle(21); + graphx->Draw("AC"); + graphx->GetHistogram()->SetXTitle("x on pad"); + graphx->GetHistogram()->SetYTitle("xcog-x"); + + + pad12->cd(); + graphxr->SetFillColor(42); + graphxr->SetMarkerColor(4); + graphxr->SetMarkerStyle(21); + graphxr->Draw("AP"); + graphxr->GetHistogram()->SetXTitle("xcog on pad"); + graphxr->GetHistogram()->SetYTitle("xcog-x"); + + + pad13->cd(); + graphy->SetFillColor(42); + graphy->SetMarkerColor(4); + graphy->SetMarkerStyle(21); + graphy->Draw("AF"); + graphy->GetHistogram()->SetXTitle("y on pad"); + graphy->GetHistogram()->SetYTitle("ycog-y"); + + + + pad14->cd(); + graphyr->SetFillColor(42); + graphyr->SetMarkerColor(4); + graphyr->SetMarkerStyle(21); + graphyr->Draw("AF"); + graphyr->GetHistogram()->SetXTitle("ycog on pad"); + graphyr->GetHistogram()->SetYTitle("ycog-y"); + + c1->Update(); + +} +*/ +/* +Double_t sinoid(Double_t *x, Double_t *par) +{ + Double_t arg = -2*TMath::Pi()*x[0]; + Double_t fitval= par[0]*TMath::Sin(arg)+ + par[1]*TMath::Sin(2*arg)+ + par[2]*TMath::Sin(3*arg)+ + par[3]*TMath::Sin(4*arg)+ + par[4]*TMath::Sin(5*arg); + return fitval; + } +*/ + + + + + + + diff --git a/MUON/AliMUONClusterFinderv0.h b/MUON/AliMUONClusterFinderv0.h new file mode 100644 index 00000000000..6cdf6107d39 --- /dev/null +++ b/MUON/AliMUONClusterFinderv0.h @@ -0,0 +1,78 @@ +#ifndef AliMUONClusterFinderv0_H +#define AliMUONClusterFinderv0_H +//////////////////////////////////////////////// +// MUON Cluster Finder Class // +//////////////////////////////////////////////// +#include "AliMUONClusterFinder.h" +//#include "TF1.h" + +class AliMUONClusterFinderv0 : +public AliMUONClusterFinder { +//public: +// TClonesArray* fDigits; +// Int_t fNdigits; +//protected: +// AliMUONsegmentation* fSegmentation; +// AliMUONresponse* fResponse; +// TClonesArray* fRawClusters; +// Int_t fChamber; +// Int_t fNRawClusters; +// AliMUONHitMapA1* fHitMap; +// TF1* fCogCorr; + + public: + AliMUONClusterFinderv0 + (AliMUONsegmentation *segmentation, + AliMUONresponse *response, TClonesArray *digits, Int_t chamber); + AliMUONClusterFinderv0(); + ~AliMUONClusterFinderv0(){delete fRawClusters;} +// virtual void SetSegmentation( +// AliMUONsegmentation *segmentation){ +// fSegmentation=segmentation; +// } +// virtual void SetResponse(AliMUONresponse *response) { +// fResponse=response; +// } + +// virtual void SetDigits(TClonesArray *MUONdigits) { +// fDigits=MUONdigits; +// fNdigits = fDigits->GetEntriesFast(); +// } + +// virtual void SetChamber(Int_t ich){ +// fChamber=ich; +// } + +// virtual void AddRawCluster(const AliMUONRawCluster); + // Search for raw clusters + virtual void FindRawClusters(); +// virtual void FindCluster(Int_t i, Int_t j, AliMUONRawCluster &c); + // Specific methods + virtual void SetOffset(AliMUONRawCluster *cluster); + virtual Int_t PeakOffsetAndCoordinates(Int_t DigitIndex, Float_t *X, Float_t *Y); + // Decluster + virtual void Decluster(AliMUONRawCluster *cluster); + // Self Calibration of COG +// virtual void CalibrateCOG(); +// virtual void SinoidalFit(Float_t x, Float_t y, TF1 &func); + // +// virtual void CorrectCOG(){;} + + // + virtual Bool_t Centered(AliMUONRawCluster *cluster); + virtual void SplitByLocalMaxima(AliMUONRawCluster *cluster); +// virtual void FillCluster(AliMUONRawCluster *cluster); + void AliMUONClusterFinderv0::DumpCluster(class AliMUONRawCluster *); + + + TClonesArray* RawClusters(){return fRawClusters;} + ClassDef(AliMUONClusterFinderv0,1) //Class for clustering and reconstruction of space points +}; +#endif + + + + + + + diff --git a/MUON/AliMUONConst.h b/MUON/AliMUONConst.h index 1cbc196e664..968ea4da2a2 100644 --- a/MUON/AliMUONConst.h +++ b/MUON/AliMUONConst.h @@ -18,7 +18,19 @@ const Float_t zend = 511.+0.15-2*0.001; // z-out position of first chamber // const Float_t adc_satm = 1024; // dynamic range (10 bits) -const Float_t zero_supm = 6.; // zero suppression +const Int_t zero_supm = 6; // zero suppression const Float_t sig_noise = 500.; // electronics noise (no. of electrons) +const Float_t kScale=1.; + + +///////////////////////////////////////////////////////////////////////////// +// +//--------------------------------------------------------------------- +// ALICE MUON segmentation Parameters +//-------------------------------------------------------------------- +// +// +const Int_t kMaxNeighbours = 24; // max number of neighbours #endif + diff --git a/MUON/AliMUONHitMap.cxx b/MUON/AliMUONHitMap.cxx new file mode 100644 index 00000000000..297cba63996 --- /dev/null +++ b/MUON/AliMUONHitMap.cxx @@ -0,0 +1,98 @@ +#include "AliMUONHitMap.h" +ClassImp(AliMUONHitMap) +ClassImp(AliMUONHitMapA1) + +AliMUONHitMapA1::AliMUONHitMapA1(AliMUONsegmentation *seg, TObjArray *dig) +{ + fSegmentation = seg; + fNpx = fSegmentation->Npx(); + fNpy = fSegmentation->Npy(); + fMaxIndex=2*(fNpx+1)*2*(fNpy+1)+2*fNpy; + + fHitMap = new Int_t[fMaxIndex]; + fDigits = dig; + fNdigits = fDigits->GetEntriesFast(); + Clear(); +} + + +AliMUONHitMapA1::~AliMUONHitMapA1() +{ +// if (fDigits) delete fDigits; + if (fHitMap) delete[] fHitMap; +} + +void AliMUONHitMapA1::Clear() +{ + memset(fHitMap,0,sizeof(int)*fMaxIndex); +} + +Int_t AliMUONHitMapA1::CheckedIndex(Int_t ix, Int_t iy) +{ + Int_t index=2*fNpy*(ix+fNpx)+(iy+fNpy); + if (index > fMaxIndex) { + printf("\n \n \n Try to read/write outside array !!!! \n \n %d %d %d %d %d %d",ix,iy, fMaxIndex, index, fNpx, fNpy); + return fMaxIndex-1; + } else { + return index; + } +} + + +void AliMUONHitMapA1::FillHits() +{ + Int_t ndigits = fDigits->GetEntriesFast(); + //printf("\n Filling hits into HitMap\n"); + //printf("FindRawClusters -- ndigits %d \n",ndigits); + if (!ndigits) return; + AliMUONdigit *dig; + for (Int_t ndig=0; ndigUncheckedAt(ndig); + SetHit(dig->fPadX,dig->fPadY,ndig); + } +} + + +void AliMUONHitMapA1::SetHit(Int_t ix, Int_t iy, Int_t idigit) +{ +// fHitMap[kMaxNpady*(ix+fNpx)+(iy+fNpy)]=idigit+1; + fHitMap[CheckedIndex(ix, iy)]=idigit+1; +} + +void AliMUONHitMapA1::DeleteHit(Int_t ix, Int_t iy) +{ +// fHitMap[kMaxNpady*(ix+fNpx)+(iy+fNpy)]=0; + fHitMap[CheckedIndex(ix, iy)]=0; +} + +void AliMUONHitMapA1::FlagHit(Int_t ix, Int_t iy) +{ + fHitMap[CheckedIndex(ix, iy)]= + -TMath::Abs(fHitMap[CheckedIndex(ix, iy)]); +} + +Int_t AliMUONHitMapA1::GetHitIndex(Int_t ix, Int_t iy) +{ + return TMath::Abs(fHitMap[CheckedIndex(ix, iy)])-1; +} + +TObject* AliMUONHitMapA1::GetHit(Int_t ix, Int_t iy) +{ + Int_t index=GetHitIndex(ix,iy); + // Force crash if index does not exist ! (Manu) + return (index <0) ? 0 : fDigits->UncheckedAt(GetHitIndex(ix,iy)); +} + +Flag_t AliMUONHitMapA1::TestHit(Int_t ix, Int_t iy) +{ + Int_t inf=fHitMap[CheckedIndex(ix, iy)]; + if (inf < 0) { + return used; + } else if (inf == 0) { + return empty; + } else { + return unused; + } +} + + diff --git a/MUON/AliMUONHitMap.h b/MUON/AliMUONHitMap.h new file mode 100644 index 00000000000..49dff3cd96f --- /dev/null +++ b/MUON/AliMUONHitMap.h @@ -0,0 +1,53 @@ +#ifndef AliMUONHitMap_H +#define AliMUONHitMap_H + +#include "AliMUON.h" +#include "TArrayI.h" +typedef enum {empty, used, unused} Flag_t; +const Int_t kMaxNpadx=1200, kMaxNpady=1200; + +class AliMUONHitMap : +public TObject { + public: + virtual void FillHits() =0; + virtual void Clear() =0; + virtual void SetHit(Int_t ix, Int_t iy, Int_t idigit) =0; + virtual void DeleteHit(Int_t ix, Int_t iy) =0; + virtual Int_t GetHitIndex(Int_t ix, Int_t iy) =0; + virtual TObject * GetHit(Int_t ix, Int_t iy) =0; + virtual void FlagHit(Int_t ix, Int_t iy) =0; + virtual Flag_t TestHit(Int_t ix, Int_t iy) =0; + + ClassDef(AliMUONHitMap,1) //virtual base class for muon HitMap +}; + +class AliMUONHitMapA1 : +public AliMUONHitMap +{ + private: + AliMUONsegmentation *fSegmentation; + Int_t fNpx; + Int_t fNpy; + TObjArray *fDigits; + Int_t fNdigits; + Int_t *fHitMap; + Int_t fMaxIndex; + + public: + AliMUONHitMapA1(AliMUONsegmentation *seg, TObjArray *dig); + virtual ~AliMUONHitMapA1(); + virtual void FillHits(); + virtual void Clear(); + virtual void SetHit(Int_t ix, Int_t iy, Int_t idigit); + virtual void DeleteHit(Int_t ix, Int_t iy); + virtual Int_t GetHitIndex(Int_t ix, Int_t iy); + virtual TObject* GetHit(Int_t ix, Int_t); + virtual void FlagHit(Int_t ix, Int_t iy); + virtual Flag_t TestHit(Int_t ix, Int_t iy); + private: + Int_t CheckedIndex(Int_t ix, Int_t iy); + ClassDef(AliMUONHitMapA1,1) // Implements HitMap as a 2-dim array +}; +#endif + + diff --git a/MUON/AliMUONSegRes.h b/MUON/AliMUONSegRes.h new file mode 100644 index 00000000000..57b64bacbda --- /dev/null +++ b/MUON/AliMUONSegRes.h @@ -0,0 +1,139 @@ +#ifndef MUONSegRes_H +#define MUONSegRes_H +#include "TObject.h" +#include "TClonesArray.h" +#include "TF1.h" +class AliMUONchamber; +class AliMUONRecCluster; + +//---------------------------------------------- +// +// Chamber segmentation virtual base class +// +class AliMUONsegmentation : +public TObject { + public: + // Set Chamber Segmentation Parameters + // + // Pad size Dx*Dy + virtual void SetPADSIZ(Float_t p1, Float_t p2) =0; + // Anod Pitch + virtual void SetDAnod(Float_t D) =0; + // Transform from pad (wire) to real coordinates and vice versa + // + // Anod wire coordinate closest to xhit + virtual Float_t GetAnod(Float_t xhit) =0; + // Transform from pad to real coordinates + virtual void GetPadIxy(Float_t x ,Float_t y ,Int_t &ix,Int_t &iy)=0; + // Transform from real to pad coordinates + virtual void GetPadCxy(Int_t ix,Int_t iy,Float_t &x ,Float_t &y )=0; + // + // Initialisation + virtual void Init(AliMUONchamber*) =0; + // + // Get member data + // + // Pad size in x + virtual Float_t Dpx() =0; + // Pad size in y + virtual Float_t Dpy() =0; + // Pad size in x by Sector + virtual Float_t Dpx(Int_t) =0; + // Pad size in y by Sector + virtual Float_t Dpy(Int_t) =0; + // Max number of Pads in x + virtual Int_t Npx() =0; + // max number of Pads in y + virtual Int_t Npy() =0; + // set pad position + virtual void SetPad(Int_t, Int_t) =0; + // set hit position + virtual void SetHit(Float_t, Float_t) =0; + + // + // Iterate over pads + // Initialiser + virtual void FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) =0; + // Stepper + virtual void NextPad() =0; + // Condition + virtual Int_t MorePads() =0; + // + // Distance between 1 pad and a position + virtual Float_t Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t *dummy) =0; + // Number of pads read in parallel and offset to add to x + // (specific to LYON, but mandatory for display) + virtual void GetNParallelAndOffset(Int_t iX, Int_t iY, + Int_t *Nparallel, Int_t *Offset) =0; + // Get next neighbours + virtual void Neighbours + (Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) =0; + // Provisory RecCluster coordinates reconstructor + virtual void FitXY(AliMUONRecCluster* Cluster,TClonesArray* MUONdigits) =0; + // + // Current pad cursor during disintegration + // x-coordinate + virtual Int_t Ix() =0; + // y-coordinate + virtual Int_t Iy() =0; + // current sector + virtual Int_t ISector() =0; + // calculate sector from pad coordinates + virtual Int_t Sector(Int_t ix, Int_t iy) =0; + // + // Signal Generation Condition during Stepping + virtual Int_t SigGenCond(Float_t x, Float_t y, Float_t z) = 0; + // Initialise signal gneration at coord (x,y,z) + virtual void SigGenInit(Float_t x, Float_t y, Float_t z) = 0; + // Current integration limits + virtual void IntegrationLimits + (Float_t& x1, Float_t& x2, Float_t& y1, Float_t& y2) = 0; + // Test points for auto calibration + virtual void GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) = 0; + // Debug utilities + virtual void Draw() = 0; + // Function for systematic corrections + virtual void SetCorrFunc(Int_t, TF1*) = 0; + virtual TF1* CorrFunc(Int_t) = 0; + + ClassDef(AliMUONsegmentation,1) //Segmentation class for homogeneous segmentation +}; +//---------------------------------------------- +// +// Chamber response virtual base class +// +class AliMUONresponse : +public TObject { + public: + // + // Configuration methods + // + // Number of sigmas over which cluster didintegration is performed + virtual void SetSigmaIntegration(Float_t p1) =0; + virtual Float_t SigmaIntegration() =0; + // charge slope in ADC/e + virtual void SetChargeSlope(Float_t p1) =0; + virtual Float_t ChargeSlope() =0; + // sigma of the charge spread function + virtual void SetChargeSpread(Float_t p1, Float_t p2) =0; + virtual Float_t ChargeSpreadX() =0; + virtual Float_t ChargeSpreadY() =0; + // Adc-count saturation value + virtual void SetMaxAdc(Float_t p1) =0; + virtual Float_t MaxAdc() =0; + // anode cathode Pitch + virtual void SetPitch(Float_t) =0; + virtual Float_t Pitch() =0; + // + // Chamber response methods + // Pulse height from scored quantity (eloss) + virtual Float_t IntPH(Float_t eloss) =0; + // Charge disintegration + virtual Float_t IntXY(AliMUONsegmentation *) =0; + + ClassDef(AliMUONresponse,1) // Implementation of Mathieson CPC response +}; +#endif + + + diff --git a/MUON/AliMUONSegResV0.cxx b/MUON/AliMUONSegResV0.cxx new file mode 100644 index 00000000000..c23c625c9fd --- /dev/null +++ b/MUON/AliMUONSegResV0.cxx @@ -0,0 +1,280 @@ +#include "AliMUONSegResV0.h" +#include "TMath.h" +#include "TRandom.h" +#include "TArc.h" +#include "AliMUONchamber.h" +ClassImp(AliMUONsegmentationV0) + void AliMUONsegmentationV0::Init(AliMUONchamber* Chamber) +{ + fNpx=(Int_t) (Chamber->ROuter()/fDpx+1); + fNpy=(Int_t) (Chamber->ROuter()/fDpy+1); + fRmin=Chamber->RInner(); + fRmax=Chamber->ROuter(); + fCorr=0; + +} + + +Float_t AliMUONsegmentationV0::GetAnod(Float_t xhit) +{ + Float_t wire= (xhit>0)? Int_t(xhit/fWireD)+0.5:Int_t(xhit/fWireD)-0.5; + return fWireD*wire; +} + +void AliMUONsegmentationV0::SetPADSIZ(Float_t p1, Float_t p2) +{ + fDpx=p1; + fDpy=p2; +} +void AliMUONsegmentationV0:: + GetPadIxy(Float_t x, Float_t y, Int_t &ix, Int_t &iy) +{ +// returns pad coordinates (ix,iy) for given real coordinates (x,y) +// + ix = (x>0)? Int_t(x/fDpx)+1 : Int_t(x/fDpx)-1; + iy = (y>0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1; + if (iy > fNpy) iy= fNpy; + if (iy < -fNpy) iy=-fNpy; + if (ix > fNpx) ix= fNpx; + if (ix < -fNpx) ix=-fNpx; +} +void AliMUONsegmentationV0:: +GetPadCxy(Int_t ix, Int_t iy, Float_t &x, Float_t &y) +{ +// returns real coordinates (x,y) for given pad coordinates (ix,iy) +// + x = (ix>0) ? Float_t(ix*fDpx)-fDpx/2. : Float_t(ix*fDpx)+fDpx/2.; + y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.; +} + +void AliMUONsegmentationV0:: +SetHit(Float_t xhit, Float_t yhit) +{ + // + // Find the wire position (center of charge distribution) +// Float_t x0a=GetAnod(xhit); + fxhit=xhit; + fyhit=yhit; +} + +void AliMUONsegmentationV0:: +SetPad(Int_t ix, Int_t iy) +{ + GetPadCxy(ix,iy,fx,fy); +} + +void AliMUONsegmentationV0:: +FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) +{ + // + // Find the wire position (center of charge distribution) + Float_t x0a=GetAnod(xhit); + fxhit=x0a; + fyhit=yhit; + // + // and take fNsigma*sigma around this center + Float_t x01=x0a - dx; + Float_t x02=x0a + dx; + Float_t y01=yhit - dy; + Float_t y02=yhit + dy; + // + // find the pads over which the charge distributes + GetPadIxy(x01,y01,fixmin,fiymin); + GetPadIxy(x02,y02,fixmax,fiymax); +// printf("\n %f %f %d %d \n",x02,y02,fixmax,fiymax); +// printf("\n FirstPad called %f %f \n", fDpx, fDpy); +// printf("\n Hit Position %f %f \n",xhit,yhit); +// printf("\n Integration limits: %i %i %i %i",fixmin,fixmax,fiymin,fiymax); +// printf("\n Integration limits: %f %f %f %f \n",x01,x02,y01,y02); + // + // Set current pad to lower left corner + fix=fixmin; + fiy=fiymin; + GetPadCxy(fix,fiy,fx,fy); +} + +void AliMUONsegmentationV0::NextPad() +{ + // + // Step to next pad in integration region + if (fix != fixmax) { + if (fix==-1) fix++; + fix++; + } else if (fiy != fiymax) { + fix=fixmin; + if (fiy==-1) fiy++; + fiy++; + } else { + printf("\n Error: Stepping outside integration region\n "); + } + GetPadCxy(fix,fiy,fx,fy); +} + +Int_t AliMUONsegmentationV0::MorePads() +// +// Are there more pads in the integration region +{ + if (fix == fixmax && fiy == fiymax) { + return 0; + } else { + return 1; + + } +} + +void AliMUONsegmentationV0::SigGenInit(Float_t x,Float_t y,Float_t z) +{ +// +// Initialises pad and wire position during stepping + fxt =x; + fyt =y; + GetPadIxy(x,y,fixt,fiyt); + fiwt= (x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1 ; +} + +Int_t AliMUONsegmentationV0::SigGenCond(Float_t x,Float_t y,Float_t z) +{ +// +// Signal will be generated if particle crosses pad boundary or +// boundary between two wires. + Int_t ixt, iyt; + GetPadIxy(x,y,ixt,iyt); + Int_t iwt=(x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1; + if ((ixt != fixt) || (iyt !=fiyt) || (iwt != fiwt)) { + return 1; + } else { + return 0; + } +} +void AliMUONsegmentationV0:: +IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) +{ +// x1=GetAnod(fxt)-fx-fDpx/2.; + x1=fxhit-fx-fDpx/2.; + x2=x1+fDpx; + y1=fyhit-fy-fDpy/2.; + y2=y1+fDpy; +} + +void AliMUONsegmentationV0:: +Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[7], Int_t Ylist[7]) +{ + /* + *Nlist=4;Xlist[0]=Xlist[1]=iX;Xlist[2]=iX-1;Xlist[3]=iX+1; + Ylist[0]=iY-1;Ylist[1]=iY+1;Ylist[2]=Ylist[3]=iY; + */ + *Nlist=8; + Xlist[0]=Xlist[1]=iX; + Xlist[2]=iX-1; + Xlist[3]=iX+1; + Ylist[0]=iY-1; + Ylist[1]=iY+1; + Ylist[2]=Ylist[3]=iY; + + // Diagonal elements + Xlist[4]=iX+1; + Ylist[4]=iY+1; + + Xlist[5]=iX-1; + Ylist[5]=iY-1; + + Xlist[6]=iX-1; + Ylist[6]=iY+1; + + Xlist[7]=iX+1; + Ylist[7]=iY-1; +} + +Float_t AliMUONsegmentationV0::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y +, Int_t *dummy) +// Returns the square of the distance between 1 pad +// labelled by its Channel numbers and a coordinate +{ + Float_t x,y; + GetPadCxy(iX,iY,x,y); + return (x-X)*(x-X) + (y-Y)*(y-Y); +} + + +void AliMUONsegmentationV0:: +FitXY(AliMUONRecCluster* Cluster,TClonesArray* MUONdigits) + // Default : Centre of gravity method +{ + ; +} + +void AliMUONsegmentationV0::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) +{ + n=1; + x[0]=(fRmax+fRmin)/2/TMath::Sqrt(2.); + y[0]=x[0]; +} + +void AliMUONsegmentationV0::Draw() +{ + TArc *circle; + Float_t scale=0.95/fRmax/2.; + + + circle = new TArc(0.5,0.5,fRmax*scale,0.,360.); + circle->SetFillColor(2); + circle->Draw(); + + circle = new TArc(0.5,0.5,fRmin*scale,0.,360.); + circle->SetFillColor(1); + circle->Draw(); +} + + + +//___________________________________________ +ClassImp(AliMUONresponseV0) +Float_t AliMUONresponseV0::IntPH(Float_t eloss) +{ + // Get number of electrons and return charge + + Int_t nel; + nel= Int_t(eloss*1.e9/32.); + Float_t charge=0; + if (nel == 0) nel=1; + for (Int_t i=1;i<=nel;i++) { + charge -= fChargeSlope*TMath::Log(gRandom->Rndm()); + } + return charge; +} +// ------------------------------------------- + +Float_t AliMUONresponseV0::IntXY(AliMUONsegmentation * segmentation) +{ + + const Float_t invpitch = 1/fPitch; +// +// Integration limits defined by segmentation model +// + Float_t xi1, xi2, yi1, yi2; + segmentation->IntegrationLimits(xi1,xi2,yi1,yi2); + xi1=xi1*invpitch; + xi2=xi2*invpitch; + yi1=yi1*invpitch; + yi2=yi2*invpitch; +// +// The Mathieson function + Double_t ux1=fSqrtKx3*TMath::TanH(fKx2*xi1); + Double_t ux2=fSqrtKx3*TMath::TanH(fKx2*xi2); + + Double_t uy1=fSqrtKy3*TMath::TanH(fKy2*yi1); + Double_t uy2=fSqrtKy3*TMath::TanH(fKy2*yi2); + + + return Float_t(4.*fKx4*(TMath::ATan(ux2)-TMath::ATan(ux1))* + fKy4*(TMath::ATan(uy2)-TMath::ATan(uy1))); +} + + + + + + + + + diff --git a/MUON/AliMUONSegResV0.h b/MUON/AliMUONSegResV0.h new file mode 100644 index 00000000000..7e714a97efd --- /dev/null +++ b/MUON/AliMUONSegResV0.h @@ -0,0 +1,208 @@ +#ifndef MUONSegResV0_H +#define MUONSegResV0_H + +#include "AliMUONSegRes.h" +class AliMUONchamber; + +class AliMUONsegmentationV0 : +public AliMUONsegmentation { + public: + AliMUONsegmentationV0(){} + virtual ~AliMUONsegmentationV0(){} + // Set Chamber Segmentation Parameters + // + // Pad size Dx*Dy + virtual void SetPADSIZ(Float_t p1, Float_t p2); + // Anod Pitch + virtual void SetDAnod(Float_t D) {fWireD = D;}; + // Transform from pad (wire) to real coordinates and vice versa + // + // Anod wire coordinate closest to xhit + virtual Float_t GetAnod(Float_t xhit); + // Transform from pad to real coordinates + virtual void GetPadIxy(Float_t x ,Float_t y ,Int_t &ix,Int_t &iy); + // Transform from real to pad coordinates + virtual void GetPadCxy(Int_t ix,Int_t iy,Float_t &x ,Float_t &y ); + // + // Initialisation + virtual void Init(AliMUONchamber*); + // + // Get member data + // + // Pad size in x + virtual Float_t Dpx(){return fDpx;} + // Pad size in y + virtual Float_t Dpy(){return fDpy;} + // Pad size in x by Sector + virtual Float_t Dpx(Int_t) {return fDpx;} + // Pad size in y by Secto + virtual Float_t Dpy(Int_t) {return fDpy;} + // Max number of Pads in x + virtual Int_t Npx(){return fNpx;} + // max number of Pads in y + virtual Int_t Npy(){return fNpy;} + // set pad position + virtual void SetPad(Int_t, Int_t); + // set hit position + virtual void SetHit(Float_t, Float_t); + // + // Iterate over pads + // Initialiser + virtual void FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy); + // Stepper + virtual void NextPad(); + // Condition + virtual Int_t MorePads(); + // + // Distance between 1 pad and a position + virtual Float_t Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t * +dummy); + // Number of pads read in parallel and offset to add to x + // (specific to LYON, but mandatory for display) + virtual void GetNParallelAndOffset(Int_t iX, Int_t iY, + Int_t *Nparallel, Int_t *Offset) {*Nparallel=1;*Offset=0;} + // Get next neighbours + virtual void Neighbours + (Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]); + // Provisory RecCluster coordinates reconstructor + virtual void FitXY(AliMUONRecCluster* Cluster,TClonesArray* MUONdigits); + // + // Current Pad during Integration + // x-coordinaten + virtual Int_t Ix(){return fix;} + // y-coordinate + virtual Int_t Iy(){return fiy;} + // current sector + virtual Int_t ISector(){return 1;} + // calculate sector from pad coordinates + virtual Int_t Sector(Int_t ix, Int_t iy) {return 1;} + // + // Signal Generation Condition during Stepping + virtual Int_t SigGenCond(Float_t x, Float_t y, Float_t z); + // Initialise signal gneration at coord (x,y,z) + virtual void SigGenInit(Float_t x, Float_t y, Float_t z); + // Current integration limits + virtual void IntegrationLimits + (Float_t& x1, Float_t& x2, Float_t& y1, Float_t& y2); + // Test points for auto calibration + virtual void GiveTestPoints(Int_t &n, Float_t *x, Float_t *y); + // Debugging utilities + virtual void Draw(); + // Function for systematic corrections + virtual void SetCorrFunc(Int_t dum, TF1* func) {fCorr=func;} + + virtual TF1* CorrFunc(Int_t) {return fCorr;} + + + ClassDef(AliMUONsegmentationV0,1) + protected: + // + // Implementation of the segmentation data + // Version 0 models rectangular pads with the same dimensions all + // over the cathode plane + // + // geometry + // + Float_t fDpx; // x pad width per sector + Float_t fDpy; // y pad base width + Int_t fNpx; // Number of pads in x + Int_t fNpy; // Number of pads in y + Float_t fWireD; // wire pitch + Float_t fRmin; // inner radius + Float_t fRmax; // outer radius + + + // Chamber region consideres during disintegration + Int_t fixmin; // lower left x + Int_t fixmax; // lower left y + Int_t fiymin; // upper right x + Int_t fiymax; // upper right y + // + // Current pad during integration (cursor for disintegration) + Int_t fix; // pad coord. x + Int_t fiy; // pad coord. y + Float_t fx; // x + Float_t fy; // y + // + // Current pad and wire during tracking (cursor at hit centre) + // + // + Float_t fxhit; + Float_t fyhit; + // Reference point to define signal generation condition + Int_t fixt; // pad coord. x + Int_t fiyt; // pad coord. y + Int_t fiwt; // wire number + Float_t fxt; // x + Float_t fyt; // y + TF1* fCorr; // correction function + +}; + +class AliMUONresponseV0 : //Mathieson response +public AliMUONresponse { + public: + AliMUONresponseV0(){} + virtual ~AliMUONresponseV0(){} + // + // Configuration methods + // + // Number of sigmas over which cluster didintegration is performed + virtual void SetSigmaIntegration(Float_t p1) {fSigmaIntegration=p1;} + virtual Float_t SigmaIntegration() {return fSigmaIntegration;} + // charge slope in ADC/e + virtual void SetChargeSlope(Float_t p1) {fChargeSlope=p1;} + virtual Float_t ChargeSlope() {return fChargeSlope;} + // sigma of the charge spread function + virtual void SetChargeSpread(Float_t p1, Float_t p2) + {fChargeSpreadX=p1; fChargeSpreadY=p2;} + virtual Float_t ChargeSpreadX() {return fChargeSpreadX;} + virtual Float_t ChargeSpreadY() {return fChargeSpreadY;} + // Adc-count saturation value + virtual void SetMaxAdc(Float_t p1) {fMaxAdc=p1;} + virtual Float_t MaxAdc() {return fMaxAdc;} + // anode cathode Pitch + virtual Float_t Pitch() {return fPitch;} + virtual void SetPitch(Float_t p1) {fPitch=p1;}; + // Mathieson parameters + virtual void SetSqrtKx3(Float_t p1) {fSqrtKx3=p1;}; + virtual void SetKx2(Float_t p1) {fKx2=p1;}; + virtual void SetKx4(Float_t p1) {fKx4=p1;}; + virtual void SetSqrtKy3(Float_t p1) {fSqrtKy3=p1;}; + virtual void SetKy2(Float_t p1) {fKy2=p1;}; + virtual void SetKy4(Float_t p1) {fKy4=p1;}; + + // + // Chamber response methods + // Pulse height from scored quantity (eloss) + virtual Float_t IntPH(Float_t eloss); + // Charge disintegration + virtual Float_t IntXY(AliMUONsegmentation * segmentation); + + ClassDef(AliMUONresponseV0,1) + protected: + Float_t fChargeSlope; // Slope of the charge distribution + Float_t fChargeSpreadX; // Width of the charge distribution in x + Float_t fChargeSpreadY; // Width of the charge distribution in y + Float_t fSigmaIntegration; // Number of sigma's used for charge distribution + Float_t fMaxAdc; // Maximum ADC channel + Float_t fSqrtKx3; // Mathieson parameters for x + Float_t fKx2; + Float_t fKx4; + Float_t fSqrtKy3; // Mathieson parameters for y + Float_t fKy2; + Float_t fKy4; + Float_t fPitch; //anode-cathode pitch +}; +#endif + + + + + + + + + + + diff --git a/MUON/AliMUONSegResV01.cxx b/MUON/AliMUONSegResV01.cxx new file mode 100644 index 00000000000..5a60360ea49 --- /dev/null +++ b/MUON/AliMUONSegResV01.cxx @@ -0,0 +1,473 @@ +///////////////////////////////////////////////////// +// Segmentation and Response classes version 01 // +///////////////////////////////////////////////////// + +#include +#include +#include +#include + +#include "AliMUONSegResV01.h" +#include "AliRun.h" +#include "AliMC.h" +#include "iostream.h" + +//___________________________________________ +ClassImp(AliMUONsegmentationV01) + +Float_t AliMUONsegmentationV01::Dpx(Int_t isec) +{ + return fDpxD[isec]; +} + +Float_t AliMUONsegmentationV01::Dpy(Int_t isec) +{ + return fDpy; +} + +AliMUONsegmentationV01::AliMUONsegmentationV01() +{ + fNsec=4; + fRSec.Set(fNsec); + fNDiv.Set(fNsec); + fDpxD.Set(fNsec); + fRSec[0]=fRSec[1]=fRSec[2]=fRSec[3]=0; + fNDiv[0]=fNDiv[1]=fNDiv[2]=fNDiv[3]=0; + fDpxD[0]=fDpxD[1]=fDpxD[2]=fDpxD[3]=0; + fCorr = new TObjArray(3); + (*fCorr)[0]=0; + (*fCorr)[1]=0; + (*fCorr)[2]=0; +} + +void AliMUONsegmentationV01::SetSegRadii(Float_t r[4]) +{ + for (Int_t i=0; i<4; i++) { + fRSec[i]=r[i]; + printf("\n R %d %f \n",i,fRSec[i]); + + } +} + + +void AliMUONsegmentationV01::SetPadDivision(Int_t ndiv[4]) +{ +// +// Defines the pad size perp. to the anode wire (y) for different sectors. +// + for (Int_t i=0; i<4; i++) { + fNDiv[i]=ndiv[i]; + printf("\n Ndiv %d %d \n",i,fNDiv[i]); + } + ndiv[0]=ndiv[1]; +} + + +void AliMUONsegmentationV01::Init(AliMUONchamber* Chamber) +{ +// +// Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector +// These arrays help in converting from real to pad co-ordinates and +// vice versa +// + Int_t isec; + printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n"); + fNpy=Int_t(fRSec[fNsec-1]/fDpy)+1; + + fDpxD[fNsec-1]=fDpx; + if (fNsec > 1) { + for (Int_t i=fNsec-2; i>=0; i--){ + fDpxD[i]=fDpxD[fNsec-1]/fNDiv[i]; + printf("\n test ---dx %d %f \n",i,fDpxD[i]); + } + } +// +// fill the arrays defining the pad segmentation boundaries + Float_t ry; + Int_t dnx; + Int_t add; +// +// loop over sections + for(isec=0; isec fRSec[isec]) { + fNpxS[isec][iy]=0; + fCx[isec][iy]=0; + } else { + ry=TMath::Sqrt(fRSec[isec]*fRSec[isec]-x*x); + if (isec > 1) { + dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]); + if (isec < fNsec-1) { + if (TMath::Odd((Long_t)dnx)) dnx++; + } + fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx; + fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec]; + } else if (isec == 1) { + dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]); + fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx; + add=4 - (fNpxS[isec][iy])%4; + if (add < 4) fNpxS[isec][iy]+=add; + dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy]; + fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec]; + } else { + dnx=Int_t(ry/fDpxD[isec]); + fNpxS[isec][iy]=dnx; + fCx[isec][iy]=dnx*fDpxD[isec]; + } + } + } // y-pad loop + } // sector loop + // + // for debugging only + + printf("segmentationv01 - I was here ! \n"); +} + +Int_t AliMUONsegmentationV01::Sector(Int_t ix, Int_t iy) +{ + Int_t absix=TMath::Abs(ix); + Int_t absiy=TMath::Abs(iy); + Int_t isec=0; + for (Int_t i=0; i0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1; + if (iy > fNpy) iy= fNpy; + if (iy < -fNpy) iy=-fNpy; +// +// Find sector isec + Int_t isec=-1; + Float_t absx=TMath::Abs(x); + Int_t absiy=TMath::Abs(iy); + for (Int_t i=0; i < fNsec; i++) { + if (absx <= fCx[i][absiy]) { + isec=i; + break; + } + } + if (isec>0) { + ix= Int_t((absx-fCx[isec-1][absiy])/fDpxD[isec]) + +fNpxS[isec-1][absiy]+1; + } else if (isec == 0) { + ix= Int_t(absx/fDpxD[isec])+1; + } else { + ix=fNpxS[fNsec-1][absiy]+1; + } +// printf("\n something %d %d \n",isec,absiy); + + ix = (x>0) ? ix:-ix; +} + +void AliMUONsegmentationV01:: +GetPadCxy(Int_t ix, Int_t iy, Float_t &x, Float_t &y) +{ +// returns real coordinates (x,y) for given pad coordinates (ix,iy) +// + y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.; +// +// Find sector isec + Int_t isec=AliMUONsegmentationV01::Sector(ix,iy); +// + Int_t absix=TMath::Abs(ix); + Int_t absiy=TMath::Abs(iy); + if (isec) { + x=fCx[isec-1][absiy]+(absix-fNpxS[isec-1][absiy])*fDpxD[isec]; + x=(ix>0) ? x-fDpxD[isec]/2 : -x+fDpxD[isec]/2; + } else { + x=y=0; + } +} + +void AliMUONsegmentationV01:: +SetPad(Int_t ix, Int_t iy) +{ + GetPadCxy(ix,iy,fx,fy); + fSector=Sector(ix,iy); +} + + +void AliMUONsegmentationV01:: +FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) +{ + // + // Find the wire position (center of charge distribution) + Float_t x0a=GetAnod(xhit); + fxhit=x0a; + fyhit=yhit; + + // + // and take fNsigma*sigma around this center + Float_t x01=x0a - dx; + Float_t x02=x0a + dx; + Float_t y01=yhit - dy; + Float_t y02=yhit + dy; + // + // find the pads over which the charge distributes + GetPadIxy(x01,y01,fixmin,fiymin); + GetPadIxy(x02,y02,fixmax,fiymax); + fxmin=x01; + fxmax=x02; + fymin=y01; + fymax=y02; + + // + // Set current pad to lower left corner + if (fixmax < fixmin) fixmax=fixmin; + if (fiymax < fiymin) fiymax=fiymin; + fix=fixmin; + fiy=fiymin; + GetPadCxy(fix,fiy,fx,fy); +} + + +void AliMUONsegmentationV01::NextPad() +{ + // + // Step to next pad in integration region + Float_t xc,yc; + Int_t iyc; + +// step from left to right + if (fx < fxmax && fx != 0) { + if (fix==-1) fix++; + fix++; +// step up + } else if (fiy != fiymax) { + if (fiy==-1) fiy++; + fiy++; +// get y-position of next row (yc), xc not used here + GetPadCxy(fix,fiy,xc,yc); +// get x-pad coordiante for 1 pad in row (fix) + GetPadIxy(fxmin,yc,fix,iyc); + } else { + printf("\n Error: Stepping outside integration region\n "); + } + GetPadCxy(fix,fiy,fx,fy); + fSector=Sector(fix,fiy); + if (MorePads() && + (fSector ==-1 || fSector==0 || + TMath::Abs(fx)<1.5 || TMath::Abs(fy)<1.5)) + NextPad(); + +// printf("\n this pad %f %f %d %d \n",fx,fy,fix,fiy); + +} + +Int_t AliMUONsegmentationV01::MorePads() +// +// Are there more pads in the integration region +{ + if ((fx >= fxmax && fiy >= fiymax) || fy==0) { + return 0; + } else { + return 1; + } +} + +void AliMUONsegmentationV01:: +IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) +{ + x1=fxhit-fx-Dpx(fSector)/2.; + x2=x1+Dpx(fSector); + y1=fyhit-fy-Dpy(fSector)/2.; + y2=y1+Dpy(fSector); +} + +void AliMUONsegmentationV01:: +Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) +{ + const Float_t epsilon=fDpy/1000; + + Float_t x,y; + Int_t ixx, iyy, isec1; +// + Int_t isec0=AliMUONsegmentationV01::Sector(iX,iY); + Int_t i=0; +// +// step right + Xlist[i]=iX+1; + Ylist[i++]=iY; +// +// step left + Xlist[i]=iX-1; + Ylist[i++]=iY; +// +// step up + AliMUONsegmentationV01::GetPadCxy(iX,iY,x,y); + AliMUONsegmentationV01::GetPadIxy(x+epsilon,y+fDpy,ixx,iyy); + Xlist[i]=ixx; + Ylist[i++]=iY+1; + isec1=AliMUONsegmentationV01::Sector(ixx,iyy); + if (isec1==isec0) { +// +// no sector boundary crossing + Xlist[i]=ixx+1; + Ylist[i++]=iY+1; + + Xlist[i]=ixx-1; + Ylist[i++]=iY+1; + } else if (isec1 < isec0) { +// finer segmentation + Xlist[i]=ixx+1; + Ylist[i++]=iY+1; + + Xlist[i]=ixx-1; + Ylist[i++]=iY+1; + + Xlist[i]=ixx-2; + Ylist[i++]=iY+1; + } else { +// coarser segmenation + + if (TMath::Odd(iX-fNpxS[isec1-1][iY+1])) { + Xlist[i]=ixx-1; + Ylist[i++]=iY+1; + } else { + Xlist[i]=ixx+1; + Ylist[i++]=iY+1; + } + } +// +// step down + AliMUONsegmentationV01::GetPadCxy(iX,iY,x,y); + AliMUONsegmentationV01::GetPadIxy(x+epsilon,y-fDpy,ixx,iyy); + Xlist[i]=ixx; + Ylist[i++]=iY-1; + isec1=AliMUONsegmentationV01::Sector(ixx,iyy); + if (isec1==isec0) { +// +// no sector boundary crossing + Xlist[i]=ixx+1; + Ylist[i++]=iY-1; + + Xlist[i]=ixx-1; + Ylist[i++]=iY-1; + } else if (isec1 < isec0) { +// finer segmentation + Xlist[i]=ixx+1; + Ylist[i++]=iY-1; + + Xlist[i]=ixx-1; + Ylist[i++]=iY-1; + + Xlist[i]=ixx-2; + Ylist[i++]=iY-1; + } else { +// coarser segmentation + + if (TMath::Odd(iX-fNpxS[isec1-1][iY-1])) { + Xlist[i]=ixx-1; + Ylist[i++]=iY-1; + } else { + Xlist[i]=ixx+1; + Ylist[i++]=iY-1; + } + + } + *Nlist=i; +} + +//___________________________________________ +void AliMUONsegmentationV01:: +FitXY(AliMUONRecCluster* Cluster,TClonesArray* MUONdigits) + // Default : Centre of gravity method +{ + Float_t x=0; + Float_t y=0; + Float_t q=0; + Float_t xToAdd; + Float_t yToAdd; + + if (gAlice->TreeD()->GetReadEvent() != Cluster->GetCathod()+1) + // next line warns if in the future cathod 1 is not event 2 ! + printf("ClusterFillXY : not reading the right cathod !\n"); + for(Int_t clusDigit=Cluster->FirstDigitIndex(); + clusDigit!=Cluster->InvalidDigitIndex(); + clusDigit=Cluster->NextDigitIndex()) { + AliMUONdigit* pDigit=(AliMUONdigit*)MUONdigits->UncheckedAt(clusDigit); + GetPadCxy(pDigit->fPadX,pDigit->fPadY,xToAdd,yToAdd); + x+= xToAdd*pDigit->fSignal; + y+= yToAdd*pDigit->fSignal; + q+= (Float_t) pDigit->fSignal; + } + Cluster->fX=x/q; + Cluster->fY=y/q; +} + +void AliMUONsegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) +{ + n=3; + x[0]=(fRSec[0]+fRSec[1])/2/TMath::Sqrt(2.); + y[0]=x[0]; + x[1]=(fRSec[1]+fRSec[2])/2/TMath::Sqrt(2.); + y[1]=x[1]; + x[2]=(fRSec[2]+fRSec[3])/2/TMath::Sqrt(2.); + y[2]=x[2]; +} + +void AliMUONsegmentationV01::Draw() +{ + TBox *box; + + Float_t dx=0.95/fCx[3][1]/2; + Float_t dy=0.95/(Float_t(Npy()))/2; + Float_t x0,y0,x1,y1; + Float_t xc=0.5; + Float_t yc=0.5; + + for (Int_t iy=1; iySetFillColor(isec+1); + box->Draw(); + + box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc); + box->SetFillColor(isec+1); + box->Draw(); + + box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc); + box->SetFillColor(isec+1); + box->Draw(); + + box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc); + box->SetFillColor(isec+1); + box->Draw(); + } + } +} +void AliMUONsegmentationV01::SetCorrFunc(Int_t isec, TF1* func) +{ + (*fCorr)[isec]=func; + +} + +TF1* AliMUONsegmentationV01::CorrFunc(Int_t isec) +{ + return (TF1*) (*fCorr)[isec]; +} + diff --git a/MUON/AliMUONSegResV01.h b/MUON/AliMUONSegResV01.h new file mode 100644 index 00000000000..c072d37e498 --- /dev/null +++ b/MUON/AliMUONSegResV01.h @@ -0,0 +1,113 @@ +#ifndef MUONSegResV01_H +#define MUONSegResV01_H +///////////////////////////////////////////////////// +// Segmentation and Response classes version 01 // +///////////////////////////////////////////////////// + +#include "AliMUON.h" +#include "AliMUONSegResV0.h" +#include "TArrayF.h" +#include "TArrayI.h" +#include "TObjArray.h" + +class AliMUONsegmentationV01 : +public AliMUONsegmentationV0 { + public: + AliMUONsegmentationV01(); + virtual ~AliMUONsegmentationV01(){} + // + // Set Chamber Segmentation Parameters + // + virtual void SetPadDivision(Int_t ndiv[4]); + // Radii + virtual void SetSegRadii(Float_t r[4]); + // + // Transform from pad (wire) to real coordinates and vice versa + // + // Transform from pad to real coordinates + virtual void GetPadIxy(Float_t x ,Float_t y ,Int_t &ix,Int_t &iy); + // Transform from real to pad coordinates + virtual void GetPadCxy(Int_t ix,Int_t iy,Float_t &x ,Float_t &y ); + // + // Initialisation + virtual void Init(AliMUONchamber*); + // + // Get member data + // + // Pad size in x by Sector + virtual Float_t Dpx(Int_t isec); + // Pad size in y by Sector + virtual Float_t Dpy(Int_t isec); + // Max number of Pads in x + virtual Int_t Npx(){return fNpxS[fNsec-1][1]+1;} + // + virtual void SetPad(Int_t,Int_t); + // + // Iterate over pads + // Initialiser + virtual void FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy); + // Stepper + virtual void NextPad(); + // Condition + virtual Int_t MorePads(); + // Get next neighbours + virtual void Neighbours + (Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]); + // Provisory RecCluster coordinates reconstructor + virtual void FitXY(AliMUONRecCluster* Cluster,TClonesArray* MUONdigits); + // + // Current Pad during Integration + // current sector + virtual Int_t ISector() {return fSector;} + // calculate sector from pad coordinates + virtual Int_t Sector(Int_t ix, Int_t iy); + // + // Integration + // Current integration limits + virtual void IntegrationLimits + (Float_t& x1, Float_t& x2, Float_t& y1, Float_t& y2); + // Test points for auto calibration + void GiveTestPoints(Int_t &n, Float_t *x, Float_t *y); + // + // Debugging utilities + virtual void Draw(); + // Function for systematic corrections + virtual void SetCorrFunc(Int_t dum, TF1* func); + virtual TF1* CorrFunc(Int_t); + + + ClassDef(AliMUONsegmentationV01,1) + protected: + // + // Implementation of the segmentation data + // Version 0 models rectangular pads with the same dimensions all + // over the cathode plane + // + // geometry + // + Int_t fNsec; // Number of sectors + TArrayF fRSec; // sector outer radia + TArrayI fNDiv; // pad size division + TArrayF fDpxD; // y pad width per sector + Int_t fNpxS[10][1000]; // Number of pads per sector in x + Float_t fCx[10][1000]; // pad-sector contour x vs y + // Chamber region consideres during disintegration + // (lower left and upper right corner) + // + Float_t fxmin; + Float_t fxmax; + Float_t fymin; + Float_t fymax; + + // + // Current pad during integration (cursor for disintegration) + Int_t fSector; + TObjArray *fCorr; +}; +#endif + + + + + + diff --git a/MUON/AliMUONSegResV02.cxx b/MUON/AliMUONSegResV02.cxx new file mode 100644 index 00000000000..b0a3871c019 --- /dev/null +++ b/MUON/AliMUONSegResV02.cxx @@ -0,0 +1,110 @@ +///////////////////////////////////////////////////// +// Segmentation and Response classes version 02 // +///////////////////////////////////////////////////// + +#include +#include +#include +#include "AliMUONSegResV02.h" +#include "AliRun.h" +#include "AliMC.h" +#include "iostream.h" + +//___________________________________________ +ClassImp(AliMUONsegmentationV02) + +void AliMUONsegmentationV02::SetPADSIZ(Float_t p1, Float_t p2) +{ + fDpy=p1; + fDpx=p2; +} + +Int_t AliMUONsegmentationV02::Npx() +{return AliMUONsegmentationV01::Npy();} + +Int_t AliMUONsegmentationV02::Npy() +{return AliMUONsegmentationV01::Npx();} + + +Float_t AliMUONsegmentationV02::Dpx(Int_t isec) +{return fDpy;} + +Float_t AliMUONsegmentationV02::Dpy(Int_t isec) +{return fDpxD[isec];} + +Int_t AliMUONsegmentationV02::Sector(Int_t ix, Int_t iy) +{return AliMUONsegmentationV01::Sector(iy, ix);} + +void AliMUONsegmentationV02:: +GetPadIxy(Float_t x, Float_t y, Int_t &ix, Int_t &iy) +{ +AliMUONsegmentationV01::GetPadIxy(y, x, iy, ix); +// printf("\n x,y,ix,iy %f %f %d %d", x,y,ix,iy); +} + +void AliMUONsegmentationV02:: +GetPadCxy(Int_t ix, Int_t iy, Float_t &x, Float_t &y) +{ + AliMUONsegmentationV01::GetPadCxy(iy, ix, y, x); +// printf("\n ix,iy,x,y %d %d %f %f ", ix,iy,x,y); +} +void AliMUONsegmentationV02::SetPad(Int_t ix,Int_t iy) +{ + GetPadCxy(ix,iy,fx,fy); + fSector=Sector(ix,iy); +} + + + +void AliMUONsegmentationV02::NextPad() +{ + // + // Step to next pad in integration region + Float_t xc,yc; + Int_t ixc; + +// step up + if (fy < fymax && fy != 0) { + if (fiy==-1) fiy++; + fiy++; +// step right + } else if (fix != fixmax) { + if (fix==-1) fix++; + fix++; +// get y-position of next row (yc), xc not used here + GetPadCxy(fix,fiy,xc,yc); +// get x-pad coordiante for 1 pad in row (fix) + GetPadIxy(xc,fymin,ixc,fiy); + } else { + printf("\n Error: Stepping outside integration region\n "); + } + GetPadCxy(fix,fiy,fx,fy); + fSector=Sector(fix,fiy); + if (MorePads() && + (fSector ==-1 || fSector==0 || + TMath::Abs(fx)<1.5 || TMath::Abs(fy)<1.5)) + NextPad(); +// printf("\n this pad %f %f %d %d \n",fx,fy,fix,fiy); + +} + +Int_t AliMUONsegmentationV02::MorePads() +// +// Are there more pads in the integration region +{ + if ((fy >= fymax && fix >= fixmax) || fx==0) { + return 0; + } else { + return 1; + } +} + +void AliMUONsegmentationV02:: +Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) +{ + Int_t N; + AliMUONsegmentationV01::Neighbours(iY, iX, &N, Ylist, Xlist); + *Nlist=N; +} + + diff --git a/MUON/AliMUONSegResV02.h b/MUON/AliMUONSegResV02.h new file mode 100644 index 00000000000..f1e83866afe --- /dev/null +++ b/MUON/AliMUONSegResV02.h @@ -0,0 +1,60 @@ +#ifndef MUONv02_H +#define MUONv02_H +///////////////////////////////////////////////////// +// Segmentation and Response classes version 01 // +///////////////////////////////////////////////////// + +#include "AliMUON.h" +#include "TArrayF.h" +#include "TArrayI.h" +#include "AliMUONSegResV01.h" +class AliMUONsegmentationV02 : +public AliMUONsegmentationV01 { + public: + AliMUONsegmentationV02(){}; + virtual ~AliMUONsegmentationV02(){} + // + virtual void SetPADSIZ(Float_t p1, Float_t p2); + // + // Get member data + // Pad size in x + virtual Float_t Dpx() {return fDpy;} + // Pad size in y + virtual Float_t Dpy() {return fDpx;} + // Pad size in x by Sector + virtual Float_t Dpx(Int_t isec); + // Pad size in y by Sector + virtual Float_t Dpy(Int_t isec); + // Max number of Pads in x + virtual Int_t Npx(); + // max number of Pads in y + virtual Int_t Npy(); + // calculate sector from pad coordinates + virtual Int_t Sector(Int_t ix, Int_t iy); + // + // Transform from pad (wire) to real coordinates and vice versa + // Transform from pad to real coordinates + virtual void GetPadCxy(Int_t ix,Int_t iy,Float_t &x ,Float_t &y ); + // Transform from pad to real coordinates + virtual void GetPadIxy(Float_t x ,Float_t y ,Int_t &ix,Int_t &iy); + virtual void SetPad(Int_t ix,Int_t iy); + // Stepper + virtual void NextPad(); + // Condition + virtual Int_t MorePads(); + + virtual void Neighbours + (Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]); + // Get next neighbours + ClassDef(AliMUONsegmentationV02,1) //Muon chamber segmentation version 02 + }; +#endif + + + + + + + + + diff --git a/MUON/AliMUONSegResV04.cxx b/MUON/AliMUONSegResV04.cxx new file mode 100644 index 00000000000..06c372a0f20 --- /dev/null +++ b/MUON/AliMUONSegResV04.cxx @@ -0,0 +1,137 @@ +///////////////////////////////////////////////////// +// Segmentation and Response classes version 04 // +///////////////////////////////////////////////////// + +#include +#include +#include + +#include "AliMUONSegResV04.h" +#include "AliRun.h" +#include "AliMC.h" +#include "iostream.h" + +//___________________________________________ +ClassImp(AliMUONsegmentationV04) + + +void AliMUONsegmentationV04::Init(AliMUONchamber* Chamber) +{ + printf("\n Initialise segmentation v04 \n"); +// +// Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector +// These arrays help in converting from real to pad co-ordinates and +// vice versa +// +// +// PCB module size in cm + const Float_t dxPCB=40, dyPCB=40; +// PCB distribution (7 rows with 1+3 segmentation regions) + const Int_t kpcb[7][4] = {{1, 2, 2, 2}, + {0, 3, 2, 2}, + {0, 2, 2, 2}, + {0, 0, 3, 3}, + {0, 0, 2, 3}, + {0, 0, 0, 4}, + {0, 0, 0, 3}}; + + +// +// 3 3 3 | 3 3 3 +// 3 3 3 3 | 3 3 3 3 +// 3 3 3 2 2 | 2 2 3 3 3 +// 3 3 3 2 2 2 | 2 2 2 3 3 3 +// 3 3 2 2 1 1 | 1 1 2 2 3 3 +// 3 3 2 2 1 1 1 | 1 1 1 2 2 3 3 +// 3 3 2 2 1 1 0 | 0 1 1 2 2 3 3 +// ------------------------------ +// 3 3 2 2 1 1 0 | 0 1 1 2 2 3 3 +// 3 3 2 2 1 1 1 | 1 1 1 2 2 3 3 +// 3 3 2 2 1 1 | 1 1 2 2 3 3 +// 3 3 3 2 2 2 | 2 2 2 3 3 3 +// 3 3 3 2 2 | 2 2 3 3 3 +// 3 3 3 3 | 3 3 3 3 +// 3 3 3 | 3 3 3 +// +// number of pad rows per PCB +// + Int_t NpyPCB=Int_t(dyPCB/fDpy); +// +// maximum number of pad rows + fNpy=7*NpyPCB; +// +// Calculate padsize along x + fDpxD[fNsec-1]=fDpx; + if (fNsec > 1) { + for (Int_t i=fNsec-2; i>=0; i--){ + fDpxD[i]=fDpxD[fNsec-1]/fNDiv[i]; + printf("\n test ---dx %d %f \n",i,fDpxD[i]); + } + } +// +// fill the arrays defining the pad segmentation boundaries +// +// loop over pcb module rows + Int_t iy=0; + for (Int_t irow=0; irow<7; irow++) { +// +// loop over pads along the anode wires + for (Int_t i=0; i<=NpyPCB; i++) { +// iy counts the padrow + iy++; +// Loop over sectors (isec=0 is the dead space surounding the beam pipe) + for (Int_t isec=0; isec<4; isec++) { + if (isec==0) { + fNpxS[0][iy]=kpcb[irow][0]*Int_t(dxPCB/fDpxD[0]); + fCx[0][iy]=kpcb[irow][0]*dxPCB; + } else { + fNpxS[isec][iy]=fNpxS[isec-1][iy] + +kpcb[irow][isec]*Int_t(dxPCB/fDpxD[isec]); + + fCx[isec][iy]=fCx[isec-1][iy] + +kpcb[irow][isec]*dxPCB; + } + } // sectors + } // pad raws in module + } // PCB rows +/* + for (Int_t iy=1; iy< fNpy; iy++) { + printf("\nBoundary %d %f %d %f %d %f %d %f", + fNpxS[0][iy], fCx[0][iy], + fNpxS[1][iy], fCx[1][iy], + fNpxS[2][iy], fCx[2][iy], + fNpxS[3][iy], fCx[3][iy]); + + } +*/ +} + +void AliMUONsegmentationV04::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) +{ + n=3; + x[0]=(fCx[1][1]+fCx[0][1])/2/TMath::Sqrt(2.); + y[0]=x[0]; + x[1]=(fCx[2][1]+fCx[1][1])/2/TMath::Sqrt(2.); + y[1]=x[1]; + x[2]=(fCx[3][1]+fCx[2][1])/2/TMath::Sqrt(2.); + y[2]=x[2]; + printf("\n 1%f %f", x[0], y[0]); + printf("\n 2%f %f", x[1], y[1]); + printf("\n 3%f %f\n ", x[2], y[2]); +} + + + + + + + + + + + + + + + + diff --git a/MUON/AliMUONSegResV04.h b/MUON/AliMUONSegResV04.h new file mode 100644 index 00000000000..4a24fcc81da --- /dev/null +++ b/MUON/AliMUONSegResV04.h @@ -0,0 +1,30 @@ +#ifndef MUONSegResV04_H +#define MUONSegResV04_H +///////////////////////////////////////////////////// +// Segmentation and Response classes version 01 // +///////////////////////////////////////////////////// + +#include "AliMUON.h" +#include "AliMUONSegResV01.h" +#include "TArrayF.h" +#include "TArrayI.h" +class AliMUONsegmentationV04 : +public AliMUONsegmentationV01 { + public: + AliMUONsegmentationV04(){} + virtual ~AliMUONsegmentationV04(){} + // Initialisation + virtual void Init(AliMUONchamber*); + // Test points for auto calibration + void GiveTestPoints(Int_t &n, Float_t *x, Float_t *y); + ClassDef(AliMUONsegmentationV04,1) +}; + + +#endif + + + + + + diff --git a/MUON/AliMUONSegResV05.cxx b/MUON/AliMUONSegResV05.cxx new file mode 100644 index 00000000000..e4815f86b0e --- /dev/null +++ b/MUON/AliMUONSegResV05.cxx @@ -0,0 +1,135 @@ +///////////////////////////////////////////////////// +// Segmentation and Response classes version 04 // +///////////////////////////////////////////////////// + +#include +#include +#include + +#include "AliMUONSegResV05.h" +#include "AliRun.h" +#include "AliMC.h" +#include "iostream.h" + +//___________________________________________ +ClassImp(AliMUONsegmentationV05) + + +void AliMUONsegmentationV05::Init(AliMUONchamber* Chamber) +{ + printf("\n Initialise segmentation v05 \n"); +// +// Fill the arrays fCx (x-contour) and fNpxS (ix-contour) for each sector +// These arrays help in converting from real to pad co-ordinates and +// vice versa +// +// +// PCB module size in cm + const Float_t dxPCB=40, dyPCB=40; +// PCB distribution (7 rows with 1+3 segmentation regions) + const Int_t kpcb[7][4] = {{1, 2, 2, 2}, + {0, 3, 2, 2}, + {0, 2, 2, 2}, + {0, 0, 3, 3}, + {0, 0, 2, 3}, + {0, 0, 0, 4}, + {0, 0, 0, 3}}; + + +// +// 3 3 3 | 3 3 3 +// 3 3 3 3 | 3 3 3 3 +// 3 3 3 2 2 | 2 2 3 3 3 +// 3 3 3 2 2 2 | 2 2 2 3 3 3 +// 3 3 2 2 1 1 | 1 1 2 2 3 3 +// 3 3 2 2 1 1 1 | 1 1 1 2 2 3 3 +// 3 3 2 2 1 1 0 | 0 1 1 2 2 3 3 +// ------------------------------ +// 3 3 2 2 1 1 0 | 0 1 1 2 2 3 3 +// 3 3 2 2 1 1 1 | 1 1 1 2 2 3 3 +// 3 3 2 2 1 1 | 1 1 2 2 3 3 +// 3 3 3 2 2 2 | 2 2 2 3 3 3 +// 3 3 3 2 2 | 2 2 3 3 3 +// 3 3 3 3 | 3 3 3 3 +// 3 3 3 | 3 3 3 +// +// number of pad rows per PCB +// + Int_t NpyPCB=Int_t(dyPCB/fDpy); +// +// maximum number of pad rows + fNpy=7*NpyPCB; +// +// Calculate padsize along x + fDpxD[fNsec-1]=fDpx; + if (fNsec > 1) { + for (Int_t i=fNsec-2; i>=0; i--){ + fDpxD[i]=fDpxD[fNsec-1]/fNDiv[i]; + printf("\n test ---dx %d %f \n",i,fDpxD[i]); + } + } +// +// fill the arrays defining the pad segmentation boundaries +// +// loop over pcb module rows + Int_t iy=0; + for (Int_t irow=0; irow<7; irow++) { +// +// loop over pads along the anode wires + for (Int_t i=0; i<=NpyPCB; i++) { +// iy counts the padrow + iy++; +// Loop over sectors (isec=0 is the dead space surounding the beam pipe) + for (Int_t isec=0; isec<4; isec++) { + if (isec==0) { + fNpxS[0][iy]=kpcb[irow][0]*Int_t(dxPCB/fDpxD[0]); + fCx[0][iy]=kpcb[irow][0]*dxPCB; + } else { + fNpxS[isec][iy]=fNpxS[isec-1][iy] + +kpcb[irow][isec]*Int_t(dxPCB/fDpxD[isec]); + + fCx[isec][iy]=fCx[isec-1][iy] + +kpcb[irow][isec]*dxPCB; + } + } // sectors + } // pad raws in module + } // PCB rows +/* + for (Int_t iy=1; iy< fNpy; iy++) { + printf("\nBoundary %d %f %d %f %d %f %d %f", + fNpxS[0][iy], fCx[0][iy], + fNpxS[1][iy], fCx[1][iy], + fNpxS[2][iy], fCx[2][iy], + fNpxS[3][iy], fCx[3][iy]); + + } +*/ +} + +void AliMUONsegmentationV05::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) +{ + n=1; + x[0]=(fCx[1][1]+fCx[0][1])/2/TMath::Sqrt(2.); + y[0]=x[0]; +// x[1]=(fCx[2][1]+fCx[1][1])/2; +// y[1]=x[1]; +// x[2]=(fCx[3][1]+fCx[2][1])/2; +// y[2]=x[2]; +} + + + + + + + + + + + + + + + + + diff --git a/MUON/AliMUONSegResV05.h b/MUON/AliMUONSegResV05.h new file mode 100644 index 00000000000..01c1751dea6 --- /dev/null +++ b/MUON/AliMUONSegResV05.h @@ -0,0 +1,28 @@ +#ifndef MUONSegResV05_H +#define MUONSegResV05_H +///////////////////////////////////////////////////// +// Segmentation and Response classes version 01 // +///////////////////////////////////////////////////// + +#include "AliMUON.h" +#include "AliMUONSegResV02.h" +#include "TArrayF.h" +#include "TArrayI.h" +class AliMUONsegmentationV05 : +public AliMUONsegmentationV02 { + public: + AliMUONsegmentationV05(){} + virtual ~AliMUONsegmentationV05(){} + // Initialisation + virtual void Init(AliMUONchamber*); + // Test points for auto calibration + void GiveTestPoints(Int_t &n, Float_t *x, Float_t *y); + ClassDef(AliMUONsegmentationV05,1) +}; +#endif + + + + + + diff --git a/MUON/AliMUONSegResV1.cxx b/MUON/AliMUONSegResV1.cxx new file mode 100644 index 00000000000..78e64479fdf --- /dev/null +++ b/MUON/AliMUONSegResV1.cxx @@ -0,0 +1,497 @@ +///////////////////////////////////////////////////////// +// Manager and hits classes for set:MUON version LYON // +///////////////////////////////////////////////////////// + +#include +#include +#include + +//#include "AliMUONv0.h" +#include "AliMUONchamber.h" +#include "AliMUONSegResV1.h" +#include "AliRun.h" +#include "AliMC.h" +#include "iostream.h" + +//___________________________________________ +ClassImp(AliMUONsegmentationV1) + +AliMUONsegmentationV1::AliMUONsegmentationV1() + // initizalize the class with default settings +{ +fNzone=1; +fDAnod=0.0; +fDpx=0.0; +fDpx=0.0; // forces crash if not initialized by user +fNZoneCut[0]=0; +fSensOffset=0; +} + + +void AliMUONsegmentationV1::Init(AliMUONchamber* Chamber) +{ + // valid only for T5/6 + // beware : frMin is SENSITIVE radius by definition. + frSensMin2 = (Chamber->RInner())*(Chamber->RInner()); + frSensMax2 = (Chamber->ROuter())*(Chamber->ROuter()); + fNpx=(Int_t) (Chamber->ROuter()/fDpx) + 1; + fNpy=(Int_t) (Chamber->ROuter()/fDpy) + 1; + // fNwire=3; + DefaultCut(); + fCorr=0; +} + +void AliMUONsegmentationV1::DefaultCut(void) +{ +SetNzone(3); +AddCut(0,5*6,18*8); +AddCut(0,9*6,15*8); +AddCut(0,11*6,12*8); +AddCut(0,12*6,9*8); +AddCut(0,13*6,6*8); +AddCut(1,6*6,20*12); +AddCut(1,12*6,18*12); +AddCut(1,15*6,15*12); +AddCut(1,18*6,12*12); +AddCut(1,21*6,9*12); +SetSensOffset(3.0); +SetDAnod(0.325); +} + +Int_t AliMUONsegmentationV1::GetiAnod(Float_t xhit) +{ +Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1; +return (xhit>0) ? kwire : -kwire ; +} + +Float_t AliMUONsegmentationV1::GetAnod(Float_t xhit) +{ + Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1; // to be compatible ... + return (xhit>0) ? fDAnod*(kwire-0.5)+fSensOffset : -fDAnod*(kwire-0.5)-fSensOffset ; +} + +// For chamber T5/6 p1 and p2 should be same for each zone +void AliMUONsegmentationV1::SetPADSIZ(Float_t p1, Float_t p2) +{ + fDpx=p1; + fDpy=p2; +} + +void AliMUONsegmentationV1:: + GetPadIxy(Float_t x, Float_t y, Int_t &ix, Int_t &iy) +{ +// returns pad coordinates (ix,iy) for given real coordinates (x,y) +// + ix = (x>0)? Int_t((x-fSensOffset)/fDpx)+1 : Int_t((x+fSensOffset)/fDpx)-1; + iy = (y>0)? Int_t((y-fSensOffset)/fDpy)+1 : Int_t((y+fSensOffset)/fDpy)-1; +} + +void AliMUONsegmentationV1:: +GetPadCxy(Int_t ix, Int_t iy, Float_t &x, Float_t &y) +{ +// returns real coordinates (x,y) for given pad coordinates (ix,iy) +// + x = (ix>0) ? (Float_t(ix)-0.5)*fDpx+fSensOffset : (Float_t(ix)+0.5)*fDpx-fSensOffset; + y = (iy>0) ? (Float_t(iy)-0.5)*fDpy+fSensOffset : (Float_t(iy)+0.5)*fDpy-fSensOffset; +} + +void AliMUONsegmentationV1::AddCut(Int_t Zone, Int_t nX, Int_t nY) +{// the pad nX,nY is last INSIDE zone Zone. First pad is labelled 1 and not 0 +if (Zone+1>=fNzone) // no cut for last Zone : it is the natural boundary of the chamber + printf("AliMUONsegmentationV1::AddCut ==> Zone %d not allowed !\n",Zone); +fZoneX[Zone][fNZoneCut[Zone]] = nX; +fZoneY[Zone][fNZoneCut[Zone]] = nY; +fNZoneCut[Zone]++; +} + +Int_t AliMUONsegmentationV1::GetZone(Float_t X, Float_t Y) +{ +Int_t iX, iY; +GetPadIxy(X,Y,iX,iY); +return GetZone( iX , iY ); +} + +Int_t AliMUONsegmentationV1::GetZone(Int_t nX, Int_t nY) +{// Beware : first pad begins at 1 !! +Int_t aX = TMath::Abs(nX); +Int_t aY = TMath::Abs(nY); +Int_t zone=fNzone-1; +for (Int_t iZone=fNzone-2;iZone>=0;iZone--) + { + for (Int_t iCut=0;iCut frSensMax2 || radius2 < frSensMin2 ) + && MorePads() ) + NextPad(); +} + +void AliMUONsegmentationV1::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) +{ + // + // Find the wire position (center of charge distribution) + Float_t x0a=GetAnod(xhit); + fxhit=x0a; + fyhit=yhit; + + // + // and take fNsigma*sigma around this center + Float_t x01=x0a - dx; + Float_t x02=x0a + dx; + Float_t y01=yhit - dy; + Float_t y02=yhit + dy; + + // Do not cross over frames... + if (x01 * x0a < 0) + x01 = TMath::Sign(fSensOffset, x0a); + if (x02 * x0a < 0) + x02 = TMath::Sign(fSensOffset, x0a); + if (y01 * yhit < 0) + y01 = TMath::Sign(fSensOffset, yhit); + if (y02 * yhit < 0) + y02 = TMath::Sign(fSensOffset, yhit); + // + // find the pads over which the charge distributes + GetPadIxy(x01,y01,fixmin,fiymin); + GetPadIxy(x02,y02,fixmax,fiymax); + // + // Set current pad to lower left corner + fix=fixmin; + fiy=fiymin; + SetPadCoord(fix,fiy); +} + +void AliMUONsegmentationV1::NextPad() +{ + // + // Step to next pad in integration region + if (fix != fixmax) { + fix++; + } else if (fiy != fiymax) { + fix=fixmin; + fiy++; + } else + printf("\n Error: Stepping outside integration region\n "); + SetPadCoord(fix,fiy); +} + +Int_t AliMUONsegmentationV1::MorePads() +// +// Are there more pads in the integration region +{ + if (fix == fixmax && fiy == fiymax) { + return 0; + } else { + return 1; + } +} + +Int_t AliMUONsegmentationV1::IsParallel2(Int_t iX, Int_t iY) +// test if the pad is read in parallel for zone 2 +// iX and iY are assumed to be positive and starting at 0 numbering (cF. iX) +// returns 1 or 2 if read in parallel, +// according to the actual number in the chain, 0 else +// +// chainage is result is +// 1 2 3 1 2 3 1 1 1 2 2 2 y +// 7 8 9 10 11 12 0 0 0 0 0 0 ^ +// 4 5 6 4 5 6 1 1 1 2 2 2 +->x +// +{ +if (iY%3==1) return 0; +return (iX%6)/3+1; +} + +Int_t AliMUONsegmentationV1::IsParallel3(Int_t iX, Int_t iY) +// test if the pad is read in parallel for zone 3 +// iX and iY are assumed to be positive and starting at 0 numbering (cF. iX) +// returns 1,2 or 3 if read in parallel, +// according to the actual number in the chain, 0 else +// +// chainage is result is +//16 2 3 1 2 3 1 2 3 0 1 1 1 2 2 2 3 3 +// 7 8 9 10 11 12 13 14 15 0 0 0 0 0 0 0 0 0 +// 4 5 6 4 5 6 4 5 6 1 1 1 2 2 2 3 3 3 +// +{ +if (iY%3==1) return 0; +return (iX%9)/3+1 - (iY%3==2 && iX%3==0); +} + +Int_t AliMUONsegmentationV1::NParallel2(Int_t iX, Int_t iY) +// returns the number of pads connected in parallel for zone 2 +// iX and iY are assumed to be positive and starting at 0 numbering (cF. iX) +// +// result is +// 2 2 2 2 2 2 +// 1 1 1 1 1 1 +// 2 2 2 2 2 2 +// +{ +if (iY%3==1) return 1; +return 2; +} + +Int_t AliMUONsegmentationV1::NParallel3(Int_t iX, Int_t iY) +// test if the pad is read in parallel for zone 3 +// iX and iY are assumed to be positive and starting at 0 numbering (cF. iX) +// returns 1,2 or 3 if read in parallel, +// according to the actual number in the chain, 0 else +// +// result is +// 1 3 3 2 3 3 2 3 3 +// 1 1 1 1 1 1 1 1 1 +// 3 3 3 3 3 3 3 3 3 +// +{ +if (iY%3==1) return 1; +if (iY%3==2 && iX%9==0) return 1; +return 3 - (iY%3==2 && iX%3==0); +} + + +Int_t AliMUONsegmentationV1::Ix(Int_t trueX, Int_t trueY) +// returns the X number of pad which corresponds to the logical +// channel, expressed in x and y. +{ +Int_t wix = TMath::Abs(trueX)-1; +Int_t wiy = TMath::Abs(trueY)-1; +Int_t zone = GetZone(trueX,trueY); +Int_t par3; +switch (zone) { + case 0: return trueX; + case 1: + if (IsParallel2(wix,wiy) == 2) + return (trueX>0)? trueX-3 : trueX+3 ; + return trueX; + case 2: + if ( (par3= IsParallel3(wix,wiy)) ) + return (trueX>0) ? trueX-3*(par3-1) : trueX+3*(par3-1) ; + return trueX ; + default : + printf("Couille dans AliMUONsegmentationV1::ix\n"); + } +return -1; +} + +Int_t AliMUONsegmentationV1::Ix() +// returns the X number of pad which has to increment charge +// due to parallel read-out +{return Ix(fix,fiy);} + +Int_t AliMUONsegmentationV1::ISector() +// This function is of no use for this kind of segmentation. +{ +return GetZone(fix,fiy); +} + +void AliMUONsegmentationV1::SigGenInit(Float_t x,Float_t y,Float_t z) +{ +// +// Initialises pad and wire position during stepping + fxt =x; + fyt =y; + GetPadIxy(x,y,fixt,fiyt); + fiwt= GetiAnod(x); + +} + +Int_t AliMUONsegmentationV1::SigGenCond(Float_t x,Float_t y,Float_t z) +{ +// +// Signal will be generated if particle crosses pad boundary or +// boundary between two wires. + Int_t ixt; + Int_t iyt; + GetPadIxy(x,y,ixt,iyt); + Int_t iwt= GetiAnod(x); + + if ((ixt != fixt) || (iyt !=fiyt) || (iwt != fiwt)) { + return 1; + } else { + return 0; + } +} + +void AliMUONsegmentationV1:: +IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) +{ + x1=fxhit-fx-fDpx/2.; + x2=x1+fDpx; + y1=fyhit-fy-fDpy/2.; + y2=y1+fDpy; +} + +void AliMUONsegmentationV1::GetNParallelAndOffset(Int_t iX, Int_t iY,Int_t +*Nparallel, Int_t* Offset) +{ +Int_t wix = TMath::Abs(iX)-1; +Int_t wiy = TMath::Abs(iY)-1; +Int_t zone = GetZone(iX,iY); +switch (zone) { + case 0: + *Nparallel=1; + *Offset=0; + break; + case 1: + *Nparallel = NParallel2(wix,wiy); + (iX>0) ? *Offset =3 : *Offset = -3; + if (IsParallel2(wix,wiy)>1) + printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n"); + break; + case 2: + *Nparallel = NParallel3(wix,wiy); + (iX>0) ? *Offset =3 : *Offset = -3; + if (IsParallel3(wix,wiy)>1) + printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n"); + break; + } +} + + +Float_t AliMUONsegmentationV1::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t *Offset) +// +// Computes the offset for which the physical pad has the minimum distance squared +// (returned value) to the given coordinates +{ +Int_t nPara,offset; +GetNParallelAndOffset(iX,iY,&nPara,&offset); +Float_t d2min=1E10; +for (Int_t i=0;i d2) + { + d2min = d2; + *Offset = i*offset; + } + } +return d2min; +} + +void AliMUONsegmentationV1::CleanNeighbours(Int_t* Nlist, Int_t *Xlist, + Int_t *Ylist) +// In the raw neighbours list, some pads do not exist +// and some others are read in parallel ... +// So we prune non-existing neighbours from the list (event if this should be +// at last not be a problem due to the clustering algorithm...) +{ +Int_t nTot=0; +for (Int_t nList=0;nList<*Nlist;nList++) + { + // prune if it does not exist + if ( Xlist[nList]==0 || Ylist[nList]==0 ) + continue; + // compute true position + Xlist[nTot] = Ix(Xlist[nList],Ylist[nList]) ; + Ylist[nTot] = Ylist[nList] ; + // and prune if it does already exist + Int_t nTest; + for (nTest=0;nTest1) { + Xlist[4]=Xlist[5]=iX+offset;Xlist[6]=iX+offset-1;Xlist[7]=iX+offset+1; + Ylist[4]=iY-1;Ylist[5]=iY+1;Ylist[6]=Ylist[7]=iY; + if (nParallel>2) { + Xlist[8]=Xlist[9]=iX+2*offset;Xlist[10]=iX+2*offset-1;Xlist[11]=iX+2*offset+1; + Ylist[8]=iY-1;Ylist[9]=iY+1;Ylist[10]=Ylist[11]=iY; + } + } +CleanNeighbours(Nlist,Xlist,Ylist); +} + +void AliMUONsegmentationV1:: +NeighboursDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[24], Int_t Ylist[24]) +// returns the X number of pad which has to increment charge +// due to parallel read-out +{ +Int_t nParallel, offset; +GetNParallelAndOffset(iX,iY,&nParallel,&offset); +// +// now fill raw list of neighbours +*Nlist=0; +for (Int_t i=0;i +#include +#include "TVirtualPad.h" +ClassImp(AliMUONTUBE) + +AliMUONTUBE::AliMUONTUBE():TTUBE() +{;} + +//_____________________________________________________________________________ + +AliMUONTUBE::AliMUONTUBE(Text_t *name, Text_t *title, Text_t *material, Float_t rmin, + Float_t rmax, Float_t dz,Float_t aspect): + TTUBE(name, title, material, rmin, rmax, dz, aspect) +{} + +//______________________________________________________________________________ + AliMUONTUBE::AliMUONTUBE(Text_t *name, Text_t *title, Text_t *material, Float_t rmax, + Float_t dz) + : TTUBE(name, title, material, rmax, dz) +{ +} + +//______________________________________________________________________________ + void AliMUONTUBE::Paint(Option_t *option) +{ +//*-*-*-*-*-*-*-*Paint this 3-D shape with its current attributes*-*-*-*-*-*-*-* +//*-* ================================================ + + Int_t i, j; + Int_t n = GetNumberOfDivisions(); + const Int_t numpoints = 4*n; + +//*-* Allocate memory for points *-* + + Float_t *points = new Float_t[3*numpoints]; + if (!points) return; + + SetPoints(points); + + if (gPad->GetView3D()) PaintGLPoints(points); + +//== for (i = 0; i < numpoints; i++) +//== gNode->Local2Master(&points[3*i],&points[3*i]); + + X3DBuffer *buff = new X3DBuffer; + if (buff) { + buff->numPoints = numpoints; + buff->numSegs = n*6; + if (strstr(option, "x3d")) buff->numSegs = n*8; + buff->numPolys = n*4; + } + +//*-* Allocate memory for points *-* + + buff->points = points; + + Int_t c = ((GetLineColor() % 8) - 1) * 4; // Basic colors: 0, 1, ... 7 + if (c < 0) c = 0; + +//*-* Allocate memory for segments *-* + + buff->segs = new Int_t[buff->numSegs*3]; + if (buff->segs) { + for (i = 0; i < 4; i++) { + for (j = 0; j < n; j++) { + buff->segs[(i*n+j)*3 ] = c; + buff->segs[(i*n+j)*3+1] = i*n+j; + buff->segs[(i*n+j)*3+2] = i*n+j+1; + } + buff->segs[(i*n+j-1)*3+2] = i*n; + } + for (i = 4; i < 6; i++) { + for (j = 0; j < n; j++) { + buff->segs[(i*n+j)*3 ] = c+1; + buff->segs[(i*n+j)*3+1] = (i-4)*n+j; + buff->segs[(i*n+j)*3+2] = (i-2)*n+j; + } + } + if (strstr(option, "x3d")) + { + for (i = 6; i < 8; i++) { + for (j = 0; j < n; j++) { + buff->segs[(i*n+j)*3 ] = c; + buff->segs[(i*n+j)*3+1] = 2*(i-6)*n+j; + buff->segs[(i*n+j)*3+2] = (2*(i-6)+1)*n+j; + } + } + } + } +//*-* Allocate memory for polygons *-* + + Int_t indx = 0; + + buff->polys = new Int_t[buff->numPolys*6]; + if (buff->polys) { + for (i = 0; i < 2; i++) { + for (j = 0; j < n; j++) { + indx = 6*(i*n+j); + buff->polys[indx ] = c; + buff->polys[indx+1] = 4; + buff->polys[indx+2] = i*n+j; + buff->polys[indx+3] = (4+i)*n+j; + buff->polys[indx+4] = (2+i)*n+j; + buff->polys[indx+5] = (4+i)*n+j+1; + } + buff->polys[indx+5] = (4+i)*n; + } + for (i = 2; i < 4; i++) { + for (j = 0; j < n; j++) { + indx = 6*(i*n+j); + buff->polys[indx ] = c+(i-2)*2+1; + buff->polys[indx+1] = 4; + buff->polys[indx+2] = (i-2)*2*n+j; + buff->polys[indx+3] = (4+i)*n+j; + buff->polys[indx+4] = ((i-2)*2+1)*n+j; + buff->polys[indx+5] = (4+i)*n+j+1; + } + buff->polys[indx+5] = (4+i)*n; + } + } + + //*-* Paint in the pad + Bool_t rangeView = strcmp(option,"range")==0 ? kTRUE : kFALSE; + PaintShape(buff,rangeView); + + if (strstr(option, "x3d")) { + if(buff && buff->points && buff->segs) + FillX3DBuffer(buff); + else { + gSize3D.numPoints -= buff->numPoints; + gSize3D.numSegs -= buff->numSegs; + gSize3D.numPolys -= buff->numPolys; + } + } + + if (buff->points) delete [] buff->points; + if (buff->segs) delete [] buff->segs; + if (buff->polys) delete [] buff->polys; + if (buff) delete buff; +} + diff --git a/MUON/AliMUONTUBE.h b/MUON/AliMUONTUBE.h new file mode 100644 index 00000000000..414c6daa290 --- /dev/null +++ b/MUON/AliMUONTUBE.h @@ -0,0 +1,19 @@ +#ifndef AliMUONTube_H +#define AliMUONTube_H +//////////////////////////////////////////////// +// Manager and hits classes for set:MUON // +//////////////////////////////////////////////// +#include "TTUBE.h" + +class AliMUONTUBE : +public TTUBE { + + public: + AliMUONTUBE(); + AliMUONTUBE(Text_t *name, Text_t *title, Text_t *material, Float_t rmin, Float_t rmax, Float_t dz,Float_t aspect); + AliMUONTUBE(Text_t *name, Text_t *title, Text_t *material, Float_t rmax, Float_t dz); + virtual ~AliMUONTUBE(){}; + virtual void Paint(Option_t* option); + ClassDef(AliMUONTUBE,1) +}; +#endif diff --git a/MUON/AliMUONchamber.cxx b/MUON/AliMUONchamber.cxx new file mode 100644 index 00000000000..b670ee3c86d --- /dev/null +++ b/MUON/AliMUONchamber.cxx @@ -0,0 +1,81 @@ +#include "AliMUONchamber.h" +#include "TMath.h" +ClassImp(AliMUONchamber) + AliMUONchamber::AliMUONchamber() +{ + fSegmentation = new TObjArray(2); + fResponse=0; + fnsec=1; +} + +void AliMUONchamber::Init() +{ + + ((AliMUONsegmentation *) (*fSegmentation)[0])->Init(this); + if (fnsec==2) { + ((AliMUONsegmentation *) (*fSegmentation)[1])->Init(this); + } + +} + +void AliMUONchamber::DisIntegration(Float_t eloss, Float_t xhit, Float_t yhit, + Int_t& nnew,Float_t newclust[6][500]) +{ +// +// Generates pad hits (simulated cluster) +// using the segmentation and the response model + Float_t dx, dy; + // + // Width of the integration area + // + dx=fResponse->SigmaIntegration()*fResponse->ChargeSpreadX(); + dy=fResponse->SigmaIntegration()*fResponse->ChargeSpreadY(); + // + // Get pulse height from energy loss + Float_t qtot = fResponse->IntPH(eloss); + // + // Loop Over Pads + + Float_t qcheck=0, qp; + nnew=0; + for (Int_t i=1; i<=fnsec; i++) { + qcheck=0; + AliMUONsegmentation * segmentation=(AliMUONsegmentation *) (*fSegmentation)[i-1]; + for (segmentation->FirstPad(xhit, yhit, dx, dy); + segmentation->MorePads(); + segmentation->NextPad()) + { + qp=fResponse->IntXY(segmentation); + qp=TMath::Abs(qp); + +// +// + if (qp > 1.e-4) { + qcheck+=qp; + // + // --- store signal information + newclust[0][nnew]=qtot; + newclust[1][nnew]=segmentation->Ix(); + newclust[2][nnew]=segmentation->Iy(); + newclust[3][nnew]=qp * qtot; + newclust[4][nnew]=segmentation->ISector(); + newclust[5][nnew]=(Float_t) i; +// printf("\n pad hit %d %d %f %f \n",nnew,i,newclust[1][nnew],newclust[2][nnew]); + nnew++; + + + } + } // Pad loop +// printf("\n check sum is %f %f %f %f %d \n",qcheck,qtot,xhit,yhit,fGid); + } // Cathode plane loop +} + + + + void AliMUONchamber::InitGeo(Float_t zpos) +{ +// sensitive gas gap + fdGas= 0.5; +// 3% radiation length of aluminum (X0=8.9 cm) + fdAlu= 3.0/100*8.9; +} diff --git a/MUON/AliMUONchamber.h b/MUON/AliMUONchamber.h new file mode 100644 index 00000000000..b0bb093b2ec --- /dev/null +++ b/MUON/AliMUONchamber.h @@ -0,0 +1,128 @@ +#ifndef MUONchamber_H +#define MUONchamber_H +#include "TObjArray.h" +#include "AliMUONSegRes.h" + +class AliMUONClusterFinder; +class AliMUONresponse ; +class AliMUONsegmentation ; + +class AliMUONchamber: +public TObject +{ + public: + AliMUONchamber(); + ~AliMUONchamber(){} +// +// Set and get GEANT id + Int_t GetGid() {return fGid;} + void SetGid(Int_t id) {fGid=id;} +// +// Initialisation and z-Position + void Init(); + void SetZPOS(Float_t p1) {fzPos=p1;} + Float_t ZPosition() {return fzPos;} +// Set inner radius of sensitive volume + void SetRInner(Float_t rmin) {frMin=rmin;} +// Set outer radius of sensitive volum + void SetROuter(Float_t rmax) {frMax=rmax;} + +// Return inner radius of sensitive volume + Float_t RInner() {return frMin;} +// Return outer radius of sensitive volum + Float_t ROuter() {return frMax;} +// +// Configure response model + void ResponseModel(AliMUONresponse* thisResponse) {fResponse=thisResponse;} +// +// Configure segmentation model + void SegmentationModel(Int_t i, AliMUONsegmentation* thisSegmentation) { + (*fSegmentation)[i-1] = thisSegmentation; + } + void ReconstructionModel(AliMUONClusterFinder *thisReconstruction) { + fReconstruction = thisReconstruction; + } + +// +// Get reference to response model + AliMUONresponse* &GetResponseModel(){return fResponse;} +// + AliMUONClusterFinder* &GetReconstructionModel(){return fReconstruction;} +// +// Get reference to segmentation model + AliMUONsegmentation* GetSegmentationModel(Int_t isec) { + return (AliMUONsegmentation *) (*fSegmentation)[isec-1]; + } + TObjArray* GetChamberSegmentation(){return fSegmentation;} + + Int_t Nsec() {return fnsec;} + void SetNsec(Int_t nsec) {fnsec=nsec;} +// +// Member function forwarding to the segmentation and response models +// +// Calculate pulse height from energy loss + Float_t IntPH(Float_t eloss) {return fResponse->IntPH(eloss);} +// +// Ask segmentation if signal should be generated + Int_t SigGenCond(Float_t x, Float_t y, Float_t z) + { + if (fnsec==1) { + return ((AliMUONsegmentation*) (*fSegmentation)[0]) + ->SigGenCond(x, y, z) ; + } else { + return (((AliMUONsegmentation*) (*fSegmentation)[0]) + ->SigGenCond(x, y, z)) || + (((AliMUONsegmentation*) (*fSegmentation)[1]) + ->SigGenCond(x, y, z)) ; + } + } +// +// Initialisation of segmentation for hit + void SigGenInit(Float_t x, Float_t y, Float_t z) + { + + if (fnsec==1) { + ((AliMUONsegmentation*) (*fSegmentation)[0])->SigGenInit(x, y, z) ; + } else { + ((AliMUONsegmentation*) (*fSegmentation)[0])->SigGenInit(x, y, z) ; + ((AliMUONsegmentation*) (*fSegmentation)[1])->SigGenInit(x, y, z) ; + } + } + +// Configuration forwarding +// + void SetSigmaIntegration(Float_t p1) {fResponse->SetSigmaIntegration(p1);} + void SetChargeSlope(Float_t p1) {fResponse->SetChargeSlope(p1);} + void SetChargeSpread(Float_t p1, Float_t p2) {fResponse->SetChargeSpread(p1,p2);} + void SetMaxAdc(Float_t p1) {fResponse->SetMaxAdc(p1);} + + void SetPADSIZ(Int_t isec, Float_t p1, Float_t p2) { + ((AliMUONsegmentation*) (*fSegmentation)[isec-1])->SetPADSIZ(p1,p2); + } +// +// Cluster formation method + void DisIntegration(Float_t, Float_t, Float_t, Int_t&x, Float_t newclust[6][500]); + ClassDef(AliMUONchamber,1) + void InitGeo(Float_t z); + + private: +// GEANT volume if for sensitive volume of this chamber + Int_t fGid; +// z-position of this chamber + Float_t fzPos; // z-position of chambers + Int_t fnsec; // number of segmentation zones + Float_t frMin; // innermost sensitive radius + Float_t frMax; // outermost sensitive radius +// The segmentation models for the cathode planes +// fnsec=1: one plane segmented, fnsec=2: both planes are segmented. + + TObjArray *fSegmentation; + AliMUONClusterFinder *fReconstruction; + AliMUONresponse *fResponse; + + public: + Float_t fdGas; // half gaz gap + Float_t fdAlu; // half Alu width +}; + +#endif diff --git a/MUON/AliMUONdisplay.cxx b/MUON/AliMUONdisplay.cxx index af6a00e3817..69c3c164ce5 100644 --- a/MUON/AliMUONdisplay.cxx +++ b/MUON/AliMUONdisplay.cxx @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -28,6 +27,7 @@ #include #include #include +#include #include #include "AliRun.h" @@ -39,6 +39,7 @@ #include "TParticle.h" + ClassImp(AliMUONdisplay) @@ -47,6 +48,9 @@ AliMUONdisplay::AliMUONdisplay() { fPoints = 0; fPhits = 0; + fRpoints = 0; + fR2points = 0; + fCpoints = 0; fCanvas = 0; } @@ -99,7 +103,7 @@ AliMUONdisplay::AliMUONdisplay(Int_t size) // If you are lost, you can click on HELP in any Root canvas or browser. //Begin_Html /* - + */ //End_Html @@ -109,21 +113,26 @@ AliMUONdisplay::AliMUONdisplay(Int_t size) gAlice->SetDisplay(this); // Initialize display default parameters - SetRange(); - + SetRange(200,2000); // Set front view by default - fTheta = 0; + fTheta = 0; fPhi = -90; - fPsi = 0; + fPsi = 0; fChamber = 1; fCathode = 1; // fRzone = 1.e10; fDrawClusters = kTRUE; + fDrawCoG = kTRUE; + fDrawCoG = kTRUE; + fDrawCathCor = kTRUE; fZoomMode = 1; fZooms = 0; fClustersCuts = 0; fPoints = 0; - fPhits = 0; + fPhits = 0; + fRpoints = 0; + fR2points = 0; + fCpoints = 0; // Create colors CreateColors(); // Create display canvas @@ -202,6 +211,18 @@ AliMUONdisplay::~AliMUONdisplay() if (fPhits) fPhits->Delete(); delete fPhits; fPhits = 0; + // + if (fRpoints) fRpoints->Delete(); + delete fRpoints; + fRpoints = 0; +// + if (fR2points) fR2points->Delete(); + delete fR2points; + fR2points = 0; +// + if (fCpoints) fCpoints->Delete(); + delete fCpoints; + fCpoints = 0; } //_____________________________________________________________________________ @@ -222,7 +243,7 @@ void AliMUONdisplay::DisplayButtons() fButtons->SetBorderSize(2); fButtons->cd(); - // Int_t butcolor = 33; +// Int_t butcolor = 33; Float_t dbutton = 0.08; Float_t y = 0.96; Float_t dy = 0.014; @@ -278,7 +299,7 @@ void AliMUONdisplay::CreateColors() g=i*0.2; b=0.; color=i; - color=50+23-color; + color=260+23-color; // printf("CreateColors - i, k, color %d %d %d \n",i,k,color); new TColor(color,r,g,b); } @@ -290,7 +311,7 @@ void AliMUONdisplay::CreateColors() g=1.; b=0.; color=i+5; - color=50+23-color; + color=260+23-color; // printf("CreateColors - i, k, color %d %d %d \n",i,k,color); new TColor(color,r,g,b); } @@ -302,7 +323,7 @@ void AliMUONdisplay::CreateColors() g=1.; b=i*0.2+0.2; color=i+9; - color=50+23-color; + color=260+23-color; // printf("CreateColors - i, k, color %d %d %d \n",i,k,color); new TColor(color,r,g,b); } @@ -314,7 +335,7 @@ void AliMUONdisplay::CreateColors() g=1.1-i*0.2; b=1.; color=i+13; - color=50+23-color; + color=260+23-color; // printf("CreateColors - i, k, color %d %d %d \n",i,k,color); new TColor(color,r,g,b); } @@ -326,7 +347,7 @@ void AliMUONdisplay::CreateColors() g=0.; b=1.; color=i+17; - color=50+23-color; + color=260+23-color; // printf("CreateColors - i, k, color %d %d %d \n",i,k,color); new TColor(color,r,g,b); } @@ -355,8 +376,14 @@ void AliMUONdisplay::DisplayColorScale() TText *text = new TText(0,0,""); text->SetTextFont(61); - text->SetTextSize(0.03); + text->SetTextSize(0.2); text->SetTextAlign(22); + + AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONchamber *iChamber = &(MUON->Chamber(fChamber-1)); + AliMUONresponse * response=iChamber->GetResponseModel(); + Int_t adcmax= (Int_t) response->MaxAdc(); + TBox *box; char label[8]; @@ -367,10 +394,11 @@ void AliMUONdisplay::DisplayColorScale() for (i=0;i<22;i++) { ylow = y1 + hs*(Float_t(i)); yup = y1 + hs*(Float_t(i+1)); - color = 51+i; + color = 261+i; // Int_t scale=(i+1)*(Int_t)adc_satm/22; // sprintf(label,"%d",scale); - Double_t logscale=Double_t(i+1)*(TMath::Log(adc_satm)/22); + //Double_t logscale=Double_t(i+1)*(TMath::Log(adc_satm)/22); + Double_t logscale=Double_t(i+1)*(TMath::Log(adcmax)/22); Int_t scale=(Int_t)TMath::Exp(logscale); sprintf(label,"%d",scale); box = new TBox(xlow, ylow, xup, yup); @@ -408,8 +436,7 @@ void AliMUONdisplay::Draw(Option_t *) fPad->cd(); - DrawView(fTheta, fPhi, fPsi); // see how to draw PGON+inner frames - + DrawView(fTheta, fPhi, fPsi); // Display the event number and title fPad->cd(); DrawTitle(); @@ -435,13 +462,23 @@ void AliMUONdisplay::DrawClusters() for (digit=0;digitUncheckedAt(digit); if (!pm) continue; - // Float_t *pxyz; - // pxyz=pm->GetP(); + Float_t *pxyz; + pxyz=pm->GetP(); +// Int_t color=(Int_t)pm->GetMarkerColor(); + // printf("DrawClusters - color %d \n",color); + // DrawP(pxyz[0],pxyz[1],pxyz[2],0.75,0.5,color); // printf("DrawClusters - pxyz[0],pxyz[1] %f %f \n",pxyz[0],pxyz[1]); - pm->Draw(); + for (Int_t im=0;im<3;im++) { + TMarker3DBox *marker=pm->GetMarker(im); + // marker->Dump(); + if (marker) + marker->Draw(); + } + pm->Draw(); // Int_t n=pm->GetN(); // printf("DrawClusters - n %d \n",n); fClustersCuts +=pm->GetN(); + } } @@ -470,6 +507,79 @@ void AliMUONdisplay::DrawHits() } +//_____________________________________________________________________________ +void AliMUONdisplay::DrawCoG() +{ +// Draw hits for MUON chambers + if (!fDrawCoG) return; + LoadCoG(fChamber,fCathode); + + Int_t ncog, icog; + TObjArray *points; + AliMUONpoints *pm; + + points = Rpoints(); + if (!points) return; + ncog = points->GetEntriesFast(); + printf("DrawCoG - ncog %d \n",ncog); + for (icog=0;icogUncheckedAt(icog); + if (!pm) continue; + pm->Draw(); + } +} +void AliMUONdisplay::DrawCoG2() +{ +// Draw hits for MUON chambers + + if (!fDrawCoG) return; + + + if (fCathode==1) { + LoadCoG2(fChamber,2); + } else if (fCathode==2) { + LoadCoG2(fChamber,1); + } + + Int_t ncog, icog; + TObjArray *points; + AliMUONpoints *pm; + + points = R2points(); + if (!points) return; + ncog = points->GetEntriesFast(); + printf("DrawCoG - ncog %d \n",ncog); + for (icog=0;icogUncheckedAt(icog); + if (!pm) continue; + pm->Draw(); + } + +} +//_____________________________________________________________________________ +void AliMUONdisplay::DrawCathCor() +{ +// Draw hits for MUON chambers + + if (!fDrawCathCor) return; + + LoadCathCor(fChamber); + + Int_t ncog, icog; + TObjArray *points; + AliMUONpoints *pm; + + points = Cpoints(); + if (!points) return; + ncog = points->GetEntriesFast(); + printf("DrawCathCor - ncog %d \n",ncog); + for (icog=0;icogUncheckedAt(icog); + if (!pm) continue; + pm->Draw(); + } +} +//_____________________________________________________________________________ //_____________________________________________________________________________ void AliMUONdisplay::DrawTitle(Option_t *option) { @@ -510,8 +620,9 @@ void AliMUONdisplay::DrawView(Float_t theta, Float_t phi, Float_t psi) gPad->SetFillColor(1); gPad->Clear(); - Int_t iret; + Int_t iret=0; TView *view = new TView(1); + Float_t range = fRrange*fRangeSlider->GetMaximum(); view->SetRange(-range,-range,-range,range, range, range); fZoomX0[0] = -1; @@ -519,17 +630,25 @@ void AliMUONdisplay::DrawView(Float_t theta, Float_t phi, Float_t psi) fZoomX1[0] = 1; fZoomY1[0] = 1; fZooms = 0; + +// Display MUON Chamber Geometry +// gAlice->GetGeometry()->Draw("same"); + char NodeName[7]; + sprintf(NodeName,"MUON%d",100+fChamber); + printf("Node name %s", NodeName); - // Display MUON Chamber Geometry - // gAlice->GetGeometry()->Draw("same"); - - //add clusters to the pad + TNode *node1=gAlice->GetGeometry()->GetNode(NodeName); + if (node1) node1->Draw("same"); +// ok if I rotate the chamber in a proper way + +//add clusters to the pad DrawClusters(); DrawHits(); - + DrawCoG(); + DrawCoG2(); + DrawCathCor(); // add itself to the list (must be last) AppendPad(); - view->SetView(phi, theta, psi, iret); } @@ -609,8 +728,12 @@ void AliMUONdisplay::LoadDigits(Int_t chamber, Int_t cathode) // Read digits info and store x,y,z info in arrays fPoints // Loop on all detectors + if (chamber > 10) return; + fChamber=chamber; fCathode=cathode; + + printf("cathode, fCathode %d %d \n",cathode,fCathode); ResetPoints(); @@ -622,7 +745,10 @@ void AliMUONdisplay::LoadDigits(Int_t chamber, Int_t cathode) if (MUONdigits == 0) return; gAlice->ResetDigits(); - gAlice->TreeD()->GetEvent(cathode); + + Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); + gAlice->TreeD()->GetEvent(nent-2+cathode-1); + //gAlice->TreeD()->GetEvent(cathode); Int_t ndigits = MUONdigits->GetEntriesFast(); if (ndigits == 0) return; if (fPoints == 0) fPoints = new TObjArray(ndigits); @@ -632,47 +758,304 @@ void AliMUONdisplay::LoadDigits(Int_t chamber, Int_t cathode) printf("LoadPoints - iChamber %p \n",iChamber); segmentation=iChamber->GetSegmentationModel(cathode); printf("LoadPoints - segmentation %p \n",segmentation); - Float_t dpx = segmentation->Dpx(); - Float_t dpy = segmentation->Dpy(); - printf("LoadPoints - dpx, dpy %f %f \n",dpx,dpy); - Float_t zpos=iChamber->ZPosition(); + Float_t dpxbig = segmentation->Dpx()/2.; + Float_t dpy = segmentation->Dpy()/2.; + printf("LoadPoints - dpxbig, dpy %f %f \n",dpxbig,dpy); + Float_t zpos=iChamber->ZPosition(); // check with Andreas printf("LoadPoint - zpos %f \n",zpos); AliMUONdigit *mdig; AliMUONpoints *points = 0; + TMarker3DBox *marker=0; + // TMatrix *matrix; // //loop over all digits and store their position // points = new AliMUONpoints(ndigits); Int_t npoints=1; for (Int_t digit=0;digitUncheckedAt(digit); - points = new AliMUONpoints(npoints); - fPoints->AddAt(points,digit); + mdig = (AliMUONdigit*)MUONdigits->UncheckedAt(digit); + // + // First get all needed parameters + // Int_t charge=mdig->fSignal; // set the color according to the color scale // Int_t scale=(Int_t)adc_satm/22; // Int_t index=(Int_t)charge/scale; Int_t index=Int_t(TMath::Log(charge)/(TMath::Log(adc_satm)/22)); - Int_t color=51+index; - if (color>72) color=72; - points->SetMarkerColor(color); - points->SetMarkerStyle(21); - points->SetMarkerSize(0.5); + Int_t color=261+index; + if (color>282) color=282; // get the center of the pad - add on x and y half of pad size Float_t xpad, ypad; segmentation->GetPadCxy(mdig->fPadX, mdig->fPadY,xpad, ypad); + // printf("xpad,ypad,zpos,dpx,dpy %f %f %f %f %f\n",xpad,ypad,zpos,dpx,dpy); + Int_t isec=segmentation->Sector(mdig->fPadX, mdig->fPadY); + // printf(" isec %d \n",isec); + Float_t dpx=segmentation->Dpx(isec)/2; + Float_t dpy=segmentation->Dpy(isec)/2; + // printf(" dpx %f \n",dpx); + Int_t nPara, offset; + segmentation->GetNParallelAndOffset(mdig->fPadX,mdig->fPadY, + &nPara,&offset); + // + // Then set the objects + // + points = new AliMUONpoints(npoints); + fPoints->AddAt(points,digit); + + points->SetMarkerColor(color); + points->SetMarkerStyle(21); + points->SetMarkerSize(0.5); points->SetParticle(-1); points->SetHitIndex(-1); points->SetTrackIndex(-1); points->SetDigitIndex(digit); - points->SetPoint(0,xpad,ypad,zpos); - // Float_t *pxyz; - // pxyz=points->GetP(); - // printf("pxyz[0],pxyz[1],color %f %f %d \n",pxyz[0],pxyz[1],color); - // Int_t np=points->GetN(); - // printf("np %d \n",np); + points->SetPoint(0,xpad,ypad,zpos); + for (Int_t imark=0;imarkGetPadCxy(mdig->fPadX + imark*offset, mdig->fPadY,xpad, ypad); + marker=new TMarker3DBox(xpad,ypad,zpos,dpx,dpy,0,0,0); + marker->SetLineColor(2); + marker->SetFillStyle(1001); + marker->SetFillColor(color); + marker->SetRefObject((TObject*)points); + points->Set3DMarker(imark, marker); + + // DrawPad(xpad,ypad,zpos,dpx,dpy,color); + + // Float_t *pxyz; + // pxyz=points->GetP(); + // printf("pxyz[0],pxyz[1],color %f %f %d \n",pxyz[0],pxyz[1],color); + // Int_t np=points->GetN(); + // printf("np %d \n",np); + } + } +} +//___________________________________________ +void AliMUONdisplay::LoadCoG(Int_t chamber, Int_t cathode) +{ +// Read raw clusters info and store x,y,z info in arrays fRpoints +// Loop on all detectors + + if (chamber > 10) return; + + ResetRpoints(); + + AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONchamber* iChamber; +// AliMUONsegmentation* segmentation; + + TClonesArray *MUONrawclust = MUON->RawClustAddress(chamber-1); + if (MUONrawclust == 0) return; + + MUON->ResetRawClusters(); + +// gAlice->TreeR()->GetEvent(fEvent+cathode); + + Int_t nent=(Int_t)gAlice->TreeR()->GetEntries(); + gAlice->TreeR()->GetEvent(nent-2+cathode-1); + //gAlice->TreeR()->GetEvent(cathode); + Int_t nrawcl = MUONrawclust->GetEntriesFast(); + if (nrawcl == 0) return; + if (fRpoints == 0) fRpoints = new TObjArray(nrawcl); + printf("Found %d raw clust for cathode %d in chamber %d \n",nrawcl,cathode,chamber); + + iChamber = &(MUON->Chamber(chamber-1)); + printf("LoadPoints - iChamber %p \n",iChamber); + Float_t zpos=iChamber->ZPosition(); // check with Andreas + printf("LoadPoint - zpos %f \n",zpos); + AliMUONRawCluster *mRaw; + AliMUONpoints *points = 0; + // + //loop over all raw clusters and store their position + points = new AliMUONpoints(nrawcl); + for (Int_t iraw=0;irawUncheckedAt(iraw); + fRpoints->AddAt(points,iraw); + points->SetMarkerColor(51); + points->SetMarkerStyle(2); + points->SetMarkerSize(1.); + points->SetParticle(-1); + points->SetHitIndex(-1); + points->SetTrackIndex(-1); + points->SetDigitIndex(-1); + points->SetPoint(iraw,mRaw->fX,mRaw->fY,zpos); + } +} +//___________________________________________ +void AliMUONdisplay::LoadCoG2(Int_t chamber, Int_t cathode) +{ +// Read raw clusters info and store x,y,z info in arrays fRpoints +// Loop on all detectors + + if (chamber > 10) return; + + ResetR2points(); + + AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONchamber* iChamber; +// AliMUONsegmentation* segmentation; + + TClonesArray *MUONrawclust = MUON->RawClustAddress(chamber-1); + if (MUONrawclust == 0) return; + + MUON->ResetRawClusters(); + +// gAlice->TreeR()->GetEvent(fEvent+cathode); + Int_t nent=(Int_t)gAlice->TreeR()->GetEntries(); + gAlice->TreeR()->GetEvent(nent-2+cathode-1); + //gAlice->TreeR()->GetEvent(cathode); + Int_t nrawcl = MUONrawclust->GetEntriesFast(); + if (nrawcl == 0) return; + if (fR2points == 0) fR2points = new TObjArray(nrawcl); + printf("Found %d raw clust for cathode %d in chamber %d \n",nrawcl,cathode,chamber); + + iChamber = &(MUON->Chamber(chamber-1)); + Float_t zpos=iChamber->ZPosition(); // check with Andreas + AliMUONRawCluster *mRaw; + AliMUONpoints *points = 0; + // + //loop over all raw clusters and store their position + points = new AliMUONpoints(nrawcl); + for (Int_t iraw=0;irawUncheckedAt(iraw); + fR2points->AddAt(points,iraw); + points->SetMarkerColor(51); + points->SetMarkerStyle(4); + points->SetMarkerSize(1.3); + points->SetParticle(-1); + points->SetHitIndex(-1); + points->SetTrackIndex(-1); + points->SetDigitIndex(-1); + points->SetPoint(iraw,mRaw->fX,mRaw->fY,zpos); } } +//___________________________________________ +void AliMUONdisplay::LoadCathCor(Int_t chamber) +{ +// Read correlation info and store x,y,z info in arrays fCpoints +// Loop on all detectors + + if (chamber > 10) return; + fChamber=chamber; + ResetCpoints(); + + AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONchamber* iChamber; + iChamber = &(MUON->Chamber(chamber-1)); + Float_t zpos=iChamber->ZPosition(); // check with Andreas + + + //new + MUON->GetTreeC(fEvent); + TTree *TC=MUON->TreeC(); + if (!TC) return; + Int_t nent=(Int_t)TC->GetEntries(); + printf("Found %d entries in the tree (must be one per cathode per event!)\n",nent); + + TClonesArray *MUONcorrel = MUON->CathCorrelAddress(chamber-1); + if (MUONcorrel == 0) return; + + MUON->ResetCorrelation(); + // TC->GetEvent(nent-1); + TC->GetEvent(); + + Int_t ncor = MUONcorrel->GetEntries(); + printf("Found %d entries in TreeC for chamber %d \n",ncor,chamber); + if (!ncor) return; + if (!fCpoints) fCpoints = new TObjArray(ncor); + + AliMUONcorrelation *mCor; + AliMUONpoints *points = 0; + // + //loop over all raw clusters and store their position + points = new AliMUONpoints(ncor); + for (Int_t icor=0;icorUncheckedAt(icor); + fCpoints->AddAt(points,icor); + points->SetMarkerColor(4); + points->SetMarkerStyle(4); + points->SetMarkerSize(0.8); + points->SetParticle(-1); + points->SetHitIndex(-1); + points->SetTrackIndex(-1); + points->SetDigitIndex(-1); + points->SetPoint(icor,mCor->fX[0],mCor->fY[0],zpos); + } +} + +//___________________________________________ +void AliMUONdisplay::DrawP(Float_t xpad, Float_t ypad, Float_t zpos ,Float_t dpx, Float_t dpy, Int_t color) +{ + fPad->cd(); + + Float_t xlow, xup, ylow, yup; + TBox *box; +//*-* draw pad + + // printf("DrawPad -- color %d \n",color); + + xlow=(xpad > 0) ? xpad-dpx/2. : xpad+dpx/2.; + xup=(xlow > 0) ? xlow+dpx : xlow-dpx; + ylow=(ypad > 0) ? ypad-dpy/2. : ypad+dpy/2.; + yup=(ylow > 0) ? ylow+dpy : ylow-dpy; + + box = new TBox(xlow, ylow, xup, yup); + box->SetLineColor(2); + box->SetFillStyle(1001); + box->SetFillColor(color); + /* + Int_t x1=gPad->XtoAbsPixel(xlow); + Int_t y1=gPad->YtoAbsPixel(ylow); + Int_t x2=gPad->XtoAbsPixel(xup); + Int_t y2=gPad->YtoAbsPixel(yup); + printf("DrawPad -- x1,y1,x2,y2 %d %d %d %d \n",x1,y1,x2,y2); + // box->DrawBox(xlow,ylow,xup,yup); + gGXW->DrawBox(x1,y1,x2,y2, TGXW::kFilled); + */ + box->Draw(); + + //Create temporary storage + /* + Int_t *pxy = new Int_t[4]; + Float_t *x = new Float_t[2]; + Float_t *y = new Float_t[2]; + Float_t xndc[3]; + Float_t ptr[3]; + ptr[0]=xlow; + ptr[1]=ylow; + ptr[2]=zpos; + + TView *view = gPad->GetView(); //Get current 3-D view + if(!view) return; //Check if `view` is valid + +//- convert points from world to pixel coordinates + + Int_t nin = 0; + for (Int_t i = 0; i < 2; i++) { + view->WCtoNDC(ptr, xndc); + if (xndc[0] < gPad->GetX1() || xndc[0] > gPad->GetX2()) continue; + if (xndc[1] < gPad->GetY1() || xndc[1] > gPad->GetY2()) continue; + x[nin] = xndc[0]; + y[nin] = xndc[1]; + // pxy[nin].fX = gPad->XtoPixel(x[nin]); + // pxy[nin].fY = gPad->YtoPixel(y[nin]); + pxy[i+nin] = gPad->XtoPixel(x[nin]); + pxy[i+1+nin] = gPad->YtoPixel(y[nin]); + printf("DrawPad -- x,y,pxy,pxy %f %f %d %d \n",x[nin],y[nin],pxy[i+nin],pxy[i+1+nin]); + nin++; + ptr[0]=xup; + ptr[1]=yup; + } + +//- invoke the graphics subsystem + box->DrawBox((Int_t)x[0],(Int_t)y[0],(Int_t)x[1],(Int_t)y[1]); + // gGXW->DrawBox(pxy[0],pxy[1],pxy[2],pxy[3], TGXW::kFilled); + delete [] x; + delete [] y; + + delete [] pxy; + */ +} //___________________________________________ void AliMUONdisplay::LoadHits(Int_t chamber) @@ -680,6 +1063,8 @@ void AliMUONdisplay::LoadHits(Int_t chamber) // Read hits info and store x,y,z info in arrays fPhits // Loop on all detectors + if (chamber > 10) return; + fChamber=chamber; ResetPhits(); @@ -689,43 +1074,84 @@ void AliMUONdisplay::LoadHits(Int_t chamber) iChamber = &(MUON->Chamber(chamber-1)); Float_t zpos=iChamber->ZPosition(); - printf("LoadHits - zpos %f \n",zpos); + //printf("LoadHits - zpos %f \n",zpos); Int_t ntracks = (Int_t)gAlice->TreeH()->GetEntries(); - printf("ntracks %d\n",ntracks); + printf("LoadHits - primary tracks %d\n",ntracks); Int_t ntrks = gAlice->GetNtrack(); - printf("ntrks %d\n",ntrks); + printf("LoadHits - all tracks %d\n",ntrks); - if (fPhits == 0) fPhits = new TObjArray(ntracks); - // if (fPhits == 0) fPhits = new TObjArray(ntrks); + Int_t nthits=0; + for (Int_t track=0; trackResetHits(); + gAlice->TreeH()->GetEvent(track); + TClonesArray *MUONhits = MUON->Hits(); + if (MUONhits == 0) return; + nthits += MUONhits->GetEntriesFast(); + } + if (fPhits == 0) fPhits = new TObjArray(nthits); + //printf("nthits %d \n",nthits); - TVector *xp = new TVector(10); - TVector *yp = new TVector(10); - TVector *ptrk = new TVector(10); - TVector *phit = new TVector(10); + // old stuff + // + //if (fPhits == 0) fPhits = new TObjArray(ntracks); + /* + TVector *xp = new TVector(20); + TVector *yp = new TVector(20); + // TVector *zp = new TVector(20); + TVector *ptrk = new TVector(20); + TVector *phit = new TVector(20); + */ + // end old stuff + + Int_t nhold=0; for (Int_t track=0; trackResetHits(); gAlice->TreeH()->GetEvent(track); TClonesArray *MUONhits = MUON->Hits(); - // printf("MUONhits %p\n",MUONhits); if (MUONhits == 0) return; Int_t nhits = MUONhits->GetEntriesFast(); if (nhits == 0) continue; - // printf("nhits %d \n",nhits); AliMUONhit *mHit; AliMUONpoints *points = 0; - // Int_t trko=-99, trk; - // points = new AliPoints(nhits); + Int_t npoints=1; + for (Int_t hit=0;hitUncheckedAt(hit); + Int_t nch = mHit->fChamber; // chamber number + if (nch != chamber) continue; + // + // Retrieve info and set the objects + // + points = new AliMUONpoints(npoints); + fPhits->AddAt(points,nhold+hit); + points->SetMarkerColor(kRed); + points->SetMarkerStyle(5); + points->SetMarkerSize(1.); + points->SetParticle(mHit->fTrack); + //Int_t index=points->GetIndex(); + points->SetHitIndex(hit); + points->SetTrackIndex(track); + points->SetDigitIndex(-1); + points->SetPoint(0,mHit->fX,mHit->fY,zpos); + } + nhold+=nhits; + + + // old stuff + /* Int_t npoints=0; for (Int_t hit=0;hitUncheckedAt(hit); Int_t nch = mHit->fChamber; // chamber number if (nch != chamber) continue; + (*xp)(npoints)=mHit->fX; (*yp)(npoints)=mHit->fY; + // (*zp)(npoints)=mHit->fZ; (*ptrk)(npoints)=Float_t(mHit->GetTrack()); - (*phit)(npoints)=Float_t(hit); - // printf("track, trk %d %d\n",track,mHit->GetTrack()); + //(*ptrk)(npoints)=Float_t(mHit->fTrack); + (*phit)(npoints)=Float_t(hit); + printf("hit,(*phit)(npoints), track, trk, fTrack ipart %d %f %d %d %d %f\n",hit,(*phit)(npoints),track,mHit->GetTrack(),mHit->fTrack,mHit->fParticle); npoints++; } if (npoints == 0) continue; @@ -736,20 +1162,27 @@ void AliMUONdisplay::LoadHits(Int_t chamber) points->SetMarkerStyle(5); points->SetMarkerSize(1.); points->SetParticle(Int_t((*ptrk)(p))); - // Int_t index=points->GetIndex(); - // printf("index %d \n",index); + Int_t index=points->GetIndex(); points->SetHitIndex(Int_t((*phit)(p))); points->SetTrackIndex(track); + printf("p, index, Int_t((*ptrk)(p)), hit, track %d %d %d %d %d \n",p, index,Int_t((*ptrk)(p)),Int_t((*phit)(p)),track); points->SetDigitIndex(-1); - points->SetPoint(p,(*xp)(p),(*yp)(p),zpos); + points->SetPoint(p,(*xp)(p),(*yp)(p),zpos); + // points->SetPoint(p,(*xp)(p),(*yp)(p),(*zp)(p)); } - xp->Zero(); - yp->Zero(); - ptrk->Zero(); - phit->Zero(); - fPhits->AddAt(points,track); - // Int_t np=points->GetN(); - // printf("np %d \n",np); + xp->Zero(); + yp->Zero(); + // zp->Zero(); + ptrk->Zero(); + phit->Zero(); + fPhits->AddAt(points,track); + // Int_t np=points->GetN(); + // printf("np %d \n",np); + + + */ + // end old stuff + } } @@ -831,12 +1264,12 @@ void AliMUONdisplay::ShowNextEvent(Int_t delta) // Display (current event_number+delta) // delta = 1 shown next event // delta = -1 show previous event - if (delta) { gAlice->Clear(); Int_t current_event = gAlice->GetHeader()->GetEvent(); Int_t new_event = current_event + delta; gAlice->GetEvent(new_event); + fEvent=new_event; if (!gAlice->TreeD()) return; } LoadDigits(fChamber,fCathode); @@ -878,3 +1311,50 @@ void AliMUONdisplay::ResetPhits() fPhits = 0; } } +//_____________________________________________________________________________ +void AliMUONdisplay::ResetRpoints() +{ + // + // Reset array of points + // + if (fRpoints) { + fRpoints->Delete(); + delete fRpoints; + fRpoints = 0; + } +} +//_____________________________________________________________________________ +void AliMUONdisplay::ResetR2points() +{ + // + // Reset array of points + // + if (fR2points) { + fR2points->Delete(); + delete fR2points; + fR2points = 0; + } +} +//_____________________________________________________________________________ +void AliMUONdisplay::ResetCpoints() +{ + // + // Reset array of points + // + if (fCpoints) { + fCpoints->Delete(); + delete fCpoints; + fCpoints = 0; + } +} + + + + + + + + + + + diff --git a/MUON/AliMUONdisplay.h b/MUON/AliMUONdisplay.h index bcc0208f40e..c277bd9569b 100644 --- a/MUON/AliMUONdisplay.h +++ b/MUON/AliMUONdisplay.h @@ -26,11 +26,15 @@ const Int_t kMAXZOOM = 20; class AliMUONdisplay : /*splaypublic TObject,*/ public AliDisplay { private: + Int_t fEvent; Int_t fChamber; Int_t fCathode; Int_t fZoomMode; //=1 if in zoom mode Bool_t fDrawClusters; //Flag True if Clusters to be drawn + Bool_t fDrawCoG; //Flag True if CoG to be drawn + Bool_t fDrawCathCor; //Flag True if correlated point + //to be drawn Float_t fTheta; //Viewing angle theta Float_t fPhi; //Viewing angle phi Float_t fPsi; //Viewving angle psi (rotation on display) @@ -55,6 +59,9 @@ private: TArc *fArcButton; //Gren/Red button to show Pick/Zoom mode TObjArray *fPoints; //Array of points for each cathode TObjArray *fPhits; //Array of hit points for each chamber + TObjArray *fRpoints; //Array of cog points for each cathode + TObjArray *fR2points; //Array of cog points for each cathode + TObjArray *fCpoints; //Array of correlated points for each first cathode public: AliMUONdisplay(); AliMUONdisplay(Int_t size); @@ -67,28 +74,44 @@ public: virtual void Draw(Option_t *option=""); virtual void DrawClusters(); virtual void DrawHits(); + virtual void DrawCoG(); + virtual void DrawCoG2(); + virtual void DrawCathCor(); + virtual void DrawTitle(Option_t *option=""); virtual void DrawView(Float_t theta, Float_t phi, Float_t psi=0); + virtual void DrawP(Float_t,Float_t,Float_t,Float_t,Float_t,Int_t); virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py); Int_t GetZoomMode() {return fZoomMode;} Int_t GetChamber() {return fChamber;} Int_t GetCathode() {return fCathode;} virtual void LoadDigits(Int_t chamber, Int_t cathode); virtual void LoadHits(Int_t chamber); + virtual void LoadCoG(Int_t chamber, Int_t cathode); + virtual void LoadCoG2(Int_t chamber, Int_t cathode); + virtual void LoadCathCor(Int_t chamber); TPad *Pad() {return fPad;} TObjArray *Points() {return fPoints;} TObjArray *Phits() {return fPhits;} + TObjArray *Rpoints() {return fRpoints;} + TObjArray *R2points() {return fR2points;} + TObjArray *Cpoints() {return fCpoints;} virtual void Paint(Option_t *option=""); virtual void SetDrawClusters(Bool_t draw=kTRUE) {fDrawClusters=draw;} // *MENU* virtual void SetChamberAndCathode(Int_t chamber=1, Int_t cathode=1); // *MENU* - virtual void SetRange(Float_t rrange=250, Float_t zrange=1050); // *MENU* - virtual void SetView(Float_t theta, Float_t phi, Float_t psi=0); + virtual void SetDrawCoG(Bool_t draw=kTRUE) {fDrawCoG=draw;} // *MENU* + virtual void SetDrawCathCor(Bool_t draw=kTRUE) {fDrawCathCor=draw;} // *MENU* + virtual void SetRange(Float_t rrange=250., Float_t zrange=1050.); // *MENU* + virtual void SetView(Float_t theta=0, Float_t phi=-90, Float_t psi=0); virtual void SetPickMode(); virtual void SetZoomMode(); virtual void ShowNextEvent(Int_t delta=1); virtual void UnZoom(); // *MENU* virtual void ResetPoints(); virtual void ResetPhits(); + virtual void ResetRpoints(); + virtual void ResetR2points(); + virtual void ResetCpoints(); ClassDef(AliMUONdisplay, 0) //Utility class to display MUON clusters... }; diff --git a/MUON/AliMUONpoints.cxx b/MUON/AliMUONpoints.cxx index 94643a6f752..7e642c4b260 100644 --- a/MUON/AliMUONpoints.cxx +++ b/MUON/AliMUONpoints.cxx @@ -4,19 +4,24 @@ // // //Begin_Html /* - + */ //End_Html // // // // /////////////////////////////////////////////////////////////////////////////// -#include "AliMUONdisplay.h" + #include "AliMUONpoints.h" +#include "AliMUONdisplay.h" #include "AliRun.h" #include "TPad.h" +#include "TVirtualPad.h" +#include "TPolyLine3D.h" +#include "TPaveText.h" #include "TView.h" #include "TMath.h" +//const Int_t MAX_Nipx=1026, MAX_Nipy=1026; const Int_t MAX_Nipx=400, MAX_Nipy=800; ClassImp(AliMUONpoints) @@ -30,6 +35,8 @@ AliMUONpoints::AliMUONpoints() fHitIndex = 0; fTrackIndex = 0; fDigitIndex = 0; + fMarker[0] = fMarker[1] = fMarker[2]=0; + fMatrix = 0; } //_____________________________________________________________________________ @@ -42,6 +49,8 @@ AliMUONpoints::AliMUONpoints(Int_t npoints) fHitIndex = 0; fTrackIndex = 0; fDigitIndex = 0; + fMarker[0] = fMarker[1] = fMarker[2]=0; + fMatrix = 0; } //_____________________________________________________________________________ @@ -53,8 +62,27 @@ AliMUONpoints::~AliMUONpoints() fHitIndex = 0; fTrackIndex = 0; fDigitIndex = 0; + for (Int_t i=0;i<3;i++){ + if ( +fMarker[i]) delete fMarker[i]; + } + fMatrix = 0; } +//_____________________________________________________________________________ +//void AliMUONpoints::ExecuteEvent(Int_t event, Int_t px, Int_t py) +//{ + // + //*-*-*-*-*-*-*-*-*-*Execute action corresponding to one event*-*-*-*-*-*-*-* + //*-* ========================================= + //*-* + //*-* This member function must be implemented to realize the action + //*-* corresponding to the mouse click on the object in the window + //*-* + //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +// gPad->SetCursor(kCross); + +//} //_____________________________________________________________________________ void AliMUONpoints::DumpHit() { @@ -63,6 +91,7 @@ void AliMUONpoints::DumpHit() // AliMUONhit *hit = GetHit(); if (hit) hit->Dump(); + printf("fTrackIndex %d \n",fTrackIndex); } //_____________________________________________________________________________ @@ -73,6 +102,10 @@ void AliMUONpoints::DumpDigit() // AliMUONdigit *digit = GetDigit(); if (digit) digit->Dump(); + for (int i=0;i<10;i++) { + printf(" track charge %d %d \n",digit->fTracks[i],digit->fTcharges[i]); + } + } //_____________________________________________________________________________ @@ -81,8 +114,30 @@ void AliMUONpoints::InspectHit() // // Inspect hit corresponding to this point // + + if (fHitIndex < 0 ) return; + TVirtualPad *padsav = gPad; AliMUONhit *hit = GetHit(); if (hit) hit->Inspect(); + TVirtualPad *padinspect = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject("inspect"); + padinspect->cd(); + Float_t xmin = gPad->GetX1(); + Float_t xmax = gPad->GetX2(); + Float_t ymin = gPad->GetY1(); + Float_t ymax = gPad->GetY2(); + Float_t dy = ymax-ymin; + + TPaveText *pad = new TPaveText(xmin, ymin+0.1*dy, xmax, ymin+0.15*dy); + pad->SetBit(kCanDelete); + pad->SetFillColor(42); + pad->Draw(); + char ptitle[100]; + sprintf(ptitle," %s , fTrack: %d fTrackIndex: %d ",GetName(),fIndex,fTrackIndex); + pad->AddText(ptitle); + padinspect->cd(); + padinspect->Update(); + if (padsav) padsav->cd(); + } //_____________________________________________________________________________ @@ -91,8 +146,34 @@ void AliMUONpoints::InspectDigit() // // Inspect digit corresponding to this point // + if (fDigitIndex < 0) return; + TVirtualPad *padsav = gPad; AliMUONdigit *digit = GetDigit(); if (digit) digit->Inspect(); + TVirtualPad *padinspect = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject("inspect"); + padinspect->cd(); + Float_t xmin = gPad->GetX1(); + Float_t xmax = gPad->GetX2(); + Float_t ymin = gPad->GetY1(); + Float_t ymax = gPad->GetY2(); + Float_t dy = ymax-ymin; + + TPaveText *pad = new TPaveText(xmin, ymin+0.1*dy, xmax, ymin+0.25*dy); + pad->SetBit(kCanDelete); + pad->SetFillColor(42); + pad->Draw(); + char ptitle[11][100]; + // sprintf(ptitle[11],"Tracks making this digit"); + // pad->AddText(ptitle[11]); + for (int i=0;i<10;i++) { + if (digit->fTracks[i] == 0) continue; + sprintf(ptitle[i],"fTrackIndex: %d Charge: %d",digit->fTracks[i],digit->fTcharges[i]); + pad->AddText(ptitle[i]); + } + padinspect->cd(); + padinspect->Update(); + if (padsav) padsav->cd(); + } //_____________________________________________________________________________ @@ -103,6 +184,14 @@ Int_t AliMUONpoints::GetTrackIndex() // printf("GetTrackIndex - fTrackIndex %d \n",fTrackIndex); this->Inspect(); + /* + if (fDigitIndex != 0) { + Int_t ncol=this->fMatrix->GetNcols(); + for (int i=0;ifMatrix))(0,i),(*(this->fMatrix))(1,i)); + } + } + */ return fTrackIndex; } @@ -117,6 +206,7 @@ AliMUONhit *AliMUONpoints::GetHit() const TClonesArray *MUONhits = MUON->Hits(); Int_t nhits = MUONhits->GetEntriesFast(); if (fHitIndex < 0 || fHitIndex >= nhits) return 0; + printf("ftrackIndex, fHitIndex %d %d \n",fTrackIndex,fHitIndex); return (AliMUONhit*)MUONhits->UncheckedAt(fHitIndex); } @@ -133,7 +223,9 @@ AliMUONdigit *AliMUONpoints::GetDigit() const AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); TClonesArray *MUONdigits = MUON->DigitsAddress(chamber-1); - gAlice->TreeD()->GetEvent(cathode); + Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); + gAlice->TreeD()->GetEvent(nent-2+cathode-1); + //gAlice->TreeD()->GetEvent(cathode); Int_t ndigits = MUONdigits->GetEntriesFast(); if (fDigitIndex < 0 || fDigitIndex >= ndigits) return 0; return (AliMUONdigit*)MUONdigits->UncheckedAt(fDigitIndex); @@ -150,11 +242,20 @@ struct PreCluster : public AliMUONreccluster { int idx; int cut; int npeaks; - PreCluster() : AliMUONreccluster() {cut=npeaks=0;} + int npoly; + float xpoly[100]; + float ypoly[100]; + float zpoly[100]; + PreCluster() : AliMUONreccluster() {cut=npeaks=npoly=0; + for (int k=0;k<100;k++) { + xpoly[k]=ypoly[k]=zpoly[k]=0; + } + } + }; //_____________________________________________________________________________ -static void FindCluster(AliMUONchamber *iChamber, AliMUONsegmentation *segmentation, int i, int j, Bin bins[MAX_Nipx][MAX_Nipy], PreCluster &c) +static void FindCluster(AliMUONchamber *iChamber, AliMUONsegmentation *segmentation, int i, int j, Bin bins[][MAX_Nipy], PreCluster &c) { @@ -173,30 +274,79 @@ static void FindCluster(AliMUONchamber *iChamber, AliMUONsegmentation *segmentat q=-q; c.cut=1; } - if (b.idx >= 0 && b.idx != c.idx) { + // if (b.idx >= 0 && b.idx != c.idx) { + if (b.idx >= 0 && b.idx > c.idx) { c.idx=b.idx; c.npeaks++; + printf("FindCluster - one more peak \n"); } if (q > TMath::Abs(c.summit->fSignal)) c.summit=b.dig; + Float_t zpos=iChamber->ZPosition(); // check with Andreas + Int_t npx = segmentation->Npx(); Int_t npy = segmentation->Npy(); - Float_t x,y; - segmentation->GetPadCxy(i-npx, j-npy, x,y); - printf("FindCluster - x y %f %f \n",x,y); + printf("FindCluster - npx npy %d %d \n",npx,npy); + + // get pad coordinates and prepare the up and down steps + Int_t jup =(j-npy > 0) ? j+1 : (j-npy-1)+npy; + Int_t jdown=(j-npy > 0) ? j-1 : (j-npy+1)+npy; + // Int_t jup =j+1; + // Int_t jdown=j-1; + Float_t x, y; + segmentation->GetPadCxy(i-npx, j-npy,x, y); + Int_t isec0=segmentation->Sector(i-npx,j-npy); + printf("FindCluster - i-npx j-npy isec0 %d %d %d \n",i-npx,j-npy,isec0); + // printf("FindCluster - x y %f %f \n",x,y); + + Float_t dpy = segmentation->Dpy(isec0); + Float_t dpx = segmentation->Dpx(isec0)/16; + Int_t ixx, iyy; + Float_t absx=TMath::Abs(x); + // iup + (y >0) ? segmentation->GetPadIxy(absx+dpx,y+dpy,ixx,iyy) : segmentation->GetPadIxy(absx+dpx,y-dpy,ixx,iyy); + printf(" iup: ixx iyy %d %d \n",ixx,iyy); + Int_t jtest=TMath::Abs(iyy)-npy-1; + if (j != jtest) { + //printf(" j != jtest - something's wrong %d %d \n",j,jtest); + } + Int_t iup=(x >0) ? ixx+npx : -ixx+npx; + // idown + (y >0) ? segmentation->GetPadIxy(absx+dpx,y-dpy,ixx,iyy) : segmentation->GetPadIxy(absx+dpx,y+dpy,ixx,iyy); + printf(" idown: ixx iyy %d %d \n",ixx,iyy); + Int_t idown=(x >0) ? ixx+npx : -ixx+npx; + if (bins[idown][jdown].dig == 0) { + (y >0) ? segmentation->GetPadIxy(absx-dpx,y-dpy,ixx,iyy) : segmentation->GetPadIxy(absx-dpx,y+dpy,ixx,iyy); + printf(" idown: ixx iyy %d %d \n",ixx,iyy); + idown=(x >0) ? ixx+npx : -ixx+npx; + } + + printf("i, iup, idown, j, jup, jdown %d %d %d %d %d %d \n",i,iup,idown,j,jup,jdown); + + // calculate center of gravity + c.npoly++; + if (c.npoly > 100 ) { + printf("FindCluster - npoly >100, npoly %d \n",c.npoly); + c.npoly=100; + } + c.xpoly[c.npoly-1]=x; + c.ypoly[c.npoly-1]=y; + c.zpoly[c.npoly-1]=zpos; c.fX += q*x; c.fY += q*y; c.fQ += q; b.dig = 0; b.idx = c.idx; - + + // left and right if (bins[i-1][j].dig) FindCluster(iChamber,segmentation,i-1,j,bins,c); - if (bins[i][j-1].dig) FindCluster(iChamber,segmentation,i,j-1,bins,c); if (bins[i+1][j].dig) FindCluster(iChamber,segmentation,i+1,j,bins,c); - if (bins[i][j+1].dig) FindCluster(iChamber,segmentation,i,j+1,bins,c); + // up and down + if (bins[iup][jup].dig) FindCluster(iChamber,segmentation,iup,jup,bins,c); + if (bins[idown][jdown].dig) FindCluster(iChamber,segmentation,idown,jdown,bins,c); } @@ -208,8 +358,11 @@ void AliMUONpoints::GetCenterOfGravity() // simple MUON cluster finder from digits -- finds neighbours and // calculates center of gravity for the cluster // - const Int_t MAX_Nipx=400, MAX_Nipy=800; - printf("\n Hallo world"); + + // const Int_t MAX_Nipx=1026, MAX_Nipy=1026; + + Bin bins[MAX_Nipx][MAX_Nipy]; + AliMUONdisplay *display=(AliMUONdisplay*)gAlice->Display(); Int_t chamber=display->GetChamber(); Int_t cathode=display->GetCathode(); @@ -222,9 +375,11 @@ void AliMUONpoints::GetCenterOfGravity() Int_t npx = segmentation->Npx(); Int_t npy = segmentation->Npy(); Float_t zpos=iChamber->ZPosition(); - + TClonesArray *MUONdigits = MUON->DigitsAddress(chamber-1); - gAlice->TreeD()->GetEvent(cathode); + Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); + gAlice->TreeD()->GetEvent(nent-2+cathode-1); + //gAlice->TreeD()->GetEvent(cathode); Int_t ndigits = MUONdigits->GetEntriesFast(); if (fDigitIndex < 0 || fDigitIndex >= ndigits) return; @@ -232,41 +387,72 @@ void AliMUONpoints::GetCenterOfGravity() dig=(AliMUONdigit*)MUONdigits->UncheckedAt(fDigitIndex); Int_t ipx=dig->fPadX; Int_t ipy=dig->fPadY; - Bin bins[MAX_Nipx][MAX_Nipy]; bins[ipx+npx][ipy+npy].dig=dig; int ndig; int ncls=0; - for (ndig=0; ndigUncheckedAt(ndig); - int i=dig->fPadX, j=dig->fPadY; - bins[i+npx][j+npy].dig=dig; + for (ndig=0;ndigUncheckedAt(ndig); + int i=dig->fPadX, j=dig->fPadY; + bins[i+npx][j+npy].dig=dig; } - - PreCluster c; c.summit=bins[ipx+npx][ipy+npy].dig; c.idx=ncls; - FindCluster(iChamber,segmentation,ipx+npx, ipy+npy, bins, c); - if (c.npeaks>1) { + PreCluster c; c.summit=bins[ipx+npx][ipy+npy].dig; c.idx=ncls; + FindCluster(iChamber,segmentation,ipx+npx, ipy+npy, bins, c); + printf("GetCenterOfGravity -- npoly %d \n",c.npoly); + + if (c.npeaks>1) { printf("GetCenterOfGravity -- more than one peak"); - } - c.fX /= c.fQ; - c.fY /= c.fQ; - printf("GetCenterOfGravity - c.fX c.fY c.fQ %f %f %d \n",c.fX,c.fY,c.fQ); - - c.fTracks[0]=c.summit->fTracks[0]; - c.fTracks[1]=c.summit->fTracks[1]; - c.fTracks[2]=c.summit->fTracks[2]; - ncls++; - AliMUONpoints *points = 0; - points = new AliMUONpoints(1); - points->SetMarkerColor(kYellow); - points->SetMarkerStyle(5); - points->SetMarkerSize(1.); - points->SetPoint(0,c.fX,c.fY,zpos); - points->Draw(); - - printf("GetCenterOfGravity -- ncls %d \n",ncls); + } + c.fX /= c.fQ; + c.fY /= c.fQ; + printf("GetCenterOfGravity - c.fX c.fY c.fQ c.npeaks %f %f %d %d \n",c.fX,c.fY,c.fQ,c.npeaks); + /* + c.fTracks[0]=(Int_t)(*(c.summit->fTrks))(0); + c.fTracks[1]=(Int_t)(*(c.summit->fTrks))(1); + c.fTracks[2]=(Int_t)(*(c.summit->fTrks))(2); + */ + c.fTracks[0]=c.summit->fTracks[0]; + c.fTracks[1]=c.summit->fTracks[1]; + c.fTracks[2]=c.summit->fTracks[2]; + ncls++; + AliMUONpoints *points = 0; + points = new AliMUONpoints(1); + points->SetMarkerColor(kYellow); + points->SetMarkerStyle(5); + points->SetMarkerSize(1.); + points->SetPoint(0,c.fX,c.fY,zpos); + points->SetParticle(-1); + points->Draw(); -} + TPolyLine3D *pline=0; + /* + pline=new TPolyLine3D(c.npoly); + Int_t np=c.npoly; + TVector *xp=new TVector(c.npoly); + TVector *yp=new TVector(c.npoly); + TVector *zp=new TVector(c.npoly); + for (int i=0;iSetPoint(i,(*xp)(i),(*yp)(i),(*zp)(i)); + //printf("np, i, xp, yp, zp %d %d %f %f %f \n",np,i,(*xp)(i),(*yp)(i),(*zp)(i)); + } + */ + pline=new TPolyLine3D(c.npoly,c.xpoly,c.ypoly,c.zpoly); + pline->SetLineColor(kWhite); + pline->Draw(); + /* + delete xp; + delete yp; + delete zp; + */ + for (int k=0;k +*/ +//End_Html +// // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "AliMUONpoints.h" +#include "AliMUONdisplay.h" +#include "AliRun.h" +#include "TPad.h" +#include "TVirtualPad.h" +#include "TPolyLine3D.h" +#include "TPaveText.h" +#include "TView.h" +#include "TMath.h" + +//const Int_t MAX_Nipx=1026, MAX_Nipy=1026; +const Int_t MAX_Nipx=400, MAX_Nipy=800; + +ClassImp(AliMUONpoints) + +//_____________________________________________________________________________ +AliMUONpoints::AliMUONpoints() +{ + // + // Default constructor + // + fHitIndex = 0; + fTrackIndex = 0; + fDigitIndex = 0; + fMarker[0] = fMarker[1] = fMarker[2]=0; + fMatrix = 0; +} + +//_____________________________________________________________________________ +AliMUONpoints::AliMUONpoints(Int_t npoints) + :AliPoints(npoints) +{ + // + // Standard constructor + // + fHitIndex = 0; + fTrackIndex = 0; + fDigitIndex = 0; + fMarker[0] = fMarker[1] = fMarker[2]=0; + fMatrix = 0; +} + +//_____________________________________________________________________________ +AliMUONpoints::~AliMUONpoints() +{ + // + // Default destructor + // + fHitIndex = 0; + fTrackIndex = 0; + fDigitIndex = 0; + for (Int_t i=0;i<3;i++){ + if ( +fMarker[i]) delete fMarker[i]; + } + fMatrix = 0; +} + +//_____________________________________________________________________________ +//void AliMUONpoints::ExecuteEvent(Int_t event, Int_t px, Int_t py) +//{ + // + //*-*-*-*-*-*-*-*-*-*Execute action corresponding to one event*-*-*-*-*-*-*-* + //*-* ========================================= + //*-* + //*-* This member function must be implemented to realize the action + //*-* corresponding to the mouse click on the object in the window + //*-* + //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* +// gPad->SetCursor(kCross); + +//} +//_____________________________________________________________________________ +void AliMUONpoints::DumpHit() +{ + // + // Dump hit corresponding to this point + // + AliMUONhit *hit = GetHit(); + if (hit) hit->Dump(); + printf("fTrackIndex %d \n",fTrackIndex); +} + +//_____________________________________________________________________________ +void AliMUONpoints::DumpDigit() +{ + // + // Dump digit corresponding to this point + // + AliMUONdigit *digit = GetDigit(); + if (digit) digit->Dump(); + for (int i=0;i<10;i++) { + printf(" track charge %d %d \n",digit->fTracks[i],digit->fTcharges[i]); + } + +} + +//_____________________________________________________________________________ +void AliMUONpoints::InspectHit() +{ + // + // Inspect hit corresponding to this point + // + + if (fHitIndex < 0 ) return; + TVirtualPad *padsav = gPad; + AliMUONhit *hit = GetHit(); + if (hit) hit->Inspect(); + TVirtualPad *padinspect = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject("inspect"); + padinspect->cd(); + Float_t xmin = gPad->GetX1(); + Float_t xmax = gPad->GetX2(); + Float_t ymin = gPad->GetY1(); + Float_t ymax = gPad->GetY2(); + Float_t dy = ymax-ymin; + + TPaveText *pad = new TPaveText(xmin, ymin+0.1*dy, xmax, ymin+0.15*dy); + pad->SetBit(kCanDelete); + pad->SetFillColor(42); + pad->Draw(); + char ptitle[100]; + sprintf(ptitle," %s , fTrack: %d fTrackIndex: %d ",GetName(),fIndex,fTrackIndex); + pad->AddText(ptitle); + padinspect->cd(); + padinspect->Update(); + if (padsav) padsav->cd(); + +} + +//_____________________________________________________________________________ +void AliMUONpoints::InspectDigit() +{ + // + // Inspect digit corresponding to this point + // + if (fDigitIndex < 0) return; + TVirtualPad *padsav = gPad; + AliMUONdigit *digit = GetDigit(); + if (digit) digit->Inspect(); + TVirtualPad *padinspect = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject("inspect"); + padinspect->cd(); + Float_t xmin = gPad->GetX1(); + Float_t xmax = gPad->GetX2(); + Float_t ymin = gPad->GetY1(); + Float_t ymax = gPad->GetY2(); + Float_t dy = ymax-ymin; + + TPaveText *pad = new TPaveText(xmin, ymin+0.1*dy, xmax, ymin+0.25*dy); + pad->SetBit(kCanDelete); + pad->SetFillColor(42); + pad->Draw(); + char ptitle[11][100]; + // sprintf(ptitle[11],"Tracks making this digit"); + // pad->AddText(ptitle[11]); + for (int i=0;i<10;i++) { + if (digit->fTracks[i] == 0) continue; + sprintf(ptitle[i],"fTrackIndex: %d Charge: %d",digit->fTracks[i],digit->fTcharges[i]); + pad->AddText(ptitle[i]); + } + padinspect->cd(); + padinspect->Update(); + if (padsav) padsav->cd(); + +} + +//_____________________________________________________________________________ +Int_t AliMUONpoints::GetTrackIndex() +{ + // + // Dump digit corresponding to this point + // + printf("GetTrackIndex - fTrackIndex %d \n",fTrackIndex); + this->Inspect(); + /* + if (fDigitIndex != 0) { + Int_t ncol=this->fMatrix->GetNcols(); + for (int i=0;ifMatrix))(0,i),(*(this->fMatrix))(1,i)); + } + } + */ + return fTrackIndex; +} + +//_____________________________________________________________________________ +AliMUONhit *AliMUONpoints::GetHit() const +{ + // + // Returns pointer to hit index in AliRun::fParticles + // + AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); + gAlice->TreeH()->GetEvent(fTrackIndex); + TClonesArray *MUONhits = MUON->Hits(); + Int_t nhits = MUONhits->GetEntriesFast(); + if (fHitIndex < 0 || fHitIndex >= nhits) return 0; + return (AliMUONhit*)MUONhits->UncheckedAt(fHitIndex); +} + +//_____________________________________________________________________________ +AliMUONdigit *AliMUONpoints::GetDigit() const +{ + // + // Returns pointer to digit index in AliRun::fParticles + // + + AliMUONdisplay *display=(AliMUONdisplay*)gAlice->Display(); + Int_t chamber=display->GetChamber(); + Int_t cathode=display->GetCathode(); + + AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); + TClonesArray *MUONdigits = MUON->DigitsAddress(chamber-1); + gAlice->TreeD()->GetEvent(cathode); + Int_t ndigits = MUONdigits->GetEntriesFast(); + if (fDigitIndex < 0 || fDigitIndex >= ndigits) return 0; + return (AliMUONdigit*)MUONdigits->UncheckedAt(fDigitIndex); +} +//_____________________________________________________________________________ +struct Bin { + const AliMUONdigit *dig; + int idx; + Bin() {dig=0; idx=-1;} +}; + +struct PreCluster : public AliMUONreccluster { + const AliMUONdigit* summit; + int idx; + int cut; + int npeaks; + int npoly; + float xpoly[100]; + float ypoly[100]; + float zpoly[100]; + PreCluster() : AliMUONreccluster() {cut=npeaks=npoly=0; + for (int k=0;k<100;k++) { + xpoly[k]=ypoly[k]=zpoly[k]=0; + } + } + +}; +//_____________________________________________________________________________ + +static void FindCluster(AliMUONchamber *iChamber, AliMUONsegmentation *segmentation, int i, int j, Bin bins[][MAX_Nipy], PreCluster &c) + +{ + + // + // Find clusters + // + + printf("I'm in FindCluster \n"); + + Bin& b=bins[i][j]; + Int_t q=b.dig->fSignal; + + printf("FindCluster - i j q %d %d %d\n",i,j,q); + + if (q<0) { + q=-q; + c.cut=1; + } + // if (b.idx >= 0 && b.idx != c.idx) { + if (b.idx >= 0 && b.idx > c.idx) { + c.idx=b.idx; + c.npeaks++; + printf("FindCluster - one more peak \n"); + } + + if (q > TMath::Abs(c.summit->fSignal)) c.summit=b.dig; + + Float_t zpos=iChamber->ZPosition(); // check with Andreas + + Int_t npx = segmentation->Npx(); + Int_t npy = segmentation->Npy(); + + // get pad coordinates and prepare the up and down steps + Int_t jup =(j-npy > 0) ? j+1 : (j-npy-1)+npy; + Int_t jdown=(j-npy > 0) ? j-1 : (j-npy+1)+npy; + // Int_t jup =j+1; + // Int_t jdown=j-1; + Float_t x, y; + segmentation->GetPadCxy(i-npx, j-npy,x, y); + Int_t isec0=segmentation->Sector(i-npx,j-npy); + printf("FindCluster - i-npx j-npy isec0 %d %d %d \n",i-npx,j-npy,isec0); + // printf("FindCluster - x y %f %f \n",x,y); + + Float_t dpy = segmentation->Dpy(); + Float_t dpx = segmentation->Dpx()/16; + Int_t ixx, iyy; + Float_t absx=TMath::Abs(x); + // iup + (y >0) ? segmentation->GetPadIxy(absx+dpx,y+dpy,ixx,iyy) : segmentation->GetPadIxy(absx+dpx,y-dpy,ixx,iyy); + printf(" iup: ixx iyy %d %d \n",ixx,iyy); + Int_t jtest=TMath::Abs(iyy)-npy-1; + if (j != jtest) { + printf(" j != jtest - something's wrong %d %d \n",j,jtest); + } + Int_t iup=(x >0) ? ixx+npx : -ixx+npx; + // idown + (y >0) ? segmentation->GetPadIxy(absx+dpx,y-dpy,ixx,iyy) : segmentation->GetPadIxy(absx+dpx,y+dpy,ixx,iyy); + printf(" idown: ixx iyy %d %d \n",ixx,iyy); + Int_t idown=(x >0) ? ixx+npx : -ixx+npx; + if (bins[idown][jdown].dig == 0) { + (y >0) ? segmentation->GetPadIxy(absx-dpx,y-dpy,ixx,iyy) : segmentation->GetPadIxy(absx-dpx,y+dpy,ixx,iyy); + printf(" idown: ixx iyy %d %d \n",ixx,iyy); + idown=(x >0) ? ixx+npx : -ixx+npx; + } + + printf("i, iup, idown, j, jup, jdown %d %d %d %d %d %d \n",i,iup,idown,j,jup,jdown); + + // calculate center of gravity + c.npoly++; + if (c.npoly > 100 ) { + printf("FindCluster - npoly >100, npoly %d \n",c.npoly); + c.npoly=100; + } + c.xpoly[c.npoly-1]=x; + c.ypoly[c.npoly-1]=y; + c.zpoly[c.npoly-1]=zpos; + + c.fX += q*x; + c.fY += q*y; + c.fQ += q; + + b.dig = 0; b.idx = c.idx; + + // left and right + if (bins[i-1][j].dig) FindCluster(iChamber,segmentation,i-1,j,bins,c); + if (bins[i+1][j].dig) FindCluster(iChamber,segmentation,i+1,j,bins,c); + // up and down + if (bins[iup][jup].dig) FindCluster(iChamber,segmentation,iup,jup,bins,c); + if (bins[idown][jdown].dig) FindCluster(iChamber,segmentation,idown,jdown,bins,c); + +} + +//_____________________________________________________________________________ + +void AliMUONpoints::GetCenterOfGravity() +{ + // + // simple MUON cluster finder from digits -- finds neighbours and + // calculates center of gravity for the cluster + // + + // const Int_t MAX_Nipx=1026, MAX_Nipy=1026; + + Bin bins[MAX_Nipx][MAX_Nipy]; + + AliMUONdisplay *display=(AliMUONdisplay*)gAlice->Display(); + Int_t chamber=display->GetChamber(); + Int_t cathode=display->GetCathode(); + + AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONchamber *iChamber; + AliMUONsegmentation *segmentation; + iChamber =&(MUON->Chamber(chamber-1)); + segmentation=iChamber->GetSegmentationModel(cathode); + Int_t npx = segmentation->Npx(); + Int_t npy = segmentation->Npy(); + Float_t zpos=iChamber->ZPosition(); + + TClonesArray *MUONdigits = MUON->DigitsAddress(chamber-1); + gAlice->TreeD()->GetEvent(cathode); + Int_t ndigits = MUONdigits->GetEntriesFast(); + if (fDigitIndex < 0 || fDigitIndex >= ndigits) return; + + AliMUONdigit *dig; + dig=(AliMUONdigit*)MUONdigits->UncheckedAt(fDigitIndex); + Int_t ipx=dig->fPadX; + Int_t ipy=dig->fPadY; + bins[ipx+npx][ipy+npy].dig=dig; + + int ndig; + int ncls=0; + for (ndig=0;ndigUncheckedAt(ndig); + int i=dig->fPadX, j=dig->fPadY; + bins[i+npx][j+npy].dig=dig; + } + PreCluster c; c.summit=bins[ipx+npx][ipy+npy].dig; c.idx=ncls; + FindCluster(iChamber,segmentation,ipx+npx, ipy+npy, bins, c); + printf("GetCenterOfGravity -- npoly %d \n",c.npoly); + + if (c.npeaks>1) { + printf("GetCenterOfGravity -- more than one peak"); + } + c.fX /= c.fQ; + c.fY /= c.fQ; + printf("GetCenterOfGravity - c.fX c.fY c.fQ c.npeaks%f %f %d %d \n",c.fX,c.fY,c.fQ,c.npeaks); + /* + c.fTracks[0]=(Int_t)(*(c.summit->fTrks))(0); + c.fTracks[1]=(Int_t)(*(c.summit->fTrks))(1); + c.fTracks[2]=(Int_t)(*(c.summit->fTrks))(2); + */ + c.fTracks[0]=c.summit->fTracks[0]; + c.fTracks[1]=c.summit->fTracks[1]; + c.fTracks[2]=c.summit->fTracks[2]; + ncls++; + AliMUONpoints *points = 0; + points = new AliMUONpoints(1); + points->SetMarkerColor(kYellow); + points->SetMarkerStyle(5); + points->SetMarkerSize(1.); + points->SetPoint(0,c.fX,c.fY,zpos); + points->SetParticle(-1); + points->Draw(); + + TPolyLine3D *pline=0; + /* + pline=new TPolyLine3D(c.npoly); + Int_t np=c.npoly; + Float_t *x=new Float_t(c.npoly); + Float_t *y=new Float_t(c.npoly); + Float_t *z=new Float_t(c.npoly); + for (int i=0;iSetPoint(i,x[i],y[i],z[i]); + } + */ + pline=new TPolyLine3D(c.npoly,c.xpoly,c.ypoly,c.zpoly); + pline->SetLineColor(kWhite); + pline->Draw(); + + + printf("GetCenterOfGravity -- ncls %d \n",ncls); + +} + diff --git a/MUON/AliMUONv0.cxx b/MUON/AliMUONv0.cxx index 94b51e6cac4..c40dac891d7 100644 --- a/MUON/AliMUONv0.cxx +++ b/MUON/AliMUONv0.cxx @@ -5,6 +5,7 @@ #include #include #include +#include #include "AliMUONv0.h" #include "AliRun.h" @@ -31,13 +32,14 @@ AliMUONv0::AliMUONv0(const char *name, const char *title) { // // z-Positions of Chambers - const Float_t zch[7]={511., 686., 971., 1245., 1445., 1610, 1710.}; +// const Float_t zch[7]={515., 690., 962.85, 1249., 1449., 1610, 1710.}; + const Float_t zch[7]={515., 690., 975., 1249., 1449., 1610, 1710.}; // // inner diameter - const Float_t dmi[7]={ 35., 47., 67., 86., 100., 96., 101.96}; + const Float_t dmi[7]={ 35., 47., 66., 80., 80., 96., 101.96}; // // outer diameter - const Float_t dma[7]={183., 245., 346., 442., 513., 824., 874.}; + const Float_t dma[7]={183., 245., 316.6, 520., 520., 824., 874.}; // Int_t k; @@ -56,8 +58,8 @@ AliMUONv0::AliMUONv0(const char *name, const char *title) chamber->SetZPOS(zch[i]); // chamber->InitGeo(zch[i]); - chamber->frMin=dmi[i]/2.; - chamber->frMax=dma[i]/2.; + chamber->SetRInner(dmi[i]/2); + chamber->SetROuter(dma[i]/2); // } // Chamber j in } // Station i @@ -76,23 +78,30 @@ void AliMUONv0::Trigger(Float_t (*x)[4], Float_t (*y)[4], Int_t& iflag) //___________________________________________ void AliMUONv0::CreateGeometry() { - Int_t *idtmed = fIdtmed->GetArray()-1099; + Int_t *idtmed = fIdtmed->GetArray()-1099; // // Note: all chambers have the same structure, which could be // easily parameterised. This was intentionally not done in order // to give a starting point for the implementation of the actual // design of each station. -// + // Distance between Stations - const Float_t dstation = 8.; // Float_t bpar[3]; Float_t tpar[3]; - Float_t tspar[5], pgpar[10]; + Float_t pgpar[10]; Float_t zpos1, zpos2, zfpos; - Float_t dframep=3.; + Float_t dframep=3.; // Value for station 3 should be 6 ... + Float_t dframep1=3.; + Bool_t frames=true; + + Float_t dframez=0.9; - Float_t dr, rMin; + Float_t dr; + Float_t dstation[5]={8., 8., 24.3, 8., 8.}; + // Float_t dstation[5]={20., 20., 24.3, 20., 20.}; + // Float_t dstation[5]={20., 100., 100., 100., 100.}; + // // Rotation matrices in the x-y plane Int_t idrotm[1199]; @@ -109,24 +118,34 @@ void AliMUONv0::CreateGeometry() // // pointer to the current chamber +// pointer to the current chamber + Int_t idAlu1=idtmed[1103]; + Int_t idAlu2=idtmed[1104]; +// Int_t idAlu1=idtmed[1100]; +// Int_t idAlu2=idtmed[1100]; + Int_t idAir=idtmed[1100]; + Int_t idGas=idtmed[1105]; + + AliMUONchamber *iChamber; //******************************************************************** // Station 1 ** //******************************************************************** // CONCENTRIC iChamber=(AliMUONchamber*) (*fChambers)[0]; - zpos1=iChamber->ZPosition()-dstation/2; - zpos2=zpos1+dstation; + zpos1=iChamber->ZPosition()-dstation[0]/2; + zpos2=zpos1+dstation[0]; zfpos=-(iChamber->fdGas+dframez)/2; // // Mother volume - tpar[0] = iChamber->frMin-dframep; - tpar[1] = (iChamber->frMax+dframep)/TMath::Cos(phi); - tpar[2] = dstation/2; + tpar[0] = iChamber->RInner()-dframep1; + tpar[1] = (iChamber->ROuter()+dframep1)/TMath::Cos(phi); + //tpar[2] = dstation[0]/2; + tpar[2] = dstation[0]/4; - gMC->Gsvolu("C01M", "TUBE", idtmed[1100], tpar, 3); - gMC->Gsvolu("C02M", "TUBE", idtmed[1100], tpar, 3); + gMC->Gsvolu("C01M", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("C02M", "TUBE", idAir, tpar, 3); gMC->Gspos("C01M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); gMC->Gspos("C02M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); // Aluminium frames @@ -136,24 +155,24 @@ void AliMUONv0::CreateGeometry() pgpar[2] = 12.; pgpar[3] = 2; pgpar[4] = -dframez/2; - pgpar[5] = iChamber->frMax; - pgpar[6] = pgpar[5]+dframep; + pgpar[5] = iChamber->ROuter(); + pgpar[6] = pgpar[5]+dframep1; pgpar[7] = +dframez/2; pgpar[8] = pgpar[5]; pgpar[9] = pgpar[6]; - gMC->Gsvolu("C01O", "PGON", idtmed[1103], pgpar, 10); - gMC->Gsvolu("C02O", "PGON", idtmed[1103], pgpar, 10); + gMC->Gsvolu("C01O", "PGON", idAlu1, pgpar, 10); + gMC->Gsvolu("C02O", "PGON", idAlu1, pgpar, 10); gMC->Gspos("C01O",1,"C01M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C01O",2,"C01M", 0.,0.,+zfpos, 0,"ONLY"); gMC->Gspos("C02O",1,"C02M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C02O",2,"C02M", 0.,0.,+zfpos, 0,"ONLY"); // // Inner frame - tpar[0]= iChamber->frMin-dframep; - tpar[1]= iChamber->frMin; + tpar[0]= iChamber->RInner()-dframep1; + tpar[1]= iChamber->RInner(); tpar[2]= dframez/2; - gMC->Gsvolu("C01I", "TUBE", idtmed[1103], tpar, 3); - gMC->Gsvolu("C02I", "TUBE", idtmed[1103], tpar, 3); + gMC->Gsvolu("C01I", "TUBE", idAlu1, tpar, 3); + gMC->Gsvolu("C02I", "TUBE", idAlu1, tpar, 3); gMC->Gspos("C01I",1,"C01M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C01I",2,"C01M", 0.,0.,+zfpos, 0,"ONLY"); @@ -161,107 +180,114 @@ void AliMUONv0::CreateGeometry() gMC->Gspos("C02I",2,"C02M", 0.,0.,+zfpos, 0,"ONLY"); // // Frame Crosses - bpar[0] = (iChamber->frMax - iChamber->frMin)/2; - bpar[1] = dframep/2; + if (frames) { + + bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; + bpar[1] = dframep1/2; bpar[2] = dframez/2; - gMC->Gsvolu("C01B", "BOX", idtmed[1103], bpar, 3); - gMC->Gsvolu("C02B", "BOX", idtmed[1103], bpar, 3); + gMC->Gsvolu("C01B", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C02B", "BOX", idAlu1, bpar, 3); - gMC->Gspos("C01B",1,"C01M", +iChamber->frMin+bpar[0] , 0,-zfpos, + gMC->Gspos("C01B",1,"C01M", +iChamber->RInner()+bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C01B",2,"C01M", -iChamber->frMin-bpar[0] , 0,-zfpos, + gMC->Gspos("C01B",2,"C01M", -iChamber->RInner()-bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C01B",3,"C01M", 0, +iChamber->frMin+bpar[0] ,-zfpos, + gMC->Gspos("C01B",3,"C01M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C01B",4,"C01M", 0, -iChamber->frMin-bpar[0] ,-zfpos, + gMC->Gspos("C01B",4,"C01M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C01B",5,"C01M", +iChamber->frMin+bpar[0] , 0,+zfpos, + gMC->Gspos("C01B",5,"C01M", +iChamber->RInner()+bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C01B",6,"C01M", -iChamber->frMin-bpar[0] , 0,+zfpos, + gMC->Gspos("C01B",6,"C01M", -iChamber->RInner()-bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C01B",7,"C01M", 0, +iChamber->frMin+bpar[0] ,+zfpos, + gMC->Gspos("C01B",7,"C01M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C01B",8,"C01M", 0, -iChamber->frMin-bpar[0] ,+zfpos, + gMC->Gspos("C01B",8,"C01M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C02B",1,"C02M", +iChamber->frMin+bpar[0] , 0,-zfpos, + gMC->Gspos("C02B",1,"C02M", +iChamber->RInner()+bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C02B",2,"C02M", -iChamber->frMin-bpar[0] , 0,-zfpos, + gMC->Gspos("C02B",2,"C02M", -iChamber->RInner()-bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C02B",3,"C02M", 0, +iChamber->frMin+bpar[0] ,-zfpos, + gMC->Gspos("C02B",3,"C02M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C02B",4,"C02M", 0, -iChamber->frMin-bpar[0] ,-zfpos, + gMC->Gspos("C02B",4,"C02M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C02B",5,"C02M", +iChamber->frMin+bpar[0] , 0,+zfpos, + gMC->Gspos("C02B",5,"C02M", +iChamber->RInner()+bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C02B",6,"C02M", -iChamber->frMin-bpar[0] , 0,+zfpos, + gMC->Gspos("C02B",6,"C02M", -iChamber->RInner()-bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C02B",7,"C02M", 0, +iChamber->frMin+bpar[0] ,+zfpos, + gMC->Gspos("C02B",7,"C02M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C02B",8,"C02M", 0, -iChamber->frMin-bpar[0] ,+zfpos, + gMC->Gspos("C02B",8,"C02M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - + } // // Chamber Material represented by Alu sheet - tpar[0]= iChamber->frMin+dframep*2; - tpar[1]= iChamber->frMax-dframep*2; + tpar[0]= iChamber->RInner(); + tpar[1]= iChamber->ROuter(); tpar[2] = (iChamber->fdGas+iChamber->fdAlu)/2; - gMC->Gsvolu("C01A", "TUBE", idtmed[1103], tpar, 3); - gMC->Gsvolu("C02A", "TUBE", idtmed[1103], tpar, 3); + gMC->Gsvolu("C01A", "TUBE", idAlu2, tpar, 3); + gMC->Gsvolu("C02A", "TUBE",idAlu2, tpar, 3); gMC->Gspos("C01A", 1, "C01M", 0., 0., 0., 0, "ONLY"); gMC->Gspos("C02A", 1, "C02M", 0., 0., 0., 0, "ONLY"); // // Sensitive volumes // tpar[2] = iChamber->fdGas; tpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C01G", "TUBE", idtmed[1105], tpar, 3); - gMC->Gsvolu("C02G", "TUBE", idtmed[1105], tpar, 3); + gMC->Gsvolu("C01G", "TUBE", idtmed[1108], tpar, 3); + gMC->Gsvolu("C02G", "TUBE", idtmed[1108], tpar, 3); gMC->Gspos("C01G", 1, "C01A", 0., 0., 0., 0, "ONLY"); gMC->Gspos("C02G", 1, "C02A", 0., 0., 0., 0, "ONLY"); // // Frame Crosses to be placed inside gas - dr = (iChamber->frMax - iChamber->frMin); - bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; - bpar[1] = dframep/2; + if (frames) { + + dr = (iChamber->ROuter() - iChamber->RInner()); + bpar[0] = TMath::Sqrt(dr*dr-dframep1*dframep1/4)/2; + bpar[1] = dframep1/2; bpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C01F", "BOX", idtmed[1103], bpar, 3); - gMC->Gsvolu("C02F", "BOX", idtmed[1103], bpar, 3); + gMC->Gsvolu("C01F", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C02F", "BOX", idAlu1, bpar, 3); - gMC->Gspos("C01F",1,"C01G", +iChamber->frMin+bpar[0] , 0, 0, + gMC->Gspos("C01F",1,"C01G", +iChamber->RInner()+bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C01F",2,"C01G", -iChamber->frMin-bpar[0] , 0, 0, + gMC->Gspos("C01F",2,"C01G", -iChamber->RInner()-bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C01F",3,"C01G", 0, +iChamber->frMin+bpar[0] , 0, + gMC->Gspos("C01F",3,"C01G", 0, +iChamber->RInner()+bpar[0] , 0, idrotm[1101],"ONLY"); - gMC->Gspos("C01F",4,"C01G", 0, -iChamber->frMin-bpar[0] , 0, + gMC->Gspos("C01F",4,"C01G", 0, -iChamber->RInner()-bpar[0] , 0, idrotm[1101],"ONLY"); - gMC->Gspos("C02F",1,"C02G", +iChamber->frMin+bpar[0] , 0, 0, + gMC->Gspos("C02F",1,"C02G", +iChamber->RInner()+bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C02F",2,"C02G", -iChamber->frMin-bpar[0] , 0, 0, + gMC->Gspos("C02F",2,"C02G", -iChamber->RInner()-bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C02F",3,"C02G", 0, +iChamber->frMin+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C02F",4,"C02G", 0, -iChamber->frMin-bpar[0] , 0, + gMC->Gspos("C02F",3,"C02G", 0, +iChamber->RInner()+bpar[0] , 0, idrotm[1101],"ONLY"); + gMC->Gspos("C02F",4,"C02G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); + } + // // //******************************************************************** // Station 2 ** //******************************************************************** iChamber=(AliMUONchamber*) (*fChambers)[2]; - zpos1=iChamber->ZPosition()-dstation/2; - zpos2=zpos1+dstation; + zpos1=iChamber->ZPosition()-dstation[1]/2; + zpos2=zpos1+dstation[1]; zfpos=-(iChamber->fdGas+dframez)/2; // // Mother volume - tpar[0] = iChamber->frMin-dframep; - tpar[1] = (iChamber->frMax+dframep)/TMath::Cos(phi); - tpar[2] = dstation/2; + tpar[0] = iChamber->RInner()-dframep; + tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); + //tpar[2] = dstation[1]/2; + tpar[2] = dstation[1]/4; - gMC->Gsvolu("C03M", "TUBE", idtmed[1100], tpar, 3); - gMC->Gsvolu("C04M", "TUBE", idtmed[1100], tpar, 3); + gMC->Gsvolu("C03M", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("C04M", "TUBE", idAir, tpar, 3); gMC->Gspos("C03M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); gMC->Gspos("C04M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); // Aluminium frames @@ -271,24 +297,24 @@ idrotm[1101],"ONLY"); pgpar[2] = 12.; pgpar[3] = 2; pgpar[4] = -dframez/2; - pgpar[5] = iChamber->frMax; + pgpar[5] = iChamber->ROuter(); pgpar[6] = pgpar[5]+dframep; pgpar[7] = +dframez/2; pgpar[8] = pgpar[5]; pgpar[9] = pgpar[6]; - gMC->Gsvolu("C03O", "PGON", idtmed[1103], pgpar, 10); - gMC->Gsvolu("C04O", "PGON", idtmed[1103], pgpar, 10); + gMC->Gsvolu("C03O", "PGON", idAlu1, pgpar, 10); + gMC->Gsvolu("C04O", "PGON", idAlu1, pgpar, 10); gMC->Gspos("C03O",1,"C03M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C03O",2,"C03M", 0.,0.,+zfpos, 0,"ONLY"); gMC->Gspos("C04O",1,"C04M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C04O",2,"C04M", 0.,0.,+zfpos, 0,"ONLY"); // // Inner frame - tpar[0]= iChamber->frMin-dframep; - tpar[1]= iChamber->frMin; + tpar[0]= iChamber->RInner()-dframep; + tpar[1]= iChamber->RInner(); tpar[2]= dframez/2; - gMC->Gsvolu("C03I", "TUBE", idtmed[1103], tpar, 3); - gMC->Gsvolu("C04I", "TUBE", idtmed[1103], tpar, 3); + gMC->Gsvolu("C03I", "TUBE", idAlu1, tpar, 3); + gMC->Gsvolu("C04I", "TUBE", idAlu1, tpar, 3); gMC->Gspos("C03I",1,"C03M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C03I",2,"C03M", 0.,0.,+zfpos, 0,"ONLY"); @@ -296,90 +322,97 @@ idrotm[1101],"ONLY"); gMC->Gspos("C04I",2,"C04M", 0.,0.,+zfpos, 0,"ONLY"); // // Frame Crosses - bpar[0] = (iChamber->frMax - iChamber->frMin)/2; + if (frames) { + + bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; bpar[1] = dframep/2; bpar[2] = dframez/2; - gMC->Gsvolu("C03B", "BOX", idtmed[1103], bpar, 3); - gMC->Gsvolu("C04B", "BOX", idtmed[1103], bpar, 3); + gMC->Gsvolu("C03B", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C04B", "BOX", idAlu1, bpar, 3); - gMC->Gspos("C03B",1,"C03M", +iChamber->frMin+bpar[0] , 0,-zfpos, + gMC->Gspos("C03B",1,"C03M", +iChamber->RInner()+bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C03B",2,"C03M", -iChamber->frMin-bpar[0] , 0,-zfpos, + gMC->Gspos("C03B",2,"C03M", -iChamber->RInner()-bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C03B",3,"C03M", 0, +iChamber->frMin+bpar[0] ,-zfpos, + gMC->Gspos("C03B",3,"C03M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C03B",4,"C03M", 0, -iChamber->frMin-bpar[0] ,-zfpos, + gMC->Gspos("C03B",4,"C03M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C03B",5,"C03M", +iChamber->frMin+bpar[0] , 0,+zfpos, + gMC->Gspos("C03B",5,"C03M", +iChamber->RInner()+bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C03B",6,"C03M", -iChamber->frMin-bpar[0] , 0,+zfpos, + gMC->Gspos("C03B",6,"C03M", -iChamber->RInner()-bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C03B",7,"C03M", 0, +iChamber->frMin+bpar[0] ,+zfpos, + gMC->Gspos("C03B",7,"C03M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C03B",8,"C03M", 0, -iChamber->frMin-bpar[0] ,+zfpos, + gMC->Gspos("C03B",8,"C03M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C04B",1,"C04M", +iChamber->frMin+bpar[0] , 0,-zfpos, + gMC->Gspos("C04B",1,"C04M", +iChamber->RInner()+bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C04B",2,"C04M", -iChamber->frMin-bpar[0] , 0,-zfpos, + gMC->Gspos("C04B",2,"C04M", -iChamber->RInner()-bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C04B",3,"C04M", 0, +iChamber->frMin+bpar[0] ,-zfpos, + gMC->Gspos("C04B",3,"C04M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C04B",4,"C04M", 0, -iChamber->frMin-bpar[0] ,-zfpos, + gMC->Gspos("C04B",4,"C04M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C04B",5,"C04M", +iChamber->frMin+bpar[0] , 0,+zfpos, + gMC->Gspos("C04B",5,"C04M", +iChamber->RInner()+bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C04B",6,"C04M", -iChamber->frMin-bpar[0] , 0,+zfpos, + gMC->Gspos("C04B",6,"C04M", -iChamber->RInner()-bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C04B",7,"C04M", 0, +iChamber->frMin+bpar[0] ,+zfpos, + gMC->Gspos("C04B",7,"C04M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C04B",8,"C04M", 0, -iChamber->frMin-bpar[0] ,+zfpos, + gMC->Gspos("C04B",8,"C04M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - + } // // Chamber Material represented by Alu sheet - tpar[0]= iChamber->frMin+dframep*2; - tpar[1]= iChamber->frMax-dframep*2; + tpar[0]= iChamber->RInner(); + tpar[1]= iChamber->ROuter(); tpar[2] = (iChamber->fdGas+iChamber->fdAlu)/2; - gMC->Gsvolu("C03A", "TUBE", idtmed[1103], tpar, 3); - gMC->Gsvolu("C04A", "TUBE", idtmed[1103], tpar, 3); + gMC->Gsvolu("C03A", "TUBE", idAlu2, tpar, 3); + gMC->Gsvolu("C04A", "TUBE", idAlu2, tpar, 3); gMC->Gspos("C03A", 1, "C03M", 0., 0., 0., 0, "ONLY"); gMC->Gspos("C04A", 1, "C04M", 0., 0., 0., 0, "ONLY"); // // Sensitive volumes // tpar[2] = iChamber->fdGas; tpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C03G", "TUBE", idtmed[1105], tpar, 3); - gMC->Gsvolu("C04G", "TUBE", idtmed[1105], tpar, 3); + gMC->Gsvolu("C03G", "TUBE", idGas, tpar, 3); + gMC->Gsvolu("C04G", "TUBE", idGas, tpar, 3); gMC->Gspos("C03G", 1, "C03A", 0., 0., 0., 0, "ONLY"); gMC->Gspos("C04G", 1, "C04A", 0., 0., 0., 0, "ONLY"); + + if (frames) { // // Frame Crosses to be placed inside gas - dr = (iChamber->frMax - iChamber->frMin); + dr = (iChamber->ROuter() - iChamber->RInner()); bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; bpar[1] = dframep/2; bpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C03F", "BOX", idtmed[1103], bpar, 3); - gMC->Gsvolu("C04F", "BOX", idtmed[1103], bpar, 3); + gMC->Gsvolu("C03F", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C04F", "BOX", idAlu1, bpar, 3); - gMC->Gspos("C03F",1,"C03G", +iChamber->frMin+bpar[0] , 0, 0, + gMC->Gspos("C03F",1,"C03G", +iChamber->RInner()+bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C03F",2,"C03G", -iChamber->frMin-bpar[0] , 0, 0, + gMC->Gspos("C03F",2,"C03G", -iChamber->RInner()-bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C03F",3,"C03G", 0, +iChamber->frMin+bpar[0] , 0, + gMC->Gspos("C03F",3,"C03G", 0, +iChamber->RInner()+bpar[0] , 0, idrotm[1101],"ONLY"); - gMC->Gspos("C03F",4,"C03G", 0, -iChamber->frMin-bpar[0] , 0, + gMC->Gspos("C03F",4,"C03G", 0, -iChamber->RInner()-bpar[0] , 0, idrotm[1101],"ONLY"); - gMC->Gspos("C04F",1,"C04G", +iChamber->frMin+bpar[0] , 0, 0, + gMC->Gspos("C04F",1,"C04G", +iChamber->RInner()+bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C04F",2,"C04G", -iChamber->frMin-bpar[0] , 0, 0, + gMC->Gspos("C04F",2,"C04G", -iChamber->RInner()-bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C04F",3,"C04G", 0, +iChamber->frMin+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C04F",4,"C04G", 0, -iChamber->frMin-bpar[0] , 0, + gMC->Gspos("C04F",3,"C04G", 0, +iChamber->RInner()+bpar[0] , 0, idrotm[1101],"ONLY"); + gMC->Gspos("C04F",4,"C04G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); + } + +#ifdef FUTURE //******************************************************************** // Station 3 ** //******************************************************************** @@ -387,27 +420,28 @@ idrotm[1101],"ONLY"); iChamber=(AliMUONchamber*) (*fChambers)[4]; zpos1=iChamber->ZPosition(); // 975-13.75 zpos2=zpos1 // +dstation; - +27.5; + +24.3; // // Mother volume - tpar[0] = iChamber->frMin; - tpar[1]= TMath::Sqrt(iChamber->frMax*iChamber->frMax + dframep*dframep) ; + tpar[0] = iChamber->RInner()-dframep; + tpar[1]= TMath::Sqrt((iChamber->ROuter()+dframep)*(iChamber->ROuter()+dframep) + dframep*dframep) ; + tpar[2] = // 3.; 5.325*2; - gMC->Gsvolu("C05M", "TUBE", idtmed[1100], tpar, 3); - gMC->Gsvolu("C06M", "TUBE", idtmed[1100], tpar, 3); + gMC->Gsvolu("C05M", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("C06M", "TUBE", idAir, tpar, 3); gMC->Gspos("C05M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); gMC->Gspos("C06M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); // // Mother volume for one quadrant - tspar[0]= iChamber->frMin; - tspar[1]= TMath::Sqrt(iChamber->frMax*iChamber->frMax + dframep*dframep) ; + tspar[0]= tpar[0]; + tspar[1]= tpar[1]; tspar[2]= // dframez; 5.325; - tspar[3] = 0.-TMath::ATan2(dframep,iChamber->frMin)*180/kPI; - tspar[4] = 90.+TMath::ATan2(dframep,iChamber->frMin)*180/kPI; - gMC->Gsvolu("C05Q", "TUBS", idtmed[1100], tspar, 5); - gMC->Gsvolu("C06Q", "TUBS", idtmed[1100], tspar, 5); + tspar[3] = 0.-TMath::ATan2(dframep/2.,iChamber->RInner()-dframep)*180/kPI; + tspar[4] = 90.+TMath::ATan2(dframep/2,iChamber->RInner()-dframep)*180/kPI; + gMC->Gsvolu("C05Q", "TUBS", idAir, tspar, 5); + gMC->Gsvolu("C06Q", "TUBS", idAir, tspar, 5); // Position the four quadrants gMC->Gspos("C05Q",1,"C05M", 0., 0., 5.325, idrotm[1100], "ONLY"); gMC->Gspos("C05Q",2,"C05M", 0., 0.,-5.325, idrotm[1101], "ONLY"); @@ -420,43 +454,43 @@ idrotm[1101],"ONLY"); gMC->Gspos("C06Q",4,"C06M", 0., 0.,-5.325, idrotm[1103], "ONLY"); // Aluminium frames // Outer frame - tspar[0]= iChamber->frMax-dframep*2; - tspar[1]= iChamber->frMax; + tspar[0]= iChamber->ROuter(); + tspar[1]= iChamber->ROuter()+dframep; tspar[3] = 0.; tspar[4] = 90.; - gMC->Gsvolu("C05O", "TUBS", idtmed[1100], tspar, 5); - gMC->Gsvolu("C06O", "TUBS", idtmed[1100], tspar, 5); + gMC->Gsvolu("C05O", "TUBS", idAir, tspar, 5); + gMC->Gsvolu("C06O", "TUBS", idAir, tspar, 5); gMC->Gspos("C05O",1,"C05Q", 0.,0.,0., 0,"ONLY"); gMC->Gspos("C06O",1,"C06Q", 0.,0.,0., 0,"ONLY"); // // Inner frame - tspar[0]= iChamber->frMin; - tspar[1]= iChamber->frMin+dframep*2; - gMC->Gsvolu("C05I", "TUBS", idtmed[1100], tspar, 5); - gMC->Gsvolu("C06I", "TUBS", idtmed[1100], tspar, 5); + tspar[0]= iChamber->RInner()-dframep; + tspar[1]= iChamber->RInner(); + gMC->Gsvolu("C05I", "TUBS", idAir, tspar, 5); + gMC->Gsvolu("C06I", "TUBS", idAir, tspar, 5); gMC->Gspos("C05I",1,"C05Q", 0.,0.,0., 0,"ONLY"); gMC->Gspos("C06I",1,"C06Q", 0.,0.,0., 0,"ONLY"); // // Boundary half frame - bpar[0] = (iChamber->frMax - iChamber->frMin)/2; - bpar[1] = dframep/2; + bpar[0] = (iChamber->ROuter() +dframep*2 - iChamber->RInner())/2; + bpar[1] = dframep/4; bpar[2] = 5.325; - gMC->Gsvolu("C05B", "BOX", idtmed[1103], bpar, 3); - gMC->Gsvolu("C06B", "BOX", idtmed[1103], bpar, 3); + gMC->Gsvolu("C05B", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C06B", "BOX", idAlu1, bpar, 3); //place 2 boudaries - gMC->Gspos("C05B",1,"C05Q", iChamber->frMin+bpar[0] ,-bpar[1],0., idrotm[1100],"ONLY"); - gMC->Gspos("C05B",2,"C05Q", -bpar[1],iChamber->frMin+bpar[0] ,0., idrotm[1101],"ONLY"); - gMC->Gspos("C06B",1,"C06Q", iChamber->frMin+bpar[0] ,-bpar[1],0., idrotm[1100],"ONLY"); - gMC->Gspos("C06B",2,"C06Q", -bpar[1],iChamber->frMin+bpar[0] ,0., idrotm[1101],"ONLY"); + gMC->Gspos("C05B",1,"C05Q", iChamber->RInner()+bpar[0] ,-bpar[1],0., idrotm[1100],"ONLY"); + gMC->Gspos("C05B",2,"C05Q", -bpar[1],iChamber->RInner()+bpar[0] ,0., idrotm[1101],"ONLY"); + gMC->Gspos("C06B",1,"C06Q", iChamber->RInner()+bpar[0] ,-bpar[1],0., idrotm[1100],"ONLY"); + gMC->Gspos("C06B",2,"C06Q", -bpar[1],iChamber->RInner()+bpar[0] ,0., idrotm[1101],"ONLY"); // // Boundary second half frame (should not overlapp with sensitive surface, nor frames) -// Effective inner radius due to circle effect - rMin = TMath::Sqrt( - (iChamber->frMin+2*dframep)*(iChamber->frMin+2*dframep) - dframep*dframep ); - bpar[0] = (iChamber->frMax - 2*dframep - rMin ) /2; +// Effective outer radius due to circle effect + rMax = TMath::Sqrt( + iChamber->ROuter()*iChamber->ROuter() - dframep*dframep ); + bpar[0] = (rMax - iChamber->RInner() ) /2; bpar[2] = (5.325- (0.055 + 0.325)) / 2; - gMC->Gsvolu("C05H", "BOX", idtmed[1103], bpar, 3); - gMC->Gsvolu("C06H", "BOX", idtmed[1103], bpar, 3); + gMC->Gsvolu("C05H", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C06H", "BOX", idAlu1, bpar, 3); //place 2 boudaries gMC->Gspos("C05H",1,"C05Q", rMin+bpar[0],bpar[1], 0.055+0.325+bpar[2] , idrotm[1100],"ONLY"); gMC->Gspos("C05H",2,"C05Q", rMin+bpar[0],bpar[1],-(0.055+0.325+bpar[2]), idrotm[1100],"ONLY"); @@ -469,48 +503,196 @@ idrotm[1101],"ONLY"); // // Chamber Material represented by Alu sheet // tspar[2] = (iChamber->fdAlu)+(iChamber->fdGas); - tspar[0]= iChamber->frMin+dframep*2; - tspar[1]= iChamber->frMax-dframep*2; + tspar[0]= iChamber->RInner(); + tspar[1]= iChamber->ROuter(); tspar[2] = 0.055 + 0.325; - gMC->Gsvolu("C05A", "TUBS", idtmed[1103], tspar, 5); - gMC->Gsvolu("C06A", "TUBS", idtmed[1103], tspar, 5); + gMC->Gsvolu("C05A", "TUBS", idAlu2, tspar, 5); + gMC->Gsvolu("C06A", "TUBS", idAlu2, tspar, 5); gMC->Gspos("C05A", 1, "C05Q", 0., 0., 0., 0, "ONLY"); gMC->Gspos("C06A", 1, "C06Q", 0., 0., 0., 0, "ONLY"); // // Sensitive volumes // tpar[2] = iChamber->fdGas; tspar[2] = 0.325; - gMC->Gsvolu("C05G", "TUBS", idtmed[1105], tspar, 5); - gMC->Gsvolu("C06G", "TUBS", idtmed[1105], tspar, 5); + gMC->Gsvolu("C05G", "TUBS", idGas, tspar, 5); + gMC->Gsvolu("C06G", "TUBS", idGas, tspar, 5); gMC->Gspos("C05G", 1, "C05A", 0., 0., 0., 0, "ONLY"); gMC->Gspos("C06G", 1, "C06A", 0., 0., 0., 0, "ONLY"); // // Overwrite sensitive volume with ALU // Overwrite Gaz volume bpar[2] = 0.325; - gMC->Gsvolu("C05Z", "BOX", idtmed[1103], bpar, 3); - gMC->Gsvolu("C06Z", "BOX", idtmed[1103], bpar, 3); + gMC->Gsvolu("C05Z", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C06Z", "BOX", idAlu1, bpar, 3); gMC->Gspos("C05Z",1,"C05G", rMin+bpar[0] ,bpar[1],0., idrotm[1100],"ONLY"); gMC->Gspos("C05Z",2,"C05G", bpar[1], rMin+bpar[0] ,0., idrotm[1101],"ONLY"); gMC->Gspos("C06Z",1,"C06G", rMin+bpar[0] ,bpar[1],0., idrotm[1100],"ONLY"); gMC->Gspos("C06Z",2,"C06G", bpar[1], rMin+bpar[0] ,0., idrotm[1101],"ONLY"); +#else +//******************************************************************** +// Station 3 ** +//******************************************************************** + iChamber=(AliMUONchamber*) (*fChambers)[4]; + zpos1=iChamber->ZPosition()-dstation[2]/2; + zpos2=zpos1+dstation[2]; + zfpos= // -(iChamber->fdGas+dframez)/2; + - ( 0.65 + 5.)/2; +// +// Mother volume + tpar[0] = iChamber->RInner()-dframep; + tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); + tpar[2] = // dstation[3]/2; + dstation[2]/4; + gMC->Gsvolu("C05M", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("C06M", "TUBE", idAir, tpar, 3); + gMC->Gspos("C05M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); + gMC->Gspos("C06M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); +// Aluminium frames +// Outer frames + pgpar[0] = 360/12/2; + pgpar[1] = 360.; + pgpar[2] = 12.; + pgpar[3] = 2; + pgpar[4] = // -dframez/2; + - 5./2; + pgpar[5] = iChamber->ROuter(); + pgpar[6] = pgpar[5]+dframep; + pgpar[7] = // +dframez/2; + 5./2; + pgpar[8] = pgpar[5]; + pgpar[9] = pgpar[6]; + gMC->Gsvolu("C05O", "PGON", idAlu1, pgpar, 10); + gMC->Gsvolu("C06O", "PGON", idAlu1, pgpar, 10); + gMC->Gspos("C05O",1,"C05M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C05O",2,"C05M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C06O",1,"C06M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C06O",2,"C06M", 0.,0.,+zfpos, 0,"ONLY"); +// +// Inner frame + tpar[0]= iChamber->RInner()-dframep; + tpar[1]= iChamber->RInner(); + tpar[2]= // dframez/2; + 5./2; + gMC->Gsvolu("C05I", "TUBE", idAlu1, tpar, 3); + gMC->Gsvolu("C06I", "TUBE", idAlu1, tpar, 3); + + gMC->Gspos("C05I",1,"C05M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C05I",2,"C05M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C06I",1,"C06M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C06I",2,"C06M", 0.,0.,+zfpos, 0,"ONLY"); +// +// Frame Crosses + if (frames) { + bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; + bpar[1] = dframep/2; + bpar[2] = // dframez/2; + 5./2; + gMC->Gsvolu("C05B", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C06B", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C05B",1,"C05M", +iChamber->RInner()+bpar[0] , 0,-zfpos, +idrotm[1100],"ONLY"); + gMC->Gspos("C05B",2,"C05M", -iChamber->RInner()-bpar[0] , 0,-zfpos, +idrotm[1100],"ONLY"); + gMC->Gspos("C05B",3,"C05M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, +idrotm[1101],"ONLY"); + gMC->Gspos("C05B",4,"C05M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, +idrotm[1101],"ONLY"); + gMC->Gspos("C05B",5,"C05M", +iChamber->RInner()+bpar[0] , 0,+zfpos, +idrotm[1100],"ONLY"); + gMC->Gspos("C05B",6,"C05M", -iChamber->RInner()-bpar[0] , 0,+zfpos, +idrotm[1100],"ONLY"); + gMC->Gspos("C05B",7,"C05M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, +idrotm[1101],"ONLY"); + gMC->Gspos("C05B",8,"C05M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, +idrotm[1101],"ONLY"); + + gMC->Gspos("C06B",1,"C06M", +iChamber->RInner()+bpar[0] , 0,-zfpos, +idrotm[1100],"ONLY"); + gMC->Gspos("C06B",2,"C06M", -iChamber->RInner()-bpar[0] , 0,-zfpos, +idrotm[1100],"ONLY"); + gMC->Gspos("C06B",3,"C06M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, +idrotm[1101],"ONLY"); + gMC->Gspos("C06B",4,"C06M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, +idrotm[1101],"ONLY"); + gMC->Gspos("C06B",5,"C06M", +iChamber->RInner()+bpar[0] , 0,+zfpos, +idrotm[1100],"ONLY"); + gMC->Gspos("C06B",6,"C06M", -iChamber->RInner()-bpar[0] , 0,+zfpos, +idrotm[1100],"ONLY"); + gMC->Gspos("C06B",7,"C06M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, +idrotm[1101],"ONLY"); + gMC->Gspos("C06B",8,"C06M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + } + + +// +// Chamber Material represented by Alu sheet + tpar[0]= iChamber->RInner(); + tpar[1]= iChamber->ROuter(); + tpar[2] = // (iChamber->fdGas+iChamber->fdAlu)/2; + 0.65 + 0.055; + gMC->Gsvolu("C05A", "TUBE", idAlu2, tpar, 3); + gMC->Gsvolu("C06A", "TUBE", idAlu2, tpar, 3); + gMC->Gspos("C05A", 1, "C05M", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C06A", 1, "C06M", 0., 0., 0., 0, "ONLY"); +// +// Sensitive volumes + tpar[2] = // iChamber->fdGas/2; + 0.65/2; + gMC->Gsvolu("C05G", "TUBE", idGas, tpar, 3); + gMC->Gsvolu("C06G", "TUBE", idGas, tpar, 3); + gMC->Gspos("C05G", 1, "C05A", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C06G", 1, "C06A", 0., 0., 0., 0, "ONLY"); +// +// Frame Crosses to be placed inside gas + if (frames) { + dr = (iChamber->ROuter() - iChamber->RInner()); + bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; + bpar[1] = dframep/2; + bpar[2] = // iChamber->fdGas/2; + 0.65/2; + gMC->Gsvolu("C05F", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C06F", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C05F",1,"C05G", +iChamber->RInner()+bpar[0] , 0, 0, +idrotm[1100],"ONLY"); + gMC->Gspos("C05F",2,"C05G", -iChamber->RInner()-bpar[0] , 0, 0, +idrotm[1100],"ONLY"); + gMC->Gspos("C05F",3,"C05G", 0, +iChamber->RInner()+bpar[0] , 0, +idrotm[1101],"ONLY"); + gMC->Gspos("C05F",4,"C05G", 0, -iChamber->RInner()-bpar[0] , 0, +idrotm[1101],"ONLY"); + + gMC->Gspos("C06F",1,"C06G", +iChamber->RInner()+bpar[0] , 0, 0, +idrotm[1100],"ONLY"); + gMC->Gspos("C06F",2,"C06G", -iChamber->RInner()-bpar[0] , 0, 0, +idrotm[1100],"ONLY"); + gMC->Gspos("C06F",3,"C06G", 0, +iChamber->RInner()+bpar[0] , 0, +idrotm[1101],"ONLY"); + gMC->Gspos("C06F",4,"C06G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); +} + +#endif //******************************************************************** // Station 4 ** //******************************************************************** iChamber=(AliMUONchamber*) (*fChambers)[6]; - zpos1=iChamber->ZPosition()-dstation/2; - zpos2=zpos1+dstation; + zpos1=iChamber->ZPosition()-dstation[3]/2; + zpos2=zpos1+dstation[3]; zfpos=-(iChamber->fdGas+dframez)/2; // // Mother volume - tpar[0] = iChamber->frMin-dframep; - tpar[1] = (iChamber->frMax+dframep)/TMath::Cos(phi); - tpar[2] = dstation/2; + tpar[0] = iChamber->RInner()-dframep; + tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); + //tpar[2] = dstation[3]/2; + tpar[2] = dstation[3]/4; - gMC->Gsvolu("C07M", "TUBE", idtmed[1100], tpar, 3); - gMC->Gsvolu("C08M", "TUBE", idtmed[1100], tpar, 3); + gMC->Gsvolu("C07M", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("C08M", "TUBE", idAir, tpar, 3); gMC->Gspos("C07M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); gMC->Gspos("C08M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); // Aluminium frames @@ -520,24 +702,24 @@ idrotm[1101],"ONLY"); pgpar[2] = 12.; pgpar[3] = 2; pgpar[4] = -dframez/2; - pgpar[5] = iChamber->frMax; + pgpar[5] = iChamber->ROuter(); pgpar[6] = pgpar[5]+dframep; pgpar[7] = +dframez/2; pgpar[8] = pgpar[5]; pgpar[9] = pgpar[6]; - gMC->Gsvolu("C07O", "PGON", idtmed[1103], pgpar, 10); - gMC->Gsvolu("C08O", "PGON", idtmed[1103], pgpar, 10); + gMC->Gsvolu("C07O", "PGON", idAlu1, pgpar, 10); + gMC->Gsvolu("C08O", "PGON", idAlu1, pgpar, 10); gMC->Gspos("C07O",1,"C07M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C07O",2,"C07M", 0.,0.,+zfpos, 0,"ONLY"); gMC->Gspos("C08O",1,"C08M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C08O",2,"C08M", 0.,0.,+zfpos, 0,"ONLY"); // // Inner frame - tpar[0]= iChamber->frMin-dframep; - tpar[1]= iChamber->frMin; + tpar[0]= iChamber->RInner()-dframep; + tpar[1]= iChamber->RInner(); tpar[2]= dframez/2; - gMC->Gsvolu("C07I", "TUBE", idtmed[1103], tpar, 3); - gMC->Gsvolu("C08I", "TUBE", idtmed[1103], tpar, 3); + gMC->Gsvolu("C07I", "TUBE", idAlu1, tpar, 3); + gMC->Gsvolu("C08I", "TUBE", idAlu1, tpar, 3); gMC->Gspos("C07I",1,"C07M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C07I",2,"C07M", 0.,0.,+zfpos, 0,"ONLY"); @@ -545,106 +727,111 @@ idrotm[1101],"ONLY"); gMC->Gspos("C08I",2,"C08M", 0.,0.,+zfpos, 0,"ONLY"); // // Frame Crosses - bpar[0] = (iChamber->frMax - iChamber->frMin)/2; + if (frames) { + bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; bpar[1] = dframep/2; bpar[2] = dframez/2; - gMC->Gsvolu("C07B", "BOX", idtmed[1103], bpar, 3); - gMC->Gsvolu("C08B", "BOX", idtmed[1103], bpar, 3); + gMC->Gsvolu("C07B", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C08B", "BOX", idAlu1, bpar, 3); - gMC->Gspos("C07B",1,"C07M", +iChamber->frMin+bpar[0] , 0,-zfpos, + gMC->Gspos("C07B",1,"C07M", +iChamber->RInner()+bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C07B",2,"C07M", -iChamber->frMin-bpar[0] , 0,-zfpos, + gMC->Gspos("C07B",2,"C07M", -iChamber->RInner()-bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C07B",3,"C07M", 0, +iChamber->frMin+bpar[0] ,-zfpos, + gMC->Gspos("C07B",3,"C07M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C07B",4,"C07M", 0, -iChamber->frMin-bpar[0] ,-zfpos, + gMC->Gspos("C07B",4,"C07M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C07B",5,"C07M", +iChamber->frMin+bpar[0] , 0,+zfpos, + gMC->Gspos("C07B",5,"C07M", +iChamber->RInner()+bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C07B",6,"C07M", -iChamber->frMin-bpar[0] , 0,+zfpos, + gMC->Gspos("C07B",6,"C07M", -iChamber->RInner()-bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C07B",7,"C07M", 0, +iChamber->frMin+bpar[0] ,+zfpos, + gMC->Gspos("C07B",7,"C07M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C07B",8,"C07M", 0, -iChamber->frMin-bpar[0] ,+zfpos, + gMC->Gspos("C07B",8,"C07M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C08B",1,"C08M", +iChamber->frMin+bpar[0] , 0,-zfpos, + gMC->Gspos("C08B",1,"C08M", +iChamber->RInner()+bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C08B",2,"C08M", -iChamber->frMin-bpar[0] , 0,-zfpos, + gMC->Gspos("C08B",2,"C08M", -iChamber->RInner()-bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C08B",3,"C08M", 0, +iChamber->frMin+bpar[0] ,-zfpos, + gMC->Gspos("C08B",3,"C08M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C08B",4,"C08M", 0, -iChamber->frMin-bpar[0] ,-zfpos, + gMC->Gspos("C08B",4,"C08M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C08B",5,"C08M", +iChamber->frMin+bpar[0] , 0,+zfpos, + gMC->Gspos("C08B",5,"C08M", +iChamber->RInner()+bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C08B",6,"C08M", -iChamber->frMin-bpar[0] , 0,+zfpos, + gMC->Gspos("C08B",6,"C08M", -iChamber->RInner()-bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C08B",7,"C08M", 0, +iChamber->frMin+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C08B",8,"C08M", 0, -iChamber->frMin-bpar[0] ,+zfpos, + gMC->Gspos("C08B",7,"C08M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, idrotm[1101],"ONLY"); + gMC->Gspos("C08B",8,"C08M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + } + // // Chamber Material represented by Alu sheet - tpar[0]= iChamber->frMin+dframep*2; - tpar[1]= iChamber->frMax-dframep*2; + tpar[0]= iChamber->RInner(); + tpar[1]= iChamber->ROuter(); tpar[2] = (iChamber->fdGas+iChamber->fdAlu)/2; - gMC->Gsvolu("C07A", "TUBE", idtmed[1103], tpar, 3); - gMC->Gsvolu("C08A", "TUBE", idtmed[1103], tpar, 3); + gMC->Gsvolu("C07A", "TUBE", idAlu2, tpar, 3); + gMC->Gsvolu("C08A", "TUBE", idAlu2, tpar, 3); gMC->Gspos("C07A", 1, "C07M", 0., 0., 0., 0, "ONLY"); gMC->Gspos("C08A", 1, "C08M", 0., 0., 0., 0, "ONLY"); // // Sensitive volumes // tpar[2] = iChamber->fdGas; tpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C07G", "TUBE", idtmed[1105], tpar, 3); - gMC->Gsvolu("C08G", "TUBE", idtmed[1105], tpar, 3); + gMC->Gsvolu("C07G", "TUBE", idGas, tpar, 3); + gMC->Gsvolu("C08G", "TUBE", idGas, tpar, 3); gMC->Gspos("C07G", 1, "C07A", 0., 0., 0., 0, "ONLY"); gMC->Gspos("C08G", 1, "C08A", 0., 0., 0., 0, "ONLY"); // // Frame Crosses to be placed inside gas - dr = (iChamber->frMax - iChamber->frMin); + if (frames) { + dr = (iChamber->ROuter() - iChamber->RInner()); bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; bpar[1] = dframep/2; bpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C07F", "BOX", idtmed[1103], bpar, 3); - gMC->Gsvolu("C08F", "BOX", idtmed[1103], bpar, 3); + gMC->Gsvolu("C07F", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C08F", "BOX", idAlu1, bpar, 3); - gMC->Gspos("C07F",1,"C07G", +iChamber->frMin+bpar[0] , 0, 0, + gMC->Gspos("C07F",1,"C07G", +iChamber->RInner()+bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C07F",2,"C07G", -iChamber->frMin-bpar[0] , 0, 0, + gMC->Gspos("C07F",2,"C07G", -iChamber->RInner()-bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C07F",3,"C07G", 0, +iChamber->frMin+bpar[0] , 0, + gMC->Gspos("C07F",3,"C07G", 0, +iChamber->RInner()+bpar[0] , 0, idrotm[1101],"ONLY"); - gMC->Gspos("C07F",4,"C07G", 0, -iChamber->frMin-bpar[0] , 0, + gMC->Gspos("C07F",4,"C07G", 0, -iChamber->RInner()-bpar[0] , 0, idrotm[1101],"ONLY"); - gMC->Gspos("C08F",1,"C08G", +iChamber->frMin+bpar[0] , 0, 0, + gMC->Gspos("C08F",1,"C08G", +iChamber->RInner()+bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C08F",2,"C08G", -iChamber->frMin-bpar[0] , 0, 0, + gMC->Gspos("C08F",2,"C08G", -iChamber->RInner()-bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C08F",3,"C08G", 0, +iChamber->frMin+bpar[0] , 0, + gMC->Gspos("C08F",3,"C08G", 0, +iChamber->RInner()+bpar[0] , 0, idrotm[1101],"ONLY"); - gMC->Gspos("C08F",4,"C08G", 0, -iChamber->frMin-bpar[0] , 0, + gMC->Gspos("C08F",4,"C08G", 0, -iChamber->RInner()-bpar[0] , 0, idrotm[1101],"ONLY"); - + } //******************************************************************** // Station 5 ** //******************************************************************** iChamber=(AliMUONchamber*) (*fChambers)[8]; - zpos1=iChamber->ZPosition()-dstation/2; - zpos2=zpos1+dstation; + zpos1=iChamber->ZPosition()-dstation[4]/2; + zpos2=zpos1+dstation[4]; zfpos=-(iChamber->fdGas+dframez)/2; // // Mother volume - tpar[0] = iChamber->frMin-dframep; - tpar[1] = (iChamber->frMax+dframep)/TMath::Cos(phi); - tpar[2] = dstation/2; + tpar[0] = iChamber->RInner()-dframep; + tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); + //tpar[2] = dstation[4]/2; + tpar[2] = dstation[4]/4; - gMC->Gsvolu("C09M", "TUBE", idtmed[1100], tpar, 3); - gMC->Gsvolu("C10M", "TUBE", idtmed[1100], tpar, 3); + gMC->Gsvolu("C09M", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("C10M", "TUBE", idAir, tpar, 3); gMC->Gspos("C09M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); gMC->Gspos("C10M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); // Aluminium frames @@ -654,114 +841,121 @@ idrotm[1101],"ONLY"); pgpar[2] = 12.; pgpar[3] = 2; pgpar[4] = -dframez/2; - pgpar[5] = iChamber->frMax; + pgpar[5] = iChamber->ROuter(); pgpar[6] = pgpar[5]+dframep; pgpar[7] = +dframez/2; pgpar[8] = pgpar[5]; pgpar[9] = pgpar[6]; - gMC->Gsvolu("C09O", "PGON", idtmed[1103], pgpar, 10); - gMC->Gsvolu("C10O", "PGON", idtmed[1103], pgpar, 10); + gMC->Gsvolu("C09O", "PGON", idAlu1, pgpar, 10); + gMC->Gsvolu("C10O", "PGON", idAlu1, pgpar, 10); gMC->Gspos("C09O",1,"C09M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C09O",2,"C09M", 0.,0.,+zfpos, 0,"ONLY"); gMC->Gspos("C10O",1,"C10M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C10O",2,"C10M", 0.,0.,+zfpos, 0,"ONLY"); // // Inner frame - tpar[0]= iChamber->frMin-dframep; - tpar[1]= iChamber->frMin; + tpar[0]= iChamber->RInner()-dframep; + tpar[1]= iChamber->RInner(); tpar[2]= dframez/2; - gMC->Gsvolu("C09I", "TUBE", idtmed[1103], tpar, 3); - gMC->Gsvolu("C10I", "TUBE", idtmed[1103], tpar, 3); + gMC->Gsvolu("C09I", "TUBE", idAlu1, tpar, 3); + gMC->Gsvolu("C10I", "TUBE", idAlu1, tpar, 3); gMC->Gspos("C09I",1,"C09M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C09I",2,"C09M", 0.,0.,+zfpos, 0,"ONLY"); gMC->Gspos("C10I",1,"C10M", 0.,0.,-zfpos, 0,"ONLY"); gMC->Gspos("C10I",2,"C10M", 0.,0.,+zfpos, 0,"ONLY"); + + if (frames) { // // Frame Crosses - bpar[0] = (iChamber->frMax - iChamber->frMin)/2; + + bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; bpar[1] = dframep/2; bpar[2] = dframez/2; - gMC->Gsvolu("C09B", "BOX", idtmed[1103], bpar, 3); - gMC->Gsvolu("C10B", "BOX", idtmed[1103], bpar, 3); + gMC->Gsvolu("C09B", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C10B", "BOX", idAlu1, bpar, 3); - gMC->Gspos("C09B",1,"C09M", +iChamber->frMin+bpar[0] , 0,-zfpos, + gMC->Gspos("C09B",1,"C09M", +iChamber->RInner()+bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C09B",2,"C09M", -iChamber->frMin-bpar[0] , 0,-zfpos, + gMC->Gspos("C09B",2,"C09M", -iChamber->RInner()-bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C09B",3,"C09M", 0, +iChamber->frMin+bpar[0] ,-zfpos, + gMC->Gspos("C09B",3,"C09M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C09B",4,"C09M", 0, -iChamber->frMin-bpar[0] ,-zfpos, + gMC->Gspos("C09B",4,"C09M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C09B",5,"C09M", +iChamber->frMin+bpar[0] , 0,+zfpos, + gMC->Gspos("C09B",5,"C09M", +iChamber->RInner()+bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C09B",6,"C09M", -iChamber->frMin-bpar[0] , 0,+zfpos, + gMC->Gspos("C09B",6,"C09M", -iChamber->RInner()-bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C09B",7,"C09M", 0, +iChamber->frMin+bpar[0] ,+zfpos, + gMC->Gspos("C09B",7,"C09M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C09B",8,"C09M", 0, -iChamber->frMin-bpar[0] ,+zfpos, + gMC->Gspos("C09B",8,"C09M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C10B",1,"C10M", +iChamber->frMin+bpar[0] , 0,-zfpos, + gMC->Gspos("C10B",1,"C10M", +iChamber->RInner()+bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C10B",2,"C10M", -iChamber->frMin-bpar[0] , 0,-zfpos, + gMC->Gspos("C10B",2,"C10M", -iChamber->RInner()-bpar[0] , 0,-zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C10B",3,"C10M", 0, +iChamber->frMin+bpar[0] ,-zfpos, + gMC->Gspos("C10B",3,"C10M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C10B",4,"C10M", 0, -iChamber->frMin-bpar[0] ,-zfpos, + gMC->Gspos("C10B",4,"C10M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, idrotm[1101],"ONLY"); - gMC->Gspos("C10B",5,"C10M", +iChamber->frMin+bpar[0] , 0,+zfpos, + gMC->Gspos("C10B",5,"C10M", +iChamber->RInner()+bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C10B",6,"C10M", -iChamber->frMin-bpar[0] , 0,+zfpos, + gMC->Gspos("C10B",6,"C10M", -iChamber->RInner()-bpar[0] , 0,+zfpos, idrotm[1100],"ONLY"); - gMC->Gspos("C10B",7,"C10M", 0, +iChamber->frMin+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C10B",8,"C10M", 0, -iChamber->frMin-bpar[0] ,+zfpos, + gMC->Gspos("C10B",7,"C10M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, idrotm[1101],"ONLY"); + gMC->Gspos("C10B",8,"C10M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + } + // // Chamber Material represented by Alu sheet - tpar[0]= iChamber->frMin+dframep*2; - tpar[1]= iChamber->frMax-dframep*2; + tpar[0]= iChamber->RInner(); + tpar[1]= iChamber->ROuter(); tpar[2] = (iChamber->fdGas+iChamber->fdAlu)/2; - gMC->Gsvolu("C09A", "TUBE", idtmed[1103], tpar, 3); - gMC->Gsvolu("C10A", "TUBE", idtmed[1103], tpar, 3); + gMC->Gsvolu("C09A", "TUBE", idAlu2, tpar, 3); + gMC->Gsvolu("C10A", "TUBE", idAlu2, tpar, 3); gMC->Gspos("C09A", 1, "C09M", 0., 0., 0., 0, "ONLY"); gMC->Gspos("C10A", 1, "C10M", 0., 0., 0., 0, "ONLY"); // // Sensitive volumes // tpar[2] = iChamber->fdGas; tpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C09G", "TUBE", idtmed[1105], tpar, 3); - gMC->Gsvolu("C10G", "TUBE", idtmed[1105], tpar, 3); + gMC->Gsvolu("C09G", "TUBE", idGas, tpar, 3); + gMC->Gsvolu("C10G", "TUBE", idGas, tpar, 3); gMC->Gspos("C09G", 1, "C09A", 0., 0., 0., 0, "ONLY"); gMC->Gspos("C10G", 1, "C10A", 0., 0., 0., 0, "ONLY"); // // Frame Crosses to be placed inside gas - dr = (iChamber->frMax - iChamber->frMin); + if (frames) { + dr = (iChamber->ROuter() - iChamber->RInner()); bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; bpar[1] = dframep/2; bpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C09F", "BOX", idtmed[1103], bpar, 3); - gMC->Gsvolu("C10F", "BOX", idtmed[1103], bpar, 3); + gMC->Gsvolu("C09F", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C10F", "BOX", idAlu1, bpar, 3); - gMC->Gspos("C09F",1,"C09G", +iChamber->frMin+bpar[0] , 0, 0, + gMC->Gspos("C09F",1,"C09G", +iChamber->RInner()+bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C09F",2,"C09G", -iChamber->frMin-bpar[0] , 0, 0, + gMC->Gspos("C09F",2,"C09G", -iChamber->RInner()-bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C09F",3,"C09G", 0, +iChamber->frMin+bpar[0] , 0, + gMC->Gspos("C09F",3,"C09G", 0, +iChamber->RInner()+bpar[0] , 0, idrotm[1101],"ONLY"); - gMC->Gspos("C09F",4,"C09G", 0, -iChamber->frMin-bpar[0] , 0, + gMC->Gspos("C09F",4,"C09G", 0, -iChamber->RInner()-bpar[0] , 0, idrotm[1101],"ONLY"); - gMC->Gspos("C10F",1,"C10G", +iChamber->frMin+bpar[0] , 0, 0, + gMC->Gspos("C10F",1,"C10G", +iChamber->RInner()+bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C10F",2,"C10G", -iChamber->frMin-bpar[0] , 0, 0, + gMC->Gspos("C10F",2,"C10G", -iChamber->RInner()-bpar[0] , 0, 0, idrotm[1100],"ONLY"); - gMC->Gspos("C10F",3,"C10G", 0, +iChamber->frMin+bpar[0] , 0, + gMC->Gspos("C10F",3,"C10G", 0, +iChamber->RInner()+bpar[0] , 0, idrotm[1101],"ONLY"); - gMC->Gspos("C10F",4,"C10G", 0, -iChamber->frMin-bpar[0] , 0, + gMC->Gspos("C10F",4,"C10G", 0, -iChamber->RInner()-bpar[0] , 0, idrotm[1101],"ONLY"); + } /////////////////////////////////////// // GEOMETRY FOR THE TRIGGER CHAMBERS // @@ -787,18 +981,18 @@ idrotm[1101],"ONLY"); zpos2=zpos1+DTPLANES; // Mother volume definition - tpar[0] = iChamber->frMin; - tpar[1] = iChamber->frMax; + tpar[0] = iChamber->RInner(); + tpar[1] = iChamber->ROuter(); tpar[2] = 0.4; - gMC->Gsvolu("CM11", "TUBE", idtmed[1100], tpar, 3); - gMC->Gsvolu("CM12", "TUBE", idtmed[1100], tpar, 3); + gMC->Gsvolu("CM11", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("CM12", "TUBE", idAir, tpar, 3); // Definition of the flange between the beam shielding and the RPC tpar[0]= R_MIN1; tpar[1]= R_MAX1; tpar[2]= 0.4; - gMC->Gsvolu("CF1A", "TUBE", idtmed[1103], tpar, 3); //Al + gMC->Gsvolu("CF1A", "TUBE", idAlu1, tpar, 3); //Al gMC->Gspos("CF1A", 1, "CM11", 0., 0., 0., 0, "MANY"); gMC->Gspos("CF1A", 2, "CM12", 0., 0., 0., 0, "MANY"); @@ -808,7 +1002,7 @@ idrotm[1101],"ONLY"); tpar[1]= 0.; tpar[2]= 0.; - gMC->Gsvolu("CC1A", "BOX ", idtmed[1103], tpar, 0); //Al + gMC->Gsvolu("CC1A", "BOX ", idAlu1, tpar, 0); //Al gMC->Gsvolu("CB1A", "BOX ", idtmed[1107], tpar, 0); //Bakelite gMC->Gsvolu("CG1A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer @@ -896,7 +1090,7 @@ idrotm[1101],"ONLY"); tpar[1]= 0.; tpar[2]= 0.; - gMC->Gsvolu("CC2A", "BOX ", idtmed[1103], tpar, 0); //Al + gMC->Gsvolu("CC2A", "BOX ", idAlu1, tpar, 0); //Al gMC->Gsvolu("CB2A", "BOX ", idtmed[1107], tpar, 0); //Bakelite gMC->Gsvolu("CG2A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer @@ -987,18 +1181,18 @@ idrotm[1101],"ONLY"); const Float_t R_MAX3=R_MAX1*zpos3/zpos1; // Mother volume definition - tpar[0] = iChamber->frMin; - tpar[1] = iChamber->frMax; + tpar[0] = iChamber->RInner(); + tpar[1] = iChamber->ROuter(); tpar[2] = 0.4; - gMC->Gsvolu("CM21", "TUBE", idtmed[1100], tpar, 3); - gMC->Gsvolu("CM22", "TUBE", idtmed[1100], tpar, 3); + gMC->Gsvolu("CM21", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("CM22", "TUBE", idAir, tpar, 3); // Definition of the flange between the beam shielding and the RPC tpar[0]= R_MIN3; tpar[1]= R_MAX3; tpar[2]= 0.4; - gMC->Gsvolu("CF2A", "TUBE", idtmed[1103], tpar, 3); //Al + gMC->Gsvolu("CF2A", "TUBE", idAlu1, tpar, 3); //Al gMC->Gspos("CF2A", 1, "CM21", 0., 0., 0., 0, "MANY"); gMC->Gspos("CF2A", 2, "CM22", 0., 0., 0., 0, "MANY"); @@ -1008,7 +1202,7 @@ idrotm[1101],"ONLY"); tpar[1]= 0.; tpar[2]= 0.; - gMC->Gsvolu("CC3A", "BOX ", idtmed[1103], tpar, 0); //Al + gMC->Gsvolu("CC3A", "BOX ", idAlu1, tpar, 0); //Al gMC->Gsvolu("CB3A", "BOX ", idtmed[1107], tpar, 0); //Bakelite gMC->Gsvolu("CG3A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer @@ -1096,7 +1290,7 @@ idrotm[1101],"ONLY"); tpar[1]= 0.; tpar[2]= 0.; - gMC->Gsvolu("CC4A", "BOX ", idtmed[1103], tpar, 0); //Al + gMC->Gsvolu("CC4A", "BOX ", idAlu1, tpar, 0); //Al gMC->Gsvolu("CB4A", "BOX ", idtmed[1107], tpar, 0); //Bakelite gMC->Gsvolu("CG4A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer @@ -1170,6 +1364,7 @@ idrotm[1101],"ONLY"); gMC->Gsposp("CC4A", 22, "CM22",-X_MC4D,-Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); gMC->Gspos("CM22", 1, "ALIC", 0., 0., zpos4, 0, "ONLY"); + } @@ -1222,6 +1417,7 @@ void AliMUONv0::CreateMaterials() // // --- Define the various materials for GEANT --- AliMaterial(9, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2); + AliMaterial(10, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2); AliMaterial(15, "AIR$ ", 14.61, 7.3, .001205, 30423.24, 67500); AliMixture(19, "Bakelite$", abak, zbak, dbak, -3, wbak); AliMixture(20, "ArC4H10 GAS$", ag, zg, dg, 3, wg); @@ -1243,6 +1439,8 @@ void AliMUONv0::CreateMaterials() AliMedium(4, "ALU_CH_US ", 9, 0, ISXFLD, SXMGMX, tmaxfd, fMaxStepAlu, fMaxDestepAlu, epsil, stmin); + AliMedium(5, "ALU_CH_US ", 10, 0, ISXFLD, SXMGMX, tmaxfd, fMaxStepAlu, + fMaxDestepAlu, epsil, stmin); // // Ar-isoC4H10 gas @@ -1256,6 +1454,9 @@ void AliMUONv0::CreateMaterials() AliMedium(8, "BAKE_CH_TRIGGER ", 19, 0, ISXFLD, SXMGMX, tmaxfd, fMaxStepAlu, fMaxDestepAlu, epsil, stmin); + AliMedium(9, "ARG_CO2 ", 22, 1, ISXFLD, SXMGMX, tmaxfd, fMaxStepGas, + fMaxDestepAlu, epsil, stmin); + } //___________________________________________ @@ -1270,8 +1471,10 @@ void AliMUONv0::Init() for (Int_t i=0; iInit(); } + // // Set the chamber (sensitive region) GEANT identifier + AliMC* gMC = AliMC::GetMC(); ((AliMUONchamber*)(*fChambers)[0])->SetGid(gMC->VolId("C01G")); ((AliMUONchamber*)(*fChambers)[1])->SetGid(gMC->VolId("C02G")); ((AliMUONchamber*)(*fChambers)[2])->SetGid(gMC->VolId("C03G")); @@ -1297,12 +1500,17 @@ void AliMUONv0::StepManager() static Int_t idvol; static Int_t vol[2]; Int_t ipart; - static Float_t hits[10]; + TLorentzVector pos; + TLorentzVector mom; + Float_t theta,phi; Float_t destep, step; - static Float_t eloss, xhit, yhit, tlength; + + static Float_t eloss, eloss2, xhit, yhit, tlength; const Float_t big=1.e10; - TLorentzVector pos, mom; + // modifs perso + static Float_t hits[14]; + TClonesArray &lhits = *fHits; // @@ -1330,6 +1538,9 @@ void AliMUONv0::StepManager() gMC->TrackMomentum(mom); ipart = gMC->TrackPid(); + //Int_t ipart1 = gMC->IdFromPDG(ipart); + //printf("ich, ipart %d %d \n",vol[0],ipart1); + // // momentum loss and steplength in last step destep = gMC->Edep(); @@ -1339,21 +1550,37 @@ void AliMUONv0::StepManager() // record hits when track enters ... if( gMC->IsTrackEntering()) { gMC->SetMaxStep(fMaxStepGas); - // Double_t tc = mom[0]*mom[0]+mom[1]*mom[1]; - //Double_t rt = TMath::Sqrt(tc); - //theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg; - //phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg; + Double_t tc = mom[0]*mom[0]+mom[1]*mom[1]; + Double_t rt = TMath::Sqrt(tc); + Double_t pmom = TMath::Sqrt(tc+mom[2]*mom[2]); + Double_t tx=mom[0]/pmom; + Double_t ty=mom[1]/pmom; + Double_t tz=mom[2]/pmom; + Double_t s=((AliMUONchamber*)(*fChambers)[idvol]) + ->GetResponseModel() + ->Pitch()/tz; + theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg; + phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg; hits[0] = Float_t(ipart); // Geant3 particle type - hits[1] = pos[0]; // X-position for hit - hits[2] = pos[1]; // Y-position for hit - hits[3] = pos[2]; // Z-position for hit - hits[4] = mom.Theta()*kRaddeg; // theta angle of incidence - hits[5] = mom.Phi()*kRaddeg; // phi angle of incidence + hits[1] = pos[0]+s*tx; // X-position for hit + hits[2] = pos[1]+s*ty; // Y-position for hit + hits[3] = pos[2]+s*tz; // Z-position for hit + hits[4] = theta; // theta angle of incidence + hits[5] = phi; // phi angle of incidence hits[8] = (Float_t) fNclusters; // first padhit hits[9] = -1; // last pad hit + + // modifs perso + hits[10] = mom[3]; // hit momentum P + hits[11] = mom[0]; // Px/P + hits[12] = mom[1]; // Py/P + hits[13] = mom[2]; // Pz/P + // fin modifs perso + // phi angle of incidence tlength = 0; eloss = 0; + eloss2 = 0; xhit = pos[0]; yhit = pos[1]; // Only if not trigger chamber @@ -1367,6 +1594,7 @@ void AliMUONv0::StepManager() //printf("In the Trigger Chamber #%d\n",idvol-9); } } + eloss2+=destep; // // Calculate the charge induced on a pad (disintegration) in case @@ -1379,11 +1607,12 @@ void AliMUONv0::StepManager() // Only if not trigger chamber if(idvol<10) { - if (eloss > 0) MakePadHits(xhit,yhit,eloss,idvol); + if (eloss > 0) + MakePadHits(0.5*(xhit+pos[0]),0.5*(yhit+pos[1]),eloss,idvol); } hits[6]=tlength; - hits[7]=eloss; + hits[7]=eloss2; if (fNclusters > (Int_t)hits[8]) { hits[8]= hits[8]+1; hits[9]= (Float_t) fNclusters; @@ -1403,7 +1632,8 @@ void AliMUONv0::StepManager() ((AliMUONchamber*) (*fChambers)[idvol]) ->SigGenInit(pos[0], pos[1], pos[2]); // printf("\n-> MakePadHits, reason special %d",ipart); - if (eloss > 0) MakePadHits(xhit,yhit,eloss,idvol); + if (eloss > 0) + MakePadHits(0.5*(xhit+pos[0]),0.5*(yhit+pos[1]),eloss,idvol); xhit = pos[0]; yhit = pos[1]; eloss = destep; @@ -1415,334 +1645,3 @@ void AliMUONv0::StepManager() tlength += step ; } } - -//___________________________________________ -void AliMUON::MakePadHits(Float_t xhit,Float_t yhit,Float_t eloss, Int_t idvol) -{ -// -// Calls the charge disintegration method of the current chamber and adds -// the simulated cluster to the root treee -// - Int_t clhits[7]; - Float_t newclust[6][500]; - Int_t nnew; - - -// -// Integrated pulse height on chamber - - - clhits[0]=fNhits+1; -// -// - ((AliMUONchamber*) (*fChambers)[idvol])->DisIntegration(eloss, xhit, yhit, nnew, newclust); -// printf("\n Add new clusters %d %f", nnew, eloss*1.e9); - Int_t ic=0; - -// -// Add new clusters - for (Int_t i=0; i 0) { - ic++; -// Cathode plane - clhits[1] = Int_t(newclust[5][i]); -// Cluster Charge - clhits[2] = Int_t(newclust[0][i]); -// Pad: ix - clhits[3] = Int_t(newclust[1][i]); -// Pad: iy - clhits[4] = Int_t(newclust[2][i]); -// Pad: charge - clhits[5] = Int_t(newclust[3][i]); -// Pad: chamber sector - clhits[6] = Int_t(newclust[4][i]); - - AddCluster(clhits); - } - } -// printf("\n %d new clusters added", ic); -} - -ClassImp(AliMUONchamber) - AliMUONchamber::AliMUONchamber() -{ - fSegmentation = new TObjArray(2); - fResponse=0; - fnsec=1; -} - -void AliMUONchamber::Init() -{ - - ((AliMUONsegmentation *) (*fSegmentation)[0])->Init(this); - if (fnsec==2) { - ((AliMUONsegmentation *) (*fSegmentation)[1])->Init(this); - } - -} - -void AliMUONchamber::DisIntegration(Float_t eloss, Float_t xhit, Float_t yhit, - Int_t& nnew,Float_t newclust[6][500]) -{ -// -// Generates pad hits (simulated cluster) -// using the segmentation and the response model - Float_t dx, dy; - // - // Width of the integration area - // - dx=fResponse->Nsigma()*fResponse->ChwX(); - dy=fResponse->Nsigma()*fResponse->ChwY(); - // - // Get pulse height from energy loss - Float_t qtot = fResponse->IntPH(eloss); - // - // Loop Over Pads - - Float_t qcheck=0, qp; - nnew=0; - for (Int_t i=1; i<=fnsec; i++) { - qcheck=0; - AliMUONsegmentation * segmentation=(AliMUONsegmentation *) (*fSegmentation)[i-1]; - for (segmentation->FirstPad(xhit, yhit, dx, dy); - segmentation->MorePads(); - segmentation->NextPad()) - { - qp=fResponse->IntXY(segmentation); - qp=TMath::Abs(qp); - -// -// - if (qp > 1.e-4) { - qcheck+=qp; - // - // --- store signal information - newclust[0][nnew]=qtot; - newclust[1][nnew]=segmentation->Ix(); - newclust[2][nnew]=segmentation->Iy(); - newclust[3][nnew]=qp * qtot; - newclust[4][nnew]=segmentation->ISector(); - newclust[5][nnew]=(Float_t) i; -// printf("\n pad hit %d %d %f %f ",nnew,i,newclust[1][nnew],newclust[2][nnew]); - nnew++; - - - } - } // Pad loop -// printf("\n check sum is %f %f %f %f %d",qcheck,qtot,xhit,yhit,fGid); - } // Cathode plane loop -} - - -ClassImp(AliMUONsegmentation) -ClassImp(AliMUONresponse) -//___________________________________________ -ClassImp(AliMUONsegmentationV0) - void AliMUONsegmentationV0::Init(AliMUONchamber* Chamber) -{ - fNpx=(Int_t) (Chamber->frMax/fDpx+1); - fNpy=(Int_t) (Chamber->frMax/fDpy+1); -} - - -Float_t AliMUONsegmentationV0::GetAnod(Float_t xhit) -{ - Float_t wire= (xhit<0)? Int_t(xhit/fWireD)+0.5:Int_t(xhit/fWireD)-0.5; - return fWireD*wire; -} - -void AliMUONsegmentationV0::SetPADSIZ(Float_t p1, Float_t p2) -{ - fDpx=p1; - fDpy=p2; -} -void AliMUONsegmentationV0:: - GetPadIxy(Float_t x, Float_t y, Int_t &ix, Int_t &iy) -{ -// returns pad coordinates (ix,iy) for given real coordinates (x,y) -// - ix = (x>0)? Int_t(x/fDpx)+1 : Int_t(x/fDpx)-1; - iy = (y>0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1; - if (iy > fNpy) iy= fNpy; - if (iy < -fNpy) iy=-fNpy; - if (ix > fNpx) ix= fNpx; - if (ix < -fNpx) ix=-fNpx; -} -void AliMUONsegmentationV0:: -GetPadCxy(Int_t ix, Int_t iy, Float_t &x, Float_t &y) -{ -// returns real coordinates (x,y) for given pad coordinates (ix,iy) -// - x = (ix>0) ? Float_t(ix*fDpx)-fDpx/2. : Float_t(ix*fDpx)+fDpx/2.; - y = (iy>0) ? Float_t(iy*fDpy)-fDpy/2. : Float_t(iy*fDpy)+fDpy/2.; -} - -void AliMUONsegmentationV0:: -FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) -{ - // - // Find the wire position (center of charge distribution) - Float_t x0a=GetAnod(xhit); - // - // and take fNsigma*sigma around this center - Float_t x01=x0a - dx; - Float_t x02=x0a + dx; - Float_t y01=yhit - dy; - Float_t y02=yhit + dy; - // - // find the pads over which the charge distributes - GetPadIxy(x01,y01,fixmin,fiymin); - GetPadIxy(x02,y02,fixmax,fiymax); -// printf("\n %f %f %d %d",x02,y02,fixmax,fiymax); -// printf("\n FirstPad called %f %f ", fDpx, fDpy); -// printf("\n Hit Position %f %f",xhit,yhit); -// printf("\n Integration limits: %i %i %i %i",fixmin,fixmax,fiymin,fiymax); -// printf("\n Integration limits: %f %f %f %f \n",x01,x02,y01,y02); - // - // Set current pad to lower left corner - fix=fixmin; - fiy=fiymin; - GetPadCxy(fix,fiy,fx,fy); -} - -void AliMUONsegmentationV0::NextPad() -{ - // - // Step to next pad in integration region - if (fix != fixmax) { - fix++; - } else if (fiy != fiymax) { - fix=fixmin; - fiy++; - } else { - printf("\n Error: Stepping outside integration region\n "); - } - GetPadCxy(fix,fiy,fx,fy); -} - -Int_t AliMUONsegmentationV0::MorePads() -// -// Are there more pads in the integration region -{ - if (fix == fixmax && fiy == fiymax) { - return 0; - } else { - return 1; - - } -} - -void AliMUONsegmentationV0::SigGenInit(Float_t x,Float_t y,Float_t) -{ -// -// Initialises pad and wire position during stepping - fxt =x; - fyt =y; - GetPadIxy(x,y,fixt,fiyt); - fiwt=Int_t(x/fWireD)+1; -} - -Int_t AliMUONsegmentationV0::SigGenCond(Float_t x,Float_t y,Float_t) -{ -// -// Signal will be generated if particle crosses pad boundary or -// boundary between two wires. - Int_t ixt, iyt; - GetPadIxy(x,y,ixt,iyt); - Int_t iwt=Int_t(x/fWireD)+1; - - if ((ixt != fixt) || (iyt !=fiyt) || (iwt != fiwt)) { - return 1; - } else { - return 0; - } -} -void AliMUONsegmentationV0:: -IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) -{ - x1=fxt-fx-fDpx/2.; - x2=x1+fDpx; - y1=fyt-fy-fDpy/2.; - y2=y1+fDpy; -} - -void AliMUONsegmentationV0:: -Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[7], Int_t Ylist[7]) -{ - *Nlist=4;Xlist[0]=Xlist[1]=iX;Xlist[2]=iX-1;Xlist[3]=iX+1; - Ylist[0]=iY-1;Ylist[1]=iY+1;Ylist[2]=Ylist[3]=iY; -} - -void AliMUONsegmentationV0:: -FitXY(AliMUONRecCluster* ,TClonesArray* ) - // Default : Centre of gravity method -{ - ; -} - - -//___________________________________________ -ClassImp(AliMUONresponseV0) -Float_t AliMUONresponseV0::IntPH(Float_t eloss) -{ - // Get number of electrons and return charge - - Int_t nel; - nel= Int_t(eloss*1.e9/26.); - Float_t charge=0; - if (nel == 0) nel=1; - for (Int_t i=1;i<=nel;i++) { - charge -= fChslope*TMath::Log(gRandom->Rndm()); - } - return charge; -} -// ------------------------------------------- -Float_t AliMUONresponseV0::IntXY(AliMUONsegmentation * segmentation) -{ - - const Float_t invpitch = 1/fPitch; -// -// Integration limits defined by segmentation model -// - Float_t xi1, xi2, yi1, yi2; - segmentation->IntegrationLimits(xi1,xi2,yi1,yi2); - xi1=xi1*invpitch; - xi2=xi2*invpitch; - yi1=yi1*invpitch; - yi2=yi2*invpitch; -// -// The Mathieson function - Double_t ux1=fSqrtKx3*TMath::TanH(fKx2*xi1); - Double_t ux2=fSqrtKx3*TMath::TanH(fKx2*xi2); - - Double_t uy1=fSqrtKy3*TMath::TanH(fKy2*yi1); - Double_t uy2=fSqrtKy3*TMath::TanH(fKy2*yi2); - - - return Float_t(4.*fKx4*(TMath::ATan(ux2)-TMath::ATan(ux1))* - fKy4*(TMath::ATan(uy2)-TMath::ATan(uy1))); -} - -// ------------------------------------------- -ClassImp(AliMUONgeometry) - void AliMUONgeometry::InitGeo(Float_t) -{ - fdGas= 0.5; - fdAlu= 2.5/100*8.9; -} - - - - - - - - - - - - - - - - diff --git a/MUON/AliMUONv0.h b/MUON/AliMUONv0.h index 91b4b1740a3..bacb914104a 100644 --- a/MUON/AliMUONv0.h +++ b/MUON/AliMUONv0.h @@ -1,17 +1,16 @@ -#ifndef MUONv0_H -#define MUONv0_H +#ifndef MUONV0_H +#define MUONV0_H ///////////////////////////////////////////////////////// // Manager and hits classes for set:MUON version 0 // ///////////////////////////////////////////////////////// #include "AliMUON.h" - +#include "AliMUONClusterFinder.h" class AliMUONv0 : public AliMUON { - public: AliMUONv0(); AliMUONv0(const char *name, const char *title); - virtual ~AliMUONv0() {} + virtual ~AliMUONv0() {} virtual void CreateGeometry(); virtual void CreateMaterials(); virtual void Init(); @@ -20,141 +19,7 @@ public: virtual void Trigger(Float_t (*)[4], Float_t (*)[4], Int_t& iflag); private: ClassDef(AliMUONv0,1) //Hits manager for set:MUON version 0 - -}; -class AliMUONsegmentationV0 : -public AliMUONsegmentation { - public: - AliMUONsegmentationV0(){} - virtual ~AliMUONsegmentationV0(){} - // - // Set Chamber Segmentation Parameters - virtual void SetPADSIZ(Float_t p1, Float_t p2); - virtual void SetDAnod(Float_t D) {fWireD = D;}; - // - // Transform from pad (wire) to real coordinates and vice versa - virtual Float_t GetAnod(Float_t xhit); - virtual void GetPadIxy(Float_t x ,Float_t y ,Int_t &ix,Int_t &iy); - virtual void GetPadCxy(Int_t ix,Int_t iy,Float_t &x ,Float_t &y ); - // - // Initialisation - virtual void Init(AliMUONchamber*); - // - // Get member data - virtual Float_t Dpx(){return fDpx;} - virtual Float_t Dpy(){return fDpy;} - virtual Int_t Npx(){return fNpx;} - virtual Int_t Npy(){return fNpy;} - // - // Iterate over pads - virtual void FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy); - virtual void NextPad(); - virtual Int_t MorePads(); - // Get next neighbours - virtual void Neighbours - (Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]); - // Provisory RecCluster coordinates reconstructor - virtual void FitXY(AliMUONRecCluster* Cluster,TClonesArray* MUONdigits); - // - // Current Pad during Integration - virtual Int_t Ix(){return fix;} - virtual Int_t Iy(){return fiy;} - virtual Int_t ISector(){return 1;} - // - // Signal Generation Condition during Stepping - virtual Int_t SigGenCond(Float_t x, Float_t y, Float_t z); - virtual void SigGenInit(Float_t x, Float_t y, Float_t z); - virtual void IntegrationLimits - (Float_t& x1, Float_t& x2, Float_t& y1, Float_t& y2); - // - // Identification - ClassDef(AliMUONsegmentationV0,1) - protected: - // - // Implementation of the segmentation data - // Version 0 models rectangular pads with the same dimensions all - // over the cathode plane - // - // geometry - // - Float_t fDpx; // x pad width per sector - Float_t fDpy; // y pad base width - Int_t fNpx; - Int_t fNpy; // Number of pads in y - Float_t fWireD; // wire pitch - - // Chamber region consideres during disintegration (lower left and upper right corner) - // - Int_t fixmin; - Int_t fixmax; - Int_t fiymin; - Int_t fiymax; - // - // Current pad during integration (cursor for disintegration) - Int_t fix; - Int_t fiy; - Float_t fx; - Float_t fy; - // - // Current pad and wire during tracking (cursor at hit centre) - Int_t fixt; - Int_t fiyt; - Int_t fiwt; - Float_t fxt; - Float_t fyt; }; - -class AliMUONresponseV0 : //Mathieson response -public AliMUONresponse { - public: - AliMUONresponseV0(){} - virtual ~AliMUONresponseV0(){} - // - // Configuration methods - // - virtual void SetRSIGM(Float_t p1) {fNsigma=p1;} - virtual void SetMUCHSP(Float_t p1) {fChslope=p1;} - virtual void SetMUSIGM(Float_t p1, Float_t p2) {fChwX=p1; fChwY=p2;} - virtual void SetMAXADC(Float_t p1) {fadc_satm=p1;} - // Mathieson parameters - virtual void SetSqrtKx3(Float_t p1) {fSqrtKx3=p1;}; - virtual void SetKx2(Float_t p1) {fKx2=p1;}; - virtual void SetKx4(Float_t p1) {fKx4=p1;}; - virtual void SetSqrtKy3(Float_t p1) {fSqrtKy3=p1;}; - virtual void SetKy2(Float_t p1) {fKy2=p1;}; - virtual void SetKy4(Float_t p1) {fKy4=p1;}; - virtual void SetPitch(Float_t p1) {fPitch=p1;}; - // - // Get member data - virtual Float_t Chslope() {return fChslope;} - virtual Float_t ChwX() {return fChwX;} - virtual Float_t ChwY() {return fChwY;} - virtual Float_t Nsigma() {return fNsigma;} - virtual Float_t adc_satm() {return fadc_satm;} - // - // Chamber response methods - // Pulse height from scored quantity (eloss) - virtual Float_t IntPH(Float_t eloss); - // Charge disintegration - virtual Float_t IntXY(AliMUONsegmentation * segmentation); - // Identification - // - ClassDef(AliMUONresponseV0,1) - protected: - Float_t fChslope; // Slope of the charge distribution - Float_t fChwX; // Width of the charge distribution in x - Float_t fChwY; // Width of the charge distribution in y - Float_t fNsigma; // Number of sigma's used for charge distribution - Float_t fadc_satm; // Maximum ADC channel - Float_t fSqrtKx3; // Mathieson parameters for x - Float_t fKx2; - Float_t fKx4; - Float_t fSqrtKy3; // Mathieson parameters for y - Float_t fKy2; - Float_t fKy4; - Float_t fPitch; //anode-cathode pitch -}; - #endif diff --git a/MUON/MUONDigitsTestnew.C b/MUON/MUONDigitsTestnew.C index fccc3c66b5b..16aeb4d30ad 100644 --- a/MUON/MUONDigitsTestnew.C +++ b/MUON/MUONDigitsTestnew.C @@ -1,3 +1,5 @@ +#include "iostream.h" + void MUONdigitsTestnew (Int_t evNumber1=0,Int_t evNumber2=0) { ///////////////////////////////////////////////////////////////////////// @@ -10,9 +12,8 @@ void MUONdigitsTestnew (Int_t evNumber1=0,Int_t evNumber2=0) // Dynamically link some shared libs if (gClassTable->GetID("AliRun") < 0) { - gSystem->Load("libGeant3Dummy.sl"); // a dummy version of Geant3 - gSystem->Load("PHOS/libPHOSdummy.sl"); // the standard Alice classes - gSystem->Load("libgalice.sl"); // the standard Alice classes + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); } // Connect the Root Galice file containing Geometry, Kine and Hits diff --git a/MUON/MUONLinkDef.h b/MUON/MUONLinkDef.h index 539b8af0e50..18a17cbb06d 100644 --- a/MUON/MUONLinkDef.h +++ b/MUON/MUONLinkDef.h @@ -2,13 +2,12 @@ #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; - +#pragma link C++ enum Cluster_t; #pragma link C++ class AliMUON-; #pragma link C++ class AliMUONv0; #pragma link C++ class AliMUONhit; #pragma link C++ class AliMUONdigit; #pragma link C++ class AliMUONlist; -#pragma link C++ class AliMUONgeometry; #pragma link C++ class AliMUONcluster; #pragma link C++ class AliMUONreccluster; #pragma link C++ class AliMUONRecCluster; @@ -17,12 +16,20 @@ #pragma link C++ class AliMUONsegmentationV0; #pragma link C++ class AliMUONresponseV0; #pragma link C++ class AliMUONsegmentationV01; +#pragma link C++ class AliMUONsegmentationV02; +#pragma link C++ class AliMUONsegmentationV04; +#pragma link C++ class AliMUONsegmentationV05; #pragma link C++ class AliMUONsegmentationV1; #pragma link C++ class AliMUONchamber; #pragma link C++ class AliMUONpoints; #pragma link C++ class AliMUONdisplay; -#pragma link C++ class Bin-; -#pragma link C++ class PreCluster-; +#pragma link C++ class AliMUONClusterFinder; +#pragma link C++ class AliMUONClusterFinderv0; +#pragma link C++ class AliMUONcorrelation; +#pragma link C++ class AliMUONRawCluster; +#pragma link C++ class AliMUONHitMap; +#pragma link C++ class AliMUONHitMapA1; +#pragma link C++ class AliMUONTUBE; #endif diff --git a/MUON/MUONcathcorel.C b/MUON/MUONcathcorel.C new file mode 100644 index 00000000000..46213327f80 --- /dev/null +++ b/MUON/MUONcathcorel.C @@ -0,0 +1,55 @@ +#include "iostream.h" + +void MUONcathcorel (Int_t evNumber1=0,Int_t evNumber2=9) +{ +///////////////////////////////////////////////////////////////////////// +// This macro is a small example of a ROOT macro +// illustrating how to read the output of GALICE +// and do some analysis. +// +///////////////////////////////////////////////////////////////////////// + +// Dynamically link some shared libs + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + + +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (file) file->Close(); + file = new TFile("galice.root","UPDATE"); + file->ls(); + + printf ("I'm after Map \n"); + +// Get AliRun object from file or create it if not on file + + if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + } + printf ("I'm after gAlice \n"); + + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); +// +// Event Loop +// + for (int nev=0; nev<= evNumber2; nev++) { + Int_t nparticles = gAlice->GetEvent(nev); + cout << "nev " <CathodeCorrelation(nev); + } // event loop + file->Close(); +} + + + + diff --git a/MUON/MUONcombi.C b/MUON/MUONcombi.C index 06436faf8a8..5ec65ea3d18 100644 --- a/MUON/MUONcombi.C +++ b/MUON/MUONcombi.C @@ -10,7 +10,7 @@ void MUONcombi (Int_t evNumber=0) // Root > anal(2); //process third event //Begin_Html /* - + */ //End_Html ///////////////////////////////////////////////////////////////////////// diff --git a/MUON/MUONdigit.C b/MUON/MUONdigit.C index ccef496a3e3..a1e3e8a14e1 100644 --- a/MUON/MUONdigit.C +++ b/MUON/MUONdigit.C @@ -1,69 +1,46 @@ -void MUONdigit (Int_t evNumber1=0,Int_t evNumber2=0,Int_t nCathode=1) +#include "iostream.h" + +void MUONdigit (Int_t evNumber1=0,Int_t evNumber2=0,Int_t nsignal =25) { ///////////////////////////////////////////////////////////////////////// -// // -// This macros converts the pad-hit information into digits // -// // +// This macro is a small example of a ROOT macro +// illustrating how to read the output of GALICE +// and do some analysis. +// ///////////////////////////////////////////////////////////////////////// // Dynamically link some shared libs if (gClassTable->GetID("AliRun") < 0) { - gSystem->Load("$ALITOP/cern.so/lib/libpdfDUMMY.so"); - gSystem->Load("$ALITOP/cern.so/lib/libPythia.so"); - gSystem->Load("$ROOTSYS/lib/libEG.so"); - gSystem->Load("$ROOTSYS/lib/libEGPythia.so"); - gSystem->Load("libGeant3Dummy.so"); //a dummy version of Geant3 - gSystem->Load("PHOS/libPHOSdummy.so"); //the standard Alice classes - gSystem->Load("libgalice.so"); //the standard Alice classes + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); } + // Connect the Root Galice file containing Geometry, Kine and Hits TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); if (file) file->Close(); file = new TFile("galice.root","UPDATE"); file->ls(); -// file->Map(); - printf ("\n File loaded !"); + printf ("I'm after Map \n"); // Get AliRun object from file or create it if not on file if (!gAlice) { gAlice = (AliRun*)file->Get("gAlice"); - if (gAlice) printf("\n AliRun object found on file\n"); + if (gAlice) printf("AliRun object found on file\n"); if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); } - printf ("\n gAlice created !\n"); - - AliMUON *MUON = gAlice->GetDetector("MUON"); - - AliMUONchamber* iChamber; - AliMUONsegmentation* segmentation; - - Int_t Npx[10]; - Int_t Npy[10]; - - Int_t nxmax=1026; - Int_t nymax=1026; - AliMUONlist *elem[10][1026][1026]; - TObjArray *obj=new TObjArray; - - Int_t trk[500]; - Int_t chtrk[500]; - - - Int_t digits[3]; - TVector *trinfo; - trinfo=new TVector(2); - + printf ("I'm after gAlice \n"); + + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); // -// Loop over events +// Event Loop // - - Int_t Nh=0; - Int_t Nh1=0; + Int_t nbgr_ev=0; + for (int nev=0; nev<= evNumber2; nev++) { Int_t nparticles = gAlice->GetEvent(nev); cout << "nev " <TreeH(); - Int_t ntracks = TH->GetEntries(); - Int_t Nc=0; - - Int_t counter=0; - // - // loop over cathodes - for (int icat=0; icatResetHits(); - Int_t nbytes += TH->GetEvent(track); - if (MUON) { - for(AliMUONhit* mHit=(AliMUONhit*)MUON->FirstHit(-1); - mHit; - mHit=(AliMUONhit*)MUON->NextHit()) - { - Int_t nch = mHit->fChamber; // chamber number - Float_t x = mHit->fX; // x-pos of hit - Float_t y = mHit->fY; // y-pos - - - iChamber = &(MUON->Chamber(nch-1)); - response=iChamber->GetResponseModel(); - - Int_t nsec=iChamber->Nsec(); - Int_t rmin = (Int_t)iChamber->frMin; - Int_t rmax = (Int_t)iChamber->frMax; - if (nch > 10) continue; - -// -// - for (AliMUONcluster* mPad= - (AliMUONcluster*)MUON->FirstPad(mHit); - mPad; - mPad=(AliMUONcluster*)MUON->NextPad()) - { - Int_t cathode = mPad->fCathode; // cathode number - Int_t nhit = mPad->fHitNumber; // hit number - Int_t qtot = mPad->fQ; // charge - Int_t ipx = mPad->fPadX; // pad X - Int_t ipy = mPad->fPadY; // pad Y - Int_t iqpad = mPad->fQpad; // charge per pad - Int_t rsec = mPad->fRSec; // sector# -// -// - if (cathode != (icat+1)) continue; - segmentation=iChamber-> - GetSegmentationModel(cathode); - Int_t Npx[nch-1] = segmentation->Npx(); - Int_t Npy[nch-1] = segmentation->Npy(); - - - Int_t npx=Npx[nch-1]; - Int_t npy=Npy[nch-1]; - Float_t thex, they; - segmentation->GetPadCxy(ipx,ipy,thex,they); - - Float_t rpad=TMath::Sqrt(thex*thex+they*they); - - - // check boundaries - if (rpad < rmin || iqpad ==0 || rpad > rmax) continue; - - // fill the info array + Int_t nbgr_ev=Int_t(nev/nsignal); +// printf("nbgr_ev %d\n",nbgr_ev); + //if (MUON) MUON->Digitise(nev,nbgr_ev,"Add"," ","galice_bgr.root"); + if (MUON) MUON->Digitise(nev,nbgr_ev,"rien"," ","galice_bgr.root"); +// char hname[30]; +// sprintf(hname,"TreeD%d",nev); +// file->ls(); + } // event loop + file->Close(); +} - trinfo(0)=(Float_t)track; - trinfo(1)=(Float_t)iqpad; - digits[0]=ipx; - digits[1]=ipy; - digits[2]=iqpad; - // build the list of fired pads and update the info - - AliMUONlist *pdigit=elem[nch-1][ipy+npy][ipx+npx]; - if (pdigit==0) { - obj->AddAtAndExpand( - new AliMUONlist(rpad,digits),counter); - counter++; - Int_t last=obj->GetLast(); - pdigit=(AliMUONlist*)obj->At(last); - elem[nch-1][ipy+npy][ipx+npx]=pdigit; - // list of tracks - TObjArray *trlist= - (TObjArray*)pdigit->TrackList(); - trlist->Add(trinfo); - } else { - // update charge - (*pdigit).fSignal+=iqpad; - // update list of tracks - TObjArray* trlist=(TObjArray*)pdigit - ->TrackList(); - Int_t nptracks=trlist->GetEntriesFast(); - - for (Int_t tr=0;trAt(tr); -// TVector &vtrk = *ptrk; - Int_t entries=ptrk->GetNrows(); - trk[tr]=Int_t(ptrk(0)); - chtrk[tr]=Int_t(ptrk(1)); - if (trk[tr]==track) { - chtrk[tr]+=iqpad; - trlist->RemoveAt(tr); - trinfo(0)=trk[tr]; - trinfo(1)=chtrk[tr]; - trlist->AddAt(trinfo,tr); - } else { - trlist->Add(trinfo); - } - } // end loop over list of tracks for one pad - } // end if pdigit - } //end loop over clust - } // hit loop - } // if MUON - } // track loop - Int_t tracks[10]; - Int_t charges[10]; - cout<<"Start filling digits now !"<fSignal; - // - if ( q <= zero_supm ) continue; - if ( q > adc_satm) q=adc_satm; - digits[0]=address->fPadX; - digits[1]=address->fPadY; - digits[2]=address->fSignal; - TObjArray* trlist=(TObjArray*)address->TrackList(); - Int_t nptracks=trlist->GetEntriesFast(); - // this was changed to accomodate the real number of tracks - if (nptracks > 10) { - cout<<"Attention - nptracks > 10 "<At(tr); - Int_t entries=pp->GetNrows(); - TVector &v2 = *pp; - tracks[tr]=(Int_t)v2(0); - charges[tr]=(Int_t)v2(1); - } //end loop over list of tracks for one pad - // fill digits - MUON->AddDigits(id,tracks,charges,digits); - nd++; - } // end loop over ix - } // end loop over iy - cout<<"I'm out of the loops over pads"<TreeD()->Fill(); - TTree *TD=gAlice->TreeD(); - int ndig=TD->GetEntries(); - cout<<"number of digits "<DigitsAddress(i); - int ndig=fDch->GetEntriesFast(); - printf (" i, ndig %d %d \n",i,ndig); - } - MUON->ResetDigits(); - obj->Clear(); - } //end loop over cathodes - char hname[30]; - sprintf(hname,"TreeD%d",nev); - gAlice->TreeD()->Write(hname); - - file->ls(); -// file->Map(); - } // event loop - obj->Delete(); - delete obj; - file->Close(); - cout<<"END digitisation "<GetID("AliRun") < 0) { - gSystem->Load("$ALITOP/cern.so/lib/libpdfDUMMY.so"); - gSystem->Load("$ALITOP/cern.so/lib/libPythia.so"); - gSystem->Load("$ROOTSYS/lib/libEG.so"); - gSystem->Load("$ROOTSYS/lib/libEGPythia.so"); - gSystem->Load("libGeant3Dummy.so"); //a dummy version of Geant3 - gSystem->Load("PHOS/libPHOSdummy.so"); //the standard Alice classes - gSystem->Load("libgalice.so"); //the standard Alice classes + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + /* + } else { + delete gAlice; + gAlice = 0; + */ } + // Connect the Root Galice file containing Geometry, Kine and Hits TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); if (!file) file = new TFile("galice.root"); diff --git a/MUON/MUONrawclusters.C b/MUON/MUONrawclusters.C new file mode 100644 index 00000000000..fa854493424 --- /dev/null +++ b/MUON/MUONrawclusters.C @@ -0,0 +1,140 @@ +#include "iostream.h" + +void MUONrawclusters (Int_t evNumber1=0,Int_t evNumber2=0) +{ +///////////////////////////////////////////////////////////////////////// +// This macro is a small example of a ROOT macro +// illustrating how to read the output of GALICE +// and do some analysis. +// +///////////////////////////////////////////////////////////////////////// + +// Dynamically link some shared libs + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (!file) file = new TFile("galice.root","UPDATE"); + +// Get AliRun object from file or create it if not on file + + if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + } +// +// Set reconstruction models +// +// Get pointers to Alice detectors and Digits containers + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); + + RecModel1 = new AliMUONClusterFinder(); + RecModel1->SetNperMax(90); + //RecModel1->SetClusterSize(12); + RecModel1->SetClusterSize(100); + RecModel1->SetDeclusterFlag(0); + MUON->SetReconstructionModel(0,RecModel1); + + RecModel2 = new AliMUONClusterFinder(); + RecModel2->SetNperMax(90); + //RecModel2->SetClusterSize(12); + RecModel2->SetClusterSize(100); + RecModel2->SetDeclusterFlag(0); + MUON->SetReconstructionModel(1,RecModel2); + + RecModel3 = new AliMUONClusterFinder(); + RecModel3->SetNperMax(90); + //RecModel3->SetClusterSize(12); + RecModel3->SetClusterSize(100); + RecModel3->SetDeclusterFlag(0); + MUON->SetReconstructionModel(2,RecModel3); + + RecModel4 = new AliMUONClusterFinder(); + RecModel4->SetNperMax(90); + //RecModel4->SetClusterSize(12); + RecModel4->SetClusterSize(100); + RecModel4->SetDeclusterFlag(0); + MUON->SetReconstructionModel(3,RecModel4); + + //RecModel5 = new AliMUONClusterFinderv0(); + RecModel5 = new AliMUONClusterFinder(); + RecModel5->SetNperMax(90); + //RecModel5->SetClusterSize(15); + RecModel5->SetClusterSize(100); + RecModel5->SetDeclusterFlag(0); + MUON->SetReconstructionModel(4,RecModel5); + + //RecModel6 = new AliMUONClusterFinderv0(); + RecModel6 = new AliMUONClusterFinder(); + RecModel6->SetNperMax(90); + //RecModel6->SetClusterSize(15); + RecModel6->SetClusterSize(100); + RecModel6->SetDeclusterFlag(0); + MUON->SetReconstructionModel(5,RecModel6); + + RecModel7 = new AliMUONClusterFinder(); + RecModel7->SetNperMax(90); + //RecModel7->SetClusterSize(9); + RecModel7->SetClusterSize(100); + RecModel7->SetDeclusterFlag(0); + MUON->SetReconstructionModel(6,RecModel7); + + RecModel8 = new AliMUONClusterFinder(); + RecModel8->SetNperMax(90); + //RecModel8->SetClusterSize(9); + RecModel8->SetClusterSize(100); + RecModel8->SetDeclusterFlag(0); + MUON->SetReconstructionModel(7,RecModel8); + + RecModel9 = new AliMUONClusterFinder(); + RecModel9->SetNperMax(90); + //RecModel9->SetClusterSize(9); + RecModel9->SetClusterSize(100); + RecModel9->SetDeclusterFlag(0); + MUON->SetReconstructionModel(8,RecModel9); + + RecModel10 = new AliMUONClusterFinder(); + RecModel10->SetNperMax(90); + // RecModel1->SetClusterSize(9); + RecModel1->SetClusterSize(100); + RecModel10->SetDeclusterFlag(0); + MUON->SetReconstructionModel(9,RecModel10); + + +// +// Loop over events +// + Int_t Nh=0; + Int_t Nh1=0; + for (int nev=0; nev<= evNumber2; nev++) { + Int_t nparticles = gAlice->GetEvent(nev); + cout << "nev " << nev <TreeH(); + Int_t ntracks = TH->GetEntries(); + cout<<"ntracks "<Particles(); + TTree *TD = gAlice->TreeD(); + Int_t nent=TD->GetEntries(); + //printf("Found %d entries in the tree (must be one per cathode per event!)\n",nent); + if (MUON) { + MUON->FindClusters(nev,nent-2); + } // end if MUON + } // event loop + //file->ls(); + file->Close(); +} + diff --git a/MUON/MUONtest.C b/MUON/MUONtest.C index a8c31f1ebba..a1bf962031c 100644 --- a/MUON/MUONtest.C +++ b/MUON/MUONtest.C @@ -1,4 +1,4 @@ -void MUONtest (Int_t evNumber1=0,Int_t evNumber2=0) +void MUONtestabso (Int_t evNumber1=0,Int_t evNumber2=0) { ///////////////////////////////////////////////////////////////////////// // This macro is a small example of a ROOT macro @@ -44,36 +44,15 @@ void MUONtest (Int_t evNumber1=0,Int_t evNumber2=0) // Create some histograms - TH1F *ccharge1 = new TH1F("ccharge1","Cluster Charge distribution" - ,100,0.,500.); - TH1F *pcharge1 = new TH1F("pcharge1","Pad Charge distribution" - ,100,0.,200.); - TH1F *xresid1 = new TH1F("xresid1","x-Residuals" - ,100,-2.0,2.0); - TH1F *yresid1 = new TH1F("yresid1","y-Residuals" - ,100,-0.2,0.2); - TH1F *npads1 = new TH1F("npads1" ,"Pads per Hit" - ,20,-0.5,19.5); - TH2F *xresys1 = new TH2F("xresys1","x-Residuals systematics" - ,50,-0.4,0.4,100,-0.2,0.2); - TH2F *yresys1 = new TH2F("yresys1","y-Residuals systematics" - ,50,-0.4,0.4,100,-0.1,0.1); - - TH1F *ccharge2 = new TH1F("ccharge2","Cluster Charge distribution" - ,100,0.,500.); - TH1F *pcharge2 = new TH1F("pcharge2","Pad Charge distribution" - ,100,0.,200.); - TH1F *xresid2 = new TH1F("xresid2","x-Residuals" - ,100,-2.0,2.0); - TH1F *yresid2 = new TH1F("yresid2","y-Residuals" - ,100,-0.2,0.2); - TH1F *npads2 = new TH1F("npads2" ,"Pads per Hit" - ,20,-0.5,19.5); - TH2F *xresys2 = new TH2F("xresys2","x-Residuals systematics" - ,50,-0.4,0.4,100,-0.2,0.2); - TH2F *yresys2 = new TH2F("yresys2","y-Residuals systematics" - ,50,-0.4,0.4,100,-0.1,0.1); + TH1F *zv = new TH1F("zv","z vertex" + ,100,468.,503.); + TH1F *xv = new TH1F("xv","x vertex" + ,100,0.,50.); + TH1F *yv = new TH1F("yv","y vertex" + ,100,0.,50.); + TH1F *ip = new TH1F("ip","ipart" + ,100,0.,50.); AliMUONchamber* iChamber; // @@ -88,17 +67,13 @@ void MUONtest (Int_t evNumber1=0,Int_t evNumber2=0) if (nev < evNumber1) continue; if (nparticles <= 0) return; - AliMUON *MUON = (AliMUON*) gAlice->GetDetector("MUON"); - printf("\n track %d %d \n ", nev, MUON); + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); + printf("\n nev %d \n ", nev); TTree *TH = gAlice->TreeH(); Int_t ntracks = TH->GetEntries(); - Int_t Nc=0; - Int_t npad[2]; - Float_t Q[2], xmean[2],ymean[2],xres[2],yres[2], xonpad[2], yonpad[2]; - // -// Loop over events +// Loop over tracks // for (Int_t track=0; trackfChamber; // chamber number Float_t x = mHit->fX; // x-pos of hit Float_t y = mHit->fY; // y-pos -// -// - iChamber = & MUON->Chamber(nch-1); - response=iChamber->GetResponseModel(); -// -// - if (nch <= 1) { - for (Int_t i=0; i<2; i++) { - xmean[i]=0; - ymean[i]=0; - Q[i]=0; - npad[i]=0; - } - for (AliMUONcluster *mPad=(AliMUONcluster*)MUON->FirstPad(mHit); - mPad; - mPad=(AliMUONcluster*)MUON->NextPad() - ) - { - Int_t nseg = mPad->fCathode; // segmentation - Int_t nhit = mPad->fHitNumber; // hit number - Int_t qtot = mPad->fQ; // charge - Int_t ipx = mPad->fPadX; // pad number on X - Int_t ipy = mPad->fPadY; // pad number on Y - Int_t iqpad = mPad->fQpad; // charge per pad - Int_t rpad = mPad->fRpad; // r-pos of pad -// -// - segmentation=iChamber->GetSegmentationModel(nseg); - Int_t ind=nseg-1; -// printf("Pad of hit, padx, pady, iqpad, ncha %d %d %d %d %d %d\n", -// nhit, ipx, ipy, iqpad, nseg, ind); + Float_t z = mHit->fZ; // y-pos + + if (nch > 1) continue; + + Int_t ipart = mHit->fParticle; + TClonesArray *fPartArray = gAlice->Particles(); + TParticle *Part; + Int_t ftrack = mHit->fTrack; + Int_t id = ((TParticle*) fPartArray->UncheckedAt(ftrack))->GetPdgCode(); + ip->Fill((float)ipart,(float) 1); + + if (ipart != 3) continue; + Float_t xv = Part->Vx(); // vertex + Float_t yv = Part->Vy(); // vertex + Float_t zv = Part->Vz(); // z vertex + xv->Fill(xv,(float) 1); + yv->Fill(yv,(float) 1); + zv->Fill(zv,(float) 1); + } + + } + } + } - - if (nseg == 1) { - pcharge1->Fill(iqpad,(float) 1); - ccharge1->Fill(qtot ,(float) 1); - } else { - pcharge2->Fill(iqpad,(float) 1); - ccharge2->Fill(qtot ,(float) 1); - } -// Calculate centre of gravity -// - if (iqpad > 0) { - npad[ind]++; - xmean[ind]+=iqpad*segmentation->GetPadx(ipx); - ymean[ind]+=iqpad*segmentation->GetPady(ipy); - Q[ind]+=iqpad; - } - - } //pad hit loop - for (Int_t i=0; i<2; i++) { - segmentation = iChamber->GetSegmentationModel(i+1); - if (Q[i] >0) { - xmean[i] = xmean[i]/Q[i]; - xres[i] = xmean[i]-x; - ymean[i] = ymean[i]/Q[i]; - yres[i] = ymean[i]-y; - -// Systematic Error -// - Int_t icx=segmentation.GetPadix(x); - Int_t icy=segmentation.GetPadiy(y); - xonpad[i]=segmentation.GetPadx(icx)-x; - yonpad[i]=segmentation.GetPady(icy)-y; - } - } // plane loop - xresid1->Fill(xres[0],(float) 1); - yresid1->Fill(yres[0],(float) 1); - npads1->Fill(npad[0],(float) 1); - if (npad[0] >=2 && Q[0] > 6 ) { - xresys1->Fill(xonpad[0],xres[0],(float) 1); - yresys1->Fill(yonpad[0],yres[0],(float) 1); - } - - xresid2->Fill(xres[1],(float) 1); - yresid2->Fill(yres[1],(float) 1); - npads2->Fill(npad[1],(float) 1); - if (npad[1] >=2 && Q[1] > 6) { - xresys2->Fill(xonpad[1],xres[1],(float) 1); - yresys2->Fill(yonpad[1],yres[1],(float) 1); - } - } // chamber 1/2 - } // hit loop - } // if MUON - } // track loop - } // event loop //Create a canvas, set the view range, show histograms TCanvas *c1 = new TCanvas("c1","Charge and Residuals",400,10,600,700); @@ -215,111 +128,23 @@ void MUONtest (Int_t evNumber1=0,Int_t evNumber2=0) pad14->Draw(); pad11->cd(); - ccharge1->SetFillColor(42); - ccharge1->SetXTitle("ADC units"); - ccharge1->Draw(); + ip->SetFillColor(42); + ip->SetXTitle("ipart"); + ip->Draw(); pad12->cd(); - pcharge1->SetFillColor(42); - pcharge1->SetXTitle("ADC units"); - pcharge1->Draw(); + xv->SetFillColor(42); + xv->SetXTitle("xvert"); + xv->Draw(); pad13->cd(); - xresid1->SetFillColor(42); - xresid1->Draw(); + yv->SetFillColor(42); + yv->SetXTitle("yvert"); + yv->Draw(); pad14->cd(); - yresid1->SetFillColor(42); - yresid1->Draw(); - - TCanvas *c2 = new TCanvas("c2","Cluster Size",400,10,600,700); - pad21 = new TPad("pad21"," ",0.01,0.51,0.49,0.99); - pad22 = new TPad("pad22"," ",0.51,0.51,0.99,0.99); - pad23 = new TPad("pad23"," ",0.01,0.01,0.49,0.49); - pad24 = new TPad("pad24"," ",0.51,0.01,0.99,0.49); - pad21->SetFillColor(11); - pad22->SetFillColor(11); - pad23->SetFillColor(11); - pad24->SetFillColor(11); - pad21->Draw(); - pad22->Draw(); - pad23->Draw(); - pad24->Draw(); - - pad21->cd(); - npads1->SetFillColor(42); - npads1->SetXTitle("Cluster Size"); - npads1->Draw(); - - pad23->cd(); - xresys1->SetXTitle("x on pad"); - xresys1->SetYTitle("x-xcog"); - xresys1->Draw(); - - pad24->cd(); - yresys1->SetXTitle("y on pad"); - yresys1->SetYTitle("y-ycog"); - yresys1->Draw(); - - TCanvas *c3 = new TCanvas("c3","Charge and Residuals",400,10,600,700); - pad31 = new TPad("pad31"," ",0.01,0.51,0.49,0.99); - pad32 = new TPad("pad32"," ",0.51,0.51,0.99,0.99); - pad33 = new TPad("pad33"," ",0.01,0.01,0.49,0.49); - pad34 = new TPad("pad34"," ",0.51,0.01,0.99,0.49); - pad31->SetFillColor(11); - pad32->SetFillColor(11); - pad33->SetFillColor(11); - pad34->SetFillColor(11); - pad31->Draw(); - pad32->Draw(); - pad33->Draw(); - pad34->Draw(); - - pad31->cd(); - ccharge2->SetFillColor(42); - ccharge2->SetXTitle("ADC units"); - ccharge2->Draw(); - - pad32->cd(); - pcharge2->SetFillColor(42); - pcharge2->SetXTitle("ADC units"); - pcharge2->Draw(); - - pad33->cd(); - xresid2->SetFillColor(42); - xresid2->Draw(); - - pad34->cd(); - yresid2->SetFillColor(42); - yresid2->Draw(); - - TCanvas *c4 = new TCanvas("c4","Cluster Size",400,10,600,700); - pad41 = new TPad("pad41"," ",0.01,0.51,0.49,0.99); - pad42 = new TPad("pad42"," ",0.51,0.51,0.99,0.99); - pad43 = new TPad("pad43"," ",0.01,0.01,0.49,0.49); - pad44 = new TPad("pad44"," ",0.51,0.01,0.99,0.49); - pad41->SetFillColor(11); - pad42->SetFillColor(11); - pad43->SetFillColor(11); - pad44->SetFillColor(11); - pad41->Draw(); - pad42->Draw(); - pad43->Draw(); - pad44->Draw(); - - pad41->cd(); - npads2->SetFillColor(42); - npads2->SetXTitle("Cluster Size"); - npads2->Draw(); - - pad43->cd(); - xresys2->SetXTitle("x on pad"); - xresys2->SetYTitle("x-xcog"); - xresys2->Draw(); - - pad44->cd(); - yresys2->SetXTitle("y on pad"); - yresys2->SetYTitle("y-ycog"); - yresys2->Draw(); + zv->SetFillColor(42); + zv->SetXTitle("zvert"); + zv->Draw(); } diff --git a/MUON/MUONtestabso.C b/MUON/MUONtestabso.C new file mode 100644 index 00000000000..e8c4fb4f001 --- /dev/null +++ b/MUON/MUONtestabso.C @@ -0,0 +1,159 @@ +void MUONtestabso (Int_t evNumber1=0,Int_t evNumber2=0) +{ +///////////////////////////////////////////////////////////////////////// +// This macro is a small example of a ROOT macro +// illustrating how to read the output of GALICE +// and do some analysis. +// +///////////////////////////////////////////////////////////////////////// + +// Dynamically link some shared libs + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + + + if (!file) { + printf("\n Creating galice.root \n"); + file = new TFile("galice.root"); + } else { + printf("\n galice.root found in file list"); + } + file->ls(); + +// Get AliRun object from file or create it if not on file + if (!gAlice) { + gAlice = (AliRun*)(file->Get("gAlice")); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) { + printf("\n create new gAlice object"); + gAlice = new AliRun("gAlice","Alice test program"); + } + } + + printf ("I'm after gAlice \n"); + +// Create some histograms + + + TH1F *zv = new TH1F("zv","z vertex" + ,100,450..,506.); + TH1F *xv = new TH1F("xv","x vertex" + ,140,-70.,70.); + TH1F *yv = new TH1F("yv","y vertex" + ,140,-70.,70.); + + TH1F *ip = new TH1F("ip","geant part" + ,50,0.,10.); + TH2F *rzv = new TH2F("rzv","R-z vert" + ,100,500.,506.,50,0.,50.); + + AliMUONchamber* iChamber; +// +// Loop over events +// + Int_t Nh=0; + Int_t Nh1=0; + for (Int_t nev=0; nev<= evNumber2; nev++) { + cout << "nev " << nev <GetEvent(nev); + cout << "nparticles " << nparticles <GetModule("MUON"); + printf("\n nev %d \n ", nev); + + TTree *TH = gAlice->TreeH(); + Int_t ntracks = TH->GetEntries(); +// +// Loop over tracks +// + for (Int_t track=0; trackResetHits(); + Int_t nbytes += TH->GetEvent(track); + if (MUON) { + for(AliMUONhit* mHit=(AliMUONhit*)MUON->FirstHit(-1); + mHit; + mHit=(AliMUONhit*)MUON->NextHit()) + { + Int_t nch = mHit->fChamber; // chamber number + Float_t x = mHit->fX; // x-pos of hit + Float_t y = mHit->fY; // y-pos + Float_t z = mHit->fZ; // y-pos + + if (nch > 1) continue; + + Int_t ipart = mHit->fParticle; + TClonesArray *fPartArray = gAlice->Particles(); + TParticle *Part; + Int_t ftrack = mHit->fTrack; + Part = (TParticle*) fPartArray->UncheckedAt(ftrack); + //Int_t id = ((TParticle*) fPartArray->UncheckedAt(ftrack))->GetPdgCode(); + ip->Fill((float)ipart); + + if (ipart > 3) continue; + + Float_t xvert = Part->Vx(); // vertex + Float_t yvert = Part->Vy(); // vertex + Float_t zvert = Part->Vz(); // z vertex + xv->Fill(xvert); + yv->Fill(yvert); + zv->Fill(zvert); + Float_t rvert=TMath::Sqrt(xvert*xvert+yvert*yvert); + rzv->Fill(zvert,rvert); + + } + + } + } + } + + +//Create a canvas, set the view range, show histograms + TCanvas *c1 = new TCanvas("c1","Vetices from electrons and positrons",400,10,600,700); + pad11 = new TPad("pad11"," ",0.01,0.51,0.49,0.99); + pad12 = new TPad("pad12"," ",0.51,0.51,0.99,0.99); + pad13 = new TPad("pad13"," ",0.01,0.01,0.49,0.49); + pad14 = new TPad("pad14"," ",0.51,0.01,0.99,0.49); + pad11->SetFillColor(11); + pad12->SetFillColor(11); + pad13->SetFillColor(11); + pad14->SetFillColor(11); + pad11->Draw(); + pad12->Draw(); + pad13->Draw(); + pad14->Draw(); + + pad11->cd(); + ip->SetFillColor(42); + ip->SetXTitle("ipart"); + ip->Draw(); + + pad12->cd(); + xv->SetFillColor(42); + xv->SetXTitle("xvert"); + xv->Draw(); + + pad13->cd(); + yv->SetFillColor(42); + yv->SetXTitle("yvert"); + yv->Draw(); + + pad14->cd(); + zv->SetFillColor(42); + zv->SetXTitle("zvert"); + zv->Draw(); + + TCanvas *c2 = new TCanvas("c2","R-Z vertex distribution",400,10,600,700); + rzv->SetXTitle("zvert"); + rzv->SetYTitle("rvert"); + rzv->Draw(); +} diff --git a/MUON/MUONtestzaza.C b/MUON/MUONtestzaza.C new file mode 100644 index 00000000000..43d8a29b297 --- /dev/null +++ b/MUON/MUONtestzaza.C @@ -0,0 +1,87 @@ +// option 1 : idres=114 if j/psi +// idres=116 if upsilon + +// option 2 : ireadgeant=1 if geant hits +// ireadgeant=0 if space points + +// option 3 : ibgr=1 if upsilon+background (option 3 usefull only for geant hits) +// ibgr=0 if no background + +void MUONtestzaza (Int_t evNumber1=0, Int_t evNumber2=99, Int_t idres=116, Int_t ireadgeant=1, Int_t ibgr=0) +{ +///////////////////////////////////////////////////////////////////////// +// This macro is a small example of a ROOT macro +// illustrating how to read the output of GALICE +// and do some analysis. +// +///////////////////////////////////////////////////////////////////////// + +// Dynamically link some shared libs + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + + if (!file) { + printf("\n Creating galice.root \n"); + file = new TFile("galice.root"); + } else { printf("\n galice.root found in file list"); + } + // file->ls(); + +// Get AliRun object from file or create it if not on file + if (!gAlice) { + gAlice = (AliRun*)(file->Get("gAlice")); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) { + printf("\n create new gAlice object"); + gAlice = new AliRun("gAlice","Alice test program"); + } + } + + Double_t seff = 0.95; + Double_t sb0 = 0.7; + Double_t sbl3 = 0.2; + + Int_t ifit = 0; + Int_t idebug = 1; + + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); + + Int_t nparticles = gAlice->GetEvent(evNumber1); + if (nparticles <= 0) return; + MUON->Init(seff,sb0,sbl3); +// Loop over events +// + Int_t inev_bgd=0; + Int_t nev_bgd=4; + + for (Int_t nev= evNumber1; nev<= evNumber2; nev++) + { + printf("nev=%d\n",nev); + if (nev != evNumber1) Int_t nparticles = gAlice->GetEvent(nev); + if (nev < evNumber1) continue; + if (nparticles <= 0) return; + MUON->FinishEvent(); + if (ireadgeant==1 && ibgr==1) { + if (inev_bgd==nev_bgd) inev_bgd=0; + MUON->Reconst(ifit,idebug,inev_bgd,nev,idres,ireadgeant,"Add","galice_bgr.root"); + inev_bgd++; + } + else + MUON->Reconst(ifit,idebug,inev_bgd,nev,idres,ireadgeant,"rien1","rien2"); + MUON->FinishEvent(); + + + + } // event loop + + MUON->Close(); +} + + + diff --git a/MUON/Makefile b/MUON/Makefile index 67847728f17..6b50e4ad04e 100644 --- a/MUON/Makefile +++ b/MUON/Makefile @@ -9,8 +9,12 @@ PACKAGE = MUON # C++ sources -SRCS = AliMUON.cxx AliMUONdisplay.cxx AliMUONpoints.cxx \ - AliMUONsegmentv1.cxx AliMUONv0.cxx AliMUONv01.cxx +SRCS = AliMUONchamber.cxx AliMUONSegResV0.cxx AliMUONSegResV01.cxx \ + AliMUONSegResV02.cxx AliMUONSegResV04.cxx AliMUONSegResV05.cxx\ + AliMUONSegResV1.cxx AliMUON.cxx AliMUONv0.cxx \ + AliMUONdisplay.cxx AliMUONpoints.cxx \ + AliMUONClusterFinder.cxx AliMUONClusterFinderv0.cxx \ + AliMUONHitMap.cxx AliMUONTUBE.cxx # C++ Headers @@ -24,7 +28,7 @@ DICTO = $(patsubst %.cxx,tgt_$(ALICE_TARGET)/%.o,$(DICT)) # Fortran sources -FSRCS = algo.F +FSRCS = algo.F reco_muon.F # FORTRAN Objectrs diff --git a/MUON/algo.F b/MUON/algo.F index abbab22e554..9381b6b17e7 100644 --- a/MUON/algo.F +++ b/MUON/algo.F @@ -1388,7 +1388,7 @@ c MC2 x2_2b=ibits(bitpx(4,icircT),31,1) dble2_31=iand(x2_1,ior(x2_2a,x2_2b)) - dblex2(icircT)=dble2_0+2*dble2_1_30+(2.**31)*dble2_31 !dble X on MC2 + dblex2(icircT)=dble2_0+2*dble2_1_30+(2**31)*dble2_31 !dble X on MC2 x2_1=ibits(bitpx(3,icircT),0,32) sgle2A=ieor(x2_1,dblex2(icircT)) @@ -1406,7 +1406,7 @@ c MC2 x2_2b=ibits(dblex2(icircT),31,1) sgle2_31=ior(x2_2a,x2_2b) - sgle2B=sgle2_0+2*sgle2_1_30+(2.**31)*sgle2_31 + sgle2B=sgle2_0+2*sgle2_1_30+(2**31)*sgle2_31 sgle2B=not(sgle2B) sgle2B=iand(sgle2B,bitpx(4,icircT)) diff --git a/MUON/reco_muon.F b/MUON/reco_muon.F new file mode 100644 index 00000000000..cd188f0d775 --- /dev/null +++ b/MUON/reco_muon.F @@ -0,0 +1,5260 @@ +* 25/5/99 +** Authors J.P. Cussonneau & P. Lautridou + +************** commentaires ********************** + +* bon muon = tous les hits de la trace (pas forcement 28) proviennent de muons +* ghost = bonne trace dans laquelle certains hits proviennent délectrons, de muons ou sont ambigus + +* ALPHATOP +* alpha to P + +* EFF +* efficacite + +* HHIT +* h au vertex + +* HTOP +* h to P + +* INDEXMAX +* nombre de candidats a ordonner (a partir de l'ímpulsion) + +* INDEXTAB +* pour recuperer les candidats + +* ISTAT +* =1 si bon muon, =2 si ghost, =0 autrement + +* ITCHECK +* =1 si bonne trace, =0 autrement + +* IT_LIST +* permet a partir du numero de la trace de retrouver la numero du hit + +* IT_NP +* compte le nombre de plans touches par trace + +* ITRACK +* permet de retrouver le numero de la trace a partir du numero de hit + +* ITTROUGH +* pour une trace et une station donnee, dit si la trace est passee dans la chambre + +* IVERTEX +* =0 si point (0,0) du vertex impose, sinon coordonnes libres (pour le fit) + +* JCAN +* numero du hit pour une station et un candidat + +* JCANTYP +* nombre de hits par trace au niveau des stations 4 et 5 (3 ou 4) + +* JJOUT +* numero de hit associe a une chambre et a une trace + +* NMUONALL +* nombre de bons muons trouves + +* NERR +* = nombre de fois ou lón ná pas trouve la bonne trace dans la station + +* NERRALL +* nombre de cas ou pas de hit trouve par station + +* NGHOSTALL +* nombre de fantomes trouves + +* NRES +* nombre de resonances dans lácceptance + +* NRESF +* nombre de resonances trouvees + +* NTRACFALL +* nombre de traces totales trouvees + +* NTRMUALL +* nombre total de muons dans lácceptance + + +**************************************************************** + SUBROUTINE reconstmuon(IFIT,IDEBUGC,NEV,IDRES,IREADGEANT) +**************************************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + COMMON/DEBEVT/IDEBUG + + IDEBUG=IDEBUGC + +** Read events + CALL RECO_READEVT(NEV,IDRES,IREADGEANT) + + +** Trackfinding + CALL RECO_TRACKF(IDRES,IREADGEANT) + +** Precision fit + IF (IFIT.EQ.1) THEN + CALL RECO_PRECISION + ENDIF + +** Calculate + CALL RECO_SUM + + END + +******************************************** + BLOCK DATA +******************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + PARAMETER(NBSTATION=5) +* -- + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) + + DATA DZ_PL/8.,8.,24.3,8.,8./ + +** DATA DZ_PL/8.,8.,8.,8.,8./ +* DATA DZ_PL/20.,20.,20.,20.,20./ +* DATA DZ_PL/20.,20.,24.3,20.,20./ +* DATA DZ_PL/20.,40.,40.,40.,40./ +* DATA DZ_PL/20.,50.,50.,50.,50./ +* DATA DZ_PL/20.,55.,55.,55.,55./ +* DATA DZ_PL/20.,60.,60.,60.,60./ +* DATA DZ_PL/20.,80.,80.,80.,80./ +* DATA DZ_PL/20.,100.,100.,100.,100./ + + DATA ZPLANE/-511.,-686.0,-962.7,-1245.,-1445./ ! dstation=8cm + +* DATA ZPLANE/-507.5,-682.5,-967.5,-1241.5,-1441.5/ ! dstation=20cm CCC +* DATA ZPLANE/-505.,-680.,-965.,-1239.,-1439./ ! dstation=20cm +** DATA ZPLANE/-511.,-686.0,-971.,-1245.,-1445./ ! dstation=8cm +* DATA ZPLANE/-511.,-686.0,-962.7,-1245.,-1445./ ! dstation=8cm +* DATA ZPLANE/-505.,-680.,-962.7,-1239.,-1439./ ! dstation=20cm +* DATA ZPLANE/-505.,-670.,-954.,-1229.,-1429./ ! dstation=40cm +* DATA ZPLANE/-505.,-665.,-949.,-1224.,-1424./ ! dstation=50cm +* DATA ZPLANE/-505.,-663.,-947.,-1222.,-1422./ ! dstation=50cm +* DATA ZPLANE/-505.,-660.,-944.,-1219.,-1419./ ! dstation=60cm +* DATA ZPLANE/-505.,-650.,-935.,-1209.,-1409./ ! dstation=80cm +* DATA ZPLANE/-505.,-640.,-925.,-1199.,-1399./ ! dstation=100cm + +** DATA ZPLANE/-507.,-682.0,-950.7,-1241.,-1441./ + +** DATA ZCOIL,ZMAGEND/-825.0,-1125./ ! Constant field 3 Tm + DATA ZCOIL,ZMAGEND/-805.0,-1233./ ! CCC magn. field map M.B +** DATA ZCOIL,ZMAGEND/-795.1,-1242.9/ ! CCC magn. field map M.B + +* -- + END + +******************************************** + SUBROUTINE cutpxz(spxzcut) +******************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + COMMON/ACUTPXZ/ACUTPXZ + + ACUTPXZ = SPXZCUT + + END + +******************************************** + SUBROUTINE sigmacut(ssigcut) +******************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + COMMON/TRACKFI/EFF,EFF1,EFF2,XPREC,YPREC,PHIPREC,ALAMPREC, + & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP + +** SIGCUT = SSIGCUT + SIGCUT=5. ! CCC + + END + +******************************************** + SUBROUTINE xpreci(sxprec) +******************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + COMMON/TRACKFI/EFF,EFF1,EFF2,XPREC,YPREC,PHIPREC,ALAMPREC, + & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP + +** XPREC = SXPREC + XPREC = 0.01 ! CCC + + END + +******************************************** + SUBROUTINE ypreci(syprec) +******************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + COMMON/TRACKFI/EFF,EFF1,EFF2,XPREC,YPREC,PHIPREC,ALAMPREC, + & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP + + YPREC = SYPREC +** YPREC = 0.2 ! CCC + + END + +************************************************************************* + SUBROUTINE RECO_INIT(seff,sb0,sbl3) +************************************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + CALL TRACKF_INIT(seff,sb0,sbl3) + + CALL PREC_INIT + + RETURN + END + +************************************************************************* + SUBROUTINE TRACKF_INIT(seff,sb0,sbl3) +************************************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +** + PARAMETER(NBSTATION=5,NTRMAX=500) +** + COMMON/REVENT/IEVBKGI,NBKGMAX,MAXUPSEV +** + COMMON/MAGNET/BL3,B0 +** + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) +** + COMMON/FILED/FILERES,FILEBKG,FILEOUT,FILEMIN +** + COMMON/TRACKFI/EFF,EFF1,EFF2,XPREC,YPREC,PHIPREC,ALAMPREC, + & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP +** + COMMON/TRACKSUM/NRES(5),NRESF,NTRMUALL,NMUONALL,NGHOSTALL, + & NTRACKFALL,NERRALL(NBSTATION),IR +** + COMMON/ACUTPXZ/ACUTPXZ +** + COMMON/DEBEVT/IDEBUG +** + CALL HIST_CREATE +* + EFF = SEFF + B0 = SB0 + BL3 = SBL3 + + PXZCUT = ACUTPXZ + AMAGLEN = ZMAGEND-ZCOIL + ZM = AMAGLEN/2.+ZCOIL + ALPHATOP = 0.01*0.3*B0*ABS(AMAGLEN) + HTOP = ALPHATOP*ZM + HCUT = ABS(HTOP)/PXZCUT + + print*,'TRACK_INIT hcut= ',hcut + print*,'TRACK_INIT eff = ',eff + print*,'TRACK_INIT b0 = ',b0 + print*,'TRACK_INIT bl3 = ',bl3 + print*,'TRACK_INIT sigmacut = ',sigcut + print*,'TRACK_INIT cutpxz = ',pxzcut + print*,'TRACK_INIT xprec = ',xprec + print*,'TRACK_INIT yprec = ',yprec + + EFF2 = EFF**2 ! PROBA. DEUX CHAMBRES TOUCHES + EFF1 = EFF2+2.*EFF*(1.-EFF) ! PROBA. AU MOINS UNE CHAMBRE TOUCHE +** Used only for stations 4 & 5 + PHIPREC = SQRT(2.)*XPREC/DZ_PL(5) ! PHI = (OZ , PROJ. DANS XOZ) + ALAMPREC = SQRT(2.)*YPREC/DZ_PL(5) ! LAM = (OM , PROJ. DANS XOZ) + + DO I = 1,5 + NRES(I) = 0 + ENDDO + NRESF = 0 + NTRMUALL = 0 + NMUONALL = 0 + NGHOSTALL = 0 + NTRACKFALL = 0 + DO I = 1,NBSTATION + NERRALL(I) = 0 + ENDDO + IR = 0 +* + RETURN + END + +************************************************************************* + SUBROUTINE PREC_INIT +************************************************************************* +* +* +************************************************************************* + + IMPLICIT DOUBLE PRECISION (A-H, O-Z) +* + PARAMETER(NPLANE=10,NBSTATION=5) +* + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) +* + COMMON/PARAM/ZPLANEP(NPLANE),THICK,XPREC,YPREC,B0,BL3,ZMAGS, + & ZMAGE,ZABS,XMAG,ZBP1,ZBP2,CONST +* + COMMON/PRECCUT/PCUT,PTCUT,CHI2CUT +* + COMMON/PRECSUM/NRESF1,NMUONALL1,NGHOSTALL1,NTRACKFALL1 +* + COMMON/DEBEVT/IDEBUG +* + + DATA THICK/0.03D0/ ! X/X0=3% +** DATA THICK/0.02D0/ ! X/X0=2% chambre + +** DATA B0,BL3/10.,2.0/ ! Champ magnetique dans le dipole et dans L3 en kgauss + DATA B0,BL3/7.,2.0/ ! Magnetic field in the dipole & L3 in kgauss + DATA ZMAGS/805.0D0/,ZMAGE/1233.0D0/,ZABS/503.D0/ ! CCC not used when + ! magn. field map +** DATA ZMAGS/825.0D0/,ZMAGE/1125.0D0/,ZABS/503.D0/ + DATA XMAG/190.0D0/ + +** DATA XPREC/0.0100D0/,YPREC/0.144337D0/ ! CCC + DATA XPREC/0.0100D0/,YPREC/0.2D0/ + +* Input parameters + CONST = 0.299792458D-3*B0*(ZMAGE-ZMAGS) + J = 0 + DO I = 1,5 + J = J+1 + ZPLANEP(J) = -ZPLANE(I) + J = J+1 + ZPLANEP(J) = -ZPLANE(I)+DZ_PL(I) + ENDDO + + PCUT = 3. ! Coupure en PXZ muon (GeV/c) + PTCUT = 0. ! Coupure en Pt muon (GeV/c) + + CHI2CUT = 1.E4 ! Coupure sur le CHI2 du fit + + X01 = 18.8 ! C (cm) + X02 = 10.397 ! Concrete (cm) + X03 = 0.56 ! Plomb (cm) + X04 = 47.26 ! Polyethylene (cm) + X05 = 0.35 ! W (cm) + +** Calcul des parametres pour la correction de Branson de l'absorbeur + ANBP = (315.**3-90.**3)/X01 +(467.**3-315.**3)/X02+ + & (472.**3-467.**3)/X03+(477.**3-472.**3)/X04+ + & (482.**3-477.**3)/X03+(487.**3-482.**3)/X04+ + & (492.**3-487.**3)/X03+(497.**3-492.**3)/X04+ + & (502.**3-497.**3)/X03 + ADBP = (315.**2-90.**2)/X01 +(467.**2-315.**2)/X02+ + & (472.**2-467.**2)/X03+(477.**2-472.**2)/X04+ + & (482.**2-477.**2)/X03+(487.**2-482.**2)/X04+ + & (492.**2-487.**2)/X03+(497.**2-492.**2)/X04+ + & (502.**2-497.**2)/X03 + ZBP1 = 2./3.*ANBP/ADBP + ANBP = (315.**3-90.**3)/X01 +(467.**3-315.**3)/X02+ + & (503.**3-467.**3)/X05 + ADBP = (315.**2-90.**2)/X01 +(467.**2-315.**2)/X02+ + & (503.**2-467.**2)/X05 + ZBP2 = 2./3.*ANBP/ADBP +* + IF (IDEBUG.GE.1) THEN + PRINT *,' PREC_INIT B0 (kgauss)',B0,' BL3 (kgauss)',BL3 + PRINT *,' PREC_INIT ZMAGE (cm)',ZMAGE,' ZMAGS (cm)',ZMAGS, + & ' XMAG (cm)',XMAG + PRINT *,' PREC_INIT ZABS (cm)',ZABS,' ZBP1 (cm)',ZBP1, + & ' ZBP2 (cm)',ZBP2 + PRINT *,' PREC_INIT Radiation length absorber X01 (cm)',X01, + & ' X02 (cm)',X02 + PRINT *,' PREC_INIT X03(cm)',X03,' X04 (cm)',X04,' X05 (cm)', + & X05 + PRINT *,' PREC_INIT Radiation length chamber THICK (%)', + & THICK*100. + PRINT *,' PREC_INIT XPREC (cm)',XPREC,' YPREC (cm)',YPREC + PRINT *,' PREC_INIT Coupure en Pxz (GeV/c): ',PCUT + PRINT *,' PREC_INIT Coupure en Pt (GeV/c): ',PTCUT + PRINT *,' PREC_INIT Coupure en CHI2 : ',CHI2CUT + ENDIF + +* PAUSE + + NRESF1 = 0 + NMUONALL1 = 0 + NGHOSTALL1 = 0 + NTRACKFALL1 = 0 + +* Magnetic Field Map GC +** OPEN (UNIT=40,FILE='data/field02.dat', +** & STATUS='UNKNOWN') + + CALL INITFIELD + +** CLOSE(40) + + RETURN + END + +************************************************************************* + SUBROUTINE RECO_READEVT(NEV,IDRES,IREADGEANT) +************************************************************************* +* +* +************************************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER(NTRMAX=500) + + PARAMETER (NBSTATION=5,MAXIDG=20000,MAXHITTOT=20000, + & MAXHITCH=10000,MAXHIT=1000,NBCHAMBER=10) + + COMMON/RHITG/ITYPG(MAXIDG),XTRG(MAXIDG),YTRG(MAXIDG), + & PTOTG(MAXIDG),IDG(MAXIDG),IZCH(MAXIDG), + & PVERT1G(MAXIDG),PVERT2G(MAXIDG),PVERT3G(MAXIDG), + & ZVERTG(MAXIDG),NHITTOT1,CX(MAXIDG),CY(MAXIDG),CZ(MAXIDG), + & XGEANT(MAXIDG),YGEANT(MAXIDG),CLSIZE1(MAXIDG),CLSIZE2(MAXIDG) + + DIMENSION TYPG(MAXIDG),ZCH(MAXIDG) + + REAL*4 R1,R2 + DATA R1,R2/0.,1./ + + IF (IREADGEANT.eq.1) THEN ! GEANT hits + + CALL TRACKF_READ_GEANT(ITYPG,XTRG,YTRG,PTOTG,IDG,IZCH,PVERT1G, + & PVERT2G,PVERT3G,ZVERTG,NHITTOT1,CX,CY,CZ,IEVR,NEV, + & XGEANT,YGEANT,CLSIZE1,CLSIZE2) + ELSE + CALL TRACKF_READ_SPOINT(ITYPG,XTRG,YTRG,PTOTG,IDG,IZCH,PVERT1G, + & PVERT2G,PVERT3G,ZVERTG,NHITTOT1,CX,CY,CZ,IEVR,NEV, + & XGEANT,YGEANT,CLSIZE1,CLSIZE2) + ENDIF + + do i=1,NHITTOT1 + TYPG(i)=ITYPG(i) + call chfill(100,sngl(typg(i)),R1,R2) + call chfill(101,sngl(ygeant(i)),R1,R2) + call chfill(102,sngl(xgeant(i)),R1,R2) + ZCH(i)=IZCH(i) + call chfill(103,sngl(zch(i)),R1,R2) + call chfill(104,sngl(ptotg(i)),R1,R2) + call chfill(105,sngl(pvert2g(i)),R1,R2) + call chfill(106,sngl(pvert1g(i)),R1,R2) + call chfill(107,sngl(pvert3g(i)),R1,R2) + call chfill(108,sngl(zvertg(i)),R1,R2) + call chfill(109,sngl(ytrg(i)),R1,R2) + call chfill(110,sngl(xtrg(i)),R1,R2) + dx=xgeant(i)-xtrg(i) + dy=ygeant(i)-ytrg(i) + call chfill(111,sngl(dy),R1,R2) + call chfill(112,sngl(dx),R1,R2) + call chfill(119+int(zch(i)),sngl(dy),R1,R2) + call chfill(129+int(zch(i)),sngl(dx),R1,R2) + enddo + + do i=1,NHITTOT1 + CALL CHFILL (999,SNGL(PTOTG(I)),R1,R2) + enddo + + CALL TRACKF_STAT(IDRES,IREADGEANT) + + RETURN + END + +************************************************************************* + SUBROUTINE TRACKF_STAT(IDRES,IREADGEANT) +************************************************************************* +* Associate hits between two chambers inside a station +* Simulate spatial resolution and chamber efficiency +* +************************************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +* + PARAMETER (NBSTATION=5,MAXIDG=20000,MAXHITTOT=20000, + & MAXHITCH=10000,MAXHIT=1000,NBCHAMBER=10) +* + COMMON/TRACKFI/EFF,EFF1,EFF2,XPREC,YPREC,PHIPREC,ALAMPREC, + & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP +* + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) +* +* HITS GEANT initiaux par chambre + COMMON/RHITG/ITYPG(MAXIDG),XTRG(MAXIDG),YTRG(MAXIDG), + & PTOTG(MAXIDG),IDG(MAXIDG),IZCH(MAXIDG), + & PVERT1G(MAXIDG),PVERT2G(MAXIDG),PVERT3G(MAXIDG), + & ZVERTG(MAXIDG),NHITTOT1,CX(MAXIDG),CY(MAXIDG),CZ(MAXIDG), + & XGEANT(MAXIDG),YGEANT(MAXIDG),CLSIZE1(MAXIDG),CLSIZE2(MAXIDG) + +* HITS GEANT associes par station + COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), + & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), + & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), + & ZVERT(MAXHITTOT),NHITTOT + +* + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) +* + COMMON/DEBEVT/IDEBUG +* + DIMENSION RMIN(NBCHAMBER),RMAX1(NBCHAMBER) + DIMENSION XMA(NBCHAMBER,MAXHITCH),YMA(NBCHAMBER,MAXHITCH), + & IMARK(NBCHAMBER,MAXHITCH) +* + DIMENSION IEFFI(MAXHITTOT) + DIMENSION IH(NBCHAMBER,MAXHIT) + DIMENSION NHIT(NBCHAMBER) + DIMENSION DXMAX(NBSTATION),DYMAX(NBSTATION),VRES(2,5) + + REAL*4 RNDM,RN,RN1,RN2,R1,R2 + +* Chambre 10 deg. + DATA RMAX1/91.5,91.5,122.5,122.5,158.3,158.3,260.,260.,260.,260./ +* Zone de recherche entre deux plans d'une station +** DATA DXMAX/2.,1.5,2.5,3.,3./ + DATA DXMAX/1.5,1.5,3.,6.,6./ ! J psi 20cm +** DATA DXMAX/1.,1.,1.,1.,1./ ! Upsilon dz_ch = 8 cm +** DATA DYMAX/0.22,0.22,0.21,0.21,0.21/ ! CCC Upsilon dz_ch = 8cm +** DATA DXMAX/1.,1.,1.5,2.,2./ ! Upsilon dz_ch = 20 cm + DATA DYMAX/0.22,0.22,0.22,0.22,0.22/ ! CCC Upsilon dz_ch = 20 cm +** DATA DXMAX/5.,5.,5.,5.,5./ +** DATA DXMAX/10.,10.,10.,10.,10./ + DATA R1,R2/0.,1./ + + ICH = 0 + DO IZ=1,5 + ICH = ICH+1 + RMIN(ICH) = ABS(ZPLANE(IZ)*TAN(2.*ACOS(-1.)/180)) + IF (IZ.GT.2) RMIN(ICH) = 30. + ICH = ICH+1 + RMIN(ICH) = ABS(ZPLANE(IZ)*TAN(2.*ACOS(-1.)/180)) + IF (IZ.GT.2) RMIN(ICH) = 30. + ENDDO + +* Initialisations + DO ICH = 1,10 + NHIT(ICH) = 0 + ENDDO + +* 1 ere boucle Lecture des hits initiaux + + print*,'TRACKF_STAT NHITTOT1=',NHITTOT1 + + IF (IREADGEANT.EQ.1) THEN + DO I = 1,2 + DO J = 1,5 + VRES(I,J) = 0. + ENDDO + ENDDO + IMU = 0 + DO I = 1,NHITTOT1 + ICH = IZCH(I) + IF (ICH.EQ.9) THEN + ISTAK = IDG(I) + ISTAK = MOD(ISTAK,30000) + ISTAK = MOD(ISTAK,10000) + + IF ((ITYPG(I).EQ.5.OR.ITYPG(I).EQ.6).AND. + & ISTAK.EQ.IDRES) THEN ! upsilon + IMU = IMU+1 + VRES(1,IMU) = XGEANT(I) + VRES(2,IMU) = YGEANT(I) + ENDIF + ENDIF + ENDDO + ENDIF + + + DO I = 1,NHITTOT1 ! Boucle sur les hits GEANT de toutes les ch. + +** IF (ITYPG(I).NE.5.AND.ITYPG(I).NE.6) GOTO 1 ! CCC + + ICH = IZCH(I) + + IF (IREADGEANT.EQ.1) THEN ! GEANT hits + + IF (ICH.EQ.9.OR.ICH.EQ.10) THEN + DNUM = 999. + DO IM = 1,IMU + DNU = SQRT((XGEANT(I)-VRES(1,IM))**2+ + & (YGEANT(I)-VRES(2,IM))**2) + IF (DNU.LT.DNUM) DNUM = DNU + ENDDO + IF (DNUM.GT.20.) GO TO 1 + ENDIF + + CALL RANNOR(RN1,RN2) ! CCCC + X = XGEANT(I) + RN1 * XPREC + Y = YGEANT(I) + RN2 * YPREC +* efficacite des chambres + IEFFI(I) = 1 + RN = RNDM() + IF (RN.GT.EFF) IEFFI(I) = 0 + + + ELSE ! reconstructed hits + + IEFFI(I) = 1 + + X = XTRG(I) + Y = YTRG(I) + + ENDIF + + R = SQRT(X**2+Y**2) + IF (R.LT.RMIN(ICH).OR.R.GT.RMAX1(ICH)) then + if (ich.le.10.and.i.le.28) then + print*,'* chambre ',ich,' * hit ',i + print*,'ityp=',itypg(i) + print*,'x=',X,' y=',Y + print*,'R=',R,' RMIN=',RMIN(ICH),' RMAX1=',RMAX1(ICH) + endif + GO TO 1 + end if + + NHIT(ICH) = NHIT(ICH)+1 + IH(ICH,NHIT(ICH)) = I + XMA(ICH,NHIT(ICH)) = X + YMA(ICH,NHIT(ICH)) = Y + IMARK(ICH,NHIT(ICH)) = 0 + + 1 CONTINUE + ENDDO + +* Association des hits entre chambres d'une station + II = 0 ! nombre de hits GEANT par station + DO ICH1 = 1,10,2 + IZ = INT(FLOAT(ICH1+1)/2.) + JHIT(IZ) = 0 + ICH2 = ICH1+1 + + DO I1 = 1,NHIT(ICH1) + II = II+1 + IFIND = 0 + I = IH(ICH1,I1) + + ITYP(II) = ITYPG(I) + XTR(II) = XTRG(I) + YTR(II) = YTRG(I) + PTOT(II) = PTOTG(I) + ID(II) = IDG(I) + IZST(II) = IZ + PVERT1(II) = PVERT1G(I) + PVERT2(II) = PVERT2G(I) + PVERT3(II) = PVERT3G(I) + ZVERT(II) = ZVERTG(I) + + IF (IEFFI(I).EQ.1) THEN + X1 = XMA(ICH1,I1) + Y1 = YMA(ICH1,I1) + ID1 = IDG(I) + XEXT1 = (ZPLANE(IZ)-DZ_PL(IZ))/ZPLANE(IZ)*X1 + YEXT1 = (ZPLANE(IZ)-DZ_PL(IZ))/ZPLANE(IZ)*Y1 + + DO I2 = 1,NHIT(ICH2) + J = IH(ICH2,I2) + + IF (IEFFI(J).EQ.1) THEN + X2 = XMA(ICH2,I2) + Y2 = YMA(ICH2,I2) + ID2 = IDG(J) + DX = X2-XEXT1 + DY = Y2-YEXT1 + + IF (ID1.EQ.ID2.AND. + & (ITYP(II).EQ.5.OR.ITYP(II).EQ.6)) THEN + CALL CHFILL(70+IZ,SNGL(DX),R1,R2) + CALL CHFILL(80+IZ,SNGL(DY),R1,R2) + ENDIF + DX = ABS(DX) + DY = ABS(DY) + + IF (DX.LT.DXMAX(IZ).AND.DY.LT.(SIGCUT*DYMAX(IZ)) ! CCC + & ) THEN + IFIND = 1 + IMARK(ICH2,I2) = 1 + JHIT(IZ) = JHIT(IZ)+1 + XM(IZ,JHIT(IZ)) = X1 + YM(IZ,JHIT(IZ)) = Y1 + IZM(IZ,JHIT(IZ)) = 1 + PHM(IZ,JHIT(IZ)) = -ATAN((X2-X1)/DZ_PL(IZ)) + ALM(IZ,JHIT(IZ)) = ATAN((Y2-Y1)/DZ_PL(IZ)* + & COS(PHM(IZ,JHIT(IZ)))) + XMR(IZ,JHIT(IZ),1) = X1 + YMR(IZ,JHIT(IZ),1) = Y1 + XMR(IZ,JHIT(IZ),2) = X2 + YMR(IZ,JHIT(IZ),2) = Y2 + + ISTAK = ID2 + ISTAK = MOD(ISTAK,30000) + ISTAK = MOD(ISTAK,10000) + + IF ((ITYPG(J).EQ.5.OR.ITYPG(J).EQ.6).AND. + & ISTAK.EQ.IDRES) THEN ! upsilon + + ITYP(II) = ITYPG(J) + XTR(II) = XTRG(J) + YTR(II) = YTRG(J) + PTOT(II) = PTOTG(J) + ID(II) = IDG(J) + PVERT1(II) = PVERT1G(J) + PVERT2(II) = PVERT2G(J) + PVERT3(II) = PVERT3G(J) + ZVERT(II) = ZVERTG(J) + + ENDIF + + IP(IZ,JHIT(IZ)) = II + + ENDIF + ENDIF + ENDDO + + IF (IFIND.EQ.0) THEN + JHIT(IZ) = JHIT(IZ)+1 + XM(IZ,JHIT(IZ)) = X1 + YM(IZ,JHIT(IZ)) = Y1 + IZM(IZ,JHIT(IZ)) = 1 + IP(IZ,JHIT(IZ)) = II + PHM(IZ,JHIT(IZ)) = 10. + ALM(IZ,JHIT(IZ)) = 10. + XMR(IZ,JHIT(IZ),1) = X1 + YMR(IZ,JHIT(IZ),1) = Y1 + XMR(IZ,JHIT(IZ),2) = 0. + YMR(IZ,JHIT(IZ),2) = 0. + ENDIF + CALL CHFILL2(1000+IZ,SNGL(X1),SNGL(Y1),R2) + ENDIF + ENDDO + ENDDO + +* On conserve les HITS de la 2nde chambre des stations + + DO ICH = 2,10,2 + IZ = INT(FLOAT(ICH+1)/2.) + DO I = 1,NHIT(ICH) + J = IH(ICH,I) + + IF (IMARK(ICH,I).EQ.0) THEN + + II = II+1 + + ITYP(II) = ITYPG(J) + XTR(II) = XTRG(J) + YTR(II) = YTRG(J) + PTOT(II) = PTOTG(J) + ID(II) = IDG(J) + IZST(II) = IZ + PVERT1(II) = PVERT1G(J) + PVERT2(II) = PVERT2G(J) + PVERT3(II) = PVERT3G(J) + ZVERT(II) = ZVERTG(I) + + IF (IEFFI(J).EQ.1) THEN + JHIT(IZ) = JHIT(IZ)+1 + XM(IZ,JHIT(IZ)) = XMA(ICH,I) + YM(IZ,JHIT(IZ)) = YMA(ICH,I) + IZM(IZ,JHIT(IZ)) = 2 + PHM(IZ,JHIT(IZ)) = 10. + ALM(IZ,JHIT(IZ)) = 10. + IP(IZ,JHIT(IZ)) = II + XMR(IZ,JHIT(IZ),1) = 1000. + YMR(IZ,JHIT(IZ),1) = 1000. + XMR(IZ,JHIT(IZ),2) = XMA(ICH,I) + YMR(IZ,JHIT(IZ),2) = YMA(ICH,I) + ENDIF + ENDIF + ENDDO + ENDDO + + + NHITTOT = II +* + + IF (IDEBUG.GE.2) THEN + PRINT *,'TRACKF_STAT nb hits:',NHITTOT + ENDIF + +** DO IZ = 1,NBSTATION +** PRINT *,' IZ=',IZ,' JHIT(IZ)=',JHIT(IZ) +** DO J = 1,JHIT(IZ) +** II = IP(IZ,J) +** print*,'II=',II +** PRINT *,' ID(II)=',ID(II) +** ENDDO +** ENDDO + +** DO IZ = 1,NBSTATION +** PRINT *,' IZ=',IZ,' JHIT(IZ)=',JHIT(IZ) +** DO J = 1,JHIT(IZ) +** PRINT *,' PHM(IZ,J)=',PHM(IZ,J),' ALM(IZ,J)=',ALM(IZ,J) +** ENDDO +** ENDDO + + RETURN + END +************************************************************************* + SUBROUTINE TRACKF_STAT_NEW(IDRES) +************************************************************************* +* Associate hits between two chambers inside a station +* Simulate spatial resolution and chamber efficiency +* +************************************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +* + PARAMETER (NBSTATION=5,MAXIDG=20000,MAXHITTOT=20000, + & MAXHITCH=10000,MAXHIT=1000,NBCHAMBER=10) +* + COMMON/TRACKFI/EFF,EFF1,EFF2,XPREC,YPREC,PHIPREC,ALAMPREC, + & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP +* + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) +* +* HITS GEANT initiaux par chambre + COMMON/RHITG/ITYPG(MAXIDG),XTRG(MAXIDG),YTRG(MAXIDG), + & PTOTG(MAXIDG),IDG(MAXIDG),IZCH(MAXIDG), + & PVERT1G(MAXIDG),PVERT2G(MAXIDG),PVERT3G(MAXIDG), + & ZVERTG(MAXIDG),NHITTOT1,CX(MAXIDG),CY(MAXIDG),CZ(MAXIDG), + & XGEANT(MAXIDG),YGEANT(MAXIDG),CLSIZE1(MAXIDG),CLSIZE2(MAXIDG) + +* HITS GEANT associes par station + COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), + & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), + & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), + & ZVERT(MAXHITTOT),NHITTOT + +* + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) +* + COMMON/DEBEVT/IDEBUG +* + DIMENSION RMIN(NBCHAMBER),RMAX1(NBCHAMBER) + DIMENSION XMA(NBCHAMBER,MAXHITCH),YMA(NBCHAMBER,MAXHITCH), + & IMARK(NBCHAMBER,MAXHITCH) +* + DIMENSION IEFFI(MAXHITTOT) + DIMENSION IH(NBCHAMBER,MAXHIT) + DIMENSION NHIT(NBCHAMBER) + DIMENSION DXMAX(NBSTATION),DYMAX(NBSTATION),I2C(1000) + + DIMENSION DIST(2),NMUON(2),NHITMUON(2,5),NMUONGOOD(2) + + REAL*4 RNDM,RN,RN1,RN2,R1,R2 + +* Chambre 10 deg. + DATA RMAX1/91.5,91.5,122.5,122.5,158.3,158.3,260.,260.,260.,260./ +* Zone de recherche entre deux plans d'une station +** DATA DXMAX/2.,1.5,2.5,3.,3./ + DATA DXMAX/1.5,1.5,3.,3.,3./ + DATA DYMAX/0.22,0.22,0.21,0.21,0.21/ + DATA R1,R2/0.,1./ + + ICH = 0 + DO IZ=1,5 + ICH = ICH+1 + RMIN(ICH) = ABS(ZPLANE(IZ)*TAN(2.*ACOS(-1.)/180)) + IF (IZ.GT.2) RMIN(ICH) = 30. + ICH = ICH+1 + RMIN(ICH) = ABS(ZPLANE(IZ)*TAN(2.*ACOS(-1.)/180)) + IF (IZ.GT.2) RMIN(ICH) = 30. + ENDDO + +* Initialisations + DO ICH = 1,10 + NHIT(ICH) = 0 + ENDDO + + DO NCH = 1,10 + DO J=1,2 + DIST(J)=999. + NMUON(J)=0 + ENDDO + DO I = 1,NHITTOT1 + IF (IZCH(I).EQ.NCH) THEN + ISTAK = IDG(I) + ISTAK = MOD(ISTAK,30000) + ISTAK = MOD(ISTAK,10000) + IF (ISTAK.EQ.IDRES.AND.IDG(I).EQ.50116) THEN + DISTMIN=(XTRG(I)-XGEANT(I))**2+(YTRG(I)-YGEANT(I))**2 + IF (DISTMIN.LT.DIST(1)) THEN + DIST(1)=DISTMIN + NMUONGOOD(1)=I + ENDIF + NMUON(1)=NMUON(1)+1 + NHITMUON(1,NMUON(1))=I + ELSE + IF (ISTAK.EQ.IDRES.AND.IDG(I).EQ.70116) THEN + DISTMIN=(XTRG(I)-XGEANT(I))**2+(YTRG(I)-YGEANT(I))**2 + IF (DISTMIN.LT.DIST(2)) THEN + DIST(2)=DISTMIN + NMUONGOOD(2)=I + ENDIF + NMUON(2)=NMUON(2)+1 + NHITMUON(2,NMUON(2))=I + ENDIF + ENDIF + ENDIF + ENDDO + DO J=1,2 + IF (NMUON(J).GE.2) THEN + print*,'j=',j,' nmuon=',nmuon(j) + print*,'chambre',nch + DO K=1,NMUON(J) + IF (NHITMUON(J,K).NE.NMUONGOOD(J)) IDG(NHITMUON(J,K))=999 ! flag les mauvais hits MUONS + ENDDO + ENDIF + ENDDO + ENDDO + + +* 1 ere boucle Lecture des hits initiaux + + DO I = 1,NHITTOT1 ! Boucle sur les hits GEANT de toutes les ch. + + ICH = IZCH(I) + + X = XTRG(I) + Y = YTRG(I) + + R = SQRT(X**2+Y**2) + IF (R.LT.RMIN(ICH).OR.R.GT.RMAX1(ICH)) then + if (ich.le.10.and.i.le.28) then + print*,'****** chambre ',ich,' ****** hit ',i + print*,'ityp=',itypg(i) + print*,'x=',XTRG(I),' y=',YTRG(I) + print*,'R=',R,' RMIN=',RMIN(ICH),' RMAX1=',RMAX1(ICH) + endif + GO TO 1 + end if + + IEFFI(I) = 1 + + NHIT(ICH) = NHIT(ICH)+1 + IH(ICH,NHIT(ICH)) = I + XMA(ICH,NHIT(ICH)) = XTRG(I) + YMA(ICH,NHIT(ICH)) = YTRG(I) + IMARK(ICH,NHIT(ICH)) = 0 + + print*,' XTRG(I)=', XTRG(I),' YTRG(I)=', YTRG(I),' IDG(I)=', + & IDG(I),' ICH=',ICH + + 1 CONTINUE + ENDDO + + +* Association des hits entre chambres d'une station + II = 0 ! nombre de hits GEANT par station + DO ICH1 = 1,10,2 + IZ = INT(FLOAT(ICH1+1)/2.) + JHIT(IZ) = 0 + ICH2 = ICH1+1 + + DO I1 = 1,NHIT(ICH1) + II = II+1 + IFIND = 0 + I = IH(ICH1,I1) + + ITYP(II) = ITYPG(I) + XTR(II) = XTRG(I) + YTR(II) = YTRG(I) + PTOT(II) = PTOTG(I) + ID(II) = IDG(I) + IZST(II) = IZ + PVERT1(II) = PVERT1G(I) + PVERT2(II) = PVERT2G(I) + PVERT3(II) = PVERT3G(I) + ZVERT(II) = ZVERTG(I) + + IF (IEFFI(I).EQ.1) THEN + X1 = XMA(ICH1,I1) + Y1 = YMA(ICH1,I1) + ID1 = IDG(I) + XEXT1 = (ZPLANE(IZ)-DZ_PL(IZ))/ZPLANE(IZ)*X1 + YEXT1 = (ZPLANE(IZ)-DZ_PL(IZ))/ZPLANE(IZ)*Y1 + KC = 0 + PRINT *,'***** DEBUT RECHERCHE',' ID1=',ID1,' ich1=',ICH1 + PRINT *,' XTR(II)=', XTR(II),' YTR(II)=', YTR(II) + PRINT *,' ITYP(II)=', ITYP(II) + DO I2 = 1,NHIT(ICH2) + J = IH(ICH2,I2) + IF (IEFFI(J).EQ.1) THEN + X2 = XMA(ICH2,I2) + DX = X2-XEXT1 + DX = ABS(DX) + IF (DX.LT.DXMAX(IZ)) THEN + KC = KC + 1 + I2C(KC) = I2 + ID2 = IDG(J) + print *,' DX=',DX,' KC=',KC,' ID2=',ID2 + ENDIF + ENDIF + ENDDO + DYOLD = 999. + I2FIND = 0 + DO IKC = 1,KC + I2 = I2C(IKC) + Y2 = YMA(ICH2,I2) + DY = Y2-YEXT1 + DY = ABS(DY) + J = IH(ICH2,I2) + ID2 = IDG(J) + IF (DY.LT.DYOLD.AND.DY.LT.(SIGCUT*DYMAX(IZ))) THEN + DYOLD = DY + I2FIND = I2 + PRINT *,' ID2=',ID2,' DY=',DY + ENDIF + ENDDO + IF (I2FIND.GT.0) THEN + I2 = I2FIND + J = IH(ICH2,I2) + ID2 = IDG(J) + IFIND = 1 + IMARK(ICH2,I2) = 1 + JHIT(IZ) = JHIT(IZ)+1 + X2 = XMA(ICH2,I2) + Y2 = YMA(ICH2,I2) + XM(IZ,JHIT(IZ)) = X1 + YM(IZ,JHIT(IZ)) = Y1 + IZM(IZ,JHIT(IZ)) = 1 + PHM(IZ,JHIT(IZ)) = -ATAN((X2-X1)/DZ_PL(IZ)) + ALM(IZ,JHIT(IZ)) = ATAN((Y2-Y1)/DZ_PL(IZ)* + & COS(PHM(IZ,JHIT(IZ)))) + XMR(IZ,JHIT(IZ),1) = X1 + YMR(IZ,JHIT(IZ),1) = Y1 + XMR(IZ,JHIT(IZ),2) = X2 + YMR(IZ,JHIT(IZ),2) = Y2 + IP(IZ,JHIT(IZ)) = II + + ISTAK = ID2 + ISTAK = MOD(ISTAK,30000) + ISTAK = MOD(ISTAK,10000) +* test + IF (ISTAK.EQ.IDRES.AND.ID1.NE.999) THEN + + ITYP(II) = ITYPG(J) + PTOT(II) = PTOTG(J) + XTR(II) = XTRG(I) + YTR(II) = YTRG(I) + ID(II) = IDG(J) + PVERT1(II) = PVERT1G(J) + PVERT2(II) = PVERT2G(J) + PVERT3(II) = PVERT3G(J) + ZVERT(II) = ZVERTG(J) + + ENDIF + ENDIF + + + + IF (IFIND.EQ.0) THEN + JHIT(IZ) = JHIT(IZ)+1 + XM(IZ,JHIT(IZ)) = X1 + YM(IZ,JHIT(IZ)) = Y1 + IZM(IZ,JHIT(IZ)) = 1 + IP(IZ,JHIT(IZ)) = II + PHM(IZ,JHIT(IZ)) = 10. + ALM(IZ,JHIT(IZ)) = 10. + XMR(IZ,JHIT(IZ),1) = X1 + YMR(IZ,JHIT(IZ),1) = Y1 + XMR(IZ,JHIT(IZ),2) = 0. + YMR(IZ,JHIT(IZ),2) = 0. + ENDIF + CALL CHFILL2(1000+IZ,SNGL(X1),SNGL(Y1),R2) + ENDIF + ENDDO + ENDDO + +* On conserve les HITS de la 2nde chambre des stations + + DO ICH = 2,10,2 + IZ = INT(FLOAT(ICH+1)/2.) + DO I = 1,NHIT(ICH) + J = IH(ICH,I) + + IF (IMARK(ICH,I).EQ.0) THEN +** print *,' ich=',ich,' i=',i,' j=',j + + II = II+1 + + ITYP(II) = ITYPG(J) + XTR(II) = XTRG(J) + YTR(II) = YTRG(J) + PTOT(II) = PTOTG(J) + ID(II) = IDG(J) + IZST(II) = IZ + PVERT1(II) = PVERT1G(J) + PVERT2(II) = PVERT2G(J) + PVERT3(II) = PVERT3G(J) + ZVERT(II) = ZVERTG(I) + + IF (IEFFI(J).EQ.1) THEN + JHIT(IZ) = JHIT(IZ)+1 +** XM(IZ,JHIT(IZ)) = ZPLANE(IZ)/(ZPLANE(IZ)-DZ_PL) +** & *XMA(ICH,I) +** YM(IZ,JHIT(IZ)) = ZPLANE(IZ)/(ZPLANE(IZ)-DZ_PL) +** & *YMA(ICH,I) + XM(IZ,JHIT(IZ)) = XMA(ICH,I) + YM(IZ,JHIT(IZ)) = YMA(ICH,I) + IZM(IZ,JHIT(IZ)) = 2 + PHM(IZ,JHIT(IZ)) = 10. + ALM(IZ,JHIT(IZ)) = 10. + IP(IZ,JHIT(IZ)) = II + XMR(IZ,JHIT(IZ),1) = 1000. + YMR(IZ,JHIT(IZ),1) = 1000. + XMR(IZ,JHIT(IZ),2) = XMA(ICH,I) + YMR(IZ,JHIT(IZ),2) = YMA(ICH,I) + ENDIF + ENDIF + ENDDO + ENDDO + + + NHITTOT = II +* + IF (IDEBUG.GE.2) THEN + PRINT *,'TRACKF_MICRO nb hits:',NHITTOT + ENDIF + DO IZ = 1,NBSTATION + PRINT *,' IZ=',IZ,' JHIT(IZ)=',JHIT(IZ) + DO J = 1,JHIT(IZ) + II = IP(IZ,J) + PRINT *,' ID(II)=',ID(II) + PRINT *,' XMR(IZ,J,1)=', XMR(IZ,J,1), + & ' YMR(IZ,J,1)=', YMR(IZ,J,1) + PRINT *,' XMR(IZ,J,2)=', XMR(IZ,J,2), + & ' YMR(IZ,J,2)=', YMR(IZ,J,2) + ENDDO + ENDDO + + RETURN + END + +************************************************************************* + SUBROUTINE RECO_TRACKF(IDRES,IREADGEANT) +************************************************************************* +* +* +************************************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +* + PARAMETER (MAXIDG=20000) +* + PARAMETER (MAXHITCH=10000,MAXTRK=50000,MAXHITTOT=20000, + & NBSTATION=5,MAXCAN=1000,NBCHAMBER=10,NTRMAX=500) +* + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) +* + COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), + & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), + & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), + & ZVERT(MAXHITTOT),NHITTOT + +* + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) +* + COMMON/VERIFGEANT/ITTROUGH(MAXTRK,NBSTATION), + & IT_LIST(MAXTRK),IT_NP(MAXTRK),ITCHECK(MAXTRK), + & ITRACK(MAXHITTOT) +* + COMMON/HCHHIT/HHIT(MAXHITCH),INDEXTAB(MAXHITCH),INDEXMAX +* + COMMON/PRECIS/EEXM(NBSTATION),EEYM(NBSTATION),EEPH(NBSTATION), + & EEAL(NBSTATION) +* + COMMON/MEASUR/XMES(NBSTATION),YMES(NBSTATION),IZMES(NBSTATION), + & PHMES(NBSTATION),ALMES(NBSTATION),MPOS(NBSTATION), + & MANG(NBSTATION) +* + COMMON/PLANE/XPL(NBSTATION,2),YPL(NBSTATION,2), + & PHPL(NBSTATION),ALPL(NBSTATION),CHI2PL +* + COMMON/CANDIDAT/JCAN(NBSTATION,MAXCAN),JCANTYP(MAXCAN), + & EEX(MAXCAN),EEY(MAXCAN),EEP(MAXCAN),EEA(MAXCAN) +* + COMMON /VERTEX/ERRV,IVERTEX +* + COMMON/TRACKSUM/NRES(5),NRESF,NTRMUALL,NMUONALL,NGHOSTALL, + & NTRACKFALL,NERRALL(NBSTATION),IR +* + COMMON/TRACKFOUT/IEVOUT,NTREVT,JJOUT(NBCHAMBER,NTRMAX), + & ISTAT(NTRMAX),PXZOUT(NTRMAX),TPHIOUT(NTRMAX), + & TALAMOUT(NTRMAX),XVERTOUT(NTRMAX),YVERTOUT(NTRMAX), + & CHI2OUT(NTRMAX), + & XMESOUT(NBCHAMBER,NTRMAX),YMESOUT(NBCHAMBER,NTRMAX) + & ,PXVOUT(NTRMAX),PYVOUT(NTRMAX),PZVOUT(NTRMAX) +* + COMMON/TRACKFI/EFF,EFF1,EFF2,XPREC,YPREC,PHIPREC,ALAMPREC, + & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP +* + COMMON/DEBEVT/IDEBUG + + DIMENSION PEST(5),PSTEP(5),NERR(NBSTATION) +* + REAL*4 R2 + DATA R2/1./ + +** GEANT informations + DO I = 1,MAXTRK + IT_LIST(I)= 0 + ENDDO + DO I = 1,MAXHITTOT + ITRACK(I) = 0 + ENDDO + NTRTOT = 0 +* BOUCLE SUR LES HITS + + DO IH = 1,NHITTOT + DO IT = 1,NTRTOT + IF (ID(IH).EQ.IT_LIST(IT)) GOTO 4 + ENDDO + NTRTOT = NTRTOT +1 ! NB de trace GEANT + IT_LIST(NTRTOT) = ID(IH) ! ID DE LA TRACE NTRTOT + IT_NP(NTRTOT) = 0 ! NOMBRE DE HITS PAR TRACE + DO II=1,NBSTATION + ITTROUGH(NTRTOT,II) = 0 + ENDDO + IT = NTRTOT + 4 IT_NP(IT) = IT_NP(IT)+1 + ITTROUGH(IT,IZST(IH))=IH ! =IH si la trace IT touche le plan IZST + ITRACK(IH) = IT + ENDDO + IF (IDEBUG.GE.2) THEN + PRINT *,'RECO_TRACKF nb total de trace GEANT:',NTRTOT + ENDIF + NTRPART=0 + NTRMU = 0 + + DO IT = 1,NTRTOT +* print*,'(ITTROUGH(IT,1)=',ITTROUGH(IT,1) +* print*,'(ITTROUGH(IT,2)=',ITTROUGH(IT,2) +* print*,'(ITTROUGH(IT,3)=',ITTROUGH(IT,3) +* print*,'(ITTROUGH(IT,4)=',ITTROUGH(IT,4) +* print*,'(ITTROUGH(IT,5)=',ITTROUGH(IT,5) + ITCHECK(IT) = 0 + IF ((ITTROUGH(IT,1)*ITTROUGH(IT,2)*ITTROUGH(IT,3)* + & ITTROUGH(IT,4)*ITTROUGH(IT,5)).NE.0) + & THEN + NTRPART=NTRPART+1 + IH = ITTROUGH(IT,NBSTATION) + IF (ITYP(IH).EQ.5.OR.ITYP(IH).EQ.6) THEN + ISTAK = ID(IH) + ISTAK = MOD(ISTAK,30000) + ISTAK = MOD(ISTAK,10000) +* test + pt=sqrt(pvert1(ih)**2+pvert2(ih)**2) + thet=datan2(pt,pvert3(ih))*180/3.1416 + pp=sqrt(pt**2+pvert3(ih)**2) + +* print*,'istak=',istak + + IF (ISTAK.EQ.IDRES) THEN ! psi or upsilon + print*,'resonance' + NTRMU = NTRMU+1 + NTRMUALL = NTRMUALL+1 + ITCHECK(IT) = 1 + ENDIF + ENDIF + ENDIF + ENDDO + + IF (IDEBUG.GE.2) THEN + PRINT *,'RECO_TRACKF nb of part. GEANT crossing 5 st.:', + & NTRPART + PRINT *,'RECO_TRACKF nb of muons/res. GEANT crossing 5 st.:', + & NTRMU + ENDIF + +** CALL H_ACCEPTANCE(5) +** CALL H_ACCEPTANCE(4) +** PAUSE + + NCAN = 0 + +* Recherche 5 -> 4 + + CALL ORDONNE_HIT(5,HCUT) + + DO IH = 1,INDEXMAX + JJ = INDEXTAB(IH) + X1 = XM(5,JJ)-(ZPLANE(5)-ZPLANE(4))*TAN(PHM(5,JJ)) + Y1 = YM(5,JJ)+(ZPLANE(5)-ZPLANE(4))*TAN(ALM(5,JJ)) + & /COS(PHM(5,JJ)) + X2 = XM(5,JJ)-(ZPLANE(5)-ZPLANE(4)+DZ_PL(4))*TAN(PHM(5,JJ)) + Y2 = YM(5,JJ)+(ZPLANE(5)-ZPLANE(4)+DZ_PL(4))*TAN(ALM(5,JJ)) + & /COS(PHM(5,JJ)) +* Domaine de recherche dans la st. 4 + HCONST = 0.0136*SQRT(0.06)/HTOP ! -> X/X0=0.03 % / chamber + EPH2 = 2.0*PHIPREC**2 + (HCONST*HHIT(JJ))**2 + EAL2 = 2.0*ALAMPREC**2 + (HCONST*HHIT(JJ))**2 +** 29.07 + EXM2 = 2.0*(XPREC/SQRT(2.))**2 + & + (ZPLANE(5)-ZPLANE(4))**2/2.*EPH2 + EYM2 = 2.0*YPREC**2 + (ZPLANE(5)-ZPLANE(4))**2/2.*EAL2 + P1 = PTOT(IP(5,JJ)) + CALL CHFILL2(2500,SNGL(P1),SNGL(HHIT(JJ)),1.) + CALL CHFILL2(2501,SNGL(P1),SNGL(HHIT(JJ)**2),1.) + CALL CHFILL2(2502,SNGL(P1),SNGL(EPH2),1.) + CALL CHFILL2(2503,SNGL(P1),SNGL(EAL2),1.) + CALL CHFILL2(2504,SNGL(P1),SNGL(EXM2),1.) + CALL CHFILL2(2505,SNGL(P1),SNGL(EYM2),1.) + + CALL CHFILL2(2507,SNGL(P1),SNGL(SQRT(EPH2)),1.) + CALL CHFILL2(2508,SNGL(P1),SNGL(SQRT(EAL2)),1.) + CALL CHFILL2(2509,SNGL(P1),SNGL(SQRT(EXM2)),1.) + CALL CHFILL2(2510,SNGL(P1),SNGL(SQRT(EYM2)),1.) +** end 29.07 + EXM12 = (PHIPREC**2+(HCONST*HHIT(JJ))**2)* + & (ZPLANE(5)-ZPLANE(4))**2 + XPREC**2 + EYM12 = (ALAMPREC**2+(HCONST*HHIT(JJ))**2)* + & (ZPLANE(5)-ZPLANE(4))**2 + YPREC**2 + EXM22 = (PHIPREC**2+(HCONST*HHIT(JJ))**2)* + & (ZPLANE(5)-ZPLANE(4)+DZ_PL(4))**2 + XPREC**2 + EYM22 = (ALAMPREC**2+(HCONST*HHIT(JJ))**2)* + & (ZPLANE(5)-ZPLANE(4)+DZ_PL(4))**2 + YPREC**2 + + EPH = SIGCUT*SQRT(EPH2) + EAL = SIGCUT*SQRT(EAL2) + EX1 = SIGCUT*SQRT(EXM12) + EY1 = SIGCUT*SQRT(EYM12) + EX2 = SIGCUT*SQRT(EXM22) + EY2 = SIGCUT*SQRT(EYM22) +** 29.07 + EXM = SIGCUT*SQRT(EXM2) + EYM = SIGCUT*SQRT(EYM2) + CALL CHFILL2(2511,SNGL(P1),SNGL(EPH),1.) + CALL CHFILL2(2512,SNGL(P1),SNGL(EAL),1.) + CALL CHFILL2(2513,SNGL(P1),SNGL(EXM),1.) + CALL CHFILL2(2514,SNGL(P1),SNGL(EYM),1.) +** end 29.07 +** P2 = (HTOP/HHIT(JJ))**2 + +** EPH=SIGCUT*SQRT(9.14D-7+1.2D-3/P2) +** EAL=SIGCUT*SQRT(1.84D-4) +** EX1=SIGCUT*SQRT(1.95D-2+6.37/P2) +** EY1=SIGCUT*SQRT(3.89+151./P2) +** EX2=EX1 +** EY2=EY2 + +* renvoie le num de hit de 4 le plus pres dans le domaine de recherche + + CALL DISTMIN4(X1,Y1,PHM(5,JJ),ALM(5,JJ),4,EX1,EY1,EPH,EAL, + & IFIND) + P1 = PTOT(IP(5,JJ)) + CALL CHECK_HISTO4(11,4,IFIND,5,JJ,X1,Y1,PHM(5,JJ),ALM(5,JJ),P1, + & EX1,EY1,EPH,EAL) + IF (IFIND.GT.0) THEN + CALL STOCK_CANDIDAT(5,JJ,4,IFIND,EX1,EY1,EPH,EAL,NCAN,1) + ELSE + CALL DISTMIN2(X1,Y1,X2,Y2,4,EX1,EY1,EX2,EY2,IFIND) + CALL CHECK_HISTO2(0,4,IFIND,5,JJ,X1,Y1,X2,Y2,P1,EX1,EY1, + & EX2,EY2) + IF (IFIND.GT.0) THEN + CALL STOCK_CANDIDAT(5,JJ,4,IFIND,EX1,EY1,EPH,EAL,NCAN,2) + ENDIF + ENDIF + ENDDO + +* Recherche 4 -> 5 + + CALL ORDONNE_HIT(4,HCUT) + + DO IH = 1,INDEXMAX + JJ = INDEXTAB(IH) + X1 = XM(4,JJ)-(ZPLANE(4)-ZPLANE(5))*TAN(PHM(4,JJ)) + Y1 = YM(4,JJ)+(ZPLANE(4)-ZPLANE(5))*TAN(ALM(4,JJ)) + & /COS(PHM(4,JJ)) + X2 = XM(4,JJ)-(ZPLANE(4)-ZPLANE(5)+DZ_PL(5))*TAN(PHM(4,JJ)) + Y2 = YM(4,JJ)+(ZPLANE(4)-ZPLANE(5)+DZ_PL(5))*TAN(ALM(4,JJ)) + & /COS(PHM(4,JJ)) +* Domaine de recherche dans la st. 5 + HCONST = 0.0136*SQRT(0.06)/HTOP ! -> X/X0=0.03 / chamber +** EPH2 = 2.0*PHIPREC**2 + (HCONST*HHIT(JJ))**2 +** EAL2 = 2.0*ALAMPREC**2 + (HCONST*HHIT(JJ))**2 +** EX12 = 2.0*(XPREC/SQRT(2.))**2 +** & + (ZPLANE(5)-ZPLANE(4))**2/2.*EPH2 +** EY12 = 2.0*YPREC**2 + (ZPLANE(5)-ZPLANE(4))**2/2.*EAL2 +** EX22 = 2.0*(XPREC/SQRT(2.))**2 +** & + (ZPLANE(5)-ZPLANE(4)-DZ_PL(5))**2/2.*EPH2 +** EY22 = 2.0*YPREC**2 + (ZPLANE(5)-ZPLANE(4)-DZ_PL(5))**2/2. +** & *EAL2 + EPH2 = 2.0*PHIPREC**2 + (HCONST*HHIT(JJ))**2 + EAL2 = 2.0*ALAMPREC**2 + (HCONST*HHIT(JJ))**2 +** 29.07 + EXM2 = 2.0*(XPREC/SQRT(2.))**2 + & + (ZPLANE(5)-ZPLANE(4))**2/2.*EPH2 + EYM2 = 2.0*YPREC**2 + (ZPLANE(5)-ZPLANE(4))**2/2.*EAL2 + P1 = PTOT(IP(4,JJ)) + CALL CHFILL2(2400,SNGL(P1),SNGL(HHIT(JJ)),1.) + CALL CHFILL2(2401,SNGL(P1),SNGL(HHIT(JJ)**2),1.) + CALL CHFILL2(2402,SNGL(P1),SNGL(EPH2),1.) + CALL CHFILL2(2403,SNGL(P1),SNGL(EAL2),1.) + CALL CHFILL2(2404,SNGL(P1),SNGL(EXM2),1.) + CALL CHFILL2(2405,SNGL(P1),SNGL(EYM2),1.) + + CALL CHFILL2(2407,SNGL(P1),SNGL(SQRT(EPH2)),1.) + CALL CHFILL2(2408,SNGL(P1),SNGL(SQRT(EAL2)),1.) + CALL CHFILL2(2409,SNGL(P1),SNGL(SQRT(EXM2)),1.) + CALL CHFILL2(2410,SNGL(P1),SNGL(SQRT(EYM2)),1.) +** end 29.07 + + EXM12 = (PHIPREC**2+(HCONST*HHIT(JJ))**2)* + & (ZPLANE(5)-ZPLANE(4))**2 + XPREC**2 + EYM12 = (ALAMPREC**2+(HCONST*HHIT(JJ))**2)* + & (ZPLANE(5)-ZPLANE(4))**2 + YPREC**2 + EXM22 = (PHIPREC**2+(HCONST*HHIT(JJ))**2)* + & (ZPLANE(5)-ZPLANE(4)-DZ_PL(5))**2 + XPREC**2 + EYM22 = (ALAMPREC**2+(HCONST*HHIT(JJ))**2)* + & (ZPLANE(5)-ZPLANE(4)-DZ_PL(5))**2 + YPREC**2 + + EPH = SIGCUT*SQRT(EPH2) + EAL = SIGCUT*SQRT(EAL2) + EX1 = SIGCUT*SQRT(EXM12) + EY1 = SIGCUT*SQRT(EYM12) + EX2 = SIGCUT*SQRT(EXM22) + EY2 = SIGCUT*SQRT(EYM22) +** 29.07 + EXM = SIGCUT*SQRT(EXM2) + EYM = SIGCUT*SQRT(EYM2) + CALL CHFILL2(2411,SNGL(P1),SNGL(EPH),1.) + CALL CHFILL2(2412,SNGL(P1),SNGL(EAL),1.) + CALL CHFILL2(2413,SNGL(P1),SNGL(EXM),1.) + CALL CHFILL2(2414,SNGL(P1),SNGL(EYM),1.) +** end 29.07 + +** P2 = (HTOP/HHIT(JJ))**2 + +** EPH=SIGCUT*SQRT(9.14D-7+1.2D-3/P2) +** EAL=SIGCUT*SQRT(1.84D-4) +** EX1=SIGCUT*SQRT(1.95D-2+6.37/P2) +** EY1=SIGCUT*SQRT(3.89+151./P2) +** EX2=EX1 +** EY2=EY2 +* Renvoie le num de hit de 5 le plus pres dans le domaine de recherche + CALL DISTMIN2(X1,Y1,X2,Y2,5,EX1,EY1,EX2,EY2,IFIND) + P1 = PTOT(IP(4,JJ)) + CALL CHECK_HISTO2(0,5,IFIND,4,JJ,X1,Y1,X2,Y2,P1,EX1,EY1, + & EX2,EY2) + IF (IFIND.GT.0) THEN + DO ICAN=1,NCAN + IF (IFIND.EQ.JCAN(5,ICAN).AND.JJ.EQ.JCAN(4,ICAN)) GOTO 40 + IF (ABS(XM(5,JCAN(5,ICAN))-XM(5,IFIND)).LT.XPREC/10.) + & GO TO 40 ! elimine les doubles comptages de traces ccc + ENDDO + CALL STOCK_CANDIDAT(4,JJ,5,IFIND,EX1,EY1,EPH,EAL,NCAN,3) + ENDIF +40 CONTINUE + ENDDO + + + NMU45 = 0 + DO ICAN = 1,NCAN + JJ4 = JCAN(4,ICAN) + JJ5 = JCAN(5,ICAN) + IF (JJ4.GT.0.AND.JJ5.GT.0) THEN + ID4 = ID(IP(4,JJ4)) + ID5 = ID(IP(5,JJ5)) + IT = ITRACK(IP(5,JJ5)) + IF (ITCHECK(IT).EQ.1) THEN + IF (ID4.EQ.ID5) THEN + NMU45 = NMU45 + 1 + ENDIF + ENDIF + ENDIF + ENDDO + IF (NMU45.GE.2) NRES(1) = NRES(1)+1 + + IF (IDEBUG.GE.2) THEN + PRINT *,'RECO_TRACKF nb candidat recherche 4->5 et 5->4 :' + & ,NCAN + PRINT *,'RECO_TRACKF nb of good muons 4->5 et 5->4 :' + & ,NMU45 + + ENDIF + + NMU345 = 0 +* +* -- Boucle sur les candidats (4,5) NCAN +* + DO I = 1,NBSTATION + NERR(I) = 0 + ENDDO + NMUONF = 0 + NGHOST = 0 + NTRACKF = 0 + + DO ICAN = 1,NCAN + JJ1 = 0 + JJ2 = 0 + JJ3 = 0 + DO ICH = 1,NBSTATION + MPOS(ICH) = 0 + MANG(ICH) = 0 + ENDDO + MPOS(4) = 1 + MPOS(5) = 1 + MANG(4) = 1 + MANG(5) = 1 + IF (JCANTYP(ICAN).EQ.2) MANG(4)=0 + IF (JCANTYP(ICAN).EQ.3) MANG(5)=0 + EEXM(5) = EEX(ICAN)/SIGCUT + EEYM(5) = EEY(ICAN)/SIGCUT + EEPH(5) = EEP(ICAN)/SIGCUT + EEAL(5) = EEA(ICAN)/SIGCUT + EEXM(4) = EEX(ICAN)/SIGCUT + EEYM(4) = EEY(ICAN)/SIGCUT + EEPH(4) = EEP(ICAN)/SIGCUT + EEAL(4) = EEA(ICAN)/SIGCUT + JJ5 = JCAN(5,ICAN) + JJ4 = JCAN(4,ICAN) + P = PTOT(IP(5,JJ5)) + IF (IZM(4,JJ4).EQ.1) THEN + ZPL4 = ZPLANE(4) + ELSE + ZPL4 = ZPLANE(4)-DZ_PL(4) + ENDIF + IF (IZM(5,JJ5).EQ.1) THEN + ZPL5 = ZPLANE(5) + ELSE + ZPL5 = ZPLANE(5)-DZ_PL(5) + ENDIF + TPHEST = (XM(5,JJ5) - XM(4,JJ4))/(ZPL5-ZPL4) + PHEST = ATAN(TPHEST) + TALEST = -(YM(5,JJ5) - YM(4,JJ4))*COS(PHEST) + & /(ZPL5-ZPL4) + PXZEST = -HTOP/(XM(4,JJ4) - ZPL4*TPHEST) + PEST(1) = 1.0/PXZEST + PEST(2) = TPHEST - ALPHATOP/PXZEST ! PHI emission au vertex + PEST(3) = TALEST ! tan(lambda) !h=zm*ang deviation alpha + PEST(4) = 0.0 !alpha=qbl/pxz + PEST(5) = 0.0 + PSTEP(1) = 0.003 ! =d(1/p)=delta(p)/p**2 + PSTEP(2) = 0.001 ! 0.5 degre + PSTEP(3) = 0.001 ! 0.5 degre + PSTEP(4) = 0.0 + PSTEP(5) = 1.0 + XMES(4) = XM(4,JJ4) + YMES(4) = YM(4,JJ4) + IZMES(4) = IZM(4,JJ4) + PHMES(4) = PHM(4,JJ4) + ALMES(4) = ALM(4,JJ4) + XMES(5) = XM(5,JJ5) + YMES(5) = YM(5,JJ5) + IZMES(5) = IZM(5,JJ5) + PHMES(5) = PHM(5,JJ5) + ALMES(5) = ALM(5,JJ5) + + IVERTEX = 0 ! Vertex = (0,0,0) + +* -- Fit 4,5,V pour la recherche dans 3 + + CALL TRACKF_FIT(IVERTEX,PEST,PSTEP,PXZINV45,TPHI45,TALAM45, + & XVERT,YVERT) + +* -- Recherche dans la station 3 + + P2 = (1.0D0 + TALAM45**2)/(PXZINV45**2) ! P**2 +** EPH=SIGCUT*SQRT(3.6D-6+0.011/P2) +** EAL=SIGCUT*SQRT(6.85D-4) +** EXM=SIGCUT*SQRT(0.034+446./P2) +** EYM=SIGCUT*SQRT(0.049+354./P2) + EPH=SIGCUT*SQRT(4.1D-7+0.015/P2) + EAL=SIGCUT*SQRT(1.04D-4) + EXM=SIGCUT*SQRT(0.0+459./P2) + EYM=SIGCUT*SQRT(0.042+345./P2) + EEXM(3) = EXM/SIGCUT + EEYM(3) = EYM/SIGCUT + EEPH(3) = EPH/SIGCUT + EEAL(3) = EAL/SIGCUT +** 29.07 + CALL CHF1(2301,SNGL(SQRT(P2)),1.) + P1 = PTOT(IP(5,JJ5)) + CALL CHFILL2(2311,SNGL(P1),SNGL(EPH),1.) + CALL CHFILL2(2312,SNGL(P1),SNGL(EAL),1.) + CALL CHFILL2(2313,SNGL(P1),SNGL(EXM),1.) + CALL CHFILL2(2314,SNGL(P1),SNGL(EYM),1.) + + CALL CHFILL2(2315,SNGL(SQRT(P2)),SNGL(EPH),1.) + CALL CHFILL2(2316,SNGL(SQRT(P2)),SNGL(EAL),1.) + CALL CHFILL2(2317,SNGL(SQRT(P2)),SNGL(EXM),1.) + CALL CHFILL2(2318,SNGL(SQRT(P2)),SNGL(EYM),1.) + + CALL CHFILL2(2302,SNGL(SQRT(P2)),SNGL((EPH/SIGCUT)**2),1.) + CALL CHFILL2(2303,SNGL(SQRT(P2)),SNGL((EAL/SIGCUT)**2),1.) + CALL CHFILL2(2304,SNGL(SQRT(P2)),SNGL((EXM/SIGCUT)**2),1.) + CALL CHFILL2(2305,SNGL(SQRT(P2)),SNGL((EYM/SIGCUT)**2),1.) + + CALL CHFILL2(2307,SNGL(P1),SNGL((EPH/SIGCUT)**2),1.) + CALL CHFILL2(2308,SNGL(P1),SNGL((EAL/SIGCUT)**2),1.) + CALL CHFILL2(2309,SNGL(P1),SNGL((EXM/SIGCUT)**2),1.) + CALL CHFILL2(2310,SNGL(P1),SNGL((EYM/SIGCUT)**2),1.) +** end 29.07 + +** DO IEX = 4,5 +** EEXM(IEX) = EEXM(3) +** EEYM(IEX) = EEYM(3) +** EEPH(IEX) = EEPH(3) +** EEAL(IEX) = EEAL(3) +** ENDDO + X1 = XPL(3,1) + Y1 = YPL(3,1) + X2 = XPL(3,2) + Y2 = YPL(3,2) + PHI1 = PHPL(3) + ALAM1 = ALPL(3) + + CALL DISTMIN4(X1,Y1,PHI1,ALAM1,3,EXM,EYM,EPH,EAL,IPA3) + + P1 = PTOT(IP(5,JJ5)) + + CALL CHECK_HISTO4(61,3,IPA3,5,JJ5,X1,Y1,PHI1,ALAM1,P1, + & EXM,EYM,EPH,EAL) + + IF (IPA3.NE.0) THEN + JJ3 = IPA3 + XMES(3) = XM(3,JJ3) + YMES(3) = YM(3,JJ3) + IZMES(3) = IZM(3,JJ3) + PHMES(3) = PHM(3,JJ3) + ALMES(3) = ALM(3,JJ3) + MPOS(3) = 1 + MANG(3) = 1 + GO TO 124 + ELSE + CALL DISTMIN2(X1,Y1,X2,Y2,3,EXM,EYM,0.D0,0.D0,IP3) + CALL CHECK_HISTO2(0,3,IP3,5,JJ5,X1,Y1,X2,Y2,P1,EXM,EYM, + & 0.D0,0.D0) + ENDIF + IF (IP3.NE.0) THEN + JJ3 = IP3 + XMES(3) = XM(3,JJ3) + YMES(3) = YM(3,JJ3) + IZMES(3) = IZM(3,JJ3) + MPOS(3) = 1 + MANG(3) = 0 + ELSE + GO TO 123 + ENDIF + + +* -- Fit 3,4,5 pour la recherche dans 2 + + 124 CONTINUE + + IF (JJ5.GT.0.AND.JJ4.GT.0.AND.JJ3.GT.0) THEN + ID4 = ID(IP(4,JJ4)) + ID5 = ID(IP(5,JJ5)) + ID3 = ID(IP(3,JJ3)) + IT = ITRACK(IP(5,JJ5)) + IF (ITCHECK(IT).EQ.1) THEN + IF ((ID5.EQ.ID3).AND.(ID5.EQ.ID4)) THEN + NMU345 = NMU345 + 1 + ENDIF + ENDIF + ENDIF + + IVERTEX = 0 + + PEST(1) = PXZINV45 + PEST(2) = TPHI45 + PEST(3) = TALAM45 + PEST(4) = 0. + PEST(5) = 0. + PSTEP(1) = 0.003 + PSTEP(2) = 0.001 + PSTEP(3) = 0.001 + PSTEP(4) = 1. + PSTEP(5) = 1. + + CALL TRACKF_FIT(IVERTEX,PEST,PSTEP,PXZINV345,TPHI345, + & TALAM345,XVERT,YVERT) + +* -- Recherche dans la st. 2 + + P2 = (1.0D0 + TALAM345**2)/(PXZINV345**2) ! P**2 +** EPH=SIGCUT*SQRT(3.63D-6+4.8D-3/P2) +** EAL=SIGCUT*SQRT(6.49D-4) +** EXM=SIGCUT*SQRT(1.64D-2+821./P2) +** EYM=SIGCUT*SQRT(4.83D-2+866./P2) + EPH=SIGCUT*SQRT(5.78D-7+5.97D-3/P2) + EAL=SIGCUT*SQRT(1.D-4) + EXM=SIGCUT*SQRT(0.+1453./P2) + EYM=SIGCUT*SQRT(2.78D-2+504./P2) + EEXM(2) = EXM/SIGCUT + EEYM(2) = EYM/SIGCUT + EEPH(2) = EPH/SIGCUT + EEAL(2) = EAL/SIGCUT +** 29.07 + CALL CHF1(2201,SNGL(SQRT(P2)),1.) + P1 = PTOT(IP(5,JJ5)) + CALL CHFILL2(2211,SNGL(P1),SNGL(EPH),1.) + CALL CHFILL2(2212,SNGL(P1),SNGL(EAL),1.) + CALL CHFILL2(2213,SNGL(P1),SNGL(EXM),1.) + CALL CHFILL2(2214,SNGL(P1),SNGL(EYM),1.) + + CALL CHFILL2(2215,SNGL(SQRT(P2)),SNGL(EPH),1.) + CALL CHFILL2(2216,SNGL(SQRT(P2)),SNGL(EAL),1.) + CALL CHFILL2(2217,SNGL(SQRT(P2)),SNGL(EXM),1.) + CALL CHFILL2(2218,SNGL(SQRT(P2)),SNGL(EYM),1.) + + CALL CHFILL2(2202,SNGL(SQRT(P2)),SNGL((EPH/SIGCUT)**2),1.) + CALL CHFILL2(2203,SNGL(SQRT(P2)),SNGL((EAL/SIGCUT)**2),1.) + CALL CHFILL2(2204,SNGL(SQRT(P2)),SNGL((EXM/SIGCUT)**2),1.) + CALL CHFILL2(2205,SNGL(SQRT(P2)),SNGL((EYM/SIGCUT)**2),1.) + + CALL CHFILL2(2207,SNGL(P1),SNGL((EPH/SIGCUT)**2),1.) + CALL CHFILL2(2208,SNGL(P1),SNGL((EAL/SIGCUT)**2),1.) + CALL CHFILL2(2209,SNGL(P1),SNGL((EXM/SIGCUT)**2),1.) + CALL CHFILL2(2210,SNGL(P1),SNGL((EYM/SIGCUT)**2),1.) +** end 29.07 + +** DO IEX = 3,5 +** EEXM(IEX) = EEXM(2) +** EEYM(IEX) = EEYM(2) +** EEPH(IEX) = EEPH(2) +** EEAL(IEX) = EEAL(2) +** ENDDO + + X1 = XPL(2,1) + Y1 = YPL(2,1) + PHI1 = PHPL(2) + ALAM1 = ALPL(2) + CALL DISTMIN4(X1,Y1,PHI1,ALAM1,2,EXM,EYM,EPH,EAL,IPA2) + P1 = PTOT(IP(5,JJ5)) + CALL CHECK_HISTO4(21,2,IPA2,5,JJ5,X1,Y1,PHI1,ALAM1,P1, + & EXM,EYM,EPH,EAL) +* -- Recherche dans la st. 1 +** EPH=SIGCUT*SQRT(3.54D-6+4.49D-3/P2) +** EAL=SIGCUT*SQRT(6.14D-4) +** EXM=SIGCUT*SQRT(6.43D-2+986./P2) +** EYM=SIGCUT*SQRT(4.66D-2+1444./P2) + EPH=SIGCUT*SQRT(4.96D-7+5.87D-3/P2) + EAL=SIGCUT*SQRT(1.D-4) + EXM=SIGCUT*SQRT(6.98D-4+1467./P2) + EYM=SIGCUT*SQRT(5.22D-2+1013./P2) + EEXM(1) = EXM/SIGCUT + EEYM(1) = EYM/SIGCUT + EEPH(1) = EPH/SIGCUT + EEAL(1) = EAL/SIGCUT +** 29.07 + CALL CHFILL2(2111,SNGL(P1),SNGL(EPH),1.) + CALL CHFILL2(2112,SNGL(P1),SNGL(EAL),1.) + CALL CHFILL2(2113,SNGL(P1),SNGL(EXM),1.) + CALL CHFILL2(2114,SNGL(P1),SNGL(EYM),1.) + + CALL CHFILL2(2115,SNGL(SQRT(P2)),SNGL(EPH),1.) + CALL CHFILL2(2116,SNGL(SQRT(P2)),SNGL(EAL),1.) + CALL CHFILL2(2117,SNGL(SQRT(P2)),SNGL(EXM),1.) + CALL CHFILL2(2118,SNGL(SQRT(P2)),SNGL(EYM),1.) + + CALL CHFILL2(2102,SNGL(SQRT(P2)),SNGL((EPH/SIGCUT)**2),1.) + CALL CHFILL2(2103,SNGL(SQRT(P2)),SNGL((EAL/SIGCUT)**2),1.) + CALL CHFILL2(2104,SNGL(SQRT(P2)),SNGL((EXM/SIGCUT)**2),1.) + CALL CHFILL2(2105,SNGL(SQRT(P2)),SNGL((EYM/SIGCUT)**2),1.) + + CALL CHFILL2(2107,SNGL(P1),SNGL((EPH/SIGCUT)**2),1.) + CALL CHFILL2(2108,SNGL(P1),SNGL((EAL/SIGCUT)**2),1.) + CALL CHFILL2(2109,SNGL(P1),SNGL((EXM/SIGCUT)**2),1.) + CALL CHFILL2(2110,SNGL(P1),SNGL((EYM/SIGCUT)**2),1.) +** end 29.07 + + +** DO IEX = 2,5 +** EEXM(IEX) = EEXM(1) +** EEYM(IEX) = EEYM(1) +** EEPH(IEX) = EEPH(1) +** EEAL(IEX) = EEAL(1) +** ENDDO + + X1 = XPL(1,1) + Y1 = YPL(1,1) + PHI1 = PHPL(1) + ALAM1 = ALPL(1) + CALL DISTMIN4(X1,Y1,PHI1,ALAM1,1,EXM,EYM,EPH,EAL,IPA1) + CALL CHECK_HISTO4(31,1,IPA1,5,JJ5,X1,Y1,PHI1,ALAM1,P1, + & EXM,EYM,EPH,EAL) +* -- A partir de P+A dans la st. 2 + IPA2PA1 = 0 + IF (IPA2.GT.0) THEN + PEST(1) = PXZINV345 + PEST(2) = TPHI345 + PEST(3) = TALAM345 + PEST(4) = 0. + PEST(5) = 0. + PSTEP(1) = 0.003 + PSTEP(2) = 0.001 + PSTEP(3) = 0.001 + PSTEP(4) = 1. + PSTEP(5) = 1. + XMES(2) = XM(2,IPA2) + YMES(2) = YM(2,IPA2) + IZMES(2) = IZM(2,IPA2) + PHMES(2) = PHM(2,IPA2) + ALMES(2) = ALM(2,IPA2) + MPOS(2) = 1 + MANG(2) = 1 + IVERTEX = 1 +* -- Fit V,2,3,4,5 pour la recherche dans 1 + + CALL TRACKF_FIT(IVERTEX,PEST,PSTEP,PXZINV,TPHI,TALAM, + & XVERT,YVERT) + +* !!! ATTENTION aux erreurs + + P2 = (1.0D0 + TALAM**2)/(PXZINV**2) +** EPH=SIGCUT*SQRT(3.15D-6+9.21D-3/P2) +** EAL=SIGCUT*SQRT(5.94D-4) +** EXM=SIGCUT*SQRT(4.16D-2+182./P2) +** EYM=SIGCUT*SQRT(2.13) + EPH=SIGCUT*SQRT(9.58D-7+8.93D-3/P2) + EAL=SIGCUT*SQRT(1.D-4) + EXM=SIGCUT*SQRT(1.92D-2+103.3/P2) + EYM=SIGCUT*SQRT(6.3D-2+81.1/P2) + EEXM(1) = EXM/SIGCUT + EEYM(1) = EYM/SIGCUT + EEPH(1) = EPH/SIGCUT + EEAL(1) = EAL/SIGCUT +** 29.07 + CALL CHF1(2701,SNGL(SQRT(P2)),1.) + CALL CHFILL2(2711,SNGL(P1),SNGL(EPH),1.) + CALL CHFILL2(2712,SNGL(P1),SNGL(EAL),1.) + CALL CHFILL2(2713,SNGL(P1),SNGL(EXM),1.) + CALL CHFILL2(2714,SNGL(P1),SNGL(EYM),1.) + + CALL CHFILL2(2715,SNGL(SQRT(P2)),SNGL(EPH),1.) + CALL CHFILL2(2716,SNGL(SQRT(P2)),SNGL(EAL),1.) + CALL CHFILL2(2717,SNGL(SQRT(P2)),SNGL(EXM),1.) + CALL CHFILL2(2718,SNGL(SQRT(P2)),SNGL(EYM),1.) + + CALL CHFILL2(2702,SNGL(SQRT(P2)),SNGL((EPH/SIGCUT)**2),1.) + CALL CHFILL2(2703,SNGL(SQRT(P2)),SNGL((EAL/SIGCUT)**2),1.) + CALL CHFILL2(2704,SNGL(SQRT(P2)),SNGL((EXM/SIGCUT)**2),1.) + CALL CHFILL2(2705,SNGL(SQRT(P2)),SNGL((EYM/SIGCUT)**2),1.) + + + CALL CHFILL2(2707,SNGL(P1),SNGL((EPH/SIGCUT)**2),1.) + CALL CHFILL2(2708,SNGL(P1),SNGL((EAL/SIGCUT)**2),1.) + CALL CHFILL2(2709,SNGL(P1),SNGL((EXM/SIGCUT)**2),1.) + CALL CHFILL2(2710,SNGL(P1),SNGL((EYM/SIGCUT)**2),1.) +** end 29.07 + + +** DO IEX = 2,5 +** EEXM(IEX) = EEXM(1) +** EEYM(IEX) = EEYM(1) +** EEPH(IEX) = EEPH(1) +** EEAL(IEX) = EEAL(1) +** ENDDO + + X1 = XPL(1,1) + Y1 = YPL(1,1) + X2 = XPL(1,2) + Y2 = YPL(1,2) + PHI1 = PHPL(1) + ALAM1 = ALPL(1) + CALL DISTMIN4(X1,Y1,PHI1,ALAM1,1,EXM,EYM,EPH,EAL, + & IPA2PA1) + CALL CHECK_HISTO4(41,1,IPA2PA1,5,JJ5,X1,Y1,PHI1,ALAM1, + & P1,EXM,EYM,EPH,EAL) + IF (IPA2PA1.GT.0) THEN + JJ2 = IPA2 + JJ1 = IPA2PA1 + XMES(1) = XM(1,JJ1) + YMES(1) = YM(1,JJ1) + IZMES(1) = IZM(1,JJ1) + PHMES(1) = PHM(1,JJ1) + ALMES(1) = ALM(1,JJ1) + MPOS(1) = 1 + MANG(1) = 1 + GOTO 123 + ELSE + CALL DISTMIN2(X1,Y1,X2,Y2,1,EXM,EYM,0.D0,0.D0,IPA2P1) + CALL CHECK_HISTO2(0,1,IPA2P1,5,JJ5,X1,Y1,X2,Y2,P1, + & EXM,EYM,0.D0,0.D0) + ENDIF + ENDIF +* -- A partir de P+A dans la st. 1 + IPA1PA2 = 0 + IF (IPA1.GT.0) THEN + PEST(1) = PXZINV345 + PEST(2) = TPHI345 + PEST(3) = TALAM345 + PEST(4) = 0. + PEST(5) = 0. + PSTEP(1) = 0.003 + PSTEP(2) = 0.001 + PSTEP(3) = 0.001 + PSTEP(4) = 1. + PSTEP(5) = 1. + XMES(1) = XM(1,IPA1) + YMES(1) = YM(1,IPA1) + IZMES(1) = IZM(1,IPA1) + PHMES(1) = PHM(1,IPA1) + ALMES(1) = ALM(1,IPA1) + MPOS(1) = 1 + MANG(1) = 1 + MPOS(2) = 0 + MANG(2) = 0 + IVERTEX = 1 +* -- Fit V,1,3,4,5 pour la recherche dans 2 + + CALL TRACKF_FIT(IVERTEX,PEST,PSTEP,PXZINV,TPHI,TALAM, + & XVERT,YVERT) + +* !!! ATTENTION aux erreurs + + P2 = (1.0D0 + TALAM**2)/(PXZINV**2) +** EPH=SIGCUT*SQRT(3.15D-6+9.21D-3/P2) +** EAL=SIGCUT*SQRT(5.94D-4) +** EXM=SIGCUT*SQRT(4.16D-2+182./P2) +** EYM=SIGCUT*SQRT(2.13) + EPH=SIGCUT*SQRT(9.58D-7+8.93D-3/P2) + EAL=SIGCUT*SQRT(1.D-4) + EXM=SIGCUT*SQRT(4.0D-2+11.4/P2) + EYM=SIGCUT*SQRT(5.5D-2+44.35/P2) + + EEXM(2) = EXM/SIGCUT + EEYM(2) = EYM/SIGCUT + EEPH(2) = EPH/SIGCUT + EEAL(2) = EAL/SIGCUT +** 29.07 + CALL CHF1(2801,SNGL(SQRT(P2)),1.) + CALL CHFILL2(2811,SNGL(P1),SNGL(EPH),1.) + CALL CHFILL2(2812,SNGL(P1),SNGL(EAL),1.) + CALL CHFILL2(2813,SNGL(P1),SNGL(EXM),1.) + CALL CHFILL2(2814,SNGL(P1),SNGL(EYM),1.) + + CALL CHFILL2(2815,SNGL(SQRT(P2)),SNGL(EPH),1.) + CALL CHFILL2(2816,SNGL(SQRT(P2)),SNGL(EAL),1.) + CALL CHFILL2(2817,SNGL(SQRT(P2)),SNGL(EXM),1.) + CALL CHFILL2(2818,SNGL(SQRT(P2)),SNGL(EYM),1.) + + CALL CHFILL2(2802,SNGL(SQRT(P2)),SNGL((EPH/SIGCUT)**2),1.) + CALL CHFILL2(2803,SNGL(SQRT(P2)),SNGL((EAL/SIGCUT)**2),1.) + CALL CHFILL2(2804,SNGL(SQRT(P2)),SNGL((EXM/SIGCUT)**2),1.) + CALL CHFILL2(2805,SNGL(SQRT(P2)),SNGL((EYM/SIGCUT)**2),1.) + + + CALL CHFILL2(2807,SNGL(P1),SNGL((EPH/SIGCUT)**2),1.) + CALL CHFILL2(2808,SNGL(P1),SNGL((EAL/SIGCUT)**2),1.) + CALL CHFILL2(2809,SNGL(P1),SNGL((EXM/SIGCUT)**2),1.) + CALL CHFILL2(2810,SNGL(P1),SNGL((EYM/SIGCUT)**2),1.) + +** end 29.07 + + + + +** DO IEX = 1,5 +** EEXM(IEX) = EEXM(2) +** EEYM(IEX) = EEYM(2) +** EEPH(IEX) = EEPH(2) +** EEAL(IEX) = EEAL(2) +** ENDDO + + X1 = XPL(2,1) + Y1 = YPL(2,1) + X2 = XPL(2,2) + Y2 = YPL(2,2) + PHI1 = PHPL(2) + ALAM1 = ALPL(2) + + CALL DISTMIN4(X1,Y1,PHI1,ALAM1,2,EXM,EYM,EPH,EAL, + & IPA1PA2) + + CALL CHECK_HISTO4(51,2,IPA1PA2,5,JJ5,X1,Y1,PHI1,ALAM1, + & P1,EXM,EYM,EPH,EAL) + IF (IPA1PA2.GT.0) THEN + JJ1 = IPA1 + JJ2 = IPA1PA2 + XMES(2) = XM(2,JJ2) + YMES(2) = YM(2,JJ2) + IZMES(2) = IZM(2,JJ2) + PHMES(2) = PHM(2,JJ2) + ALMES(2) = ALM(2,JJ2) + MPOS(2) = 1 + MANG(2) = 1 + GOTO 123 + ELSE + CALL DISTMIN2(X1,Y1,X2,Y2,2,EXM,EYM,0.D0,0.D0,IPA1P2) + CALL CHECK_HISTO2(0,2,IPA1P2,5,JJ5,X1,Y1,X2,Y2,P1, + & EXM,EYM,0.D0,0.D0) + ENDIF + ENDIF +* -- Selection par type de candidat + IF (IPA1PA2.EQ.0.OR.IPA2PA1.EQ.0) THEN + IF (IPA2.GT.0.AND.IPA2P1.GT.0) THEN + JJ2 = IPA2 + JJ1 = IPA2P1 + XMES(1) = XM(1,JJ1) + YMES(1) = YM(1,JJ1) + IZMES(1) = IZM(1,JJ1) + MPOS(1) = 1 + MANG(1) = 0 + MPOS(2) = 1 + MANG(2) = 1 + ELSEIF(IPA1.GT.0.AND.IPA1P2.GT.0) THEN + JJ1 = IPA1 + JJ2 = IPA1P2 + XMES(2) = XM(2,JJ2) + YMES(2) = YM(2,JJ2) + IZMES(2) = IZM(2,JJ2) + MPOS(1) = 1 + MANG(1) = 1 + MPOS(2) = 1 + MANG(2) = 0 + ENDIF + ENDIF + + 123 CONTINUE +*** + NTRACKFOLD = NTRACKF + NMUONFOLD = NMUONF + NGHOSTOLD = NGHOST + CALL CHECK_MUON(JJ1,JJ2,JJ3,JJ4,JJ5,NTRACKF,NMUONF, + & NGHOST,NERR,PXZINV,TPHI,TALAM,XVERT,YVERT) + + IF (NTRACKF.GT.NTRACKFOLD) THEN + ISTAT(NTRACKF) = 0 + IF (NMUONF.GT.NMUONFOLD) ISTAT(NTRACKF) = 1 ! Good muon + IF (NGHOST.GT.NGHOSTOLD) ISTAT(NTRACKF) = 2 ! ghost track + PXZOUT(NTRACKF) = 1./PXZINV + TPHIOUT(NTRACKF) = TPHI + TALAMOUT(NTRACKF) = TALAM + XVERTOUT(NTRACKF) = XVERT + YVERTOUT(NTRACKF) = YVERT + PXVOUT(NTRACKF) = PVERT1(IP(5,JJ5)) + PYVOUT(NTRACKF) = PVERT2(IP(5,JJ5)) + PZVOUT(NTRACKF) = PVERT3(IP(5,JJ5)) + CHI2OUT(NTRACKF) = CHI2PL + ENDIF +*** + ENDDO ! end loop on candidats NCAN + + IF (NMU345.GE.2) NRES(2) = NRES(2) + 1 + + IF (IDEBUG.GE.2) THEN + PRINT *,'RECO_TRACKF nb of good muons 3 4 5 :' + & ,NMU345 + + ENDIF + + IF (IDEBUG.GE.2) THEN + PRINT *,'RECO_TRACKF nb of track /evt :',NTRACKF + PRINT *,'RECO_TRACKF nb of good muon /evt :',NMUONF + PRINT *,'RECO_TRACKF nb of ghost /evt :',NGHOST + DO I = 1,4 + PRINT *,'RECO_TRACKF nb of error in st',I,'/evt:',NERR(I) + ENDDO + ENDIF + IF (NTRMU.GE.2) NRES(5) = NRES(5)+1 + IF (NMUONF.GE.2) NRESF = NRESF+1 + NMUONALL = NMUONALL+NMUONF + NGHOSTALL = NGHOSTALL+NGHOST + NTRACKFALL = NTRACKFALL+NTRACKF + DO I = 1,4 + NERRALL(I) = NERRALL(I)+NERR(I) + ENDDO + + CALL TRACKF_OUT(IR,NTRACKF) +*** + RETURN + END + +********************************************************************** + SUBROUTINE TRACKF_OUT(IR,NTRACKF) +********************************************************************** +* +* +********************************************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER (MAXHITCH=10000,MAXTRK=50000,MAXHITTOT=20000, + & NBSTATION=5) + PARAMETER (NBCHAMBER=10,NTRMAX=500) + + COMMON/RECOUT/JJO(NBCHAMBER,NTRMAX),XMESO(NBCHAMBER,NTRMAX), + & YMESO(NBCHAMBER,NTRMAX) + + COMMON/TRACKFOUT/IEVOUT,NTREVT,JJOUT(NBCHAMBER,NTRMAX), + & ISTAT(NTRMAX),PXZOUT(NTRMAX),TPHIOUT(NTRMAX), + & TALAMOUT(NTRMAX),XVERTOUT(NTRMAX),YVERTOUT(NTRMAX), + & CHI2OUT(NTRMAX), + & XMESOUT(NBCHAMBER,NTRMAX),YMESOUT(NBCHAMBER,NTRMAX) + & ,PXVOUT(NTRMAX),PYVOUT(NTRMAX),PZVOUT(NTRMAX) +** + IEVOUT = IR + NTREVT = NTRACKF + IF (NTREVT.GT.0) THEN + DO ITR = 1,NTREVT + ICH = 0 + DO IST = 1,NBSTATION + DO ILOOP = 1,2 + ICH = ICH + 1 + JJOUT(ICH,ITR) = JJO(ICH,ITR) + IF (JJOUT(ICH,ITR).GT.0) THEN + XMESOUT(ICH,ITR) = XMESO(ICH,ITR) + YMESOUT(ICH,ITR) = YMESO(ICH,ITR) + ENDIF + ENDDO + ENDDO + ENDDO + ENDIF + + + RETURN + END +********************************************************************** + SUBROUTINE CHECK_MUON(JJ1,JJ2,JJ3,JJ4,JJ5, + & NTRACKF,NMUONF,NGHOST,NERR,PXZINV,TPHI,TALAM, + & XVERT,YVERT) +********************************************************************** +* Check muon track candidate using GEANT informations +* +********************************************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +* -- + PARAMETER (MAXHITCH=10000,MAXTRK=50000,MAXHITTOT=20000, + & NBSTATION=5) + PARAMETER (NBCHAMBER=10,NTRMAX=500) + + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) + + COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), + & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), + & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), + & ZVERT(MAXHITTOT),NHITTOT + + COMMON/VERIFGEANT/ITTROUGH(MAXTRK,NBSTATION), + & IT_LIST(MAXTRK),IT_NP(MAXTRK),ITCHECK(MAXTRK), + & ITRACK(MAXHITTOT) + + COMMON/MEASUR/XMES(NBSTATION),YMES(NBSTATION),IZMES(NBSTATION), + & PHMES(NBSTATION),ALMES(NBSTATION),MPOS(NBSTATION), + & MANG(NBSTATION) + + COMMON/RECOUT/JJO(NBCHAMBER,NTRMAX),XMESO(NBCHAMBER,NTRMAX), + & YMESO(NBCHAMBER,NTRMAX) + + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) + + COMMON/MAGNET/BL3,B0 + + REAL*4 R1,R2 + DATA R1,R2/0.,1./ + + DIMENSION NERR(NBSTATION),JJK(NBSTATION) + +* print*,' *** appel de la subroutine check_muon ***' + + IF (JJ1.GT.0.AND.JJ2.GT.0.AND.JJ3.GT.0.AND.JJ4.GT.0 + & .AND.JJ5.GT.0) THEN + IDFIND = ID(IP(5,JJ5)) + IT = ITRACK(IP(5,JJ5)) + JJK(1) = JJ1 + JJK(2) = JJ2 + JJK(3) = JJ3 + JJK(4) = JJ4 + JJK(5) = JJ5 + NTRACKF = NTRACKF+1 + DO I = 1,NBCHAMBER + JJO(I,NTRACKF) = 0 + ENDDO + ICH1 = -1 + DO IST = 1,5 + ICH1 = ICH1 + 2 + IF (XMR(IST,JJK(IST),1).LT.999.) THEN + JJO(ICH1,NTRACKF) = JJK(IST) + XMESO(ICH1,NTRACKF) = XMR(IST,JJK(IST),1) + YMESO(ICH1,NTRACKF) = YMR(IST,JJK(IST),1) + ICH2 = ICH1 + 1 + IF (MANG(IST).EQ.1) THEN + JJO(ICH2,NTRACKF) = JJK(IST) + XMESO(ICH2,NTRACKF) = XMR(IST,JJK(IST),2) + YMESO(ICH2,NTRACKF) = YMR(IST,JJK(IST),2) + ENDIF + ELSE + ICH2 = ICH1+1 + JJO(ICH2,NTRACKF) = JJK(IST) + XMESO(ICH2,NTRACKF) = XMR(IST,JJK(IST),2) + YMESO(ICH2,NTRACKF) = YMR(IST,JJK(IST),2) + ENDIF + ENDDO + + CALL CHFILL(700,SNGL(XVERT),R1,R2) + CALL CHFILL(701,SNGL(YVERT),R1,R2) + + IF (ITCHECK(IT).EQ.1) THEN + + + IF (ID(IP(1,JJ1)).EQ.IDFIND .AND. + & ID(IP(2,JJ2)).EQ.IDFIND .AND. + & ID(IP(3,JJ3)).EQ.IDFIND .AND. + & ID(IP(4,JJ4)).EQ.IDFIND) THEN + + NMUONF = NMUONF+1 ! Bon muon + + PT = SQRT(PVERT1(IP(5,JJ5))**2+PVERT2(IP(5,JJ5))**2) + PZ = PVERT3(IP(5,JJ5)) + E = SQRT(PT**2+PZ**2+0.1056**2) + YRAP = 0.5*DLOG((E+PZ)/(E-PZ)) + PHIM = DATAN2(PVERT2(IP(5,JJ5)),PVERT1(IP(5,JJ5))) + CALL CHFILL(801,SNGL(YRAP),R1,R2) + CALL CHFILL(901,SNGL(PT),R1,R2) + CALL CHFILL(911,SNGL(PHIM),R1,R2) + ELSE + + NGHOST = NGHOST+1 ! ghost + + PT = SQRT(PVERT1(IP(5,JJ5))**2+PVERT2(IP(5,JJ5))**2) + PZ = PVERT3(IP(5,JJ5)) + E = SQRT(PT**2+PZ**2+0.1056**2) + YRAP = 0.5*DLOG((E+PZ)/(E-PZ)) + PHIM = DATAN2(PVERT2(IP(5,JJ5)),PVERT1(IP(5,JJ5))) + CALL CHFILL(802,SNGL(YRAP),R1,R2) + CALL CHFILL(902,SNGL(PT),R1,R2) + CALL CHFILL(912,SNGL(PHIM),R1,R2) + ENDIF + ENDIF + ENDIF + IF (ITCHECK(ITRACK(IP(5,JJ5))).EQ.1) THEN + IF (JJ3.EQ.0) NERR(3) = NERR(3)+1 + IF (JJ3.NE.0) THEN + IF (JJ1.EQ.0) NERR(1) = NERR(1)+1 + IF (JJ2.EQ.0) NERR(2) = NERR(2)+1 + ENDIF + PT = SQRT(PVERT1(IP(5,JJ5))**2+PVERT2(IP(5,JJ5))**2) + PZ = PVERT3(IP(5,JJ5)) + E = SQRT(PT**2+PZ**2+0.1056**2) + YRAP = 0.5*DLOG((E+PZ)/(E-PZ)) + PHIM = DATAN2(PVERT2(IP(5,JJ5)),PVERT1(IP(5,JJ5))) + CALL CHFILL(800,SNGL(YRAP),R1,R2) + CALL CHFILL(900,SNGL(PT),R1,R2) + CALL CHFILL(910,SNGL(PHIM),R1,R2) + ENDIF + + RETURN + END + + +************************************************************************* + SUBROUTINE RECO_SUM +************************************************************************* +* +* +************************************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +* + PARAMETER (MAXHITCH=10000,MAXTRK=50000,MAXHITTOT=20000, + & NBSTATION=5) + PARAMETER (NBCHAMBER=10,NTRMAX=500) +* + COMMON/TRACKFOUT/IEVOUT,NTREVT,JJOUT(NBCHAMBER,NTRMAX), + & ISTAT(NTRMAX),PXZOUT(NTRMAX),TPHIOUT(NTRMAX), + & TALAMOUT(NTRMAX),XVERTOUT(NTRMAX),YVERTOUT(NTRMAX), + & CHI2OUT(NTRMAX), + & XMESOUT(NBCHAMBER,NTRMAX),YMESOUT(NBCHAMBER,NTRMAX) + & ,PXVOUT(NTRMAX),PYVOUT(NTRMAX),PZVOUT(NTRMAX) +* + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) +* + COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), + & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), + & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), + & ZVERT(MAXHITTOT),NHITTOT +* + COMMON/RECOUT/JJO(NBCHAMBER,NTRMAX),XMESO(NBCHAMBER,NTRMAX), + & YMESO(NBCHAMBER,NTRMAX) +* + COMMON/TRACKSUM/NRES(5),NRESF,NTRMUALL,NMUONALL,NGHOSTALL, + & NTRACKFALL,NERRALL(NBSTATION),IR +* + COMMON/PRECSUM/NRESF1,NMUONALL1,NGHOSTALL1,NTRACKFALL1 +* + REAL*4 PXR,PYR,PZR,ZVR,CHI2R,PXV,PYV,PZV + COMMON/PAWCR4/IEVR,NTRACKR,ISTATR(NTRMAX),ISIGNR(NTRMAX), + & PXR(NTRMAX),PYR(NTRMAX),PZR(NTRMAX),ZVR(NTRMAX), + & CHI2R(NTRMAX),PXV(NTRMAX),PYV(NTRMAX),PZV(NTRMAX) +* + COMMON/DEBEVT/IDEBUG +* + NMUF = 0 + NGHF = 0 + DO ITR = 1,NTREVT + NTRACKFALL1 = NTRACKFALL1 + 1 + IF (ISTAT(ITR).EQ.1) THEN + NMUF = NMUF + 1 + NMUONALL1 = NMUONALL1 + 1 + ELSEIF (ISTAT(ITR).EQ.2) THEN + NGHF = NGHF + 1 + NGHOSTALL1 = NGHOSTALL1 + 1 + ENDIF + ENDDO + IF (NMUF.EQ.2) NRESF1 = NRESF1 + 1 +* + NTRACKR = NTREVT + DO ITR = 1,NTREVT + ISTATR(ITR) = ISTAT(ITR) + ISIGNR(ITR) = 1 + IF (PXZOUT(ITR).LT.0.) ISIGNR(ITR) = -1 + PXZ = ABS(PXZOUT(ITR)) + PHI = ATAN(TPHIOUT(ITR)) + ALAM = ATAN(TALAMOUT(ITR)) + PYR(ITR) = PXZ*SIN(PHI) + PXR(ITR) = PXZ*TAN(ALAM) + PZR(ITR) = PXZ*COS(PHI) + ZVR(ITR) = 0. + CHI2R(ITR) = CHI2OUT(ITR) + PXV(ITR) = PXVOUT(ITR) + PYV(ITR) = PYVOUT(ITR) + PZV(ITR) = PZVOUT(ITR) + ENDDO + + CALL CHFNT(IEVR,NTRACKR,ISTATR,ISIGNR, + & PXR,PYR,PZR,ZVR,CHI2R,PXV,PYV,PZV) + + IF (IDEBUG.GE.2) THEN + PRINT *,'RECO_SUM evt number :',IEVOUT + PRINT *,'RECO_SUM nb of track /evt :',NTREVT + PRINT *,'RECO_SUM nb of good muon /evt :',NMUF + PRINT *,'RECO_SUM nb of ghost /evt :',NGHF + IF (NTREVT.GT.0) THEN + DO ITR = 1,NTREVT + PRINT *,'RECO_SUM track number :',ITR + PRINT *,'RECO_SUM PXZOUT :',PXZOUT(ITR) + PRINT *,'RECO_SUM CHI2OUT :',CHI2OUT(ITR) + PRINT *,' PX GEANT= ', PXV(ITR),' PX RECONS= ',PYR(ITR) + PRINT *,' PY GEANT= ', PYV(ITR),' PY RECONS= ',PXR(ITR) + PRINT *,' PZ GEANT= ', PZV(ITR),' PZ RECONS= ',PZR(ITR) + PXZV = SQRT( PYV(ITR)**2+PZV(ITR)**2) + PXZR = SQRT( PXR(ITR)**2+PZR(ITR)**2) + PRINT *,' PXZ GEANT= ', PXZV,' PXZ RECONS= ',PXZR + FIV=ATAN2(PYV(ITR),PZV(ITR)) + ALAMV=ATAN2(PXV(ITR),PXZV) + FIR=ATAN2(PXR(ITR),PZR(ITR)) + ALAMR=ATAN2(PYR(ITR),PXZR) +** PRINT *,' PHI GEANT= ',FIV,' PXZ RECONS= ',FIR +** PRINT *,' ALAM GEANT= ',ALAMV,' ALAM RECONS= ',ALAMR + ENDDO + ENDIF + ENDIF + + RETURN + END + +************************************************************************* + SUBROUTINE RECO_TERM +************************************************************************* +* +* +************************************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +* + PARAMETER(NBSTATION=5) +* + COMMON/TRACKSUM/NRES(5),NRESF,NTRMUALL,NMUONALL,NGHOSTALL, + & NTRACKFALL,NERRALL(NBSTATION),IR +* + COMMON/PRECSUM/NRESF1,NMUONALL1,NGHOSTALL1,NTRACKFALL1 +* + COMMON/DEBEVT/IDEBUG +* + CHARACTER*50 FILEBKG,FILERES,FILEOUT,FILEMIN +* + IF (IDEBUG.GE.1) THEN + PRINT *,' ' + PRINT *,'RECO_TERM ***** SUMMARY TRACK-FINDING *****' + PRINT *,'RECO_TERM nb of resonances :',NRES(5) + PRINT *,'RECO_TERM nb of resonances 45 :',NRES(1) + PRINT *,'RECO_TERM nb of resonances 345 :',NRES(2) + PRINT *,'RECO_TERM nb of resonances found :',NRESF + PRINT *,'RECO_TERM nb of muon track :',NTRMUALL + PRINT *,'RECO_TERM nb of track found :',NTRACKFALL + PRINT *,'RECO_TERM nb of muon track found :',NMUONALL + PRINT *,'RECO_TERM nb of ghost found :',NGHOSTALL + DO I = 1,4 + PRINT *,'RECO_TERM nb of error in st',I,':',NERRALL(I) + ENDDO + + PRINT *,' ' + PRINT *,'RECO_TERM ***** SUMMARY PRECISION *****' + PRINT *,'RECO_TERM nb of resonances found :',NRESF1 + PRINT *,'RECO_TERM nb of track found :',NTRACKFALL1 + PRINT *,'RECO_TERM nb of muon track found :',NMUONALL1 + PRINT *,'RECO_TERM nb of ghost found :',NGHOSTALL1 + ENDIF +* + CALL HIST_CLOSED + + RETURN + END + +************************************************************************* + SUBROUTINE RECO_PRECISION +************************************************************************* +* +* +************************************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +* + PARAMETER (MAXHITCH=10000,MAXTRK=50000,MAXHITTOT=20000, + & NBSTATION=5,MAXCAN=1000,NTRMAX=500) + PARAMETER (NPLANE=10) +* + COMMON/PARAM/ZPLANEP(NPLANE),THICK,XPREC,YPREC,B0,BL3,ZMAGS, + & ZMAGE,ZABS,XMAG,ZBP1,ZBP2,CONST +* + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) +* + COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), + & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), + & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), + & ZVERT(MAXHITTOT),NHITTOT +* + COMMON/TRACKFOUT/IEVOUT,NTREVT,JJOUT(NPLANE,NTRMAX), + & ISTAT(NTRMAX),PXZOUT(NTRMAX),TPHIOUT(NTRMAX), + & TALAMOUT(NTRMAX),XVERTOUT(NTRMAX),YVERTOUT(NTRMAX), + & CHI2OUT(NTRMAX), + & XMESOUT(NPLANE,NTRMAX),YMESOUT(NPLANE,NTRMAX) + & ,PXVOUT(NTRMAX),PYVOUT(NTRMAX),PZVOUT(NTRMAX) + +* + COMMON/MEAS/LPLANE(NPLANE),XMP(NPLANE),YMP(NPLANE) +* + COMMON/FCNOUT/PXZEA,ALAMEA,PHIEA,XEA,YEA,NPLU,CHI2 +* + COMMON/PRECCUT/PCUT,PTCUT,CHI2CUT +* + DIMENSION PARMU(MAXCAN,NPLANE,2),LPLANEMU(MAXCAN,NPLANE) +* + IF (NTREVT.EQ.0) RETURN + + DO ITR = 1,NTREVT + ICH = 0 + DO IST = 1,NBSTATION + DO ILOOP = 1,2 + ICH = ICH + 1 +** print *,' ich=',ich + IF (JJOUT(ICH,ITR).GT.0) THEN + LPLANEMU(ITR,ICH) = 1 + PARMU(ITR,ICH,1) = XMESOUT(ICH,ITR) + PARMU(ITR,ICH,2) = YMESOUT(ICH,ITR) +** print *,' x,y ', PARMU(ITR,ICH,1),PARMU(ITR,ICH,2) + ELSE + LPLANEMU(ITR,ICH) = 0 + ENDIF + ENDDO + ENDDO + ENDDO +* + NTRACK = 0 + DO ICAN = 1,NTREVT + DO ICH = 1,NPLANE + LPLANE(ICH) = LPLANEMU(ICAN,ICH) + XMP(ICH) = PARMU(ICAN,ICH,1) + YMP(ICH) = PARMU(ICAN,ICH,2) + ENDDO + + IF (LPLANE(1).GT.0) THEN + X1 = XMP(1) + Y1 = YMP(1) + IPL1 = 1 + ELSE + X1 = XMP(2) + Y1 = YMP(2) + IPL1 = 2 + ENDIF + IF (LPLANE(3).GT.0) THEN + X2 = XMP(3) + Y2 = YMP(3) + IPL2 = 3 + ELSE + X2 = XMP(4) + Y2 = YMP(4) + IPL2 = 4 + ENDIF + IF (LPLANE(7).GT.0) THEN + X3 = XMP(7) + IPL3 = 7 + ELSE + X3 = XMP(8) + IPL3 = 8 + ENDIF + IF (LPLANE(9).GT.0) THEN + X4 = XMP(9) + IPL4 = 9 + ELSE + X4 = XMP(10) + IPL4 = 10 + ENDIF + + PHIAV = DATAN2((X2-X1),(ZPLANEP(IPL2)-ZPLANEP(IPL1))) + PHIAP = DATAN2((X4-X3),(ZPLANEP(IPL4)-ZPLANEP(IPL3))) + DPHI = (PHIAP-PHIAV) + ASIGN = 1. + IF (DPHI.LT.0.) ASIGN = -1. ! CCC + PXZ = CONST/DABS(DPHI) +** Cuts PXZ + IF (PXZ.LT.PCUT) GO TO 2 + + PXZINVI = ASIGN/PXZ ! CCC +** PXZINVI = 1./PXZOUT(ICAN) ! CCC +** PXZINVI = -1./49. ! CCC + PHII = PHIAV + ALAMI = DATAN2((Y2-Y1),DSQRT((X2-X1)**2 + & +(ZPLANEP(IPL2)-ZPLANEP(IPL1))**2)) + XVR = X1 + YVR = Y1 +** print *,' avant prec_fit pxzi phii alami x y',1./ PXZINVI, +** & PHII, ALAMI ,XVR,YVR +** PRINT *,' X1 X2 X3 X4',X1,X2,X3,X4 +** PRINT *,' Z1 Z2 Z3 Z4',ZPLANEP(IPL1),ZPLANEP(IPL2), +** & ZPLANEP(IPL3),ZPLANEP(IPL4) +** PRINT *,' CONST= ',CONST + + PRINT *,' RECO_PRECISION CHI2OUT avant fit ',CHI2OUT(ICAN) + + IF (CHI2OUT(ICAN).GT.CHI2CUT) GO TO 2 + +** Fit des traces apres l'absorbeur + CALL PREC_FIT (PXZINVI,PHII,ALAMI,XVR,YVR, + & PXZINVF,PHIF,ALAMF,XVERTF,YVERTF,EPXZINV,EPHI,EALAM, + & EXVERT,EYVERT) + +** Correction de Branson + CALL BRANSON(PXZEA,PHIEA,ALAMEA,XEA,YEA) + + PXZ1 = DABS(PXZEA) + PX1 = PXZ1*DSIN(PHIEA) + PY1 = PXZ1*DTAN(ALAMEA) + PT1 = DSQRT(PX1**2+PY1**2) +** Cuts PT + IF (PT1.LT.PTCUT) GO TO 2 +** Cuts CHI2 + IF ((CHI2/FLOAT(2*NPLU-5)).GT.CHI2CUT) GO TO 2 + + NTRACK = NTRACK + 1 + DO ICH = 1,NPLANE + JJOUT(ICH,NTRACK) = JJOUT(ICH,ICAN) + XMESOUT(ICH,NTRACK) = XMESOUT(ICH,ICAN) + YMESOUT(ICH,NTRACK) = YMESOUT(ICH,ICAN) + ENDDO + ISTAT(NTRACK) = ISTAT(ICAN) + PXZOUT(NTRACK) = PXZEA + TPHIOUT(NTRACK) = DTAN(PHIEA) + TALAMOUT(NTRACK) = DTAN(ALAMEA) + XVERTOUT(NTRACK) = XEA + YVERTOUT(NTRACK) = YEA + CHI2OUT(NTRACK) = CHI2/FLOAT(2*NPLU-5) + + PRINT *,' RECO_PRECISION CHI2OUT apres fit',CHI2OUT(NTRACK) + +** print *,' reco_precision pxz tphi talam xvert yvert chi2', +** & PXZEA,PHIEA,ALAMEA, +** & XEA,YEA,CHI2/FLOAT(2*NPLU-5) + 2 CONTINUE + ENDDO + NTREVT = NTRACK + + RETURN + END + + +************************************************************************ + SUBROUTINE ORDONNE_HIT(ICH,HCUT) +************************************************************************** +* +* Sort hits in station ICH according to the "impact parameter" HHIT +* +************************************************************************** + + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER (MAXHITCH=10000,MAXTRK=50000,MAXHITTOT=20000, + & NBSTATION=5) + + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) + + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) + + COMMON/VERIFGEANT/ITTROUGH(MAXTRK,NBSTATION), + & IT_LIST(MAXTRK),IT_NP(MAXTRK),ITCHECK(MAXTRK), + & ITRACK(MAXHITTOT) + + COMMON/HCHHIT/HHIT(MAXHITCH),INDEXTAB(MAXHITCH),INDEXMAX +* + COMMON/DEBEVT/IDEBUG +* + REAL*4 H4(MAXHITCH) +* tri des impulsion par ordre decroissant +* le tab INDEXTAB contient les j ordonnes +* INDEXMAX est l indice max du tableau = NBHIT si pas de contrainte + + JJ=0 + INDEXMAX = 0 +* boucle sur le nombre de hits candidats de la station + + DO J=1,JHIT(ICH) + + IF (PHM(ICH,J).LT.6.3) THEN !2pi=6.3 radian + JJ=JJ+1 +* calcul du h dans XOY a z=0 + HHIT(J)=ABS(XM(ICH,J)-ZPLANE(ICH)*PHM(ICH,J)) +* cut en Pxz + IF (HHIT(J).LT.HCUT) THEN + INDEXMAX=INDEXMAX+1 + INDEXTAB(INDEXMAX)=J + ELSEIF(ITCHECK(ITRACK(IP(ICH,J))).EQ.1) THEN + IF (IDEBUG.GE.2) THEN + PRINT *,'ORDONNE_HIT rejet muon/res in st.',ICH, + & ' h=',HHIT(J) + ENDIF + ENDIF + ENDIF + ENDDO + + NBHIT=JHIT(ICH) + + DO I = 1,NBHIT + H4(I) = SNGL(HHIT(I)) + ENDDO + + CALL SORTZV(H4,INDEXTAB,INDEXMAX,-1,0,1) + + DO I = 1,NBHIT + HHIT(I) = DBLE(H4(I)) + ENDDO +** PRINT *,'ORDONNE st. numero',ICH +** PRINT *,'ORDONNE nb de hits initiaux dans st.',ICH,':',JHIT(ICH) +** PRINT *,'ORDONNE nb de hits avec mes. angulaire:',JJ +** PRINT *,'ORDONNE nb de hits avec mes. ang. et cut en Pxz:',INDEXMAX + IF (IDEBUG.GE.2) THEN + PRINT *,'ORDONNE_HIT nb de hits accepte dans st.',ICH,':', + & INDEXMAX + ENDIF + + RETURN + END +*********************************************************************************** + SUBROUTINE DISTMIN4(X1,Y1,PHI1,ALAM1,ICH,EX,EY,EPHI,ELAM,IFIND) +*********************************************************************************** +* Find the nearest hit in station ICH in the (X,Y,lambda,phi) phase space +* +*********************************************************************************** + + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER (MAXHITCH=10000,NBSTATION=5) + + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) + + IFIND = 0 + DISTMIN=4. + DO I=1,JHIT(ICH) + IF (PHM(ICH,I).LE.6.3) THEN ! angles measured + IF (ABS(PHI1-PHM(ICH,I)) .LT. EPHI .AND. + & ABS(ALAM1-ALM(ICH,I)) .LT. ELAM .AND. + & ABS(X1-XM(ICH,I)) .LT. EX .AND. + & ABS(Y1-YM(ICH,I)) .LT. EY) THEN + DIST = ((PHI1-PHM(ICH,I))/EPHI)**2 + + & ((ALAM1-ALM(ICH,I))/ELAM)**2 + + & ((X1-XM(ICH,I))/EX)**2 + + & ((Y1-YM(ICH,I))/EY)**2 + IF (DIST .LT. DISTMIN) THEN + DISTMIN = DIST + IFIND = I + ENDIF + ENDIF + ENDIF + ENDDO + + RETURN + END +*********************************************************************************** + SUBROUTINE DISTMIN2(X1,Y1,X2,Y2,ICH,EX1,EY1,EX2,EY2,IFIND) +*********************************************************************************** +* Find the nearest hit in station ICH in the (X,Y) space +* +*********************************************************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER (MAXHITCH=10000,NBSTATION=5) + + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) + + IFIND = 0 + DISTMIN=2. + DO I=1,JHIT(ICH) + IF (IZM(ICH,I).EQ.1) THEN + X = X1 + Y = Y1 + ELSE + X = X2 + Y = Y2 + ENDIF + EX = EX1 + EY = EY1 + IF (ICH.EQ.4.OR.ICH.EQ.5) THEN + IF (IZM(ICH,I).EQ.1) THEN + EX = EX1 + EY = EY1 + ELSE + EX = EX2 + EY = EY2 + ENDIF + ENDIF + IF (ABS(X-XM(ICH,I)) .LT. EX .AND. + & ABS(Y-YM(ICH,I)) .LT. EY) THEN + DIST = ((X-XM(ICH,I))/EX)**2 + + & ((Y-YM(ICH,I))/EY)**2 + IF (DIST .LT. DISTMIN) THEN + DISTMIN = DIST + IFIND = I + ENDIF + ENDIF + ENDDO + + RETURN + END +******************************************************************************** + SUBROUTINE H_ACCEPTANCE(ICH) +******************************************************************************** +* Etude de l'acceptance des resonnances en fonction du H +* dans la station ICH +* +* INPUT : ICH +* OUTPUT : Histo #1 +******************************************************************************** + + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER (MAXHITCH=10000,MAXTRK=50000,MAXHITTOT=20000, + & NBSTATION=5) + + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) + + COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), + & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), + & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), + & ZVERT(MAXHITTOT),NHITTOT + + + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) + + COMMON/VERIFGEANT/ITTROUGH(MAXTRK,NBSTATION), + & IT_LIST(MAXTRK),IT_NP(MAXTRK),ITCHECK(MAXTRK), + & ITRACK(MAXHITTOT) + + COMMON/HCHHIT/HHIT(MAXHITCH),INDEXTAB(MAXHITCH),INDEXMAX + + REAL*4 R1,R2 + DATA R1,R2/0.,1./ + + NMUONI = 0 + DO J = 1,JHIT(ICH) + IF (ITYP(IP(ICH,J)).EQ.5.OR.ITYP(IP(ICH,J)).EQ.6) THEN + ISTAK = ID(IP(ICH,J)) + ISTAK = MOD(ISTAK,30000) + ISTAK = MOD(ISTAK,10000) + IF (ISTAK.EQ.0) THEN +** PRINT *,'ACCEPT. id du muon dans st.',ICH,':',ITYP(IP(ICH,J)) + NMUONI = NMUONI+1 + ENDIF + ENDIF + ENDDO +* PRINT *,'ACCEPT. nb de muons/res total dans st.',ICH,':',NMUONI +* pause + + DO IH = 1,500 + HCUT = IH +* Sort hits in st. z + CALL ORDONNE_HIT(ICH,HCUT) + NMUON = 0 + DO IND = 1,INDEXMAX + IIND = IP(ICH,INDEXTAB(IND)) + IDPART = ITYP(IIND) + ISTAK = ID(IIND) + ISTAK = MOD(ISTAK,30000) + ISTAK = MOD(ISTAK,10000) +** PRINT *,' IDPART=',IDPART,' ISTAK=',ISTAK + IF (IDPART.EQ.5.OR.IDPART.EQ.6.AND.ISTAK.EQ.0) THEN + NMUON = NMUON+1 + ENDIF + ENDDO + IF (NMUON.EQ.2.AND.NMUONI.EQ.2) THEN + CALL CHFILL(ICH*100,SNGL(HCUT),R1,R2) + ENDIF + ENDDO + + RETURN + END + +******************************************************************************** + SUBROUTINE OLDFOLLOW(ZSTR,PEST,IFLAG,XPL,YPL,PHPL,ALPL) +******************************************************************************** +* Calculate the particle trajectory in the spectrometer and +* (XPL,YPL,PHPL,ALPL) +* for the 5 stations. +* +******************************************************************************** + IMPLICIT DOUBLE PRECISION (A-H,O-Z) +* + PARAMETER(NBSTATION=5) +* + DIMENSION XPL(NBSTATION,2),YPL(NBSTATION,2),PHPL(NBSTATION), + & ALPL(NBSTATION),PEST(NBSTATION) + + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) + + COMMON /MEASUR/XMES(NBSTATION),YMES(NBSTATION),IZMES(NBSTATION), + & PHMES(NBSTATION),ALMES(NBSTATION),MPOS(NBSTATION), + & MANG(NBSTATION) + COMMON /MAGNET/BL3,B0 + + LOGICAL LFLAG, LFLAG1 + + XSTR = PEST(4) + YSTR = PEST(5) + PXZINV = PEST(1) + TPHI = PEST(2) + PHI = ATAN(TPHI) + TALAM = PEST(3) + PXZ = 1.0/PXZINV + PY = ABS(PXZ)*TALAM + PX = -ABS(PXZ)*SIN(PHI) + PZ = -ABS(PXZ)*COS(PHI) + PXY = SQRT(PX**2 + PY**2) + FI=ATAN2(PY,PX) + SINFI = SIN(FI) + COSFI = COS(FI) + TTHET = PZ/PXY + RS = PXY*(100.0/(0.299792458*BL3)) + IF(PXZINV.LT.0.0) RS = -RS +* XC = XSTR + RS*SIN(FI) +* YC = YSTR - RS*COS(FI) + PX0 = PX + PY0 = PY + LFLAG = .TRUE. + LFLAG1 = .TRUE. +* PRINT *, XC,YC,RS,FI,TTHET,PXY,PZ + + DO J = 1,5 + + IF (IFLAG.EQ.3 .OR. MPOS(J).EQ.1) THEN + IF(ZPLANE(J) .GT. ZCOIL) THEN +* DFI = (ZPLANE(J)-ZSTR)/(TTHET*RS) +* FIN = FI - DFI +* XPL(J,1) = XC - RS*SIN(FIN) +* YPL(J,1) = YC + RS*COS(FIN) + DFR = (ZPLANE(J)-ZSTR)/TTHET + XPL(J,1) = XSTR + DFR*COSFI + 0.5D0*DFR*DFR*SINFI/RS + YPL(J,1) = YSTR + DFR*SINFI - 0.5D0*DFR*DFR*COSFI/RS + DFR2 = (ZPLANE(J)-DZ_PL(J)-ZSTR)/TTHET + XPL(J,2) = XSTR + DFR2*COSFI + 0.5D0*DFR2*DFR2*SINFI/RS + YPL(J,2) = YSTR + DFR2*SINFI - 0.5D0*DFR2*DFR2*COSFI/RS + IF (IFLAG.EQ.3 .OR. MANG(J).EQ.1) THEN +* PX=PXY*COS(FIN) +* PY=PXY*SIN(FIN) + PX = PX0 + DFR * (PY0 - 0.5D0*PX0*DFR/RS) / RS + PY = PY0 - DFR * (PX0 + 0.5D0*PY0*DFR/RS) / RS + PHPL(J)=ATAN(PX/PZ) + ALPL(J)=ATAN(PY/SQRT(PX**2+PZ**2)) + ENDIF + ELSE + IF( LFLAG) THEN +* DFI = (ZCOIL-ZSTR)/(TTHET*RS) +* FIN = FI - DFI +* XCOIL = XC - RS*SIN(FIN) +* YCOIL = YC + RS*COS(FIN) + DFR = (ZCOIL-ZSTR)/TTHET + XCOIL = XSTR + DFR*COSFI + 0.5D0*DFR*DFR*SINFI/RS + YCOIL = YSTR + DFR*SINFI - 0.5D0*DFR*DFR*COSFI/RS +* PX=PXY*COS(FIN) +* PY=PXY*SIN(FIN) + PX = PX0 + DFR * (PY0 - 0.5D0*PX0*DFR/RS) / RS + PY = PY0 - DFR * (PX0 + 0.5D0*PY0*DFR/RS) / RS + PXZ = SQRT(PX**2 + PZ**2) + PHI=ATAN(PX/PZ) + TALAM = PY/PXZ + ALAM = ATAN(TALAM) + RD = PXZ*(100.0/(0.299792458*B0)) + IF(PXZINV.LT.0.0) RD = -RD + ZC = ZCOIL - RD*SIN(PHI) + XC = XCOIL + RD*COS(PHI) + IF(ABS(ZMAGEND-ZC).GT.ABS(RD)) STOP 'FOLLOW' + LFLAG = .FALSE. + ENDIF + IF(ZPLANE(J) .GT. ZMAGEND) THEN + FIN = ASIN((ZPLANE(J) - ZC)/RD) + XPL(J,1)= XC - RD*COS(FIN) + YPL(J,1)= YCOIL - RD*(FIN - PHI)*TALAM + FIN2 = ASIN((ZPLANE(J)-DZ_PL(J) - ZC)/RD) + XPL(J,2)= XC - RD*COS(FIN2) + YPL(J,2)= YCOIL - RD*(FIN2 - PHI)*TALAM + PHPL(J)=FIN + ALPL(J)=ALAM + ELSE + IF (LFLAG1) THEN + FIN = ASIN((ZMAGEND - ZC)/RD) + XMAGEND = XC - RD*COS(FIN) + YMAGEND = YCOIL - RD*(FIN - PHI)*TALAM + TPHI = TAN(FIN) + CPHI = COS(FIN) + LFLAG1 = .FALSE. + ENDIF + XPL(J,1) = XMAGEND + (ZPLANE(J)-ZMAGEND)*TPHI + YPL(J,1) = YMAGEND - (ZPLANE(J)-ZMAGEND)*TALAM/CPHI + XPL(J,2) = XMAGEND + (ZPLANE(J)-DZ_PL(J)-ZMAGEND)*TPHI + YPL(J,2) = YMAGEND - (ZPLANE(J)-DZ_PL(J)-ZMAGEND)* + & TALAM/CPHI + PHPL(J)=FIN + ALPL(J)=ALAM + ENDIF + ENDIF + ENDIF + ENDDO + RETURN + END +******************************************************************************** + SUBROUTINE FOLLOW(ZSTR,PEST,IFLAG,XPL,YPL,PHPL,ALPL) +******************************************************************************** +* Calculate the particle trajectory in the spectrometer +* (XPL,YPL,PHPL,ALPL) +* for the 5 stations. +* Runge Kutta +******************************************************************************** + IMPLICIT DOUBLE PRECISION (A-H,O-Z) +* + PARAMETER(NBSTATION=5,NPLANE=10) +* + DIMENSION XPL(NBSTATION,2),YPL(NBSTATION,2),PHPL(NBSTATION), + & ALPL(NBSTATION),PEST(NBSTATION) + + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) + + COMMON/PARAM/ZPLANEP(NPLANE),THICK,XPREC,YPREC,B0,BL3,ZMAGS, + & ZMAGE,ZABS,XMAG,ZBP1,ZBP2,CONST + + COMMON /MEASUR/XMES(NBSTATION),YMES(NBSTATION),IZMES(NBSTATION), + & PHMES(NBSTATION),ALMES(NBSTATION),MPOS(NBSTATION), + & MANG(NBSTATION) + + + DIMENSION VECT(7),VOUT(7) + + STEP = 6. ! 1 cm + NSTEPMAX = 5000 + + ASIGN = 1. + IF (PEST(1).LT.0.) ASIGN = -1. + TPHI = -1.*PEST(2) + PHI = DATAN(TPHI) + TALAM = PEST(3) + ALAM = DATAN(TALAM) + PXZ = DABS(1./PEST(1)) + + PX = PXZ*DSIN(PHI) + PY = PXZ*DTAN(ALAM) + PZ = PXZ*DCOS(PHI) + PTOT = PXZ/DCOS(ALAM) + + VECT(1) = PEST(4) + VECT(2) = PEST(5) + VECT(3) = 0. + VECT(4) = PX/PTOT + VECT(5) = PY/PTOT + VECT(6) = PZ/PTOT + VECT(7) = PTOT + + Z = VECT(3) + NSTEP = 0 +* +** Runge Kutta +** PRINT *,' AV GRKUTA ASIGN',ASIGN,' THET',THET + ISTOLD = 0 + DO ICH = 1,NPLANE + + IST = INT(FLOAT(ICH+1)/2.) + + + DO WHILE (Z.GE.0..AND.Z.LT.ABS(ZPLANEP(ICH)) + & .AND.NSTEP.LE.NSTEPMAX) + NSTEP = NSTEP+1 +** WRITE(6,*) NSTEP,(VECT(I),I=1,7) + CALL RECO_GRKUTA (ASIGN,STEP,VECT,VOUT) + DO I = 1,7 + VECT(I) = VOUT(I) + ENDDO + Z = VECT(3) + ENDDO + IF (IST.NE.ISTOLD) THEN + IPCH = 1 + ELSE + IPCH = 2 + ENDIF + XPL(IST,IPCH) = VECT(1)-(Z-ABS(ZPLANEP(ICH)))*VECT(4)/VECT(6) + YPL(IST,IPCH) = VECT(2)-(Z-ABS(ZPLANEP(ICH)))*VECT(5)/VECT(6) + IF (IPCH.EQ.2) THEN + DX = XPL(IST,2)-XPL(IST,1) + DY = YPL(IST,2)-YPL(IST,1) + PHPL(IST) = -1.*DATAN2(DX,DZ_PL(IST)) + ALPL(IST) = DATAN2(DY,DSQRT(DX**2+DZ_PL(IST)**2)) + ENDIF + ISTOLD = IST + ENDDO +** print *,' vect= ',vect(1),vect(2),vect(3),vect(4),vect(5), +** & vect(6),vect(7) + + + RETURN + END +******************************************************************************* + SUBROUTINE FCN(NPAR,GRAD,FVAL,PEST,IFLAG,FUTIL) +******************************************************************************* +* Calculate FVAL=CHI2 the function minimized by minuit for a given track +* +******************************************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER(NBSTATION=5) + +* DIMENSION PEST(*),GRAD(*) + DIMENSION PEST(5),GRAD(5) + DIMENSION PEEST(NBSTATION) + + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) + + + COMMON/PRECIS/EEXM(NBSTATION),EEYM(NBSTATION),EEPH(NBSTATION), + & EEAL(NBSTATION) + + COMMON /MEASUR/XMES(NBSTATION),YMES(NBSTATION),IZMES(NBSTATION), + & PHMES(NBSTATION),ALMES(NBSTATION), MPOS(NBSTATION), + & MANG(NBSTATION) + + COMMON /PLANE/XPL(NBSTATION,2),YPL(NBSTATION,2),PHPL(NBSTATION), + & ALPL(NBSTATION),CHI2PL + + COMMON/VERTEX/ERRV,IVERTEX + + PEEST(1)=PEST(1) + PEEST(2)=PEST(2) + PEEST(3)=PEST(3) + IF(IVERTEX.EQ.1) THEN + PEEST(4)=PEST(4) ! position du vertex + PEEST(5)=PEST(5) + ELSE + PEEST(4)=0.0D0 + PEEST(5)=0.0D0 + ENDIF + + CALL FOLLOW (0.0D0,PEEST,IFLAG,XPL,YPL,PHPL,ALPL) ! calcul des + IF(IFLAG.EQ.1) THEN ! points d impacts dans les + PRINT *,'FCN ',XPL(4,1),XMES(4) ! plans + PRINT *,'FCN ',YPL(4,1),YMES(4) + PRINT *,'FCN ',XPL(5,1),XMES(5) + PRINT *,'FCN ',YPL(5,1),YMES(5) + ENDIF + +* IF (IVERTEX.EQ.1) THEN +* FVAL = (PEST(4)/ERRV)**2 + (PEST(5)/ERRV)**2 +* ELSE + FVAL = 0.0D0 +* ENDIF + NPLPL = 0 + DO J = 1,NBSTATION + IF (MPOS(J).EQ.1) THEN + NPLPL = NPLPL+1 + XPLC = XPL(J,IZMES(J)) + YPLC = YPL(J,IZMES(J)) + FF = (XMES(J) - XPLC)/EEXM(J) + FVAL =FVAL + FF**2 + FF = (YMES(J) - YPLC)/EEYM(J) + FVAL =FVAL + FF**2 + ENDIF + IF (MANG(J).EQ.1) THEN + NPLPL = NPLPL+1 + FF = (PHMES(J) - PHPL(J))/EEPH(J) + FVAL =FVAL + FF**2 + FF = (ALMES(J) - ALPL(J))/EEAL(J) + FVAL =FVAL + FF**2 + ENDIF + ENDDO +** PRINT *,'ST 1',XPL(1,1),XMES(1),YPL(1,1),YMES(1) +** PRINT *,'ST 2',XPL(2,1),XMES(2),YPL(2,1),YMES(2) +** PRINT *,'ST 3',XPL(3,1),XMES(3),YPL(3,1),YMES(3) +** PRINT *,'ST 4',XPL(4,1),XMES(4),YPL(4,1),YMES(4) +** PRINT *,'ST 5',XPL(5,1),XMES(5),YPL(5,1),YMES(5) + NPARAM = 3 + IF (IVERTEX.EQ.1) NPARAM = 5 + CHI2PL = FVAL/FLOAT(2*NPLPL-NPARAM) + + RETURN + END +******************************************************************************** + SUBROUTINE STOCK_CANDIDAT(ICH1,JHITCH1,ICH2,IFIND,EXM,EYM,EPH,EAL, + & NCAN,ICODE) +******************************************************************************** +* Fill common CANDIDAT with track candidates from the search in stations 4&5 +* +******************************************************************************** + + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER (MAXHITTOT=20000,MAXHITCH=10000,NBSTATION=5,MAXCAN=1000) + + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) + + COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), + & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), + & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), + & ZVERT(MAXHITTOT),NHITTOT + + + COMMON/CANDIDAT/JCAN(NBSTATION,MAXCAN),JCANTYP(MAXCAN), + & EEX(MAXCAN),EEY(MAXCAN),EEP(MAXCAN),EEA(MAXCAN) + +** PRINT *,'STOCK st. init.=',ICH1,'id. init.=',ID(IP(ICH1,JHITCH1)) +** PRINT *,'STOCK st. finale=',ICH2,'id. final=',ID(IP(ICH2,IFIND)) +** PRINT *,'STOCK ifind=',IFIND +** PRINT *,'STOCK icode=',ICODE + NCAN = NCAN+1 + JCAN(ICH1,NCAN) = JHITCH1 + JCAN(ICH2,NCAN) = IFIND + JCANTYP(NCAN) = ICODE + EEX(NCAN) = EXM + EEY(NCAN) = EYM + EEP(NCAN) = EPH + EEA(NCAN) = EAL + + RETURN + END +***************************************************************************** + SUBROUTINE CHECK_HISTO4(IDHIST,ICH2,IHIT2,ICH1,IHIT1, + & X1,Y1,PHI1,ALAM1,P1,EXM,EYM,EPH,EAL) +***************************************************************************** +* Check hit IHIT2 with GEANT informations from hit HIT1 +* +* INPUT : ICH2 : No st. de recherche +* IDCH1,X1,Y1,PHI1,ALAM1,P1 : Trace de reference +* OUTPUT : JOK : No hit dans ICH2 appartenant a la meme trace. +* +***************************************************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER (MAXHITCH=10000,MAXHITTOT=20000,NBSTATION=5, + & MAXTRK=50000) + + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) + + COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), + & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), + & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), + & ZVERT(MAXHITTOT),NHITTOT + + COMMON/VERIFGEANT/ITTROUGH(MAXTRK,NBSTATION), + & IT_LIST(MAXTRK),IT_NP(MAXTRK),ITCHECK(MAXTRK), + & ITRACK(MAXHITTOT) +* + COMMON/DEBEVT/IDEBUG + + REAL*4 R2 + DATA R2/1./ + + JOK = 0 + + DO I=1,JHIT(ICH2) + IF (PHM(ICH2,I).LE.6.3) THEN + IF (ID(IP(ICH1,IHIT1)).EQ.ID(IP(ICH2,I))) THEN + JOK = I + IF (IDHIST.GT.0) THEN + CALL CHFILL2(IDHIST,SNGL(P1), + & SNGL((X1-XM(ICH2,I))**2),1.) + CALL CHFILL2(IDHIST+1,SNGL(P1), + & SNGL((Y1-YM(ICH2,I))**2),1.) + CALL CHFILL2(IDHIST+2,SNGL(P1), + & SNGL((PHI1-PHM(ICH2,I))**2),1.) + CALL CHFILL2(IDHIST+3,SNGL(P1), + & SNGL((ALAM1-ALM(ICH2,I))**2),1.) + CALL CHF1(400+IDHIST, + & SNGL(X1-XM(ICH2,I)),1.) + CALL CHF1(400+IDHIST+1, + & SNGL(Y1-YM(ICH2,I)),1.) + CALL CHF1(400+IDHIST+2, + & SNGL(PHI1-PHM(ICH2,I)),1.) + CALL CHF1(400+IDHIST+3, + & SNGL(ALAM1-ALM(ICH2,I)),1.) + CALL CHF1(IDHIST+4,SNGL(P1),R2) + ENDIF + ENDIF + ENDIF + ENDDO + + IF (JOK.GT.0) THEN + IF (ITCHECK(ITRACK(IP(ICH1,IHIT1))).EQ.1) THEN + IF (IDEBUG.GE.2) THEN + IF (IHIT2.EQ.0) THEN + PRINT *,'CHECK4 histo nb:',IDHIST + PRINT *,'CHECK4 p de st.',ICH1,'=',P1 + PRINT *,'CHECK4 track not found in st.',ICH2 + PRINT *,'CHECK4 error X :',(XM(ICH2,JOK)-X1), EXM + PRINT *,'CHECK4 error Y :',(YM(ICH2,JOK)-Y1), EYM + PRINT *,'CHECK4 error PHI :',(PHM(ICH2,JOK)-PHI1),EPH + PRINT *,'CHECK4 error ALAM :',(ALM(ICH2,JOK)-ALAM1), + & EAL + ELSEIF (IHIT2.NE.JOK) THEN + PRINT *,'CHECK4 histo nb:',IDHIST + PRINT *,'CHECK4 p de st.',ICH1,'=',P1 + PRINT *,'CHECK4 ghost in st.',ICH2 + PRINT *,'CHECK4 id part. recherchee:', + & ID(IP(ICH1,IHIT1)) + PRINT *,'CHECK4 id ghost trouve :', + & ID(IP(ICH2,IHIT2)) + ENDIF + ENDIF + ENDIF + ENDIF + + RETURN + END +***************************************************************************** + SUBROUTINE CHECK_HISTO2(IDHIST,ICH2,IHIT2,ICH1,IHIT1, + & X1,Y1,X2,Y2,P1,EX1,EY1,EX2,EY2) +***************************************************************************** +* Check hit IHIT2 with GEANT informations from hit HIT1 +* +* INPUT : IDHIST : No histo +* ICH2 : No st. de recherche +* IDCH1,X1,Y1,PHI1,ALAM1,P1 : Trace de reference +* OUTPUT : JOK : No hit dans ICH2 appartenant a la meme trace. +* +***************************************************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER (MAXHITCH=10000,MAXHITTOT=20000,NBSTATION=5, + & MAXTRK=50000) + + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) + + COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), + & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), + & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), + & ZVERT(MAXHITTOT),NHITTOT + + COMMON/VERIFGEANT/ITTROUGH(MAXTRK,NBSTATION), + & IT_LIST(MAXTRK),IT_NP(MAXTRK),ITCHECK(MAXTRK), + & ITRACK(MAXHITTOT) +* + COMMON/DEBEVT/IDEBUG + + REAL*4 R2 + DATA R2/1./ + + JOK = 0 + + DO I=1,JHIT(ICH2) + IF (ID(IP(ICH1,IHIT1)).EQ.ID(IP(ICH2,I))) THEN + JOK = I + IF (IDHIST.GT.0) THEN + IF (IZM(ICH2,I).EQ.1) THEN + X = X1 + Y = Y1 + ELSE + X = X2 + Y = Y2 + ENDIF + CALL CHFILL2(200+IDHIST,SNGL(P1), + & SNGL((X-XM(ICH2,I))**2),1.) + CALL CHFILL2(200+IDHIST+1,SNGL(P1), + & SNGL((Y-YM(ICH2,I))**2),1.) + CALL CHF1(200+IDHIST+2, + & SNGL(X-XM(ICH2,I)),1.) + CALL CHF1(200+IDHIST+3, + & SNGL(Y-YM(ICH2,I)),1.) + CALL CHF1(200+IDHIST+4,SNGL(P1),R2) + ENDIF + ENDIF + ENDDO + + IF (JOK.GT.0) THEN + IF (ITCHECK(ITRACK(IP(ICH1,IHIT1))).EQ.1) THEN + EXM = EX1 + EYM = EY1 + IF (IZM(ICH2,JOK).EQ.1) THEN + X = X1 + Y = Y1 + IF (ICH2.EQ.4.OR.ICH2.EQ.5) THEN + EXM = EX1 + EYM = EY1 + ENDIF + ELSE + X = X2 + Y = Y2 + IF (ICH2.EQ.4.OR.ICH2.EQ.5) THEN + EXM = EX2 + EYM = EY2 + ENDIF + ENDIF + IF (IDEBUG.GE.2) THEN + IF (IHIT2.EQ.0) THEN + PRINT *,'CHECK2 histo nb:',IDHIST + PRINT *,'CHECK2 p de st.',ICH1,'=',P1 + PRINT *,'CHECK2 track not found in st.',ICH2 + PRINT *,'CHECK2 error X :',(XM(ICH2,JOK)-X), EXM + PRINT *,'CHECK2 error Y :',(YM(ICH2,JOK)-Y), EYM + ELSEIF(IHIT2.NE.JOK) THEN + PRINT *,'CHECK2 histo nb:',IDHIST + PRINT *,'CHECK2 p de st.',ICH1,'=',P1 + PRINT *,'CHECK2 ghost in st.',ICH2 + PRINT *,'CHECK2 id part. recherchee:', + & ID(IP(ICH1,IHIT1)) + PRINT *,'CHECK2 id ghost trouve :', + & ID(IP(ICH2,IHIT2)) + ENDIF + ENDIF + ENDIF + ENDIF + + RETURN + END + + + +************************************************************************ + DOUBLE PRECISION FUNCTION DEDX (P,THET,XEA,YEA) +************************************************************************ +* DEDX est la nouvelle impulsion au vertex, corrigee de la perte +* d'energie dans l'absorbeur +* +************************************************************************ + + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + + REA = DSQRT(XEA**2+YEA**2) + IF (REA.GT.26.3611) THEN +* Plomb + SPB = 5./DCOS(THET) + P = P+SPB/1000.*11.35*(16.66D-3 * P+1.33) +* Polyethylene + SPO = 5./DCOS(THET) + P = P+SPO/1000.*0.935*(2.22D-3 * P+2.17) +* Plomb + SPB = 5./DCOS(THET) + P = P+SPB/1000.*11.35*(16.66D-3 * P+1.33) +* Polyethylene + SPO = 5./DCOS(THET) + P = P+SPO/1000.*0.935*(2.22D-3 * P+2.17) +* Plomb + SPB = 5./DCOS(THET) + P = P+SPB/1000.*11.35*(16.66D-3 * P+1.33) +* Polyethylene + SPO = 5./DCOS(THET) + P = P+SPO/1000.*0.935*(2.22D-3 * P+2.17) +* Plomb + SPB = 5./DCOS(THET) + P = P+SPB/1000.*11.35*(16.66D-3 * P+1.33) + + ELSE +* Tungstene + SW = (503.-467.)/DCOS(THET) + P = P+SW/1000.*19.3*(16.66D-3 * P+1.33) + ENDIF + +* Concrete + SCONC = (467.-315.)/DCOS(THET) + P = P+SCONC/1000.*2.5*(2.22D-3*P+2.17) + +* Carbone + SC = (315.-90.)/DCOS(THET) + P = P+SC/1000.*1.93*(2.22D-3*P+2.17) ! Carbone + + DEDX = P + + RETURN + + END +************************************************************************ + SUBROUTINE BRANSON(PXZ,PHI,ALAM,XEA,YEA) +************************************************************************ +* +* Correction de Branson du multiple scattering dans l'absorbeur +* +************************************************************************ + + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + + PARAMETER(NPLANE=10) + COMMON/PARAM/ZPLANEP(NPLANE),THICK,XPREC,YPREC,B0,BL3,ZMAGS, + & ZMAGE,ZABS,XMAG,ZBP1,ZBP2,CONST + + ASIGN = 1. + IF (PXZ.LT.0.) ASIGN = -1. + PXZ = DABS(PXZ) + PX = PXZ*DSIN(PHI) + PY = PXZ*DTAN(ALAM) + PZ = PXZ*DCOS(PHI) + + PTOT = PXZ/DCOS(ALAM) + + ZEA = ZABS + + REA = DSQRT(XEA**2+YEA**2) + IF (REA.GT.26.3611) THEN + ZBP = ZBP1 + ELSE ! Abso. W pour theta < 3 deg + ZBP = ZBP2 + ENDIF + + XBP = XEA-PX/PZ*(ZEA-ZBP) + YBP = YEA-PY/PZ*(ZEA-ZBP) + PZ = PTOT*ZBP/DSQRT(XBP**2+YBP**2+ZBP**2) + PX = PZ*XBP/ZBP + PY = PZ*YBP/ZBP + PXZ = DSQRT(PX**2+PZ**2) + PHI = DATAN2(PX,PZ) + ALAM = DATAN2(PY,PXZ) + +** THET = DATAN2(REA,ZEA) + + PT = DSQRT(PX**2+PY**2) + THET = DATAN2(PT,PZ) + PTOT = DEDX(PTOT,THET,XEA,YEA) + + PXZ = ASIGN*PTOT*DCOS(ALAM) + + RETURN + END + +*************************************************************** + SUBROUTINE DSINV(N,A,IDIM,IFAIL) +*************************************************************** + + DOUBLE PRECISION A(IDIM,*), ZERO, ONE, X, Y + + REAL PIVOTF + CHARACTER*6 HNAME + + DOUBLE PRECISION S1, S31, S32, S33, DOTF + + PIVOTF(X) = SNGL(X) + DOTF(X,Y,S1) = X * Y + S1 + + DATA HNAME / 'DSINV ' / + DATA ZERO, ONE / 0.D0, 1.D0 / + + IF(IDIM .LT. N .OR. N .LE. 0) GOTO 900 +* +* sfact.inc +* + IFAIL = 0 + DO 144 J = 1, N + IF(PIVOTF(A(J,J)) .LE. 0.) GOTO 150 + A(J,J) = ONE / A(J,J) + IF(J .EQ. N) GOTO 199 + 140 JP1 = J+1 + DO 143 L = JP1, N + A(J,L) = A(J,J)*A(L,J) + S1 = -A(L,J+1) + DO 141 I = 1, J + S1 = DOTF(A(L,I),A(I,J+1),S1) + 141 CONTINUE + A(L,J+1) = -S1 + 143 CONTINUE + 144 CONTINUE + 150 IFAIL = -1 + RETURN + 199 CONTINUE +* +* sfinv.inc +* + IF(N .EQ. 1) GOTO 399 + A(1,2) = -A(1,2) + A(2,1) = A(1,2)*A(2,2) + IF(N .EQ. 2) GOTO 320 + DO 314 J = 3, N + JM2 = J - 2 + DO 312 K = 1, JM2 + S31 = A(K,J) + DO 311 I = K, JM2 + S31 = DOTF(A(K,I+1),A(I+1,J),S31) + 311 CONTINUE + A(K,J) = -S31 + A(J,K) = -S31*A(J,J) + 312 CONTINUE + A(J-1,J) = -A(J-1,J) + A(J,J-1) = A(J-1,J)*A(J,J) + 314 CONTINUE + 320 J = 1 + 323 S33 = A(J,J) + IF(J .EQ. N) GOTO 325 + JP1 = J + 1 + DO 324 I = JP1, N + S33 = DOTF(A(J,I),A(I,J),S33) + 324 CONTINUE + 325 A(J,J) = S33 + JM1 = J + J = JP1 + DO 328 K = 1, JM1 + S32 = ZERO + DO 327 I = J, N + S32 = DOTF(A(K,I),A(I,J),S32) + 327 CONTINUE + A(K,J) = S32 + A(J,K) = S32 + 328 CONTINUE + IF(J .LT. N) GOTO 323 + 399 CONTINUE + + RETURN + 900 CALL TMPRNT(HNAME,N,IDIM,0) + RETURN + END + +******************************************************* + SUBROUTINE TMPRNT(NAME,N,IDIM,K) +******************************************************* + + CHARACTER*6 NAME + LOGICAL MFLAG, RFLAG + + IF(NAME(2:2) .EQ. 'S') THEN + CALL KERMTR('F012.1',LGFILE,MFLAG,RFLAG) + ELSE + CALL KERMTR('F011.1',LGFILE,MFLAG,RFLAG) + ENDIF + IF(NAME(3:6) .EQ. 'FEQN') ASSIGN 1002 TO IFMT + IF(NAME(3:6) .NE. 'FEQN') ASSIGN 1001 TO IFMT + IF(MFLAG) THEN + IF(LGFILE .EQ. 0) THEN + IF(NAME(3:6) .EQ. 'FEQN') THEN + WRITE(*,IFMT) NAME, N, IDIM, K + ELSE + WRITE(*,IFMT) NAME, N, IDIM + ENDIF + ELSE + IF(NAME(3:6) .EQ. 'FEQN') THEN + WRITE(LGFILE,IFMT) NAME, N, IDIM, K + ELSE + WRITE(LGFILE,IFMT) NAME, N, IDIM + ENDIF + ENDIF + ENDIF + IF(.NOT. RFLAG) CALL ABEND + RETURN + 1001 FORMAT(7X, 31H PARAMETER ERROR IN SUBROUTINE , A6, + + 27H ... (N.LT.1 OR IDIM.LT.N)., + + 5X, 3HN =, I4, 5X, 6HIDIM =, I4, 1H. ) + 1002 FORMAT(7X, 31H PARAMETER ERROR IN SUBROUTINE , A6, + + 37H ... (N.LT.1 OR IDIM.LT.N OR K.LT.1)., + + 5X, 3HN =, I4, 5X, 6HIDIM =, I4, 5X, 3HK =, I4,1H.) + END +* +* $Id$ +* +* $Log$ +* Revision 1.1.1.1 1996/02/15 17:48:35 mclareni +* Kernlib +* +* + +*********************************************************** + SUBROUTINE KERSET(ERCODE,LGFILE,LIMITM,LIMITR) +*********************************************************** + + PARAMETER(KOUNTE = 27) + CHARACTER*6 ERCODE, CODE(KOUNTE) + LOGICAL MFLAG, RFLAG + INTEGER KNTM(KOUNTE), KNTR(KOUNTE) + + DATA LOGF / 0 / + DATA CODE(1), KNTM(1), KNTR(1) / 'C204.1', 255, 255 / + DATA CODE(2), KNTM(2), KNTR(2) / 'C204.2', 255, 255 / + DATA CODE(3), KNTM(3), KNTR(3) / 'C204.3', 255, 255 / + DATA CODE(4), KNTM(4), KNTR(4) / 'C205.1', 255, 255 / + DATA CODE(5), KNTM(5), KNTR(5) / 'C205.2', 255, 255 / + DATA CODE(6), KNTM(6), KNTR(6) / 'C305.1', 255, 255 / + DATA CODE(7), KNTM(7), KNTR(7) / 'C308.1', 255, 255 / + DATA CODE(8), KNTM(8), KNTR(8) / 'C312.1', 255, 255 / + DATA CODE(9), KNTM(9), KNTR(9) / 'C313.1', 255, 255 / + DATA CODE(10),KNTM(10),KNTR(10) / 'C336.1', 255, 255 / + DATA CODE(11),KNTM(11),KNTR(11) / 'C337.1', 255, 255 / + DATA CODE(12),KNTM(12),KNTR(12) / 'C341.1', 255, 255 / + DATA CODE(13),KNTM(13),KNTR(13) / 'D103.1', 255, 255 / + DATA CODE(14),KNTM(14),KNTR(14) / 'D106.1', 255, 255 / + DATA CODE(15),KNTM(15),KNTR(15) / 'D209.1', 255, 255 / + DATA CODE(16),KNTM(16),KNTR(16) / 'D509.1', 255, 255 / + DATA CODE(17),KNTM(17),KNTR(17) / 'E100.1', 255, 255 / + DATA CODE(18),KNTM(18),KNTR(18) / 'E104.1', 255, 255 / + DATA CODE(19),KNTM(19),KNTR(19) / 'E105.1', 255, 255 / + DATA CODE(20),KNTM(20),KNTR(20) / 'E208.1', 255, 255 / + DATA CODE(21),KNTM(21),KNTR(21) / 'E208.2', 255, 255 / + DATA CODE(22),KNTM(22),KNTR(22) / 'F010.1', 255, 0 / + DATA CODE(23),KNTM(23),KNTR(23) / 'F011.1', 255, 0 / + DATA CODE(24),KNTM(24),KNTR(24) / 'F012.1', 255, 0 / + DATA CODE(25),KNTM(25),KNTR(25) / 'F406.1', 255, 0 / + DATA CODE(26),KNTM(26),KNTR(26) / 'G100.1', 255, 255 / + DATA CODE(27),KNTM(27),KNTR(27) / 'G100.2', 255, 255 / + + LOGF = LGFILE + L = 0 + IF(ERCODE .NE. ' ') THEN + DO 10 L = 1, 6 + IF(ERCODE(1:L) .EQ. ERCODE) GOTO 12 + 10 CONTINUE + 12 CONTINUE + ENDIF + DO 14 I = 1, KOUNTE + IF(L .EQ. 0) GOTO 13 + IF(CODE(I)(1:L) .NE. ERCODE(1:L)) GOTO 14 + 13 IF(LIMITM.GE.0) KNTM(I) = LIMITM + IF(LIMITR.GE.0) KNTR(I) = LIMITR + 14 CONTINUE + RETURN + ENTRY KERMTR(ERCODE,LOG,MFLAG,RFLAG) + LOG = LOGF + DO 20 I = 1, KOUNTE + IF(ERCODE .EQ. CODE(I)) GOTO 21 + 20 CONTINUE + WRITE(*,1000) ERCODE + CALL ABEND + RETURN + 21 RFLAG = KNTR(I) .GE. 1 + IF(RFLAG .AND. (KNTR(I) .LT. 255)) KNTR(I) = KNTR(I) - 1 + MFLAG = KNTM(I) .GE. 1 + IF(MFLAG .AND. (KNTM(I) .LT. 255)) KNTM(I) = KNTM(I) - 1 + IF(.NOT. RFLAG) THEN + IF(LOGF .LT. 1) THEN + WRITE(*,1001) CODE(I) + ELSE + WRITE(LOGF,1001) CODE(I) + ENDIF + ENDIF + IF(MFLAG .AND. RFLAG) THEN + IF(LOGF .LT. 1) THEN + WRITE(*,1002) CODE(I) + ELSE + WRITE(LOGF,1002) CODE(I) + ENDIF + ENDIF + RETURN + 1000 FORMAT(' KERNLIB LIBRARY ERROR. ' / + + ' ERROR CODE ',A6,' NOT RECOGNIZED BY KERMTR', + + ' ERROR MONITOR. RUN ABORTED.') + 1001 FORMAT(/' ***** RUN TERMINATED BY CERN LIBRARY ERROR ', + + 'CONDITION ',A6) + 1002 FORMAT(/' ***** CERN LIBRARY ERROR CONDITION ',A6) + END + +************************** + subroutine abend +************************** + + stop 'abend!' + end + +************************************************************************ + SUBROUTINE FCNFIT(NPAR, GRAD, FVAL, XVAL, IFLAG, FUTIL) +************************************************************************ +* With magnetic Field Map GRKUTA +* +* Calcule FVAL: la fonction minimisee par MINUIT +* With magnetic field map +* +************************************************************************ + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + + PARAMETER(NPLANE=10) + + COMMON/PARAM/ZPLANEP(NPLANE),THICK,XPREC,YPREC,B0,BL3,ZMAGS, + & ZMAGE,ZABS,XMAG,ZBP1,ZBP2,CONST + + COMMON/MEAS/LPLANE(NPLANE),XMP(NPLANE),YMP(NPLANE) + + COMMON/FCNOUT/PXZEA,ALAMEA,PHIEA,XEA,YEA,NPLU,CHI2 + + DIMENSION GRAD(*),XVAL(*),AMS(500),DISTAZ(500) + + DIMENSION XP(NPLANE),YP(NPLANE), + & COV(NPLANE,NPLANE),AP(NPLANE),COVY(NPLANE,NPLANE) + DIMENSION VECT(7),VOUT(7) + + STEP = 2. ! 1 cm + NSTEPMAX = 5000 + PITODEG = 57.295 + XV = XVAL(4) + YV = XVAL(5) + + ASIGN = 1. + IF (XVAL(1).LT.0.) ASIGN = -1. + PHI = XVAL(2) + ALAM = XVAL(3) + PXZ = DABS(1./XVAL(1)) + + PX = PXZ*DSIN(PHI) + PY = PXZ*DTAN(ALAM) + PZ = PXZ*DCOS(PHI) + PTOT = PXZ/DCOS(ALAM) + + A12 = 0. + NTMAX = 0 + + ZEA = ZABS + XEA = XV + YEA = YV + PXEA = PX + PYEA = PY + PHIEA = PHI + PXZEA = ASIGN*PXZ + ALAMEA = ALAM + + VECT(1) = XV + VECT(2) = YV + VECT(3) = ZABS + VECT(4) = PX/PTOT + VECT(5) = PY/PTOT + VECT(6) = PZ/PTOT + VECT(7) = PTOT + + R = SQRT(VECT(1)*VECT(1)+VECT(2)*VECT(2)) + + Z = VECT(3) + NSTEP = 0 + IX = 0 + IY = 0 + IZ = 0 +** PRINT *,' AV GRKUTA ASIGN',ASIGN,' THET',THET + DO ICH = 1,NPLANE + DO WHILE (Z.GE.ZABS.AND.Z.LT.ZPLANEP(ICH) + & .AND.NSTEP.LE.NSTEPMAX) +** & .AND.(THETA*PITODEG).GT.2. +** & .AND. (THETA*PITODEG).LT.9.) + NSTEP = NSTEP+1 +** WRITE(6,*) NSTEP,(VECT(I),I=1,7) + CALL RECO_GRKUTA(ASIGN,STEP,VECT,VOUT) + DO I = 1,7 + VECT(I) = VOUT(I) + ENDDO + Z = VECT(3) + R = SQRT(VECT(1)*VECT(1)+VECT(2)*VECT(2)) + ENDDO + IF (NSTEP.EQ.NSTEPMAX) RETURN + XP(ICH) = VECT(1)-(Z-ZPLANEP(ICH))*VECT(4)/VECT(6) + YP(ICH) = VECT(2)-(Z-ZPLANEP(ICH))*VECT(5)/VECT(6) + AL = THICK/ VECT(6) + AP(ICH) = (0.0136D0/PTOT)*DSQRT(AL)*(1+0.038D0*DLOG(AL)) + ENDDO +** PRINT *,' AP GRKUTA ASIGN',ASIGN,' THET',THET + + +** Matrice de covariance + I = 0 + DO II = 1,NPLANE + IF (LPLANE(II).EQ.1) THEN + I = I + 1 +* I = II + J = I - 1 + DO JJ = II, NPLANE + IF (LPLANE(JJ).EQ.1) THEN + J = J + 1 +* J = JJ + COV (I,J) = 0.0D0 + COV (J,I) = A12 + IF (I .EQ. J) THEN + COV(J,I) =COV(J,I) + XPREC**2 + ENDIF + +* IF (I .EQ. 10 .AND. J .EQ. 10) PRINT *,'10 10 ',COV(J,I) + DO L = 1,NTMAX + COV(J,I) = COV(J,I) + & + (ZPLANEP(II) + DISTAZ(L))*(ZPLANEP(JJ) + + & DISTAZ(L))*AMS(L)**2 + ENDDO + DO K = 1, II-1 + COV(J,I) = COV(J,I) + & + (ZPLANEP(II)-ZPLANEP(K))* + & (ZPLANEP(JJ)-ZPLANEP(K))*AP(K)**2 +* IF (I .EQ. 10 .AND. J .EQ. 10) PRINT *,'10 10 ',COV(J,I) + ENDDO + COVY(I,J) = 0.0D0 + COVY(J,I) = COV(J,I) + IF (I .EQ. J) THEN + COVY(J,I) = COVY(J,I) - XPREC**2 + YPREC**2 + ENDIF + ENDIF + ENDDO + ENDIF + ENDDO + +* Inversion des matrices de covariance + NPLU = I + + IFAIL = 0 + CALL DSINV(NPLU, COV, NPLANE, IFAIL) +** IF (JFAIL.NE.0 .AND. IFAIL .NE. 0) STOP 'ERROR' + IF (IFAIL .NE. 0) STOP 'ERROR' + IFAIL = 0 + CALL DSINV(NPLU, COVY, NPLANE, IFAIL) +** IF (JFAIL.NE.0 .AND. IFAIL .NE. 0) STOP 'ERROR' + IF (IFAIL .NE. 0) STOP 'ERROR' +* PRINT *,' COVARIANCE MATRIX AFTER' +* DO I = 1, NPLANE +* PRINT *,(COV(J,I),J=1,NPLANE) +* ENDDO + +** Calcul de FVAL ou CHI2 + FVAL = 0.0D0 + I = 0 + DO II = 1,NPLANE + IF (LPLANE(II).EQ.1) THEN + I = I+1 +* I = II + J = 0 + DO JJ = 1,NPLANE + IF (LPLANE(JJ).EQ.1) THEN + J = J+1 +* J = JJ + FVAL = FVAL + COV(J,I)*(XMP(II)-XP(II))*(XMP(JJ)-XP(JJ)) + FVAL = FVAL + COVY(J,I)*(YMP(II)-YP(II)) + & *(YMP(JJ)-YP(JJ)) +** IF (JJ.EQ.II) THEN +** FVAL = FVAL + (XM(II)-XP(II))*(XM(JJ)-XP(JJ))/XPREC**2 +** FVAL = FVAL + (YM(II)-YP(II)) +** & *(YM(JJ)-YP(JJ))/YPREC**2 +** ENDIF + ENDIF + ENDDO + ENDIF + ENDDO + CHI2 = FVAL + +** IF (CHI2.GT.1.E4) THEN +** PRINT *,'FCNFIT CHI2= ',CHI2 +** FVAL = 0. +** ENDIF + + + 1000 FORMAT(I5,7F12.6) + + RETURN + END + +************************************************************************ + SUBROUTINE NEWFCNFIT(NPAR, GRAD, FVAL, XVAL, IFLAG, FUTIL) +************************************************************************ +* With magnetic Field Map GRKUTA +* trackfinding +* Calcule FVAL: la fonction minimisee par MINUIT +* With magnetic field map +* +************************************************************************ + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + + PARAMETER(NPLANE=10) + + COMMON/PARAM/ZPLANEP(NPLANE),THICK,XPREC,YPREC,B0,BL3,ZMAGS, + & ZMAGE,ZABS,XMAG,ZBP1,ZBP2,CONST + + COMMON/MEAS/LPLANE(NPLANE),XMP(NPLANE),YMP(NPLANE) + + COMMON/FCNOUT/PXZEA,ALAMEA,PHIEA,XEA,YEA,NPLU,CHI2 + + DIMENSION GRAD(*),XVAL(*),AMS(500),DISTAZ(500) + + DIMENSION XP(NPLANE),YP(NPLANE), + & COV(NPLANE,NPLANE),AP(NPLANE),COVY(NPLANE,NPLANE) + DIMENSION VECT(7),VOUT(7) + + STEP = 2. ! 1 cm + NSTEPMAX = 5000 + PITODEG = 57.295 + XV = XVAL(4) + YV = XVAL(5) + + ASIGN = 1. + IF (XVAL(1).LT.0.) ASIGN = -1. + PHI = XVAL(2) + ALAM = XVAL(3) + PXZ = DABS(1./XVAL(1)) + + PX = PXZ*DSIN(PHI) + PY = PXZ*DTAN(ALAM) + PZ = PXZ*DCOS(PHI) + PTOT = PXZ/DCOS(ALAM) + + A12 = 0. + NTMAX = 0 + + ZEA = ZABS + XEA = XV + YEA = YV + PXEA = PX + PYEA = PY + PHIEA = PHI + PXZEA = ASIGN*PXZ + ALAMEA = ALAM + + VECT(1) = XV + VECT(2) = YV + VECT(3) = ZABS + VECT(4) = PX/PTOT + VECT(5) = PY/PTOT + VECT(6) = PZ/PTOT + VECT(7) = PTOT + + R = SQRT(VECT(1)*VECT(1)+VECT(2)*VECT(2)) + + Z = VECT(3) + NSTEP = 0 + IX = 0 + IY = 0 + IZ = 0 +** PRINT *,' AV GRKUTA ASIGN',ASIGN,' THET',THET + DO ICH = 1,NPLANE + DO WHILE (Z.GE.ZABS.AND.Z.LT.ZPLANEP(ICH) + & .AND.NSTEP.LE.NSTEPMAX) +** & .AND.(THETA*PITODEG).GT.2. +** & .AND. (THETA*PITODEG).LT.9.) + NSTEP = NSTEP+1 +** WRITE(6,*) NSTEP,(VECT(I),I=1,7) + CALL RECO_GRKUTA (ASIGN,STEP,VECT,VOUT) + DO I = 1,7 + VECT(I) = VOUT(I) + ENDDO + Z = VECT(3) + R = SQRT(VECT(1)*VECT(1)+VECT(2)*VECT(2)) + ENDDO + IF (NSTEP.EQ.NSTEPMAX) RETURN + XP(ICH) = VECT(1)-(Z-ZPLANEP(ICH))*VECT(4)/VECT(6) + YP(ICH) = VECT(2)-(Z-ZPLANEP(ICH))*VECT(5)/VECT(6) + AL = THICK/ VECT(6) + AP(ICH) = (0.0136D0/PTOT)*DSQRT(AL)*(1+0.038D0*DLOG(AL)) + ENDDO +** PRINT *,' AP GRKUTA ASIGN',ASIGN,' THET',THET + + +** Matrice de covariance + I = 0 + DO II = 1,NPLANE + IF (LPLANE(II).EQ.1) THEN + I = I + 1 +* I = II + J = I - 1 + DO JJ = II, NPLANE + IF (LPLANE(JJ).EQ.1) THEN + J = J + 1 +* J = JJ + COV (I,J) = 0.0D0 + COV (J,I) = A12 + IF (I .EQ. J) THEN + COV(J,I) =COV(J,I) + XPREC**2 + ENDIF + +* IF (I .EQ. 10 .AND. J .EQ. 10) PRINT *,'10 10 ',COV(J,I) + DO L = 1,NTMAX + COV(J,I) = COV(J,I) + & + (ZPLANEP(II) + DISTAZ(L))*(ZPLANEP(JJ) + + & DISTAZ(L))*AMS(L)**2 + ENDDO + DO K = 1, II-1 + COV(J,I) = COV(J,I) + & + (ZPLANEP(II)-ZPLANEP(K))* + & (ZPLANEP(JJ)-ZPLANEP(K))*AP(K)**2 +* IF (I .EQ. 10 .AND. J .EQ. 10) PRINT *,'10 10 ',COV(J,I) + ENDDO + COVY(I,J) = 0.0D0 + COVY(J,I) = COV(J,I) + IF (I .EQ. J) THEN + COVY(J,I) = COVY(J,I) - XPREC**2 + YPREC**2 + ENDIF + ENDIF + ENDDO + ENDIF + ENDDO + +* Inversion des matrices de covariance + NPLU = I + + IFAIL = 0 + CALL DSINV(NPLU, COV, NPLANE, IFAIL) +** IF (JFAIL.NE.0 .AND. IFAIL .NE. 0) STOP 'ERROR' + IF (IFAIL .NE. 0) STOP 'ERROR' + IFAIL = 0 + CALL DSINV(NPLU, COVY, NPLANE, IFAIL) +** IF (JFAIL.NE.0 .AND. IFAIL .NE. 0) STOP 'ERROR' + IF (IFAIL .NE. 0) STOP 'ERROR' +* PRINT *,' COVARIANCE MATRIX AFTER' +* DO I = 1, NPLANE +* PRINT *,(COV(J,I),J=1,NPLANE) +* ENDDO + +** Calcul de FVAL ou CHI2 + FVAL = 0.0D0 + I = 0 + DO II = 1,NPLANE + IF (LPLANE(II).EQ.1) THEN + I = I+1 +* I = II + J = 0 + DO JJ = 1,NPLANE + IF (LPLANE(JJ).EQ.1) THEN + J = J+1 +* J = JJ + FVAL = FVAL + COV(J,I)*(XMP(II)-XP(II))*(XMP(JJ)-XP(JJ)) + FVAL = FVAL + COVY(J,I)*(YMP(II)-YP(II)) + & *(YMP(JJ)-YP(JJ)) +** IF (JJ.EQ.II) THEN +** FVAL = FVAL + (XM(II)-XP(II))*(XM(JJ)-XP(JJ))/XPREC**2 +** FVAL = FVAL + (YM(II)-YP(II)) +** & *(YM(JJ)-YP(JJ))/YPREC**2 +** ENDIF + ENDIF + ENDDO + ENDIF + ENDDO + CHI2 = FVAL + +** IF (CHI2.GT.1.E4) THEN +** PRINT *,'FCNFIT CHI2= ',CHI2 +** FVAL = 0. +** ENDIF + + + 1000 FORMAT(I5,7F12.6) + + RETURN + END + +*********************************************************************** + SUBROUTINE INITFIELDOLD +* +* Galina +*********************************************************************** + + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + +** IMPLICIT REAL*8(A-H,O-Z) +** REAL *4 BX,BY,BZ + COMMON/DAT1/Z(81),X(81),Y(81,44),DX,DZ,LPX,LPY,LPZ + COMMON/DAT2/BX(81,81,44),BY(81,81,44),BZ(81,81,44) + COMMON/REG1/ZMAX,ZMIN,XMAX,XMIN + COMMON/REG2/AY1,CY1,AY2,CY2 +** REAL *4 BXP,BYP,BZP + COMMON/SDAT1/ZP(51),RAD(10),FI(33),DZP,DFI,DR,YY0,LPPZ,NR,NFI + COMMON/SDAT2/BXP(51,10,33),BYP(51,10,33),BZP(51,10,33) + COMMON/SDAT4/B(2,2,32) + COMMON/REG3/ZPMAX,ZPMIN,RMAX,RMIN +cc COMMON/CONST/PI2,EPS + REWIND 40 + 1000 FORMAT(5(1X,D15.7)) + 2000 FORMAT(5(1X,I5)) + READ(40,2000) LPX,LPY,LPZ + READ(40,1000) (Z(K),K=1,81) + READ(40,1000) (X(K),K=1,81) + READ(40,1000) DX,DY,DZ + READ(40,1000) ZMAX,ZMIN,XMAX,XMIN +c write(*,*) 'zmin zmax',ZMIN,ZMAX +c write(*,*) 'xmin xmax',XMIN,XMAX + READ(40,1000) AY1,CY1,AY2,CY2 +c write(*,*) 'ay1,cy1,ay2,cy2', AY1,CY1,AY2,CY2 +cc READ(40,1000) PI2,EPS + READ(40,1000) (((BX(K,L,M),K=1,81),L=1,81),M=1,44) + READ(40,1000) (((BY(K,L,M),K=1,81),L=1,81),M=1,44) + READ(40,1000) (((BZ(K,L,M),K=1,81),L=1,81),M=1,44) +** RETURN +** END +c Polar part + READ(40,2000) LPPZ,NR,NFI + READ(40,1000) (ZP(K),K=1,51) + READ(40,1000) (RAD(K),K=1,10) + READ(40,1000) (FI(L),L=1,33) + READ(40,1000) DZP,DFI,DR +c write(*,*) 'dzp dfi dR',DZP,DFI,DR + READ(40,1000) ZPMAX,ZPMIN,RMAX,RMIN +c write(*,*) 'zmin zmax',ZPMIN,ZPMAX +c write(*,*) 'Rmin Rmax',RMIN,RMAX + READ(40,1000) (((BXP(K,L,M),K=1,51),L=1,10),M=1,33) + READ(40,1000) (((BYP(K,L,M),K=1,51),L=1,10),M=1,33) + READ(40,1000) (((BZP(K,L,M),K=1,51),L=1,10),M=1,33) + READ(40,1000) (((B(K,L,M),K=1,2),L=1,2),M=1,32) +** RETURN +** END + + + + + RETURN + END + +*********************************************************************** + SUBROUTINE RECO_GUFLDOLD(X,F) +C ^^^^^^^^^^^^^^^^^^^^^^ +C field map G. Chabratova +C +C Field map 31/05/99 +*********************************************************************** + + + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + COMMON/MAGERR/IMAGERR + + DIMENSION X(7),F(3) + + XT = X(2) + X(2) = X(1) + X(1) = XT + + X0 = X(1)/100. + Y0 = X(2)/100. + Z0 = X(3)/100. + + CALL FREG1(Z0,X0,Y0,FZ0,FX0,FY0,IND) +** PRINT 3000,Z0,X0,Y0,FZ0,FX0,FY0,IND + + IF(IND.EQ.0) GOTO 1 + CALL FREG2(Z0,X0,Y0,FZ0,FX0,FY0,IND) + IMAGERR = 0 + IF(IND.EQ.2) THEN + IMAGERR = 1 +** print 1000 +** PRINT 3000,Z0,X0,Y0,FZ0,FX0,FY0,IND + ENDIF + 1000 format(1x,'Attention!!! The point is out of range!!!') + + 3000 FORMAT(1X,'Z=',D13.7,1X,'X=',D13.7,1X,'Y=',D13.7,1X, + & 'BZ=',D13.7,1X,'BX=',D13.7,1X,'BY=',D13.7,1X,'IND=',I3) + + 1 F(1) = FX0*10. + F(2) = FY0*10. + F(3) = FZ0*10. + +** X(1) = X0*100. +** X(2) = Y0*100. +** X(3) = Z0*100. + + + FT = F(2) + F(2) = F(1) + F(1) = FT + + XT = X(2) + X(2) = X(1) + X(1) = XT + + RETURN + END + + +************************************************** + SUBROUTINE FREG1(Z0,X0,Y0,FZ0,FX0,FY0,IND) +************************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +** REAL *4 BX,BY,BZ + COMMON/DAT1/Z(81),X(81),Y(81,44),DX,DZ,LPX,LPY,LPZ + COMMON/DAT2/BX(81,81,44),BY(81,81,44),BZ(81,81,44) + COMMON/REG1/ZMAX,ZMIN,XMAX,XMIN + COMMON/REG2/AY1,CY1,AY2,CY2 + KC=1 + LC=1 + MC=1 + IND=0 + IF(Z0.LT.ZMIN.OR.Z0.GT.ZMAX)GO TO 100 + IF(X0.LT.XMIN.OR.X0.GT.XMAX)GO TO 100 + YY1=AY1*Z0+CY1 + YY2=AY2*Z0+CY2 + 2000 FORMAT(1X,'YY1=',D15.7,1X,'YY2=',D15.7,1X,'Y0=',D15.7) +c PRINT 2000,YY1,YY2,Y0 + IF(Y0.LT.YY1)GO TO 100 + IF(Y0.GT.YY2)GO TO 100 + CALL FIZ(Z0,Z,DZ,KC,K0,Z1,Z2,81) + CALL FIZ(X0,X,DX,LC,L0,X1,X2,81) + DY=(YY2-YY1)/DFLOAT(LPY-1) + YY=(Y0-YY1) + M0=(YY/DY) + + IF(Y0.GE.(YY1+DFLOAT(M0)*DY).AND.Y0.LE.(YY1+DFLOAT(M0+1)*DY)) + &GO TO 700 + M0=M0+1 + 700 CONTINUE + Y2=(Y0-(YY1+DFLOAT(M0)*DY))/DY + Y1=1.-Y2 +** write(*,*) 'm0 Y1 Y2',m0,Y1,Y2 +** print *,' k0=',k0,' l0=',l0,' m0=',m0 +** print *,' z1=',z1,' z2=',z2 + FX1=Z1*BX(K0,L0,M0)+Z2*BX(K0+1,L0,M0) + FX2=Z2*BX(K0+1,L0+1,M0)+Z1*BX(K0,L0+1,M0) + FFX1=X1*FX1+X2*FX2 + GX1=Z1*BX(K0,L0,M0+1)+Z2*BX(K0+1,L0,M0+1) + GX2=Z2*BX(K0+1,L0+1,M0+1)+Z1*BX(K0,L0+1,M0+1) + GGX1=X1*GX1+X2*GX2 + FX0=Y1*FFX1+Y2*GGX1 + FX1=Z1*BY(K0,L0,M0)+Z2*BY(K0+1,L0,M0) + FX2=Z2*BY(K0+1,L0+1,M0)+Z1*BY(K0,L0+1,M0) + FFX1=X1*FX1+X2*FX2 + GX1=Z1*BY(K0,L0,M0+1)+Z2*BY(K0+1,L0,M0+1) + GX2=Z2*BY(K0+1,L0+1,M0+1)+Z1*BY(K0,L0+1,M0+1) + GGX1=X1*GX1+X2*GX2 + FY0=Y1*FFX1+Y2*GGX1 + FX1=Z1*BZ(K0,L0,M0)+Z2*BZ(K0+1,L0,M0) + FX2=Z2*BZ(K0+1,L0+1,M0)+Z1*BZ(K0,L0+1,M0) + FFX1=X1*FX1+X2*FX2 + GX1=Z1*BZ(K0,L0,M0+1)+Z2*BZ(K0+1,L0,M0+1) + GX2=Z2*BZ(K0+1,L0+1,M0+1)+Z1*BZ(K0,L0+1,M0+1) + GGX1=X1*GX1+X2*GX2 + FZ0=Y1*FFX1+Y2*GGX1 + RETURN + 100 CONTINUE + IND=1 + 1000 format(1x,'Attention!!! The point is out of range!!!') +C print 1000 + RETURN + END + +************************************************* + SUBROUTINE FIZ(Z0,Z,DEL,KI,K0,Z1,Z2,NDZ) +************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +** CC DIMENSION Z(NDZ) + DIMENSION Z(10000) + DDEL=Z0-Z(KI) + KDEL=INT(DDEL/DEL) + KJ=KI+KDEL + K0 = NDZ - 1 ! CCCC +* if (k0.gt.81) print*,'ndz=',ndz + IF (KJ.GT.NDZ) THEN ! CCC + K0 = NDZ-1 + GO TO 100 + ENDIF + DO 1 K=KJ,NDZ-1 ! CCC + IF(Z0.LT.Z(K)) THEN + K0 = K + GO TO 100 + ENDIF + 1 CONTINUE + 100 CONTINUE +* print *,'K0=',K0,' Z0',z0, Z(K0), Z(K0+1),z2 + if (k0.gt.81) print*,'k0=',k0 + Z2=(Z0-Z(K0))/(Z(K0+1)-Z(K0)) + Z1=1.-Z2 +** write(*,*) 'ko z1 z2', K0,Z1,Z2,' ki=',ki,' kj=',kj,' K=',K +** write(*,*)' NDZ Z(K0) Z(K0+1)',NDZ,Z(K0), Z(K0+1) + RETURN + END + +*************************************************** + SUBROUTINE FREG2(Z0,X0,Y0,FZ0,FX0,FY0,IND) +************************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +** REAL *4 BXP,BYP,BZP + COMMON/SDAT1/ZP(51),RAD(10),FI(33),DZP,DFI,DR,YY0,LPPZ,NR,NFI + COMMON/SDAT2/BXP(51,10,33),BYP(51,10,33),BZP(51,10,33) + COMMON/SDAT4/B(2,2,32) + COMMON/REG3/ZPMAX,ZPMIN,RMAX,RMIN +cc COMMON/CONST/PI2,EPS + KP=32+1 + LP=1 + MP=1 + YY0=0.3 + EPS=0.1D-6 + PI2=0.6283185E+01 + R0=DSQRT((X0-YY0)**2+Y0**2) +c write (*,*)'ro=',R0 + IF(Z0.LT.ZPMIN.OR.Z0.GT.ZPMAX)GO TO 100 + IF(R0.LT.RMIN.OR.R0.GT.RMAX)GO TO 100 + IF(R0.LE.DR)GO TO 3000 + CALL FIZ(Z0,ZP,DZP,KP,K0,Z1,Z2,51) + CALL FIZ(R0,RAD,DR,LP,L0,X1,X2,10) +** print *,' r0=',r0,' rad=',rad,' dr=',dr,' lp=',lp,' l0=',l0, +** & ' x1=',x1,' x2=',x2 + FI0=DACOS((X0-YY0)/R0) + IF(Y0.LT.0.D+0)FI0=PI2-FI0 + CALL FIZ(FI0,FI,DFI,MP,M0,Y1,Y2,32) +** print *,' Apres FIZ',' k0=',k0,' l0=',l0,' m0=',m0 + FX1=Z1*BXP(K0,L0,M0)+Z2*BXP(K0+1,L0,M0) + FX2=Z2*BXP(K0+1,L0+1,M0)+Z1*BXP(K0,L0+1,M0) + FFX1=X1*FX1+X2*FX2 + GX1=Z1*BXP(K0,L0,M0+1)+Z2*BXP(K0+1,L0,M0+1) + GX2=Z2*BXP(K0+1,L0+1,M0+1)+Z1*BXP(K0,L0+1,M0+1) + GGX1=X1*GX1+X2*GX2 + FX0=Y1*FFX1+Y2*GGX1 + FX1=Z1*BYP(K0,L0,M0)+Z2*BYP(K0+1,L0,M0) + FX2=Z2*BYP(K0+1,L0+1,M0)+Z1*BYP(K0,L0+1,M0) + FFX1=X1*FX1+X2*FX2 + GX1=Z1*BYP(K0,L0,M0+1)+Z2*BYP(K0+1,L0,M0+1) + GX2=Z2*BYP(K0+1,L0+1,M0+1)+Z1*BYP(K0,L0+1,M0+1) + GGX1=X1*GX1+X2*GX2 + FY0=Y1*FFX1+Y2*GGX1 + FX1=Z1*BZP(K0,L0,M0)+Z2*BZP(K0+1,L0,M0) +** CCC FX2=Z2*BZ(K0+1,L0+1,M0)+Z1*BZ(K0,L0+1,M0) + FX2=Z2*BZP(K0+1,L0+1,M0)+Z1*BZP(K0,L0+1,M0) + FFX1=X1*FX1+X2*FX2 + GX1=Z1*BZP(K0,L0,M0+1)+Z2*BZP(K0+1,L0,M0+1) + GX2=Z2*BZP(K0+1,L0+1,M0+1)+Z1*BZP(K0,L0+1,M0+1) + GGX1=X1*GX1+X2*GX2 + FZ0=Y1*FFX1+Y2*GGX1 + IND=0 + RETURN + 100 CONTINUE + IND=2 + 1000 format(1x,'Attention!!! The point is out of range!!!') +C print 1000 + RETURN + 3000 CONTINUE + IF(R0.LT.EPS)GO TO 4000 + CALL FIZ(Z0,ZP,DZP,KP,K0,Z1,Z2,51) + XX=X0-YY0 + FI0=DACOS(XX/R0) + IF(Y0.LT.0.D+0)FI0=PI2-FI0 + CALL FIZ(FI0,FI,DFI,MP,M0,Y1,Y2,32) + ALF2=B(1,1,M0)*XX+B(1,2,M0)*Y0 + ALF3=B(2,1,M0)*XX+B(2,2,M0)*Y0 + ALF1=1.-ALF2-ALF3 + FX1=ALF1*BXP(K0,1,1)+ALF2*BXP(K0,1,M0)+ALF3*BXP(K0,1,M0+1) + FX2=ALF1*BXP(K0+1,1,1)+ALF2*BXP(K0+1,1,M0)+ALF3*BXP(K0+1,1,M0+1) + FX0=Z1*FX1+Z2*FX2 + FX1=ALF1*BYP(K0,1,1)+ALF2*BYP(K0,1,M0)+ALF3*BYP(K0,1,M0+1) + FX2=ALF1*BYP(K0+1,1,1)+ALF2*BYP(K0+1,1,M0)+ALF3*BYP(K0+1,1,M0+1) + FY0=Z1*FX1+Z2*FX2 + FX1=ALF1*BZP(K0,1,1)+ALF2*BZP(K0,1,M0)+ALF3*BZP(K0,1,M0+1) + FX2=ALF1*BZP(K0+1,1,1)+ALF2*BZP(K0+1,1,M0)+ALF3*BZP(K0+1,1,M0+1) + FZ0=Z1*FX1+Z2*FX2 +c write(*,*) 'RCalled by : , GUSWIM * +C. * Authors R.Brun, M.Hansroul ********* * +C. * V.Perevoztchikov (CUT STEP implementation) * +C. * * +C. * * +C. ****************************************************************** +C. + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + +** REAL CHARGE, STEP, VECT(*), VOUT(*), F(4) +** REAL XYZT(3), XYZ(3), X, Y, Z, XT, YT, ZT + DIMENSION VECT(*), VOUT(*), F(3) + DIMENSION XYZT(3), XYZ(3) + DIMENSION SECXS(4),SECYS(4),SECZS(4),HXP(3) + EQUIVALENCE (X,XYZ(1)),(Y,XYZ(2)),(Z,XYZ(3)), + + (XT,XYZT(1)),(YT,XYZT(2)),(ZT,XYZT(3)) +* + PARAMETER (MAXIT = 1992, MAXCUT = 11) + PARAMETER (EC=2.9979251D-4,DLT=1D-4,DLT32=DLT/32) + PARAMETER (ZERO=0, ONE=1, TWO=2, THREE=3) + PARAMETER (THIRD=ONE/THREE, HALF=ONE/TWO) + PARAMETER (PISQUA=.986960440109D+01) + PARAMETER (IX=1,IY=2,IZ=3,IPX=4,IPY=5,IPZ=6) +*. +*. ------------------------------------------------------------------ +*. +* This constant is for units CM,GEV/C and KGAUSS +* + ITER = 0 + NCUT = 0 + DO 10 J=1,7 + VOUT(J)=VECT(J) + 10 CONTINUE + PINV = EC * CHARGE / VECT(7) + TL = 0. + H = STEP +* +* + 20 REST = STEP-TL + IF (ABS(H).GT.ABS(REST)) H = REST + CALL RECO_GUFLD(VOUT,F) +* +* Start of integration +* + X = VOUT(1) + Y = VOUT(2) + Z = VOUT(3) + A = VOUT(4) + B = VOUT(5) + C = VOUT(6) +* + H2 = HALF * H + H4 = HALF * H2 + PH = PINV * H + PH2 = HALF * PH + SECXS(1) = (B * F(3) - C * F(2)) * PH2 + SECYS(1) = (C * F(1) - A * F(3)) * PH2 + SECZS(1) = (A * F(2) - B * F(1)) * PH2 + ANG2 = (SECXS(1)**2 + SECYS(1)**2 + SECZS(1)**2) + IF (ANG2.GT.PISQUA) GO TO 40 + DXT = H2 * A + H4 * SECXS(1) + DYT = H2 * B + H4 * SECYS(1) + DZT = H2 * C + H4 * SECZS(1) + XT = X + DXT + YT = Y + DYT + ZT = Z + DZT +* +* Second intermediate point +* + EST = ABS(DXT)+ABS(DYT)+ABS(DZT) + IF (EST.GT.H) GO TO 30 + + CALL RECO_GUFLD(XYZT,F) + AT = A + SECXS(1) + BT = B + SECYS(1) + CT = C + SECZS(1) +* + SECXS(2) = (BT * F(3) - CT * F(2)) * PH2 + SECYS(2) = (CT * F(1) - AT * F(3)) * PH2 + SECZS(2) = (AT * F(2) - BT * F(1)) * PH2 + AT = A + SECXS(2) + BT = B + SECYS(2) + CT = C + SECZS(2) + SECXS(3) = (BT * F(3) - CT * F(2)) * PH2 + SECYS(3) = (CT * F(1) - AT * F(3)) * PH2 + SECZS(3) = (AT * F(2) - BT * F(1)) * PH2 + DXT = H * (A + SECXS(3)) + DYT = H * (B + SECYS(3)) + DZT = H * (C + SECZS(3)) + XT = X + DXT + YT = Y + DYT + ZT = Z + DZT + AT = A + TWO*SECXS(3) + BT = B + TWO*SECYS(3) + CT = C + TWO*SECZS(3) +* + EST = ABS(DXT)+ABS(DYT)+ABS(DZT) + IF (EST.GT.2.*ABS(H)) GO TO 30 + + CALL RECO_GUFLD(XYZT,F) +* + Z = Z + (C + (SECZS(1) + SECZS(2) + SECZS(3)) * THIRD) * H + Y = Y + (B + (SECYS(1) + SECYS(2) + SECYS(3)) * THIRD) * H + X = X + (A + (SECXS(1) + SECXS(2) + SECXS(3)) * THIRD) * H +* + SECXS(4) = (BT*F(3) - CT*F(2))* PH2 + SECYS(4) = (CT*F(1) - AT*F(3))* PH2 + SECZS(4) = (AT*F(2) - BT*F(1))* PH2 + A = A+(SECXS(1)+SECXS(4)+TWO * (SECXS(2)+SECXS(3))) * THIRD + B = B+(SECYS(1)+SECYS(4)+TWO * (SECYS(2)+SECYS(3))) * THIRD + C = C+(SECZS(1)+SECZS(4)+TWO * (SECZS(2)+SECZS(3))) * THIRD +* + EST = ABS(SECXS(1)+SECXS(4) - (SECXS(2)+SECXS(3))) + ++ ABS(SECYS(1)+SECYS(4) - (SECYS(2)+SECYS(3))) + ++ ABS(SECZS(1)+SECZS(4) - (SECZS(2)+SECZS(3))) +* + IF (EST.GT.DLT .AND. ABS(H).GT.1.E-4) GO TO 30 + ITER = ITER + 1 + NCUT = 0 +* If too many iterations, go to HELIX + IF (ITER.GT.MAXIT) GO TO 40 +* + TL = TL + H + IF (EST.LT.(DLT32)) THEN + H = H*TWO + ENDIF + CBA = ONE/ SQRT(A*A + B*B + C*C) + VOUT(1) = X + VOUT(2) = Y + VOUT(3) = Z + VOUT(4) = CBA*A + VOUT(5) = CBA*B + VOUT(6) = CBA*C + REST = STEP - TL + IF (STEP.LT.0.) REST = -REST + IF (REST .GT. 1.E-5*ABS(STEP)) GO TO 20 +* + GO TO 999 +* +** CUT STEP + 30 NCUT = NCUT + 1 +* If too many cuts , go to HELIX + IF (NCUT.GT.MAXCUT) GO TO 40 + H = H*HALF + GO TO 20 +* +** ANGLE TOO BIG, USE HELIX + 40 F1 = F(1) + F2 = F(2) + F3 = F(3) + F4 = SQRT(F1**2+F2**2+F3**2) + RHO = -F4*PINV + TET = RHO * STEP + IF(TET.NE.0.) THEN + HNORM = ONE/F4 + F1 = F1*HNORM + F2 = F2*HNORM + F3 = F3*HNORM +* + HXP(1) = F2*VECT(IPZ) - F3*VECT(IPY) + HXP(2) = F3*VECT(IPX) - F1*VECT(IPZ) + HXP(3) = F1*VECT(IPY) - F2*VECT(IPX) + + HP = F1*VECT(IPX) + F2*VECT(IPY) + F3*VECT(IPZ) +* + RHO1 = ONE/RHO + SINT = SIN(TET) + COST = TWO*SIN(HALF*TET)**2 +* + G1 = SINT*RHO1 + G2 = COST*RHO1 + G3 = (TET-SINT) * HP*RHO1 + G4 = -COST + G5 = SINT + G6 = COST * HP + + VOUT(IX) = VECT(IX) + (G1*VECT(IPX) + G2*HXP(1) + G3*F1) + VOUT(IY) = VECT(IY) + (G1*VECT(IPY) + G2*HXP(2) + G3*F2) + VOUT(IZ) = VECT(IZ) + (G1*VECT(IPZ) + G2*HXP(3) + G3*F3) + + VOUT(IPX) = VECT(IPX) + (G4*VECT(IPX) + G5*HXP(1) + G6*F1) + VOUT(IPY) = VECT(IPY) + (G4*VECT(IPY) + G5*HXP(2) + G6*F2) + VOUT(IPZ) = VECT(IPZ) + (G4*VECT(IPZ) + G5*HXP(3) + G6*F3) +* + ELSE + VOUT(IX) = VECT(IX) + STEP*VECT(IPX) + VOUT(IY) = VECT(IY) + STEP*VECT(IPY) + VOUT(IZ) = VECT(IZ) + STEP*VECT(IPZ) +* + ENDIF +* + 999 END + + +******************************************************************* + SUBROUTINE RECO_GUFLDOLD1(X,B) +C +C CONSTANT FIELD +C +C *** ROUTINE DESCRIBING THE MAGNETIC FIELD IN THE ALICE SETUP *** +C *** NVE 14-NOV-1990 CERN GENEVA *** +C +C CALLED BY : GUFLD +C ORIGIN : NICK VAN EIJNDHOVEN +C +C Input : +C ------- +C X = (X,Y,Z) coordinates in cm +C +C Output : +C -------- +C B = Magnetic field components (BX,BY,BZ) in KG +C + + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER(NBSTATION=5) +C + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) + + +C + DIMENSION X(3),B(3) + + XT = X(2) + X(2) = X(1) + X(1) = XT + + B(1) = 0. + B(2) = 0. + B(3) = 0. + + IF (X(3).LT.(-1.*ZCOIL)) THEN + B(3) = 2. + ELSEIF ( X(3).LT.(-1.*ZMAGEND)) THEN + B(1) = -10. + ENDIF + + BT = B(2) + B(2) = B(1) + B(1) = BT + + XT = X(2) + X(2) = X(1) + X(1) = XT +** print *,' x =',X(1),X(2),X(3) +** print *,' B =',B(1),B(2),B(3) + +C + + + 999 END + +******************************************************************* + SUBROUTINE RECO_GUFLD(X,B) +C +C Field map Mariana +C +C *** ROUTINE DESCRIBING THE MAGNETIC FIELD IN THE ALICE SETUP *** +C *** NVE 14-NOV-1990 CERN GENEVA *** +C +C CALLED BY : GUFLD +C ORIGIN : NICK VAN EIJNDHOVEN +C +C Input : +C ------- +C X = (X,Y,Z) coordinates in cm +C +C Output : +C -------- +C B = Magnetic field components (BX,BY,BZ) in KG +C + + IMPLICIT DOUBLE PRECISION(A-H,O-Z) +C + +C --- Common containing magnetic field map data + REAL DZ,DX,DY,UDX,UDY,UDZ + $,XMBEG,YMBEG,ZMBEG,XMEND,YMEND,ZMEND + $,BV + INTEGER NX,NY,NZ + + PARAMETER(MAXFLD=250000) + COMMON /SCXMFD/ NX,NY,NZ,DZ,DX,DY,UDX,UDY,UDZ + $,XMBEG,YMBEG,ZMBEG,XMEND,YMEND,ZMEND + $,BV(MAXFLD) +C + +C + DIMENSION X(3),B(3) + DOUBLE PRECISION ONE, RATX, RATY, RATZ, HIX, HIY, HIZ + $, RATX1, RATY1, RATZ1 + $, BHYHZ, BHYLZ, BLYHZ, BLYLZ, BHZ, BLZ + $, XL(3) + + PARAMETER (ONE=1) + + EXTERNAL BX,BY,BZ + + XT = X(2) + X(2) = X(1) + X(1) = XT + + + ISXFMAP = 3 + +** BX(JX,JY,JZ)=BV(3*((JZ-1)*(NX*NY)+(JY-1)*NX+(JX-1))+1) +** BY(JX,JY,JZ)=BV(3*((JZ-1)*(NX*NY)+(JY-1)*NX+(JX-1))+2) +** BZ(JX,JY,JZ)=BV(3*((JZ-1)*(NX*NY)+(JY-1)*NX+(JX-1))+3) + + + +* +* --- Act accordingly to ISXFMAP +* + IF(ISXFMAP.EQ.1) THEN + IF (ABS(X(3)) .LT. 700. + + .AND. X(1)**2+(X(2)+30.)**2 .LT. 560.**2 ) THEN + B(1)=0. + B(2)=0. + B(3)=2. + ELSE IF (X(3) .GE. 725. .AND. X(3) .LT. 1225.) THEN + DZ=ABS(975.-X(3))/100. + B(1)=(1.-0.1*DZ*DZ)*7.0 + B(2)=0. + B(3)=0. + ELSE + B(1)=0. + B(2)=0. + B(3)=0. + ENDIF + ELSE IF(ISXFMAP.LE.3) THEN + IF (-700.LT.X(3).AND.X(3).LT.ZMBEG + + .AND. X(1)**2+(X(2)+30.)**2 .LT. 560.**2 ) THEN + B(1)=0. + B(2)=0. + B(3)=2. + ELSE IF ((X(3) .GE. ZMBEG .AND. X(3) .LT. ZMEND) .AND. + + (XMBEG.LE.ABS(X(1)).AND.ABS(X(1)).LT.XMEND) .AND. + + (YMBEG.LE.ABS(X(2)).AND.ABS(X(2)).LT.YMEND)) THEN + + + +C --- find the position in the grid --- + + XL(1)=ABS(X(1))-XMBEG + XL(2)=ABS(X(2))-YMBEG + XL(3)=X(3)-ZMBEG + +C --- Start with X + + HIX=XL(1)*UDX + RATX=HIX-AINT(HIX) + IX=HIX+1 + + HIY=XL(2)*UDY + RATY=HIY-AINT(HIY) + IY=HIY+1 + + HIZ=XL(3)*UDZ + RATZ=HIZ-AINT(HIZ) + IZ=HIZ+1 + + IF(ISXFMAP.EQ.2) THEN +* ... Simple interpolation + + B(1) = BX(IX,IY,IZ)*(ONE-RATX) + BX(IX+1,IY+1,IZ+1)*RATX + B(2) = BY(IX,IY,IZ)*(ONE-RATY) + BY(IX+1,IY+1,IZ+1)*RATY + B(3) = BZ(IX,IY,IZ)*(ONE-RATZ) + BZ(IX+1,IY+1,IZ+1)*RATZ + ELSE IF(ISXFMAP.EQ.3) THEN +* ... more complicated interpolation + RATX1=ONE-RATX + RATY1=ONE-RATY + RATZ1=ONE-RATZ +** print *,' bx by bz', BX(IX ,IY+1,IZ+1),BY(IX ,IY+1,IZ+1) +** & , BZ(IX ,IY+1,IZ+1) + BHYHZ = BX(IX ,IY+1,IZ+1)*RATX1+BX(IX+1,IY+1,IZ+1)*RATX + BHYLZ = BX(IX ,IY+1,IZ )*RATX1+BX(IX+1,IY+1,IZ )*RATX + BLYHZ = BX(IX ,IY ,IZ+1)*RATX1+BX(IX+1,IY ,IZ+1)*RATX + BLYLZ = BX(IX ,IY ,IZ )*RATX1+BX(IX+1,IY ,IZ )*RATX + BHZ = BLYHZ *RATY1+BHYHZ *RATY + BLZ = BLYLZ *RATY1+BHYLZ *RATY + B(1) = BLZ *RATZ1+BHZ *RATZ +* + BHYHZ = BY(IX ,IY+1,IZ+1)*RATX1+BY(IX+1,IY+1,IZ+1)*RATX + BHYLZ = BY(IX ,IY+1,IZ )*RATX1+BY(IX+1,IY+1,IZ )*RATX + BLYHZ = BY(IX ,IY ,IZ+1)*RATX1+BY(IX+1,IY ,IZ+1)*RATX + BLYLZ = BY(IX ,IY ,IZ )*RATX1+BY(IX+1,IY ,IZ )*RATX + BHZ = BLYHZ *RATY1+BHYHZ *RATY + BLZ = BLYLZ *RATY1+BHYLZ *RATY + B(2) = BLZ *RATZ1+BHZ *RATZ +* + BHYHZ = BZ(IX ,IY+1,IZ+1)*RATX1+BZ(IX+1,IY+1,IZ+1)*RATX + BHYLZ = BZ(IX ,IY+1,IZ )*RATX1+BZ(IX+1,IY+1,IZ )*RATX + BLYHZ = BZ(IX ,IY ,IZ+1)*RATX1+BZ(IX+1,IY ,IZ+1)*RATX + BLYLZ = BZ(IX ,IY ,IZ )*RATX1+BZ(IX+1,IY ,IZ )*RATX + BHZ = BLYHZ *RATY1+BHYHZ *RATY + BLZ = BLYLZ *RATY1+BHYLZ *RATY + B(3) = BLZ *RATZ1+BHZ *RATZ +* + ENDIF +* ... use the dipole symmetry + + IF (X(1)*X(2).LT.0) B(2)=-B(2) + IF (X(1).LT.0) B(3)=-B(3) + +* + + ELSE + + B(1)=0. + B(2)=0. + B(3)=0. + + ENDIF ! z-coord for m.f. + + ENDIF ! endif ISXFMAP + + SXMAGN = 1. + SXMGMX = 20. + 12 B(1)=B(1)*SXMAGN + B(2)=B(2)*SXMAGN + B(3)=B(3)*SXMAGN + BTOT=SQRT(B(1)**2+B(2)**2+B(3)**2) + IF(BTOT.GT.SXMGMX) THEN + PRINT 10100, BTOT,SXMGMX +10100 FORMAT(' *GUFLD* Field ',G10.4,' larger than max ',G10.4) + ENDIF + + + BT = B(2) + B(2) = B(1) + B(1) = BT + + XT = X(2) + X(2) = X(1) + X(1) = XT + +C + + RETURN + END + + +******************************************* + DOUBLE PRECISION FUNCTION BX(JX,JY,JZ) + + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + +C --- Common containing magnetic field map data + REAL DZ,DX,DY,UDX,UDY,UDZ + $,XMBEG,YMBEG,ZMBEG,XMEND,YMEND,ZMEND + $,BV + INTEGER NX,NY,NZ + + PARAMETER(MAXFLD=250000) + COMMON /SCXMFD/ NX,NY,NZ,DZ,DX,DY,UDX,UDY,UDZ + $,XMBEG,YMBEG,ZMBEG,XMEND,YMEND,ZMEND + $,BV(MAXFLD) + + BX=BV(3*((JZ-1)*(NX*NY)+(JY-1)*NX+(JX-1))+1) + + END + +******************************************* + DOUBLE PRECISION FUNCTION BY(JX,JY,JZ) + + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + +C --- Common containing magnetic field map data + REAL DZ,DX,DY,UDX,UDY,UDZ + $,XMBEG,YMBEG,ZMBEG,XMEND,YMEND,ZMEND + $,BV + INTEGER NX,NY,NZ + + PARAMETER(MAXFLD=250000) + COMMON /SCXMFD/ NX,NY,NZ,DZ,DX,DY,UDX,UDY,UDZ + $,XMBEG,YMBEG,ZMBEG,XMEND,YMEND,ZMEND + $,BV(MAXFLD) + + BY=BV(3*((JZ-1)*(NX*NY)+(JY-1)*NX+(JX-1))+2) + + END + +******************************************* + DOUBLE PRECISION FUNCTION BZ(JX,JY,JZ) + + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + +C --- Common containing magnetic field map data + REAL DZ,DX,DY,UDX,UDY,UDZ + $,XMBEG,YMBEG,ZMBEG,XMEND,YMEND,ZMEND + $,BV + INTEGER NX,NY,NZ + + PARAMETER(MAXFLD=250000) + COMMON /SCXMFD/ NX,NY,NZ,DZ,DX,DY,UDX,UDY,UDZ + $,XMBEG,YMBEG,ZMBEG,XMEND,YMEND,ZMEND + $,BV(MAXFLD) + + BZ=BV(3*((JZ-1)*(NX*NY)+(JY-1)*NX+(JX-1))+3) + + END + +*********************************************************************** + SUBROUTINE INITFIELD + +C +C Marianna +C +C *** INITIALISATION OF THE FIELD MAP *** +C *** FCA 24-AUG-1998 CERN GENEVA *** +C +C CALLED BY : GALICE +C ORIGIN : NICK VAN EIJNDHOVEN +C + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + +C --- Common containing magnetic field map data + REAL DZ,DX,DY,UDX,UDY,UDZ + $,XMBEG,YMBEG,ZMBEG,XMEND,YMEND,ZMEND + $,BV + INTEGER NX,NY,NZ + + PARAMETER(MAXFLD=250000) + COMMON /SCXMFD/ NX,NY,NZ,DZ,DX,DY,UDX,UDY,UDZ + $,XMBEG,YMBEG,ZMBEG,XMEND,YMEND,ZMEND + $,BV(MAXFLD) + + ISXFMAP = 3 + + IF(ISXFMAP.EQ.1) THEN +* ... constant field, nothing to do + ELSE IF(ISXFMAP.LE.3) THEN +* ... constant mesh field + PRINT 10000, ISXFMAP +10000 FORMAT(' *SXFMAP* Magnetic field map flag: ',I5 + $ ,'; Reading magnetic field map data ') +* + OPEN(77,FILE='data/field01.dat', + $ FORM='FORMATTED',STATUS='OLD') + READ(77,*) NX,NY,NZ,DX,DY,DZ,XMBEG,YMBEG,ZMBEG + PRINT*,'NX,NY,NZ,DX,DY,DZ,XMBEG,YMBEG,ZMBEG', + $ NX,NY,NZ,DX,DY,DZ,XMBEG,YMBEG,ZMBEG + IF(3*NX*NY*NZ.GT.MAXFLD) THEN + WRITE(6,10100) 3*NX*NY*NZ,MAXFLD + STOP 'Increase MAXFLD' + ENDIF + UDX=1/DX + UDY=1/DY + UDZ=1/DZ + XMEND=XMBEG+(NX-1)*DX + YMEND=YMBEG+(NY-1)*DY + ZMEND=ZMBEG+(NZ-1)*DZ + DO IZ=1,NZ + IPZ=3*(IZ-1)*(NX*NY) + DO IY=1,NY + IPY=IPZ+3*(IY-1)*NX + DO IX=1,NX + IPX=IPY+3*(IX-1) + READ(77,*) BV(IPX+3),BV(IPX+2),BV(IPX+1) + ENDDO + ENDDO + ENDDO + CLOSE(77) + ENDIF ! endif ISXFMAP +* +10100 FORMAT('*** SXFMAP: Need ',I7,' have ',I7) + END + +**************************************** + SUBROUTINE RANNOR (A,B) +**************************************** +C +C CERN PROGLIB# V100 RANNOR .VERSION KERNFOR 4.18 880425 +C ORIG. 18/10/77 +C + Y = RNDM() + IF (Y.EQ.0.) Y = RNDM() + Z = RNDM() + + X = 6.283185*Z + R = SQRT (-2.0*LOG(Y)) + A = R*SIN (X) + B = R*COS (X) + RETURN + END +************************************************************************ + SUBROUTINE OLDFCNFIT(NPAR,GRAD,FVAL,XVAL,IFLAG,FUTIL) +************************************************************************ +* Calcule FVAL: la fonction minimisee par MINUIT +* with constant magnetic Field +* +************************************************************************ + + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + + PARAMETER(NPLANE=10) + + COMMON/PARAM/ZPLANEP(NPLANE),THICK,XPREC,YPREC,B0,BL3,ZMAGS, + & ZMAGE,ZABS,XMAG,ZBP1,ZBP2,CONST + + COMMON/MEAS/LPLANE(NPLANE),XMP(NPLANE),YMP(NPLANE) + + COMMON/FCNOUT/PXZEA,ALAMEA,PHIEA,XEA,YEA,NPLU,CHI2 + + DIMENSION GRAD(*),XVAL(*),AMS(500),DISTAZ(500) + + DIMENSION XP(NPLANE),YP(NPLANE), + & COV(NPLANE,NPLANE),AP(NPLANE),COVY(NPLANE,NPLANE) + DIMENSION VECT(7),VOUT(7) + + XV = XVAL(4) + YV = XVAL(5) + + ASIGN = 1. + IF (XVAL(1).LT.0.) ASIGN = -1. + PHI = XVAL(2) + ALAM = XVAL(3) + PXZ = DABS(1./XVAL(1)) + + PX = PXZ*DSIN(PHI) + PY = PXZ*DTAN(ALAM) + PZ = PXZ*DCOS(PHI) + PTOT = PXZ/DCOS(ALAM) + TTHET = DSQRT(DTAN(ALAM)**2+DSIN(PHI)**2)/DCOS(PHI) + THET = DATAN(TTHET) + PT = DSQRT(PX**2+PY**2) + + RL3 = ASIGN*PT / (0.299792458D-3 * BL3) + ALPHA = DATAN2(PY,PX) + XC = XV+RL3*DSIN(ALPHA) + YC = YV-RL3*DCOS(ALPHA) + + A12 = 0. + NTMAX = 0 + + ZEA = ZABS + XEA = XV + YEA = YV + PXEA = PX + PYEA = PY + PHIEA = PHI + PXZEA = ASIGN*PXZ + ALAMEA = ALAM +* 1er plan + ANGDEV = (ZPLANEP(1)-ZEA)*TTHET/RL3 + XP(1) = XC+RL3*DSIN(ANGDEV-ALPHA) + YP(1) = YC+RL3*DCOS(ANGDEV-ALPHA) + AL = THICK/ DCOS(THET) + AP(1) = (0.0136D0/PTOT) * DSQRT(AL) * (1 + 0.038D0*DLOG(AL)) +* 2eme plan + ANGDEV = (ZPLANEP(2)-ZEA)*TTHET/RL3 + XP(2) = XC+RL3*DSIN(ANGDEV-ALPHA) + YP(2) = YC+RL3*DCOS(ANGDEV-ALPHA) + AL = THICK/ DCOS(THET) + AP(2) = (0.0136D0/PTOT) * DSQRT(AL) * (1 + 0.038D0*DLOG(AL)) +* 3eme plan + ANGDEV = (ZPLANEP(3)-ZEA)*TTHET/RL3 + XP(3) = XC+RL3*DSIN(ANGDEV-ALPHA) + YP(3) = YC+RL3*DCOS(ANGDEV-ALPHA) + AL = THICK/ DCOS(THET) + AP(3) = (0.0136D0/PTOT) * DSQRT(AL) * (1 + 0.038D0*DLOG(AL)) +* 4eme plan + ANGDEV = (ZPLANEP(4)-ZEA)*TTHET/RL3 + XP(4) = XC+RL3*DSIN(ANGDEV-ALPHA) + YP(4) = YC+RL3*DCOS(ANGDEV-ALPHA) + AL = THICK/ DCOS(THET) + AP(4) = (0.0136D0/PTOT) * DSQRT(AL) * (1 + 0.038D0*DLOG(AL)) +* Fin de L3 + ANGDEV = (700.D0-ZEA)*TTHET/RL3 + XPL3 = XC+RL3*DSIN(ANGDEV-ALPHA) + YPL3 = YC+RL3*DCOS(ANGDEV-ALPHA) + PX = PT*DCOS(ANGDEV-ALPHA) + PY = -PT*DSIN(ANGDEV-ALPHA) + PHIC = DATAN2(PY,PX) + CX = DSIN(THET)*DCOS(PHIC) + CY = DSIN(THET)*DSIN(PHIC) + CZ = DCOS(THET) +* Entree du dipole + VECT(1) = XPL3+(ZMAGS-700.)*CX/CZ + VECT(2) = YPL3+(ZMAGS-700.)*CY/CZ + VECT(3) = ZMAGS + VECT(4) = CX + VECT(5) = CY + VECT(6) = CZ + VECT(7) = PTOT + + PXZ = PTOT*DSQRT(VECT(4)**2+VECT(6)**2) + RDIP = ASIGN*PXZ / (0.299792458D-3 * B0) + PHI1 = DATAN2(VECT(4),VECT(6)) + XC = VECT(1)+RDIP*DCOS(PHI1) + ZC = VECT(3)-RDIP*DSIN(PHI1) + + IF (DABS((ZMAGE-ZPLANEP(5))/RDIP).GE.1.D0) RETURN ! Particule boucle dans le champ + XP(5) = XC-ASIGN*DSQRT(RDIP**2-(ZPLANEP(5)-ZC)**2) + YP(5) = VECT(2)+(ZPLANEP(5)-ZMAGS)*VECT(5)/VECT(6) + CX = (ZPLANEP(5)-ZC)/RDIP + CY = VECT(5) + CZ = DABS((XP(5)-XC)/RDIP) + THET = DATAN2(DSQRT(CX**2+CY**2),CZ) + AL = THICK/ DCOS(THET) + AP(5) = (0.0136D0/PTOT) * DSQRT(AL) * (1 + 0.038D0*DLOG(AL)) + + IF (DABS((ZMAGE-ZPLANEP(6))/RDIP).GE.1.D0) RETURN ! Particule boucle dans le champ + XP(6) = XC-ASIGN*DSQRT(RDIP**2-(ZPLANEP(6)-ZC)**2) + YP(6) = VECT(2)+(ZPLANEP(6)-ZMAGS)*VECT(5)/VECT(6) + CX = (ZPLANEP(6)-ZC)/RDIP + CY = VECT(5) + CZ = DABS((XP(6)-XC)/RDIP) + THET = DATAN2(DSQRT(CX**2+CY**2),CZ) + AL = THICK/ DCOS(THET) + AP(6) = (0.0136D0/PTOT) * DSQRT(AL) * (1 + 0.038D0*DLOG(AL)) + + + IF (DABS((ZMAGE-ZC)/RDIP).GE.1.D0) RETURN ! Particule boucle dans le champ + VOUT(1) = XC-ASIGN*DSQRT(RDIP**2-(ZMAGE-ZC)**2) + VOUT(2) = VECT(2)+(ZMAGE-ZMAGS)*VECT(5)/VECT(6) + VOUT(3) = ZMAGE + VOUT(4) = (ZMAGE-ZC)/RDIP + VOUT(5) = VECT(5) + VOUT(6) = DABS((VOUT(1)-XC)/RDIP) + VOUT(7) = PTOT + + DO IV = 1,7 + VECT(IV) = VOUT(IV) + ENDDO + +* 7eme plan + THET = DATAN2(DSQRT(VECT(4)**2+VECT(5)**2),VECT(6)) + XP(7) = VECT(1)+(ZPLANEP(7)-ZMAGE)*VECT(4)/VECT(6) + YP(7) = VECT(2)+(ZPLANEP(7)-ZMAGE)*VECT(5)/VECT(6) + AL = THICK/ DCOS(THET) + AP(7) = (0.0136D0/PTOT) * DSQRT(AL) * (1 + 0.038D0*DLOG(AL)) +* 8eme plan + XP(8) = XP(7)+(ZPLANEP(8)-ZPLANEP(7))*VECT(4)/VECT(6) + YP(8) = YP(7)+(ZPLANEP(8)-ZPLANEP(7))*VECT(5)/VECT(6) + AL = THICK/ DCOS(THET) + AP(8) = (0.0136D0/PTOT) * DSQRT(AL) * (1 + 0.038D0*DLOG(AL)) + +* 9eme plan + XP(9) = XP(8)+(ZPLANEP(9)-ZPLANEP(8))*VECT(4)/VECT(6) + YP(9) = YP(8)+(ZPLANEP(9)-ZPLANEP(8))*VECT(5)/VECT(6) + AL = THICK/ DCOS(THET) + AP(9) = (0.0136D0/PTOT) * DSQRT(AL) * (1 + 0.038D0*DLOG(AL)) + +* 10eme plan + XP(10) = XP(9)+(ZPLANEP(10)-ZPLANEP(9))*VECT(4)/VECT(6) + YP(10) = YP(9)+(ZPLANEP(10)-ZPLANEP(9))*VECT(5)/VECT(6) + AL = THICK/ DCOS(THET) + AP(10) = (0.0136D0/PTOT) * DSQRT(AL) * (1 + 0.038D0*DLOG(AL)) + +** Matrice de covariance + I = 0 + DO II = 1,NPLANE + IF (LPLANE(II).EQ.1) THEN + I = I + 1 +* I = II + J = I - 1 + DO JJ = II, NPLANE + IF (LPLANE(JJ).EQ.1) THEN + J = J + 1 +* J = JJ + COV (I,J) = 0.0D0 + COV (J,I) = A12 + IF (I .EQ. J) THEN + COV(J,I) =COV(J,I) + XPREC**2 + ENDIF + +* IF (I .EQ. 10 .AND. J .EQ. 10) PRINT *,'10 10 ',COV(J,I) + DO L = 1,NTMAX + COV(J,I) = COV(J,I) + & + (ZPLANEP(II) + DISTAZ(L))*(ZPLANEP(JJ) + DISTAZ(L))*AMS(L)**2 + ENDDO + DO K = 1, II-1 + COV(J,I) = COV(J,I) + & + (ZPLANEP(II)-ZPLANEP(K))*(ZPLANEP(JJ)-ZPLANEP(K))*AP(K)**2 +* IF (I .EQ. 10 .AND. J .EQ. 10) PRINT *,'10 10 ',COV(J,I) + ENDDO + COVY(I,J) = 0.0D0 + COVY(J,I) = COV(J,I) + IF (I .EQ. J) THEN + COVY(J,I) = COVY(J,I) - XPREC**2 + YPREC**2 + ENDIF + ENDIF + ENDDO + ENDIF + ENDDO + +* Inversion des matrices de covariance + NPLU = I + + IFAIL = 0 + CALL DSINV(NPLU, COV, NPLANE, IFAIL) +** IF (JFAIL.NE.0 .AND. IFAIL .NE. 0) STOP 'ERROR' + IF (IFAIL .NE. 0) STOP 'ERROR' + IFAIL = 0 + CALL DSINV(NPLU, COVY, NPLANE, IFAIL) +** IF (JFAIL.NE.0 .AND. IFAIL .NE. 0) STOP 'ERROR' + IF (IFAIL .NE. 0) STOP 'ERROR' +* PRINT *,' COVARIANCE MATRIX AFTER' +* DO I = 1, NPLANE +* PRINT *,(COV(J,I),J=1,NPLANE) +* ENDDO + +** Calcul de FVAL ou CHI2 + FVAL = 0.0D0 + I = 0 + DO II = 1,NPLANE + IF (LPLANE(II).EQ.1) THEN + I = I+1 +* I = II + J = 0 + DO JJ = 1,NPLANE + IF (LPLANE(JJ).EQ.1) THEN + J = J+1 +* J = JJ + FVAL = FVAL + COV(J,I)*(XMP(II)-XP(II))*(XMP(JJ)-XP(JJ)) + FVAL = FVAL + COVY(J,I)*(YMP(II)-YP(II)) + & *(YMP(JJ)-YP(JJ)) +** IF (JJ.EQ.II) THEN +** FVAL = FVAL + (XMP(II)-XP(II))*(XMP(JJ)-XP(JJ))/XPREC**2 +** FVAL = FVAL + (YMP(II)-YP(II)) +** & *(YMP(JJ)-YP(JJ))/YPREC**2 +** ENDIF + ENDIF + ENDDO + ENDIF + ENDDO + CHI2 = FVAL + print *,' fcnfit pxz tphi talam xvert yvert chi2', + & PXZEA,PHIEA,ALAMEA, + & XEA,YEA,CHI2/FLOAT(2*NPLU-5) + + 1000 FORMAT(I5,7F12.6) + + RETURN + END + +