////////////////////////////////////////////////
#include <TTUBE.h>
+#include <TBRIK.h>
+#include <TRotMatrix.h>
#include <TNode.h>
+#include <TTree.h>
#include <TRandom.h>
#include <TObject.h>
#include <TVector.h>
#include <TObjArray.h>
+#include <TMinuit.h>
+#include <TParticle.h>
+#include <TROOT.h>
+#include <TFile.h>
+#include <TNtuple.h>
+#include <TCanvas.h>
+#include <TPad.h>
+#include <TDirectory.h>
+#include <TObjectTable.h>
+#include <AliPDG.h>
#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()
{
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;
+ */
}
//___________________________________________
{
//Begin_Html
/*
-<img src="picts/alimuon.gif">
+<img src="gif/alimuon.gif">
*/
//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
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;
}
//___________________________________________
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)
//
// 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 )
{
// Create Tree branches for the MUON.
const Int_t buffersize = 4000;
- char branchname[20];
+ char branchname[30];
sprintf(branchname,"%sCluster",GetName());
AliDetector::MakeBranch(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()) {
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) {
}
}
}
+
+ // 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()
// 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();
}
+ */
}
//___________________________________________
}
//___________________________________________
-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;
((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);
{
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<nnew; i++) {
+ if (Int_t(newclust[3][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"<<fFileName<<endl;
+ File=new TFile(fFileName);
+ cout<<"I have opened "<<fFileName<<" file "<<endl;
+ fHits2 = new TClonesArray("AliMUONhit",1000 );
+ fClusters2 = new TClonesArray("AliMUONcluster",10000);
+ }
+ first=false;
+ File->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; digit<ndigits; digit++)
- {
- mdig = (AliMUONdigit*)MUONdigits->UncheckedAt(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;digit<ndigits;digit++) {
- mdig = (AliMUONdigit*)MUONdigits->UncheckedAt(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;Ilist<Nlist;Ilist++) {
- if (elem[kMaxNpadx+Xlist[Ilist]][kMaxNpady
- +Ylist[Ilist]]) {
- //
- // Add the digit at the end and reset the table
- //
- Cluster->AddDigit(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; track<ntracks; track++) {
+ gAlice->ResetHits();
+ 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;tr<nptracks;tr++) {
+ TVector *pptrk_p=(TVector*)trlist->At(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; track<ntracks; track++) {
+
+ if (fHits2) fHits2->Clear();
+ if (fClusters2) fClusters2->Clear();
+
+ TH1->GetEvent(track);
+//
+// Loop over hits
+ AliMUONhit* mHit;
+ for(int i=0;i<fHits2->GetEntriesFast();++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;j<fClusters2->GetEntriesFast();++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;tr<nptracks;tr++) {
+ TVector *pptrk_p=(TVector*)trlist->At(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 "<<endl;
+ // const Float_t zero_supm = 6.;
+ Int_t nentries=list->GetEntriesFast();
+ //printf(" \n \n nentries %d \n",nentries);
+ // start filling the digits
+
+ for (Int_t nent=0;nent<nentries;nent++) {
+ AliMUONlist *address=(AliMUONlist*)list->At(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 "<<nptracks<<endl;
+ nptracks=10;
+ }
+ if (nptracks > 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;tr<nptracks;tr++) {
+ TVector *pp_p=(TVector*)trlist->At(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"<<endl;
+ // gAlice->GetEvent(nev);
+ gAlice->TreeD()->Fill();
+ //TTree *TD=gAlice->TreeD();
+ /*
+ Stat_t ndig=TD->GetEntries();
+ cout<<"number of digits "<<ndig<<endl;
+ TClonesArray *fDch;
+ for (int i=0;i<10;i++) {
+ fDch= MUON->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;nent<nadr;nent++) {
+ TVector *pv=(TVector*)p_adr->At(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<imax;i++){
+ qmax=0;
+ jmax=0;
+
+ for(j=0;j<ntr;j++){
+
+ if((i == 1 && j == idx[i-1])
+ ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
+
+ if(charges[j] > 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 "<<nent<<endl;
+ TClonesArray *fRch;
+ for (int i=0;i<10;i++) {
+ fRch=RawClustAddress(i);
+ int nraw=fRch->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; iraw1<nrawcl1; iraw1++) {
+ mRaw1= (AliMUONRawCluster*)MUONrawclust->UncheckedAt(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; iraw1<nrawcl1; iraw1++) {
+ idx[3]=iraw1;
+ xc2[3]=x1[iraw1];
+ yc2[3]=y1[iraw1];
+ //printf("nrawcl2 is zero - idx[0] %d\n",idx[0]);
+
+ AddCathCorrel(ich,idx,xc2,yc2);
+ // reset
+ idx[3]=-1;
+ xc2[3]=0.;
+ yc2[3]=0.;
+
+ } // store information from cathode 1 only
+ } else {
+ // printf("Found %d raw clusters for cathode 2 in chamber %d \n",
+ // nrawcl2, ich+1);
+
+ for (Int_t iraw2=0; iraw2<nrawcl2; iraw2++) {
+ mRaw2= (AliMUONRawCluster*)MUONrawclust->UncheckedAt(iraw2);
+ x2[iraw2]=mRaw2->fX;
+ y2[iraw2]=mRaw2->fY;
+ q2[iraw2]=(Float_t)mRaw2->fQ;
+ } // rawclusters cathode 2
+//
+// Initalisation finished
+ for (iraw1=0; iraw1<nrawcl1; iraw1++) {
+ // find the sector
+ Int_t ix,iy;
+ seg->GetPadIxy(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]<seg->Dpx(isec) && xdarray[1]<seg->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<imax;i++) {
+ if (idx2[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;i<counter;i++) {
+ xdarray[i]=1100.;
+ xarray[i]=0.;
+ yarray[i]=0.;
+ qarray[i]=0.;
+ idx2[i]=-1;
+ }
+ for (int i=0;i<3;i++) {
+ idx[i]=-1;
+ xc2[i]=0.;
+ yc2[i]=0.;
+ }
+ } // iraw1
+ }
+ x1.Reset();
+ x2.Reset();
+ y1.Reset();
+ y2.Reset();
+ q1.Reset();
+ q2.Reset();
+ } //ich
+//
+ if (first) {
+ MakeTreeC("C");
+ first=false;
+ }
+ TTree *TC=TreeC();
+ TC->Fill();
+ //Int_t nentries=(Int_t)TC->GetEntries();
+ //cout<<"number entries in tree of correlated clusters "<<nentries<<endl;
+ TClonesArray *fCch;
+ static Int_t countev=0;
+ Int_t countch=0;
+
+ for (int i=0;i<10;i++) {
+ fCch= CathCorrelAddress(i);
+ Int_t ncor=fCch->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.
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) { }
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++) {
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 {
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);
}
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 "<<fFileName<<endl;
+ File=new TFile(fFileName);
+ cout<<"I have opened "<<fFileName<<" file "<<endl;
+ fHits2 = new TClonesArray("AliMUONhit",1000 );
+ fParticles2 = new TClonesArray("GParticle",1000);
+ first=false;
+ }
+ File->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="<<ntracks<<endl;
+
+ Int_t maxidg = 0;
+ Int_t nres=0;
+
+//
+// Loop over tracks
+//
+
+ for (Int_t track=0; track<ntracks;track++) {
+ gAlice->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 "<<izch[maxidg]<<" ptot="<<ptotg[maxidg]<<" theta="<<thet<<" phi="<<mHit->fPhi<<" z="<<zz<<endl;
+
+ Int_t iparent = Part->GetFirstMother();
+ if (iparent >= 0) {
+ Int_t ip;
+ while(1) {
+ ip=((TParticle*) fPartArray->UncheckedAt(iparent))->GetFirstMother();
+ if (ip < 0) {
+ break;
+ } else {
+ iparent = ip;
+ }
+ }
+ }
+ //printf("iparent - %d\n",iparent);
+ Int_t id1 = ftrack; // numero de la particule generee au vertex
+ Int_t idum = track+1;
+ Int_t id2 = ((TParticle*) fPartArray->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="<<xgeant[maxidg]<<endl;
+ //cout<<"y="<<ygeant[maxidg]<<endl;
+ //cout<<"typ="<<itypg[maxidg]<<endl;
+
+ maxidg ++;
+
+ }
+ }
+ } // hit loop
+ } // if MUON
+ } // track loop first file
+
+ if (TH1 && fHits2 ) { // if background file
+ ntracks =(Int_t)TH1->GetEntries();
+ printf("Trackf_read - 2-nd file - ntracks %d\n",ntracks);
+
+ // Loop over tracks
+ for (Int_t track=0; track<ntracks; track++) {
+
+ if (fHits2) fHits2->Clear();
+ TH1->GetEvent(track);
+
+ // Loop over hits
+ for (int i=0;i<fHits2->GetEntriesFast();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="<<nhittot1<<endl;
+
+ static Int_t nbres=0;
+ if (nres>=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 "<<nev<<endl;
+
+ MUON->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;icor<ncor;icor++) {
+ AliMUONcorrelation * mCor = (AliMUONcorrelation*)MUONcorrel->UncheckedAt(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;i<mul;i++) {
+ Int_t idx=mRaw->fIndexMap[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;i<mul;i++) {
+ Int_t idx=mRaw->fIndexMap[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 "<<ievr<<endl;
+ nhittot1 = maxidg ;
+ cout<<"nhittot1="<<nhittot1<<endl;
+
+ static Int_t nbres=0;
+ static Int_t nbcor=0;
+ if (nres>=19) nbres++;
+ printf("nres ,nncor - %d %d\n",nres,nncor);
+ printf("nbres - %d\n",nbres);
+ if (nncor>=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)
//___________________________________________
//
// 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];
}
//_____________________________________________________________________________
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)
AliHit(shunt, track)
{
fChamber=vol[0];
- fParticle=(Int_t) hits[0];
+ fParticle=hits[0];
fX=hits[1];
fY=hits[2];
fZ=hits[3];
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 (r<ro) return -1;
+ else return 0;
+ */
+ AliMUONRawCluster *raw=(AliMUONRawCluster *)obj;
+ Float_t y=fY;
+ Float_t yo=raw->fY;
+ if (y>yo) return 1;
+ else if (y<yo) return -1;
+ else return 0;
+
}
-AliMUONRecCluster::
-AliMUONRecCluster(Int_t FirstDigit,Int_t Ichamber, Int_t Icathod)
+Int_t AliMUONRawCluster::
+BinarySearch(Float_t y, TArrayF coord, Int_t from, Int_t upto)
{
- fX = 0.;
- fY = 0.;
- fDigits = new TArrayI(10);
- fNdigit=0;
- AddDigit(FirstDigit);
- fChamber=Ichamber;
- fCathod=Icathod;
+ // Find object using a binary search. Array must first have been sorted.
+ // Search can be limited by setting upto to desired index.
+
+ Int_t low=from, high=upto-1, half;
+ while(high-low>1) {
+ 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;i<fNdigit;i++)
- array[i] = fDigits->At(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;i<imax;i++){
+ xmin=1001.;
+ jmin=0;
+
+ for(j=0;j<ntr;j++){
+ if ((i == 1 && j == id[i-1])
+ ||(i == 2 && (j == id[i-1] || j == id[i-2]))) continue;
+ if (TMath::Abs(xdarray[j]) < xmin) {
+ xmin = TMath::Abs(xdarray[j]);
+ jmin=j;
+ }
+ } // j
+ if (xmin != 1001.) {
+ id[i]=jmin;
+ jx[i]=xarray[jmin];
+ jy[i]=yarray[jmin];
+ jq[i]=qarray[jmin];
+ jid[i]=idx[jmin];
+ }
+
+ } // i
+
+ for (i=0;i<3;i++){
+ if (jid[i] == -2) {
+ xarray[i]=1001.;
+ yarray[i]=1001.;
+ qarray[i]=1001.;
+ idx[i]=-1;
+ } else {
+ xarray[i]=jx[i];
+ yarray[i]=jy[i];
+ qarray[i]=jq[i];
+ idx[i]=jid[i];
+ }
}
- fDigits->AddAt(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; i<fMultiplicity; i++) {
+ if (fPhysicsMap[i]==2) iPhys++;
+ if (fPhysicsMap[i]==1) iMixed++;
+ if (fPhysicsMap[i]==0) iBg++;
+ }
+ if (iMixed==0 && iBg==0) {
+ return 2;
+ } else if ((iPhys != 0 && iBg !=0) || iMixed != 0) {
+ return 1;
+ } else {
+ return 0;
+ }
}
-Int_t AliMUONRecCluster::FirstDigitIndex()
-{
- fCurrentDigit=0;
- return fDigits->At(fCurrentDigit);
-}
+
+ClassImp(AliMUONreccluster)
+ClassImp(AliMUONsegmentation)
+ClassImp(AliMUONresponse)
+
+
+
+
+
-Int_t AliMUONRecCluster::NextDigitIndex()
-{
- fCurrentDigit++;
- if (fCurrentDigit<fNdigit)
- return fDigits->At(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!
-}
#include "AliDetector.h"
#include "AliHit.h"
#include "AliMUONConst.h"
-#include "AliDigit.h"
+#include "AliDigit.h"
+#include "AliMUONchamber.h"
+#include "AliMUONSegRes.h"
#include <TVector.h>
#include <TObjArray.h>
-
+#include <TArrayF.h>
+#include <TFile.h>
+#include <TTree.h>
+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 {
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() {;}
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
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
};
//___________________________________________
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);
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() {}
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
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
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:
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
--- /dev/null
+#include "AliMUONClusterFinder.h"
+#include "TTree.h"
+#include "AliRun.h"
+#include <TCanvas.h>
+#include <TH1.h>
+#include <TPad.h>
+#include <TGraph.h>
+#include <TPostScript.h>
+#include <TMinuit.h>
+
+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;i<fNdigit;i++)
+ array[i] = fDigits->At(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 (fCurrentDigit<fNdigit)
+ return fDigits->At(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; i<nn; i++) {
+ if (fHitMap->TestHit(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; i<mul; i++)
+ {
+ dig[i]= (AliMUONdigit*)fDigits->UncheckedAt(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; i<mul; i++) {
+ fSegmentation->Neighbours(ix[i], iy[i], &nn, X, Y);
+ IsLocal[i]=kTRUE;
+ for (j=0; j<nn; j++) {
+ if (fHitMap->TestHit(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; k<NLocal; k++) {
+ if (X[j]==ix[IndLocal[k]] && Y[j]==iy[IndLocal[k]]){
+ IsLocal[i]=kFALSE;
+ }
+ }
+ }
+ }
+ } // loop over next neighbours
+ // Maxima should not be on the edge
+ if (IsLocal[i]) {
+ IndLocal[NLocal]=i;
+ NLocal++;
+ }
+ } // loop over all digits
+// printf("Found %d local Maxima",NLocal);
+//
+// If only one local maximum found but multiplicity is high
+// take global maximum from the list of digits.
+ if (NLocal==1 && mul>12) {
+ Int_t nnew=0;
+ for (i=0; i<mul; i++) {
+ if (!IsLocal[i]) {
+ IndLocal[NLocal]=i;
+ IsLocal[i]=kTRUE;
+ NLocal++;
+ nnew++;
+ }
+ if (nnew==1) break;
+ }
+ }
+
+// If number of local maxima is 2 try to fit a double gaussian
+ if (NLocal==2) {
+//
+// Initialise global variables for fit
+ gFirst=1;
+ gSegmentation=fSegmentation;
+ gResponse =fResponse;
+ gNbins=mul;
+
+ for (i=0; i<mul; i++) {
+ gix[i]=ix[i];
+ giy[i]=iy[i];
+ gCharge[i]=Float_t(q[i]);
+ }
+//
+ if (gFirst) {
+ gFirst=kFALSE;
+ gMyMinuit = new TMinuit(5);
+ }
+ gMyMinuit->SetFCN(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<Int_t>(gChargeTot*qfrac);
+ } else {
+ cnew.fQ=static_cast<Int_t>(gChargeTot*(1-qfrac));
+ }
+ gSegmentation->SetHit(xrec[j],yrec[j]);
+ for (i=0; i<mul; i++) {
+ cnew.fIndexMap[cnew.fMultiplicity]=c->fIndexMap[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; i<mul; i++) {
+ if (!IsLocal[i]) {
+ IndLocal[NLocal]=i;
+ IsLocal[i]=kTRUE;
+ NLocal++;
+ nnew++;
+ }
+ if (nnew==nGlob) break;
+ }
+ }
+ }
+ //
+ // Associate hits to peaks
+ //
+ for (i=0; i<mul; i++) {
+ Float_t dmin=1.E10;
+ Float_t qmax=0;
+ if (IsLocal[i]) continue;
+ for (j=0; j<NLocal; j++) {
+ Int_t il=IndLocal[j];
+ Float_t d=TMath::Sqrt((x[i]-x[il])*(x[i]-x[il])
+ +(y[i]-y[il])*(y[i]-y[il]));
+ Float_t ql=q[il];
+ //
+ // Select nearest peak
+ //
+ if (d<dmin) {
+ dmin=d;
+ qmax=ql;
+ AssocPeak[i]=j;
+ } else if (d==dmin) {
+ //
+ // If more than one take highest peak
+ //
+ if (ql>qmax) {
+ dmin=d;
+ qmax=ql;
+ AssocPeak[i]=j;
+ }
+ }
+ }
+ }
+
+
+ //
+ // One cluster for each maximum
+ //
+ for (j=0; j<NLocal; j++) {
+ AliMUONRawCluster cnew;
+ if (fNPeaks == 0) {
+ cnew.fNcluster[0]=-1;
+ cnew.fNcluster[1]=fNRawClusters;
+ } else {
+ cnew.fNcluster[0]=fNPeaks;
+ cnew.fNcluster[1]=0;
+ }
+ cnew.fIndexMap[0]=c->fIndexMap[IndLocal[j]];
+ cnew.fMultiplicity=1;
+ for (i=0; i<mul; i++) {
+ if (IsLocal[i]) continue;
+ if (AssocPeak[i]==j) {
+ cnew.fIndexMap[cnew.fMultiplicity]=c->fIndexMap[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; i<c->fMultiplicity; 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; in<nn; in++) {
+ Int_t ix=Xlist[in];
+ Int_t iy=Ylist[in];
+ if (fHitMap->TestHit(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; ndig<fNdigits; ndig++) {
+ dig = (AliMUONdigit*)fDigits->UncheckedAt(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;k<c.fMultiplicity;k++) {
+ c.fIndexMap[k]=0;
+ }
+ c.fMultiplicity=0;
+ } // end loop ndig
+ delete fHitMap;
+}
+
+void AliMUONClusterFinder::
+CalibrateCOG()
+{
+ Float_t x[5];
+ Float_t y[5];
+ Int_t n, i;
+ TF1 func;
+ if (fSegmentation) {
+ fSegmentation->GiveTestPoints(n, x, y);
+ for (i=0; i<n; i++) {
+ Float_t xtest=x[i];
+ Float_t ytest=y[i];
+ SinoidalFit(xtest, ytest, func);
+ fSegmentation->SetCorrFunc(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; i<ns; i++) {
+//
+// Pad Loop
+//
+ Float_t sum=0;
+ Float_t qcheck=0;
+ segmentation->SigGenInit(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; i<ns; i++) {
+//
+// Pad Loop
+//
+ Float_t sum=0;
+ Float_t qcheck=0;
+ segmentation->SigGenInit(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<gNbins; jbin++) {
+ qtot+=gCharge[jbin];
+ }
+ gFirst=0;
+ //printf("\n sum of charge from DiscrCharge %f\n", qtot);
+ gChargeTot=static_cast<Int_t>(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; i<gNbins; i++) {
+ Float_t q0=gCharge[i];
+ Float_t q1=DiscrCharge(i,par);
+ delta=(q0-q1)/TMath::Sqrt(q0);
+ chisq+=delta*delta;
+ qcont+=q1;
+ qtot+=q0;
+ }
+ chisq=chisq+=(qtot-qcont)*(qtot-qcont)*0.5;
+ f=chisq;
+}
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+#ifndef AliMUONClusterFinder_H
+#define AliMUONClusterFinder_H
+////////////////////////////////////////////////
+// MUON Cluster Finder Class //
+////////////////////////////////////////////////
+#include "AliMUONHitMap.h"
+#include "TF1.h"
+class AliMUONClusterFinder :
+ public TObject
+{
+public:
+ TClonesArray* fDigits;
+ Int_t fNdigits;
+protected:
+ AliMUONsegmentation* fSegmentation;
+ AliMUONresponse* fResponse;
+ TClonesArray* fRawClusters;
+ Int_t fChamber;
+ Int_t fNRawClusters;
+ AliMUONHitMapA1* fHitMap;
+ TF1* fCogCorr;
+ Int_t fNperMax;
+ Int_t fDeclusterFlag;
+ Int_t fClusterSize;
+ Int_t fNPeaks;
+ public:
+ AliMUONClusterFinder
+ (AliMUONsegmentation *segmentation,
+ AliMUONresponse *response, TClonesArray *digits, Int_t chamber);
+ AliMUONClusterFinder();
+ ~AliMUONClusterFinder(){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);
+ // 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
+
+
+
+
+
+
+
--- /dev/null
+#include "AliMUONClusterFinderv0.h"
+#include "AliMUONSegResV1.h"
+//#include "TTree.h"
+//#include "AliRun.h"
+//#include <TCanvas.h>
+//#include <TH1.h>
+//#include <TPad.h>
+//#include <TGraph.h>
+
+//----------------------------------------------------------
+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;i<nPara; i++)
+ {
+ // Compute the charge on the 9 neighbouring pads
+ // We assume that there are no pads connected in parallel in the neighbourhood
+ //
+ Float_t q=0;
+ for (Int_t dx=-1;dx<2;dx++)
+ for (Int_t dy=-1;dy<2;dy++)
+ {
+ if (dx==dy && dy==0)
+ continue;
+ Int_t padY=dig->fPadY+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;i<cluster->fMultiplicity;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; i<cluster->fMultiplicity; 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; i<nn; i++) {
+ if (fHitMap->TestHit(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; i<mul; i++)
+ {
+ dig[i]= (AliMUONdigit*)fDigits->UncheckedAt(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; i<mul; i++) {
+ fSegmentation->Neighbours(ix[i], iy[i], &nn, X, Y);
+ IsLocal[i]=kTRUE;
+ for (j=0; j<nn; j++) {
+ if (fHitMap->TestHit(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; k<NLocal; k++) {
+ if (X[j]==ix[IndLocal[k]] && Y[j]==iy[IndLocal[k]]){
+ IsLocal[i]=kFALSE;
+ }
+ }
+ }
+ }
+ } // loop over next neighbours
+ if (IsLocal[i]) {
+ IndLocal[NLocal]=i;
+ // New for LYON : we guess which is the actual position of the pad hit
+ // But this would run like that for normal chamber !
+ c->fOffsetMap[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; i<mul; i++) {
+// if (!IsLocal[i]) {
+// IndLocal[NLocal]=i;
+// IsLocal[i]=kTRUE;
+// NLocal++;
+// nnew++;
+// }
+// if (nnew==nGlob) break;
+// }
+// }
+// }
+//
+//
+// Associate hits to peaks
+//
+ for (i=0; i<mul; i++) {
+ //
+ // loop on digits
+ //
+ Float_t dmin=1.E10;
+ Float_t qmax=0;
+ Int_t offset;
+ if (IsLocal[i]) continue;
+ for (j=0; j<NLocal; j++) {
+ //
+ // Loop on peaks
+ //
+ Int_t il=IndLocal[j];
+// Float_t d=TMath::Sqrt((x[i]-x[il])*(x[i]-x[il])
+// +(y[i]-y[il])*(y[i]-y[il]));
+ // Can run like that for non-Lyon chambers
+ Float_t d = fSegmentation->Distance2AndOffset(ix[i],iy[i],x[il],y[il], &offset);
+ Float_t ql=q[il];
+//
+// Select nearest peak
+//
+ if (d<dmin) {
+ dmin=d;
+ qmax=ql;
+ AssocPeak[i]=j;
+ c->fOffsetMap[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; j<NLocal; j++) {
+ AliMUONRawCluster cnew;
+ cnew.fIndexMap[0]=c->fIndexMap[IndLocal[j]];
+ cnew.fOffsetMap[0]=c->fOffsetMap[IndLocal[j]];
+ cnew.fMultiplicity=1;
+ for (i=0; i<mul; i++) {
+ if (IsLocal[i]) continue;
+ if (AssocPeak[i]==j) {
+ cnew.fIndexMap[cnew.fMultiplicity]=c->fIndexMap[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; i<c->fMultiplicity; 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; in<nn; in++) {
+ Int_t ix=Xlist[in];
+ Int_t iy=Ylist[in];
+ if (fHitMap->TestHit(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; ndig<fNdigits; ndig++) {
+ dig = (AliMUONdigit*)fDigits->UncheckedAt(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;k<c.fMultiplicity;k++) {
+ c.fIndexMap[k]=0;
+ c.fOffsetMap[k]=0;
+ }
+ c.fMultiplicity=0;
+ } // end loop ndig
+ delete fHitMap;
+}
+
+/*
+
+void AliMUONClusterFinder::
+CalibrateCOG()
+{
+ Float_t x[5];
+ Float_t y[5];
+ Int_t n, i;
+ TF1 func;
+
+ if (fSegmentation) {
+ fSegmentation->GiveTestPoints(n, x, y);
+ for (i=0; i<n; i++) {
+ Float_t xtest=x[i];
+ Float_t ytest=y[i];
+ SinoidalFit(xtest, ytest, func);
+ }
+ fCogCorr = 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);
+
+// MANU : without const, error on HP
+ const 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->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; i<ns; i++) {
+//
+// Pad Loop
+//
+ Float_t sum=0;
+ Float_t qcheck=0;
+ segmentation->SigGenInit(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; i<ns; i++) {
+//
+// Pad Loop
+//
+ Float_t sum=0;
+ Float_t qcheck=0;
+ segmentation->SigGenInit(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;
+ }
+*/
+
+
+
+
+
+
+
--- /dev/null
+#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
+
+
+
+
+
+
+
//
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
+
--- /dev/null
+#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; ndig<fNdigits; ndig++) {
+ dig = (AliMUONdigit*)fDigits->UncheckedAt(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;
+ }
+}
+
+
--- /dev/null
+#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
+
+
--- /dev/null
+#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
+
+
+
--- /dev/null
+#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)));
+}
+
+
+
+
+
+
+
+
+
--- /dev/null
+#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
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/////////////////////////////////////////////////////
+// Segmentation and Response classes version 01 //
+/////////////////////////////////////////////////////
+
+#include <TTUBE.h>
+#include <TNode.h>
+#include <TBox.h>
+#include <TRandom.h>
+
+#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<fNsec; isec++) {
+//
+// loop over pads along the aode wires
+ for (Int_t iy=1; iy<=fNpy; iy++) {
+//
+ Float_t x=iy*fDpy-fDpy/2;
+ if (x > 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; i<fNsec; i++) {
+ if (absix<=fNpxS[i][absiy]){
+ isec=i;
+ break;
+ }
+ }
+ return isec;
+}
+
+ void AliMUONsegmentationV01::
+ GetPadIxy(Float_t x, Float_t y, Int_t &ix, Int_t &iy)
+{
+// returns pad coordinates (ix,iy) for given real coordinates (x,y)
+//
+ iy = (y>0)? 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; iy<Npy(); iy++)
+ {
+ for (Int_t isec=0; isec<4; isec++) {
+ if (isec==0) {
+ x0=0;
+ x1=fCx[isec][iy]*dx;
+ } else {
+ x0=fCx[isec-1][iy]*dx;
+ x1=fCx[isec][iy]*dx;
+ }
+ y0=Float_t(iy-1)*dy;
+ y1=y0+dy;
+ box=new TBox(x0+xc,y0+yc,x1+xc,y1+yc);
+ box->SetFillColor(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];
+}
+
--- /dev/null
+#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
+
+
+
+
+
+
--- /dev/null
+/////////////////////////////////////////////////////
+// Segmentation and Response classes version 02 //
+/////////////////////////////////////////////////////
+
+#include <TTUBE.h>
+#include <TNode.h>
+#include <TRandom.h>
+#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;
+}
+
+
--- /dev/null
+#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
+
+
+
+
+
+
+
+
+
--- /dev/null
+/////////////////////////////////////////////////////
+// Segmentation and Response classes version 04 //
+/////////////////////////////////////////////////////
+
+#include <TTUBE.h>
+#include <TNode.h>
+#include <TRandom.h>
+
+#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]);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+#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
+
+
+
+
+
+
--- /dev/null
+/////////////////////////////////////////////////////
+// Segmentation and Response classes version 04 //
+/////////////////////////////////////////////////////
+
+#include <TTUBE.h>
+#include <TNode.h>
+#include <TRandom.h>
+
+#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];
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+#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
+
+
+
+
+
+
--- /dev/null
+/////////////////////////////////////////////////////////
+// Manager and hits classes for set:MUON version LYON //
+/////////////////////////////////////////////////////////
+
+#include <TTUBE.h>
+#include <TNode.h>
+#include <TRandom.h>
+
+//#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<fNZoneCut[iZone];iCut++)
+ if ( aY<=fZoneY[iZone][iCut] && aX<=fZoneX[iZone][iCut] )
+ {
+ zone=iZone;
+ break;
+ }
+ }
+return zone;
+}
+
+void AliMUONsegmentationV1::
+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 AliMUONsegmentationV1::
+SetPad(Int_t ix, Int_t iy)
+{
+ GetPadCxy(ix,iy,fx,fy);
+}
+
+
+void AliMUONsegmentationV1::SetPadCoord(Int_t iX, Int_t iY)
+{
+GetPadCxy(iX,iY,fx,fy);
+Float_t radius2;
+if ( ( (radius2=fx*fx+fy*fy) > 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<nPara; i++)
+ {
+ Float_t x,y;
+ GetPadCxy(iX+i*offset,iY,x,y);
+ Float_t d2=(x-X)*(x-X) + (y-Y)*(y-Y);
+ if ( d2min > 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;nTest<nTot; nTest++)
+ {
+ if ( Xlist[nTest]==Xlist[nTot] && Ylist[nTest]==Ylist[nTot])
+ // we found it
+ break ;
+ }
+ if (nTest==nTot)
+ nTot++;
+ }
+*Nlist = nTot;
+}
+
+void AliMUONsegmentationV1::
+NeighboursNonDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[12], Int_t Ylist[12])
+// 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=4*nParallel;
+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;
+if (nParallel>1) {
+ 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<nParallel;i++)
+ for (Int_t dx=-1;dx<2;dx++)
+ for (Int_t dy=-1;dy<2;dy++)
+ {
+ if (dx==dy && dy==0)
+ continue;
+ Xlist[*Nlist] = iX + dx + i*offset;
+ Ylist[*Nlist] = iY + dy;
+ (*Nlist)++;
+ }
+CleanNeighbours(Nlist,Xlist,Ylist);
+}
+
+void AliMUONsegmentationV1::Neighbours(Int_t iX, Int_t iY, Int_t* Nlist,
+ Int_t Xlist[24], Int_t Ylist[24])
+{NeighboursDiag(iX,iY,Nlist,Xlist,Ylist);}
+
+
+void AliMUONsegmentationV1::
+FitXY(AliMUONRecCluster* Cluster,TClonesArray* MUONdigits)
+ // Default : Centre of gravity method
+{
+printf (" AliMUONsegmentationV1::FitXY called!\n");
+ ;
+}
+
+void AliMUONsegmentationV1::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y)
+{
+ n=1;
+ x[0]=(TMath::Sqrt(frSensMax2)-TMath::Sqrt(frSensMin2))/2/TMath::Sqrt(2.);
+ y[0]=x[0];
+}
+
--- /dev/null
+#ifndef MUONSegResV1_H
+#define MUONSegResV1_H
+/////////////////////////////////////////////////////////
+// Manager and hits classes for set:MUON version 0 //
+/////////////////////////////////////////////////////////
+
+#include "AliMUONSegRes.h"
+
+const Int_t NZONE = 3; // Specific for chamber with equal pads
+const Int_t NZONEm1 = 2; // NZONE - 1
+const Int_t NZONECUT = 30;
+
+class AliMUONsegmentationV1 :
+public AliMUONsegmentation {
+ public:
+ AliMUONsegmentationV1();
+ virtual ~AliMUONsegmentationV1(){}
+ //
+ // Set Chamber Segmentation Parameters
+ void SetNzone(Int_t N) {fNzone = N;};
+ virtual void SetPADSIZ(Float_t p1, Float_t p2);
+ void SetSensOffset(Float_t Offset) {fSensOffset = Offset;};
+ void SetDAnod(Float_t D) {fDAnod = D;};
+ // max x and y for the zone in number of pads units
+ //(WARNING : first pad is labelled 0 !!)
+ virtual void AddCut(Int_t Zone, Int_t nX, Int_t nY);
+ virtual void DefaultCut(void);
+
+ //
+ // Initialisation
+ virtual void Init(AliMUONchamber*);
+ //
+ // Get member data
+ virtual Float_t Dpx(){return fDpx;}
+ virtual Float_t Dpy(){return fDpy;}
+ virtual Float_t Dpx(Int_t i){return fDpx;}
+ virtual Float_t Dpy(Int_t i){return fDpy;}
+ virtual Int_t Npx(){return fNpx;}
+ virtual Int_t Npy(){return fNpy;}
+ virtual Float_t GetRealDpx(Int_t isec) {return fDpx;}
+ //
+ // know the zone of segmentation
+ virtual Int_t GetZone(Float_t X, Float_t Y);
+ virtual Int_t GetZone(Int_t X, Int_t Y);
+ //
+ // Transform from pad (wire) to real coordinates and vice versa
+ virtual Int_t GetiAnod(Float_t xhit);
+ 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 );
+ // set pad position
+ virtual void SetPad(Int_t, Int_t);
+ // set hit position
+ virtual void SetHit(Float_t, Float_t);
+ //
+ // Iterate over pads
+ virtual void SetPadCoord(Int_t iX, Int_t iY);
+ 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 // implementation Neighbours function
+ (Int_t iX, Int_t iY, Int_t* Nlist, Int_t *Xlist, Int_t *Ylist);
+ virtual void NeighboursDiag // with diagonal elements
+ (Int_t iX, Int_t iY, Int_t* Nlist, Int_t *Xlist, Int_t *Ylist);
+ virtual void NeighboursNonDiag // without diagonal elements
+ (Int_t iX, Int_t iY, Int_t* Nlist, Int_t *Xlist, Int_t *Ylist);
+ void CleanNeighbours(Int_t* Nlist, Int_t *Xlist, Int_t *Ylist);
+ // Provisory RecCluster coordinates reconstructor
+ virtual void FitXY(AliMUONRecCluster* Cluster,TClonesArray* MUONdigits);
+ //
+ // Channel number expressed in pad coordinates (stored in Cluster)
+ virtual Int_t Ix(Int_t trueX, Int_t trueY);
+ virtual Int_t Ix();
+ virtual Int_t Iy(){return fiy;}
+ // Actual number of pad in the chain
+ virtual Int_t ISector();
+ virtual Int_t Sector(Int_t ix, Int_t iy) {return 1;}
+ // Position of pad in perellel read-out
+ virtual Int_t IsParallel2(Int_t iX, Int_t iY);
+ virtual Int_t IsParallel3(Int_t iX, Int_t iY);
+ // Number of pads read in parallel
+ virtual Int_t NParallel2(Int_t iX, Int_t iY);
+ virtual Int_t NParallel3(Int_t iX, Int_t iY);
+ //
+ // Number of pads read in parallel and offset to add to x
+ virtual void GetNParallelAndOffset(Int_t iX, Int_t iY,
+ Int_t *Nparallel, Int_t *Offset);
+ // Minimum 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 *Offset);
+ //
+ // Signal Generation Condition during Stepping
+ Int_t SigGenCond(Float_t x, Float_t y, Float_t z);
+ void SigGenInit(Float_t x, Float_t y, Float_t z);
+ void GiveTestPoints(Int_t &n, Float_t *x, Float_t *y);
+ virtual void IntegrationLimits
+ (Float_t& x1, Float_t& x2, Float_t& y1, Float_t& y2);
+ //
+ virtual void Draw(){;}
+ // Function for systematic corrections
+ virtual void SetCorrFunc(Int_t dum, TF1* func) {fCorr=func;}
+ virtual TF1* CorrFunc(Int_t) {return fCorr;}
+
+ //
+ // Identification
+ virtual char* YourName() {return fName;}
+
+ ClassDef(AliMUONsegmentationV1,1)
+ protected:
+ //
+ // Implementation of the segmentation data
+ // Version This models rectangular pads with the same dimensions all
+ // over the cathode plane but let the possibilit for different design
+ //
+ // geometry
+ Int_t fNzone; // Number of differents sensitive zones
+ Float_t fDpx; // X pad width
+ Float_t fDpy; // Y pad width
+ Int_t fNZoneCut[NZONEm1]; // Number of cuts for given zone
+ Int_t fZoneX[NZONEm1][NZONECUT]; // X descriptor of zone segmentations
+ Int_t fZoneY[NZONEm1][NZONECUT]; // Y descriptor of zone segmentations
+ Float_t frSensMax2; // square of maximum sensitive radius
+ Float_t frSensMin2; // square of minimum sensitive radius
+ Int_t fNpx; // Maximum number of pads along x
+ Int_t fNpy; // Maximum number of pads along y
+ Float_t fDAnod; // Anod gap
+ Float_t fSensOffset; // Offset of sensitive zone with respect to quadrant (positive)
+
+ // 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;
+ Float_t fxhit;
+ Float_t fyhit;
+
+ TF1* fCorr;
+
+ //
+ // Version Identifier
+ char *fName;
+
+
+
+};
+
+#endif
+
+
--- /dev/null
+#include <AliMUONTUBE.h>
+#include <TTUBE.h>
+#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;
+}
+
--- /dev/null
+#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
--- /dev/null
+#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;
+}
--- /dev/null
+#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
#include <TView.h>
#include <TText.h>
#include <TPolyMarker3D.h>
-#include <TPolyMarker.h>
#include <TPaveLabel.h>
#include <TPaveText.h>
#include <TList.h>
#include <TGaxis.h>
#include <TGXW.h>
#include <TMath.h>
+#include <TMatrix.h>
#include <X3DBuffer.h>
#include "AliRun.h"
#include "TParticle.h"
+
ClassImp(AliMUONdisplay)
{
fPoints = 0;
fPhits = 0;
+ fRpoints = 0;
+ fR2points = 0;
+ fCpoints = 0;
fCanvas = 0;
}
// If you are lost, you can click on HELP in any Root canvas or browser.
//Begin_Html
/*
-<img src="picts/aliMUONdisplay.gif">
+<img src="gif/aliMUONdisplay.gif">
*/
//End_Html
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
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;
}
//_____________________________________________________________________________
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;
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);
}
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);
}
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);
}
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);
}
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);
}
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];
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);
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();
for (