From a9e2aefa97f1153d6f61e580a32d396156706b7b Mon Sep 17 00:00:00 2001 From: morsch Date: Thu, 15 Jun 2000 07:58:49 +0000 Subject: [PATCH] Code from MUON-dev joined --- MUON/AliMUON.cxx | 3246 +++++------------ MUON/AliMUON.h | 362 +- MUON/AliMUONChamber.cxx | 163 + MUON/AliMUONChamber.h | 128 + MUON/AliMUONChamberTrigger.cxx | 126 + MUON/AliMUONChamberTrigger.h | 40 + MUON/AliMUONClusterFinder.cxx | 1197 +++--- MUON/AliMUONClusterFinder.h | 119 +- MUON/AliMUONClusterFinderV0.cxx | 758 ++++ MUON/AliMUONClusterFinderV0.h | 42 + MUON/AliMUONClusterFinderVS.cxx | 1992 ++++++++++ MUON/AliMUONClusterFinderVS.h | 125 + MUON/AliMUONClusterFinderv0.h | 1 + MUON/AliMUONConst.h | 4 +- MUON/AliMUONDigit.cxx | 59 + MUON/AliMUONDigit.h | 26 + MUON/AliMUONDisplay.cxx | 1354 +++++++ MUON/{AliMUONdisplay.h => AliMUONDisplay.h} | 119 +- MUON/AliMUONEventReconstructor.cxx | 1112 ++++++ MUON/AliMUONEventReconstructor.h | 134 + MUON/AliMUONGlobalTrigger.cxx | 73 + MUON/AliMUONGlobalTrigger.h | 43 + MUON/AliMUONHit.cxx | 57 + MUON/AliMUONHit.h | 34 + MUON/AliMUONHitForRec.cxx | 237 ++ MUON/AliMUONHitForRec.h | 91 + MUON/AliMUONHitMap.cxx | 101 +- MUON/AliMUONHitMap.h | 62 +- MUON/AliMUONHitMapA1.cxx | 155 + MUON/AliMUONHitMapA1.h | 57 + MUON/AliMUONLocalTrigger.cxx | 46 + MUON/AliMUONLocalTrigger.h | 35 + MUON/AliMUONPadHit.cxx | 38 + MUON/AliMUONPadHit.h | 31 + MUON/AliMUONPoints.cxx | 259 ++ MUON/{AliMUONpoints.h => AliMUONPoints.h} | 49 +- MUON/AliMUONRawCluster.cxx | 164 + MUON/AliMUONRawCluster.h | 49 + MUON/AliMUONReconstHit.cxx | 35 + MUON/AliMUONReconstHit.h | 31 + MUON/AliMUONResponse.cxx | 26 + MUON/AliMUONResponse.h | 66 + MUON/AliMUONResponseTrigger.cxx | 96 + MUON/AliMUONResponseTrigger.h | 34 + MUON/AliMUONResponseV0.cxx | 89 + MUON/AliMUONResponseV0.h | 94 + MUON/AliMUONSegResV01.cxx | 183 +- MUON/AliMUONSegResV01.h | 54 +- MUON/AliMUONSegResV04.h | 34 - MUON/AliMUONSegResV05.h | 33 - MUON/AliMUONSegResV1.cxx | 509 --- MUON/AliMUONSegment.cxx | 292 ++ MUON/AliMUONSegment.h | 68 + MUON/AliMUONSegmentation.cxx | 26 + ...{AliMUONSegRes.h => AliMUONSegmentation.h} | 74 +- MUON/AliMUONSegmentationTrigger.cxx | 330 ++ MUON/AliMUONSegmentationTrigger.h | 78 + MUON/AliMUONSegmentationTriggerX.cxx | 251 ++ MUON/AliMUONSegmentationTriggerX.h | 73 + MUON/AliMUONSegmentationTriggerY.cxx | 253 ++ MUON/AliMUONSegmentationTriggerY.h | 74 + MUON/AliMUONSegmentationV0.cxx | 279 ++ ...MUONSegResV0.h => AliMUONSegmentationV0.h} | 138 +- MUON/AliMUONSegmentationV01.cxx | 504 +++ MUON/AliMUONSegmentationV01.h | 124 + ...gResV02.cxx => AliMUONSegmentationV02.cxx} | 82 +- ...ONSegResV02.h => AliMUONSegmentationV02.h} | 27 +- ...gResV04.cxx => AliMUONSegmentationV04.cxx} | 57 +- MUON/AliMUONSegmentationV04.h | 33 + ...gResV05.cxx => AliMUONSegmentationV05.cxx} | 49 +- MUON/AliMUONSegmentationV05.h | 31 + MUON/AliMUONSegmentationV1.cxx | 545 +++ MUON/AliMUONSegmentationV1.h | 179 + MUON/AliMUONTUBE.cxx | 160 - MUON/AliMUONTUBE.h | 24 - MUON/AliMUONTrack.cxx | 311 ++ MUON/AliMUONTrack.h | 54 + MUON/AliMUONTrackHit.cxx | 93 + MUON/AliMUONTrackHit.h | 45 + MUON/AliMUONTrackParam.cxx | 231 ++ MUON/AliMUONTrackParam.h | 54 + MUON/AliMUONTrackReconstructor.cxx | 1150 ++++++ MUON/AliMUONTrackReconstructor.h | 40 + MUON/AliMUONTransientDigit.cxx | 57 + MUON/AliMUONTransientDigit.h | 28 + MUON/AliMUONTriggerCircuit.cxx | 539 +++ MUON/AliMUONTriggerCircuit.h | 81 + MUON/AliMUONTriggerDecision.cxx | 1358 +++++++ MUON/AliMUONTriggerDecision.h | 110 + MUON/AliMUONTriggerLut.cxx | 260 ++ MUON/AliMUONTriggerLut.h | 48 + MUON/AliMUONchamber.cxx | 100 - MUON/AliMUONchamber.h | 133 - MUON/AliMUONdisplay.cxx | 1252 ------- MUON/AliMUONpoints.cxx | 451 --- MUON/AliMUONproto.cxx | 594 +++ MUON/AliMUONproto.h | 36 + MUON/AliMUONv0.cxx | 1961 +++------- MUON/AliMUONv0.h | 7 +- MUON/AliMUONv1.cxx | 1657 +++++++++ MUON/AliMUONv1.h | 34 + MUON/Config.C | 784 ++++ MUON/MUONConfig.C | 412 +++ MUON/MUONLinkDef.h | 65 +- MUON/MUONRawDigit.C | 125 + MUON/MUONTestTrigger.C | 110 + MUON/MUONTriggerLut.C | 34 + MUON/MUONTriggerLut.root | Bin 0 -> 47713 bytes MUON/MUONcombi.C | 93 +- MUON/MUONdigit.C | 77 +- MUON/MUONdigits.C | 266 -- MUON/MUONdisplay.C | 2 +- MUON/MUONdoubles.C | 298 ++ MUON/MUONhitrectest.C | 186 + MUON/MUONhits.C | 226 ++ MUON/MUONlist2digits.C | 333 -- MUON/MUONmultest.C | 194 + MUON/MUONocc.C | 297 ++ MUON/MUONrawclusters.C | 129 +- MUON/{MUONcathcorel.C => MUONrechits.C} | 4 +- MUON/MUONstraggling.C | 190 + MUON/MUONtestabso.C | 244 +- MUON/MUONtestrawclust.C | 171 + MUON/MUONtestzaza.C | 87 - MUON/MUONtracking.C | 131 + MUON/MUONtrigger.C | 53 + MUON/Makefile | 33 +- MUON/abso_dedx.C | 54 + MUON/algo.F | 2153 ----------- MUON/dedx.C | 36 + MUON/masse.C | 195 + MUON/reco_muon.F | 1951 +++++++--- 132 files changed, 25608 insertions(+), 11732 deletions(-) create mode 100644 MUON/AliMUONChamber.cxx create mode 100644 MUON/AliMUONChamber.h create mode 100644 MUON/AliMUONChamberTrigger.cxx create mode 100644 MUON/AliMUONChamberTrigger.h create mode 100644 MUON/AliMUONClusterFinderV0.cxx create mode 100644 MUON/AliMUONClusterFinderV0.h create mode 100644 MUON/AliMUONClusterFinderVS.cxx create mode 100644 MUON/AliMUONClusterFinderVS.h create mode 100644 MUON/AliMUONDigit.cxx create mode 100644 MUON/AliMUONDigit.h create mode 100644 MUON/AliMUONDisplay.cxx rename MUON/{AliMUONdisplay.h => AliMUONDisplay.h} (78%) create mode 100644 MUON/AliMUONEventReconstructor.cxx create mode 100644 MUON/AliMUONEventReconstructor.h create mode 100644 MUON/AliMUONGlobalTrigger.cxx create mode 100644 MUON/AliMUONGlobalTrigger.h create mode 100644 MUON/AliMUONHit.cxx create mode 100644 MUON/AliMUONHit.h create mode 100644 MUON/AliMUONHitForRec.cxx create mode 100644 MUON/AliMUONHitForRec.h create mode 100644 MUON/AliMUONHitMapA1.cxx create mode 100644 MUON/AliMUONHitMapA1.h create mode 100644 MUON/AliMUONLocalTrigger.cxx create mode 100644 MUON/AliMUONLocalTrigger.h create mode 100644 MUON/AliMUONPadHit.cxx create mode 100644 MUON/AliMUONPadHit.h create mode 100644 MUON/AliMUONPoints.cxx rename MUON/{AliMUONpoints.h => AliMUONPoints.h} (67%) create mode 100644 MUON/AliMUONRawCluster.cxx create mode 100644 MUON/AliMUONRawCluster.h create mode 100644 MUON/AliMUONReconstHit.cxx create mode 100644 MUON/AliMUONReconstHit.h create mode 100644 MUON/AliMUONResponse.cxx create mode 100644 MUON/AliMUONResponse.h create mode 100644 MUON/AliMUONResponseTrigger.cxx create mode 100644 MUON/AliMUONResponseTrigger.h create mode 100644 MUON/AliMUONResponseV0.cxx create mode 100644 MUON/AliMUONResponseV0.h delete mode 100644 MUON/AliMUONSegResV04.h delete mode 100644 MUON/AliMUONSegResV05.h delete mode 100644 MUON/AliMUONSegResV1.cxx create mode 100644 MUON/AliMUONSegment.cxx create mode 100644 MUON/AliMUONSegment.h create mode 100644 MUON/AliMUONSegmentation.cxx rename MUON/{AliMUONSegRes.h => AliMUONSegmentation.h} (62%) create mode 100644 MUON/AliMUONSegmentationTrigger.cxx create mode 100644 MUON/AliMUONSegmentationTrigger.h create mode 100644 MUON/AliMUONSegmentationTriggerX.cxx create mode 100644 MUON/AliMUONSegmentationTriggerX.h create mode 100644 MUON/AliMUONSegmentationTriggerY.cxx create mode 100644 MUON/AliMUONSegmentationTriggerY.h create mode 100644 MUON/AliMUONSegmentationV0.cxx rename MUON/{AliMUONSegResV0.h => AliMUONSegmentationV0.h} (51%) create mode 100644 MUON/AliMUONSegmentationV01.cxx create mode 100644 MUON/AliMUONSegmentationV01.h rename MUON/{AliMUONSegResV02.cxx => AliMUONSegmentationV02.cxx} (60%) rename MUON/{AliMUONSegResV02.h => AliMUONSegmentationV02.h} (75%) rename MUON/{AliMUONSegResV04.cxx => AliMUONSegmentationV04.cxx} (77%) create mode 100644 MUON/AliMUONSegmentationV04.h rename MUON/{AliMUONSegResV05.cxx => AliMUONSegmentationV05.cxx} (78%) create mode 100644 MUON/AliMUONSegmentationV05.h create mode 100644 MUON/AliMUONSegmentationV1.cxx create mode 100644 MUON/AliMUONSegmentationV1.h delete mode 100644 MUON/AliMUONTUBE.cxx delete mode 100644 MUON/AliMUONTUBE.h create mode 100644 MUON/AliMUONTrack.cxx create mode 100644 MUON/AliMUONTrack.h create mode 100644 MUON/AliMUONTrackHit.cxx create mode 100644 MUON/AliMUONTrackHit.h create mode 100644 MUON/AliMUONTrackParam.cxx create mode 100644 MUON/AliMUONTrackParam.h create mode 100644 MUON/AliMUONTrackReconstructor.cxx create mode 100644 MUON/AliMUONTrackReconstructor.h create mode 100644 MUON/AliMUONTransientDigit.cxx create mode 100644 MUON/AliMUONTransientDigit.h create mode 100644 MUON/AliMUONTriggerCircuit.cxx create mode 100644 MUON/AliMUONTriggerCircuit.h create mode 100644 MUON/AliMUONTriggerDecision.cxx create mode 100644 MUON/AliMUONTriggerDecision.h create mode 100644 MUON/AliMUONTriggerLut.cxx create mode 100644 MUON/AliMUONTriggerLut.h delete mode 100644 MUON/AliMUONchamber.cxx delete mode 100644 MUON/AliMUONchamber.h delete mode 100644 MUON/AliMUONdisplay.cxx delete mode 100644 MUON/AliMUONpoints.cxx create mode 100644 MUON/AliMUONproto.cxx create mode 100644 MUON/AliMUONproto.h create mode 100644 MUON/AliMUONv1.cxx create mode 100644 MUON/AliMUONv1.h create mode 100644 MUON/Config.C create mode 100644 MUON/MUONConfig.C create mode 100644 MUON/MUONRawDigit.C create mode 100644 MUON/MUONTestTrigger.C create mode 100644 MUON/MUONTriggerLut.C create mode 100644 MUON/MUONTriggerLut.root delete mode 100644 MUON/MUONdigits.C create mode 100644 MUON/MUONdoubles.C create mode 100644 MUON/MUONhitrectest.C create mode 100644 MUON/MUONhits.C delete mode 100644 MUON/MUONlist2digits.C create mode 100644 MUON/MUONmultest.C create mode 100644 MUON/MUONocc.C rename MUON/{MUONcathcorel.C => MUONrechits.C} (93%) create mode 100644 MUON/MUONstraggling.C create mode 100644 MUON/MUONtestrawclust.C delete mode 100644 MUON/MUONtestzaza.C create mode 100644 MUON/MUONtracking.C create mode 100644 MUON/MUONtrigger.C create mode 100644 MUON/abso_dedx.C delete mode 100644 MUON/algo.F create mode 100644 MUON/dedx.C create mode 100644 MUON/masse.C diff --git a/MUON/AliMUON.cxx b/MUON/AliMUON.cxx index c8c511995e5..23ea3a43851 100644 --- a/MUON/AliMUON.cxx +++ b/MUON/AliMUON.cxx @@ -12,41 +12,70 @@ * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ - /* $Log$ -Revision 1.16 2000/04/26 10:17:31 fca -Changes in Lego for G4 compatibility +Revision 1.14.4.17 2000/06/14 14:36:46 morsch +- add TriggerCircuit (PC) +- add GlobalTrigger and LocalTrigger and specific methods (PC) + +Revision 1.14.4.16 2000/06/09 21:20:28 morsch +Most coding rule violations corrected + +Revision 1.14.4.15 2000/05/02 09:54:32 morsch +RULE RN17 violations corrected + +Revision 1.14.4.12 2000/04/26 12:25:02 morsch +Code revised by P. Crochet: +- Z position of TriggerChamber changed according to A.Tournaire Priv.Comm. +- ToF included in the method MakePadHits +- inner radius of flange between beam shielding and trigger corrected +- Trigger global volume updated (according to the new geometry) + +Revision 1.14.4.11 2000/04/19 19:42:08 morsch +Some changes of variable names curing viols and methods concerning +correlated clusters removed. + +Revision 1.14.4.10 2000/03/22 16:44:07 gosset +Memory leak suppressed in function Digitise: +p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri) + +Revision 1.14.4.9 2000/03/20 18:15:25 morsch +Positions of trigger chambers corrected (P.C.) -Revision 1.15 2000/01/19 17:16:56 fca -Introducing a list of lists of hits -- more hits allowed for detector now +Revision 1.14.4.8 2000/02/21 15:38:01 morsch +Call to AddHitList introduced to make this version compatible with head. -Revision 1.14 1999/11/03 13:17:07 fca -Have ProdProcess return const char* +Revision 1.14.4.7 2000/02/20 07:45:53 morsch +Bugs in Trigger part of BuildGeomemetry corrected (P.C) -Revision 1.13 1999/10/26 06:04:48 fca -Introduce TLorentzVector in AliMC::GetSecondary. Thanks to I.Hrivnacova +Revision 1.14.4.6 2000/02/17 14:28:54 morsch +Trigger included into initialization and digitization -Revision 1.12 1999/10/07 21:08:10 fca -Corrections by G.Chabratova +Revision 1.14.4.5 2000/02/15 10:02:58 morsch +Log messages of previous revisions added -Revision 1.11 1999/10/05 17:15:45 fca -Minor syntax for the Alpha OSF +Revision 1.14.4.2 2000/02/04 10:57:34 gosset +Z position of the chambers: +it was the Z position of the stations; +it is now really the Z position of the chambers. + !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS" + !!!! AND "AliMUONChamber::ZPosition" + !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ" + !!!! AND "AliMUONChamber::Z" -Revision 1.10 1999/10/01 09:24:40 fca -Protect against no current file in FinishEvent +Revision 1.14.4.3 2000/02/04 16:19:04 gosset +Correction for mis-spelling of NCH -Revision 1.9 1999/09/29 09:24:20 fca -Introduction of the Copyright and cvs Log +Revision 1.14.4.4 2000/02/15 09:43:38 morsch +Log message added */ -//////////////////////////////////////////////// + +/////////////////////////////////////////////// // Manager and hits classes for set:MUON // //////////////////////////////////////////////// -#include -#include #include #include #include @@ -66,127 +95,62 @@ Introduction of the Copyright and cvs Log #include #include #include +#include #include "AliMUON.h" -#include "TTUBE.h" +#include "AliMUONHit.h" +#include "AliMUONPadHit.h" +#include "AliMUONDigit.h" +#include "AliMUONTransientDigit.h" +#include "AliMUONRawCluster.h" +#include "AliMUONLocalTrigger.h" +#include "AliMUONGlobalTrigger.h" +#include "AliMUONHitMap.h" +#include "AliMUONHitMapA1.h" +#include "AliMUONChamberTrigger.h" + #include "AliMUONClusterFinder.h" +#include "AliMUONTriggerDecision.h" #include "AliRun.h" #include "AliMC.h" #include "iostream.h" #include "AliCallf77.h" +#include "AliConst.h" + +// Defaults parameters for Z positions of chambers +// taken from values for "stations" in AliMUON::AliMUON +// const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.}; +// and from array "dstation" in AliMUONv1::CreateGeometry +// Float_t dstation[5]={20., 20., 20, 20., 20.}; +// for tracking chambers, +// according to (Z1 = zch - dstation) and (Z2 = zch + dstation) +// for the first and second chambers in the station, respectively, +// and from "DTPLANES" in AliMUONv1::CreateGeometry +// const Float_t DTPLANES = 15.; +// for trigger chambers, +// according to (Z1 = zch) and (Z2 = zch + DTPLANES) +// for the first and second chambers in the station, respectively +static const Float_t kDefaultChambersZ[kNCH] = +{518., 538., 680., 700., 965., 985., 1239., 1259., 1439., 1459., + 1603.5, 1618.5, 1703.5, 1718.5}; -#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();} -} - -void fcnfwrap(Int_t &i1, Double_t *d1, Double_t &d2, - Double_t *d3, Int_t i2) -{ - fcnf(i1,d1,d2,d3,i2); -} - -void fcnfitfwrap(Int_t &i1, Double_t *d1, Double_t &d2, - Double_t *d3, Int_t i2) -{ - fcnfitf(i1,d1,d2,d3,i2); -} - - -// Static variables for the pad-hit iterator routines -static Int_t sMaxIterPad=0; -static Int_t sCurIterPad=0; -static TTree *TrH1; -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() { - fIshunt = 0; - fHits = 0; - fClusters = 0; - fNclusters = 0; - fDchambers = 0; - fNdch = 0; - fRawClusters= 0; - fNrawch = 0; - fCathCorrel= 0; - fNcorch = 0; - fTreeC = 0; - - // modifs perso - fSPxzCut = 0; - fSSigmaCut = 0; - fSXPrec = 0; - fSYPrec = 0; + fIshunt = 0; + fHits = 0; + fPadHits = 0; + fNPadHits = 0; + fDchambers = 0; + fTriggerCircuits = 0; // cp new design of AliMUONTriggerDecision + fNdch = 0; + fRawClusters = 0; + fNrawch = 0; + fGlobalTrigger = 0; + fNLocalTrigger = 0; + fLocalTrigger = 0; + fNLocalTrigger = 0; } //___________________________________________ @@ -199,40 +163,37 @@ AliMUON::AliMUON(const char *name, const char *title) */ //End_Html - fHits = new TClonesArray("AliMUONhit",1000); + fHits = new TClonesArray("AliMUONHit",1000); gAlice->AddHitList(fHits); - fClusters = new TClonesArray("AliMUONcluster",10000); - fNclusters = 0; + fPadHits = new TClonesArray("AliMUONPadHit",10000); + fNPadHits = 0; fIshunt = 0; - fNdch = new Int_t[10]; + fNdch = new Int_t[kNCH]; - fDchambers = new TObjArray(10); + fDchambers = new TObjArray(kNCH); Int_t i; - for (i=0; i<10 ;i++) { - (*fDchambers)[i] = new TClonesArray("AliMUONdigit",10000); + for (i=0; iSetGid(0); + // Default values for Z of chambers + chamber->SetZ(kDefaultChambersZ[ch]); +// + chamber->InitGeo(kDefaultChambersZ[ch]); + chamber->SetRInner(kDmin[st]/2); + chamber->SetROuter(kDmax[st]/2); +// + } // Chamber stCH (0, 1) in + } // Station st (0...) + fMaxStepGas=0.01; + fMaxStepAlu=0.1; + fMaxDestepGas=-1; + fMaxDestepAlu=-1; +// + fMaxIterPad = 0; + fCurIterPad = 0; + + // cp new design of AliMUONTriggerDecision + fTriggerCircuits = new TObjArray(kNTriggerCircuit); + for (Int_t circ=0; circGetGeometry()->GetNode("alice"); + 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.}; + const Float_t kCz[7]={511., 686., 971., 1245., 1445., 1600, 1700.}; +// inner diameter (Xlenght for trigger chamber -> active area) + const Float_t kDmin[7]={ 35., 47., 67., 86., 100., 544., 544.}; +// outer diameter (Ylenght for trigger chamber -> active area) + const Float_t kDmax[7]={183., 245., 346., 520., 520., 612., 612.}; 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[8]; - for (Int_t i=0; i<5; i++) { + Float_t rmin, rmax, dx, dy, dz, dr, xpos, ypos, zpos; + Float_t dzc1=4.; // tracking chambers + Float_t dzc2=15.; // trigger chambers + Float_t hole=102.; // x-y hole around beam pipe for trig. chambers + Float_t zscale; // scaling parameter trigger chambers + Float_t halfx, halfy; + char nameChamber[9], nameSense[9], nameFrame[9], nameNode[8]; + char nameSense1[9], nameSense2[9]; + for (Int_t i=0; i<7; i++) { for (Int_t j=0; j<2; j++) { Int_t id=2*i+j+1; - if (j==0) { - zpos=cz[i]-dzc; + if (i<5) { // tracking chambers + if (j==0) { + zpos=kCz[i]-dzc1; + } else { + zpos=kCz[i]+dzc1; + } } else { - zpos=cz[i]+dzc; + if (j==0) { + zpos=kCz[i]; + } else { + zpos=kCz[i]+dzc2; + } } - - - 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); - fNodes->Add(Node); - Node->cd(); - dr=dx+rmin; - sprintf(NameNode,"MUON%d",300+id); - NodeF = new TNode(NameNode,"Frame0",FMUON,dr, 0, 0,rot000,""); - NodeF->SetLineColor(kColorMUON); - fNodes->Add(NodeF); - Node->cd(); - sprintf(NameNode,"MUON%d",400+id); - NodeF = new TNode(NameNode,"Frame1",FMUON,0 ,dr,0,rot090,""); - NodeF->SetLineColor(kColorMUON); - fNodes->Add(NodeF); - Node->cd(); - sprintf(NameNode,"MUON%d",500+id); - NodeF = new TNode(NameNode,"Frame2",FMUON,-dr,0,0,rot180,""); - NodeF->SetLineColor(kColorMUON); - fNodes->Add(NodeF); - Node ->cd(); - sprintf(NameNode,"MUON%d",600+id); - NodeF = new TNode(NameNode,"Frame3",FMUON,0,-dr,0,rot270,""); - NodeF->SetLineColor(kColorMUON); - fNodes->Add(NodeF); + sprintf(nameChamber,"C_MUON%d",id); + sprintf(nameSense,"S_MUON%d",id); + sprintf(nameSense1,"S1_MUON%d",id); + sprintf(nameSense2,"S2_MUON%d",id); + sprintf(nameFrame,"F_MUON%d",id); + if (i<5) { // tracking chambers + rmin = kDmin[i]/2.-3; + rmax = kDmax[i]/2.+3; + new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.); + rmin = kDmin[i]/2.; + rmax = kDmax[i]/2.; + new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.); + dx=(rmax-rmin)/2; + dy=3.; + dz=0.25; + TBRIK* frMUON = 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",frMUON,dr, 0, 0,rot000,""); + nodeF->SetLineColor(kColorMUON); + node->cd(); + sprintf(nameNode,"MUON%d",400+id); + nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,""); + nodeF->SetLineColor(kColorMUON); + node->cd(); + sprintf(nameNode,"MUON%d",500+id); + nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,""); + nodeF->SetLineColor(kColorMUON); + node ->cd(); + sprintf(nameNode,"MUON%d",600+id); + nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,""); + nodeF->SetLineColor(kColorMUON); + } else { + zscale=zpos/kCz[5]; + Float_t xsize=kDmin[i]*zscale; + Float_t ysize=kDmax[i]*zscale; + Float_t holeScaled=hole*zscale; + + halfx=xsize/2.+3.; + halfy=ysize/2.+3.; + new TBRIK(nameChamber,"Mother","void",halfx,halfy,0.25); + top->cd(); + sprintf(nameNode,"MUON%d",100+id); + node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,""); + node->SetLineColor(kColorMUON2); + fNodes->Add(node); + +// up/down of beam pipe + halfx=xsize/2.; + halfy=(ysize/2.-holeScaled/2.)/2.; + new TBRIK(nameSense,"Sens. region","void",halfx,halfy,0.25); + + node->cd(); + ypos=holeScaled/2.+((ysize/2.-holeScaled/2.)/2.); + sprintf(nameNode,"MUON%d",200+id); + nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,""); + nodeS->SetLineColor(kColorMUON2); + + node->cd(); + ypos=-1.*ypos; + sprintf(nameNode,"MUON%d",300+id); + nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,""); + nodeS->SetLineColor(kColorMUON2); + +// left/right of beam pipe + halfx=(xsize/2.-holeScaled/2.)/2.; + halfy=holeScaled/2.; + new TBRIK(nameSense1,"Sens. region","void",halfx,halfy,0.25); + + node->cd(); + xpos=holeScaled/2.+((xsize/2.-holeScaled/2.)/2.); + sprintf(nameNode,"MUON%d",400+id); + nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,""); + nodeS->SetLineColor(kColorMUON2); + + node->cd(); + xpos=-1.*xpos; + sprintf(nameNode,"MUON%d",500+id); + nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,""); + nodeS->SetLineColor(kColorMUON2); + +// missing corners + halfx=17.*zscale/2.; + halfy=halfx; + new TBRIK(nameSense2,"Sens. region","void",halfx,halfy,0.25); + + node->cd(); + xpos=holeScaled/2.-halfx; + ypos=xpos; + sprintf(nameNode,"MUON%d",600+id); + nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,""); + nodeS->SetLineColor(kColorMUON2); + + node->cd(); + ypos=-1.*xpos; + sprintf(nameNode,"MUON%d",700+id); + nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,""); + nodeS->SetLineColor(kColorMUON2); + + node->cd(); + xpos=-1.*xpos; + sprintf(nameNode,"MUON%d",800+id); + nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,""); + nodeS->SetLineColor(kColorMUON2); + + node->cd(); + ypos=-1.*xpos; + sprintf(nameNode,"MUON%d",900+id); + nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,""); + nodeS->SetLineColor(kColorMUON2); + } } } } @@ -421,41 +540,54 @@ void AliMUON::MakeBranch(Option_t* option) { // Create Tree branches for the MUON. - const Int_t buffersize = 4000; + const Int_t kBufferSize = 4000; char branchname[30]; sprintf(branchname,"%sCluster",GetName()); AliDetector::MakeBranch(option); - if (fClusters && gAlice->TreeH()) { - gAlice->TreeH()->Branch(branchname,&fClusters, buffersize); + if (fPadHits && gAlice->TreeH()) { + gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize); printf("Making Branch %s for clusters\n",branchname); } // one branch for digits per chamber Int_t i; - for (i=0; i<10 ;i++) { + for (i=0; iTreeD()) { - gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), buffersize); + gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize); printf("Making Branch %s for digits in chamber %d\n",branchname,i+1); } } - //printf("Make Branch - TreeR address %p\n",gAlice->TreeR()); + printf("Make Branch - TreeR address %p\n",gAlice->TreeR()); // one branch for raw clusters per chamber - for (i=0; i<10 ;i++) { + for (i=0; iTreeR()) { - gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), buffersize); + gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize); printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1); } } +// one branch for global trigger + sprintf(branchname,"%sGlobalTrigger",GetName()); + if (fGlobalTrigger && gAlice->TreeR()) { + gAlice->TreeR()->Branch(branchname,&fGlobalTrigger,kBufferSize); + printf("Making Branch %s for Global Trigger\n",branchname); + } +// one branch for local trigger + sprintf(branchname,"%sLocalTrigger",GetName()); + if (fLocalTrigger && gAlice->TreeR()) { + gAlice->TreeR()->Branch(branchname,&fLocalTrigger,kBufferSize); + printf("Making Branch %s for Local Trigger\n",branchname); + } + } //___________________________________________ @@ -471,14 +603,14 @@ void AliMUON::SetTreeAddress() TTree *treeR = gAlice->TreeR(); if (treeH) { - if (fClusters) { + if (fPadHits) { branch = treeH->GetBranch("MUONCluster"); - if (branch) branch->SetAddress(&fClusters); + if (branch) branch->SetAddress(&fPadHits); } } if (treeD) { - for (int i=0; i<10; i++) { + for (int i=0; iGetBranch(branchname); @@ -490,23 +622,31 @@ void AliMUON::SetTreeAddress() // printf("SetTreeAddress --- treeR address %p \n",treeR); if (treeR) { - for (int i=0; i<10; i++) { + for (int i=0; iGetBranch(branchname); if (branch) branch->SetAddress(&((*fRawClusters)[i])); } } - } + if (fLocalTrigger) { + branch = treeR->GetBranch("MUONLocalTrigger"); + if (branch) branch->SetAddress(&fLocalTrigger); + } + if (fGlobalTrigger) { + branch = treeR->GetBranch("MUONGlobalTrigger"); + if (branch) branch->SetAddress(&fGlobalTrigger); + } + } } //___________________________________________ void AliMUON::ResetHits() { // Reset number of clusters and the cluster array for this detector AliDetector::ResetHits(); - fNclusters = 0; - if (fClusters) fClusters->Clear(); + fNPadHits = 0; + if (fPadHits) fPadHits->Clear(); } //____________________________________________ @@ -515,7 +655,7 @@ void AliMUON::ResetDigits() // // Reset number of digits and the digits array for this detector // - for ( int i=0;i<10;i++ ) { + for ( int i=0;iClear(); if (fNdch) fNdch[i]=0; } @@ -526,63 +666,79 @@ void AliMUON::ResetRawClusters() // // Reset number of raw clusters and the raw clust array for this detector // - for ( int i=0;i<10;i++ ) { + for ( int i=0;iClear(); if (fNrawch) fNrawch[i]=0; } } + //____________________________________________ -void AliMUON::ResetCorrelation() +void AliMUON::ResetTrigger() { - // - // 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; - } + // Reset Local and Global Trigger + fNGlobalTrigger = 0; + if (fGlobalTrigger) fGlobalTrigger->Clear(); + fNLocalTrigger = 0; + if (fLocalTrigger) fLocalTrigger->Clear(); +} + +//____________________________________________ +void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2) +{ + Int_t i=2*(id-1); + ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2); + ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2); } //___________________________________________ +void AliMUON::SetChambersZ(const Float_t *Z) +{ + // Set Z values for all chambers (tracking and trigger) + // from the array pointed to by "Z" + for (Int_t ch = 0; ch < kNCH; ch++) + ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]); + return; +} -void AliMUON::SetPADSIZ(Int_t id, Int_t isec, Float_t p1, Float_t p2) +//___________________________________________ +void AliMUON::SetChambersZToDefault() { - Int_t i=2*(id-1); - ((AliMUONchamber*) (*fChambers)[i]) ->SetPADSIZ(isec,p1,p2); - ((AliMUONchamber*) (*fChambers)[i+1])->SetPADSIZ(isec,p1,p2); + // Set Z values for all chambers (tracking and trigger) + // to default values + SetChambersZ(kDefaultChambersZ); + return; } //___________________________________________ void AliMUON::SetChargeSlope(Int_t id, Float_t p1) { Int_t i=2*(id-1); - ((AliMUONchamber*) (*fChambers)[i])->SetChargeSlope(p1); - ((AliMUONchamber*) (*fChambers)[i+1])->SetChargeSlope(p1); + ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1); + ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1); } //___________________________________________ void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2) { Int_t i=2*(id-1); - ((AliMUONchamber*) (*fChambers)[i])->SetChargeSpread(p1,p2); - ((AliMUONchamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2); + ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2); + ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2); } //___________________________________________ void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1) { Int_t i=2*(id-1); - ((AliMUONchamber*) (*fChambers)[i])->SetSigmaIntegration(p1); - ((AliMUONchamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1); + ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1); + ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(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); } //___________________________________________ @@ -616,67 +772,34 @@ void AliMUON::SetMuonAcc(Bool_t acc, Float_t angmin, Float_t angmax) fAccMax=angmax; } //___________________________________________ -void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliMUONsegmentation *segmentation) +void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliMUONSegmentation *segmentation) { - ((AliMUONchamber*) (*fChambers)[id])->SegmentationModel(isec, segmentation); + ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation); } //___________________________________________ -void AliMUON::SetResponseModel(Int_t id, AliMUONresponse *response) +void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response) { - ((AliMUONchamber*) (*fChambers)[id])->ResponseModel(response); + ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response); } void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinder *reconst) { - ((AliMUONchamber*) (*fChambers)[id])->ReconstructionModel(reconst); + ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst); } void AliMUON::SetNsec(Int_t id, Int_t nsec) { - ((AliMUONchamber*) (*fChambers)[id])->SetNsec(nsec); + ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec); } //___________________________________________ -void AliMUON::StepManager() -{ - printf("Dummy version of muon step -- it should never happen!!\n"); - /* - const Float_t kRaddeg = 180/TMath::Pi(); - Int_t nsec, ipart; - TLorentzVector x, p; - Float_t pt, th0, th2; - char *proc; - if(fAccCut) { - if((nsec=gMC->NSecondaries())>0) { - proc=gMC->ProdProcess(); - if((gMC->TrackPid()==443 || gMC->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(); - } else { - gMC->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); - pt = TMath::Sqrt(p[0]*p[0]+p[1]*p[1]); - th2 = TMath::ATan2(pt,p[2])*kRaddeg; - if(!(fAccMin < th0 && th0 < fAccMax) || - !(fAccMin < th2 && th2 < fAccMax)) - gMC->StopEvent(); - } - } - } - } - */ -} -void AliMUON::MakePadHits(Float_t xhit,Float_t yhit,Float_t eloss, Int_t idvol) + +void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, + Float_t eloss, Float_t tof, Int_t idvol) { // // Calls the charge disintegration method of the current chamber and adds @@ -694,8 +817,8 @@ void AliMUON::MakePadHits(Float_t xhit,Float_t yhit,Float_t eloss, Int_t idvol) clhits[0]=fNhits+1; // // - ((AliMUONchamber*) (*fChambers)[idvol])->DisIntegration(eloss, xhit, yhit, nnew, newclust); -// printf("\n Add new clusters %d %f \n", nnew, eloss*1.e9); + ((AliMUONChamber*) (*fChambers)[idvol]) + ->DisIntegration(eloss, tof, xhit, yhit, nnew, newclust); Int_t ic=0; // @@ -716,77 +839,76 @@ void AliMUON::MakePadHits(Float_t xhit,Float_t yhit,Float_t eloss, Int_t idvol) // Pad: chamber sector clhits[6] = Int_t(newclust[4][i]); - AddCluster(clhits); + AddPadHit(clhits); } } -// printf("\n %d new clusters added", ic); } -void AliMUON::Digitise(Int_t nev,Int_t bgr_ev,Option_t *option, Option_t *,Text_t *filename) +//---------------------------------------------------------------------- + +void AliMUON::Digitise(Int_t nev,Int_t bgrEvent,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=kTRUE; -// static TTree *TrH1; - static TFile *File; - char *Add = strstr(option,"Add"); - //char *listoftracks = strstr(opt,"listoftracks"); + static TFile *file; + char *addBackground = strstr(option,"Add"); - AliMUONchamber* iChamber; - AliMUONsegmentation* segmentation; + 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); + static TClonesArray *pAddress=0; + if(!pAddress) pAddress=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 ) { + AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON"); + AliMUONHitMap * hitMap[kNCH]; + for (Int_t i=0; icd(); - //File->ls(); + file->cd(); + //file->ls(); // Get Hits Tree header from file if(fHits2) fHits2->Clear(); - if(fClusters2) fClusters2->Clear(); - if(TrH1) delete TrH1; - TrH1=0; + if(fPadHits2) fPadHits2->Clear(); + if(fTrH1) delete fTrH1; + fTrH1=0; char treeName[20]; - sprintf(treeName,"TreeH%d",bgr_ev); - TrH1 = (TTree*)gDirectory->Get(treeName); - //printf("TrH1 %p of treename %s for event %d \n",TrH1,treeName,bgr_ev); + sprintf(treeName,"TreeH%d",bgrEvent); + fTrH1 = (TTree*)gDirectory->Get(treeName); + //printf("fTrH1 %p of treename %s for event %d \n",fTrH1,treeName,bgrEvent); - if (!TrH1) { - printf("ERROR: cannot find Hits Tree for event:%d\n",bgr_ev); + if (!fTrH1) { + printf("ERROR: cannot find Hits Tree for event:%d\n",bgrEvent); } // Set branch addresses TBranch *branch; char branchname[20]; sprintf(branchname,"%s",GetName()); - if (TrH1 && fHits2) { - branch = TrH1->GetBranch(branchname); + if (fTrH1 && fHits2) { + branch = fTrH1->GetBranch(branchname); if (branch) branch->SetAddress(&fHits2); } - if (TrH1 && fClusters2) { - branch = TrH1->GetBranch("MUONCluster"); - if (branch) branch->SetAddress(&fClusters2); + if (fTrH1 && fPadHits2) { + branch = fTrH1->GetBranch("MUONCluster"); + if (branch) branch->SetAddress(&fPadHits2); } // test - //Int_t ntracks1 =(Int_t)TrH1->GetEntries(); + //Int_t ntracks1 =(Int_t)fTrH1->GetEntries(); //printf("background - ntracks1 - %d\n",ntracks1); } // @@ -796,82 +918,78 @@ void AliMUON::Digitise(Int_t nev,Int_t bgr_ev,Option_t *option, Option_t *,Text_ Int_t countadr=0; for (int icat=0; icat<2; icat++) { Int_t counter=0; - for (Int_t i =0; i<10; i++) { - iChamber=(AliMUONchamber*) (*fChambers)[i]; + for (Int_t i =0; iNsec()==1 && icat==1) { continue; } else { - segmentation=iChamber->GetSegmentationModel(icat+1); + segmentation=iChamber->SegmentationModel(icat+1); } - HitMap[i] = new AliMUONHitMapA1(segmentation, list); + 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]; + TTree *treeH = gAlice->TreeH(); + Int_t ntracks =(Int_t) treeH->GetEntries(); + Int_t nmuon[kNCH]={0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + Float_t xhit[kNCH][2]; + Float_t yhit[kNCH][2]; for (Int_t track=0; trackResetHits(); - TH->GetEvent(track); + treeH->GetEvent(track); // // Loop over hits - for(AliMUONhit* mHit=(AliMUONhit*)MUON->FirstHit(-1); + for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1); mHit; - mHit=(AliMUONhit*)MUON->NextHit()) + mHit=(AliMUONHit*)pMUON->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(); + if (nch > kNCH-1) continue; + iChamber = &(pMUON->Chamber(nch)); // 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]); - - } + if (addBackground) { + + 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); + for (AliMUONPadHit* mPad= + (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits); mPad; - mPad=(AliMUONcluster*)MUON->NextPad(fClusters)) + mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits)) { 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 + Int_t iqpad = Int_t(mPad->fQpad);// charge per pad // // if (cathode != (icat+1)) continue; // fill the info array Float_t thex, they; - segmentation=iChamber->GetSegmentationModel(cathode); + segmentation=iChamber->SegmentationModel(cathode); segmentation->GetPadCxy(ipx,ipy,thex,they); - Float_t rpad=TMath::Sqrt(thex*thex+they*they); - if (rpad < rmin || iqpad ==0 || rpad > rmax) continue; +// 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]); + new((*pAddress)[countadr++]) TVector(2); + TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]); trinfo(0)=(Float_t)track; trinfo(1)=(Float_t)iqpad; @@ -879,41 +997,42 @@ void AliMUON::Digitise(Int_t nev,Int_t bgr_ev,Option_t *option, Option_t *,Text_ digits[1]=ipy; digits[2]=iqpad; digits[3]=iqpad; - if (mHit->fParticle == kMuonPlus || mHit->fParticle == kMuonMinus) { - digits[4]=mPad->fHitNumber; + if (mHit->fParticle == kMuonPlus || + mHit->fParticle == kMuonMinus) { + digits[4]=mPad->fHitNumber; } else digits[4]=-1; - AliMUONlist* pdigit; + AliMUONTransientDigit* pdigit; // build the list of fired pads and update the info - if (!HitMap[nch]->TestHit(ipx, ipy)) { + if (!hitMap[nch]->TestHit(ipx, ipy)) { list->AddAtAndExpand( - new AliMUONlist(nch,digits),counter); + new AliMUONTransientDigit(nch,digits),counter); - HitMap[nch]->SetHit(ipx, ipy, counter); + hitMap[nch]->SetHit(ipx, ipy, counter); counter++; - pdigit=(AliMUONlist*)list->At(list->GetLast()); + pdigit=(AliMUONTransientDigit*)list->At(list->GetLast()); // list of tracks TObjArray *trlist=(TObjArray*)pdigit->TrackList(); trlist->Add(&trinfo); } else { - pdigit=(AliMUONlist*) HitMap[nch]->GetHit(ipx, ipy); + pdigit=(AliMUONTransientDigit*) 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); + Int_t lastEntry=trlist->GetLast(); + TVector *pTrack=(TVector*)trlist->At(lastEntry); + TVector &ptrk=*pTrack; + Int_t lastTrack=Int_t(ptrk(0)); + Int_t lastCharge=Int_t(ptrk(1)); + if (lastTrack==track) { + lastCharge+=iqpad; + trlist->RemoveAt(lastEntry); + trinfo(0)=lastTrack; + trinfo(1)=lastCharge; + trlist->AddAt(&trinfo,lastEntry); } else { trlist->Add(&trinfo); } @@ -921,8 +1040,8 @@ void AliMUON::Digitise(Int_t nev,Int_t bgr_ev,Option_t *option, Option_t *,Text_ Int_t nptracks=trlist->GetEntriesFast(); if (nptracks > 2) { for (Int_t tr=0;trAt(tr); - TVector &pptrk=*pptrk_p; + TVector *ppTrack=(TVector*)trlist->At(tr); + TVector &pptrk=*ppTrack; trk[tr]=Int_t(pptrk(0)); chtrk[tr]=Int_t(pptrk(1)); } @@ -931,34 +1050,29 @@ void AliMUON::Digitise(Int_t nev,Int_t bgr_ev,Option_t *option, Option_t *,Text_ } //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)TrH1->GetEntries(); - //printf("background - icat,ntracks1 %d %d\n",icat,ntracks); - //printf("background - Start loop over tracks \n"); + if (addBackground) { + ntracks =(Int_t)fTrH1->GetEntries(); // // Loop over tracks // for (Int_t track=0; trackClear(); - if (fClusters2) fClusters2->Clear(); + if (fPadHits2) fPadHits2->Clear(); - TrH1->GetEvent(track); + fTrH1->GetEvent(track); // // Loop over hits - AliMUONhit* mHit; + AliMUONHit* mHit; for(int i=0;iGetEntriesFast();++i) - { - mHit=(AliMUONhit*) (*fHits2)[i]; + { + mHit=(AliMUONHit*) (*fHits2)[i]; Int_t nch = mHit->fChamber-1; // chamber number if (nch >9) continue; - iChamber = &(MUON->Chamber(nch)); + iChamber = &(pMUON->Chamber(nch)); Int_t rmin = (Int_t)iChamber->RInner(); Int_t rmax = (Int_t)iChamber->ROuter(); Float_t xbgr=mHit->fX; @@ -974,79 +1088,75 @@ void AliMUON::Digitise(Int_t nev,Int_t bgr_ev,Option_t *option, Option_t *,Text_ // // Loop over pad hits - for (AliMUONcluster* mPad= - (AliMUONcluster*)MUON->FirstPad(mHit,fClusters2); + for (AliMUONPadHit* mPad= + (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits2); mPad; - mPad=(AliMUONcluster*)MUON->NextPad(fClusters2)) + mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits2)) { - + // mPad = (AliMUONPadHit*) (*fPadHits2)[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 + Int_t iqpad = Int_t(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=iChamber->SegmentationModel(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; - + new((*pAddress)[countadr++]) TVector(2); + TVector &trinfo=*((TVector*) (*pAddress)[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); + AliMUONTransientDigit* pdigit; + // build the list of fired pads and update the info + if (!hitMap[nch]->TestHit(ipx, ipy)) { + list->AddAtAndExpand(new AliMUONTransientDigit(nch,digits),counter); + + hitMap[nch]->SetHit(ipx, ipy, counter); counter++; - pdigit=(AliMUONlist*)list->At(list->GetLast()); + pdigit=(AliMUONTransientDigit*)list->At(list->GetLast()); // list of tracks - TObjArray *trlist=(TObjArray*)pdigit-> - TrackList(); - trlist->Add(&trinfo); + TObjArray *trlist=(TObjArray*)pdigit-> + TrackList(); + trlist->Add(&trinfo); } else { - pdigit=(AliMUONlist*) HitMap[nch]->GetHit(ipx, ipy); + pdigit=(AliMUONTransientDigit*) 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); - } + TObjArray* trlist=(TObjArray*)pdigit-> + TrackList(); + Int_t lastEntry=trlist->GetLast(); + TVector *pTrack=(TVector*)trlist-> + At(lastEntry); + TVector &ptrk=*pTrack; + Int_t lastTrack=Int_t(ptrk(0)); + if (lastTrack==-1) { + continue; + } else { + trlist->Add(&trinfo); + } // check the track list - Int_t nptracks=trlist->GetEntriesFast(); - if (nptracks > 0) { - for (Int_t tr=0;trAt(tr); - TVector &pptrk=*pptrk_p; - trk[tr]=Int_t(pptrk(0)); - chtrk[tr]=Int_t(pptrk(1)); - } - } // end if nptracks + Int_t nptracks=trlist->GetEntriesFast(); + if (nptracks > 0) { + for (Int_t tr=0;trAt(tr); + TVector &pptrk=*ppTrack; + trk[tr]=Int_t(pptrk(0)); + chtrk[tr]=Int_t(pptrk(1)); + } + } // end if nptracks } // end if pdigit } //end loop over clusters } // hit loop @@ -1054,114 +1164,96 @@ void AliMUON::Digitise(Int_t nev,Int_t bgr_ev,Option_t *option, Option_t *,Text_ //Int_t nentr2=list->GetEntriesFast(); //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2); TTree *fAli=gAlice->TreeK(); - TFile *file; + TFile *file=NULL; if (fAli) file =fAli->GetCurrentFile(); file->cd(); - } // if Add - + } // if addBackground + Int_t tracks[10]; Int_t charges[10]; - //cout<<"start filling digits \n "<GetEntriesFast(); - //printf(" \n \n nentries %d \n",nentries); - // start filling the digits for (Int_t nent=0;nentAt(nent); + AliMUONTransientDigit *address=(AliMUONTransientDigit*)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; + iChamber=(AliMUONChamber*) (*fChambers)[ich]; +// +// Digit Response (noise, threshold, saturation, ...) +// if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise; + AliMUONResponse * response=iChamber->ResponseModel(); + q=response->DigitResponse(q); + + if (!q) continue; + digits[0]=address->fPadX; digits[1]=address->fPadY; digits[2]=q; digits[3]=address->fPhysics; digits[4]=address->fHit; - //printf("fSignal, fPhysics fTrack %d %d %d \n",digits[2],digits[3],digits[4]); TObjArray* trlist=(TObjArray*)address->TrackList(); Int_t nptracks=trlist->GetEntriesFast(); //printf("nptracks, trlist %d %p\n",nptracks,trlist); - // this was changed to accomodate the real number of tracks - if (nptracks > 10) { - cout<<"Attention - nptracks > 10 "< 2) { - printf("Attention - nptracks > 2 %d \n",nptracks); - printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q); - } - for (Int_t tr=0;trAt(tr); - if(!pp_p ) printf("pp_p - %p\n",pp_p); - TVector &pp =*pp_p; - tracks[tr]=Int_t(pp(0)); - charges[tr]=Int_t(pp(1)); + // this was changed to accomodate the real number of tracks + if (nptracks > 10) { + cout<<"Attention - nptracks > 10 "< 2) { + printf("Attention - nptracks > 2 %d \n",nptracks); + printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q); + } + for (Int_t tr=0;trAt(tr); + if(!ppP ) printf("ppP - %p\n",ppP); + TVector &pp =*ppP; + 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 + } //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; - } + 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); + pMUON->AddDigits(ich,tracks,charges,digits); + // delete trlist; } //cout<<"I'm out of the loops for digitisation"<GetEvent(nev); gAlice->TreeD()->Fill(); - TTree *TD=gAlice->TreeD(); - - Stat_t ndig=TD->GetEntries(); - cout<<"number of digits "<DigitsAddress(k); - int ndig=fDch->GetEntriesFast(); - printf (" i, ndig %d %d \n",k,ndig); - } - - MUON->ResetDigits(); + pMUON->ResetDigits(); list->Delete(); - for(Int_t ii=0;ii<10;++ii) { - if (HitMap[ii]) { - hm=HitMap[ii]; + + for(Int_t ii=0;iiTreeD()->Write(hname); - // reset tree - gAlice->TreeD()->Reset(); - delete list; - //Int_t nadr=p_adr->GetEntriesFast(); - // printf(" \n \n nadr %d \n",nadr); - - p_adr->Clear(); - // gObjectTable->Print(); - + + char hname[30]; + sprintf(hname,"TreeD%d",nev); + gAlice->TreeD()->Write(hname); + // reset tree + gAlice->TreeD()->Reset(); + delete list; + + pAddress->Delete(); + // gObjectTable->Print(); } void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr) @@ -1219,495 +1311,229 @@ void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr) } -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(); - //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->FindRawClusters(); - } - //printf("Finish FindRawClusters for cathode %d in chamber %d\n",icat,ich); - - TClonesArray *fRch; - fRch=RawClustAddress(ich); - fRch->Sort(); - // it seems to work - - - } // for ich - // fill the tree - TTree *TR=gAlice->TreeR(); - - gAlice->TreeR()->Fill(); - - Stat_t nent=TR->GetEntries(); - cout<<"number of entries "<GetEntriesFast(); - printf (" i, nraw %d %d \n",i,nraw); +//___________________________________________ +void AliMUON::Trigger(Int_t nev){ +// call the Trigger Algorithm and fill TreeR + + Int_t singlePlus[3] = {0,0,0}; + Int_t singleMinus[3] = {0,0,0}; + Int_t singleUndef[3] = {0,0,0}; + Int_t pairUnlike[3] = {0,0,0}; + Int_t pairLike[3] = {0,0,0}; + + ResetTrigger(); + + AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1); + decision->Trigger(); + decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef, + pairUnlike, pairLike); +// add a local trigger in the list + AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike); + + for (Int_t icirc=0; icircGetITrigger(icirc)==1) { + Int_t localtr[7]={0,0,0,0,0,0,0}; + Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0}; + decision->GetLutOutput(icirc, loLpt, loHpt, loApt); + localtr[0] = icirc; + localtr[1] = decision->GetStripX11(icirc); + localtr[2] = decision->GetDev(icirc); + localtr[3] = decision->GetStripY11(icirc); + for (Int_t i=0; i<2; i++) { // convert the Lut output in 1 digit + localtr[4] = localtr[4]+Int_t(loLpt[i]*pow(2,i)); + localtr[5] = localtr[5]+Int_t(loHpt[i]*pow(2,i)); + localtr[6] = localtr[6]+Int_t(loApt[i]*pow(2,i)); } - ResetRawClusters(); - - } // for icat + // cout << loApt[0] << " , " << loApt[1] << " , " << localtr[6] << "\n"; + AddLocalTrigger(localtr); // add a local trigger in the list + } + } + delete decision; + gAlice->TreeR()->Fill(); + ResetTrigger(); char hname[30]; sprintf(hname,"TreeR%d",nev); gAlice->TreeR()->Write(hname); gAlice->TreeR()->Reset(); - - //gObjectTable->Print(); - + printf("\n End of trigger for event %d", nev); } - -//______________________________________________________________________________ -//_____________________________________________________________________________ -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=kTRUE; - 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, i; - // - 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 (i=0;i<50;i++) { - xdarray[i]=1100.; - xarray[i]=0.; - yarray[i]=0.; - qarray[i]=0.; - idx2[i]=-1; - } - for (i=0;i<4;i++) { - idx[i]=-1; - xc2[i]=0.; - yc2[i]=0.; - } - - // access to the Raw Clusters tree - for (Int_t ich=0;ich<10;ich++) { - iChamber = &(Chamber(ich)); - TClonesArray *MUONrawclust = RawClustAddress(ich); - ResetRawClusters(); - TR->GetEvent(nent-2); - //TR->GetEvent(1); - Int_t nrawcl1 = MUONrawclust->GetEntries(); - // printf("Found %d raw clusters for cathode 1 in chamber %d \n" - // ,nrawcl1,ich+1); - if (!nrawcl1) continue; - - seg = iChamber->GetSegmentationModel(1); - // loop over raw clusters of first cathode - for (iraw1=0; iraw1UncheckedAt(iraw1); - x1[iraw1]=mRaw1->fX; - y1[iraw1]=mRaw1->fY; - q1[iraw1]=(Float_t)mRaw1->fQ; //maybe better fPeakSignal - } // rawclusters cathode 1 +//____________________________________________ +void AliMUON::FindClusters(Int_t nev,Int_t lastEntry) +{ + TClonesArray *dig1, *dig2; + Int_t ndig, k; + dig1 = new TClonesArray("AliMUONDigit",1000); + dig2 = new TClonesArray("AliMUONDigit",1000); + AliMUONDigit *digit; // - // Get information from 2nd cathode - ResetRawClusters(); - TR->GetEvent(nent-1); - //TR->GetEvent(2); - Int_t nrawcl2 = MUONrawclust->GetEntries(); - if (!nrawcl2) { - for (iraw1=0; iraw1UncheckedAt(iraw2); - x2[iraw2]=mRaw2->fX; - y2[iraw2]=mRaw2->fY; - q2[iraw2]=(Float_t)mRaw2->fQ; - } // rawclusters cathode 2 +// Loop on chambers and on cathode planes // -// Initalisation finished - for (iraw1=0; iraw1GetPadIxy(x1[iraw1],y1[iraw1],ix,iy); - Int_t isec=seg->Sector(ix,iy); - // range to look for ghosts ?! - if (ich < 5) { - ymax = seg->Dpy(isec)*7/2; - xmax = seg->Dpx(isec)*7/2; - } else { - ymax = seg->Dpy(isec)*13/2; - xmax = seg->Dpx(isec)*3/2; - } - ysrch=ymax+y1[iraw1]; - - ilow = AliMUONRawCluster:: - BinarySearch(ysrch-2*ymax,y2,0,nrawcl2+1); - iup= AliMUONRawCluster:: - BinarySearch(ysrch,y2,ilow,nrawcl2+1); - if (ilow<0 || iup <0 || iup>nrawcl2) continue; - Int_t counter=0; - for (Int_t iraw2=ilow; iraw2<=iup; iraw2++) { - xrec2=x2[iraw2]; - yrec2=y2[iraw2]; - xdif=x1[iraw1]-xrec2; - ydif=y1[iraw1]-yrec2; - xd=TMath::Sqrt(xdif*xdif+ydif*ydif); - if (iraw2==ilow) { - if (ilow==iup) - xd0=TMath:: - Sqrt(2*xmax*2*xmax+2*ymax*2*ymax); - else xd0=101.; - } - Float_t qdif=TMath::Abs(q1[iraw1]-q2[iraw2])/q1[iraw1]; - - if (x1[iraw1]*xrec2 > 0) { - if (xd <= xd0 ) { -// printf("q1, q2 qdif % f %f %f \n",q1[iraw1],q2[iraw2],qdif); -// printf("x1, x2 y1 y2 % f %f %f %f \n",x1[iraw1],xrec2,y1[iraw1],yrec2); - //if (qdif <0.3) { //check this number - - xd0=xd; - idx2[counter]=iraw2; - xdarray[counter]=xd; - xarray[counter]=xdif; - yarray[counter]=ydif; - qarray[counter]=qdif; - counter++; - // } - - } - } // check for same quadrant - } // loop over 2nd cathode range - - - if (counter >=2) { - AliMUONRawCluster:: - SortMin(idx2,xdarray,xarray,yarray,qarray,counter); - if (xdarray[0]Dpx(isec) && xdarray[1]Dpx(isec)) { - if (qarray[0]>qarray[1]){ - Int_t swap=idx2[0]; - idx2[0]=idx2[1]; - idx2[1]=swap; - } - } - } - int imax; - if (counter <3) imax=counter; - else imax=3; - - for (int i=0;i= 0 && idx2[i] < nrawcl2) { - if (xarray[i] > xmax || yarray[i] > 2*ymax) - continue; - idx[i]=idx2[i]; - xc2[i]=x2[idx2[i]]; - yc2[i]=y2[idx2[i]]; - } - } - // add info about the cluster on the 'starting' cathode - - idx[3]=iraw1; - xc2[3]=x1[iraw1]; - yc2[3]=y1[iraw1]; - //if (idx[0] <0) printf("iraw1 imax idx2[0] idx[0] %d %d %d %d\n",iraw1,imax,idx2[0],idx[0]); - AddCathCorrel(ich,idx,xc2,yc2); - // reset - for (Int_t ii=0;iiFill(); - //Int_t nentries=(Int_t)TC->GetEntries(); - //cout<<"number entries in tree of correlated clusters "<GetEntriesFast(); - printf (" ii, ncor %d %d \n",ii,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])); - } + for (Int_t ich=0;ich<10;ich++) { + AliMUONChamber* iChamber=(AliMUONChamber*) (*fChambers)[ich]; + AliMUONClusterFinder* rec = iChamber->ReconstructionModel(); + gAlice->ResetDigits(); + gAlice->TreeD()->GetEvent(lastEntry); + TClonesArray *muonDigits = this->DigitsAddress(ich); + ndig=muonDigits->GetEntriesFast(); + printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich); + TClonesArray &lhits1 = *dig1; + Int_t n=0; + for (k=0; kUncheckedAt(k); + if (rec->TestTrack(digit->fTracks[0])) + new(lhits1[n++]) AliMUONDigit(*digit); + } + gAlice->ResetDigits(); + gAlice->TreeD()->GetEvent(lastEntry+1); + muonDigits = this->DigitsAddress(ich); + ndig=muonDigits->GetEntriesFast(); + printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich); + TClonesArray &lhits2 = *dig2; + n=0; + + for (k=0; kUncheckedAt(k); + if (rec->TestTrack(digit->fTracks[0])) + new(lhits2[n++]) AliMUONDigit(*digit); } - } else { - printf("ERROR: cannot find CathodeCorrelation Tree for event:%d\n",event); - } - - // gObjectTable->Print(); + if (rec) { + rec->SetDigits(dig1, dig2); + rec->SetChamber(ich); + rec->FindRawClusters(); + } + dig1->Delete(); + dig2->Delete(); + } // for ich + gAlice->TreeR()->Fill(); + ResetRawClusters(); + char hname[30]; + sprintf(hname,"TreeR%d",nev); + gAlice->TreeR()->Write(hname); + gAlice->TreeR()->Reset(); + printf("\n End of cluster finding for event %d", nev); + + delete dig1; + delete dig2; + //gObjectTable->Print(); } - + void AliMUON::Streamer(TBuffer &R__b) { // Stream an object of class AliMUON. - AliMUONchamber *iChamber; - AliMUONsegmentation *segmentation; - AliMUONresponse *response; + AliMUONChamber *iChamber; + AliMUONTriggerCircuit *iTriggerCircuit; + 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) { } AliDetector::Streamer(R__b); - R__b >> fNclusters; - R__b >> fClusters; // diff + R__b >> fNPadHits; + R__b >> fPadHits; // diff + R__b >> fNLocalTrigger; + R__b >> fLocalTrigger; + R__b >> fNGlobalTrigger; + R__b >> fGlobalTrigger; R__b >> fDchambers; R__b >> fRawClusters; - R__b >> fCathCorrel; R__b.ReadArray(fNdch); R__b.ReadArray(fNrawch); - R__b.ReadArray(fNcorch); - // 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; + R__b >> fTriggerCircuits; + for (Int_t i =0; iStreamer(R__b); + } // Stream chamber related information - for (Int_t i =0; i<10; i++) { - iChamber=(AliMUONchamber*) (*fChambers)[i]; + for (Int_t i =0; iStreamer(R__b); if (iChamber->Nsec()==1) { - segmentation=iChamber->GetSegmentationModel(1); + segmentation=iChamber->SegmentationModel(1); + if (segmentation) segmentation->Streamer(R__b); } else { - segmentation=iChamber->GetSegmentationModel(1); + segmentation=iChamber->SegmentationModel(1); + if (segmentation) segmentation->Streamer(R__b); - segmentation=iChamber->GetSegmentationModel(2); + if (segmentation) + segmentation=iChamber->SegmentationModel(2); segmentation->Streamer(R__b); } - response=iChamber->GetResponseModel(); + response=iChamber->ResponseModel(); + if (response) 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); + if (i < kNTrackingCh) { + rawcladdress=(TClonesArray*) (*fRawClusters)[i]; + rawcladdress->Streamer(R__b); + } } } else { R__b.WriteVersion(AliMUON::IsA()); AliDetector::Streamer(R__b); - R__b << fNclusters; - R__b << fClusters; // diff + R__b << fNPadHits; + R__b << fPadHits; // diff + R__b << fNLocalTrigger; + R__b << fLocalTrigger; + R__b << fNGlobalTrigger; + R__b << fGlobalTrigger; 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.WriteArray(fNdch, kNCH); + R__b.WriteArray(fNrawch, kNTrackingCh); + 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++) { - iChamber=(AliMUONchamber*) (*fChambers)[i]; + R__b << fTriggerCircuits; + for (Int_t i =0; iStreamer(R__b); + } + for (Int_t i =0; iStreamer(R__b); if (iChamber->Nsec()==1) { - segmentation=iChamber->GetSegmentationModel(1); + segmentation=iChamber->SegmentationModel(1); + if (segmentation) segmentation->Streamer(R__b); } else { - segmentation=iChamber->GetSegmentationModel(1); + segmentation=iChamber->SegmentationModel(1); + if (segmentation) segmentation->Streamer(R__b); - segmentation=iChamber->GetSegmentationModel(2); + segmentation=iChamber->SegmentationModel(2); + if (segmentation) segmentation->Streamer(R__b); } - response=iChamber->GetResponseModel(); + response=iChamber->ResponseModel(); + if (response) 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); + if (i < kNTrackingCh) { + rawcladdress=(TClonesArray*) (*fRawClusters)[i]; + rawcladdress->Streamer(R__b); + } } } } -AliMUONcluster* AliMUON::FirstPad(AliMUONhit* hit, TClonesArray *clusters) +AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters) { // // Initialise the pad iterator @@ -1715,1496 +1541,50 @@ AliMUONcluster* AliMUON::FirstPad(AliMUONhit* hit, TClonesArray *clusters) TClonesArray *theClusters = clusters; Int_t nclust = theClusters->GetEntriesFast(); if (nclust && hit->fPHlast > 0) { - sMaxIterPad=hit->fPHlast; - sCurIterPad=hit->fPHfirst; - return (AliMUONcluster*) clusters->UncheckedAt(sCurIterPad-1); + AliMUON::fMaxIterPad=hit->fPHlast; + AliMUON::fCurIterPad=hit->fPHfirst; + return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1); } else { return 0; } } -AliMUONcluster* AliMUON::NextPad(TClonesArray *clusters) +AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters) { - sCurIterPad++; - if (sCurIterPad <= sMaxIterPad) { - return (AliMUONcluster*) clusters->UncheckedAt(sCurIterPad-1); + AliMUON::fCurIterPad++; + if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) { + return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-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); + TClonesArray *muonRawCluster = 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(); + TTree *treeR = gAlice->TreeR(); + Int_t nent=(Int_t)treeR->GetEntries(); + treeR->GetEvent(nent-2+icathod-1); + //treeR->GetEvent(icathod); + //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast(); - AliMUONRawCluster * mRaw = (AliMUONRawCluster*)MUONrawclust->UncheckedAt(icluster); + AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->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=kTRUE; - static TFile *File; - char *Add = strstr(option,"Add"); - - if (Add ) { // only in case of background with geant hits - if(first) { - fFileName=filename; - cout<<"filename "<cd(); - if(fHits2) fHits2->Clear(); - if(fParticles2) fParticles2->Clear(); - if(TrH1) delete TrH1; - TrH1=0; - if(TK1) delete TK1; - TK1=0; - // Get Hits Tree header from file - char treeName[20]; - sprintf(treeName,"TreeH%d",bgd_ev); - TrH1 = (TTree*)gDirectory->Get(treeName); - if (!TrH1) { - 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 (TrH1 && fHits2) { - branch = TrH1->GetBranch(branchname); - if (branch) branch->SetAddress(&fHits2); - } - TrH1->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::InitTracking(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(); - if (TK) { - TFile *file1 = TK->GetCurrentFile(); - if(file1) file1->cd(); - } -} - -void AliMUON::CloseTracking() -{ - // - // write histos and ntuple to "reconst.root" file - reco_term(); -} - -void chfill(Int_t &id, Float_t &x, Float_t &, Float_t &) -{ - // - // 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) +AliMUON& AliMUON::operator = (const AliMUON& rhs) { - // - // introduce aliroot variables in fortran common - // tracking study from geant hits - // - - AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); - - // TTree *TK = gAlice->TreeK(); - TTree *TH = gAlice->TreeH(); - Int_t ntracks = (Int_t)TH->GetEntries(); - cout<<"ntrack="<ResetHits(); - TH->GetEvent(track); - - if (MUON) { -// -// Loop over hits -// - for(AliMUONhit* mHit=(AliMUONhit*)MUON->FirstHit(-1); - mHit; - mHit=(AliMUONhit*)MUON->NextHit()) - { - if (maxidg<=20000) { - - if (mHit->fChamber > 10) continue; - TClonesArray *fPartArray = gAlice->Particles(); - TParticle *Part; - Int_t ftrack = mHit->fTrack; - Int_t id = ((TParticle*) fPartArray->UncheckedAt(ftrack))->GetPdgCode(); - - if (id==kMuonPlus||id==kMuonMinus) { - - // inversion de x et y car le champ est inverse dans le programme tracking - xtrg[maxidg] = 0; - ytrg[maxidg] = 0; - xgeant[maxidg] = mHit->fY; // x-pos of hit - ygeant[maxidg] = mHit->fX; // y-pos of hit - clsize1[maxidg] = 0; // cluster size on 1-st cathode - clsize2[maxidg] = 0; // cluster size on 2-nd cathode - cx[maxidg] = mHit->fCyHit; // Px/P of hit - cy[maxidg] = mHit->fCxHit; // Py/P of hit - cz[maxidg] = mHit->fCzHit; // Pz/P of hit - izch[maxidg] = mHit->fChamber; - /* - Int_t pdgtype = Int_t(mHit->fParticle); // particle number - itypg[maxidg] = gMC->IdFromPDG(pdgtype); - - */ - if (id==kMuonPlus) itypg[maxidg] = 5; - else itypg[maxidg] = 6; - - ptotg[maxidg] = mHit->fPTot; // P of hit - - Part = (TParticle*) fPartArray->UncheckedAt(ftrack); - Float_t thet = Part->Theta(); - thet = thet*180./3.1416; - - 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 - maxidg ++; - - } - } - } // hit loop - } // if MUON - } // track loop first file - - if (TrH1 && fHits2 ) { // if background file - ntracks =(Int_t)TrH1->GetEntries(); - printf("Trackf_read - 2-nd file - ntracks %d\n",ntracks); - - // Loop over tracks - for (Int_t track=0; trackClear(); - TrH1->GetEvent(track); - - // Loop over hits - for (int i=0;iGetEntriesFast();i++) - { - AliMUONhit *mHit=(AliMUONhit*) (*fHits2)[i]; - - if (mHit->fChamber > 10) continue; - - if (maxidg<=20000) { - - // inversion de x et y car le champ est inverse dans le programme tracking !!!! - xtrg[maxidg] = 0; // only for reconstructed point - ytrg[maxidg] = 0; // only for reconstructed point - xgeant[maxidg] = mHit->fY; // x-pos of hit - ygeant[maxidg] = mHit->fX; // y-pos of hit - clsize1[maxidg] = 0; // cluster size on 1-st cathode - clsize2[maxidg] = 0; // cluster size on 2-nd cathode - cx[maxidg] = mHit->fCyHit; // Px/P of hit - cy[maxidg] = mHit->fCxHit; // Py/P of hit - cz[maxidg] = mHit->fCzHit; // Pz/P of hit - izch[maxidg] = mHit->fChamber; // chamber number - ptotg[maxidg] = mHit->fPTot; // P of hit - - Int_t ftrack = mHit->fTrack; - Int_t id1 = ftrack; // track number - Int_t idum = track+1; - - TClonesArray *fPartArray = fParticles2; - TParticle *Part; - Part = (TParticle*) fPartArray->UncheckedAt(ftrack); - 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 TrH1 - - ievr = nev; - nhittot1 = maxidg ; - cout<<"nhittot1="<=19) nbres++; - printf("nres, nbres %d %d \n",nres,nbres); - - hfile_global->cd(); - +// copy operator +// dummy version + return *this; } -void trackf_read_spoint(Int_t *itypg, Double_t *xtrg, Double_t *ytrg, Double_t *ptotg, Int_t *idg, Int_t *izch, Double_t *pvert1g, Double_t *pvert2g, Double_t *pvert3g, Double_t *zvertg, Int_t &nhittot1, Double_t *cx, Double_t *cy, Double_t *cz, Int_t &ievr,Int_t &nev,Double_t *xgeant, Double_t *ygeant,Double_t *clsize1, Double_t *clsize2) - -{ - // - // introduce aliroot variables in fortran common - // tracking study from reconstructed points - // - AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); - - cout<<"numero de l'evenement "<GetTreeC(nev); - TTree *TC=MUON->TreeC(); - TC->GetEntries(); - - Int_t maxidg = 0; - Int_t nres=0; - Int_t nncor=0; - static Int_t nuncor=0; - static Int_t nbadcor=0; - AliMUONRawCluster * mRaw; - AliMUONRawCluster * mRaw1; - TTree *TH = gAlice->TreeH(); - - Int_t ihit; - Int_t mult1, mult2; - if (MUON) { - for (Int_t ich=0;ich<10;ich++) { - TClonesArray *MUONcorrel = MUON->CathCorrelAddress(ich); - MUON->ResetCorrelation(); - TC->GetEvent(); - Int_t ncor = (Int_t)MUONcorrel->GetEntries(); - if (ncor>=2) nncor++; - if (!ncor) continue; - - // Loop over correlated clusters - for (Int_t icor=0;icorUncheckedAt(icor); - - Int_t flag=0; // = 1 if no information in the second cathode - Int_t index = mCor->fCorrelIndex[0]; // for the second cathode - if (index >= 0) { - Int_t index1 = mCor->fCorrelIndex[3]; // for the 1-st cathode - mRaw1 = MUON->RawCluster(ich,1,index1); - mult1=mRaw1->fMultiplicity; - mRaw = MUON->RawCluster(ich,2,index); - mult2=mRaw->fMultiplicity; - } else { - index = mCor->fCorrelIndex[3]; - mRaw = MUON->RawCluster(ich,1,index); - mult1=mRaw->fMultiplicity; - mult2=0; - flag=1; - nuncor++; - } - if (!mRaw) continue; - - Int_t ftrack1 = mRaw->fTracks[1]; // qui doit etre le meme pour - // la cathode 1 et 2 - ihit= mRaw->fTracks[0]; - //printf("icor, ftrack1 ihit %d %d %d\n",icor,ftrack1,ihit); - - if (mRaw->fClusterType == 0 ) { - - if (maxidg<=20000) { - if (flag == 0) { - xtrg[maxidg] = (Double_t) mCor->fY[3]; - ytrg[maxidg] = (Double_t) mCor->fX[0]; - Int_t index1 = mCor->fCorrelIndex[3]; - mRaw1 = MUON->RawCluster(ich,1,index1); - if (mRaw1->fClusterType==1 || mRaw1->fClusterType==2) { - Float_t xclust=mCor->fX[3]; - Float_t yclust=mCor->fY[3]; - AliMUONchamber *iChamber=&(MUON->Chamber(ich)); - AliMUONsegmentation *seg = iChamber->GetSegmentationModel(1); - Int_t ix,iy; - seg->GetPadIxy(xclust,yclust,ix,iy); - Int_t isec=seg->Sector(ix,iy); - printf("nev, CORRELATION with pure background in chamber sector %d %d %d !!!!!!!!!!!!!!!!!!!!!\n",nev,ich+1,isec); - nbadcor++; - - } // end if cluster type on cathode 1 - }else { - xtrg[maxidg] = (Double_t) mCor->fY[3]; - ytrg[maxidg] = (Double_t) mCor->fX[3]; - } // if iflag - izch[maxidg] = ich+1; - xgeant[maxidg] = 0; - ygeant[maxidg] = 0; - clsize1[maxidg] = mult1; - clsize2[maxidg] = mult2; - - cx[maxidg] = 0; // Px/P of hit - cy[maxidg] = 0; // Py/P of hit - cz[maxidg] = 0; // Pz/P of hit - itypg[maxidg] = 0; // particle number - ptotg[maxidg] = 0; // P of hit - idg[maxidg] = 0; - pvert1g[maxidg] = 0; // Px vertex - pvert2g[maxidg] = 0; // Py vertex - pvert3g[maxidg] = 0; // Pz vertex - zvertg[maxidg] = 0; // z vertex - maxidg++; - - }// fin maxidg - - } else if (mRaw->fClusterType ==1 && ftrack1 < 0) // background + resonance - { - nres++; - // get indexmap and loop over digits to find the signal - Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); - gAlice->ResetDigits(); - if (flag==0) { - //gAlice->TreeD()->GetEvent(2); // cathode 2 - gAlice->TreeD()->GetEvent(nent-1); // cathode 2 - } else { - //gAlice->TreeD()->GetEvent(1); // cathode 1 - gAlice->TreeD()->GetEvent(nent-2); // cathode 1 - } - - TClonesArray *MUONdigits = MUON->DigitsAddress(ich); - Int_t mul=mRaw->fMultiplicity; - Int_t trsign; - for (int i=0;ifIndexMap[i]; - AliMUONdigit *dig= (AliMUONdigit*)MUONdigits->UncheckedAt(idx); - trsign=dig->fTracks[0]; - ihit=dig->fHit-1; - if (trsign > 0 && ihit >= 0) break; - - } // loop over indexmap - - //printf("trsign, ihit %d %d\n",trsign,ihit); - //printf("signal+background : trsign %d\n",trsign); - - if (trsign < 0 || ihit < 0) { // no signal muon was found - - if (maxidg<=20000) { - if (flag == 0) { - xtrg[maxidg] = (Double_t) mCor->fY[3]; - ytrg[maxidg] = (Double_t) mCor->fX[0]; - }else { - xtrg[maxidg] = (Double_t) mCor->fY[3]; - ytrg[maxidg] = (Double_t) mCor->fX[3]; - } - - izch[maxidg] = ich+1; - - // initialisation of informations which - // can't be reached for background - - xgeant[maxidg] = 0; // only for resonances - ygeant[maxidg] = 0; // only for resonances - clsize1[maxidg] = mult1; - clsize2[maxidg] = mult2; - - cx[maxidg] = 0; // Px/P of hit - cy[maxidg] = 0; // Py/P of hit - cz[maxidg] = 0; // Pz/P of hit - itypg[maxidg] = 0; // particle number - ptotg[maxidg] = 0; // P of hit - idg[maxidg] = 0; - pvert1g[maxidg] = 0; // Px vertex - pvert2g[maxidg] = 0; // Py vertex - pvert3g[maxidg] = 0; // Pz vertex - zvertg[maxidg] = 0; - maxidg++; - - }// fin maxidg - } else { // signal muon - retrieve info - //printf("inside trsign, ihit %d %d\n",trsign,ihit); - if (maxidg<=20000) { - if (flag == 0) { - xtrg[maxidg] = (Double_t) mCor->fY[3]; - ytrg[maxidg] = (Double_t) mCor->fX[0]; - }else { - xtrg[maxidg] = (Double_t) mCor->fY[3]; - ytrg[maxidg] = (Double_t) mCor->fX[3]; - } - izch[maxidg] = ich+1; - clsize1[maxidg] = mult1; - clsize2[maxidg] = mult2; - - // initialise and set to the correct values - // if signal muons - - xgeant[maxidg] = 0; // only for resonances - ygeant[maxidg] = 0; // only for resonances - - cx[maxidg] = 0; // Px/P of hit - cy[maxidg] = 0; // Py/P of hit - cz[maxidg] = 0; // Pz/P of hit - itypg[maxidg] = 0; // particle number - ptotg[maxidg] = 0; // P of hit - idg[maxidg] = 0; - pvert1g[maxidg] = 0; // Px vertex - pvert2g[maxidg] = 0; // Py vertex - pvert3g[maxidg] = 0; // Pz vertex - zvertg[maxidg] = 0; - // try to retrieve info about signal muons - gAlice->ResetHits(); - TH->GetEvent(trsign); - - TClonesArray *MUONhits = MUON->Hits(); - AliMUONhit *mHit= (AliMUONhit*)MUONhits-> - UncheckedAt(ihit); - TClonesArray *fPartArray = gAlice->Particles(); - TParticle *Part; - Int_t nch=mHit->fChamber-1; - //printf("sig+bgr ich, nch %d %d \n",ich,nch); - if (nch==ich) { - Int_t ftrack = mHit->fTrack; - Int_t id = ((TParticle*) fPartArray-> - UncheckedAt(ftrack))->GetPdgCode(); - if (id==kMuonPlus||id==kMuonMinus) { - xgeant[maxidg] = (Double_t) mHit->fY; - ygeant[maxidg] = (Double_t) mHit->fX; - cx[maxidg] = (Double_t) mHit->fCyHit; - cy[maxidg] = (Double_t) mHit->fCxHit; - cz[maxidg] = (Double_t) mHit->fCzHit; - - if (id==kMuonPlus) { - itypg[maxidg] = 5; - } else if (id==kMuonMinus) { - itypg[maxidg] = 6; - } else itypg[maxidg] = 0; - - ptotg[maxidg] = (Double_t) mHit->fPTot; - Part = (TParticle*) fPartArray-> - UncheckedAt(ftrack); - Int_t iparent = Part->GetFirstMother(); - Int_t id2; - id2 = ((TParticle*) fPartArray-> - UncheckedAt(ftrack))->GetPdgCode(); - - if (iparent >= 0) { - Int_t ip; - while(1) { - ip=((TParticle*) fPartArray-> - UncheckedAt(iparent))->GetFirstMother(); - if (ip < 0) { - id2 = ((TParticle*) fPartArray-> - UncheckedAt(iparent))->GetPdgCode(); - break; - } else { - iparent = ip; - id2 = ((TParticle*) fPartArray-> - UncheckedAt(iparent))->GetPdgCode(); - } // ip<0 - } // while - }// iparent - Int_t id1 = ftrack; - Int_t idum = trsign+1; - - if (id2==443 || id2==553) { - nres++; - if (id2==443) id2=114; - else id2=116; - } - - idg[maxidg] = 30000*id1+10000*idum+id2; - pvert1g[maxidg] = (Double_t) Part->Py(); - pvert2g[maxidg] = (Double_t) Part->Px(); - pvert3g[maxidg] = (Double_t) Part->Pz(); - zvertg[maxidg] = (Double_t) Part->Vz(); - } //if muon - } //if nch - maxidg++; - } // check limits - } // sign+bgr, highest bgr - } - //pure resonance or mixed cluster with the highest - //contribution coming from resonance - if (mRaw->fClusterType >= 1 && ftrack1>=0) - { - if (maxidg<=20000) { - if (flag == 0) { - xtrg[maxidg] = (Double_t) mCor->fY[3]; - ytrg[maxidg] = (Double_t) mCor->fX[0]; - }else { - xtrg[maxidg] = (Double_t) mCor->fY[3]; - ytrg[maxidg] = (Double_t) mCor->fX[3]; - } - clsize1[maxidg] = mult1; - clsize2[maxidg] = mult2; - izch[maxidg] = ich+1; - - Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); - gAlice->ResetDigits(); - if (flag==0) { - //gAlice->TreeD()->GetEvent(2); // cathode 2 - gAlice->TreeD()->GetEvent(nent-1); // cathode 2 - } else { - //gAlice->TreeD()->GetEvent(1); // cathode 1 - gAlice->TreeD()->GetEvent(nent-2); // cathode 1 - } - - TClonesArray *MUONdigits = MUON->DigitsAddress(ich); - Int_t mul=mRaw->fMultiplicity; - for (int i=0;ifIndexMap[i]; - AliMUONdigit *dig= (AliMUONdigit*)MUONdigits->UncheckedAt(idx); - ihit=dig->fHit-1; - if (ihit >= 0) break; - - } // loop over indexmap - //printf("fClusterType, ihit %d %d \n",mRaw->fClusterType,ihit); - if (ihit < 0) { - xgeant[maxidg] = 0; // only for resonances - ygeant[maxidg] = 0; // only for resonances - - cx[maxidg] = 0; // Px/P of hit - cy[maxidg] = 0; // Py/P of hit - cz[maxidg] = 0; // Pz/P of hit - itypg[maxidg] = 0; // particle number - ptotg[maxidg] = 0; // P of hit - idg[maxidg] = 0; - pvert1g[maxidg] = 0; // Px vertex - pvert2g[maxidg] = 0; // Py vertex - pvert3g[maxidg] = 0; // Pz vertex - zvertg[maxidg] = 0; - } else { - gAlice->ResetHits(); - TH->GetEvent(ftrack1); - TClonesArray *MUONhits = MUON->Hits(); - AliMUONhit *mHit= (AliMUONhit*)MUONhits-> - UncheckedAt(ihit); - TClonesArray *fPartArray = gAlice->Particles(); - TParticle *Part; - Int_t nch=mHit->fChamber-1; - //printf("signal ich, nch %d %d \n",ich,nch); - if (nch==ich) { - Int_t ftrack = mHit->fTrack; - Int_t id = ((TParticle*) fPartArray-> - UncheckedAt(ftrack))->GetPdgCode(); - //printf("id %d \n",id); - if (id==kMuonPlus||id==kMuonMinus) { - xgeant[maxidg] = (Double_t) mHit->fY; - ygeant[maxidg] = (Double_t) mHit->fX; - cx[maxidg] = (Double_t) mHit->fCyHit; - cy[maxidg] = (Double_t) mHit->fCxHit; - cz[maxidg] = (Double_t) mHit->fCzHit; - - if (id==kMuonPlus) { - itypg[maxidg] = 5; - } else if (id==kMuonMinus) { - itypg[maxidg] = 6; - } else itypg[maxidg] = 0; - - ptotg[maxidg] = (Double_t) mHit->fPTot; - Part = (TParticle*) fPartArray-> - UncheckedAt(ftrack); - Int_t iparent = Part->GetFirstMother(); - Int_t id2; - id2 = ((TParticle*) fPartArray-> - UncheckedAt(ftrack))->GetPdgCode(); - - if (iparent >= 0) { - Int_t ip; - while(1) { - ip=((TParticle*) fPartArray-> - UncheckedAt(iparent))->GetFirstMother(); - if (ip < 0) { - id2 = ((TParticle*) fPartArray-> - UncheckedAt(iparent))->GetPdgCode(); - break; - } else { - iparent = ip; - id2 = ((TParticle*) fPartArray-> - UncheckedAt(iparent))->GetPdgCode(); - } // ip<0 - } // while - }// iparent - Int_t id1 = ftrack; - Int_t idum = ftrack1+1; - - if (id2==443 || id2==553) { - nres++; - if (id2==443) id2=114; - else id2=116; - } - // printf("id2 %d\n",id2); - idg[maxidg] = 30000*id1+10000*idum+id2; - pvert1g[maxidg] = (Double_t) Part->Py(); - pvert2g[maxidg] = (Double_t) Part->Px(); - pvert3g[maxidg] = (Double_t) Part->Pz(); - zvertg[maxidg] = (Double_t) Part->Vz(); - } //if muon - } //if nch - } // ihit - maxidg++; - } // check limits - } // if cluster type - } // icor loop - } // ich loop - }// if MUON - - - ievr = nev; - cout<<"evenement "<=20) nbcor++; - printf("nbcor - %d\n",nbcor); - printf("nuncor - %d\n",nuncor); - printf("nbadcor - %d\n",nbadcor); - - TC->Reset(); - - hfile_global->cd(); - -} - -void trackf_fit(Int_t &ivertex, Double_t *pest, Double_t *pstep, Double_t &pxzinv, Double_t &tphi, Double_t &talam, Double_t &xvert, Double_t &yvert) -{ - // - // Fit a track candidate with the following input parameters: - // INPUT : IVERTEX : vertex flag, if IVERTEX=1 (XVERT,YVERT) are free paramaters - // if IVERTEX=1 (XVERT,YVERT)=(0.,0.) - // PEST(5) : starting value of parameters (minuit) - // PSTEP(5) : step size for parameters (minuit) - // OUTPUT : PXZINV,TPHI,TALAM,XVERT,YVERT : fitted value of the parameters - - static Double_t arglist[10]; - static Double_t c[5] = {0.4, 0.45, 0.45, 90., 90.}; - static Double_t b1, b2, epxz, efi, exs, exvert, eyvert; - TString chname; - Int_t ierflg = 0; - - TMinuit *gMinuit = new TMinuit(5); - gMinuit->mninit(5,10,7); - gMinuit->SetFCN(fcnfwrap); // 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(fcnfitfwrap); - - 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) - -//___________________________________________ -AliMUONcluster::AliMUONcluster(Int_t *clhits) -{ - fHitNumber=clhits[0]; - fCathode=clhits[1]; - fQ=clhits[2]; - fPadX=clhits[3]; - fPadY=clhits[4]; - fQpad=clhits[5]; - fRSec=clhits[6]; -} -ClassImp(AliMUONdigit) -//_____________________________________________________________________________ -AliMUONdigit::AliMUONdigit(Int_t *digits) -{ - // - // Creates a MUON digit object to be updated - // - fPadX = digits[0]; - fPadY = digits[1]; - fSignal = digits[2]; - fPhysics = digits[3]; - fHit = digits[4]; - -} -//_____________________________________________________________________________ -AliMUONdigit::AliMUONdigit(Int_t *tracks, Int_t *charges, Int_t *digits) -{ - // - // Creates a MUON digit object - // - 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 ich, Int_t *digits): - AliMUONdigit(digits) -{ - // - // Creates a MUON digit list object - // - - fChamber = ich; - fTrackList = new TObjArray; - -} - -ClassImp(AliMUONhit) - -//___________________________________________ - AliMUONhit::AliMUONhit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits): - AliHit(shunt, track) -{ - fChamber=vol[0]; - fParticle=hits[0]; - fX=hits[1]; - fY=hits[2]; - fZ=hits[3]; - fTheta=hits[4]; - fPhi=hits[5]; - fTlength=hits[6]; - fEloss=hits[7]; - fPHfirst=(Int_t) hits[8]; - fPHlast=(Int_t) hits[9]; - - // 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) -{ - /* - AliMUONRawCluster *raw=(AliMUONRawCluster *)obj; - Float_t r=GetRadius(); - Float_t ro=raw->GetRadius(); - if (r>ro) return 1; - else if (rfY; - if (y>yo) return 1; - else if (y1) { - half=(high+low)/2; - if(y>coord[half]) low=half; - else high=half; - } - return low; -} - -void AliMUONRawCluster::SortMin(Int_t *idx,Float_t *xdarray,Float_t *xarray,Float_t *yarray,Float_t *qarray, Int_t ntr) -{ - // - // 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 -#include -#include -#include -#include -typedef enum {simple, medium, big} Cluster_t; - -static const int NCH=14; - -class AliMUONcluster; +#include "AliMUONTriggerCircuit.h" // cp + +static const int kNCH=14; +static const int kNTrackingCh=10; +static const int kNTriggerCh=4; +static const int kNTriggerCircuit=234; + +class AliMUONChamber; +class AliMUONLocalTrigger; +class AliMUONGlobalTrigger; +class AliMUONTriggerCircuit; +class AliMUONTriggerDecision; +class AliMUONSegmentation; +class AliMUONResponse; +class AliMUONHit; +class AliMUONPadHit; class AliMUONRawCluster; class AliMUONClusterFinder; -class AliMUONcorrelation; - - -//---------------------------------------------- - - -class AliMUONcluster : public TObject { -public: - - Int_t fHitNumber; // Hit number - Int_t fCathode; // Cathode number - Int_t fQ ; // Total charge - Int_t fPadX ; // Pad number along X - Int_t fPadY ; // Pad number along Y - Int_t fQpad ; // Charge per pad - Int_t fRSec ; // R -sector of pad - -public: - AliMUONcluster() { - fHitNumber=fQ=fPadX=fPadY=fQpad=fRSec=0; -} - AliMUONcluster(Int_t *clhits); - virtual ~AliMUONcluster() {;} - - ClassDef(AliMUONcluster,1) //Cluster object for set:MUON -}; - - -class AliMUONreccluster : 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 - -public: - AliMUONreccluster() { - fTracks[0]=fTracks[1]=fTracks[2]=-1; - fQ=0; fX=fY=0; - } - virtual ~AliMUONreccluster() {;} - - ClassDef(AliMUONreccluster,1) //Cluster object for set:MUON -}; - -//_____________________________________________________________________________ - -class AliMUONdigit : public TObject { - public: - 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]; // primary tracks making this digit (up to 10) - Int_t fPhysics; // physics contribution to signal - Int_t fHit; // hit number - temporary solution - - - - public: - AliMUONdigit() {} - AliMUONdigit(Int_t *digits); - AliMUONdigit(Int_t *tracks, Int_t *charges, Int_t *digits); - virtual ~AliMUONdigit(); - - ClassDef(AliMUONdigit,1) //Digits for set:MUON -}; -//_____________________________________________________________________________ - -class AliMUONlist : public AliMUONdigit { - public: - Int_t fChamber; // chamber number of pad - TObjArray *fTrackList; - public: - AliMUONlist() {fTrackList=0;} - AliMUONlist(Int_t rpad, Int_t *digits); - virtual ~AliMUONlist() {delete fTrackList;} - TObjArray *TrackList() {return fTrackList;} - ClassDef(AliMUONlist,1) //Digits for set:MUON -}; -//___________________________________________ +class AliMUONReconstHit; +class TVector; +class TObjArray; +class TFile; +class TTree; -//___________________________________________ - -class AliMUONhit : public AliHit { - public: - Int_t fChamber; // Chamber number - 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 ~AliMUONhit() {} - - ClassDef(AliMUONhit,1) //Hits object for set:MUON -}; - class AliMUON : public AliDetector { public: AliMUON(); AliMUON(const char *name, const char *title); + AliMUON(const AliMUON& rMUON); virtual ~AliMUON(); - 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 AddCathCorrel(Int_t, Int_t*, Float_t*, Float_t*); + virtual void AddHit(Int_t track , Int_t *vol, Float_t *hits); + virtual void AddPadHit(Int_t* clhits); + virtual void AddDigits(Int_t id, Int_t* tracks, Int_t* charges, + Int_t* digits); + virtual void AddRawCluster(Int_t id, const AliMUONRawCluster& clust); virtual void BuildGeometry(); - virtual void CreateGeometry() {} - virtual void CreateMaterials() {} - virtual void StepManager(); + void AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus, + Int_t *singleUndef, Int_t *pairUnlike, + Int_t *pairLike); + void AddLocalTrigger(Int_t* ltrigger); Int_t DistancetoPrimitive(Int_t px, Int_t py); - virtual Int_t IsVersion() const =0; -// - TClonesArray *Clusters() {return fClusters;} - virtual void MakeTreeC(Option_t *option="C"); - void GetTreeC(Int_t); + virtual Int_t IsVersion() const {return 0;} + TClonesArray *PadHits() {return fPadHits;} + TClonesArray *LocalTrigger() {return fLocalTrigger;} + TClonesArray *GlobalTrigger() {return fGlobalTrigger;} virtual void MakeBranch(Option_t *opt=" "); void SetTreeAddress(); virtual void ResetHits(); virtual void ResetDigits(); + virtual void ResetTrigger(); virtual void ResetRawClusters(); - virtual void ResetCorrelation(); - virtual void FindClusters(Int_t,Int_t); - virtual void Digitise(Int_t,Int_t,Option_t *opt1=" ",Option_t *opt2=" ",Text_t *name=" "); - virtual void CathodeCorrelation(Int_t); - virtual void SortTracks(Int_t *,Int_t *,Int_t); -// -// modifs perso - - void InitTracking(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 CloseTracking(); - 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 - + // Cluster Finding + virtual void FindClusters(Int_t event ,Int_t lastEntry); + // Digitisation + virtual void Digitise(Int_t nev,Int_t bgrEvent, Option_t *opt1=" ", + Option_t *opt2=" ",Text_t *name=" "); + virtual void SortTracks(Int_t *tracks,Int_t *charges, Int_t ntr); // Configuration Methods (per station id) // // Set Chamber Segmentation Parameters -// id refers to the station and isec to the cathode plane - virtual void SetPADSIZ(Int_t id, Int_t isec, Float_t p1, Float_t p2); - +// id refers to the station and isec to the cathode plane +// Set Z values for all chambers + virtual void SetChambersZ(const Float_t *Z); + virtual void SetChambersZToDefault(void); + virtual void SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2); // Set Signal Generation Parameters 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 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); @@ -209,46 +94,49 @@ class AliMUON : public AliDetector { 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); + virtual void MakePadHits(Float_t xhit,Float_t yhit, + Float_t eloss, Float_t tof, Int_t id); +// get Trigger answer + void Trigger(Int_t nev); // Return reference to Chamber #id - virtual AliMUONchamber& Chamber(Int_t id) {return *((AliMUONchamber *) (*fChambers)[id]);} + virtual AliMUONChamber& Chamber(Int_t id) + {return *((AliMUONChamber *) (*fChambers)[id]);} +// Return reference to Circuit #id + virtual AliMUONTriggerCircuit& TriggerCircuit(Int_t id) + {return *((AliMUONTriggerCircuit *) (*fTriggerCircuits)[id]);} // Retrieve pad hits for a given Hit - virtual AliMUONcluster* FirstPad(AliMUONhit *, TClonesArray *); - virtual AliMUONcluster* NextPad(TClonesArray *); -// Return pointers to digits + virtual AliMUONPadHit* FirstPad(AliMUONHit *hit, TClonesArray *padHits); + virtual AliMUONPadHit* NextPad(TClonesArray *padHits); +// Return pointers to digits TObjArray *Dchambers() {return fDchambers;} Int_t *Ndch() {return fNdch;} - virtual TClonesArray *DigitsAddress(Int_t id) {return ((TClonesArray *) (*fDchambers)[id]);} + virtual TClonesArray *DigitsAddress(Int_t id) + {return ((TClonesArray *) (*fDchambers)[id]);} // Return pointers to reconstructed clusters 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); + Int_t *Nrawch() {return fNrawch;} + virtual TClonesArray *RawClustAddress(Int_t id) + {return ((TClonesArray *) (*fRawClusters)[id]);} + + AliMUONRawCluster *RawCluster(Int_t ichamber, Int_t icathod, + Int_t icluster); +// Copy Operator + AliMUON& operator = (const AliMUON& rhs); - - // 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]);} - -// 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 *fTriggerCircuits; // List of Trigger Circuits + Int_t fNPadHits; // Number of pad hits + TClonesArray *fPadHits; // List of pad hits TObjArray *fDchambers; // List of digits Int_t *fNdch; // Number of digits - - - 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 + TObjArray *fRawClusters; // List of raw clusters + Int_t *fNrawch; // Number of raw clusters + Int_t fNLocalTrigger; // Number of Local Trigger + TClonesArray *fLocalTrigger; // List of Local Trigger + Int_t fNGlobalTrigger; // Number of Global Trigger + TClonesArray *fGlobalTrigger; // List of Global Trigger // Bool_t fAccCut; //Transport acceptance cut @@ -261,84 +149,20 @@ class AliMUON : public AliDetector { Float_t fMaxStepAlu; // Maximum step size inside the chamber aluminum Float_t fMaxDestepGas; // Maximum relative energy loss in gas Float_t fMaxDestepAlu; // Maximum relative energy loss in aluminum -// -// modifs perso -// Parameters for reconstruction program - Double_t fSPxzCut; // Pxz cut (GeV/c) to begin the track finding - Double_t fSSigmaCut; // Number of sig. delimiting the searching areas - Double_t fSXPrec; // Chamber precision in X (cm) - Double_t fSYPrec; // Chamber precision in Y (cm) - Text_t *fFileName; - - protected: - ClassDef(AliMUON,1) //Hits manager for set:MUON -}; -//___________________________________________ -class AliMUONRawCluster : public TObject { -public: +// Pad Iterator + Int_t fMaxIterPad; // Maximum pad index + Int_t fCurIterPad; // Current pad index +// Background eent for event mixing + Text_t *fFileName; // File with background hits + TTree *fTrH1; // Hits Tree for background event + TClonesArray *fHits2; // List of hits for one track only + TClonesArray *fPadHits2; // List of clusters for one track only - 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 kTRUE;} - 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 + ClassDef(AliMUON,1) //Hits manager for set:MUON }; - #endif diff --git a/MUON/AliMUONChamber.cxx b/MUON/AliMUONChamber.cxx new file mode 100644 index 00000000000..29b3a4734f8 --- /dev/null +++ b/MUON/AliMUONChamber.cxx @@ -0,0 +1,163 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ +/* +$Log$ +Revision 1.1.2.5 2000/06/09 21:27:01 morsch +Most coding rule violations corrected. + +Revision 1.1.2.4 2000/05/05 11:34:12 morsch +Log inside comments. + +Revision 1.1.2.3 2000/05/05 10:09:52 morsch +Log messages included +*/ + +#include "AliMUONChamber.h" +#include "AliMUONSegmentation.h" +#include "AliMUONResponse.h" + +#include "TMath.h" +ClassImp(AliMUONChamber) + + AliMUONChamber::AliMUONChamber() +{ + fSegmentation = new TObjArray(2); + (*fSegmentation)[0] = 0; + (*fSegmentation)[1] = 0; + fResponse=0; + fnsec=1; + fReconstruction=0; +} + +AliMUONChamber::~AliMUONChamber() +{ + if (fSegmentation) delete fSegmentation; +} + +AliMUONChamber::AliMUONChamber(const AliMUONChamber& rChamber) +{ +// Dummy copy constructor + ; +} + + +void AliMUONChamber::Init() +{ +// Initalisation .. +// +// ... for chamber segmentation + if ((*fSegmentation)[0]) + ((AliMUONSegmentation *) (*fSegmentation)[0])->Init(this); + + if (fnsec==2) { + if ((*fSegmentation)[1]) + ((AliMUONSegmentation *) (*fSegmentation)[1])->Init(this); + } +} + +Int_t AliMUONChamber::SigGenCond(Float_t x, Float_t y, Float_t z) +{ +// Ask segmentation if signal should be generated + 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)) ; + } +} + + +void AliMUONChamber::SigGenInit(Float_t x, Float_t y, Float_t z) +{ +// +// Initialisation of segmentation for hit +// + 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) ; + } +} + +void AliMUONChamber::DisIntegration(Float_t eloss, Float_t tof, + 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; // total charge + newclust[1][nnew]=segmentation->Ix(); // ix-position of pad + newclust[2][nnew]=segmentation->Iy(); // iy-position of pad + newclust[3][nnew]=qp * qtot; // charge on pad + newclust[4][nnew]=segmentation->ISector(); // sector id + newclust[5][nnew]=(Float_t) i; // counter + nnew++; + } + } // Pad loop + } // 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; +} + + +AliMUONChamber & AliMUONChamber::operator =(const AliMUONChamber& rhs) +{ +// Dummy assignment operator + return *this; +} diff --git a/MUON/AliMUONChamber.h b/MUON/AliMUONChamber.h new file mode 100644 index 00000000000..001a817656d --- /dev/null +++ b/MUON/AliMUONChamber.h @@ -0,0 +1,128 @@ +#ifndef ALIMUONCHAMBER_H +#define ALIMUONCHAMBER_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include "TObjArray.h" +#include "AliMUONSegmentation.h" +#include "AliMUONResponse.h" + +class AliMUONClusterFinder; +//class AliMUONResponse ; +//class AliMUONSegmentation ; + +class AliMUONChamber: +public TObject +{ + public: + AliMUONChamber(); + AliMUONChamber(const AliMUONChamber & rChamber); + virtual ~AliMUONChamber(); + +// +// Get GEANT id of sensitive volume + virtual Int_t GetGid() {return fGid;} +// Set GEANT id of sensitive volume + virtual void SetGid(Int_t id) {fGid=id;} +// +// Initialisation + virtual void Init(); +// Set z-position of chamber + virtual void SetZ(Float_t Z) {fZ = Z;} +// Get z-position of chamber + virtual Float_t Z(){return fZ;} +// Set inner radius of sensitive volume + virtual void SetRInner(Float_t rmin) {frMin=rmin;} +// Set outer radius of sensitive volum + virtual void SetROuter(Float_t rmax) {frMax=rmax;} + +// Return inner radius of sensitive volume + virtual Float_t RInner() {return frMin;} +// Return outer radius of sensitive volum + virtual Float_t ROuter() {return frMax;} +// +// Set response model + virtual void SetResponseModel(AliMUONResponse* thisResponse) {fResponse=thisResponse;} +// +// Set segmentation model + virtual void SetSegmentationModel(Int_t i, AliMUONSegmentation* thisSegmentation) { + (*fSegmentation)[i-1] = thisSegmentation; + } +// Set Cluster reconstruction model + virtual void SetReconstructionModel(AliMUONClusterFinder *thisReconstruction) { + fReconstruction = thisReconstruction; + } +// +// Get pointer to response model + virtual AliMUONResponse* &ResponseModel(){return fResponse;} +// +// Get reference to segmentation model + virtual AliMUONSegmentation* SegmentationModel(Int_t isec) { + return (AliMUONSegmentation *) (*fSegmentation)[isec-1]; + } + virtual TObjArray* ChamberSegmentation() {return fSegmentation;} +// Get pointer to cluster reconstruction model + virtual AliMUONClusterFinder* &ReconstructionModel(){return fReconstruction;} +// Get number of segmentation sectors + virtual Int_t Nsec() {return fnsec;} +// Set number of segmented cathodes (1 or 2) + virtual void SetNsec(Int_t nsec) {fnsec=nsec;} +// +// Member function forwarding to the segmentation and response models +// +// Calculate pulse height from energy loss + virtual Float_t IntPH(Float_t eloss) {return fResponse->IntPH(eloss);} +// +// Ask segmentation if signal should be generated + virtual Int_t SigGenCond(Float_t x, Float_t y, Float_t z); +// +// Initialisation of segmentation for hit + virtual void SigGenInit(Float_t x, Float_t y, Float_t z); +// Configuration forwarding +// +// Define signal distribution region +// by number of sigmas of the distribution function + virtual void SetSigmaIntegration(Float_t p1) + {fResponse->SetSigmaIntegration(p1);} +// Set the single electron pulse-height (ADCchan/e) + virtual void SetChargeSlope(Float_t p1) {fResponse->SetChargeSlope(p1);} +// Set width of charge distribution function + virtual void SetChargeSpread(Float_t p1, Float_t p2) {fResponse->SetChargeSpread(p1,p2);} +// Set maximum ADC count value + virtual void SetMaxAdc(Float_t p1) {fResponse->SetMaxAdc(p1);} +// Set Pad size + virtual void SetPadSize(Int_t isec, Float_t p1, Float_t p2) { + ((AliMUONSegmentation*) (*fSegmentation)[isec-1])->SetPadSize(p1,p2); + } +// +// Cluster formation method (charge disintegration) + virtual void DisIntegration(Float_t eloss, Float_t tof, + Float_t xhit, Float_t yhit, + Int_t& x, Float_t newclust[6][500]); +// Initialize geometry related parameters + virtual void InitGeo(Float_t z); +// + virtual Float_t DGas() {return fdGas;} + virtual Float_t DAlu() {return fdAlu;} +// assignment operator + virtual AliMUONChamber& operator =(const AliMUONChamber& rhs); + + protected: + + Float_t fdGas; // half gaz gap + Float_t fdAlu; // half Alu width + Int_t fGid; // GEANT volume if for sensitive volume of this chamber + Float_t fZ; // Z position (cm) + Int_t fnsec; // number of semented cathode planes + Float_t frMin; // innermost sensitive radius + Float_t frMax; // outermost sensitive radius + + TObjArray *fSegmentation; // pointer to segmentation + AliMUONClusterFinder *fReconstruction; // pointer to reconstruction + AliMUONResponse *fResponse; // pointer to response + ClassDef(AliMUONChamber,1) // Muon tracking and trigger chamber class +}; + +#endif diff --git a/MUON/AliMUONChamberTrigger.cxx b/MUON/AliMUONChamberTrigger.cxx new file mode 100644 index 00000000000..0ae5613b7ed --- /dev/null +++ b/MUON/AliMUONChamberTrigger.cxx @@ -0,0 +1,126 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.3 2000/06/09 21:27:35 morsch +Most coding rule violations corrected. + +Revision 1.1.2.2 2000/04/26 12:28:25 morsch +- flag pad hits with condition on ToF (CP) +- Tof included in the method DisIntegration (CP) + +Revision 1.1.2.1 2000/02/17 14:30:54 morsch +Draft version + +*/ + +#include "AliMUONChamberTrigger.h" +#include "AliMUONSegmentationTrigger.h" +#include "AliMUONResponseTrigger.h" +#include +#include +#include + +ClassImp(AliMUONChamberTrigger) + +//------------------------------------------- +AliMUONChamberTrigger::AliMUONChamberTrigger() : AliMUONChamber() +{ +// Default Constructor +} + +//------------------------------------------- +void AliMUONChamberTrigger::DisIntegration(Float_t eloss, Float_t tof, + 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 + + Int_t twentyNano; + if (tof<75*pow(10,-9)) { + twentyNano=1; + } else { + twentyNano=100; + } + + // cout << " time = " << tof << " , " << twentyNano << "\n"; + + Float_t qp; + nnew=0; + for (Int_t i=1; i<=fnsec; i++) { + AliMUONSegmentation * segmentation= + (AliMUONSegmentation*) (*fSegmentation)[i-1]; + +// Find the module & strip Id. which has fired + Int_t ix,iy; + + segmentation->GetPadIxy(xhit,yhit,ix,iy); + segmentation->SetPad(ix,iy); + +// treatment of GEANT hits w/o corresponding strip (due to the fact that +// the 2 geometries are computed in a very slightly different way) + if (ix==0&&iy==0) { + cout << " AliMUONChamberTrigger hit w/o strip " << xhit << " , " << yhit << "\n"; + } else { + // --- store signal information for this strip + newclust[0][nnew]=1.; // total charge + newclust[1][nnew]=ix; // ix-position of pad + newclust[2][nnew]=iy; // iy-position of pad + newclust[3][nnew]=twentyNano; // time of flight + newclust[4][nnew]=segmentation->ISector(); // sector id + newclust[5][nnew]=(Float_t) i; // counter + nnew++; + // set hits + segmentation->SetHit(xhit,yhit); + // get the list of nearest neighbours + Int_t nList, xList[2], yList[2]; + segmentation->Neighbours(ix,iy,&nList,xList,yList); + + for (Int_t j=0; jGetPadCxy(xList[j],yList[j],x,y); + // set pad (fx fy & fix fiy are the current pad coord. & Id.) + segmentation->SetPad(xList[j],yList[j]); + // get the chamber (i.e. current strip) response + qp=fResponse->IntXY(segmentation); + + if (qp > 0.5) { + // --- store signal information for neighbours + newclust[0][nnew]=qp; // total charge + newclust[1][nnew]=segmentation->Ix(); // ix-position of pad + newclust[2][nnew]=segmentation->Iy(); // iy-position of pad + newclust[3][nnew]=twentyNano; // time of flight + newclust[4][nnew]=segmentation->ISector(); // sector id + newclust[5][nnew]=(Float_t) i; // counter + nnew++; + } // qp > 0.5 + } // loop on neighbour + } // endif hit w/o strip + } // loop over planes +} + + + + + + + + diff --git a/MUON/AliMUONChamberTrigger.h b/MUON/AliMUONChamberTrigger.h new file mode 100644 index 00000000000..1664ca1240e --- /dev/null +++ b/MUON/AliMUONChamberTrigger.h @@ -0,0 +1,40 @@ +#ifndef ALIMUONCHAMBERTRIGGER_H +#define ALIMUONCHAMBERTRIGGER_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include "AliMUONChamber.h" + + +class AliMUONClusterFinder; +class AliMUONSegmentationTrigger ; +class AliMUONResponseTrigger ; + +class AliMUONChamberTrigger: +public AliMUONChamber { + public: + AliMUONChamberTrigger(); + virtual ~AliMUONChamberTrigger(){} +// Cluster formation method (charge disintegration) + + virtual void DisIntegration(Float_t eloss, Float_t tof, Float_t xhit, Float_t yhit, + Int_t& nnew, Float_t newclust[6][500]); + + ClassDef(AliMUONChamberTrigger,1) // Muon trigger chamber class + }; +#endif + + + + + + + + + + + + diff --git a/MUON/AliMUONClusterFinder.cxx b/MUON/AliMUONClusterFinder.cxx index 2ba034763b0..430946beaac 100644 --- a/MUON/AliMUONClusterFinder.cxx +++ b/MUON/AliMUONClusterFinder.cxx @@ -15,38 +15,57 @@ /* $Log$ +Revision 1.4.4.2 2000/06/09 21:58:15 morsch +Most coding rule violations corrected. + */ #include "AliMUONClusterFinder.h" -#include "TTree.h" +#include "AliMUON.h" +#include "AliMUONHitMap.h" +#include "AliMUONHitMapA1.h" +#include "AliMUONSegmentation.h" +#include "AliMUONResponse.h" +#include "AliMUONDigit.h" +#include "AliMUONRawCluster.h" #include "AliRun.h" + + +#include #include #include +#include #include #include #include #include +#include + +//_____________________________________________________________________ +static AliMUONSegmentation* fgSegmentation; +static AliMUONResponse* fgResponse; +static Int_t fgix[500]; +static Int_t fgiy[500]; +static Float_t fgCharge[500]; +static Int_t fgNbins; +static Int_t fgFirst=kTRUE; +static Int_t fgChargeTot; +static Float_t fgQtot; +static TMinuit* fgMyMinuit ; +// This function is minimized in the double-Mathieson fit +void fcn2(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag); +void fcn1(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag); -//---------------------------------------------------------- -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; -//---------------------------------------------------------- ClassImp(AliMUONClusterFinder) AliMUONClusterFinder::AliMUONClusterFinder -(AliMUONsegmentation *segmentation, AliMUONresponse *response, - TClonesArray *digits, Int_t chamber) + (AliMUONSegmentation *segmentation, + AliMUONResponse *response, + TClonesArray *digits, Int_t chamber) { +// Constructor fSegmentation=segmentation; fResponse=response; @@ -64,9 +83,9 @@ ClassImp(AliMUONClusterFinder) AliMUONClusterFinder::AliMUONClusterFinder() { +// Default constructor fSegmentation=0; fResponse=0; - fDigits=0; fNdigits = 0; fChamber=-1; @@ -80,13 +99,33 @@ ClassImp(AliMUONClusterFinder) fNPeaks=-1; } +AliMUONClusterFinder::AliMUONClusterFinder( + const AliMUONClusterFinder & clusterFinder) +{ +// Dummy copy Constructor + ; +} + +AliMUONClusterFinder::~AliMUONClusterFinder() +{ +// Destructor + delete fRawClusters; +} + +void AliMUONClusterFinder::SetDigits(TClonesArray *MUONdigits) +{ +// Set pointer to digits + fDigits=MUONdigits; + fNdigits = fDigits->GetEntriesFast(); +} + void AliMUONClusterFinder::AddRawCluster(const AliMUONRawCluster c) { // // Add a raw cluster copy to the list // - AliMUON *MUON=(AliMUON*)gAlice->GetModule("MUON"); - MUON->AddRawCluster(fChamber,c); + AliMUON *pMUON=(AliMUON*)gAlice->GetModule("MUON"); + pMUON->AddRawCluster(fChamber,c); fNRawClusters++; } @@ -94,15 +133,14 @@ void AliMUONClusterFinder::AddRawCluster(const AliMUONRawCluster c) void AliMUONClusterFinder::Decluster(AliMUONRawCluster *cluster) { -// AliMUONdigit *dig; -// Int_t q; - +// Decluster composite clusters + Bool_t fitted; - Int_t mul = cluster->fMultiplicity; -// printf("Decluster - multiplicity %d \n",mul); - + Int_t mul = cluster->fMultiplicity[0]; if (mul == 1 || mul ==2) { -// printf("\n Nothing special for 1- and 2-clusters \n"); + if (mul==2) { + fitted=SingleMathiesonFit(cluster); + } // // Nothing special for 1- and 2-clusters if (fNPeaks != 0) { @@ -114,15 +152,15 @@ void AliMUONClusterFinder::Decluster(AliMUONRawCluster *cluster) } else if (mul ==3) { // // 3-cluster, check topology -// printf("\n 3-cluster, check topology \n"); +// +// This part could be activated again in the future 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"); - } + if (Centered(cluster)) { + // ok, cluster is centered + fitted = SingleMathiesonFit(cluster); + } else { + // cluster is not centered, split into 2+1 + } } else { if (fNPeaks != 0) { cluster->fNcluster[0]=fNPeaks; @@ -132,44 +170,42 @@ void AliMUONClusterFinder::Decluster(AliMUONRawCluster *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++; - } - } - //} + if (mul <= fClusterSize) { + if (fDeclusterFlag) { + SplitByLocalMaxima(cluster); + } else { + if (fNPeaks != 0) { + cluster->fNcluster[0]=fNPeaks; + cluster->fNcluster[1]=0; + } + fitted=SingleMathiesonFit(cluster); + AddRawCluster(*cluster); + fNPeaks++; + } // if Declustering selected + } // if < maximum clustersize for deconvolution } // multiplicity } Bool_t AliMUONClusterFinder::Centered(AliMUONRawCluster *cluster) { - AliMUONdigit* dig; - dig= (AliMUONdigit*)fDigits->UncheckedAt(cluster->fIndexMap[0]); +// True if cluster is centered + AliMUONDigit* dig; + dig= (AliMUONDigit*)fDigits->UncheckedAt(cluster->fIndexMap[0][0]); Int_t ix=dig->fPadX; Int_t iy=dig->fPadY; Int_t nn; - Int_t X[kMaxNeighbours], Y[kMaxNeighbours], XN[kMaxNeighbours], YN[kMaxNeighbours]; + Int_t x[kMaxNeighbours], y[kMaxNeighbours], xN[kMaxNeighbours], yN[kMaxNeighbours]; - fSegmentation->Neighbours(ix,iy,&nn,X,Y); + fSegmentation->Neighbours(ix,iy,&nn,x,y); Int_t nd=0; for (Int_t i=0; iTestHit(X[i],Y[i]) == used) { - XN[nd]=X[i]; - YN[nd]=Y[i]; + if (fHitMap->TestHit(x[i],y[i]) == kUsed) { + xN[nd]=x[i]; + yN[nd]=y[i]; nd++; } } @@ -179,41 +215,41 @@ Bool_t AliMUONClusterFinder::Centered(AliMUONRawCluster *cluster) if (fNPeaks != 0) { cluster->fNcluster[0]=fNPeaks; cluster->fNcluster[1]=0; - } + } AddRawCluster(*cluster); fNPeaks++; return kTRUE; - } else if (nd ==1) { + } 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; + Int_t nind=fHitMap->GetHitIndex(xN[0], yN[0]); + Int_t i1= (nind==cluster->fIndexMap[1][0]) ? 1:2; + Int_t i2= (nind==cluster->fIndexMap[1][0]) ? 2:1; // // 2-cluster AliMUONRawCluster cnew; if (fNPeaks == 0) { - cnew.fNcluster[0]=-1; + 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]; + cnew.fMultiplicity[0]=2; + cnew.fIndexMap[0][0]=cluster->fIndexMap[0][0]; + cnew.fIndexMap[1][0]=cluster->fIndexMap[i1][0]; 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; + cluster->fMultiplicity[0]=1; + cluster->fIndexMap[0][0]=cluster->fIndexMap[i2][0]; + cluster->fIndexMap[1][0]=0; + cluster->fIndexMap[2][0]=0; FillCluster(cluster); if (fNPeaks != 0) { cluster->fNcluster[0]=fNPeaks; @@ -225,304 +261,176 @@ Bool_t AliMUONClusterFinder::Centered(AliMUONRawCluster *cluster) return kFALSE; } else { printf("\n Completely screwed up %d !! \n",nd); - } - return kFALSE; + 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; +// Search for local maxima and split cluster accordingly + Bool_t fitted; + + AliMUONDigit* digt; + Int_t i; // loops over digits + Int_t j; // loops over local maxima + fMul=c->fMultiplicity[0]; // // dump digit information into arrays // - for (i=0; iUncheckedAt(c->fIndexMap[i]); - ix[i]= dig[i]->fPadX; - iy[i]= dig[i]->fPadY; - q[i] = dig[i]->fSignal; - fSegmentation->GetPadCxy(ix[i], iy[i], x[i], y[i]); + fDig[i]= (AliMUONDigit*)fDigits->UncheckedAt(c->fIndexMap[i][0]); + fIx[i]= fDig[i]->fPadX; + fIy[i]= fDig[i]->fPadY; + fQ[i] = fDig[i]->fSignal; + fSegmentation->GetPadCxy(fIx[i], fIy[i], fX[i], fY[i]); } // // Find local maxima // - Bool_t IsLocal[100]; - Int_t NLocal=0; - Int_t AssocPeak[100]; - Int_t IndLocal[100]; + fNLocal=0; + Bool_t isLocal[100]; + Int_t assocPeak[100]; Int_t nn; - Int_t X[kMaxNeighbours], Y[kMaxNeighbours]; - for (i=0; iNeighbours(ix[i], iy[i], &nn, X, Y); - IsLocal[i]=kTRUE; + Int_t x[kMaxNeighbours], y[kMaxNeighbours]; + for (i=0; iNeighbours(fIx[i], fIy[i], &nn, x, y); + isLocal[i]=kTRUE; for (j=0; jTestHit(X[j],Y[j])==empty) continue; - digt=(AliMUONdigit*) fHitMap->GetHit(X[j], Y[j]); - if (digt->fSignal > q[i]) { - IsLocal[i]=kFALSE; + if (fHitMap->TestHit(x[j], y[j])==kEmpty) continue; + digt=(AliMUONDigit*) fHitMap->GetHit(x[j], y[j]); + if (digt->fSignal > fQ[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; kfSignal == fQ[i]) { + if (fNLocal >0) { + for (Int_t k=0; k12) { +// 12 should not be hard wired but a parameter +// + if (fNLocal==1 && fMul>=1) { Int_t nnew=0; - for (i=0; iSetFCN(fcn); - gMyMinuit->mninit(5,10,7); - Double_t arglist[20]; - Int_t ierflag=0; - arglist[0]=1; -// gMyMinuit->mnexcm("SET ERR",arglist,1,ierflag); -// Set starting values - static Double_t vstart[5]; - vstart[0]=x[IndLocal[0]]; - vstart[1]=y[IndLocal[0]]; - vstart[2]=x[IndLocal[1]]; - vstart[3]=y[IndLocal[1]]; - vstart[4]=Float_t(q[IndLocal[0]])/ - Float_t(q[IndLocal[0]]+q[IndLocal[1]]); -// lower and upper limits - static Double_t lower[5], upper[5]; - Int_t isec=fSegmentation->Sector(ix[IndLocal[0]], iy[IndLocal[0]]); - lower[0]=vstart[0]-fSegmentation->Dpx(isec)/2; - lower[1]=vstart[1]-fSegmentation->Dpy(isec)/2; -// lower[1]=vstart[1]; - - upper[0]=lower[0]+fSegmentation->Dpx(isec); - upper[1]=lower[1]+fSegmentation->Dpy(isec); -// upper[1]=vstart[1]; - - isec=fSegmentation->Sector(ix[IndLocal[1]], iy[IndLocal[1]]); - lower[2]=vstart[2]-fSegmentation->Dpx(isec)/2; - lower[3]=vstart[3]-fSegmentation->Dpy(isec)/2; -// lower[3]=vstart[3]; - - upper[2]=lower[2]+fSegmentation->Dpx(isec); - upper[3]=lower[3]+fSegmentation->Dpy(isec); -// upper[3]=vstart[3]; - - lower[4]=0.; - upper[4]=1.; -// step sizes - static Double_t step[5]={0.005, 0.03, 0.005, 0.03, 0.01}; - - gMyMinuit->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag); - gMyMinuit->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag); - gMyMinuit->mnparm(2,"x2",vstart[2],step[2],lower[2],upper[2],ierflag); - gMyMinuit->mnparm(3,"y2",vstart[3],step[3],lower[3],upper[3],ierflag); - gMyMinuit->mnparm(4,"a0",vstart[4],step[4],lower[4],upper[4],ierflag); -// ready for minimisation - gMyMinuit->SetPrintLevel(-1); - gMyMinuit->mnexcm("SET OUT", arglist, 0, ierflag); - arglist[0]= -1; - arglist[1]= 0; - - gMyMinuit->mnexcm("SET NOGR", arglist, 0, ierflag); - gMyMinuit->mnexcm("SCAN", arglist, 0, ierflag); - gMyMinuit->mnexcm("EXIT" , arglist, 0, ierflag); -// Print results -// Double_t amin,edm,errdef; -// Int_t nvpar,nparx,icstat; -// gMyMinuit->mnstat(amin,edm,errdef,nvpar,nparx,icstat); -// gMyMinuit->mnprin(3,amin); -// Get fitted parameters - Double_t xrec[2], yrec[2], qfrac; - TString chname; - Double_t epxz, b1, b2; - Int_t ierflg; - gMyMinuit->mnpout(0, chname, xrec[0], epxz, b1, b2, ierflg); - gMyMinuit->mnpout(1, chname, yrec[0], epxz, b1, b2, ierflg); - gMyMinuit->mnpout(2, chname, xrec[1], epxz, b1, b2, ierflg); - gMyMinuit->mnpout(3, chname, yrec[1], epxz, b1, b2, ierflg); - gMyMinuit->mnpout(4, chname, qfrac, epxz, b1, b2, ierflg); - printf("\n %f %f %f %f %f\n", xrec[0], yrec[0], xrec[1], yrec[1],qfrac); -// delete gMyMinuit; - - - // - // One cluster for each maximum - // - for (j=0; j<2; j++) { - AliMUONRawCluster cnew; - if (fNPeaks == 0) { - cnew.fNcluster[0]=-1; - cnew.fNcluster[1]=fNRawClusters; - } else { - cnew.fNcluster[0]=fNPeaks; - cnew.fNcluster[1]=0; - } - cnew.fMultiplicity=0; - cnew.fX=Float_t(xrec[j]); - cnew.fY=Float_t(yrec[j]); - if (j==0) { - cnew.fQ=Int_t(gChargeTot*qfrac); - } else { - cnew.fQ=Int_t(gChargeTot*(1-qfrac)); - } - gSegmentation->SetHit(xrec[j],yrec[j]); - for (i=0; ifIndexMap[i]; - gSegmentation->SetPad(gix[i], giy[i]); - Float_t q1=gResponse->IntXY(gSegmentation); - cnew.fContMap[cnew.fMultiplicity]=Float_t(q[i])/(q1*cnew.fQ); - cnew.fMultiplicity++; - } - FillCluster(&cnew,0); - //printf("\n x,y %f %f ", cnew.fX, cnew.fY); - cnew.fClusterType=cnew.PhysicsContribution(); - AddRawCluster(cnew); - fNPeaks++; - } - } - - Bool_t fitted=kTRUE; - - 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 fNperMax) { + Int_t nGlob=fMul/fNperMax-fNLocal+1; + if (nGlob > 0) { + Int_t nnew=0; + for (i=0; iqmax) { - dmin=d; - qmax=ql; - AssocPeak[i]=j; - } - } - } - } - - - // - // One cluster for each maximum - // - for (j=0; jfIndexMap[IndLocal[j]]; - cnew.fMultiplicity=1; - for (i=0; ifIndexMap[i]; - cnew.fMultiplicity++; - } - } - FillCluster(&cnew); - cnew.fClusterType=cnew.PhysicsContribution(); - AddRawCluster(cnew); - fNPeaks++; - } - } - + if (ql>qmax) { + dmin=d; + qmax=ql; + assocPeak[i]=j; + } + } + } + } + // + // One cluster for each maximum + // + for (j=0; jfIndexMap[fIndLocal[j]][0]; + cnew.fMultiplicity[0]=1; + for (i=0; ifIndexMap[i][0]; + cnew.fMultiplicity[0]++; + } + } + FillCluster(&cnew); + cnew.fClusterType=cnew.PhysicsContribution(); + AddRawCluster(cnew); + fNPeaks++; + } + } } @@ -531,92 +439,77 @@ void AliMUONClusterFinder::FillCluster(AliMUONRawCluster* c, Int_t flag) // // Completes cluster information starting from list of digits // - AliMUONdigit* dig; + AliMUONDigit* dig; Float_t x, y; Int_t ix, iy; Float_t frac=0; - c->fPeakSignal=0; + c->fPeakSignal[0]=0; if (flag) { - c->fX=0; - c->fY=0; - c->fQ=0; + c->fX[0]=0; + c->fY[0]=0; + c->fQ[0]=0; } - //c->fQ=0; - for (Int_t i=0; ifMultiplicity; i++) + for (Int_t i=0; ifMultiplicity[0]; i++) { - dig= (AliMUONdigit*)fDigits->UncheckedAt(c->fIndexMap[i]); - ix=dig->fPadX+c->fOffsetMap[i]; + dig= (AliMUONDigit*)fDigits->UncheckedAt(c->fIndexMap[i][0]); + ix=dig->fPadX+c->fOffsetMap[i][0]; iy=dig->fPadY; Int_t q=dig->fSignal; if (dig->fPhysics >= dig->fSignal) { - c->fPhysicsMap[i]=2; + c->fPhysicsMap[i]=2; } else if (dig->fPhysics == 0) { - c->fPhysicsMap[i]=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]; - } + if (q>c->fPeakSignal[0]) { + c->fPeakSignal[0]=q; + 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 (c->fContMap[i][0] > frac) { + frac=c->fContMap[i][0]; + c->fPeakSignal[0]=q; + 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; + c->fX[0] += q*x; + c->fY[0] += q*y; + c->fQ[0] += q; } - } // loop over digits - - if (flag) { - - c->fX/=c->fQ; - c->fX=fSegmentation->GetAnod(c->fX); - c->fY/=c->fQ; + + if (flag) { + c->fX[0]/=c->fQ[0]; + c->fX[0]=fSegmentation->GetAnod(c->fX[0]); + c->fY[0]/=c->fQ[0]; // // 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); - } - } + x=c->fX[0]; + y=c->fY[0]; + 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[0]-y)/fSegmentation->Dpy(isec); + c->fY[0]=c->fY[0]-cogCorr->Eval(yOnPad, 0, 0); + } + } } @@ -627,18 +520,11 @@ void AliMUONClusterFinder::FindCluster(Int_t i, Int_t j, AliMUONRawCluster &c){ // // Add i,j as element of the cluster // - Int_t idx = fHitMap->GetHitIndex(i,j); - AliMUONdigit* dig = (AliMUONdigit*) fHitMap->GetHit(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; + if (q > TMath::Abs(c.fPeakSignal[0])) { + c.fPeakSignal[0]=q; c.fTracks[0]=dig->fHit; c.fTracks[1]=dig->fTracks[0]; c.fTracks[2]=dig->fTracks[1]; @@ -646,54 +532,54 @@ void AliMUONClusterFinder::FindCluster(Int_t i, Int_t j, AliMUONRawCluster &c){ // // Make sure that list of digits is ordered // - Int_t mu=c.fMultiplicity; - c.fIndexMap[mu]=idx; - + Int_t mu=c.fMultiplicity[0]; + c.fIndexMap[mu][0]=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 + Int_t ist=(c.fIndexMap)[ind][0]; + Int_t ql=((AliMUONDigit*)fDigits ->UncheckedAt(ist))->fSignal; if (q>ql) { - c.fIndexMap[ind]=idx; - c.fIndexMap[ind+1]=ist; + c.fIndexMap[ind][0]=idx; + c.fIndexMap[ind+1][0]=ist; } else { break; } } } - c.fMultiplicity++; + c.fMultiplicity[0]++; - if (c.fMultiplicity >= 50 ) { - printf("FindCluster - multiplicity >50 %d \n",c.fMultiplicity); - c.fMultiplicity=49; + if (c.fMultiplicity[0] >= 50 ) { + printf("FindCluster - multiplicity >50 %d \n",c.fMultiplicity[0]); + c.fMultiplicity[0]=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; + c.fX[0] += q*x; + c.fY[0] += q*y; + c.fQ[0] += 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); + Int_t xList[kMaxNeighbours], yList[kMaxNeighbours]; + fSegmentation->Neighbours(i,j,&nn,xList,yList); for (Int_t in=0; inTestHit(ix,iy)==unused) FindCluster(ix, iy, c); + Int_t ix=xList[in]; + Int_t iy=yList[in]; + if (fHitMap->TestHit(ix,iy)==kUnused) FindCluster(ix, iy, c); } } @@ -705,76 +591,67 @@ 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; + AliMUONDigit *dig; Int_t ndig; Int_t nskip=0; Int_t ncls=0; fHitMap->FillHits(); for (ndig=0; ndigUncheckedAt(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) { + if (fHitMap->TestHit(i,j)==kUsed ||fHitMap->TestHit(i,j)==kEmpty) { 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.fMultiplicity[0]=0; + c.fPeakSignal[0]=dig->fSignal; 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; + // 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; + c.fX[0] /= c.fQ[0]; + c.fX[0]=fSegmentation->GetAnod(c.fX[0]); + c.fY[0] /= c.fQ[0]; // // apply correction to the coordinate along the anode wire // Int_t ix,iy; - Float_t x=c.fX; - Float_t y=c.fY; + Float_t x=c.fX[0]; + Float_t y=c.fY[0]; 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); + TF1* cogCorr=fSegmentation->CorrFunc(isec-1); + if (cogCorr) { + Float_t yOnPad=(c.fY[0]-y)/fSegmentation->Dpy(isec); + c.fY[0]=c.fY[0]-cogCorr->Eval(yOnPad,0,0); } - // // Analyse cluster and decluster if necessary // - ncls++; - c.fNcluster[1]=fNRawClusters; - c.fClusterType=c.PhysicsContribution(); - Decluster(&c); - fNPeaks=0; + ncls++; + c.fNcluster[1]=fNRawClusters; + c.fClusterType=c.PhysicsContribution(); + Decluster(&c); + fNPeaks=0; // // // // reset Cluster object - for (int k=0;kGetPadIxy(x,y,ix,iy); segmentation->GetPadCxy(ix,iy,x,y); @@ -824,7 +702,7 @@ SinoidalFit(Float_t x, Float_t y, TF1 &func) // Integration Limits Float_t dxI=fResponse->SigmaIntegration()*fResponse->ChargeSpreadX(); Float_t dyI=fResponse->SigmaIntegration()*fResponse->ChargeSpreadY(); - + // // Scanning // @@ -833,9 +711,9 @@ SinoidalFit(Float_t x, Float_t y, TF1 &func) // // y-position Float_t yscan=ymin; - Float_t dy=segmentation->Dpy(isec)/(ns-1); + Float_t dy=segmentation->Dpy(isec)/(kns-1); - for (i=0; iDpx(isec)/(ns-1); - - for (i=0; iDpx(isec)/(kns-1); + + for (i=0; iFit("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(); + 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"); +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"); - +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"); +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(); */ } +Bool_t AliMUONClusterFinder::SingleMathiesonFit(AliMUONRawCluster *c) +{ +// +// Initialise global variables for fit + Int_t i; + fMul=c->fMultiplicity[0]; + fgSegmentation=fSegmentation; + fgResponse =fResponse; + fgNbins=fMul; + Float_t qtot=0; +// +// dump digit information into arrays +// + for (i=0; iUncheckedAt(c->fIndexMap[i][0]); + fIx[i]= fDig[i]->fPadX; + fIy[i]= fDig[i]->fPadY; + fQ[i] = fDig[i]->fSignal; + fSegmentation->GetPadCxy(fIx[i], fIy[i], fX[i], fY[i]); + fgix[i]=fIx[i]; + fgiy[i]=fIy[i]; + fgCharge[i]=Float_t(fQ[i]); + qtot+=fgCharge[i]; + } + + fgQtot=qtot; + fgChargeTot=Int_t(qtot); + +// + if (fgFirst) { + fgFirst=kFALSE; + fgMyMinuit = new TMinuit(5); + } + + fgMyMinuit->SetFCN(fcn1); + fgMyMinuit->mninit(2,10,7); + Double_t arglist[20]; + Int_t ierflag=0; + arglist[0]=1; +// fgMyMinuit->mnexcm("SET ERR",arglist,1,ierflag); +// Set starting values + static Double_t vstart[2]; + vstart[0]=c->fX[0]; + vstart[1]=c->fY[0]; +// lower and upper limits + static Double_t lower[2], upper[2]; + Int_t ix,iy; + fSegmentation->GetPadIxy(c->fX[0], c->fY[0], ix, iy); + Int_t isec=fSegmentation->Sector(ix, iy); + lower[0]=vstart[0]-fSegmentation->Dpx(isec)/2; + lower[1]=vstart[1]-fSegmentation->Dpy(isec)/2; + + upper[0]=lower[0]+fSegmentation->Dpx(isec); + upper[1]=lower[1]+fSegmentation->Dpy(isec); + +// step sizes + static Double_t step[2]={0.0005, 0.0005}; + + fgMyMinuit->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag); + fgMyMinuit->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag); +// ready for minimisation + fgMyMinuit->SetPrintLevel(1); + fgMyMinuit->mnexcm("SET OUT", arglist, 0, ierflag); + arglist[0]= -1; + arglist[1]= 0; + + fgMyMinuit->mnexcm("SET NOGR", arglist, 0, ierflag); + fgMyMinuit->mnexcm("MIGRAD", arglist, 0, ierflag); + fgMyMinuit->mnexcm("EXIT" , arglist, 0, ierflag); +// Print results +// Get fitted parameters + Double_t xrec, yrec; + TString chname; + Double_t epxz, b1, b2; + Int_t ierflg; + fgMyMinuit->mnpout(0, chname, xrec, epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(1, chname, yrec, epxz, b1, b2, ierflg); + c->fX[0]=xrec; + c->fY[0]=yrec; + return kTRUE; +} + +Bool_t AliMUONClusterFinder::DoubleMathiesonFit(AliMUONRawCluster *c) +{ +// +// Initialise global variables for fit + Int_t i,j; + + fgSegmentation=fSegmentation; + fgResponse =fResponse; + fgNbins=fMul; + Float_t qtot=0; + + for (i=0; iSetFCN(fcn2); + fgMyMinuit->mninit(5,10,7); + Double_t arglist[20]; + Int_t ierflag=0; + arglist[0]=1; +// fgMyMinuit->mnexcm("SET ERR",arglist,1,ierflag); +// Set starting values + static Double_t vstart[5]; + vstart[0]=fX[fIndLocal[0]]; + vstart[1]=fY[fIndLocal[0]]; + vstart[2]=fX[fIndLocal[1]]; + vstart[3]=fY[fIndLocal[1]]; + vstart[4]=Float_t(fQ[fIndLocal[0]])/ + Float_t(fQ[fIndLocal[0]]+fQ[fIndLocal[1]]); +// lower and upper limits + static Double_t lower[5], upper[5]; + Int_t isec=fSegmentation->Sector(fIx[fIndLocal[0]], fIy[fIndLocal[0]]); + lower[0]=vstart[0]-fSegmentation->Dpx(isec); + lower[1]=vstart[1]-fSegmentation->Dpy(isec); + + upper[0]=lower[0]+2.*fSegmentation->Dpx(isec); + upper[1]=lower[1]+2.*fSegmentation->Dpy(isec); + + isec=fSegmentation->Sector(fIx[fIndLocal[1]], fIy[fIndLocal[1]]); + lower[2]=vstart[2]-fSegmentation->Dpx(isec)/2; + lower[3]=vstart[3]-fSegmentation->Dpy(isec)/2; + + upper[2]=lower[2]+fSegmentation->Dpx(isec); + upper[3]=lower[3]+fSegmentation->Dpy(isec); + + lower[4]=0.; + upper[4]=1.; +// step sizes + static Double_t step[5]={0.0005, 0.0005, 0.0005, 0.0005, 0.01}; + + fgMyMinuit->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag); + fgMyMinuit->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag); + fgMyMinuit->mnparm(2,"x2",vstart[2],step[2],lower[2],upper[2],ierflag); + fgMyMinuit->mnparm(3,"y2",vstart[3],step[3],lower[3],upper[3],ierflag); + fgMyMinuit->mnparm(4,"a0",vstart[4],step[4],lower[4],upper[4],ierflag); +// ready for minimisation + fgMyMinuit->SetPrintLevel(-1); + fgMyMinuit->mnexcm("SET OUT", arglist, 0, ierflag); + arglist[0]= -1; + arglist[1]= 0; + + fgMyMinuit->mnexcm("SET NOGR", arglist, 0, ierflag); + fgMyMinuit->mnexcm("MIGRAD", arglist, 0, ierflag); + fgMyMinuit->mnexcm("EXIT" , arglist, 0, ierflag); +// Get fitted parameters + Double_t xrec[2], yrec[2], qfrac; + TString chname; + Double_t epxz, b1, b2; + Int_t ierflg; + fgMyMinuit->mnpout(0, chname, xrec[0], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(1, chname, yrec[0], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(2, chname, xrec[1], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(3, chname, yrec[1], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(4, chname, qfrac, epxz, b1, b2, ierflg); + + Double_t fmin, fedm, errdef; + Int_t npari, nparx, istat; + + fgMyMinuit->mnstat(fmin, fedm, errdef, npari, nparx, istat); + + printf("\n fmin %f \n", fmin); + +// +// One cluster for each maximum +// + for (j=0; j<2; j++) { + AliMUONRawCluster cnew; + cnew.fChi2[0]=Float_t(fmin); + + if (fNPeaks == 0) { + cnew.fNcluster[0]=-1; + cnew.fNcluster[1]=fNRawClusters; + } else { + cnew.fNcluster[0]=fNPeaks; + cnew.fNcluster[1]=0; + } + cnew.fMultiplicity[0]=0; + cnew.fX[0]=Float_t(xrec[j]); + cnew.fY[0]=Float_t(yrec[j]); + if (j==0) { + cnew.fQ[0]=Int_t(fgChargeTot*qfrac); + } else { + cnew.fQ[0]=Int_t(fgChargeTot*(1-qfrac)); + } + fgSegmentation->SetHit(xrec[j],yrec[j]); + for (i=0; ifIndexMap[i][0]; + fgSegmentation->SetPad(fgix[i], fgiy[i]); + Float_t q1=fgResponse->IntXY(fgSegmentation); + cnew.fContMap[cnew.fMultiplicity[0]][0]=(q1*cnew.fQ[0])/Float_t(fQ[i]); + cnew.fMultiplicity[0]++; + } + FillCluster(&cnew,0); + cnew.fClusterType=cnew.PhysicsContribution(); + AddRawCluster(cnew); + fNPeaks++; + } + return kTRUE; +} + +AliMUONClusterFinder& AliMUONClusterFinder +::operator = (const AliMUONClusterFinder& rhs) +{ +// Dummy assignment operator + return *this; +} + + Double_t sinoid(Double_t *x, Double_t *par) { Double_t arg = -2*TMath::Pi()*x[0]; @@ -995,7 +1096,22 @@ Double_t DoubleGauss(Double_t *x, Double_t *par) return fitval; } -Float_t DiscrCharge(Int_t i,Double_t *par) +Float_t DiscrCharge1(Int_t i,Double_t *par) +{ +// par[0] x-position of cluster +// par[1] y-position of cluster + + fgSegmentation->SetPad(fgix[i], fgiy[i]); +// First Cluster + fgSegmentation->SetHit(par[0],par[1]); + Float_t q1=fgResponse->IntXY(fgSegmentation); + + Float_t value = fgQtot*q1; + return value; +} + + +Float_t DiscrCharge2(Int_t i,Double_t *par) { // par[0] x-position of first cluster // par[1] y-position of first cluster @@ -1004,33 +1120,23 @@ Float_t DiscrCharge(Int_t i,Double_t *par) // 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; jbinSetPad(gix[i], giy[i]); + fgSegmentation->SetPad(fgix[i], fgiy[i]); // First Cluster - gSegmentation->SetHit(par[0],par[1]); - Float_t q1=gResponse->IntXY(gSegmentation); + fgSegmentation->SetHit(par[0],par[1]); + Float_t q1=fgResponse->IntXY(fgSegmentation); // Second Cluster - gSegmentation->SetHit(par[2],par[3]); - Float_t q2=gResponse->IntXY(gSegmentation); + fgSegmentation->SetHit(par[2],par[3]); + Float_t q2=fgResponse->IntXY(fgSegmentation); - Float_t value = qtot*(par[4]*q1+(1.-par[4])*q2); - return value; + Float_t value = fgQtot*(par[4]*q1+(1.-par[4])*q2); + return value; } // -// Minimisation function -void fcn(Int_t &, Double_t *, Double_t &f, Double_t *par, Int_t ) +// Minimisation functions +// Single Mathieson +void fcn1(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag) { Int_t i; Float_t delta; @@ -1038,15 +1144,36 @@ void fcn(Int_t &, Double_t *, Double_t &f, Double_t *par, Int_t ) Float_t qcont=0; Float_t qtot=0; - for (i=0; iGetEntriesFast(); - } - +// Set current chamber id virtual void SetChamber(Int_t ich){ fChamber=ich; } - - virtual void AddRawCluster(const AliMUONRawCluster); - // Search for raw clusters +// Add a new raw cluster + virtual void AddRawCluster(const AliMUONRawCluster cluster); +// Search for raw clusters virtual void FindRawClusters(); +// Find cluster virtual void FindCluster(Int_t i, Int_t j, AliMUONRawCluster &c); - // Decluster +// Decluster virtual void Decluster(AliMUONRawCluster *cluster); - // Set max. Number of pads per local cluster +// Set max. number of pads per local cluster virtual void SetNperMax(Int_t npermax=5) {fNperMax = npermax;} - // Decluster ? +// Decluster ? virtual void SetDeclusterFlag(Int_t flag=1) {fDeclusterFlag =flag;} - // Set max. cluster size ; bigger clusters will be rejected +// Set max. cluster size ; bigger clusters will deconvoluted virtual void SetClusterSize(Int_t clsize=5) {fClusterSize = clsize;} - // Self Calibration of COG +// Self Calibration of COG virtual void CalibrateCOG(); +// Perform fit to sinoidal function virtual void SinoidalFit(Float_t x, Float_t y, TF1 &func); - // +// virtual void CorrectCOG(){;} - - // +// True if 3-cluster is centred virtual Bool_t Centered(AliMUONRawCluster *cluster); +// Perform split by local maxima virtual void SplitByLocalMaxima(AliMUONRawCluster *cluster); - virtual void FillCluster(AliMUONRawCluster *cluster, Int_t); +// Perform Double Mathieson Fit + Bool_t DoubleMathiesonFit(AliMUONRawCluster *c); + Bool_t SingleMathiesonFit(AliMUONRawCluster *c); +// Build up full cluster information + virtual void FillCluster(AliMUONRawCluster *cluster, Int_t n); virtual void FillCluster(AliMUONRawCluster *cluster) { FillCluster(cluster,1);} + virtual void SetTracks(Int_t, Int_t) {;} + virtual Bool_t TestTrack(Int_t) {return kTRUE;} + +// Return pointer to raw clusters TClonesArray* RawClusters(){return fRawClusters;} +// Assignment operator + AliMUONClusterFinder & operator = (const AliMUONClusterFinder& rhs); + +protected: + TClonesArray* fDigits; // Digits + Int_t fNdigits; // Number of Digits + AliMUONSegmentation* fSegmentation; // Chamber segmentation + AliMUONResponse* fResponse; // Chamber Response + TClonesArray* fRawClusters; // Raw Clusters + Int_t fChamber; // Chamber Number + Int_t fNRawClusters; // Number of Raw Clusters + AliMUONHitMapA1* fHitMap; // Hit Map + TF1* fCogCorr; // Systematic correction function + Int_t fNperMax; // Maximum number of pads per + // local maximum + Int_t fDeclusterFlag; // flaf for declusterin + Int_t fClusterSize; // cluster size + Int_t fNPeaks; // number of local maxima +// Current cluster + AliMUONDigit* fDig[100]; // current list of digits + Int_t fIx[100]; // current list of x-pad-coord. + Int_t fIy[100]; // current list of y-pad-coord. + Float_t fX[100]; // current list of x-coord. + Float_t fY[100]; // current list of y-coord. + Int_t fIndLocal[100]; // indices of local maxima + Int_t fNLocal; // Number of local maxima + Int_t fQ[100]; // current list of charges + Int_t fMul; // current multiplicity ClassDef(AliMUONClusterFinder,1) //Class for clustering and reconstruction of space points }; #endif diff --git a/MUON/AliMUONClusterFinderV0.cxx b/MUON/AliMUONClusterFinderV0.cxx new file mode 100644 index 00000000000..afb38f61d5b --- /dev/null +++ b/MUON/AliMUONClusterFinderV0.cxx @@ -0,0 +1,758 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +#include "AliMUONClusterFinderV0.h" +#include "AliMUONSegResV1.h" +//#include "TTree.h" +//#include "AliRun.h" +//#include +//#include +//#include +//#include + +//---------------------------------------------------------- +ClassImp(AliMUONClusterFinderV0) + + AliMUONClusterFinderV0::AliMUONClusterFinderV0 +(AliMUONSegmentation *segmentation, AliMUONResponse *response, + TClonesArray *digits, Int_t chamber) : AliMUONClusterFinder(segmentation,response,digits,chamber) +{;} + + AliMUONClusterFinderV0::AliMUONClusterFinderV0():AliMUONClusterFinder() +{;} + +/* +void AliMUONClusterFinder::AddRawCluster(const AliMUONRawCluster c) +{ + // + // Add a raw cluster copy to the list + // + AliMUON *MUON=(AliMUON*)gAlice->GetModule("MUON"); + MUON->AddRawCluster(fChamber,c); + fNRawClusters++; +} +*/ + + + +void AliMUONClusterFinderV0::Decluster(AliMUONRawCluster *cluster) +{ +// AliMUONDigit *dig; +// Int_t q; + static int done=0; + if (!done) { + printf("Calling decluster\n"); + done=1; + } + + + + Int_t mul = cluster->fMultiplicity; +// printf("Decluster - multiplicity %d \n",mul); + + if (mul == 1) { +// printf("\n Nothing special for 1-clusters \n"); +// +// Nothing special for 1-clusters +// + AddRawCluster(*cluster); + } else if (mul ==2) { +// +// 2-cluster, compute offset +// + SetOffset(cluster); + FillCluster(cluster); + AddRawCluster(*cluster); + } else if (mul ==3) { +// +// 3-cluster, check topology +// printf("\n 3-cluster, check topology \n"); +// + if (Centered(cluster)) { +// +// ok, cluster is centered +// printf("\n ok, cluster is centered \n"); + } else { +// +// cluster is not centered, split into 2+1 +// printf("\n cluster is not centered, split into 2+1 \n"); + } + + } else { + if (mul >(50-5)) printf("Decluster - multiplicity %d approaching 50\n",mul); +// +// 4-and more-pad clusters +// + SplitByLocalMaxima(cluster); + } // multiplicity +} + +Int_t AliMUONClusterFinderV0::PeakOffsetAndCoordinates(Int_t DigitIndex, Float_t *X, Float_t *Y) +// +// Computes for which allowed offsets the digit has the highest neighbouring charge +// Returns the value of the offset, and sets the pyisical coordinates of that pad +// Loop on physical neighbours is specific to AliMUONSegmentationV1 +{ +Int_t nPara, offset, returnOffset=0 ; +AliMUONDigit* dig= (AliMUONDigit*)fDigits->UncheckedAt(DigitIndex); +AliMUONSegmentationV1* seg = (AliMUONSegmentationV1*) fSegmentation; +seg->GetNParallelAndOffset(dig->fPadX,dig->fPadY,&nPara,&offset); +if (nPara>1) + { + Float_t qMax=0; + for (Int_t i=0;ifPadY+dy; + Int_t padX=seg->Ix((Int_t) (dig->fPadX+dx+i*offset) , padY); + if (fHitMap->TestHit(padX, padY)==empty) + continue; + AliMUONDigit* digt = (AliMUONDigit*) fHitMap->GetHit(padX,padY); + q += digt->fSignal; + } + if (q>qMax) + { + returnOffset=i*offset; + qMax=q; + } + } + } +fSegmentation->GetPadCxy(dig->fPadX+returnOffset,dig->fPadY,*X,*Y); +return returnOffset; +} + + +void AliMUONClusterFinderV0::SetOffset(AliMUONRawCluster *cluster) +// compute the offsets assuming that there is only one peak ! +{ +//DumpCluster(cluster); +Float_t X,Y; +cluster->fOffsetMap[0]=PeakOffsetAndCoordinates(cluster->fIndexMap[0],&X,&Y); +for (Int_t i=1;ifMultiplicity;i++) { + AliMUONDigit* dig= (AliMUONDigit*)fDigits->UncheckedAt(cluster->fIndexMap[i]); + fSegmentation->Distance2AndOffset(dig->fPadX,dig->fPadY,X,Y,&(cluster->fOffsetMap[i])); + } +} + +void AliMUONClusterFinderV0::DumpCluster(AliMUONRawCluster *cluster) +{ +printf ("other cluster\n"); +for (Int_t i=0; ifMultiplicity; i++) + { + AliMUONDigit* dig= (AliMUONDigit*)fDigits->UncheckedAt(cluster->fIndexMap[i]); + Int_t nPara, offset; + fSegmentation->GetNParallelAndOffset(dig->fPadX,dig->fPadY,&nPara,&offset); + + printf("X %d Y %d Q %d NPara %d \n",dig->fPadX, dig->fPadY,dig->fSignal, nPara); + } +} + +Bool_t AliMUONClusterFinderV0::Centered(AliMUONRawCluster *cluster) +{ + AliMUONDigit* dig; + dig= (AliMUONDigit*)fDigits->UncheckedAt(cluster->fIndexMap[0]); + Int_t ix=dig->fPadX; + Int_t iy=dig->fPadY; + Int_t nn; + Int_t X[kMaxNeighbours], Y[kMaxNeighbours], XN[kMaxNeighbours], YN[kMaxNeighbours]; + fSegmentation->Neighbours(ix,iy,&nn,X,Y); + + Int_t nd=0; + for (Int_t i=0; iTestHit(X[i],Y[i]) == used) { + XN[nd]=X[i]; + YN[nd]=Y[i]; + nd++; + } + } + if (nd==2) { +// +// cluster is centered ! + SetOffset(cluster); + FillCluster(cluster); + AddRawCluster(*cluster); + return kTRUE; + } else if (nd ==1) { +// +// Highest signal on an edge, split cluster into 2+1 +// +// who is the neighbour ? + Int_t nind=fHitMap->GetHitIndex(XN[0], YN[0]); + Int_t i1= (nind==cluster->fIndexMap[1]) ? 1:2; + Int_t i2= (nind==cluster->fIndexMap[1]) ? 2:1; +// +// 2-cluster + AliMUONRawCluster cnew; + cnew.fMultiplicity=2; + cnew.fIndexMap[0]=cluster->fIndexMap[0]; + cnew.fIndexMap[1]=cluster->fIndexMap[i1]; + SetOffset(&cnew); + FillCluster(&cnew); + AddRawCluster(cnew); +// +// 1-cluster + cluster->fMultiplicity=1; + cluster->fIndexMap[0]=cluster->fIndexMap[i2]; + cluster->fIndexMap[1]=0; + cluster->fIndexMap[2]=0; + FillCluster(cluster); + AddRawCluster(*cluster); + return kFALSE; + } else { + printf("\n Completely screwed up %d !! \n",nd); + + } + + return kFALSE; +} + + +void AliMUONClusterFinderV0::SplitByLocalMaxima(AliMUONRawCluster *c) +{ + AliMUONDigit* dig[50], *digt; + Int_t ix[50], iy[50], q[50]; + Float_t x[50], y[50]; + Int_t i; // loops over digits + Int_t j; // loops over local maxima + + Int_t mul=c->fMultiplicity; +// +// dump digit information into arrays +// + for (i=0; iUncheckedAt(c->fIndexMap[i]); + ix[i]= dig[i]->fPadX; + iy[i]= dig[i]->fPadY; + q[i] = dig[i]->fSignal; + fSegmentation->GetPadCxy(ix[i], iy[i], x[i], y[i]); + } +// +// Find local maxima +// + Bool_t IsLocal[50]; + Int_t NLocal=0; + Int_t AssocPeak[50]; + Int_t IndLocal[50]; + Int_t nn; + Int_t X[kMaxNeighbours], Y[kMaxNeighbours]; + for (i=0; iNeighbours(ix[i], iy[i], &nn, X, Y); + IsLocal[i]=kTRUE; + for (j=0; jTestHit(X[j], Y[j])==empty) continue; + digt=(AliMUONDigit*) fHitMap->GetHit(X[j], Y[j]); + if (digt->fSignal > q[i]) { + IsLocal[i]=kFALSE; + break; +// +// handle special case of neighbouring pads with equal signal + } else if (digt->fSignal == q[i]) { + if (NLocal >0) { + for (Int_t k=0; kfOffsetMap[i]=PeakOffsetAndCoordinates(c->fIndexMap[i], &(x[i]), &(y[i])); + NLocal++; + } + } // loop over all digits +// printf("Found %d local Maxima",NLocal); +// +// Associate hits to peaks +// + for (i=0; iDistance2AndOffset(ix[i],iy[i],x[il],y[il], &offset); + Float_t ql=q[il]; +// +// Select nearest peak +// + if (dfOffsetMap[i]=offset; + } else if (d==dmin) { +// +// If more than one take highest peak +// + if (ql>qmax) { + dmin=d; + qmax=ql; + AssocPeak[i]=j; + c->fOffsetMap[i]=offset; + } + } // end if + } // End loop on peaks + } // end loop on digits +// +// One cluster for each maximum +// + for (j=0; jfIndexMap[IndLocal[j]]; + cnew.fOffsetMap[0]=c->fOffsetMap[IndLocal[j]]; + cnew.fMultiplicity=1; + for (i=0; ifIndexMap[i]; + cnew.fOffsetMap[cnew.fMultiplicity]=c->fOffsetMap[i]; + cnew.fMultiplicity++; + } + } + FillCluster(&cnew); + AddRawCluster(cnew); + } +} + +/* +void AliMUONClusterFinderV0::FillCluster(AliMUONRawCluster* c) +{ +// +// Completes cluster information starting from list of digits +// + AliMUONDigit* dig; + Float_t x, y; + Int_t ix, iy; + + c->fPeakSignal=0; + c->fX=0; + c->fY=0; + c->fQ=0; + for (Int_t i=0; ifMultiplicity; i++) + { + dig= (AliMUONDigit*)fDigits->UncheckedAt(c->fIndexMap[i]); + ix=dig->fPadX + c.fOffsetMap[i]; // should be 0 for non-LYON + iy=dig->fPadY; + Int_t q=dig->fSignal; +// +// +// peak signal and track list + if (q>c->fPeakSignal) { + c->fPeakSignal=0; + c->fTracks[0]=dig->fTracks[0]; + c->fTracks[1]=dig->fTracks[1]; + c->fTracks[2]=dig->fTracks[2]; + } +// +// centre of gravity + fSegmentation->GetPadCxy(ix, iy, x, y); + c->fX += q*x; + c->fY += q*y; + c->fQ += q; + } + c->fX/=c->fQ; +// Not valid for inclined tracks in X !!! (Manu) +// c->fX=fSegmentation->GetAnod(c->fX); + c->fY/=c->fQ; +// +// apply correction to the coordinate along the anode wire +// + if (fCogCorr) { + x=c->fX; + y=c->fY; + fSegmentation->GetPadIxy(x, y, ix, iy); + fSegmentation->GetPadCxy(ix, iy, x, y); + Float_t YonPad=(c->fY-y)/fSegmentation->Dpy(); + c->fY=y-fCogCorr->Eval(YonPad, 0, 0); + } + +} +*/ +/* +void AliMUONClusterFinder::FindCluster(Int_t i, Int_t j, AliMUONRawCluster &c){ +// +// Find clusters +// +// +// Add i,j as element of the cluster +// + + Int_t idx = fHitMap->GetHitIndex(i,j); + AliMUONDigit* dig = (AliMUONDigit*) fHitMap->GetHit(i,j); + Int_t q=dig->fSignal; + if (q > TMath::Abs(c.fPeakSignal)) { + c.fPeakSignal=q; + c.fTracks[0]=dig->fTracks[0]; + c.fTracks[1]=dig->fTracks[1]; + c.fTracks[2]=dig->fTracks[2]; + } +// +// Make sure that list of digits is ordered +// + Int_t mu=c.fMultiplicity; + c.fIndexMap[mu]=idx; + + if (mu > 0) { + for (Int_t ind=mu-1; ind>=0; ind--) { + Int_t ist=(c.fIndexMap)[ind]; + Int_t ql=((AliMUONDigit*)fDigits + ->UncheckedAt(ist))->fSignal; + if (q>ql) { + c.fIndexMap[ind]=idx; + c.fIndexMap[ind+1]=ist; + } else { + break; + } + } + } + + c.fMultiplicity++; + + if (c.fMultiplicity >= 50 ) { + printf("FindCluster - multiplicity >50 %d \n",c.fMultiplicity); + c.fMultiplicity=50-1; + } + +// Prepare center of gravity calculation + Float_t x, y; + fSegmentation->GetPadCxy(i, j, x, y); + c.fX += q*x; + c.fY += q*y; + c.fQ += q; +// Flag hit as taken + fHitMap->FlagHit(i,j); +// +// Now look recursively for all neighbours +// + Int_t nn; + Int_t Xlist[kMaxNeighbours], Ylist[kMaxNeighbours]; + fSegmentation->Neighbours(i,j,&nn,Xlist,Ylist); + for (Int_t in=0; inTestHit(ix,iy)==unused) FindCluster(ix, iy, c); + } +} +*/ + +//_____________________________________________________________________________ + +void AliMUONClusterFinderV0::FindRawClusters() +{ + // + // simple MUON cluster finder from digits -- finds neighbours and + // fill the tree with raw clusters + // + if (!fNdigits) return; + + fHitMap = new AliMUONHitMapA1(fSegmentation, fDigits); + + AliMUONDigit *dig; + + int ndig; + int nskip=0; + + fHitMap->FillHits(); + for (ndig=0; ndigUncheckedAt(ndig); + Int_t i=dig->fPadX; + Int_t j=dig->fPadY; + if (fHitMap->TestHit(i,j)==used ||fHitMap->TestHit(i,j)==empty) { + nskip++; + continue; + } + AliMUONRawCluster c; + c.fMultiplicity=0; +// c.fPeakSignal=dig->fSignal; +// c.fTracks[0]=dig->fTracks[0]; +// c.fTracks[1]=dig->fTracks[1]; +// c.fTracks[2]=dig->fTracks[2]; + c.fPeakSignal=0; + FindCluster(i,j, c); + // center of gravity + c.fX /= c.fQ; + c.fX=fSegmentation->GetAnod(c.fX); + c.fY /= c.fQ; +// +// apply correction to the coordinate along the anode wire +// + + + if (fCogCorr) { + Int_t ix,iy; + Float_t x=c.fX; + Float_t y=c.fY; + fSegmentation->GetPadIxy(x, y, ix, iy); + fSegmentation->GetPadCxy(ix, iy, x, y); + Float_t YonPad=(c.fY-y)/fSegmentation->Dpy(); + c.fY=y-fCogCorr->Eval(YonPad,0,0); + } +// +// Analyse cluster and decluster if necessary +// + Decluster(&c); +// +// +// +// reset Cluster object + for (int k=0;kGiveTestPoints(n, x, y); + for (i=0; iGetPadIxy(x,y,ix,iy); + segmentation->GetPadCxy(ix,iy,x,y); + Int_t isec=segmentation->Sector(ix,iy); +// Pad Limits + Float_t xmin = x-segmentation->GetRealDpx(isec)/2; + Float_t ymin = y-segmentation->Dpy()/2; +// +// Integration Limits + Float_t dxI=fResponse->Nsigma()*fResponse->ChwX(); + Float_t dyI=fResponse->Nsigma()*fResponse->ChwY(); + +// +// Scanning +// + Int_t i; + Float_t qp; +// +// y-position + Float_t yscan=ymin; + Float_t dy=segmentation->Dpy()/(ns-1); + + for (i=0; iSigGenInit(x, yscan, 0); + + for (segmentation->FirstPad(x, yscan, dxI, dyI); + segmentation->MorePads(); + segmentation->NextPad()) + { + qp=fResponse->IntXY(segmentation); + qp=TMath::Abs(qp); +// +// + if (qp > 1.e-4) { + qcheck+=qp; + Int_t ixs=segmentation->Ix(); + Int_t iys=segmentation->Iy(); + Float_t xs,ys; + segmentation->GetPadCxy(ixs,iys,xs,ys); + sum+=qp*ys; + } + } // Pad loop + Float_t ycog=sum/qcheck; + yg[i]=(yscan-y)/segmentation->Dpy(); + yrg[i]=(ycog-y)/segmentation->Dpy(); + ysig[i]=ycog-yscan; + yscan+=dy; + } // scan loop +// +// x-position + Float_t xscan=xmin; + Float_t dx=segmentation->GetRealDpx(isec)/(ns-1); + + for (i=0; iSigGenInit(xscan, y, 0); + + for (segmentation->FirstPad(xscan, y, dxI, dyI); + segmentation->MorePads(); + segmentation->NextPad()) + { + qp=fResponse->IntXY(segmentation); + qp=TMath::Abs(qp); +// +// + if (qp > 1.e-2) { + qcheck+=qp; + Int_t ixs=segmentation->Ix(); + Int_t iys=segmentation->Iy(); + Float_t xs,ys; + segmentation->GetPadCxy(ixs,iys,xs,ys); + sum+=qp*xs; + } + } // Pad loop + Float_t xcog=sum/qcheck; + xcog=segmentation->GetAnod(xcog); + + xg[i]=(xscan-x)/segmentation->GetRealDpx(isec); + xrg[i]=(xcog-x)/segmentation->GetRealDpx(isec); + xsig[i]=xcog-xscan; + xscan+=dx; + } + + TCanvas *c1=new TCanvas(canvasname,canvasname,400,10,600,700); + TPad* pad11 = new TPad("pad11"," ",0.01,0.51,0.49,0.99); + TPad* pad12 = new TPad("pad12"," ",0.51,0.51,0.99,0.99); + TPad* pad13 = new TPad("pad13"," ",0.01,0.01,0.49,0.49); + TPad* pad14 = new TPad("pad14"," ",0.51,0.01,0.99,0.49); + pad11->SetFillColor(11); + pad12->SetFillColor(11); + pad13->SetFillColor(11); + pad14->SetFillColor(11); + pad11->Draw(); + pad12->Draw(); + pad13->Draw(); + pad14->Draw(); + TGraph *graphx = new TGraph(ns,xg ,xsig); + TGraph *graphxr= new TGraph(ns,xrg,xsig); + TGraph *graphy = new TGraph(ns,yg ,ysig); + TGraph *graphyr= new TGraph(ns,yrg,ysig); +// +// Creates a Root function based on function sinoid above +// and perform the fit +// + Double_t sinoid(Double_t *x, Double_t *par); + TF1 *sinoidf = new TF1("sinoidf",sinoid,0.5,0.5,5); + graphyr->Fit("sinoidf","V"); + sinoidf->Copy(func); + func.Eval(0,0,0); +// + pad11->cd(); + graphx->SetFillColor(42); + graphx->SetMarkerColor(4); + graphx->SetMarkerStyle(21); + graphx->Draw("AC"); + graphx->GetHistogram()->SetXTitle("x on pad"); + graphx->GetHistogram()->SetYTitle("xcog-x"); + + + pad12->cd(); + graphxr->SetFillColor(42); + graphxr->SetMarkerColor(4); + graphxr->SetMarkerStyle(21); + graphxr->Draw("AP"); + graphxr->GetHistogram()->SetXTitle("xcog on pad"); + graphxr->GetHistogram()->SetYTitle("xcog-x"); + + + pad13->cd(); + graphy->SetFillColor(42); + graphy->SetMarkerColor(4); + graphy->SetMarkerStyle(21); + graphy->Draw("AF"); + graphy->GetHistogram()->SetXTitle("y on pad"); + graphy->GetHistogram()->SetYTitle("ycog-y"); + + + + pad14->cd(); + graphyr->SetFillColor(42); + graphyr->SetMarkerColor(4); + graphyr->SetMarkerStyle(21); + graphyr->Draw("AF"); + graphyr->GetHistogram()->SetXTitle("ycog on pad"); + graphyr->GetHistogram()->SetYTitle("ycog-y"); + + c1->Update(); + +} +*/ +/* +Double_t sinoid(Double_t *x, Double_t *par) +{ + Double_t arg = -2*TMath::Pi()*x[0]; + Double_t fitval= par[0]*TMath::Sin(arg)+ + par[1]*TMath::Sin(2*arg)+ + par[2]*TMath::Sin(3*arg)+ + par[3]*TMath::Sin(4*arg)+ + par[4]*TMath::Sin(5*arg); + return fitval; + } +*/ + + + + + + + diff --git a/MUON/AliMUONClusterFinderV0.h b/MUON/AliMUONClusterFinderV0.h new file mode 100644 index 00000000000..0a2c22325ee --- /dev/null +++ b/MUON/AliMUONClusterFinderV0.h @@ -0,0 +1,42 @@ +#ifndef AliMUONClusterFinderV0_H +#define AliMUONClusterFinderV0_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +//////////////////////////////////////////////// +// MUON Cluster Finder Class // +//////////////////////////////////////////////// +#include "AliMUONClusterFinder.h" +//#include "TF1.h" + +class AliMUONClusterFinderV0 : +public AliMUONClusterFinder { + public: + AliMUONClusterFinderV0 + (AliMUONSegmentation *segmentation, + AliMUONResponse *response, TClonesArray *digits, Int_t chamber); + AliMUONClusterFinderV0(); + ~AliMUONClusterFinderV0(){delete fRawClusters;} + virtual void FindRawClusters(); + // 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); + // + virtual Bool_t Centered(AliMUONRawCluster *cluster); + virtual void SplitByLocalMaxima(AliMUONRawCluster *cluster); + void AliMUONClusterFinderV0::DumpCluster(class AliMUONRawCluster *); + + + TClonesArray* RawClusters(){return fRawClusters;} + ClassDef(AliMUONClusterFinderV0,1) //Class for clustering and reconstruction of space points +}; +#endif + + + + + + + diff --git a/MUON/AliMUONClusterFinderVS.cxx b/MUON/AliMUONClusterFinderVS.cxx new file mode 100644 index 00000000000..349cf7d34e3 --- /dev/null +++ b/MUON/AliMUONClusterFinderVS.cxx @@ -0,0 +1,1992 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ +/* +$Log$ +Revision 1.1.2.3 2000/06/09 21:58:33 morsch +Most coding rule violations corrected. + +Revision 1.1.2.2 2000/02/15 08:33:52 morsch +Error in calculation of contribution map for double clusters (Split method) corrected (A.M.) +Error in determination of track list for double cluster (FillCluster method) corrected (A.M.) +Revised and extended SplitByLocalMaxima method (Isabelle Chevrot): + - For clusters with more than 2 maxima on one of the cathode planes all valid + combinations of maxima on the two cathodes are preserved. The position of the maxima is + taken as the hit position. + - New FillCluster method with 2 arguments to find tracks associated to the clusters + defined above added. (Method destinction by argument list not very elegant in this case, + should be revides (A.M.) + - Bug in if-statement to handle maximum 1 maximum per plane corrected + - Two cluster per cathode but only 1 combination valid is handled. + - More rigerous treatment of 1-2 and 2-1 combinations of maxima. + +*/ + +#include "AliMUONClusterFinderVS.h" +#include "AliMUONDigit.h" +#include "AliMUONRawCluster.h" +#include "AliMUONSegmentation.h" +#include "AliMUONResponse.h" +#include "AliMUONHitMap.h" +#include "AliMUONHitMapA1.h" +#include "AliRun.h" +#include "AliMUON.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//_____________________________________________________________________ +static AliMUONSegmentation* fgSegmentation[2]; +static AliMUONResponse* fgResponse; +static Int_t fgix[500][2]; +static Int_t fgiy[500][2]; +static Float_t fgCharge[500][2]; +static Int_t fgNbins[2]; +static Int_t fgFirst=kTRUE; +static Int_t fgChargeTot[2]; +static Float_t fgQtot[2]; +static TMinuit* fgMyMinuit ; +// This function is minimized in the double-Mathieson fit +void fcnS2(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag); +void fcnS1(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag); +void fcnCombiS1(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag); +void fcnCombiS2(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag); + +ClassImp(AliMUONClusterFinderVS) + + AliMUONClusterFinderVS::AliMUONClusterFinderVS +(AliMUONSegmentation *seg1, AliMUONSegmentation *seg2, + AliMUONResponse *response, + TClonesArray *digits1, TClonesArray *digits2, + Int_t chamber) + :AliMUONClusterFinder(seg1, response, digits1, chamber) +{ +// Constructor + fSegmentation2=seg2; + fDigits2=digits2; + fNdigits2 = fDigits2->GetEntriesFast(); + fHitMap2=0; + fTrack[0]=fTrack[1]=-1; + +} + + AliMUONClusterFinderVS::AliMUONClusterFinderVS() + :AliMUONClusterFinder() +{ +// Default constructor + fSegmentation2=0; + fDigits2=0; + fNdigits2 = 0; + fHitMap2 = 0; + fTrack[0]=fTrack[1]=-1; +} + +AliMUONClusterFinderVS::AliMUONClusterFinderVS( + const AliMUONClusterFinderVS & clusterFinder) +{ +// Dummy copy Constructor + ; +} + +void AliMUONClusterFinderVS::SetDigits(TClonesArray *MUONdigits1, TClonesArray *MUONdigits2) { +// Set pointers to digit lists + + fDigits=MUONdigits1; + fNdigits = fDigits->GetEntriesFast(); + fDigits2=MUONdigits2; + fNdigits2 = fDigits2->GetEntriesFast(); +} + +// Get Segmentation +AliMUONSegmentation* AliMUONClusterFinderVS::Segmentation(Int_t i) +{ +// Return pointer to segmentation of cathode plane number 1 (i=0) or 2 (i=1) + return ((i==0)? fSegmentation : fSegmentation2); +} + +// Get Number of Digits +Int_t AliMUONClusterFinderVS::NDigits(Int_t i) +{ +// Return number of digits for cathode plane i+1 + return ((i==0)? fNdigits : fNdigits2); +} + +// Get Digits +TClonesArray* AliMUONClusterFinderVS::Digits(Int_t i) +{ +// Return pointer to digits for cathode plane i+1 + return ((i==0)? fDigits : fDigits2); +} + + +AliMUONHitMap* AliMUONClusterFinderVS::HitMap(Int_t i) +{ +// Return pointer to HitMap + return ((i==0)? fHitMap : fHitMap2); +} + +void AliMUONClusterFinderVS::Decluster(AliMUONRawCluster *cluster) +{ +// Decluster by local maxima + SplitByLocalMaxima(cluster); +} + +void AliMUONClusterFinderVS::SplitByLocalMaxima(AliMUONRawCluster *c) +{ +// Split complex cluster by local maxima + + Int_t cath, i; + + fMul[0]=c->fMultiplicity[0]; + fMul[1]=c->fMultiplicity[1]; + +// +// dump digit information into arrays +// + fgSegmentation[0]=Segmentation(0); + fgSegmentation[1]=Segmentation(1); + fgResponse =fResponse; + fgNbins[0]=fMul[0]; + fgNbins[1]=fMul[1]; + Float_t qtot; + + for (cath=0; cath<2; cath++) { + qtot=0; + for (i=0; iUncheckedAt(c->fIndexMap[i][cath])); + // pad coordinates + fIx[i][cath]= fDig[i][cath]->fPadX; + fIy[i][cath]= fDig[i][cath]->fPadY; + // pad charge + fQ[i][cath] = fDig[i][cath]->fSignal; + // pad centre coordinates + Segmentation(cath)-> + GetPadCxy(fIx[i][cath], fIy[i][cath], fX[i][cath], fY[i][cath]); + // globals kUsed in fitting functions + fgix[i][cath]=fIx[i][cath]; + fgiy[i][cath]=fIy[i][cath]; + fgCharge[i][cath]=Float_t(fQ[i][cath]); + // total charge per cluster + qtot+=fgCharge[i][cath]; + } // loop over cluster digits + fgQtot[cath]=qtot; + fgChargeTot[cath]=Int_t(qtot); + } // loop over cathodes + + + FindLocalMaxima(c); + +// +// Initialise and perform mathieson fits + Float_t chi2, oldchi2; +// ++++++++++++++++++*************+++++++++++++++++++++ +// (1) No more than one local maximum per cathode plane +// +++++++++++++++++++++++++++++++*************++++++++ + if ((fNLocal[0]==1 && (fNLocal[1]==0 || fNLocal[1]==1)) || + (fNLocal[0]==0 && fNLocal[1]==1)) { + +// Perform combined single Mathieson fit +// Initial values for coordinates (x,y) + + // One local maximum on cathodes 1 and 2 (X->cathode 2, Y->cathode 1) + if (fNLocal[0]==1 && fNLocal[1]==1) { + fXInit[0]=c->fX[1]; + fYInit[0]=c->fY[0]; + // One local maximum on cathode 1 (X,Y->cathode 1) + } else if (fNLocal[0]==1) { + fXInit[0]=c->fX[0]; + fYInit[0]=c->fY[0]; + // One local maximum on cathode 2 (X,Y->cathode 2) + } else { + fXInit[0]=c->fX[1]; + fYInit[0]=c->fY[1]; + } + fprintf(stderr,"\n cas (1) CombiSingleMathiesonFit(c)\n"); + chi2=CombiSingleMathiesonFit(c); +// Int_t ndf = fgNbins[0]+fgNbins[1]-2; +// Float_t prob = TMath::Prob(Double_t(chi2),ndf); +// prob1->Fill(prob); +// chi2_1->Fill(chi2); + oldchi2=chi2; + fprintf(stderr," chi2 %f ",chi2); + + c->fX[0]=fXFit[0]; + c->fY[0]=fYFit[0]; + + c->fX[1]=fXFit[0]; + c->fY[1]=fYFit[0]; + c->fChi2[0]=chi2; + c->fChi2[1]=chi2; + c->fX[0]=Segmentation(0)->GetAnod(c->fX[0]); + c->fX[1]=Segmentation(1)->GetAnod(c->fX[1]); + +// If reasonable chi^2 add result to the list of rawclusters + // if (chi2 < 50) { + if (chi2 < 0.3) { + AddRawCluster(*c); +// If not try combined double Mathieson Fit + } else { + fprintf(stderr," MAUVAIS CHI2 !!!\n"); + if (fNLocal[0]==1 && fNLocal[1]==1) { + fXInit[0]=fX[fIndLocal[0][1]][1]; + fYInit[0]=fY[fIndLocal[0][0]][0]; + fXInit[1]=fX[fIndLocal[0][1]][1]; + fYInit[1]=fY[fIndLocal[0][0]][0]; + } else if (fNLocal[0]==1) { + fXInit[0]=fX[fIndLocal[0][0]][0]; + fYInit[0]=fY[fIndLocal[0][0]][0]; + fXInit[1]=fX[fIndLocal[0][0]][0]; + fYInit[1]=fY[fIndLocal[0][0]][0]; + } else { + fXInit[0]=fX[fIndLocal[0][1]][1]; + fYInit[0]=fY[fIndLocal[0][1]][1]; + fXInit[1]=fX[fIndLocal[0][1]][1]; + fYInit[1]=fY[fIndLocal[0][1]][1]; + } + +// Initial value for charge ratios + fQrInit[0]=0.5; + fQrInit[1]=0.5; + fprintf(stderr,"\n cas (1) CombiDoubleMathiesonFit(c)\n"); + chi2=CombiDoubleMathiesonFit(c); +// Int_t ndf = fgNbins[0]+fgNbins[1]-6; +// Float_t prob = TMath::Prob(chi2,ndf); +// prob2->Fill(prob); +// chi2_2->Fill(chi2); + +// Was this any better ?? + fprintf(stderr," Old and new chi2 %f %f ", oldchi2, chi2); + if (fFitStat!=0 && chi2>0 && (2.*chi2 < oldchi2)) { + fprintf(stderr," Split\n"); + // Split cluster into two according to fit result + Split(c); + } else { + fprintf(stderr," Don't Split\n"); + // Don't split + AddRawCluster(*c); + } + } + +// +++++++++++++++++++++++++++++++++++++++ +// (2) Two local maxima per cathode plane +// +++++++++++++++++++++++++++++++++++++++ + } else if (fNLocal[0]==2 && fNLocal[1]==2) { +// +// Let's look for ghosts first +// + Float_t xm[4][2], ym[4][2]; + Float_t dpx, dpy, dx, dy; + Int_t ixm[4][2], iym[4][2]; + Int_t isec, im1, im2, ico; +// +// Form the 2x2 combinations +// 0-0, 0-1, 1-0, 1-1 + ico=0; + for (im1=0; im1<2; im1++) { + for (im2=0; im2<2; im2++) { + xm[ico][0]=fX[fIndLocal[im1][0]][0]; + ym[ico][0]=fY[fIndLocal[im1][0]][0]; + xm[ico][1]=fX[fIndLocal[im2][1]][1]; + ym[ico][1]=fY[fIndLocal[im2][1]][1]; + + ixm[ico][0]=fIx[fIndLocal[im1][0]][0]; + iym[ico][0]=fIy[fIndLocal[im1][0]][0]; + ixm[ico][1]=fIx[fIndLocal[im2][1]][1]; + iym[ico][1]=fIy[fIndLocal[im2][1]][1]; + ico++; + } + } +// ico = 0 : first local maximum on cathodes 1 and 2 +// ico = 1 : fisrt local maximum on cathode 1 and second on cathode 2 +// ico = 2 : second local maximum on cathode 1 and first on cathode 1 +// ico = 3 : second local maximum on cathodes 1 and 2 + +// Analyse the combinations and keep those that are possible ! +// For each combination check consistency in x and y + Int_t iacc; + Bool_t accepted[4]; + iacc=0; + + for (ico=0; ico<4; ico++) { + accepted[ico]=kFALSE; +// cathode one: x-coordinate + isec=Segmentation(0)->Sector(ixm[ico][0], iym[ico][0]); + dpx=Segmentation(0)->Dpx(isec)/2.; + dx=TMath::Abs(xm[ico][0]-xm[ico][1]); +// cathode two: y-coordinate + isec=Segmentation(1)->Sector(ixm[ico][1], iym[ico][1]); + dpy=Segmentation(1)->Dpy(isec)/2.; + dy=TMath::Abs(ym[ico][0]-ym[ico][1]); +// printf("\n %i %f %f %f %f \n", ico, ym[ico][0], ym[ico][1], dy, dpy ); + if ((dx <= dpx) && (dy <= dpy)) { + // consistent + accepted[ico]=kTRUE; + iacc++; + } else { + // reject + accepted[ico]=kFALSE; + } + } + + if (iacc==2) { + fprintf(stderr,"\n iacc=2: No problem ! \n"); + } else if (iacc==4) { + fprintf(stderr,"\n iacc=4: Ok, but ghost problem !!! \n"); + } else if (iacc==0) { + fprintf(stderr,"\n iacc=0: I don't know what to do with this !!!!!!!!! \n"); + } + +// Initial value for charge ratios + fQrInit[0]=Float_t(fQ[fIndLocal[0][0]][0])/ + Float_t(fQ[fIndLocal[0][0]][0]+fQ[fIndLocal[1][0]][0]); + fQrInit[1]=Float_t(fQ[fIndLocal[0][1]][1])/ + Float_t(fQ[fIndLocal[0][1]][1]+fQ[fIndLocal[1][1]][1]); + +// ******* iacc = 0 ******* +// No combinations found between the 2 cathodes +// We keep the center of gravity of the cluster + if (iacc==0) { + AddRawCluster(*c); + } + +// ******* iacc = 1 ******* +// Only one combination found between the 2 cathodes + if (iacc==1) { + +// Initial values for the 2 maxima (x,y) + +// 1 maximum is initialised with the maximum of the combination found (X->cathode 2, Y->cathode 1) +// 1 maximum is initialised with the other maximum of the first cathode + if (accepted[0]){ + fprintf(stderr,"ico=0\n"); + fXInit[0]=xm[0][1]; + fYInit[0]=ym[0][0]; + fXInit[1]=xm[3][0]; + fYInit[1]=ym[3][0]; + } else if (accepted[1]){ + fprintf(stderr,"ico=1\n"); + fXInit[0]=xm[1][1]; + fYInit[0]=ym[1][0]; + fXInit[1]=xm[2][0]; + fYInit[1]=ym[2][0]; + } else if (accepted[2]){ + fprintf(stderr,"ico=2\n"); + fXInit[0]=xm[2][1]; + fYInit[0]=ym[2][0]; + fXInit[1]=xm[1][0]; + fYInit[1]=ym[1][0]; + } else if (accepted[3]){ + fprintf(stderr,"ico=3\n"); + fXInit[0]=xm[3][1]; + fYInit[0]=ym[3][0]; + fXInit[1]=xm[0][0]; + fYInit[1]=ym[0][0]; + } + fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n"); + chi2=CombiDoubleMathiesonFit(c); +// Int_t ndf = fgNbins[0]+fgNbins[1]-6; +// Float_t prob = TMath::Prob(chi2,ndf); +// prob2->Fill(prob); +// chi2_2->Fill(chi2); + fprintf(stderr," chi2 %f\n",chi2); + +// If reasonable chi^2 add result to the list of rawclusters + if (chi2<10) { + Split(c); + + } else { +// 1 maximum is initialised with the maximum of the combination found (X->cathode 2, Y->cathode 1) +// 1 maximum is initialised with the other maximum of the second cathode + if (accepted[0]){ + fprintf(stderr,"ico=0\n"); + fXInit[0]=xm[0][1]; + fYInit[0]=ym[0][0]; + fXInit[1]=xm[3][1]; + fYInit[1]=ym[3][1]; + } else if (accepted[1]){ + fprintf(stderr,"ico=1\n"); + fXInit[0]=xm[1][1]; + fYInit[0]=ym[1][0]; + fXInit[1]=xm[2][1]; + fYInit[1]=ym[2][1]; + } else if (accepted[2]){ + fprintf(stderr,"ico=2\n"); + fXInit[0]=xm[2][1]; + fYInit[0]=ym[2][0]; + fXInit[1]=xm[1][1]; + fYInit[1]=ym[1][1]; + } else if (accepted[3]){ + fprintf(stderr,"ico=3\n"); + fXInit[0]=xm[3][1]; + fYInit[0]=ym[3][0]; + fXInit[1]=xm[0][1]; + fYInit[1]=ym[0][1]; + } + fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n"); + chi2=CombiDoubleMathiesonFit(c); +// Int_t ndf = fgNbins[0]+fgNbins[1]-6; +// Float_t prob = TMath::Prob(chi2,ndf); +// prob2->Fill(prob); +// chi2_2->Fill(chi2); + fprintf(stderr," chi2 %f\n",chi2); + +// If reasonable chi^2 add result to the list of rawclusters + if (chi2<10) { + Split(c); + } else { +//We keep only the combination found (X->cathode 2, Y->cathode 1) + for (Int_t ico=0; ico<2; ico++) { + if (accepted[ico]) { + AliMUONRawCluster cnew; + Int_t cath; + for (cath=0; cath<2; cath++) { + cnew.fX[cath]=Float_t(xm[ico][1]); + cnew.fY[cath]=Float_t(ym[ico][0]); + cnew.fMultiplicity[cath]=c->fMultiplicity[cath]; + for (i=0; ifIndexMap[i][cath]; + fgSegmentation[cath]->SetPad(fgix[i][cath], fgiy[i][cath]); + } + fprintf(stderr,"\nRawCluster %d cath %d\n",ico,cath); + fprintf(stderr,"mult_av %d\n",c->fMultiplicity[cath]); + FillCluster(&cnew,cath); + } + cnew.fClusterType=cnew.PhysicsContribution(); + AddRawCluster(cnew); + fNPeaks++; + } + } + } + } + } + +// ******* iacc = 2 ******* +// Two combinations found between the 2 cathodes + if (iacc==2) { + +// Was the same maximum taken twice + if ((accepted[0]&&accepted[1]) || (accepted[2]&&accepted[3])) { + fprintf(stderr,"\n Maximum taken twice !!!\n"); + +// Have a try !! with that + if (accepted[0]&&accepted[3]) { + fXInit[0]=xm[0][1]; + fYInit[0]=ym[0][0]; + fXInit[1]=xm[1][1]; + fYInit[1]=ym[1][0]; + } else { + fXInit[0]=xm[2][1]; + fYInit[0]=ym[2][0]; + fXInit[1]=xm[3][1]; + fYInit[1]=ym[3][0]; + } + fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n"); + chi2=CombiDoubleMathiesonFit(c); +// Int_t ndf = fgNbins[0]+fgNbins[1]-6; +// Float_t prob = TMath::Prob(chi2,ndf); +// prob2->Fill(prob); +// chi2_2->Fill(chi2); + Split(c); + + } else { +// No ghosts ! No Problems ! - Perform one fit only ! + if (accepted[0]&&accepted[3]) { + fXInit[0]=xm[0][1]; + fYInit[0]=ym[0][0]; + fXInit[1]=xm[3][1]; + fYInit[1]=ym[3][0]; + } else { + fXInit[0]=xm[1][1]; + fYInit[0]=ym[1][0]; + fXInit[1]=xm[2][1]; + fYInit[1]=ym[2][0]; + } + fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n"); + chi2=CombiDoubleMathiesonFit(c); +// Int_t ndf = fgNbins[0]+fgNbins[1]-6; +// Float_t prob = TMath::Prob(chi2,ndf); +// prob2->Fill(prob); +// chi2_2->Fill(chi2); + fprintf(stderr," chi2 %f\n",chi2); + Split(c); + } + +// ******* iacc = 4 ******* +// Four combinations found between the 2 cathodes +// Ghost !! + } else if (iacc==4) { +// Perform fits for the two possibilities !! + fXInit[0]=xm[0][1]; + fYInit[0]=ym[0][0]; + fXInit[1]=xm[3][1]; + fYInit[1]=ym[3][0]; + fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n"); + chi2=CombiDoubleMathiesonFit(c); +// Int_t ndf = fgNbins[0]+fgNbins[1]-6; +// Float_t prob = TMath::Prob(chi2,ndf); +// prob2->Fill(prob); +// chi2_2->Fill(chi2); + fprintf(stderr," chi2 %f\n",chi2); + Split(c); + fXInit[0]=xm[1][1]; + fYInit[0]=ym[1][0]; + fXInit[1]=xm[2][1]; + fYInit[1]=ym[2][0]; + fprintf(stderr,"\n cas (2) CombiDoubleMathiesonFit(c)\n"); + chi2=CombiDoubleMathiesonFit(c); +// ndf = fgNbins[0]+fgNbins[1]-6; +// prob = TMath::Prob(chi2,ndf); +// prob2->Fill(prob); +// chi2_2->Fill(chi2); + fprintf(stderr," chi2 %f\n",chi2); + Split(c); + } + + } else if (fNLocal[0]==2 && fNLocal[1]==1) { +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// (3) Two local maxima on cathode 1 and one maximum on cathode 2 +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// + Float_t xm[4][2], ym[4][2]; + Float_t dpx, dpy, dx, dy; + Int_t ixm[4][2], iym[4][2]; + Int_t isec, im1, ico; +// +// Form the 2x2 combinations +// 0-0, 0-1, 1-0, 1-1 + ico=0; + for (im1=0; im1<2; im1++) { + xm[ico][0]=fX[fIndLocal[im1][0]][0]; + ym[ico][0]=fY[fIndLocal[im1][0]][0]; + xm[ico][1]=fX[fIndLocal[0][1]][1]; + ym[ico][1]=fY[fIndLocal[0][1]][1]; + + ixm[ico][0]=fIx[fIndLocal[im1][0]][0]; + iym[ico][0]=fIy[fIndLocal[im1][0]][0]; + ixm[ico][1]=fIx[fIndLocal[0][1]][1]; + iym[ico][1]=fIy[fIndLocal[0][1]][1]; + ico++; + } +// ico = 0 : first local maximum on cathodes 1 and 2 +// ico = 1 : second local maximum on cathode 1 and first on cathode 2 + +// Analyse the combinations and keep those that are possible ! +// For each combination check consistency in x and y + Int_t iacc; + Bool_t accepted[4]; + iacc=0; + + for (ico=0; ico<2; ico++) { + accepted[ico]=kFALSE; + isec=Segmentation(0)->Sector(ixm[ico][0], iym[ico][0]); + dpx=Segmentation(0)->Dpx(isec)/2.; + dx=TMath::Abs(xm[ico][0]-xm[ico][1]); + isec=Segmentation(1)->Sector(ixm[ico][1], iym[ico][1]); + dpy=Segmentation(1)->Dpy(isec)/2.; + dy=TMath::Abs(ym[ico][0]-ym[ico][1]); +// printf("\n %i %f %f %f %f \n", ico, ym[ico][0], ym[ico][1], dy, dpy ); + if ((dx <= dpx) && (dy <= dpy)) { + // consistent + accepted[ico]=kTRUE; + iacc++; + } else { + // reject + accepted[ico]=kFALSE; + } + } + + Float_t chi21 = 100; + Float_t chi22 = 100; + + if (accepted[0]) { + fXInit[0]=xm[0][1]; + fYInit[0]=ym[0][0]; + fXInit[1]=xm[1][0]; + fYInit[1]=ym[1][0]; + chi21=CombiDoubleMathiesonFit(c); +// Int_t ndf = fgNbins[0]+fgNbins[1]-6; +// Float_t prob = TMath::Prob(chi2,ndf); +// prob2->Fill(prob); +// chi2_2->Fill(chi21); + fprintf(stderr," chi2 %f\n",chi21); + if (chi21<10) Split(c); + } else if (accepted[1]) { + fXInit[0]=xm[1][1]; + fYInit[0]=ym[1][0]; + fXInit[1]=xm[0][0]; + fYInit[1]=ym[0][0]; + chi22=CombiDoubleMathiesonFit(c); +// Int_t ndf = fgNbins[0]+fgNbins[1]-6; +// Float_t prob = TMath::Prob(chi2,ndf); +// prob2->Fill(prob); +// chi2_2->Fill(chi22); + fprintf(stderr," chi2 %f\n",chi22); + if (chi22<10) Split(c); + } + + if (chi21 > 10 && chi22 > 10) { +// We keep only the combination found (X->cathode 2, Y->cathode 1) + for (Int_t ico=0; ico<2; ico++) { + if (accepted[ico]) { + AliMUONRawCluster cnew; + Int_t cath; + for (cath=0; cath<2; cath++) { + cnew.fX[cath]=Float_t(xm[ico][1]); + cnew.fY[cath]=Float_t(ym[ico][0]); + cnew.fMultiplicity[cath]=c->fMultiplicity[cath]; + for (i=0; ifIndexMap[i][cath]; + fgSegmentation[cath]->SetPad(fgix[i][cath], fgiy[i][cath]); + } + fprintf(stderr,"\nRawCluster %d cath %d\n",ico,cath); + fprintf(stderr,"mult_av %d\n",c->fMultiplicity[cath]); + FillCluster(&cnew,cath); + } + cnew.fClusterType=cnew.PhysicsContribution(); + AddRawCluster(cnew); + fNPeaks++; + } + } + } + +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// (3') One local maximum on cathode 1 and two maxima on cathode 2 +// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + } else if (fNLocal[0]==1 && fNLocal[1]==2) { + + Float_t xm[4][2], ym[4][2]; + Float_t dpx, dpy, dx, dy; + Int_t ixm[4][2], iym[4][2]; + Int_t isec, im1, ico; +// +// Form the 2x2 combinations +// 0-0, 0-1, 1-0, 1-1 + ico=0; + for (im1=0; im1<2; im1++) { + xm[ico][0]=fX[fIndLocal[0][0]][0]; + ym[ico][0]=fY[fIndLocal[0][0]][0]; + xm[ico][1]=fX[fIndLocal[im1][1]][1]; + ym[ico][1]=fY[fIndLocal[im1][1]][1]; + + ixm[ico][0]=fIx[fIndLocal[0][0]][0]; + iym[ico][0]=fIy[fIndLocal[0][0]][0]; + ixm[ico][1]=fIx[fIndLocal[im1][1]][1]; + iym[ico][1]=fIy[fIndLocal[im1][1]][1]; + ico++; + } +// ico = 0 : first local maximum on cathodes 1 and 2 +// ico = 1 : first local maximum on cathode 1 and second on cathode 2 + +// Analyse the combinations and keep those that are possible ! +// For each combination check consistency in x and y + Int_t iacc; + Bool_t accepted[4]; + iacc=0; + + for (ico=0; ico<2; ico++) { + accepted[ico]=kFALSE; + isec=Segmentation(0)->Sector(ixm[ico][0], iym[ico][0]); + dpx=Segmentation(0)->Dpx(isec)/2.; + dx=TMath::Abs(xm[ico][0]-xm[ico][1]); + isec=Segmentation(1)->Sector(ixm[ico][1], iym[ico][1]); + dpy=Segmentation(1)->Dpy(isec)/2.; + dy=TMath::Abs(ym[ico][0]-ym[ico][1]); +// printf("\n %i %f %f %f %f \n", ico, ym[ico][0], ym[ico][1], dy, dpy ); + if ((dx <= dpx) && (dy <= dpy)) { + // consistent + accepted[ico]=kTRUE; + fprintf(stderr,"ico %d\n",ico); + iacc++; + } else { + // reject + accepted[ico]=kFALSE; + } + } + + Float_t chi21 = 100; + Float_t chi22 = 100; + + if (accepted[0]) { + fXInit[0]=xm[0][0]; + fYInit[0]=ym[0][1]; + fXInit[1]=xm[1][1]; + fYInit[1]=ym[1][1]; + chi21=CombiDoubleMathiesonFit(c); +// Int_t ndf = fgNbins[0]+fgNbins[1]-6; +// Float_t prob = TMath::Prob(chi2,ndf); +// prob2->Fill(prob); +// chi2_2->Fill(chi21); + fprintf(stderr," chi2 %f\n",chi21); + if (chi21<10) Split(c); + } else if (accepted[1]) { + fXInit[0]=xm[1][0]; + fYInit[0]=ym[1][1]; + fXInit[1]=xm[0][1]; + fYInit[1]=ym[0][1]; + chi22=CombiDoubleMathiesonFit(c); +// Int_t ndf = fgNbins[0]+fgNbins[1]-6; +// Float_t prob = TMath::Prob(chi2,ndf); +// prob2->Fill(prob); +// chi2_2->Fill(chi22); + fprintf(stderr," chi2 %f\n",chi22); + if (chi22<10) Split(c); + } + + if (chi21 > 10 && chi22 > 10) { +//We keep only the combination found (X->cathode 2, Y->cathode 1) + for (Int_t ico=0; ico<2; ico++) { + if (accepted[ico]) { + AliMUONRawCluster cnew; + Int_t cath; + for (cath=0; cath<2; cath++) { + cnew.fX[cath]=Float_t(xm[ico][1]); + cnew.fY[cath]=Float_t(ym[ico][0]); + cnew.fMultiplicity[cath]=c->fMultiplicity[cath]; + for (i=0; ifIndexMap[i][cath]; + fgSegmentation[cath]->SetPad(fgix[i][cath], fgiy[i][cath]); + } + fprintf(stderr,"\nRawCluster %d cath %d\n",ico,cath); + fprintf(stderr,"mult_av %d\n",c->fMultiplicity[cath]); + FillCluster(&cnew,cath); + } + cnew.fClusterType=cnew.PhysicsContribution(); + AddRawCluster(cnew); + fNPeaks++; + } + } + } + +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// (4) At least three local maxima on cathode 1 or on cathode 2 +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + } else if (fNLocal[0]>2 || fNLocal[1]>2) { + + Int_t param = fNLocal[0]*fNLocal[1]; + + Float_t xm[param][2], ym[param][2]; + Int_t ixm[param][2], iym[param][2]; + Int_t isec, ico; + Float_t dpx, dpy, dx, dy; + + ico=0; + for (Int_t im1=0; im1Sector(ixm[ico][0], iym[ico][0]); + dpx=Segmentation(0)->Dpx(isec)/2.; + dx=TMath::Abs(xm[ico][0]-xm[ico][1]); + isec=Segmentation(1)->Sector(ixm[ico][1], iym[ico][1]); + dpy=Segmentation(1)->Dpy(isec)/2.; + dy=TMath::Abs(ym[ico][0]-ym[ico][1]); + + fprintf(stderr,"dx %f dpx %f dy %f dpy %f\n",dx,dpx,dy,dpy); + fprintf(stderr," X %f Y %f\n",xm[ico][1],ym[ico][0]); + if ((dx <= dpx) && (dy <= dpy)) { + fprintf(stderr,"ok\n"); + Int_t cath; + AliMUONRawCluster cnew; + for (cath=0; cath<2; cath++) { + cnew.fX[cath]=Float_t(xm[ico][1]); + cnew.fY[cath]=Float_t(ym[ico][0]); + cnew.fMultiplicity[cath]=c->fMultiplicity[cath]; + for (i=0; ifIndexMap[i][cath]; + fgSegmentation[cath]->SetPad(fgix[i][cath], fgiy[i][cath]); + } + FillCluster(&cnew,cath); + } + cnew.fClusterType=cnew.PhysicsContribution(); + AddRawCluster(cnew); + fNPeaks++; + } + } + } +} + +void AliMUONClusterFinderVS::FindLocalMaxima(AliMUONRawCluster* c) +{ +// Find all local maxima of a cluster + + AliMUONDigit* digt; + + Int_t cath, cath1; // loops over cathodes + Int_t i; // loops over digits + Int_t j; // loops over cathodes +// +// Find local maxima +// +// counters for number of local maxima + fNLocal[0]=fNLocal[1]=0; +// flags digits as local maximum + Bool_t isLocal[100][2]; + for (i=0; i<100;i++) { + isLocal[i][0]=isLocal[i][1]=kFALSE; + } +// number of next neighbours and arrays to store them + Int_t nn; + Int_t x[kMaxNeighbours], y[kMaxNeighbours]; +// loop over cathodes + for (cath=0; cath<2; cath++) { +// loop over cluster digits + for (i=0; iNeighbours(fIx[i][cath], fIy[i][cath], &nn, x, y); + isLocal[i][cath]=kTRUE; + Int_t isec= Segmentation(cath)->Sector(fIx[i][cath], fIy[i][cath]); + Float_t a0 = Segmentation(cath)->Dpx(isec)*Segmentation(cath)->Dpy(isec); +// loop over next neighbours, if at least one neighbour has higher charger assumption +// digit is not local maximum + for (j=0; jTestHit(x[j], y[j])==kEmpty) continue; + digt=(AliMUONDigit*) HitMap(cath)->GetHit(x[j], y[j]); + isec=Segmentation(cath)->Sector(x[j], y[j]); + Float_t a1 = Segmentation(cath)->Dpx(isec)*Segmentation(cath)->Dpy(isec); + if (digt->fSignal/a1 > fQ[i][cath]/a0) { + isLocal[i][cath]=kFALSE; + break; +// +// handle special case of neighbouring pads with equal signal + } else if (digt->fSignal == fQ[i][cath]) { + if (fNLocal[cath]>0) { + for (Int_t k=0; kSector(fIx[i][cath],fIy[i][cath]); + dpy=Segmentation(cath)->Dpy(isec); + dpx=Segmentation(cath)->Dpx(isec); + if (isLocal[i][cath]) continue; +// Pad position should be consistent with position of local maxima on the opposite cathode + if ((TMath::Abs(fX[i][cath]-fX[fIndLocal[0][cath1]][cath1]) > dpx/2.) && + (TMath::Abs(fX[i][cath]-fX[fIndLocal[1][cath1]][cath1]) > dpx/2.)) + continue; + +// get neighbours for that digit and assume that it is local maximum + isLocal[i][cath]=kTRUE; +// compare signal to that on the two neighbours on the left and on the right + Segmentation(cath)->GetPadIxy(fX[i][cath],fY[i][cath]+dpy,ix,iy); +// iNN counts the number of neighbours with signal, it should be 1 or 2 + Int_t iNN=0; + if (HitMap(cath)->TestHit(ix, iy)!=kEmpty) { + iNN++; + digt=(AliMUONDigit*) HitMap(cath)->GetHit(ix,iy); + if (digt->fSignal > fQ[i][cath]) isLocal[i][cath]=kFALSE; + } + Segmentation(cath)->GetPadIxy(fX[i][cath],fY[i][cath]-dpy,ix,iy); + if (HitMap(cath)->TestHit(ix, iy)!=kEmpty) { + iNN++; + digt=(AliMUONDigit*) HitMap(cath)->GetHit(ix,iy); + if (digt->fSignal > fQ[i][cath]) isLocal[i][cath]=kFALSE; + } + if (isLocal[i][cath] && iNN>0) { + fIndLocal[fNLocal[cath]][cath]=i; + fNLocal[cath]++; + } + } // loop over all digits +// if one additional maximum has been found we are happy +// if more maxima have been found restore the previous situation + fprintf(stderr,"\n New search gives %d local maxima for cathode 1 \n",fNLocal[0]); + fprintf(stderr," %d local maxima for cathode 2 \n",fNLocal[1]); + if (fNLocal[cath]>2) { + fNLocal[cath]=iback; + } + + } // 1,2 local maxima + + if (fNLocal[0]==2 && (fNLocal[1]==1 || fNLocal[1]==0)) { + Int_t iback=fNLocal[1]; + +// Two local maxima on cathode 1 and one maximum on cathode 2 +// Look for local maxima considering left and right neighbours on the 2nd cathode only + cath=1; + Int_t cath1=0; + + +// +// Loop over cluster digits + for (i=0; iSector(fIx[i][cath],fIy[i][cath]); + dpx=Segmentation(cath)->Dpx(isec); + dpy=Segmentation(cath)->Dpy(isec); + if (isLocal[i][cath]) continue; +// Pad position should be consistent with position of local maxima on the opposite cathode + if ((TMath::Abs(fY[i][cath]-fY[fIndLocal[0][cath1]][cath1]) > dpy/2.) && + (TMath::Abs(fY[i][cath]-fY[fIndLocal[1][cath1]][cath1]) > dpy/2.)) + continue; +// +// get neighbours for that digit and assume that it is local maximum + isLocal[i][cath]=kTRUE; +// compare signal to that on the two neighbours on the left and on the right + Segmentation(cath)->GetPadIxy(fX[i][cath]+dpx,fY[i][cath],ix,iy); +// iNN counts the number of neighbours with signal, it should be 1 or 2 + Int_t iNN=0; + if (HitMap(cath)->TestHit(ix, iy)!=kEmpty) { + iNN++; + digt=(AliMUONDigit*) HitMap(cath)->GetHit(ix,iy); + if (digt->fSignal > fQ[i][cath]) isLocal[i][cath]=kFALSE; + } + Segmentation(cath)->GetPadIxy(fX[i][cath]-dpx,fY[i][cath],ix,iy); + if (HitMap(cath)->TestHit(ix, iy)!=kEmpty) { + iNN++; + digt=(AliMUONDigit*) HitMap(cath)->GetHit(ix,iy); + if (digt->fSignal > fQ[i][cath]) isLocal[i][cath]=kFALSE; + } + if (isLocal[i][cath] && iNN>0) { + fIndLocal[fNLocal[cath]][cath]=i; + fNLocal[cath]++; + } + } // loop over all digits +// if one additional maximum has been found we are happy +// if more maxima have been found restore the previous situation + fprintf(stderr,"\n New search gives %d local maxima for cathode 1 \n",fNLocal[0]); + fprintf(stderr,"\n %d local maxima for cathode 2 \n",fNLocal[1]); +// printf("\n New search gives %d %d \n",fNLocal[0],fNLocal[1]); + if (fNLocal[cath]>2) { + fNLocal[cath]=iback; + } + + + + } // 2,1 local maxima +} + + +void AliMUONClusterFinderVS::FillCluster(AliMUONRawCluster* c, Int_t flag, Int_t cath) +{ +// +// Completes cluster information starting from list of digits +// + AliMUONDigit* dig; + Float_t x, y; + Int_t ix, iy; + + if (cath==1) { + c->fPeakSignal[cath]=c->fPeakSignal[0]; + } else { + c->fPeakSignal[cath]=0; + } + + + if (flag) { + c->fX[cath]=0; + c->fY[cath]=0; + c->fQ[cath]=0; + } + +// fprintf(stderr,"\n fPeakSignal %d\n",c->fPeakSignal[cath]); + for (Int_t i=0; ifMultiplicity[cath]; i++) + { + dig= (AliMUONDigit*)Digits(cath)->UncheckedAt(c->fIndexMap[i][cath]); + ix=dig->fPadX+c->fOffsetMap[i][cath]; + iy=dig->fPadY; + Int_t q=dig->fSignal; + if (!flag) q=Int_t(q*c->fContMap[i][cath]); +// fprintf(stderr,"q %d c->fPeakSignal[ %d ] %d\n",q,cath,c->fPeakSignal[cath]); + if (dig->fPhysics >= dig->fSignal) { + c->fPhysicsMap[i]=2; + } else if (dig->fPhysics == 0) { + c->fPhysicsMap[i]=0; + } else c->fPhysicsMap[i]=1; +// +// +// fprintf(stderr,"q %d c->fPeakSignal[cath] %d\n",q,c->fPeakSignal[cath]); +// peak signal and track list + if (q>c->fPeakSignal[cath]) { + c->fPeakSignal[cath]=q; + c->fTracks[0]=dig->fHit; + c->fTracks[1]=dig->fTracks[0]; + c->fTracks[2]=dig->fTracks[1]; +// fprintf(stderr," c->fTracks[0] %d c->fTracks[1] %d\n",dig->fHit,dig->fTracks[0]); + } +// + if (flag) { + Segmentation(cath)->GetPadCxy(ix, iy, x, y); + c->fX[cath] += q*x; + c->fY[cath] += q*y; + c->fQ[cath] += q; + } + } // loop over digits +// fprintf(stderr," fin du cluster c\n"); + + + if (flag) { + c->fX[cath]/=c->fQ[cath]; + c->fX[cath]=Segmentation(cath)->GetAnod(c->fX[cath]); + c->fY[cath]/=c->fQ[cath]; +// +// apply correction to the coordinate along the anode wire +// + x=c->fX[cath]; + y=c->fY[cath]; + Segmentation(cath)->GetPadIxy(x, y, ix, iy); + Segmentation(cath)->GetPadCxy(ix, iy, x, y); + Int_t isec=Segmentation(cath)->Sector(ix,iy); + TF1* cogCorr = Segmentation(cath)->CorrFunc(isec-1); + + if (cogCorr) { + Float_t yOnPad=(c->fY[cath]-y)/Segmentation(cath)->Dpy(isec); + c->fY[cath]=c->fY[cath]-cogCorr->Eval(yOnPad, 0, 0); + } + } +} + +void AliMUONClusterFinderVS::FillCluster(AliMUONRawCluster* c, Int_t cath) +{ +// +// Completes cluster information starting from list of digits +// + static Float_t dr0; + + AliMUONDigit* dig; + + if (cath==0) { + dr0 = 10000; + } + + Float_t xpad, ypad; + Float_t dx, dy, dr; + + for (Int_t i=0; ifMultiplicity[cath]; i++) + { + dig= (AliMUONDigit*)Digits(cath)->UncheckedAt(c->fIndexMap[i][cath]); + Segmentation(cath)-> + GetPadCxy(dig->fPadX,dig->fPadY,xpad,ypad); + fprintf(stderr,"x %f y %f cx %f cy %f\n",xpad,ypad,c->fX[0],c->fY[0]); + dx = xpad - c->fX[0]; + dy = ypad - c->fY[0]; + dr = TMath::Sqrt(dx*dx+dy*dy); + + if (dr < dr0) { + dr0 = dr; + fprintf(stderr," dr %f\n",dr); + 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; + c->fPeakSignal[cath]=q; + c->fTracks[0]=dig->fHit; + c->fTracks[1]=dig->fTracks[0]; + c->fTracks[2]=dig->fTracks[1]; + fprintf(stderr," c->fTracks[0] %d c->fTracks[1] %d\n",dig->fHit,dig->fTracks[0]); + } +// + } // loop over digits + +// apply correction to the coordinate along the anode wire + c->fX[cath]=Segmentation(cath)->GetAnod(c->fX[cath]); +} + +void AliMUONClusterFinderVS::FindCluster(Int_t i, Int_t j, Int_t cath, AliMUONRawCluster &c){ +// +// Find clusterset +// +// +// Add i,j as element of the cluster +// + + Int_t idx = HitMap(cath)->GetHitIndex(i,j); + AliMUONDigit* dig = (AliMUONDigit*) HitMap(cath)->GetHit(i,j); + Int_t q=dig->fSignal; + Int_t theX=dig->fPadX; + Int_t theY=dig->fPadY; + if (q > TMath::Abs(c.fPeakSignal[0]) && q > TMath::Abs(c.fPeakSignal[1])) { + c.fPeakSignal[cath]=q; + 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[cath]; + c.fIndexMap[mu][cath]=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][cath]; + Int_t ql=((AliMUONDigit*)Digits(cath) + ->UncheckedAt(ist))->fSignal; + Int_t ix=((AliMUONDigit*)Digits(cath) + ->UncheckedAt(ist))->fPadX; + Int_t iy=((AliMUONDigit*)Digits(cath) + ->UncheckedAt(ist))->fPadY; + + if (q>ql || (q==ql && theX > ix && theY < iy)) { + c.fIndexMap[ind][cath]=idx; + c.fIndexMap[ind+1][cath]=ist; + } else { + break; + } + } + } + + c.fMultiplicity[cath]++; + if (c.fMultiplicity[cath] >= 50 ) { + printf("FindCluster - multiplicity >50 %d \n",c.fMultiplicity[0]); + c.fMultiplicity[cath]=49; + } + +// Prepare center of gravity calculation + Float_t x, y; + Segmentation(cath)->GetPadCxy(i, j, x, y); + + c.fX[cath] += q*x; + c.fY[cath] += q*y; + c.fQ[cath] += q; +// Flag hit as taken + HitMap(cath)->FlagHit(i,j); +// +// Now look recursively for all neighbours and pad hit on opposite cathode +// +// Loop over neighbours + Int_t ix,iy; + Int_t nn; + Int_t xList[kMaxNeighbours], yList[kMaxNeighbours]; + Segmentation(cath)->Neighbours(i,j,&nn,xList,yList); + for (Int_t in=0; inTestHit(ix,iy)==kUnused) FindCluster(ix, iy, cath, c); + } +// Neighbours on opposite cathode +// Take into account that several pads can overlap with the present pad + Float_t xmin, xmax, ymin, ymax, xc, yc; + Int_t iop; + Int_t isec=Segmentation(cath)->Sector(i,j); + if (cath==0) { + iop=1; + xmin=x-Segmentation(cath)->Dpx(isec); + xmax=x+Segmentation(cath)->Dpx(isec); + xc=xmin+.001; + while (xc < xmax) { + xc+=Segmentation(iop)->Dpx(isec); + Segmentation(iop)->GetPadIxy(xc,y,ix,iy); + if (ix>=(Segmentation(iop)->Npx()) || (iy>=Segmentation(iop)->Npy())) continue; + if (HitMap(iop)->TestHit(ix,iy)==kUnused) FindCluster(ix, iy, iop, c); + } + } else { + iop=0; + ymin=y-Segmentation(cath)->Dpy(isec); + ymax=y+Segmentation(cath)->Dpy(isec); + yc=ymin+.001; + while (yc < ymax) { + yc+=Segmentation(iop)->Dpy(isec); + Segmentation(iop)->GetPadIxy(x,yc,ix,iy); + if (ix>=(Segmentation(iop)->Npx()) || (iy>=Segmentation(iop)->Npy())) continue; + if (HitMap(iop)->TestHit(ix,iy)==kUnused) FindCluster(ix, iy, iop, c); + } + } +} + +//_____________________________________________________________________________ + +void AliMUONClusterFinderVS::FindRawClusters() +{ + // + // MUON cluster finder from digits -- finds neighbours on both cathodes and + // fills the tree with raw clusters + // + + if (!NDigits(0) && !NDigits(1)) return; + + fHitMap = new AliMUONHitMapA1(fSegmentation , fDigits); + fHitMap2 = new AliMUONHitMapA1(fSegmentation2, fDigits2); + + AliMUONDigit *dig; + + Int_t ndig, cath; + Int_t nskip=0; + Int_t ncls=0; + HitMap(0)->FillHits(); + HitMap(1)->FillHits(); +// +// Outer Loop over Cathodes + for (cath=0; cath<2; cath++) { + for (ndig=0; ndigUncheckedAt(ndig); + Int_t i=dig->fPadX; + Int_t j=dig->fPadY; + if (HitMap(cath)->TestHit(i,j)==kUsed ||fHitMap->TestHit(i,j)==kEmpty) { + nskip++; + continue; + } + fprintf(stderr,"\n CATHODE %d CLUSTER %d\n",cath,ncls); + AliMUONRawCluster c; + c.fMultiplicity[0]=0; + c.fMultiplicity[1]=0; + c.fPeakSignal[cath]=dig->fSignal; + 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,cath,c); + + // center of gravity + c.fX[0] /= c.fQ[0]; + c.fX[0]=Segmentation(0)->GetAnod(c.fX[0]); + c.fY[0] /= c.fQ[0]; + c.fX[1] /= c.fQ[1]; + c.fX[1]=Segmentation(0)->GetAnod(c.fX[1]); + c.fY[1] /= c.fQ[1]; + fprintf(stderr,"\n Cathode 1 multiplicite %d X(CG) %f Y(CG) %f\n",c.fMultiplicity[0],c.fX[0],c.fY[0]); + fprintf(stderr," Cathode 2 multiplicite %d X(CG) %f Y(CG) %f\n",c.fMultiplicity[1],c.fX[1],c.fY[1]); + +// Mathieson Fit +/* + Bool_t fitted; + + fitted=SingleMathiesonFit(&c, 0); + c.fX[0]=Segmentation(0)->GetAnod(c.fX[0]); + fitted=SingleMathiesonFit(&c, 1); + c.fX[1]=Segmentation(1)->GetAnod(c.fX[1]); +*/ +// +// Analyse cluster and decluster if necessary +// + ncls++; + c.fNcluster[1]=fNRawClusters; + c.fClusterType=c.PhysicsContribution(); + + fNPeaks=0; +// +// + Decluster(&c); +// AddRawCluster(c); + +// +// reset Cluster object + for (int k=0;kfMultiplicity[cath]; + fgSegmentation[0]=Segmentation(cath); + fgResponse =fResponse; + fgNbins[0]=fMul[cath]; + Float_t qtot=0; +// +// dump digit information into arrays +// + for (i=0; iUncheckedAt(c->fIndexMap[i][cath]); + fIx[i][cath]= fDig[i][cath]->fPadX; + fIy[i][cath]= fDig[i][cath]->fPadY; + fQ[i][cath] = fDig[i][cath]->fSignal; + Segmentation(cath)->GetPadCxy(fIx[i][cath], fIy[i][cath], fX[i][cath], fY[i][cath]); + fgix[i][0]=fIx[i][cath]; + fgiy[i][0]=fIy[i][cath]; + fgCharge[i][0]=Float_t(fQ[i][cath]); + qtot+=fgCharge[i][0]; + } + + fgQtot[0]=qtot; + fgChargeTot[0]=Int_t(qtot); + +// + if (fgFirst) { + fgFirst=kFALSE; + fgMyMinuit = new TMinuit(5); + } + + fgMyMinuit->SetFCN(fcnS1); + fgMyMinuit->mninit(2,10,7); + Double_t arglist[20]; + Int_t ierflag=0; + arglist[0]=1; +// fgMyMinuit->mnexcm("SET ERR",arglist,1,ierflag); +// Set starting values + static Double_t vstart[2]; + vstart[0]=c->fX[1]; + vstart[1]=c->fY[0]; + + +// lower and upper limits + static Double_t lower[2], upper[2]; + Int_t ix,iy; + Segmentation(cath)->GetPadIxy(c->fX[cath], c->fY[cath], ix, iy); + Int_t isec=Segmentation(cath)->Sector(ix, iy); + lower[0]=vstart[0]-Segmentation(cath)->Dpx(isec)/2; + lower[1]=vstart[1]-Segmentation(cath)->Dpy(isec)/2; + + upper[0]=lower[0]+Segmentation(cath)->Dpx(isec); + upper[1]=lower[1]+Segmentation(cath)->Dpy(isec); + +// step sizes + static Double_t step[2]={0.0005, 0.0005}; + + fgMyMinuit->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag); + fgMyMinuit->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag); +// ready for minimisation + fgMyMinuit->SetPrintLevel(1); + fgMyMinuit->mnexcm("SET OUT", arglist, 0, ierflag); + arglist[0]= -1; + arglist[1]= 0; + + fgMyMinuit->mnexcm("SET NOGR", arglist, 0, ierflag); + fgMyMinuit->mnexcm("MIGRAD", arglist, 0, ierflag); + fgMyMinuit->mnexcm("EXIT" , arglist, 0, ierflag); + Double_t fmin, fedm, errdef; + Int_t npari, nparx, istat; + + fgMyMinuit->mnstat(fmin, fedm, errdef, npari, nparx, istat); + fFitStat=istat; + +// Print results +// Get fitted parameters + Double_t xrec, yrec; + TString chname; + Double_t epxz, b1, b2; + Int_t ierflg; + fgMyMinuit->mnpout(0, chname, xrec, epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(1, chname, yrec, epxz, b1, b2, ierflg); + fXFit[cath]=xrec; + fYFit[cath]=yrec; + return fmin; +} + +Float_t AliMUONClusterFinderVS::CombiSingleMathiesonFit(AliMUONRawCluster *c) +{ +// Perform combined Mathieson fit on both cathode planes +// + if (fgFirst) { + fgFirst=kFALSE; + fgMyMinuit = new TMinuit(5); + } + + fgMyMinuit->SetFCN(fcnCombiS1); + fgMyMinuit->mninit(2,10,7); + Double_t arglist[20]; + Int_t ierflag=0; + arglist[0]=1; + static Double_t vstart[2]; + vstart[0]=fXInit[0]; + vstart[1]=fYInit[0]; + + +// lower and upper limits + static Double_t lower[2], upper[2]; + Int_t ix,iy,isec; + Segmentation(0)->GetPadIxy(fXInit[0], fYInit[0], ix, iy); + isec=Segmentation(0)->Sector(ix, iy); + Float_t dpy=Segmentation(0)->Dpy(isec)/2; + Segmentation(1)->GetPadIxy(fXInit[0], fYInit[0], ix, iy); + isec=Segmentation(1)->Sector(ix, iy); + Float_t dpx=Segmentation(1)->Dpx(isec)/2; + + + lower[0]=vstart[0]-dpx; + lower[1]=vstart[1]-dpy; + + upper[0]=vstart[0]+dpx; + upper[1]=vstart[1]+dpy; + +// step sizes + static Double_t step[2]={0.00001, 0.0001}; + + fgMyMinuit->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag); + fgMyMinuit->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag); +// ready for minimisation + fgMyMinuit->SetPrintLevel(1); + fgMyMinuit->mnexcm("SET OUT", arglist, 0, ierflag); + arglist[0]= -1; + arglist[1]= 0; + + fgMyMinuit->mnexcm("SET NOGR", arglist, 0, ierflag); + fgMyMinuit->mnexcm("MIGRAD", arglist, 0, ierflag); + fgMyMinuit->mnexcm("EXIT" , arglist, 0, ierflag); + Double_t fmin, fedm, errdef; + Int_t npari, nparx, istat; + + fgMyMinuit->mnstat(fmin, fedm, errdef, npari, nparx, istat); + fFitStat=istat; + +// Print results +// Get fitted parameters + Double_t xrec, yrec; + TString chname; + Double_t epxz, b1, b2; + Int_t ierflg; + fgMyMinuit->mnpout(0, chname, xrec, epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(1, chname, yrec, epxz, b1, b2, ierflg); + fXFit[0]=xrec; + fYFit[0]=yrec; + return fmin; +} + +Bool_t AliMUONClusterFinderVS::DoubleMathiesonFit(AliMUONRawCluster *c, Int_t cath) +{ +// +// Initialise global variables for fit + Int_t i,j; + + fgSegmentation[0]=Segmentation(cath); + fgResponse =fResponse; + fgNbins[0]=fMul[cath]; + Float_t qtot=0; + + for (i=0; iSetFCN(fcnS2); + fgMyMinuit->mninit(5,10,7); + Double_t arglist[20]; + Int_t ierflag=0; + arglist[0]=1; +// Set starting values + static Double_t vstart[5]; + vstart[0]=fX[fIndLocal[0][cath]][cath]; + vstart[1]=fY[fIndLocal[0][cath]][cath]; + vstart[2]=fX[fIndLocal[1][cath]][cath]; + vstart[3]=fY[fIndLocal[1][cath]][cath]; + vstart[4]=Float_t(fQ[fIndLocal[0][cath]][cath])/ + Float_t(fQ[fIndLocal[0][cath]][cath]+fQ[fIndLocal[1][cath]][cath]); +// lower and upper limits + static Double_t lower[5], upper[5]; + Int_t isec=Segmentation(cath)->Sector(fIx[fIndLocal[0][cath]][cath], fIy[fIndLocal[0][cath]][cath]); + lower[0]=vstart[0]-Segmentation(cath)->Dpx(isec); + lower[1]=vstart[1]-Segmentation(cath)->Dpy(isec); + + upper[0]=lower[0]+2.*Segmentation(cath)->Dpx(isec); + upper[1]=lower[1]+2.*Segmentation(cath)->Dpy(isec); + + isec=Segmentation(cath)->Sector(fIx[fIndLocal[1][cath]][cath], fIy[fIndLocal[1][cath]][cath]); + lower[2]=vstart[2]-Segmentation(cath)->Dpx(isec)/2; + lower[3]=vstart[3]-Segmentation(cath)->Dpy(isec)/2; + + upper[2]=lower[2]+Segmentation(cath)->Dpx(isec); + upper[3]=lower[3]+Segmentation(cath)->Dpy(isec); + + lower[4]=0.; + upper[4]=1.; +// step sizes + static Double_t step[5]={0.0005, 0.0005, 0.0005, 0.0005, 0.0001}; + + fgMyMinuit->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag); + fgMyMinuit->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag); + fgMyMinuit->mnparm(2,"x2",vstart[2],step[2],lower[2],upper[2],ierflag); + fgMyMinuit->mnparm(3,"y2",vstart[3],step[3],lower[3],upper[3],ierflag); + fgMyMinuit->mnparm(4,"a0",vstart[4],step[4],lower[4],upper[4],ierflag); +// ready for minimisation + fgMyMinuit->SetPrintLevel(-1); + fgMyMinuit->mnexcm("SET OUT", arglist, 0, ierflag); + arglist[0]= -1; + arglist[1]= 0; + + fgMyMinuit->mnexcm("SET NOGR", arglist, 0, ierflag); + fgMyMinuit->mnexcm("MIGRAD", arglist, 0, ierflag); + fgMyMinuit->mnexcm("EXIT" , arglist, 0, ierflag); +// Get fitted parameters + Double_t xrec[2], yrec[2], qfrac; + TString chname; + Double_t epxz, b1, b2; + Int_t ierflg; + fgMyMinuit->mnpout(0, chname, xrec[0], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(1, chname, yrec[0], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(2, chname, xrec[1], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(3, chname, yrec[1], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(4, chname, qfrac, epxz, b1, b2, ierflg); + + Double_t fmin, fedm, errdef; + Int_t npari, nparx, istat; + + fgMyMinuit->mnstat(fmin, fedm, errdef, npari, nparx, istat); + fFitStat=istat; + + +// +// One cluster for each maximum +// + for (j=0; j<2; j++) { + AliMUONRawCluster cnew; + cnew.fChi2[0]=Float_t(fmin); + + if (fNPeaks == 0) { + cnew.fNcluster[0]=-1; + cnew.fNcluster[1]=fNRawClusters; + } else { + cnew.fNcluster[0]=fNPeaks; + cnew.fNcluster[1]=0; + } + cnew.fMultiplicity[0]=0; + cnew.fX[0]=Float_t(xrec[j]); + cnew.fY[0]=Float_t(yrec[j]); + if (j==0) { + cnew.fQ[0]=Int_t(fgChargeTot[0]*qfrac); + } else { + cnew.fQ[0]=Int_t(fgChargeTot[0]*(1-qfrac)); + } + fgSegmentation[0]->SetHit(xrec[j],yrec[j]); + for (i=0; ifIndexMap[i][cath]; + fgSegmentation[0]->SetPad(fgix[i][0], fgiy[i][0]); + Float_t q1=fgResponse->IntXY(fgSegmentation[0]); + cnew.fContMap[cnew.fMultiplicity[0]][0]=(q1*cnew.fQ[0])/Float_t(fQ[i][cath]); + cnew.fMultiplicity[0]++; + } + FillCluster(&cnew,0,0); + cnew.fClusterType=cnew.PhysicsContribution(); + AddRawCluster(cnew); + fNPeaks++; + } + return kTRUE; +} + +Float_t AliMUONClusterFinderVS::CombiDoubleMathiesonFit(AliMUONRawCluster *c) +{ +// +// Perform combined double Mathieson fit on both cathode planes +// + if (fgFirst) { + fgFirst=kFALSE; + fgMyMinuit = new TMinuit(5); + } + fgMyMinuit->SetFCN(fcnCombiS2); + fgMyMinuit->mninit(6,10,7); + Double_t arglist[20]; + Int_t ierflag=0; + arglist[0]=1; +// Set starting values + static Double_t vstart[6]; + vstart[0]=fXInit[0]; + vstart[1]=fYInit[0]; + vstart[2]=fXInit[1]; + vstart[3]=fYInit[1]; + vstart[4]=fQrInit[0]; + vstart[5]=fQrInit[1]; +// lower and upper limits + static Double_t lower[6], upper[6]; + Int_t ix,iy,isec; + Float_t dpx, dpy; + + Segmentation(1)->GetPadIxy(fXInit[0], fYInit[0], ix, iy); + isec=Segmentation(1)->Sector(ix, iy); + dpx=Segmentation(1)->Dpx(isec); + + Segmentation(0)->GetPadIxy(fXInit[0], fYInit[0], ix, iy); + isec=Segmentation(0)->Sector(ix, iy); + dpy=Segmentation(0)->Dpy(isec); + + lower[0]=vstart[0]-dpx; + lower[1]=vstart[1]-dpy; + upper[0]=vstart[0]+dpx; + upper[1]=vstart[1]+dpy; + + + Segmentation(1)->GetPadIxy(fXInit[1], fYInit[1], ix, iy); + isec=Segmentation(1)->Sector(ix, iy); + dpx=Segmentation(1)->Dpx(isec); + Segmentation(0)->GetPadIxy(fXInit[1], fYInit[1], ix, iy); + isec=Segmentation(0)->Sector(ix, iy); + dpy=Segmentation(0)->Dpy(isec); + + lower[2]=vstart[2]-dpx; + lower[3]=vstart[3]-dpy; + upper[2]=vstart[2]+dpx; + upper[3]=vstart[3]+dpy; + + + lower[4]=0.; + upper[4]=1.; + lower[5]=0.; + upper[5]=1.; + +// step sizes + static Double_t step[6]={0.0005, 0.0005, 0.0005, 0.0005, 0.001, 0.001}; + + fgMyMinuit->mnparm(0,"x1",vstart[0],step[0],lower[0],upper[0],ierflag); + fgMyMinuit->mnparm(1,"y1",vstart[1],step[1],lower[1],upper[1],ierflag); + fgMyMinuit->mnparm(2,"x2",vstart[2],step[2],lower[2],upper[2],ierflag); + fgMyMinuit->mnparm(3,"y2",vstart[3],step[3],lower[3],upper[3],ierflag); + fgMyMinuit->mnparm(4,"a0",vstart[4],step[4],lower[4],upper[4],ierflag); + fgMyMinuit->mnparm(5,"a1",vstart[5],step[5],lower[5],upper[5],ierflag); +// ready for minimisation + fgMyMinuit->SetPrintLevel(-1); + fgMyMinuit->mnexcm("SET OUT", arglist, 0, ierflag); + arglist[0]= -1; + arglist[1]= 0; + + fgMyMinuit->mnexcm("SET NOGR", arglist, 0, ierflag); + fgMyMinuit->mnexcm("MIGRAD", arglist, 0, ierflag); + fgMyMinuit->mnexcm("EXIT" , arglist, 0, ierflag); +// Get fitted parameters + TString chname; + Double_t epxz, b1, b2; + Int_t ierflg; + fgMyMinuit->mnpout(0, chname, fXFit[0], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(1, chname, fYFit[0], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(2, chname, fXFit[1], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(3, chname, fYFit[1], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(4, chname, fQrFit[0], epxz, b1, b2, ierflg); + fgMyMinuit->mnpout(5, chname, fQrFit[1], epxz, b1, b2, ierflg); + + Double_t fmin, fedm, errdef; + Int_t npari, nparx, istat; + + fgMyMinuit->mnstat(fmin, fedm, errdef, npari, nparx, istat); + fFitStat=istat; + + fChi2[0]=fmin; + fChi2[1]=fmin; + return fmin; +} + +void AliMUONClusterFinderVS::Split(AliMUONRawCluster* c) +{ +// +// One cluster for each maximum +// + Int_t i, j, cath; + + for (j=0; j<2; j++) { + AliMUONRawCluster cnew; + for (cath=0; cath<2; cath++) { + cnew.fChi2[cath]=fChi2[0]; + + if (fNPeaks == 0) { + cnew.fNcluster[0]=-1; + cnew.fNcluster[1]=fNRawClusters; + } else { + cnew.fNcluster[0]=fNPeaks; + cnew.fNcluster[1]=0; + } + cnew.fMultiplicity[cath]=0; + cnew.fX[cath]=Float_t(fXFit[j]); + cnew.fY[cath]=Float_t(fYFit[j]); + if (j==0) { + cnew.fQ[cath]=Int_t(fgChargeTot[cath]*fQrFit[cath]); + } else { + cnew.fQ[cath]=Int_t(fgChargeTot[cath]*(1-fQrFit[cath])); + } + fgSegmentation[cath]->SetHit(fXFit[j],fYFit[j]); + for (i=0; ifIndexMap[i][cath]; + fgSegmentation[cath]->SetPad(fgix[i][cath], fgiy[i][cath]); + Float_t q1=fgResponse->IntXY(fgSegmentation[cath]); + cnew.fContMap[i][cath] + =(q1*Float_t(cnew.fQ[cath]))/Float_t(fQ[i][cath]); + cnew.fMultiplicity[cath]++; +// printf(" fXFIT %f fYFIT %f Multiplicite %d\n",cnew.fX[cath],cnew.fY[cath],cnew.fMultiplicity[cath]); + } + FillCluster(&cnew,0,cath); + } // cathode loop + + cnew.fClusterType=cnew.PhysicsContribution(); + if (cnew.fQ[0]>0 && cnew.fQ[1]>0) AddRawCluster(cnew); + fNPeaks++; + } +} + + +Float_t DiscrChargeS1(Int_t i,Double_t *par) +{ +// par[0] x-position of cluster +// par[1] y-position of cluster + + fgSegmentation[0]->SetPad(fgix[i][0], fgiy[i][0]); +// First Cluster + fgSegmentation[0]->SetHit(par[0],par[1]); + Float_t q1=fgResponse->IntXY(fgSegmentation[0]); + + Float_t value = fgQtot[0]*q1; + return value; +} + +Float_t DiscrChargeCombiS1(Int_t i,Double_t *par, Int_t cath) +{ +// par[0] x-position of cluster +// par[1] y-position of cluster + + fgSegmentation[cath]->SetPad(fgix[i][cath], fgiy[i][cath]); +// First Cluster + fgSegmentation[cath]->SetHit(par[0],par[1]); + Float_t q1=fgResponse->IntXY(fgSegmentation[cath]); + + Float_t value = fgQtot[cath]*q1; + return value; +} + + +Float_t DiscrChargeS2(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 + + fgSegmentation[0]->SetPad(fgix[i][0], fgiy[i][0]); +// First Cluster + fgSegmentation[0]->SetHit(par[0],par[1]); + Float_t q1=fgResponse->IntXY(fgSegmentation[0]); + +// Second Cluster + fgSegmentation[0]->SetHit(par[2],par[3]); + Float_t q2=fgResponse->IntXY(fgSegmentation[0]); + + Float_t value = fgQtot[0]*(par[4]*q1+(1.-par[4])*q2); + return value; +} + +Float_t DiscrChargeCombiS2(Int_t i,Double_t *par, Int_t cath) +{ +// 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 + + fgSegmentation[cath]->SetPad(fgix[i][cath], fgiy[i][cath]); +// First Cluster + fgSegmentation[cath]->SetHit(par[0],par[1]); + Float_t q1=fgResponse->IntXY(fgSegmentation[cath]); + +// Second Cluster + fgSegmentation[cath]->SetHit(par[2],par[3]); + Float_t q2=fgResponse->IntXY(fgSegmentation[cath]); + Float_t value; + if (cath==0) { + value = fgQtot[0]*(par[4]*q1+(1.-par[4])*q2); + } else { + value = fgQtot[1]*(par[5]*q1+(1.-par[5])*q2); + } + return value; +} + +// +// Minimisation functions +// Single Mathieson +void fcnS1(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; iGetModule("MUON"); + pMUON->AddRawCluster(fChamber,c); + fNRawClusters++; + fprintf(stderr,"\nfNRawClusters %d\n",fNRawClusters); +} + + +AliMUONClusterFinderVS& AliMUONClusterFinderVS +::operator = (const AliMUONClusterFinderVS& rhs) +{ +// Dummy assignment operator + return *this; +} + + + + + + + + + diff --git a/MUON/AliMUONClusterFinderVS.h b/MUON/AliMUONClusterFinderVS.h new file mode 100644 index 00000000000..2728ab7a090 --- /dev/null +++ b/MUON/AliMUONClusterFinderVS.h @@ -0,0 +1,125 @@ +#ifndef ALIMUONCLUSTERFINDERVS_H +#define ALIMUONCLUSTERFINDERVS_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +//////////////////////////////////////////////// +// MUON Cluster Finder Class // +//////////////////////////////////////////////// +#include "AliMUONHitMap.h" +#include "TF1.h" +#include "AliMUONClusterFinder.h" +class AliMUONClusterFinderVS : + public AliMUONClusterFinder +{ + public: + AliMUONClusterFinderVS + (AliMUONSegmentation *segmentation1, AliMUONSegmentation *segmentation2, + AliMUONResponse *response, + TClonesArray *digits1, TClonesArray *digits2, + Int_t chamber); + AliMUONClusterFinderVS(); + AliMUONClusterFinderVS(const AliMUONClusterFinderVS& clusterFinder); + virtual ~AliMUONClusterFinderVS(){;} +// Set segmentation model + virtual void SetSegmentation(AliMUONSegmentation *seg1, AliMUONSegmentation *seg2) + { + fSegmentation=seg1; + fSegmentation2=seg2; + } +// Set pointer to digits + virtual void SetDigits(TClonesArray *MUONdigits1, TClonesArray *MUONdigits2); + +// Get Segmentation + virtual AliMUONSegmentation* Segmentation(Int_t i); +// Get Number of Digits + virtual Int_t NDigits(Int_t i); +// Get Digits + virtual TClonesArray* Digits(Int_t i); +// Get HitMap + virtual AliMUONHitMap* HitMap(Int_t i); + +// Search for raw clusters + virtual void FindRawClusters(); +// Find cluster + virtual void FindCluster(Int_t i, Int_t j, Int_t cath, AliMUONRawCluster &c); +// Decluster + virtual void Decluster(AliMUONRawCluster *cluster); +// Perform split by local maxima + virtual void SplitByLocalMaxima(AliMUONRawCluster *cluster); + virtual void FindLocalMaxima(AliMUONRawCluster *cluster); + virtual void Split(AliMUONRawCluster * cluster); + +// Perform Double Mathieson Fit + Bool_t DoubleMathiesonFit(AliMUONRawCluster *c, Int_t cath); + Float_t CombiDoubleMathiesonFit(AliMUONRawCluster *c); + Float_t SingleMathiesonFit(AliMUONRawCluster *c, Int_t cath); + Float_t CombiSingleMathiesonFit(AliMUONRawCluster *c); +// Build up full cluster information + virtual void FillCluster(AliMUONRawCluster *cluster, Int_t flag, Int_t cath); + virtual void FillCluster(AliMUONRawCluster *cluster, Int_t cath); + virtual void FillCluster(AliMUONRawCluster *cluster) { + FillCluster(cluster,1,0);} + // Add a new raw cluster + virtual void AddRawCluster(const AliMUONRawCluster cluster); + + virtual void SetTracks(Int_t t1, Int_t t2) + { + fTrack[0]=t1; + fTrack[1]=t2; + } + + virtual Bool_t TestTrack(Int_t t) { + if (fTrack[0]==-1 || fTrack[1]==-1) { + return kTRUE; + } else if (t==fTrack[0] || t==fTrack[1]) { + return kTRUE; + } else { + return kFALSE; + } + } + // Assignment operator + AliMUONClusterFinderVS & operator = (const AliMUONClusterFinderVS& rhs); +protected: + TClonesArray* fDigits2; // Digits + Int_t fNdigits2; // Number of Digits + AliMUONSegmentation* fSegmentation2; // Chamber segmentation + AliMUONHitMapA1* fHitMap2; // Hit Map + AliMUONDigit* fDig[100][2]; // current list of digits + Int_t fIx[100][2]; // current list of x-pad-coord. + Int_t fIy[100][2]; // current list of y-pad-coord. + Float_t fX[100][2]; // current list of x-coord. + Float_t fY[100][2]; // current list of y-coord. + Int_t fIndLocal[100][2]; // indices of local maxima + Int_t fNLocal[2]; // Number of local maxima + Int_t fQ[100][2]; // current list of charges + Int_t fMul[2]; // current multiplicity +// Current Fit + Double_t fXFit[2]; // x-coordinate + Double_t fYFit[2]; // y-coordinate + Double_t fQrFit[2]; // charge ratio + Float_t fChi2[2]; // chi2 of fit + Float_t fXInit[2]; // start values + Float_t fYInit[2]; // start values + Float_t fQrInit[2]; // start values + Int_t fFitStat; // status of fit + +// Selected track for debugging + Int_t fTrack[2]; // Only digits with main contributions from these tracks are + // considered +// Return pointer to raw clusters + ClassDef(AliMUONClusterFinderVS,1) //Class for clustering and reconstruction of space points +}; +#endif + + + + + + + + + + diff --git a/MUON/AliMUONClusterFinderv0.h b/MUON/AliMUONClusterFinderv0.h index 0d7c24f35fd..fb7dadfd469 100644 --- a/MUON/AliMUONClusterFinderv0.h +++ b/MUON/AliMUONClusterFinderv0.h @@ -3,6 +3,7 @@ /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ + /* $Id$ */ //////////////////////////////////////////////// diff --git a/MUON/AliMUONConst.h b/MUON/AliMUONConst.h index 4010a709d36..34ac9e13964 100644 --- a/MUON/AliMUONConst.h +++ b/MUON/AliMUONConst.h @@ -3,8 +3,6 @@ /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ -/* $Id$ */ - ///////////////////////////////////////////////////////////////////////////// // //--------------------------------------------------------------------- @@ -22,7 +20,7 @@ const Float_t zend = 511.+0.15-2*0.001; // z-out position of first chamber // // -const Float_t adc_satm = 1024; // dynamic range (10 bits) +const Float_t adc_satm = 2048; // dynamic range (10 bits) const Int_t zero_supm = 6; // zero suppression const Float_t sig_noise = 500.; // electronics noise (no. of electrons) const Float_t kScale=1.; diff --git a/MUON/AliMUONDigit.cxx b/MUON/AliMUONDigit.cxx new file mode 100644 index 00000000000..2e2cbedc55d --- /dev/null +++ b/MUON/AliMUONDigit.cxx @@ -0,0 +1,59 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 22:03:22 morsch +Was before in DataStructures.cxx + +*/ + +#include "AliMUONDigit.h" + +ClassImp(AliMUONDigit) +//_____________________________________________________________________________ +AliMUONDigit::AliMUONDigit(Int_t *digits) +{ + // + // Creates a MUON digit object to be updated + // + fPadX = digits[0]; + fPadY = digits[1]; + fSignal = digits[2]; + fPhysics = digits[3]; + fHit = digits[4]; + +} +//_____________________________________________________________________________ +AliMUONDigit::AliMUONDigit(Int_t *tracks, Int_t *charges, Int_t *digits) +{ + // + // Creates a MUON digit object + // + 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() +{ + // Destructor +} diff --git a/MUON/AliMUONDigit.h b/MUON/AliMUONDigit.h new file mode 100644 index 00000000000..78598969b95 --- /dev/null +++ b/MUON/AliMUONDigit.h @@ -0,0 +1,26 @@ +#ifndef ALIMUONDIGIT_H +#define ALIMUONDIGIT_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include + +class AliMUONDigit : public TObject { + public: + 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]; // primary tracks making this digit (up to 10) + Int_t fPhysics; // physics contribution to signal + Int_t fHit; // hit number - temporary solution + public: + AliMUONDigit() {} + AliMUONDigit(Int_t *digits); + AliMUONDigit(Int_t *tracks, Int_t *charges, Int_t *digits); + virtual ~AliMUONDigit(); + ClassDef(AliMUONDigit,1) //Digits for set:MUON +}; +#endif diff --git a/MUON/AliMUONDisplay.cxx b/MUON/AliMUONDisplay.cxx new file mode 100644 index 00000000000..8b926cc72e2 --- /dev/null +++ b/MUON/AliMUONDisplay.cxx @@ -0,0 +1,1354 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.15 2000/06/14 14:37:53 morsch +method Trigger() modified + +Revision 1.1.2.14 2000/06/09 21:57:09 morsch +Bug in color scale diplay corrected. +Most coding rule violations corrected. + +Revision 1.1.2.13 2000/05/02 11:57:27 morsch +Coding rules RN3, RN13, RN17 violations corrected. + +Revision 1.1.2.12 2000/04/26 12:27:33 morsch +Mods for trigger display (P. Crochet): +- color code versus time for pad hits in trigger chambers +- call to TriggerDecision corrected + +Revision 1.1.2.11 2000/04/26 09:04:46 morsch +Obsolete cathode correlation related code removed. + +Revision 1.1.2.10 2000/04/19 19:43:47 morsch +change NCH to kNCH as in AliMUON.h +no more TreeC related methods + +Revision 1.1.2.9 2000/03/20 18:10:33 morsch +Trigger method for "online" trigger decission added + +Revision 1.1.2.8 2000/02/23 10:12:01 morsch +Dont't try to draw reconstructed hit coordinates for Trigger Chambers. +General clean-up of commented code. + +Revision 1.1.2.7 2000/02/17 14:36:55 morsch +Display of Trigger hits and clusters added. +Displacement between clusters and hits has to be investigated and corrected ! (A.M.) + +Revision 1.1.2.6 2000/02/15 10:19:42 morsch +Previous log messages included + +Revision 1.1.2.5 2000/02/15 10:09:09 morsch +Log Message added + +Revision 1.1.2.4 2000/02/08 09:17:16 gosset +One more improvement of MUON display: +same zoom for both cathode planes in a chamber + +Revision 1.1.2.3 2000/02/07 15:37:21 gosset +A few improvements of the MUON display: +new buttons to change either chamber or cathode, +added to the more complicated way +(right mouse click and explicit filling of chamber and cathode) + +Revision 1.1.2.2 2000/02/04 10:57:34 gosset +Z position of the chambers: +it was the Z position of the stations; +it is now really the Z position of the chambers. + !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS" + !!!! AND "AliMUONChamber::ZPosition" + !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ" + !!!! AND "AliMUONChamber::Z" +*/ + +////////////////////////////////////////////////////////////////////////// +// // +// AliDisplay // +// // +// Utility class to display ALICE outline, tracks, hits,.. // +// // +////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AliRun.h" +#include "AliDetector.h" +#include "AliMUON.h" +#include "AliMUONDisplay.h" +#include "AliMUONPoints.h" +#include "TParticle.h" +#include "AliMUONTriggerDecision.h" + +#include "AliMUONHit.h" +#include "AliMUONPadHit.h" +#include "AliMUONDigit.h" +#include "AliMUONRawCluster.h" + +#include "AliMUONSegmentation.h" +#include "AliMUONResponse.h" +#include "AliMUONChamber.h" + +// to manage the same zoom on both cathodes + + + +ClassImp(AliMUONDisplay) + + +//_____________________________________________________________________________ +AliMUONDisplay::AliMUONDisplay() +{ +// Constructor + fPoints = 0; + fPhits = 0; + fRpoints = 0; + fR2points = 0; + fCpoints = 0; + fCanvas = 0; + fNextCathode = kFALSE; +} + +//_____________________________________________________________________________ +AliMUONDisplay::AliMUONDisplay(Int_t size) +{ +// Create an event display object. +// A canvas named "edisplay" is created with a vertical size in pixels +// +// A QUICK Overview of the Event Display functions +// =============================================== +// +// The event display can ve invoked by executing the macro "display.C" +// A canvas like in the picture below will appear. +// +// On the left side of the canvas, the following buttons appear: +// *Next* to move to the next event +// *Previous* to move to the previous event + +// *Pick* Select this option to be able to point on a track with the +// mouse. Once on the track, use the right button to select +// an action. For example, select SetMarkerAttributes to +// change the marker type/color/size for the track. +// *Zoom* Select this option (default) if you want to zoom. +// To zoom, simply select the selected area with the left button. +// *UnZoom* To revert to the previous picture size. +// +// slider R On the left side, the vertical slider can be used to +// set the default picture size. +// +// When you are in Zoom mode, you can click on the black part of the canvas +// to select special options with the right mouse button. + +// +// When you are in pick mode, you can "Inspect" the object pointed by the mouse. +// When you are on a track, select the menu item "InspectParticle" +// to display the current particle attributes. +// +// You can activate the Root browser by selecting the Inspect menu +// in the canvas tool bar menu. Then select "Start Browser" +// This will open a new canvas with the browser. At this point, you may want +// to display some histograms (from the Trees). Go to the "File" menu +// of the browser and click on "New canvas". +// In the browser, click on item "ROOT files" in the left pane. +// Click on galice.root. +// Click on TH +// Click on TPC for example +// Click on any variable (eg TPC.fX) to histogram the variable. +// +// If you are lost, you can click on HELP in any Root canvas or browser. +//Begin_Html +/* + +*/ +//End_Html + + + fPad = 0; + + gAlice->SetDisplay(this); + + // Initialize display default parameters + SetRange(200,2000); + // Set front view by default + fTheta = 0; + fPhi = -90; + fPsi = 0; + fChamber = 1; + fCathode = 1; + // fRzone = 1.e10; + fDrawClusters = kTRUE; + fDrawCoG = kTRUE; + fDrawCoG = kTRUE; + fZoomMode = 1; + fZooms = 0; + fClustersCuts = 0; + fPoints = 0; + fPhits = 0; + fRpoints = 0; + fR2points = 0; + fCpoints = 0; + // Create colors + CreateColors(); + // Create display canvas + Int_t ysize = size; + if (ysize < 100) ysize = 750; + Int_t xsize = Int_t(size*830./ysize); + fCanvas = new TCanvas("Canvas", "MUON Clusters Display",14,47,xsize,ysize); + fCanvas->ToggleEventStatus(); + + // Create main display pad + fPad = new TPad("viewpad", "MUON display",0.15,0,0.9,1); + fPad->Draw(); + fPad->Modified(); + fPad->SetFillColor(30); + fPad->SetBorderSize(2); + + fCanvas->cd(); + + // Create colors pad + fColPad = new TPad("colpad", "Colors pad",0.9,0,1,1); + fColPad->Draw(); + fColPad->SetFillColor(17); + fColPad->SetBorderSize(2); + fColPad->cd(); + DisplayColorScale(); + + fCanvas->cd(); + // Create user interface control pad + DisplayButtons(); + fCanvas->cd(); + + // Create Range and mode pad + Float_t dxtr = 0.15; + Float_t dytr = 0.45; + fTrigPad = new TPad("trigger", "range and mode pad",0,0,dxtr,dytr); + fTrigPad->SetEditable(kFALSE); + fTrigPad->Draw(); + fTrigPad->cd(); + fTrigPad->SetFillColor(22); + fTrigPad->SetBorderSize(2); + fRangeSlider = new TSlider("range","range",0.7,0.42,0.9,0.98); + fRangeSlider->SetObject(this); + char pickmode[] = "gAlice->Display()->SetPickMode()"; + Float_t db = 0.09; + fPickButton = new TButton("Pick",pickmode,0.05,0.32,0.65,0.32+db); + fPickButton->SetFillColor(38); + fPickButton->Draw(); + char zoommode[] = "gAlice->Display()->SetZoomMode()"; + fZoomButton = new TButton("Zoom",zoommode,0.05,0.21,0.65,0.21+db); + fZoomButton->SetFillColor(38); + fZoomButton->Draw(); + fArcButton = new TArc(.8,fZoomButton->GetYlowNDC()+0.5*db,0.33*db); + fArcButton->SetFillColor(kGreen); + fArcButton->Draw(); + char butUnzoom[] = "gAlice->Display()->UnZoom()"; + TButton *button = new TButton("UnZoom",butUnzoom,0.05,0.05,0.95,0.15); + button->SetFillColor(38); + button->Draw(); + AppendPad(); // append display object as last object to force selection + + fCanvas->cd(); + fCanvas->Update(); + fNextCathode = kFALSE; +} + +AliMUONDisplay::AliMUONDisplay(const AliMUONDisplay & display) +{ +// Dummy copy constructor + ; +} + + + +//_____________________________________________________________________________ +AliMUONDisplay::~AliMUONDisplay() +{ + // Delete space point structure + if (fPoints) fPoints->Delete(); + delete fPoints; + fPoints = 0; + // + 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; +} + +//_____________________________________________________________________________ +void AliMUONDisplay::Clear(Option_t *) +{ +// Delete graphics temporary objects +} + +//_____________________________________________________________________________ +void AliMUONDisplay::DisplayButtons() +{ +// Create the user interface buttons + + + fButtons = new TPad("buttons", "newpad",0,0.45,0.15,1); + fButtons->SetEditable(kFALSE); + fButtons->Draw(); + fButtons->SetFillColor(38); + fButtons->SetBorderSize(2); + fButtons->cd(); + +// Int_t butcolor = 33; + Float_t dbutton = 0.08; + Float_t y = 0.96; + Float_t dy = 0.014; + Float_t x0 = 0.05; + Float_t x1 = 0.95; + + TButton *button; + char but1[] = "gAlice->Display()->ShowNextEvent(1)"; + button = new TButton("Event +", but1, x0, y - dbutton, x1, y); + button->SetFillColor(38); + button->Draw(); + + y -= dbutton + dy; + char but2[] = "gAlice->Display()->ShowNextEvent(-1)"; + button = new TButton("Event -", but2, x0, y - dbutton, x1, y); + button->SetFillColor(38); + button->Draw(); + + y -= dbutton + dy; + char but3[] = "((AliMUONDisplay*)(gAlice->Display()))->NextChamber(1)"; + button = new TButton("Chamber +", but3, x0, y - dbutton, x1, y); + button->SetFillColor(38); + button->Draw(); + + y -= dbutton + dy; + char but4[] = "((AliMUONDisplay*)(gAlice->Display()))->NextChamber(-1)"; + button = new TButton("Chamber -", but4, x0, y - dbutton, x1, y); + button->SetFillColor(38); + button->Draw(); + + y -= dbutton + dy; + char but5[] = "((AliMUONDisplay*)(gAlice->Display()))->SetChamberAndCathode(1,1)"; + button = new TButton("Chamber 1", but5, x0, y - dbutton, x1, y); + button->SetFillColor(38); + button->Draw(); + + y -= dbutton + dy; + char but6[] = "((AliMUONDisplay*)(gAlice->Display()))->NextCathode()"; + button = new TButton("Cathode <>", but6, x0, y - dbutton, x1, y); + button->SetFillColor(38); + button->Draw(); + + y -= dbutton + dy; + char but7[] = "((AliMUONDisplay*)(gAlice->Display()))->Trigger()"; + button = new TButton("Trigger", but7, x0, y - dbutton, x1, y); + button->SetFillColor(38); + button->Draw(); + + // display logo + TDiamond *diamond = new TDiamond(0.05,0.015,0.95,0.22); + diamond->SetFillColor(50); + diamond->SetTextAlign(22); + diamond->SetTextColor(5); + diamond->SetTextSize(0.11); + diamond->Draw(); + diamond->AddText(".. "); + diamond->AddText("ROOT"); + diamond->AddText("MUON"); + diamond->AddText("... "); + diamond->AddText(" "); +} + +//_____________________________________________________________________________ +void AliMUONDisplay::CreateColors() +{ +// Create the colors palette used to display clusters + + Int_t k,i; + Int_t color; + Float_t r,g,b; + + for (k=1;k<=5;k++) { + switch(k) { + case 1: + for (i=1;i<=5;i++) { + r=1.; + g=i*0.2; + b=0.; + color=i; + color=260+23-color; + new TColor(color,r,g,b); + } + break; + case 2: + for (i=1;i<=4;i++) { + r=1.1-i*0.2; + g=1.; + b=0.; + color=i+5; + color=260+23-color; + new TColor(color,r,g,b); + } + break; + case 3: + for (i=1;i<=4;i++) { + r=0.; + g=1.; + b=i*0.2+0.2; + color=i+9; + color=260+23-color; + new TColor(color,r,g,b); + } + break; + case 4: + for (i=1;i<=4;i++) { + r=0.; + g=1.1-i*0.2; + b=1.; + color=i+13; + color=260+23-color; + new TColor(color,r,g,b); + } + break; + case 5: + for (i=1;i<=5;i++) { + r=i*0.2; + g=0.; + b=1.; + color=i+17; + color=260+23-color; + new TColor(color,r,g,b); + } + break; + } + } +} + +//_____________________________________________________________________________ +void AliMUONDisplay::DisplayColorScale() +{ +// Display pulse height color scale + Int_t i; + Int_t color; + Float_t xlow, ylow, xup, yup, hs; + Float_t x1, y1, x2, y2; + x1 = y1 = 0; + x2 = y2 = 1.0; + + TText *text = new TText(0,0,""); + text->SetTextFont(61); + text->SetTextSize(0.2); + text->SetTextAlign(22); + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONChamber *iChamber = &(pMUON->Chamber(fChamber-1)); + AliMUONResponse * response=iChamber->ResponseModel(); + Int_t adcmax=1024; + if (response) adcmax= (Int_t) response->MaxAdc(); + + + TBox *box; + char label[8]; +//*-* draw colortable boxes + hs = (y2-y1)/Float_t(22); + xlow=x1+.05; + xup=x2-0.5; + for (i=0;i<22;i++) { + ylow = y1 + hs*(Float_t(i)); + yup = y1 + hs*(Float_t(i+1)); + color = 261+i; + 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); + box->Draw(); + box->SetFillColor(color); + text->DrawText(xlow+0.7, 0.5*(ylow+yup),label); + } +} + +//______________________________________________________________________________ +Int_t AliMUONDisplay::DistancetoPrimitive(Int_t px, Int_t) +{ +// Compute distance from point px,py to objects in event + + gPad->SetCursor(kCross); + + if (gPad == fTrigPad) return 9999; + + const Int_t kBig = 9999; + Int_t dist = kBig; + Float_t xmin = gPad->GetX1(); + Float_t xmax = gPad->GetX2(); + Float_t dx = 0.02*(xmax - xmin); + Float_t x = gPad->AbsPixeltoX(px); + if (x < xmin+dx || x > xmax-dx) return dist; + + if (fZoomMode) return 0; + else return 7; +} + +//_____________________________________________________________________________ +void AliMUONDisplay::Draw(Option_t *) +{ +// Display current event + + fPad->cd(); + + DrawView(fTheta, fPhi, fPsi); + // Display the event number and title + fPad->cd(); + DrawTitle(); +} + +void AliMUONDisplay::DrawSegmentation() +{ +// Draw graphical representation of segmenatation +// Attention: still experimental code + Int_t icat=1; + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONChamber* iChamber; + AliMUONSegmentation* seg; + iChamber = &(pMUON->Chamber(fChamber)); + seg=iChamber->SegmentationModel(icat); + Float_t zpos=iChamber->Z(); + Float_t r=iChamber->ROuter(); + + TMarker3DBox *marker; + if (icat == 1) { + for (Int_t j=0; jNpy(); j++) { + Float_t y0; + y0=j*seg->Dpy()-seg->Dpy()/2.; + for (seg->FirstPad(0.,y0,300,0.); + seg->MorePads(); + seg->NextPad()) + { + if (seg->ISector()==0) continue; + Float_t x,y; + seg->GetPadCxy(seg->Ix(), seg->Iy(), x, y); + Float_t dpx=seg->Dpx(seg->ISector())/2; + Float_t dpy=seg->Dpy(seg->ISector())/2; + marker=new TMarker3DBox(x,y,zpos,dpx,dpy,0,0,0); + marker->SetLineColor(seg->ISector()+1); + marker->SetFillStyle(1001); + marker->SetFillColor(0); + marker->Draw(); + } + } + } else { + for (Int_t j=0; j<250; j++) { + Float_t x0=j*seg->Dpx(); + Float_t y0=TMath::Sqrt(r*r-x0*x0); + + for (seg->FirstPad(x0,0,0,y0); + seg->MorePads(); + seg->NextPad()) + { + if (seg->ISector()==0) continue; + + Float_t x,y; + seg->GetPadCxy(seg->Ix(), seg->Iy(), x, y); + Float_t dpx=seg->Dpx(seg->ISector())/2; + Float_t dpy=seg->Dpy(seg->ISector())/2; + marker=new TMarker3DBox(x,y,zpos,dpx,dpy,0,0,0); + marker->SetLineColor(seg->ISector()+1); + marker->SetFillStyle(1001); + marker->SetFillColor(0); + marker->Draw(); + } + } + } +} + +//_____________________________________________________________________________ +void AliMUONDisplay::DrawClusters() +{ +// Draw clusters for MUON chambers + + Int_t ndigits, digit; + TObjArray *points; + AliMUONPoints *pm; + + + fClustersCuts = 0; + points = Points(); + if (!points) return; + ndigits = points->GetEntriesFast(); + for (digit=0;digitUncheckedAt(digit); + if (!pm) continue; + Float_t *pxyz; + pxyz=pm->GetP(); + for (Int_t im=0;im<3;im++) { + TMarker3DBox *marker=pm->GetMarker(im); + if (marker) + marker->Draw(); + } + pm->Draw(); + fClustersCuts +=pm->GetN(); + } +} + +//_____________________________________________________________________________ +void AliMUONDisplay::DrawHits() +{ +// Draw hits for MUON chambers + + LoadHits(fChamber); + + Int_t ntracks, track; + TObjArray *points; + AliMUONPoints *pm; + + fHitsCuts = 0; + points = Phits(); + if (!points) return; + ntracks = points->GetEntriesFast(); + for (track=0;trackUncheckedAt(track); + if (!pm) continue; + pm->Draw(); + fHitsCuts += pm->GetN(); + } +} + + +//_____________________________________________________________________________ +void AliMUONDisplay::DrawCoG() +{ +// Draw hits for MUON chambers + if (!fDrawCoG) return; + if (fChamber > 10) return; + LoadCoG(fChamber,fCathode); + + Int_t ncog, icog; + TObjArray *points; + AliMUONPoints *pm; + + points = Rpoints(); + if (!points) return; + ncog = points->GetEntriesFast(); + for (icog=0;icogUncheckedAt(icog); + if (!pm) continue; + pm->Draw(); + } +} +void AliMUONDisplay::DrawCoG2() +{ +// Draw hits for MUON chambers + + if (!fDrawCoG) return; + if (fChamber > 10) return; + + if (fCathode==1) { + LoadCoG2(fChamber,2); + } else if (fCathode==2) { + LoadCoG2(fChamber,1); + } + + Int_t ncog, icog; + TObjArray *points; + AliMUONPoints *pm; + + points = R2points(); + if (!points) return; + ncog = points->GetEntriesFast(); + for (icog=0;icogUncheckedAt(icog); + if (!pm) continue; + pm->Draw(); + } +} +//_____________________________________________________________________________ + +void AliMUONDisplay::DrawTitle(Option_t *option) +{ +// Draw the event title + + Float_t xmin = gPad->GetX1(); + Float_t xmax = gPad->GetX2(); + Float_t ymin = gPad->GetY1(); + Float_t ymax = gPad->GetY2(); + Float_t dx = xmax-xmin; + Float_t dy = ymax-ymin; + + if (strlen(option) == 0) { + TPaveText *title = new TPaveText(xmin +0.01*dx, ymax-0.09*dy, xmin +0.5*dx, ymax-0.01*dy); +// title->SetTextSize(0.023932); + title->SetTextSize(0.02); + title->SetBit(kCanDelete); + title->SetFillColor(42); + title->Draw(); + char ptitle[100]; + sprintf(ptitle, "Alice event:%d Run:%d Chamber:%d Cathode:%d", + gAlice->GetHeader()->GetEvent(), + gAlice->GetHeader()->GetRun(), + fChamber, + fCathode); + title->AddText(ptitle); + Int_t nparticles = gAlice->Particles()->GetEntriesFast(); + sprintf(ptitle,"Nparticles = %d Nhits = %d Npads fired = %d", + nparticles, fHitsCuts,fClustersCuts); + title->AddText(ptitle); + } else { + TPaveLabel *label = new TPaveLabel(xmin +0.01*dx, ymax-0.07*dy, xmin +0.2*dx, ymax-0.01*dy,option); + label->SetBit(kCanDelete); + label->SetFillColor(42); + label->Draw(); + } +} + +//_____________________________________________________________________________ +void AliMUONDisplay::DrawView(Float_t theta, Float_t phi, Float_t psi) +{ +// Draw a view of MUON clusters + printf("\n Draw View"); + + gPad->SetCursor(kWatch); + // gPad->SetFillColor(39); + gPad->SetFillColor(1); + gPad->Clear(); + // gPad->SetFillColor(39); + gPad->SetFillColor(1); + + + Int_t iret=0; + TView *view = new TView(1); + + Float_t range = fRrange*fRangeSlider->GetMaximum(); + view->SetRange(-range,-range,-range,range, range, range); + // zoom back to full scale only if DrawView not called from NextCathode + if (!fNextCathode) { + fZoomX0[0] = -1; + fZoomY0[0] = -1; + fZoomX1[0] = 1; + fZoomY1[0] = 1; + fZooms = 0; + } + +// Display MUON Chamber Geometry +// gAlice->GetGeometry()->Draw("same"); + char nodeName[7]; + sprintf(nodeName,"MUON%d",100+fChamber); + printf("\n Node name %s", nodeName); + + TNode *node1=gAlice->GetGeometry()->GetNode(nodeName); + if (node1) node1->Draw("same"); +//add clusters to the pad + DrawClusters(); + printf("Node name %s", nodeName); + DrawHits(); + DrawCoG(); + DrawCoG2(); +// DrawSegmentation(); + // add itself to the list (must be last) + AppendPad(); + view->SetView(phi, theta, psi, iret); +} + + +//______________________________________________________________________________ +void AliMUONDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py) +{ +// Execute action corresponding to the mouse event + + static Float_t x0, y0, x1, y1; + + static Int_t pxold, pyold; + static Int_t px0, py0; + static Int_t linedrawn; + Float_t temp; + + if (px == 0 && py == 0) { //when called by sliders + if (event == kButton1Up) { + Draw(); + } + return; + } + if (!fZoomMode && gPad->GetView()) { + gPad->GetView()->ExecuteRotateView(event, px, py); + return; + } + + // something to zoom ? + gPad->SetCursor(kCross); + + switch (event) { + + case kButton1Down: + gVirtualX->SetLineColor(-1); + gPad->TAttLine::Modify(); //Change line attributes only if necessary + x0 = gPad->AbsPixeltoX(px); + y0 = gPad->AbsPixeltoY(py); + px0 = px; py0 = py; + pxold = px; pyold = py; + linedrawn = 0; + return; + + case kButton1Motion: + if (linedrawn) gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow); + pxold = px; + pyold = py; + linedrawn = 1; + gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow); + return; + + case kButton1Up: + gPad->GetCanvas()->FeedbackMode(kFALSE); + if (px == px0) return; + if (py == py0) return; + x1 = gPad->AbsPixeltoX(px); + y1 = gPad->AbsPixeltoY(py); + + if (x1 < x0) {temp = x0; x0 = x1; x1 = temp;} + if (y1 < y0) {temp = y0; y0 = y1; y1 = temp;} + gPad->Range(x0,y0,x1,y1); + if (fZooms < kMAXZOOM-1) { + fZooms++; + fZoomX0[fZooms] = x0; + fZoomY0[fZooms] = y0; + fZoomX1[fZooms] = x1; + fZoomY1[fZooms] = y1; + } + gPad->Modified(kTRUE); + return; + } +} + +//___________________________________________ +void AliMUONDisplay::LoadDigits(Int_t chamber, Int_t cathode) +{ +// Read digits info and store x,y,z info in arrays fPoints +// Loop on all detectors + + if (chamber > 14) return; + printf(" chamber %d \n",chamber); + fChamber=chamber; + fCathode=cathode; + + ResetPoints(); + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONChamber* iChamber; + AliMUONSegmentation* segmentation; + AliMUONResponse* response; + + TClonesArray *muonDigits = pMUON->DigitsAddress(chamber-1); + if (muonDigits == 0) return; + + gAlice->ResetDigits(); + + Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); + gAlice->TreeD()->GetEvent(nent-2+cathode-1); + Int_t ndigits = muonDigits->GetEntriesFast(); + if (ndigits == 0) return; + if (fPoints == 0) fPoints = new TObjArray(ndigits); + + iChamber = &(pMUON->Chamber(chamber-1)); + + segmentation = iChamber->SegmentationModel(cathode); + response = iChamber->ResponseModel(); + Float_t zpos=iChamber->Z(); + AliMUONDigit *mdig; + AliMUONPoints *points = 0; + TMarker3DBox *marker=0; + // + //loop over all digits and store their position + + Int_t npoints=1; + Float_t adcmax=1024; + if (response) adcmax= response->MaxAdc(); + + for (Int_t digit=0;digitUncheckedAt(digit); + // + // First get all needed parameters + // + Int_t charge=mdig->fSignal; + Int_t index=Int_t(TMath::Log(charge)/(TMath::Log(adcmax)/22)); + Int_t color=261+index; + Int_t colorTrigger=2; + if (color>282) color=282; + + if (chamber > 10) { // trigger chamber + Int_t sumCharge=0; + for (Int_t icharge=0; icharge<10; icharge++) { + sumCharge=sumCharge+mdig->fTcharges[icharge]; + } + Int_t testCharge=sumCharge-(Int_t(sumCharge/10))*10; + if(sumCharge<=10||testCharge>0) { + colorTrigger=color; + } else { + colorTrigger=5; + } + } + + // get the center of the pad - add on x and y half of pad size + Float_t xpad, ypad; + segmentation->GetPadCxy(mdig->fPadX, mdig->fPadY,xpad, ypad); + + Int_t isec=segmentation->Sector(mdig->fPadX, mdig->fPadY); + Float_t dpx=segmentation->Dpx(isec)/2; + Float_t dpy=segmentation->Dpy(isec)/2; + Int_t nPara, offset; + segmentation->GetNParallelAndOffset(mdig->fPadX,mdig->fPadY, + &nPara,&offset); + // + // Then set the objects + // + points = new AliMUONPoints(npoints); + fPoints->AddAt(points,digit); + if (chamber > 10) { + points->SetMarkerColor(colorTrigger); + } else { + points->SetMarkerColor(color); + } + points->SetMarkerStyle(21); + points->SetMarkerSize(0.5); + points->SetParticle(-1); + points->SetHitIndex(-1); + points->SetTrackIndex(-1); + points->SetDigitIndex(digit); + points->SetPoint(0,xpad,ypad,zpos); + for (Int_t imark=0;imarkGetPadCxy(mdig->fPadX + imark*offset, mdig->fPadY,xpad, ypad); + marker=new TMarker3DBox(xpad,ypad,zpos,dpx,dpy,0,0,0); + marker->SetLineColor(2); + marker->SetFillStyle(1001); + marker->SetFillColor(color); + marker->SetRefObject((TObject*)points); + points->Set3DMarker(imark, marker); + } + } +} +//___________________________________________ +void AliMUONDisplay::LoadCoG(Int_t chamber, Int_t cathode) +{ +// Read raw clusters info and store x,y,z info in arrays fRpoints +// Loop on all detectors + + if (chamber > 10) return; + + ResetRpoints(); + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONChamber* iChamber; + + TClonesArray *muonRawClusters = pMUON->RawClustAddress(chamber-1); + if (muonRawClusters == 0) return; + + pMUON->ResetRawClusters(); + + + Int_t nent=(Int_t)gAlice->TreeR()->GetEntries(); + gAlice->TreeR()->GetEvent(nent-2+cathode-1); + Int_t nrawcl = muonRawClusters->GetEntriesFast(); + if (nrawcl == 0) return; + if (fRpoints == 0) fRpoints = new TObjArray(nrawcl); + + iChamber = &(pMUON->Chamber(chamber-1)); + Float_t zpos=iChamber->Z(); + AliMUONRawCluster *mRaw; + AliMUONPoints *points = 0; + // + //loop over all raw clusters and store their position + points = new AliMUONPoints(nrawcl); + for (Int_t iraw=0;irawUncheckedAt(iraw); + fRpoints->AddAt(points,iraw); + points->SetMarkerColor(51); + points->SetMarkerStyle(2); + points->SetMarkerSize(1.); + points->SetParticle(-1); + points->SetHitIndex(-1); + points->SetTrackIndex(-1); + points->SetDigitIndex(-1); + points->SetPoint(iraw,mRaw->fX[0],mRaw->fY[0],zpos); + } +} +//___________________________________________ +void AliMUONDisplay::LoadCoG2(Int_t chamber, Int_t cathode) +{ +// Read raw clusters info and store x,y,z info in arrays fRpoints +// Loop on all detectors + + if (chamber > 10) return; + + ResetR2points(); + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONChamber* iChamber; + + TClonesArray *muonRawClusters = pMUON->RawClustAddress(chamber-1); + if (muonRawClusters == 0) return; + + pMUON->ResetRawClusters(); + + Int_t nent=(Int_t)gAlice->TreeR()->GetEntries(); + gAlice->TreeR()->GetEvent(nent-2+cathode-1); + Int_t nrawcl = muonRawClusters->GetEntriesFast(); + if (nrawcl == 0) return; + if (fR2points == 0) fR2points = new TObjArray(nrawcl); + + iChamber = &(pMUON->Chamber(chamber-1)); + Float_t zpos=iChamber->Z(); + AliMUONRawCluster *mRaw; + AliMUONPoints *points = 0; + // + //loop over all raw clusters and store their position + points = new AliMUONPoints(nrawcl); + for (Int_t iraw=0;irawUncheckedAt(iraw); + fR2points->AddAt(points,iraw); + points->SetMarkerColor(51); + points->SetMarkerStyle(4); + points->SetMarkerSize(1.3); + points->SetParticle(-1); + points->SetHitIndex(-1); + points->SetTrackIndex(-1); + points->SetDigitIndex(-1); + points->SetPoint(iraw,mRaw->fX[0],mRaw->fY[0],zpos); + } +} +//___________________________________________ +void AliMUONDisplay::LoadHits(Int_t chamber) +{ +// Read hits info and store x,y,z info in arrays fPhits +// Loop on all detectors + + if (chamber > 14) return; + Int_t track; + + fChamber=chamber; + + ResetPhits(); + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONChamber* iChamber; + + iChamber = &(pMUON->Chamber(chamber-1)); + Float_t zpos=iChamber->Z(); + + Int_t ntracks = (Int_t)gAlice->TreeH()->GetEntries(); + Int_t nthits=0; + for (track=0; trackResetHits(); + gAlice->TreeH()->GetEvent(track); + TClonesArray *muonHits = pMUON->Hits(); + if (muonHits == 0) return; + nthits += muonHits->GetEntriesFast(); + } + if (fPhits == 0) fPhits = new TObjArray(nthits); + Int_t nhold=0; + for (track=0; trackResetHits(); + gAlice->TreeH()->GetEvent(track); + TClonesArray *muonHits = pMUON->Hits(); + if (muonHits == 0) return; + Int_t nhits = muonHits->GetEntriesFast(); + if (nhits == 0) continue; + AliMUONHit *mHit; + AliMUONPoints *points = 0; + Int_t npoints=1; + for (Int_t hit=0;hitUncheckedAt(hit); + Int_t nch = mHit->fChamber; // chamber number + if (nch != chamber) continue; + // + // Retrieve info and set the objects + // + points = new AliMUONPoints(npoints); + fPhits->AddAt(points,nhold+hit); + points->SetMarkerColor(kRed); + points->SetMarkerStyle(5); + points->SetMarkerSize(1.); + points->SetParticle(mHit->fTrack); + points->SetHitIndex(hit); + points->SetTrackIndex(track); + points->SetDigitIndex(-1); + points->SetPoint(0,mHit->fX,mHit->fY,zpos); + } + nhold+=nhits; + } +} + +//_____________________________________________________________________________ +void AliMUONDisplay::Paint(Option_t *) +{ +// Paint miscellaneous items +} + +//_____________________________________________________________________________ +void AliMUONDisplay::SetPickMode() +{ +// Set parameters for pick mode. +// + fZoomMode = 0; + + fArcButton->SetY1(fPickButton->GetYlowNDC()+0.5*fPickButton->GetHNDC()); + fTrigPad->Modified(); +} + +//_____________________________________________________________________________ +void AliMUONDisplay::SetZoomMode() +{ +// Set parameters for zoom mode + fZoomMode = 1; + + fArcButton->SetY1(fZoomButton->GetYlowNDC()+0.5*fZoomButton->GetHNDC()); + fTrigPad->Modified(); +} + +//_____________________________________________________________________________ +void AliMUONDisplay::NextChamber(Int_t delta) +{ + // to go from chamber to next chamber if delta = 1 + // or previous chamber otherwise + if (delta == 1) { + if (fChamber < kNCH) fChamber++; + } else { + if (fChamber > 1) fChamber--; + } + if (!fPad) return; + fPad->Clear(); + LoadDigits(fChamber, fCathode); + Draw(); +} + +//_____________________________________________________________________________ +void AliMUONDisplay::NextCathode() +{ + // to switch to other cathode plane + if (!fPad) return; + fPad->Clear(); + if (fCathode == 1) { + LoadDigits(fChamber, 2); + } else { + LoadDigits(fChamber, 1); + } + fNextCathode = kTRUE; // to keep the same zoom + Draw(); + fNextCathode = kFALSE; + TPad *pad = (TPad*)gPad->GetPadSave(); + pad->Range(fZoomX0[fZooms], fZoomY0[fZooms], + fZoomX1[fZooms], fZoomY1[fZooms]); + pad->Modified(); + fPad->cd(); + DrawTitle(); +} + +//_____________________________________________________________________________ +void AliMUONDisplay::Trigger() +{ + // returns Trigger Decision for current event + AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1); + decision->Trigger(); +} + + +//_____________________________________________________________________________ +void AliMUONDisplay::SetChamberAndCathode(Int_t chamber, Int_t cathode) +{ +// Set chamber and cathode number + fChamber = chamber; + fCathode = cathode; + + if (!fPad) return; + fPad->Clear(); + LoadDigits(chamber,cathode); + Draw(); +} + +void AliMUONDisplay::SetEvent(Int_t newevent) +{ +// Chose event + gAlice->GetEvent(newevent); + fEvent=newevent; + if (!gAlice->TreeD()) return; + if (!fPad) return; + fPad->Clear(); + LoadDigits(fChamber,fCathode); + Draw(); +} + +//_____________________________________________________________________________ +void AliMUONDisplay::SetRange(Float_t rrange, Float_t zrange) +{ +// Set view range along R and Z + fRrange = rrange; + fZrange = zrange; + + if (!fPad) return; + fPad->Clear(); + Draw(); +} + +//_____________________________________________________________________________ +void AliMUONDisplay::SetView(Float_t theta, Float_t phi, Float_t psi) +{ +// change viewing angles for current event + + fPad->cd(); + fPhi = phi; + fTheta = theta; + fPsi = psi; + Int_t iret = 0; + + TView *view = gPad->GetView(); + if (view) view->SetView(fPhi, fTheta, fPsi, iret); + else Draw(); + gPad->Modified(); +} + +//_____________________________________________________________________________ +void AliMUONDisplay::ShowNextEvent(Int_t delta) +{ +// Display (current event_number + delta) +// delta = 1 shown next event +// delta = -1 show previous event + if (delta) { + gAlice->Clear(); + Int_t currentEvent = gAlice->GetHeader()->GetEvent(); + Int_t newEvent = currentEvent + delta; + gAlice->GetEvent(newEvent); + fEvent=newEvent; + if (!gAlice->TreeD()) return; + } + + LoadDigits(fChamber, fCathode); + fPad->cd(); + Draw(); +} + +//______________________________________________________________________________ +void AliMUONDisplay::UnZoom() +{ +// Unzoom + if (fZooms <= 0) return; + fZooms--; + TPad *pad = (TPad*)gPad->GetPadSave(); + pad->Range(fZoomX0[fZooms],fZoomY0[fZooms], fZoomX1[fZooms],fZoomY1[fZooms]); + pad->Modified(); +} + +//_____________________________________________________________________________ +void AliMUONDisplay::ResetPoints() +{ + // + // Reset array of points + // + if (fPoints) { + fPoints->Delete(); + delete fPoints; + fPoints = 0; + } +} +//_____________________________________________________________________________ +void AliMUONDisplay::ResetPhits() +{ + // + // Reset array of points + // + if (fPhits) { + fPhits->Delete(); + delete fPhits; + fPhits = 0; + } +} +//_____________________________________________________________________________ +void AliMUONDisplay::ResetRpoints() +{ + // + // Reset array of points + // + if (fRpoints) { + fRpoints->Delete(); + delete fRpoints; + fRpoints = 0; + } +} +//_____________________________________________________________________________ +void AliMUONDisplay::ResetR2points() +{ + // + // Reset array of points + // + if (fR2points) { + fR2points->Delete(); + delete fR2points; + fR2points = 0; + } +} +//_____________________________________________________________________________ +void AliMUONDisplay::ResetCpoints() +{ + // + // Reset array of points + // + if (fCpoints) { + fCpoints->Delete(); + delete fCpoints; + fCpoints = 0; + } +} + + +AliMUONDisplay & AliMUONDisplay::operator = (const AliMUONDisplay &) +{ +// Dummy assignment operator + return *this; +} + + + + + + + + + diff --git a/MUON/AliMUONdisplay.h b/MUON/AliMUONDisplay.h similarity index 78% rename from MUON/AliMUONdisplay.h rename to MUON/AliMUONDisplay.h index bd039485b9a..9e051ecc25f 100644 --- a/MUON/AliMUONdisplay.h +++ b/MUON/AliMUONDisplay.h @@ -1,5 +1,6 @@ -#ifndef AliMUONdisplay_H -#define AliMUONdisplay_H +#ifndef ALIMUONDISPLAY_H +#define ALIMUONDISPLAY_H + /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ @@ -27,49 +28,13 @@ class TArc; const Int_t kMAXZOOM = 20; -class AliMUONdisplay : /*splaypublic TObject,*/ public AliDisplay { - -private: - Int_t fEvent; - Int_t fChamber; - Int_t fCathode; - Int_t fZoomMode; //=1 if in zoom mode - - Bool_t fDrawClusters; //Flag True if Clusters to be drawn - Bool_t fDrawCoG; //Flag True if CoG to be drawn - Bool_t fDrawCathCor; //Flag True if correlated point - //to be drawn - Float_t fTheta; //Viewing angle theta - Float_t fPhi; //Viewing angle phi - Float_t fPsi; //Viewving angle psi (rotation on display) - // Float_t fRzone; // - Float_t fRrange; //Size of view in R - Float_t fZrange; //Size of view along Z - Float_t fZoomX0[20]; //Low x range of zoom number i - Float_t fZoomY0[20]; //Low y range of zoom number i - Float_t fZoomX1[20]; //High x range of zoom number i - Float_t fZoomY1[20]; //High y range of zoom number i - Int_t fZooms; //Number of zooms - Int_t fHitsCuts; //Number of hits surviving cuts - Int_t fClustersCuts; //Number of clusters surviving cuts - TCanvas *fCanvas; //Pointer to the display canvas - TPad *fTrigPad; //Pointer to the trigger pad - TPad *fColPad; //Pointer to the colors pad - TPad *fButtons; //Pointer to the buttons pad - TPad *fPad; //Pointer to the event display main pad - TSlider *fRangeSlider; //Range slider - TButton *fPickButton; //Button to activate Pick mode - TButton *fZoomButton; //Button to activate Zoom mode - TArc *fArcButton; //Gren/Red button to show Pick/Zoom mode - TObjArray *fPoints; //Array of points for each cathode - TObjArray *fPhits; //Array of hit points for each chamber - TObjArray *fRpoints; //Array of cog points for each cathode - TObjArray *fR2points; //Array of cog points for each cathode - TObjArray *fCpoints; //Array of correlated points for each first cathode +class AliMUONDisplay : /*splaypublic TObject,*/ public AliDisplay { public: - AliMUONdisplay(); - AliMUONdisplay(Int_t size); - virtual ~AliMUONdisplay(); + AliMUONDisplay(); + AliMUONDisplay(Int_t size); + AliMUONDisplay(const AliMUONDisplay& display); + + virtual ~AliMUONDisplay(); virtual void Clear(Option_t *option=""); virtual void DisplayButtons(); virtual void CreateColors(); @@ -80,10 +45,10 @@ public: virtual void DrawHits(); virtual void DrawCoG(); virtual void DrawCoG2(); - virtual void DrawCathCor(); - + virtual void DrawSegmentation(); virtual void DrawTitle(Option_t *option=""); virtual void DrawView(Float_t theta, Float_t phi, Float_t psi=0); + virtual void DrawP(Float_t,Float_t,Float_t,Float_t,Float_t,Int_t){} virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py); Int_t GetZoomMode() {return fZoomMode;} Int_t GetChamber() {return fChamber;} @@ -92,7 +57,6 @@ public: virtual void LoadHits(Int_t chamber); virtual void LoadCoG(Int_t chamber, Int_t cathode); virtual void LoadCoG2(Int_t chamber, Int_t cathode); - virtual void LoadCathCor(Int_t chamber); TPad *Pad() {return fPad;} TObjArray *Points() {return fPoints;} TObjArray *Phits() {return fPhits;} @@ -101,22 +65,71 @@ public: TObjArray *Cpoints() {return fCpoints;} virtual void Paint(Option_t *option=""); virtual void SetDrawClusters(Bool_t draw=kTRUE) {fDrawClusters=draw;} // *MENU* - virtual void SetChamberAndCathode(Int_t chamber=1, Int_t cathode=1); // *MENU* - virtual void SetDrawCoG(Bool_t draw=kTRUE) {fDrawCoG=draw;} // *MENU* - virtual void SetDrawCathCor(Bool_t draw=kTRUE) {fDrawCathCor=draw;} // *MENU* - virtual void SetRange(Float_t rrange=250., Float_t zrange=1050.); // *MENU* + virtual void SetChamberAndCathode(Int_t chamber=1, Int_t cathode=1); // *MENU* + virtual void SetDrawCoG(Bool_t draw=kTRUE) {fDrawCoG=draw;} // *MENU* + virtual void SetRange(Float_t rrange=250., Float_t zrange=1050.); // *MENU* + virtual void SetEvent(Int_t newevent=0); // *MENU* virtual void SetView(Float_t theta=0, Float_t phi=-90, Float_t psi=0); virtual void SetPickMode(); virtual void SetZoomMode(); virtual void ShowNextEvent(Int_t delta=1); - virtual void UnZoom(); // *MENU* + virtual void UnZoom(); // *MENU* virtual void ResetPoints(); virtual void ResetPhits(); virtual void ResetRpoints(); virtual void ResetR2points(); virtual void ResetCpoints(); + virtual void NextChamber(Int_t delta=1); + virtual void NextCathode(); + void Trigger(); + AliMUONDisplay& operator = (const AliMUONDisplay& rhs); + + +private: + Int_t fEvent; // Current event + Int_t fChamber; // Current Chamber + Int_t fCathode; // Current cathode plane + Int_t fZoomMode; // =1 if in zoom mode - ClassDef(AliMUONdisplay, 0) //Utility class to display MUON clusters... + Bool_t fDrawClusters; //Flag True if Clusters to be drawn + Bool_t fDrawCoG; //Flag True if CoG to be drawn + //to be drawn + Float_t fTheta; //Viewing angle theta + Float_t fPhi; //Viewing angle phi + Float_t fPsi; //Viewving angle psi (rotation on display) + Float_t fRrange; //Size of view in R + Float_t fZrange; //Size of view along Z + Float_t fZoomX0[20]; //Low x range of zoom number i + Float_t fZoomY0[20]; //Low y range of zoom number i + Float_t fZoomX1[20]; //High x range of zoom number i + Float_t fZoomY1[20]; //High y range of zoom number i + Int_t fZooms; //Number of zooms + Int_t fHitsCuts; //Number of hits surviving cuts + Int_t fClustersCuts; //Number of clusters surviving cuts + TCanvas *fCanvas; //Pointer to the display canvas + TPad *fTrigPad; //Pointer to the trigger pad + TPad *fColPad; //Pointer to the colors pad + TPad *fButtons; //Pointer to the buttons pad + TPad *fPad; //Pointer to the event display main pad + TSlider *fRangeSlider; //Range slider + TButton *fPickButton; //Button to activate Pick mode + TButton *fZoomButton; //Button to activate Zoom mode + TArc *fArcButton; //Gren/Red button to show Pick/Zoom mode + TObjArray *fPoints; //Array of points for each cathode + TObjArray *fPhits; //Array of hit points for each chamber + TObjArray *fRpoints; //Array of cog points for each cathode + TObjArray *fR2points; //Array of cog points for each cathode + TObjArray *fCpoints; //Array of correlated points for each first cathode + Int_t fNextCathode; //Flagging next cathode + ClassDef(AliMUONDisplay, 0) //Utility class to display MUON clusters... }; #endif + + + + + + + + diff --git a/MUON/AliMUONEventReconstructor.cxx b/MUON/AliMUONEventReconstructor.cxx new file mode 100644 index 00000000000..360bf1bea38 --- /dev/null +++ b/MUON/AliMUONEventReconstructor.cxx @@ -0,0 +1,1112 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.4 2000/06/12 08:00:07 morsch +Dummy streamer to solve CINT compilation problem (to be investigated !) + +Revision 1.1.2.3 2000/06/09 20:59:57 morsch +Make includes consistent with new file structure. + +Revision 1.1.2.2 2000/06/09 12:58:05 gosset +Removed comment beginnings in Log sections of .cxx files +Suppressed most violations of coding rules + +Revision 1.1.2.1 2000/06/07 14:44:53 gosset +Addition of files for track reconstruction in C++ +*/ + +//__________________________________________________________________________ +// +// MUON event reconstructor in ALICE +// +// This class contains as data: +// * the parameters for the event reconstruction +// * a pointer to the array of hits to be reconstructed (the event) +// * a pointer to the array of segments made with these hits inside each station +// * a pointer to the array of reconstructed tracks +// +// It contains as methods, among others: +// * MakeEventToBeReconstructed to build the array of hits to be reconstructed +// * MakeSegments to build the segments +// * MakeTracks to build the tracks +//__________________________________________________________________________ + +#include + +#include +#include + +#include "AliCallf77.h" +#include "AliMUONEventReconstructor.h" +#include "AliMUON.h" +#include "AliMUONHitForRec.h" +#include "AliMUONSegment.h" +#include "AliMUONHit.h" +#include "AliMUONRawCluster.h" +#include "AliMUONTrack.h" +#include "AliMUONChamber.h" +#include "AliMUONTrackHit.h" +#include "AliRun.h" + +#ifndef WIN32 +# define initfield initfield_ +# define reco_gufld reco_gufld_ +#else +# define initfield INITFIELD +# define reco_gufld RECO_GUFLD +#endif + +extern "C" +{ +void type_of_call initfield(); +void type_of_call reco_gufld(Double_t *Coor, Double_t *Field); +} + +//************* Defaults parameters for reconstruction +static const Double_t DefaultMinBendingMomentum = 3.0; +static const Double_t DefaultMaxSigma2Distance = 16.0; +static const Double_t DefaultBendingResolution = 0.01; +static const Double_t DefaultNonBendingResolution = 0.144; +static const Double_t DefaultChamberThicknessInX0 = 0.03; +// Simple magnetic field: +// Value taken from macro MUONtracking.C: 0.7 T, hence 7 kG +// Length and Position from reco_muon.F, with opposite sign: +// Length = ZMAGEND-ZCOIL +// Position = (ZMAGEND+ZCOIL)/2 +// to be ajusted differently from real magnetic field ???? +static const Double_t DefaultSimpleBValue = 7.0; +static const Double_t DefaultSimpleBLength = 428.0; +static const Double_t DefaultSimpleBPosition = 1019.0; +static const Int_t DefaultRecGeantHits = 0; +static const Double_t DefaultEfficiency = 0.95; + +static const Int_t DefaultPrintLevel = 0; + +ClassImp(AliMUONEventReconstructor) // Class implementation in ROOT context + + //__________________________________________________________________________ +AliMUONEventReconstructor::AliMUONEventReconstructor(void) +{ + // Constructor for class AliMUONEventReconstructor + SetReconstructionParametersToDefaults(); + // Memory allocation for the TClonesArray of hits for reconstruction + // Is 10000 the right size ???? + fHitsForRecPtr = new TClonesArray("AliMUONHitForRec", 10000); + fNHitsForRec = 0; // really needed or GetEntriesFast sufficient ???? + // Memory allocation for the TClonesArray's of segments in stations + // Is 2000 the right size ???? + for (Int_t st = 0; st < MAX_MUON_TRACKING_STATIONS; st++) { + fSegmentsPtr[st] = new TClonesArray("AliMUONSegment", 2000); + fNSegments[st] = 0; // really needed or GetEntriesFast sufficient ???? + } + // Memory allocation for the TClonesArray of reconstructed tracks + // Is 10 the right size ???? + fRecTracksPtr = new TClonesArray("AliMUONTrack", 10); + fNRecTracks = 0; // really needed or GetEntriesFast sufficient ???? + + // Initialize magnetic field + // using Fortran subroutine INITFIELD in "reco_muon.F". + // Should rather use AliMagF ???? and remove prototyping ... + initfield(); + // Impression de quelques valeurs + Double_t coor[3], field[3]; + coor[0] = 50.0; + coor[1] = 50.0; + coor[2] = 950.0; + reco_gufld(coor, field); + cout << "coor: " << coor[0] << ", " << coor[1] << ", " << coor[2] << endl; + cout << "field: " << field[0] << ", " << field[1] << ", " << field[2] << endl; + coor[2] = -950.0; + reco_gufld(coor, field); + cout << "coor: " << coor[0] << ", " << coor[1] << ", " << coor[2] << endl; + cout << "field: " << field[0] << ", " << field[1] << ", " << field[2] << endl; + coor[2] = -950.0; + + if (fPrintLevel >= 0) { + cout << "AliMUONEventReconstructor constructed with defaults" << endl; Dump();} + return; +} + + //__________________________________________________________________________ +AliMUONEventReconstructor::~AliMUONEventReconstructor(void) +{ + // Destructor for class AliMUONEventReconstructor + delete fHitsForRecPtr; // Correct destruction of everything ???? or delete [] ???? + for (Int_t st = 0; st < MAX_MUON_TRACKING_STATIONS; st++) + delete fSegmentsPtr[st]; // Correct destruction of everything ???? + return; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::SetReconstructionParametersToDefaults(void) +{ + // Set reconstruction parameters to default values + // Would be much more convenient with a structure (or class) ???? + fMinBendingMomentum = DefaultMinBendingMomentum; + fMaxSigma2Distance = DefaultMaxSigma2Distance; + + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); + // ******** Parameters for making HitsForRec + // minimum radius, + // like in TRACKF_STAT: + // 2 degrees for stations 1 and 2, or ch(0...) from 0 to 3; + // 30 cm for stations 3 to 5, or ch(0...) from 4 to 9 + for (Int_t ch = 0; ch < MAX_MUON_TRACKING_CHAMBERS; ch++) { + if (ch < 4) fRMin[ch] = TMath::Abs((&(MUON->Chamber(ch)))->Z()) * + 2.0 * TMath::Pi() / 180.0; + else fRMin[ch] = 30.0; + } + // maximum radius + // like in TRACKF_STAT (10 degrees ????) + fRMax[0] = fRMax[1] = 91.5; + fRMax[2] = fRMax[3] = 122.5; + fRMax[4] = fRMax[5] = 158.3; + fRMax[6] = fRMax[7] = 260.0; + fRMax[8] = fRMax[9] = 260.0; + + // ******** Parameters for making segments + // should be parametrized ???? + // according to interval between chambers in a station ???? + // Maximum distance in non bending plane + // 5 * 0.22 just to remember the way it was made in TRACKF_STAT + // SIGCUT*DYMAX(IZ) + for (Int_t st = 0; st < MAX_MUON_TRACKING_STATIONS; st++) + fSegmentMaxDistNonBending[st] = 5. * 0.22; + // Maximum distance in bending plane + // values from TRACKF_STAT corresponding to (J psi 20cm) + fSegmentMaxDistBending[0] = 1.5; + fSegmentMaxDistBending[1] = 1.5; + fSegmentMaxDistBending[2] = 3.0; + fSegmentMaxDistBending[3] = 6.0; + fSegmentMaxDistBending[4] = 6.0; + + fBendingResolution = DefaultBendingResolution; + fNonBendingResolution = DefaultNonBendingResolution; + fChamberThicknessInX0 = DefaultChamberThicknessInX0; + fSimpleBValue = DefaultSimpleBValue; + fSimpleBLength = DefaultSimpleBLength; + fSimpleBPosition = DefaultSimpleBPosition; + fRecGeantHits = DefaultRecGeantHits; + fEfficiency = DefaultEfficiency; + fPrintLevel = DefaultPrintLevel; + return; +} + +//__________________________________________________________________________ +Double_t AliMUONEventReconstructor::GetImpactParamFromBendingMomentum(Double_t BendingMomentum) +{ + // Returns impact parameter at vertex in bending plane (cm), + // from the signed bending momentum "BendingMomentum" in bending plane (GeV/c), + // using simple values for dipole magnetic field. + // The sign is the sign of the charge. + return (-0.0003 * fSimpleBValue * fSimpleBLength * fSimpleBPosition / + BendingMomentum); +} + +//__________________________________________________________________________ +Double_t AliMUONEventReconstructor::GetBendingMomentumFromImpactParam(Double_t ImpactParam) +{ + // Returns signed bending momentum in bending plane (GeV/c), + // from the impact parameter "ImpactParam" at vertex in bending plane (cm), + // using simple values for dipole magnetic field. + // The sign is the sign of the charge. + return (-0.0003 * fSimpleBValue * fSimpleBLength * fSimpleBPosition / + ImpactParam); +} + +//__________________________________________________________________________ +void AliMUONEventReconstructor::SetBkgGeantFile(Text_t *BkgGeantFileName) +{ + // Set background file ... for GEANT hits + // Must be called after having loaded the firts signal event + if (fPrintLevel >= 0) { + cout << "Enter SetBkgGeantFile with BkgGeantFileName ``" + << BkgGeantFileName << "''" << endl;} + if (strlen(BkgGeantFileName)) { + // BkgGeantFileName not empty: try to open the file + if (fPrintLevel >= 2) {cout << "Before File(Bkg)" << endl; gDirectory->Dump();} + fBkgGeantFile = new TFile(BkgGeantFileName); + if (fPrintLevel >= 2) {cout << "After File(Bkg)" << endl; gDirectory->Dump();} + if (fBkgGeantFile-> IsOpen()) { + if (fPrintLevel >= 0) { + cout << "Background for GEANT hits in file: ``" << BkgGeantFileName + << "'' successfully opened" << endl;} + } + else { + cout << "Background for GEANT hits in file: " << BkgGeantFileName << endl; + cout << "NOT FOUND: EXIT" << endl; + exit(0); // right instruction for exit ???? + } + // Arrays for "particles" and "hits" + fBkgGeantParticles = new TClonesArray("TParticle", 200); + fBkgGeantHits = new TClonesArray("AliMUONHit", 2000); + // Event number to -1 for initialization + fBkgGeantEventNumber = -1; + // Back to the signal file: + // first signal event must have been loaded previously, + // otherwise, Segmentation violation at the next instruction + // How is it possible to do smething better ???? + ((gAlice->TreeK())->GetCurrentFile())->cd(); + if (fPrintLevel >= 2) {cout << "After cd(gAlice)" << endl; gDirectory->Dump();} + } + return; +} + +//__________________________________________________________________________ +void AliMUONEventReconstructor::NextBkgGeantEvent(void) +{ + // Get next event in background file for GEANT hits + // Goes back to event number 0 when end of file is reached + char treeName[20]; + TBranch *branch; + if (fPrintLevel >= 0) { + cout << "Enter NextBkgGeantEvent" << endl;} + // Clean previous event + if(fBkgGeantTK) delete fBkgGeantTK; + fBkgGeantTK = NULL; + if(fBkgGeantParticles) fBkgGeantParticles->Clear(); + if(fBkgGeantTH) delete fBkgGeantTH; + fBkgGeantTH = NULL; + if(fBkgGeantHits) fBkgGeantHits->Clear(); + // Increment event number + fBkgGeantEventNumber++; + // Get access to Particles and Hits for event from background file + if (fPrintLevel >= 2) {cout << "Before cd(Bkg)" << endl; gDirectory->Dump();} + fBkgGeantFile->cd(); + if (fPrintLevel >= 2) {cout << "After cd(Bkg)" << endl; gDirectory->Dump();} + // Particles: TreeK for event and branch "Particles" + sprintf(treeName, "TreeK%d", fBkgGeantEventNumber); + fBkgGeantTK = (TTree*)gDirectory->Get(treeName); + if (!fBkgGeantTK) { + if (fPrintLevel >= 0) { + cout << "Cannot find Kine Tree for background event: " << + fBkgGeantEventNumber << endl; + cout << "Goes back to event 0" << endl; + } + fBkgGeantEventNumber = 0; + sprintf(treeName, "TreeK%d", fBkgGeantEventNumber); + fBkgGeantTK = (TTree*)gDirectory->Get(treeName); + if (!fBkgGeantTK) { + cout << "ERROR: cannot find Kine Tree for background event: " << + fBkgGeantEventNumber << endl; + exit(0); + } + } + if (fBkgGeantTK) + fBkgGeantTK->SetBranchAddress("Particles", &fBkgGeantParticles); + fBkgGeantTK->GetEvent(0); // why event 0 ???? necessary ???? + // Hits: TreeH for event and branch "MUON" + sprintf(treeName, "TreeH%d", fBkgGeantEventNumber); + fBkgGeantTH = (TTree*)gDirectory->Get(treeName); + if (!fBkgGeantTH) { + cout << "ERROR: cannot find Hits Tree for background event: " << + fBkgGeantEventNumber << endl; + exit(0); + } + if (fBkgGeantTH && fBkgGeantHits) { + branch = fBkgGeantTH->GetBranch("MUON"); + if (branch) branch->SetAddress(&fBkgGeantHits); + } + fBkgGeantTH->GetEntries(); // necessary ???? + // Back to the signal file + ((gAlice->TreeK())->GetCurrentFile())->cd(); + if (fPrintLevel >= 2) {cout << "After cd(gAlice)" << endl; gDirectory->Dump();} + return; +} + +//__________________________________________________________________________ +void AliMUONEventReconstructor::EventReconstruct(void) +{ + // To reconstruct one event + if (fPrintLevel >= 1) cout << "enter EventReconstruct" << endl; + MakeEventToBeReconstructed(); + MakeSegments(); + MakeTracks(); + return; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::ResetHitsForRec(void) +{ + // To reset the array and the number of HitsForRec, + // and also the number of HitsForRec + // and the index of the first HitForRec per chamber + if (fHitsForRecPtr) fHitsForRecPtr->Clear(); + fNHitsForRec = 0; + for (Int_t ch = 0; ch < MAX_MUON_TRACKING_CHAMBERS; ch++) + fNHitsForRecPerChamber[ch] = fIndexOfFirstHitForRecPerChamber[ch] = 0; + return; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::ResetSegments(void) +{ + // To reset the TClonesArray of segments and the number of Segments + // for all stations + for (Int_t st = 0; st < MAX_MUON_TRACKING_STATIONS; st++) { + if (fSegmentsPtr[st]) fSegmentsPtr[st]->Clear(); + fNSegments[st] = 0; + } + return; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::ResetTracks(void) +{ + // To reset the TClonesArray of reconstructed tracks + if (fRecTracksPtr) fRecTracksPtr->Clear(); + fNRecTracks = 0; + return; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::MakeEventToBeReconstructed(void) +{ + // To make the list of hits to be reconstructed, + // either from the GEANT hits or from the raw clusters + // according to the parameter set for the reconstructor + if (fPrintLevel >= 1) cout << "enter MakeEventToBeReconstructed" << endl; + ResetHitsForRec(); + if (fRecGeantHits == 1) { + // Reconstruction from GEANT hits + // Back to the signal file + ((gAlice->TreeK())->GetCurrentFile())->cd(); + // Signal hits + // AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); // necessary ???? + // Security on MUON ???? + AddHitsForRecFromGEANT(gAlice->TreeH()); + // Background hits + AddHitsForRecFromBkgGEANT(fBkgGeantTH, fBkgGeantHits); + // Sort HitsForRec in increasing order with respect to chamber number + SortHitsForRecWithIncreasingChamber(); + } + else { + // Reconstruction from raw clusters + // AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); // necessary ???? + // Security on MUON ???? + // TreeR assumed to be be "prepared" in calling function + // by "MUON->GetTreeR(nev)" ???? + TTree *TR = gAlice->TreeR(); + AddHitsForRecFromRawClusters(TR); + // No sorting: it is done automatically in the previous function + } + if (fPrintLevel >= 10) { + cout << "end of MakeEventToBeReconstructed" << endl; + cout << "NHitsForRec: " << fNHitsForRec << endl; + for (Int_t ch = 0; ch < MAX_MUON_TRACKING_CHAMBERS; ch++) { + cout << "chamber(0...): " << ch + << " NHitsForRec: " << fNHitsForRecPerChamber[ch] + << " index(first HitForRec): " << fIndexOfFirstHitForRecPerChamber[ch] + << endl; + for (Int_t hit = fIndexOfFirstHitForRecPerChamber[ch]; + hit < fIndexOfFirstHitForRecPerChamber[ch] + fNHitsForRecPerChamber[ch]; + hit++) { + cout << "HitForRec index(0...): " << hit << endl; + ((*fHitsForRecPtr)[hit])->Dump(); + } + } + } + return; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::AddHitsForRecFromGEANT(TTree *TH) +{ + // To add to the list of hits for reconstruction + // the GEANT signal hits from a hit tree TH. + if (fPrintLevel >= 2) + cout << "enter AddHitsForRecFromGEANT with TH: " << TH << endl; + if (TH == NULL) return; + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); // necessary ???? + // Security on MUON ???? + // See whether it could be the same for signal and background ???? + // Loop over tracks in tree + Int_t ntracks = (Int_t) TH->GetEntries(); + if (fPrintLevel >= 2) + cout << "ntracks: " << ntracks << endl; + for (Int_t track = 0; track < ntracks; track++) { + gAlice->ResetHits(); + TH->GetEvent(track); + // Loop over hits + Int_t hit = 0; + for (AliMUONHit* mHit = (AliMUONHit*) MUON->FirstHit(-1); + mHit; + mHit = (AliMUONHit*) MUON->NextHit(), hit++) { + NewHitForRecFromGEANT(mHit,track, hit, 1); + } // end of hit loop + } // end of track loop + return; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::AddHitsForRecFromBkgGEANT(TTree *TH, TClonesArray *Hits) +{ + // To add to the list of hits for reconstruction + // the GEANT background hits from a hit tree TH and a pointer Hits to a hit list. + // How to have only one function "AddHitsForRecFromGEANT" ???? + if (fPrintLevel >= 2) + cout << "enter AddHitsForRecFromBkgGEANT with TH: " << TH << endl; + if (TH == NULL) return; + // Loop over tracks in tree + Int_t ntracks = (Int_t) TH->GetEntries(); + if (fPrintLevel >= 2) + cout << "ntracks: " << ntracks << endl; + for (Int_t track = 0; track < ntracks; track++) { + if (Hits) Hits->Clear(); + TH->GetEvent(track); + // Loop over hits + for (Int_t hit = 0; hit < Hits->GetEntriesFast(); hit++) { + NewHitForRecFromGEANT((AliMUONHit*) (*Hits)[hit], track, hit, 0); + } // end of hit loop + } // end of track loop + return; +} + + //__________________________________________________________________________ +AliMUONHitForRec* AliMUONEventReconstructor::NewHitForRecFromGEANT(AliMUONHit* Hit, Int_t TrackNumber, Int_t HitNumber, Int_t Signal) +{ + // To make a new hit for reconstruction from a GEANT hit pointed to by "Hit", + // with hit number "HitNumber" in the track numbered "TrackNumber", + // either from signal ("Signal" = 1) or background ("Signal" = 0) event. + // Selects hits in tracking (not trigger) chambers. + // Takes into account the efficiency (fEfficiency) + // and the smearing from resolution (fBendingResolution and fNonBendingResolution). + // Adds a condition on the radius between RMin and RMax + // to better simulate the real chambers. + // Returns the pointer to the new hit for reconstruction, + // or NULL in case of inefficiency or non tracking chamber or bad radius. + // No condition on at most 20 cm from a muon from a resonance + // like in Fortran TRACKF_STAT. + AliMUONHitForRec* hitForRec; + Double_t bendCoor, nonBendCoor, radius; + Int_t chamber = Hit->fChamber - 1; // chamber(0...) + // only in tracking chambers (fChamber starts at 1) + if (chamber >= MAX_MUON_TRACKING_CHAMBERS) return NULL; + // only if hit is efficient (keep track for checking ????) + if (gRandom->Rndm() > fEfficiency) return NULL; + // only if radius between RMin and RMax + bendCoor = Hit->fY; + nonBendCoor = Hit->fX; + radius = TMath::Sqrt((bendCoor * bendCoor) + (nonBendCoor * nonBendCoor)); + if ((radius < fRMin[chamber]) || (radius > fRMax[chamber])) return NULL; + // new AliMUONHitForRec from GEANT hit and increment number of AliMUONHitForRec's + hitForRec = new ((*fHitsForRecPtr)[fNHitsForRec]) AliMUONHitForRec(Hit); + fNHitsForRec++; + // add smearing from resolution + hitForRec->SetBendingCoor(bendCoor + gRandom->Gaus(0., fBendingResolution)); + hitForRec->SetNonBendingCoor(nonBendCoor + + gRandom->Gaus(0., fNonBendingResolution)); + // more information into HitForRec + // resolution: angular effect to be added here ???? + hitForRec->SetBendingReso2(fBendingResolution * fBendingResolution); + hitForRec->SetNonBendingReso2(fNonBendingResolution * fNonBendingResolution); + // GEANT track info + hitForRec->SetHitNumber(HitNumber); + hitForRec->SetTHTrack(TrackNumber); + hitForRec->SetGeantSignal(Signal); + if (fPrintLevel >= 10) { + cout << "track: " << TrackNumber << " hit: " << HitNumber << endl; + Hit->Dump(); + cout << "AliMUONHitForRec number (1...): " << fNHitsForRec << endl; + hitForRec->Dump();} + return hitForRec; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::SortHitsForRecWithIncreasingChamber() +{ + // Sort HitsForRec's in increasing order with respect to chamber number. + // Uses the function "Compare". + // Update the information for HitsForRec per chamber too. + Int_t ch, nhits, prevch; + fHitsForRecPtr->Sort(); + for (ch = 0; ch < MAX_MUON_TRACKING_CHAMBERS; ch++) { + fNHitsForRecPerChamber[ch] = 0; + fIndexOfFirstHitForRecPerChamber[ch] = 0; + } + prevch = 0; // previous chamber + nhits = 0; // number of hits in current chamber + // Loop over HitsForRec + for (Int_t hit = 0; hit < fNHitsForRec; hit++) { + // chamber number (0...) + ch = ((AliMUONHitForRec*) ((*fHitsForRecPtr)[hit]))->GetChamberNumber(); + // increment number of hits in current chamber + (fNHitsForRecPerChamber[ch])++; + // update index of first HitForRec in current chamber + // if chamber number different from previous one + if (ch != prevch) { + fIndexOfFirstHitForRecPerChamber[ch] = hit; + prevch = ch; + } + } + return; +} + +// //__________________________________________________________________________ +// void AliMUONEventReconstructor::AddHitsForRecFromCathodeCorrelations(TTree* TC) +// { +// // OLD VERSION WHEN ONE ONE WAS USING SO CALLED CATHODE CORRELATIONS +// // To add to the list of hits for reconstruction +// // the (cathode correlated) raw clusters +// // No condition added, like in Fortran TRACKF_STAT, +// // on the radius between RMin and RMax. +// AliMUONHitForRec *hitForRec; +// if (fPrintLevel >= 1) cout << "enter AddHitsForRecFromCathodeCorrelations" << endl; +// AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); // necessary ???? +// // Security on MUON ???? +// // Loop over tracking chambers +// for (Int_t ch = 0; ch < MAX_MUON_TRACKING_CHAMBERS; ch++) { +// // number of HitsForRec to 0 for the chamber +// fNHitsForRecPerChamber[ch] = 0; +// // index of first HitForRec for the chamber +// if (ch == 0) fIndexOfFirstHitForRecPerChamber[ch] = 0; +// else fIndexOfFirstHitForRecPerChamber[ch] = fNHitsForRec; +// TClonesArray *reconst_hits = MUON->ReconstHitsAddress(ch); +// MUON->ResetReconstHits(); +// TC->GetEvent(); +// Int_t ncor = (Int_t)reconst_hits->GetEntries(); +// // Loop over (cathode correlated) raw clusters +// for (Int_t cor = 0; cor < ncor; cor++) { +// AliMUONReconstHit * mCor = +// (AliMUONReconstHit*) reconst_hits->UncheckedAt(cor); +// // new AliMUONHitForRec from (cathode correlated) raw cluster +// // and increment number of AliMUONHitForRec's (total and in chamber) +// hitForRec = new ((*fHitsForRecPtr)[fNHitsForRec]) AliMUONHitForRec(mCor); +// fNHitsForRec++; +// (fNHitsForRecPerChamber[ch])++; +// // more information into HitForRec +// hitForRec->SetChamberNumber(ch); +// hitForRec->SetHitNumber(cor); +// // Z coordinate of the chamber (cm) with sign opposite to GEANT sign +// // could (should) be more exact from chamber geometry ???? +// hitForRec->SetZ(-(&(MUON->Chamber(ch)))->Z()); +// if (fPrintLevel >= 10) { +// cout << "chamber (0...): " << ch << +// " cathcorrel (0...): " << cor << endl; +// mCor->Dump(); +// cout << "AliMUONHitForRec number (1...): " << fNHitsForRec << endl; +// hitForRec->Dump();} +// } // end of cluster loop +// } // end of chamber loop +// return; +// } + + //__________________________________________________________________________ +void AliMUONEventReconstructor::AddHitsForRecFromRawClusters(TTree* TR) +{ + // To add to the list of hits for reconstruction all the raw clusters + // No condition added, like in Fortran TRACKF_STAT, + // on the radius between RMin and RMax. + AliMUONHitForRec *hitForRec; + AliMUONRawCluster *clus; + Int_t iclus, nclus; + TClonesArray *rawclusters; + if (fPrintLevel >= 1) cout << "enter AddHitsForRecFromRawClusters" << endl; + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); // necessary ???? + // Security on MUON ???? + // Loop over tracking chambers + for (Int_t ch = 0; ch < MAX_MUON_TRACKING_CHAMBERS; ch++) { + // number of HitsForRec to 0 for the chamber + fNHitsForRecPerChamber[ch] = 0; + // index of first HitForRec for the chamber + if (ch == 0) fIndexOfFirstHitForRecPerChamber[ch] = 0; + else fIndexOfFirstHitForRecPerChamber[ch] = fNHitsForRec; + rawclusters = MUON->RawClustAddress(ch); + MUON->ResetRawClusters(); + TR->GetEvent((Int_t) (TR->GetEntries()) - 1); // to be checked ???? + nclus = (Int_t) (rawclusters->GetEntries()); + // Loop over (cathode correlated) raw clusters + for (iclus = 0; iclus < nclus; iclus++) { + clus = (AliMUONRawCluster*) rawclusters->UncheckedAt(iclus); + // new AliMUONHitForRec from raw cluster + // and increment number of AliMUONHitForRec's (total and in chamber) + hitForRec = new ((*fHitsForRecPtr)[fNHitsForRec]) AliMUONHitForRec(clus); + fNHitsForRec++; + (fNHitsForRecPerChamber[ch])++; + // more information into HitForRec + // resolution: info should be already in raw cluster and taken from it ???? + hitForRec->SetBendingReso2(fBendingResolution * fBendingResolution); + hitForRec->SetNonBendingReso2(fNonBendingResolution * fNonBendingResolution); + // original raw cluster + hitForRec->SetChamberNumber(ch); + hitForRec->SetHitNumber(iclus); + // Z coordinate of the chamber (cm) with sign opposite to GEANT sign + // could (should) be more exact from chamber geometry ???? + hitForRec->SetZ(-(&(MUON->Chamber(ch)))->Z()); + if (fPrintLevel >= 10) { + cout << "chamber (0...): " << ch << + " raw cluster (0...): " << iclus << endl; + clus->Dump(); + cout << "AliMUONHitForRec number (1...): " << fNHitsForRec << endl; + hitForRec->Dump();} + } // end of cluster loop + } // end of chamber loop + return; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::MakeSegments(void) +{ + // To make the list of segments in all stations, + // from the list of hits to be reconstructed + if (fPrintLevel >= 1) cout << "enter MakeSegments" << endl; + ResetSegments(); + // Loop over stations + for (Int_t st = 0; st < MAX_MUON_TRACKING_STATIONS; st++) + MakeSegmentsPerStation(st); + if (fPrintLevel >= 10) { + cout << "end of MakeSegments" << endl; + for (Int_t st = 0; st < MAX_MUON_TRACKING_STATIONS; st++) { + cout << "station(0...): " << st + << " Segments: " << fNSegments[st] + << endl; + for (Int_t seg = 0; + seg < fNSegments[st]; + seg++) { + cout << "Segment index(0...): " << seg << endl; + ((*fSegmentsPtr[st])[seg])->Dump(); + } + } + } + return; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::MakeSegmentsPerStation(Int_t Station) +{ + // To make the list of segments in station number "Station" (0...) + // from the list of hits to be reconstructed. + // Updates "fNSegments"[Station]. + // Segments in stations 4 and 5 are sorted + // according to increasing absolute value of "impact parameter" + AliMUONHitForRec *hit1Ptr, *hit2Ptr; + AliMUONSegment *segment; + Bool_t last2st; + Double_t bendingSlope, distBend, distNonBend, extBendCoor, extNonBendCoor, + impactParam, maxImpactParam; + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); // necessary ???? + if (fPrintLevel >= 1) + cout << "enter MakeSegmentsPerStation (0...) " << Station << endl; + // first and second chambers (0...) in the station + Int_t ch1 = 2 * Station; + Int_t ch2 = ch1 + 1; + // variable true for stations downstream of the dipole: + // Station(0..4) equal to 3 or 4 + if ((Station == 3) || (Station == 4)) { + last2st = kTRUE; + // maximum impact parameter (cm) according to fMinBendingMomentum... + maxImpactParam = + TMath::Abs(GetImpactParamFromBendingMomentum(fMinBendingMomentum)); + } + else last2st = kFALSE; + // extrapolation factor from Z of first chamber to Z of second chamber + // dZ to be changed to take into account fine structure of chambers ???? + Double_t extrapFact = + (&(MUON->Chamber(ch2)))->Z() / (&(MUON->Chamber(ch1)))->Z(); + // index for current segment + Int_t segmentIndex = 0; + // Loop over HitsForRec in the first chamber of the station + for (Int_t hit1 = fIndexOfFirstHitForRecPerChamber[ch1]; + hit1 < fIndexOfFirstHitForRecPerChamber[ch1] + fNHitsForRecPerChamber[ch1]; + hit1++) { + // pointer to the HitForRec + hit1Ptr = (AliMUONHitForRec*) ((*fHitsForRecPtr)[hit1]); + // extrapolation, + // on the straight line joining the HitForRec to the vertex (0,0,0), + // to the Z of the second chamber of the station + extBendCoor = extrapFact * hit1Ptr->GetBendingCoor(); + extNonBendCoor = extrapFact * hit1Ptr->GetNonBendingCoor(); + // Loop over HitsForRec in the second chamber of the station + for (Int_t hit2 = fIndexOfFirstHitForRecPerChamber[ch2]; + hit2 < fIndexOfFirstHitForRecPerChamber[ch2] + fNHitsForRecPerChamber[ch2]; + hit2++) { + // pointer to the HitForRec + hit2Ptr = (AliMUONHitForRec*) ((*fHitsForRecPtr)[hit2]); + // absolute values of distances, in bending and non bending planes, + // between the HitForRec in the second chamber + // and the previous extrapolation + distBend = TMath::Abs(hit2Ptr->GetBendingCoor() - extBendCoor); + distNonBend = TMath::Abs(hit2Ptr->GetNonBendingCoor() - extNonBendCoor); + if (last2st) { + // bending slope + bendingSlope = (hit1Ptr->GetBendingCoor() - hit2Ptr->GetBendingCoor()) / + (hit1Ptr->GetZ() - hit2Ptr->GetZ()); + // absolute value of impact parameter + impactParam = + TMath::Abs(hit1Ptr->GetBendingCoor() - hit2Ptr->GetZ() * bendingSlope); + } + // check for distances not too large, + // and impact parameter not too big if stations downstream of the dipole. + // Conditions "distBend" and "impactParam" correlated for these stations ???? + if ((distBend < fSegmentMaxDistBending[Station]) && + (distNonBend < fSegmentMaxDistNonBending[Station]) && + (!last2st || (impactParam < maxImpactParam))) { + // make new segment + segment = new ((*fSegmentsPtr[Station])[segmentIndex]) + AliMUONSegment(hit1Ptr, hit2Ptr); + // update "link" to this segment from the hit in the first chamber + if (hit1Ptr->GetNSegments() == 0) + hit1Ptr->SetIndexOfFirstSegment(segmentIndex); + hit1Ptr->SetNSegments(hit1Ptr->GetNSegments() + 1); + if (fPrintLevel >= 10) { + cout << "segmentIndex(0...): " << segmentIndex + << " distBend: " << distBend + << " distNonBend: " << distNonBend + << endl; + segment->Dump(); + cout << "HitForRec in first chamber" << endl; + hit1Ptr->Dump(); + cout << "HitForRec in second chamber" << endl; + hit2Ptr->Dump(); + }; + // increment index for current segment + segmentIndex++; + } + } //for (Int_t hit2 + } // for (Int_t hit1... + fNSegments[Station] = segmentIndex; + // Sorting according to "impact parameter" if station(1..5) 4 or 5, + // i.e. Station(0..4) 3 or 4, using the function "Compare". + // After this sorting, it is impossible to use + // the "fNSegments" and "fIndexOfFirstSegment" + // of the HitForRec in the first chamber to explore all segments formed with it. + // Is this sorting really needed ???? + if ((Station == 3) || (Station == 4)) (fSegmentsPtr[Station])->Sort(); + if (fPrintLevel >= 1) cout << "Station: " << Station << " NSegments: " + << fNSegments[Station] << endl; + return; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::MakeTracks(void) +{ + // To make the tracks, + // from the list of segments and points in all stations + if (fPrintLevel >= 1) cout << "enter MakeTracks" << endl; + ResetTracks(); + // Look for candidates from at least 3 aligned points in stations(1..) 4 and 5 + MakeTrackCandidates(); + // Follow tracks in stations(1..) 3, 2 and 1 + FollowTracks(); + return; +} + + //__________________________________________________________________________ +Int_t AliMUONEventReconstructor::MakeTrackCandidatesWithTwoSegments(AliMUONSegment *BegSegment) +{ + // To make track candidates with two segments in stations(1..) 4 and 5, + // the first segment being pointed to by "BegSegment". + // Returns the number of such track candidates. + Int_t endStation, iEndSegment, nbCan2Seg; + AliMUONSegment *endSegment, *extrapSegment; + AliMUONTrack *recTrack; + Double_t mcsFactor; + if (fPrintLevel >= 1) cout << "enter MakeTrackCandidatesWithTwoSegments" << endl; + // Station for the end segment + endStation = 7 - (BegSegment->GetHitForRec1())->GetChamberNumber() / 2; + // multiple scattering factor corresponding to one chamber + mcsFactor = 0.0136 / + GetBendingMomentumFromImpactParam(BegSegment->GetBendingImpact()); + mcsFactor = fChamberThicknessInX0 * mcsFactor * mcsFactor; + // linear extrapolation to end station + extrapSegment = + BegSegment->CreateSegmentFromLinearExtrapToStation(endStation, mcsFactor); + // number of candidates with 2 segments to 0 + nbCan2Seg = 0; + // Loop over segments in the end station + for (iEndSegment = 0; iEndSegment < fNSegments[endStation]; iEndSegment++) { + // pointer to segment + endSegment = (AliMUONSegment*) ((*fSegmentsPtr[endStation])[iEndSegment]); + // test compatibility between current segment and "extrapSegment" + if ((endSegment-> + NormalizedChi2WithSegment(extrapSegment, + fMaxSigma2Distance)) <= 4.0) { + // both segments compatible: + // make track candidate from "begSegment" and "endSegment" + if (fPrintLevel >= 2) + cout << "TrackCandidate with Segment " << iEndSegment << + " in Station(0..) " << endStation << endl; + // flag for both segments in one track: + // to be done in track constructor ???? + BegSegment->SetInTrack(kTRUE); + endSegment->SetInTrack(kTRUE); + recTrack = new ((*fRecTracksPtr)[fNRecTracks]) + AliMUONTrack(BegSegment, endSegment, this); + fNRecTracks++; + if (fPrintLevel >= 10) recTrack->RecursiveDump(); + // increment number of track candidates with 2 segments + nbCan2Seg++; + } + } // for (iEndSegment = 0;... + delete extrapSegment; // should not delete HitForRec's it points to !!!! + return nbCan2Seg; +} + + //__________________________________________________________________________ +Int_t AliMUONEventReconstructor::MakeTrackCandidatesWithOneSegmentAndOnePoint(AliMUONSegment *BegSegment) +{ + // To make track candidates with one segment and one point + // in stations(1..) 4 and 5, + // the segment being pointed to by "BegSegment". + Int_t ch, ch1, ch2, endStation, iHit, iHitMax, iHitMin, nbCan1Seg1Hit; + AliMUONHitForRec *extrapHitForRec, *hit; + AliMUONTrack *recTrack; + Double_t mcsFactor; + if (fPrintLevel >= 1) + cout << "enter MakeTrackCandidatesWithOneSegmentAndOnePoint" << endl; + // station for the end point + endStation = 7 - (BegSegment->GetHitForRec1())->GetChamberNumber() / 2; + // multiple scattering factor corresponding to one chamber + mcsFactor = 0.0136 / + GetBendingMomentumFromImpactParam(BegSegment->GetBendingImpact()); + mcsFactor = fChamberThicknessInX0 * mcsFactor * mcsFactor; + // first and second chambers(0..) in the end station + ch1 = 2 * endStation; + ch2 = ch1 + 1; + // number of candidates to 0 + nbCan1Seg1Hit = 0; + // Loop over chambers of the end station + for (ch = ch2; ch >= ch1; ch--) { + // linear extrapolation to chamber + extrapHitForRec = + BegSegment->CreateHitForRecFromLinearExtrapToChamber(ch, mcsFactor); + // limits for the hit index in the loop + iHitMin = fIndexOfFirstHitForRecPerChamber[ch]; + iHitMax = iHitMin + fNHitsForRecPerChamber[ch]; + // Loop over HitForRec's in the chamber + for (iHit = iHitMin; iHit < iHitMax; iHit++) { + // pointer to HitForRec + hit = (AliMUONHitForRec*) ((*fHitsForRecPtr)[iHit]); + // test compatibility between current HitForRec and "extrapHitForRec" + if ((hit-> + NormalizedChi2WithHitForRec(extrapHitForRec, + fMaxSigma2Distance)) <= 2.0) { + // both HitForRec's compatible: + // make track candidate from begSegment and current HitForRec + if (fPrintLevel >= 2) + cout << "TrackCandidate with HitForRec " << iHit << + " in Chamber(0..) " << ch << endl; + // flag for beginning segments in one track: + // to be done in track constructor ???? + BegSegment->SetInTrack(kTRUE); + recTrack = new ((*fRecTracksPtr)[fNRecTracks]) + AliMUONTrack(BegSegment, hit, this); + // the right place to eliminate "double counting" ???? how ???? + fNRecTracks++; + if (fPrintLevel >= 10) recTrack->RecursiveDump(); + // increment number of track candidates + nbCan1Seg1Hit++; + } + } // for (iHit = iHitMin;... + delete extrapHitForRec; + } // for (ch = ch2;... + return nbCan1Seg1Hit; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::MakeTrackCandidates(void) +{ + // To make track candidates + // with at least 3 aligned points in stations(1..) 4 and 5 + // (two Segment's or one Segment and one HitForRec) + Int_t begStation, iBegSegment, nbCan1Seg1Hit, nbCan2Seg; + AliMUONSegment *begSegment; + if (fPrintLevel >= 1) cout << "enter MakeTrackCandidates" << endl; + // Loop over stations(1..) 5 and 4 for the beginning segment + for (begStation = 4; begStation > 2; begStation--) { + // Loop over segments in the beginning station + for (iBegSegment = 0; iBegSegment < fNSegments[begStation]; iBegSegment++) { + // pointer to segment + begSegment = (AliMUONSegment*) ((*fSegmentsPtr[begStation])[iBegSegment]); + if (fPrintLevel >= 2) + cout << "look for TrackCandidate's with Segment " << iBegSegment << + " in Station(0..) " << begStation << endl; + // Look for track candidates with two segments, + // "begSegment" and all compatible segments in other station. + // Only for beginning station(1..) 5 + // because candidates with 2 segments have to looked for only once. + if (begStation == 4) + nbCan2Seg = MakeTrackCandidatesWithTwoSegments(begSegment); + // Look for track candidates with one segments and one point, + // "begSegment" and all compatible HitForRec's in other station. + // Only if "begSegment" does not belong already to a track candidate. + // Is that a too strong condition ???? + if (!(begSegment->GetInTrack())) + nbCan1Seg1Hit = MakeTrackCandidatesWithOneSegmentAndOnePoint(begSegment); + } // for (iBegSegment = 0;... + } // for (begStation = 4;... + return; +} + + //__________________________________________________________________________ +void AliMUONEventReconstructor::FollowTracks(void) +{ + // Follow tracks in stations(1..) 3, 2 and 1 + AliMUONHitForRec *bestHit, *extrapHit, *hit; + AliMUONSegment *bestSegment, *extrapSegment, *segment; + AliMUONTrack *track; + AliMUONTrackParam *trackParam1, trackParam[2]; + Int_t ch, chBestHit, iHit, iSegment, station, trackIndex; + Double_t bestChi2, chi2, dZ1, dZ2, maxSigma2Distance, mcsFactor; + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); // necessary ???? + maxSigma2Distance = 4. * fMaxSigma2Distance; // sigma2cut increased by 4 !!!! + if (fPrintLevel >= 2) + cout << "enter FollowTracks" << endl; + // Loop over track candidates + for (trackIndex = 0; trackIndex < fNRecTracks; trackIndex++) { + if (fPrintLevel >= 2) + cout << "FollowTracks: track candidate(0..): " << trackIndex << endl; + // function for each track candidate ???? + track = (AliMUONTrack*) ((*fRecTracksPtr)[trackIndex]); + // Fit track candidate from vertex at X = Y = 0 + track->Fit(track->GetTrackParamAtVertex(), 3); + if (fPrintLevel >= 10) { + cout << "FollowTracks: track candidate(0..): " << trackIndex + << " after fit in stations(1..) 4 and 5" << endl; + track->RecursiveDump(); + } + // Loop over stations(1..) 3, 2 and 1 + // something SPECIAL for stations 2 and 1 for majority coincidence ???? + for (station = 2; station >= 0; station--) { + // Track parameters at first track hit (smallest Z) + trackParam1 = ((AliMUONTrackHit*) + (track->GetTrackHitsPtr()->First()))->GetTrackParam(); + // extrapolation to station + trackParam1->ExtrapToStation(station, trackParam); + extrapSegment = new AliMUONSegment::AliMUONSegment(); // empty segment + // multiple scattering factor corresponding to one chamber + // and momentum in bending plane (not total) + mcsFactor = 0.0136 * trackParam1->GetInverseBendingMomentum(); + mcsFactor = fChamberThicknessInX0 * mcsFactor * mcsFactor; + // Z difference from previous station + dZ1 = (&(MUON->Chamber(2 * station)))->Z() - + (&(MUON->Chamber(2 * station + 2)))->Z(); + // Z difference between the two previous stations + dZ2 = (&(MUON->Chamber(2 * station + 2)))->Z() - + (&(MUON->Chamber(2 * station + 4)))->Z(); + extrapSegment->SetBendingCoorReso2(fBendingResolution); + extrapSegment->SetNonBendingCoorReso2(fNonBendingResolution); + extrapSegment->UpdateFromStationTrackParam(trackParam, mcsFactor, dZ1, dZ2); + bestChi2 = 5.0; + bestSegment = NULL; + if (fPrintLevel >= 10) { + cout << "FollowTracks: track candidate(0..): " << trackIndex + << " Look for segment in station(0..): " << station << endl; + } + // Loop over segments in station + for (iSegment = 0; iSegment < fNSegments[station]; iSegment++) { + // Look for best compatible Segment in station + // should consider all possibilities ???? + // multiple scattering ???? + // separation in 2 functions: Segment and HitForRec ???? + segment = (AliMUONSegment*) ((*fSegmentsPtr[station])[iSegment]); + chi2 = segment->NormalizedChi2WithSegment(extrapSegment, maxSigma2Distance); + if (chi2 < bestChi2) { + // update best Chi2 and Segment if better found + bestSegment = segment; + bestChi2 = chi2; + } + } + if (bestSegment) { + // best segment found: add it to track candidate + track->AddSegment(bestSegment); + // set track parameters at these two TrakHit's + track->SetTrackParamAtHit(track->GetNTrackHits() - 2, &(trackParam[0])); + track->SetTrackParamAtHit(track->GetNTrackHits() - 1, &(trackParam[1])); + if (fPrintLevel >= 10) { + cout << "FollowTracks: track candidate(0..): " << trackIndex + << " Added segment in station(0..): " << station << endl; + track->RecursiveDump(); + } + } + else { + // No best segment found: + // Look for best compatible HitForRec in station: + // should consider all possibilities ???? + // multiple scattering ???? do about like for extrapSegment !!!! + extrapHit = new AliMUONHitForRec::AliMUONHitForRec(); // empty hit + bestChi2 = 3.0; + bestHit = NULL; + if (fPrintLevel >= 10) { + cout << "FollowTracks: track candidate(0..): " << trackIndex + << " Segment not found, look for hit in station(0..): " << station + << endl; + } + // Loop over chambers of the station + for (ch = 0; ch < 2; ch++) { + // coordinates of extrapolated hit + extrapHit->SetBendingCoor((&(trackParam[ch]))->GetBendingCoor()); + extrapHit->SetNonBendingCoor((&(trackParam[ch]))->GetNonBendingCoor()); + // resolutions from "extrapSegment" + extrapHit->SetBendingReso2(extrapSegment->GetBendingCoorReso2()); + extrapHit->SetNonBendingReso2(extrapSegment->GetNonBendingCoorReso2()); + // Loop over hits in the chamber + for (iHit = fIndexOfFirstHitForRecPerChamber[ch]; + iHit < fIndexOfFirstHitForRecPerChamber[ch] + + fNHitsForRecPerChamber[ch]; + iHit++) { + hit = (AliMUONHitForRec*) ((*fHitsForRecPtr)[iHit]); + // condition for hit not already in segment ???? + chi2 = hit->NormalizedChi2WithHitForRec(extrapHit, maxSigma2Distance); + if (chi2 < bestChi2) { + // update best Chi2 and HitForRec if better found + bestHit = hit; + bestChi2 = chi2; + chBestHit = ch; + } + } + } + if (bestHit) { + // best hit found: add it to track candidate + track->AddHitForRec(bestHit); + // set track parameters at these two TrakHit's + track->SetTrackParamAtHit(track->GetNTrackHits() - 1, + &(trackParam[chBestHit])); + if (fPrintLevel >= 10) { + cout << "FollowTracks: track candidate(0..): " << trackIndex + << " Added hit in station(0..): " << station << endl; + track->RecursiveDump(); + } + } + else { + fRecTracksPtr->RemoveAt(trackIndex); // Remove candidate + break; // stop the search for this candidate: + // exit from the loop over station + } + } + // Sort track hits according to increasing Z + track->GetTrackHitsPtr()->Sort(); + // Update track parameters at first track hit (smallest Z) + trackParam1 = ((AliMUONTrackHit*) + (track->GetTrackHitsPtr()->First()))->GetTrackParam(); + // Track fit from first track hit varying X and Y + track->Fit(trackParam1, 5); + if (fPrintLevel >= 10) { + cout << "FollowTracks: track candidate(0..): " << trackIndex + << " after fit from station(0..): " << station << " to 4" << endl; + track->RecursiveDump(); + } + delete extrapSegment; + } // for (station = 2;... + } // for (trackIndex = 0;... + return; +} + +void AliMUONEventReconstructor::Streamer(TBuffer &R__b) +{ + ; +} diff --git a/MUON/AliMUONEventReconstructor.h b/MUON/AliMUONEventReconstructor.h new file mode 100644 index 00000000000..51ec1865771 --- /dev/null +++ b/MUON/AliMUONEventReconstructor.h @@ -0,0 +1,134 @@ +#ifndef ALIMUONEVENTRECONSTRUCTOR_H +#define ALIMUONEVENTRECONSTRUCTOR_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/*$Id$*/ + +#include + +class AliMUONHit; +class AliMUONHitForRec; +class AliMUONSegment; +class TClonesArray; +class TFile; +class TTree; + +// Constants which should be elsewhere ???? +const Int_t MAX_MUON_TRACKING_CHAMBERS = 10; +const Int_t MAX_MUON_TRACKING_STATIONS = MAX_MUON_TRACKING_CHAMBERS / 2; + +class AliMUONEventReconstructor : public TObject { + + public: + AliMUONEventReconstructor(void); // Constructor + virtual ~AliMUONEventReconstructor(void); // Destructor + + // Parameters for event reconstruction: public methods + // Get and Set, Set to defaults + Double_t GetMinBendingMomentum(void) {return fMinBendingMomentum;} + void SetMinBendingMomentum(Double_t MinBendingMomentum) {fMinBendingMomentum = MinBendingMomentum;} + Double_t GetMaxSigma2Distance(void) {return fMaxSigma2Distance;} + void SetMaxSigma2Distance(Double_t MaxSigma2Distance) {fMaxSigma2Distance = MaxSigma2Distance;} + Double_t GetBendingResolution(void) {return fBendingResolution;} + void SetBendingResolution(Double_t BendingResolution) {fBendingResolution = BendingResolution;} + Double_t GetNonBendingResolution(void) {return fNonBendingResolution;} + void SetNonBendingResolution(Double_t NonBendingResolution) {fNonBendingResolution = NonBendingResolution;} + Double_t GetChamberThicknessInX0(void) {return fChamberThicknessInX0;} + void SetChamberThicknessInX0(Double_t ChamberThicknessInX0) {fChamberThicknessInX0 = ChamberThicknessInX0;} + Double_t GetSimpleBValue(void) {return fSimpleBValue;} + void SetSimpleBValue(Double_t SimpleBValue) {fSimpleBValue = SimpleBValue;} + Double_t GetSimpleBLength(void) {return fSimpleBLength;} + void SetSimpleBLength(Double_t SimpleBLength) {fSimpleBLength = SimpleBLength;} + Double_t GetSimpleBPosition(void) {return fSimpleBPosition;} + void SetSimpleBPosition(Double_t SimpleBPosition) {fSimpleBPosition = SimpleBPosition;} + Int_t GetRecGeantHits(void) {return fRecGeantHits;} + void SetRecGeantHits(Int_t RecGeantHits) {fRecGeantHits = RecGeantHits;} + Double_t GetEfficiency(void) {return fEfficiency;} + void SetEfficiency(Double_t Efficiency) {fEfficiency = Efficiency;} + Int_t GetPrintLevel(void) {return fPrintLevel;} + void SetPrintLevel(Int_t PrintLevel) {fPrintLevel = PrintLevel;} + void SetReconstructionParametersToDefaults(void); + + // Parameters for GEANT background events + TFile* GetBkgGeantFile(void) {return fBkgGeantFile;} + void SetBkgGeantFile(Text_t *BkgGeantFileName); // set background file for GEANT hits + void NextBkgGeantEvent(void); // next event in background file for GEANT hits + + // Hits for reconstruction + Int_t GetNHitsForRec() {return fNHitsForRec;} // Number + + // Functions + Double_t GetImpactParamFromBendingMomentum(Double_t BendingMomentum); + Double_t GetBendingMomentumFromImpactParam(Double_t ImpactParam); + void EventReconstruct(void); + + private: + + // Parameters for event reconstruction + Double_t fMinBendingMomentum; // minimum value (GeV/c) of momentum in bending plane + Double_t fMaxSigma2Distance; // maximum square distance in units of the variance (maximum chi2) + Double_t fRMin[MAX_MUON_TRACKING_CHAMBERS]; // minimum radius (cm) + Double_t fRMax[MAX_MUON_TRACKING_CHAMBERS]; // maximum radius (cm) + Double_t fSegmentMaxDistBending[MAX_MUON_TRACKING_STATIONS]; // maximum distance (cm) for segments in bending plane + Double_t fSegmentMaxDistNonBending[MAX_MUON_TRACKING_STATIONS]; // maximum distance (cm) for segments in bending plane + Double_t fBendingResolution; // chamber resolution (cm) in bending plane + Double_t fNonBendingResolution; // chamber resolution (cm) in non bending plane + Double_t fChamberThicknessInX0; // chamber thickness in number of radiation lengths + // how to take it from simulation ???? + Double_t fSimpleBValue; // simple magnetic field: value (kG) + Double_t fSimpleBLength; // simple magnetic field: length (cm) + Double_t fSimpleBPosition; // simple magnetic field: Z central position (cm) + Int_t fRecGeantHits; // reconstruction from raw clusters (0) or from GEANT hits (1) + Double_t fEfficiency; // chamber efficiency (used for GEANT hits only) + Int_t fPrintLevel; // print level + + // Parameters for GEANT background events + // should be in AliMUON class ???? + TFile *fBkgGeantFile; // pointer to file + TTree *fBkgGeantTK; // pointer to tree TK + TClonesArray *fBkgGeantParticles; // pointer to list of particles in tree TK + TTree *fBkgGeantTH; // pointer to tree TH + TClonesArray *fBkgGeantHits; // pointer to list of hits in tree TH + Int_t fBkgGeantEventNumber; // event number + + // Hits for reconstruction (should be in AliMUON ????) + TClonesArray *fHitsForRecPtr; // pointer to the array of hits for reconstruction + Int_t fNHitsForRec; // number of hits for reconstruction + // Information per chamber (should be in AliMUONChamber ????) + Int_t fNHitsForRecPerChamber[MAX_MUON_TRACKING_CHAMBERS]; // number of HitsForRec + Int_t fIndexOfFirstHitForRecPerChamber[MAX_MUON_TRACKING_CHAMBERS]; // index (0...) of first HitForRec + + // Segments inside a station + TClonesArray *fSegmentsPtr[MAX_MUON_TRACKING_STATIONS]; // array of pointers to the segments for each station + Int_t fNSegments[MAX_MUON_TRACKING_STATIONS]; // number of segments for each station + + // Tracks + TClonesArray *fRecTracksPtr; // pointer to array of reconstructed tracks + Int_t fNRecTracks; // number of reconstructed tracks + + // Functions + void ResetHitsForRec(void); + void MakeEventToBeReconstructed(void); + void AddHitsForRecFromGEANT(TTree *TH); + void AddHitsForRecFromBkgGEANT(TTree *TH, TClonesArray *Hits); + AliMUONHitForRec* NewHitForRecFromGEANT(AliMUONHit* Hit, Int_t TrackNumber, Int_t HitNumber, Int_t Signal); +/* void AddHitsForRecFromCathodeCorrelations(TTree* TC); */ + void AddHitsForRecFromRawClusters(TTree* TR); + void SortHitsForRecWithIncreasingChamber(); + void MakeSegments(void); + void ResetSegments(void); + void MakeSegmentsPerStation(Int_t Station); + void MakeTracks(void); + void ResetTracks(void); + Int_t MakeTrackCandidatesWithTwoSegments(AliMUONSegment *BegSegment); + Int_t MakeTrackCandidatesWithOneSegmentAndOnePoint(AliMUONSegment *BegSegment); + void MakeTrackCandidates(void); + void FollowTracks(void); + + protected: + + ClassDef(AliMUONEventReconstructor, 1) // Class definition in ROOT context + }; + +#endif diff --git a/MUON/AliMUONGlobalTrigger.cxx b/MUON/AliMUONGlobalTrigger.cxx new file mode 100644 index 00000000000..598dc9554d4 --- /dev/null +++ b/MUON/AliMUONGlobalTrigger.cxx @@ -0,0 +1,73 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* + +*/ + +#include "AliMUONGlobalTrigger.h" + +ClassImp(AliMUONGlobalTrigger); +//---------------------------------------------------------------------- +AliMUONGlobalTrigger::AliMUONGlobalTrigger() +{ +// constructor + fSinglePlusLpt = 0; + fSinglePlusHpt = 0; + fSinglePlusApt = 0; + + fSingleMinusLpt = 0; + fSingleMinusHpt = 0; + fSingleMinusApt = 0; + + fSingleUndefLpt = 0; + fSingleUndefHpt = 0; + fSingleUndefApt = 0; + + fPairUnlikeLpt = 0; + fPairUnlikeHpt = 0; + fPairUnlikeApt = 0; + + fPairLikeLpt = 0; + fPairLikeHpt = 0; + fPairLikeApt = 0; +} +//---------------------------------------------------------------------- +AliMUONGlobalTrigger::AliMUONGlobalTrigger(Int_t *singlePlus, + Int_t *singleMinus, + Int_t *singleUndef, + Int_t *pairUnlike, Int_t *pairLike) +{ +// Set the Global Trigger object + fSinglePlusLpt = singlePlus[0]; + fSinglePlusHpt = singlePlus[1]; + fSinglePlusApt = singlePlus[2]; + + fSingleMinusLpt = singleMinus[0]; + fSingleMinusHpt = singleMinus[1]; + fSingleMinusApt = singleMinus[2]; + + fSingleUndefLpt = singleUndef[0]; + fSingleUndefHpt = singleUndef[1]; + fSingleUndefApt = singleUndef[2]; + + fPairUnlikeLpt = pairUnlike[0]; + fPairUnlikeHpt = pairUnlike[1]; + fPairUnlikeApt = pairUnlike[2]; + + fPairLikeLpt = pairLike[0]; + fPairLikeHpt = pairLike[1]; + fPairLikeApt = pairLike[2]; +} diff --git a/MUON/AliMUONGlobalTrigger.h b/MUON/AliMUONGlobalTrigger.h new file mode 100644 index 00000000000..5dd2f2c897e --- /dev/null +++ b/MUON/AliMUONGlobalTrigger.h @@ -0,0 +1,43 @@ +#ifndef ALIMUONGLOBALTRIGGER_H +#define ALIMUONGLOBALTRIGGER_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* */ + +#include + +class AliMUONGlobalTrigger : public TObject { + public: + Int_t fSinglePlusLpt; // Number of Single Plus Low pt + Int_t fSinglePlusHpt; // Number of Single Plus High pt + Int_t fSinglePlusApt; // Number of Single Plus All pt + Int_t fSingleMinusLpt; // Number of Single Minus Low pt + Int_t fSingleMinusHpt; // Number of Single Minus High pt + Int_t fSingleMinusApt; // Number of Single Minus All pt + Int_t fSingleUndefLpt; // Number of Single Undefined Low pt + Int_t fSingleUndefHpt; // Number of Single Undefined High pt + Int_t fSingleUndefApt; // Number of Single Undefined All pt + Int_t fPairUnlikeLpt; // Number of Unlike sign pair Low pt + Int_t fPairUnlikeHpt; // Number of Unlike sign pair High pt + Int_t fPairUnlikeApt; // Number of Unlike sign pair All pt + Int_t fPairLikeLpt; // Number of Like sign pair Low pt + Int_t fPairLikeHpt; // Number of Like sign pair High pt + Int_t fPairLikeApt; // Number of Like sign pair All pt + + public: + AliMUONGlobalTrigger(); + AliMUONGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus, + Int_t *singleUndef, Int_t *pairUnlike, Int_t *pairLike); + virtual ~AliMUONGlobalTrigger(){;} + + ClassDef(AliMUONGlobalTrigger,1) // reconstructed Global Trigger object +}; +#endif + + + + + + diff --git a/MUON/AliMUONHit.cxx b/MUON/AliMUONHit.cxx new file mode 100644 index 00000000000..c11d67a01b4 --- /dev/null +++ b/MUON/AliMUONHit.cxx @@ -0,0 +1,57 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 22:02:14 morsch +Was before in DataStructures.cxx + +*/ +#include "AliMUONHit.h" + +ClassImp(AliMUONHit) + +//___________________________________________ + AliMUONHit::AliMUONHit(Int_t shunt, Int_t track, Int_t *vol, Float_t *hits): + AliHit(shunt, track) +{ +// Constructor + fChamber=vol[0]; + fParticle=hits[0]; + fX=hits[1]; + fY=hits[2]; + fZ=hits[3]; + fTheta=hits[4]; + fPhi=hits[5]; + fTlength=hits[6]; + fEloss=hits[7]; + fPHfirst=(Int_t) hits[8]; + fPHlast=(Int_t) hits[9]; + + // modifs perso + fPTot=hits[10]; + fCxHit=hits[11]; + fCyHit=hits[12]; + fCzHit=hits[13]; + fAge=hits[14]; + +} + + + + + + + diff --git a/MUON/AliMUONHit.h b/MUON/AliMUONHit.h new file mode 100644 index 00000000000..116224f8ded --- /dev/null +++ b/MUON/AliMUONHit.h @@ -0,0 +1,34 @@ +#ifndef ALIMUONHIT_H +#define ALIMUONHIT_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include "AliHit.h" + +class AliMUONHit : public AliHit { + public: + Int_t fChamber; // Chamber number + 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 + Float_t fAge; // Particle Age + Int_t fPHfirst; // first padhit + Int_t fPHlast; // last padhit + + Float_t fPTot; // hit local 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 ~AliMUONHit() {} + + ClassDef(AliMUONHit,1) //Hit object for set:MUON +}; +#endif diff --git a/MUON/AliMUONHitForRec.cxx b/MUON/AliMUONHitForRec.cxx new file mode 100644 index 00000000000..afcd225827f --- /dev/null +++ b/MUON/AliMUONHitForRec.cxx @@ -0,0 +1,237 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.4 2000/06/12 10:11:10 morsch +Dummy copy constructor and assignment operator added + +Revision 1.1.2.3 2000/06/09 22:14:43 morsch +Make includes consistent with new file naming. + +Revision 1.1.2.2 2000/06/09 12:58:05 gosset +Removed comment beginnings in Log sections of .cxx files +Suppressed most violations of coding rules + +Revision 1.1.2.1 2000/06/07 14:44:53 gosset +Addition of files for track reconstruction in C++ +*/ + +//__________________________________________________________________________ +// +// Hit for reconstruction in ALICE dimuon spectrometer +//__________________________________________________________________________ + +#include "AliMUONHitForRec.h" +#include "AliMUONTrackParam.h" +#include "AliMUONRawCluster.h" +#include "AliMUONHit.h" + +ClassImp(AliMUONHitForRec) // Class implementation in ROOT context + + //__________________________________________________________________________ +AliMUONHitForRec::AliMUONHitForRec(AliMUONHit* Ghit) +{ + // Constructor for AliMUONHitForRec from a GEANT hit. + // Fills the bending, non bending, and Z coordinates, + // which are taken from the coordinates of the GEANT hit, + // the track number (GEANT and not TH), + // and the chamber number (0...). + fBendingCoor = Ghit->fY; + fNonBendingCoor = Ghit->fX; + fZ = Ghit->fZ; + // fTrack = Ghit->fTrack; ????????? + fChamberNumber = Ghit->fChamber - 1; + // other fields will be updated in + // AliMUONEventReconstructor::NewHitForRecFromGEANT, + // except the following ones + fIndexOfFirstSegment = -1; + fNSegments = 0; + fFirstTrackHitPtr = fLastTrackHitPtr = NULL; + fNTrackHits = 0; + return; +} + +// //__________________________________________________________________________ +// AliMUONHitForRec::AliMUONHitForRec(AliMUONReconstHit* CathCorrel) +// { +// // Constructor for AliMUONHitForRec from a (cathode correlated) raw cluster. +// // Fills the bending and non bending coordinates. +// // Only the first correlation is taken into account. +// // The bending coordinate is taken from the first cathode. +// // The non bending coordinate is taken +// // from the second cathode if it exists, +// // from the first one otherwise. +// fBendingCoor = CathCorrel->fY[3]; +// if (CathCorrel->fCorrelIndex[0] >= 0) fNonBendingCoor = CathCorrel->fX[0]; +// else fNonBendingCoor = CathCorrel->fX[3]; +// return; +// } + + //__________________________________________________________________________ +AliMUONHitForRec::AliMUONHitForRec(AliMUONRawCluster* RawCluster) +{ + // Constructor for AliMUONHitForRec from a raw cluster. + // Fills the bending and non bending coordinates. + fNonBendingCoor = RawCluster->fX[0]; + fBendingCoor = RawCluster->fY[0]; + // other fields will be updated in + // AliMUONEventReconstructor::AddHitsForRecFromRawClusters, + // except the following ones + fTHTrack = -1; + fGeantSignal = -1; + fIndexOfFirstSegment = -1; + fNSegments = 0; + fFirstTrackHitPtr = fLastTrackHitPtr = NULL; + fNTrackHits = 0; + return; +} + +AliMUONHitForRec::AliMUONHitForRec (const AliMUONHitForRec& MUONHitForRec) +{ +// Dummy copy constructor +} + +AliMUONHitForRec & AliMUONHitForRec::operator=(const AliMUONHitForRec& MUONHitForRec) +{ +// Dummy assignment operator + return *this; +} +// Inline functions for Get and Set +inline Double_t AliMUONHitForRec::GetBendingCoor(void) { + // Get fBendingCoor + return fBendingCoor;} +inline void AliMUONHitForRec::SetBendingCoor(Double_t BendingCoor) { + // Set fBendingCoor + fBendingCoor = BendingCoor;} +inline Double_t AliMUONHitForRec::GetNonBendingCoor(void) { + // Get fNonBendingCoor + return fNonBendingCoor;} +inline void AliMUONHitForRec::SetNonBendingCoor(Double_t NonBendingCoor) { + // Set fNonBendingCoor + fNonBendingCoor = NonBendingCoor;} +inline Double_t AliMUONHitForRec::GetZ(void) { + // Get fZ + return fZ;} +inline void AliMUONHitForRec::SetZ(Double_t Z) { + // Set fZ + fZ = Z;} +inline Double_t AliMUONHitForRec::GetBendingReso2(void) { + // Get fBendingReso2 + return fBendingReso2;} +inline void AliMUONHitForRec::SetBendingReso2(Double_t BendingReso2) { + // Set fBendingReso2 + fBendingReso2 = BendingReso2;} +inline Double_t AliMUONHitForRec::GetNonBendingReso2(void) { + // Get fNonBendingReso2 + return fNonBendingReso2;} +inline void AliMUONHitForRec::SetNonBendingReso2(Double_t NonBendingReso2) { + // Set fNonBendingReso2 + fNonBendingReso2 = NonBendingReso2;} +inline Int_t AliMUONHitForRec::GetChamberNumber(void) { + // Get fChamberNumber + return fChamberNumber;} +inline void AliMUONHitForRec::SetChamberNumber(Int_t ChamberNumber) { + // Set fChamberNumber + fChamberNumber = ChamberNumber;} +inline Int_t AliMUONHitForRec::GetHitNumber(void) { + // Get fHitNumber + return fHitNumber;} +inline void AliMUONHitForRec::SetHitNumber(Int_t HitNumber) { + // Set fHitNumber + fHitNumber = HitNumber;} +inline Int_t AliMUONHitForRec::GetTHTrack(void) { + // Get fTHTrack + return fTHTrack;} +inline void AliMUONHitForRec::SetTHTrack(Int_t THTrack) { + // Set fTHTrack + fTHTrack = THTrack;} +inline Int_t AliMUONHitForRec::GetGeantSignal(void) { + // Get fGeantSignal + return fGeantSignal;} +inline void AliMUONHitForRec::SetGeantSignal(Int_t GeantSignal) { + // Set fGeantSignal + fGeantSignal = GeantSignal;} +inline Int_t AliMUONHitForRec::GetIndexOfFirstSegment(void) { + // Get fIndexOfFirstSegment + return fIndexOfFirstSegment;} +inline void AliMUONHitForRec::SetIndexOfFirstSegment(Int_t IndexOfFirstSegment) { + // Set fIndexOfFirstSegment + fIndexOfFirstSegment = IndexOfFirstSegment;} +inline Int_t AliMUONHitForRec::GetNSegments(void) { + // Get fNSegments + return fNSegments;} +inline void AliMUONHitForRec::SetNSegments(Int_t NSegments) { + // Set fNSegments + fNSegments = NSegments;} +inline AliMUONTrackHit* AliMUONHitForRec::GetFirstTrackHitPtr(void) { + // Get fFirstTrackHitPtr + return fFirstTrackHitPtr;} +inline void AliMUONHitForRec::SetFirstTrackHitPtr(AliMUONTrackHit* FirstTrackHitPtr) { + // Set fFirstTrackHitPtr + fFirstTrackHitPtr = FirstTrackHitPtr;} +inline AliMUONTrackHit* AliMUONHitForRec::GetLastTrackHitPtr(void) { + // Get fLastTrackHitPtr + return fLastTrackHitPtr;} +inline void AliMUONHitForRec::SetLastTrackHitPtr(AliMUONTrackHit* LastTrackHitPtr) { + // Set fLastTrackHitPtr + fLastTrackHitPtr = LastTrackHitPtr;} +inline Int_t AliMUONHitForRec::GetNTrackHits(void) { + // Get fNTrackHits + return fNTrackHits;} +inline void AliMUONHitForRec::SetNTrackHits(Int_t NTrackHits) { + // Set fNTrackHits + fNTrackHits = NTrackHits;} + + //__________________________________________________________________________ +Int_t AliMUONHitForRec::Compare(TObject* Hit) +{ + // "Compare" function to sort with increasing chamber number. + // Returns -1 (0, +1) if ChamberNumber of current HitForRec + // is smaller than (equal to, larger than) ChamberNumber of Hit + if (fChamberNumber < ((AliMUONHitForRec*)Hit)->fChamberNumber) return(-1); + else if (fChamberNumber == ((AliMUONHitForRec*)Hit)->fChamberNumber) return( 0); + else return(+1); +} + + //__________________________________________________________________________ +Double_t AliMUONHitForRec::NormalizedChi2WithHitForRec(AliMUONHitForRec* HitForRec, Double_t Sigma2Cut) +{ + // Calculate the normalized Chi2 between the current HitForRec (this) + // and the HitForRec pointed to by "HitForRec", + // i.e. the square deviations between the coordinates, + // in both the bending and the non bending plane, + // divided by the variance of the same quantities and by "Sigma2Cut". + // Returns 3 if none of the 2 quantities is OK, + // something smaller than or equal to 2 otherwise. + // Would it be more correct to use a real chi square + // including the non diagonal term ???? + Double_t chi2, chi2Max, diff, normDiff; + chi2 = 0.0; + chi2Max = 3.0; + // coordinate in bending plane + diff = this->fBendingCoor - HitForRec->fBendingCoor; + normDiff = diff * diff / + (this->fBendingReso2 + HitForRec->fBendingReso2) / Sigma2Cut; + if (normDiff > 1.0) return chi2Max; + chi2 = chi2 + normDiff; + // coordinate in non bending plane + diff = this->fNonBendingCoor - HitForRec->fNonBendingCoor; + normDiff = diff * diff / + (this->fNonBendingReso2 + HitForRec->fNonBendingReso2) / Sigma2Cut; + if (normDiff > 1.0) return chi2Max; + chi2 = chi2 + normDiff; + return chi2; +} diff --git a/MUON/AliMUONHitForRec.h b/MUON/AliMUONHitForRec.h new file mode 100644 index 00000000000..f77c7e4a770 --- /dev/null +++ b/MUON/AliMUONHitForRec.h @@ -0,0 +1,91 @@ +#ifndef ALIMUONHITFORREC_H +#define ALIMUONHITFORREC_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/*$Id$*/ + +#include + +class AliMUONHit; +class AliMUONRawCluster; +class AliMUONTrackHit; +class AliMUONTrackParam; + +class AliMUONHitForRec : public TObject { + public: + AliMUONHitForRec(){ + // Constructor + ;} // Constructor + virtual ~AliMUONHitForRec(){ + // Destructor + ;} // Destructor + AliMUONHitForRec (const AliMUONHitForRec& AliMUONHitForRec); // copy constructor + AliMUONHitForRec& operator=(const AliMUONHitForRec& AliMUONHitForRec); // assignment operator + AliMUONHitForRec(AliMUONHit* mHit); // Constructor from GEANT hit + AliMUONHitForRec(AliMUONRawCluster* RawCluster); // Constructor from raw cluster + + Double_t GetBendingCoor(void); + void SetBendingCoor(Double_t BendingCoor); + Double_t GetNonBendingCoor(void); + void SetNonBendingCoor(Double_t NonBendingCoor); + Double_t GetZ(void); + void SetZ(Double_t Z); + Double_t GetBendingReso2(void); + void SetBendingReso2(Double_t BendingReso2); + Double_t GetNonBendingReso2(void); + void SetNonBendingReso2(Double_t NonBendingReso2); + Int_t GetChamberNumber(void); + void SetChamberNumber(Int_t ChamberNumber); + Int_t GetHitNumber(void); + void SetHitNumber(Int_t HitNumber); + Int_t GetTHTrack(void); + void SetTHTrack(Int_t THTrack); + Int_t GetGeantSignal(void); + void SetGeantSignal(Int_t GeantSignal); + Int_t GetIndexOfFirstSegment(void); + void SetIndexOfFirstSegment(Int_t IndexOfFirstSegment); + Int_t GetNSegments(void); + void SetNSegments(Int_t NSegments); + AliMUONTrackHit* GetFirstTrackHitPtr(void); + void SetFirstTrackHitPtr(AliMUONTrackHit* FirstTrackHitPtr); + AliMUONTrackHit* GetLastTrackHitPtr(void); + void SetLastTrackHitPtr(AliMUONTrackHit* LastTrackHitPtr); + Int_t GetNTrackHits(void); + void SetNTrackHits(Int_t NTrackHits); + + Double_t NormalizedChi2WithHitForRec(AliMUONHitForRec* Hit, Double_t Sigma2Cut); +/* void UpdateFromChamberTrackParam(AliMUONTrackParam *TrackParam, Double_t MCSfactor); */ + + // What is necessary for sorting TClonesArray's; sufficient too ???? + Bool_t IsSortable() const { return kTRUE; } + Int_t Compare(TObject* HitForRec); // "Compare" function for sorting + protected: + private: + Double_t fBendingCoor; // coordinate (cm) in bending plane + Double_t fNonBendingCoor; // coordinate (cm) in non bending plane + Double_t fZ; // Z coordinate (cm) + Double_t fBendingReso2; // resolution**2 (cm**2) on coordinate in bending plane + Double_t fNonBendingReso2; // resolution**2 (cm**2) on coordinate in non bending plane + + // links back to original hit for various checks + // ideal would be real link to "hit" or "reconstructed hit" + // if everything would be in memory ???? + Int_t fChamberNumber; // chamber number (0...) + Int_t fHitNumber; // hit number (0...): RawCluster in "chamber" event of TR or GEANT hit in "track" event of TH + Int_t fTHTrack; // track number (0...) in TH + Int_t fGeantSignal; // Geant signal (1) or background (0) + + // links forward to the segment(s) if HitForRec in first chamber of a station + Int_t fIndexOfFirstSegment; // index of first Segment + Int_t fNSegments; // number of Segments + + // links forward to reconstructed track hits + AliMUONTrackHit *fFirstTrackHitPtr ; // pointer to first TrackHit made with HitForRec + AliMUONTrackHit *fLastTrackHitPtr ; // pointer to last TrackHit made with HitForRec + Int_t fNTrackHits; // number of TrackHit's made with HitForRec + + ClassDef(AliMUONHitForRec, 1) // Class definition in ROOT context + }; + +#endif diff --git a/MUON/AliMUONHitMap.cxx b/MUON/AliMUONHitMap.cxx index a1940f2c5d1..baee5ac70d8 100644 --- a/MUON/AliMUONHitMap.cxx +++ b/MUON/AliMUONHitMap.cxx @@ -15,103 +15,12 @@ /* $Log$ +Revision 1.3.4.2 2000/06/09 21:59:44 morsch +Most coding rule violations corrected. +AliMUONHitMapA1 removed from file. + */ #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(); - ClearMap(); -} - - -AliMUONHitMapA1::~AliMUONHitMapA1() -{ -// if (fDigits) delete fDigits; - if (fHitMap) delete[] fHitMap; -} - -void AliMUONHitMapA1::ClearMap() -{ - memset(fHitMap,0,sizeof(int)*fMaxIndex); -} - -Int_t AliMUONHitMapA1::CheckedIndex(Int_t ix, Int_t iy) -{ - Int_t index=2*fNpy*(ix+fNpx)+(iy+fNpy); - if (index > fMaxIndex) { - printf("\n \n \n Try to read/write outside array !!!! \n \n %d %d %d %d %d %d",ix,iy, fMaxIndex, index, fNpx, fNpy); - return fMaxIndex-1; - } else { - return index; - } -} - - -void AliMUONHitMapA1::FillHits() -{ - Int_t ndigits = fDigits->GetEntriesFast(); - //printf("\n Filling hits into HitMap\n"); - //printf("FindRawClusters -- ndigits %d \n",ndigits); - if (!ndigits) return; - AliMUONdigit *dig; - for (Int_t ndig=0; ndigUncheckedAt(ndig); - SetHit(dig->fPadX,dig->fPadY,ndig); - } -} - - -void AliMUONHitMapA1::SetHit(Int_t ix, Int_t iy, Int_t idigit) -{ -// fHitMap[kMaxNpady*(ix+fNpx)+(iy+fNpy)]=idigit+1; - fHitMap[CheckedIndex(ix, iy)]=idigit+1; -} - -void AliMUONHitMapA1::DeleteHit(Int_t ix, Int_t iy) -{ -// fHitMap[kMaxNpady*(ix+fNpx)+(iy+fNpy)]=0; - fHitMap[CheckedIndex(ix, iy)]=0; -} - -void AliMUONHitMapA1::FlagHit(Int_t ix, Int_t iy) -{ - fHitMap[CheckedIndex(ix, iy)]= - -TMath::Abs(fHitMap[CheckedIndex(ix, iy)]); -} - -Int_t AliMUONHitMapA1::GetHitIndex(Int_t ix, Int_t iy) -{ - return TMath::Abs(fHitMap[CheckedIndex(ix, iy)])-1; -} - -TObject* AliMUONHitMapA1::GetHit(Int_t ix, Int_t iy) -{ - Int_t index=GetHitIndex(ix,iy); - // Force crash if index does not exist ! (Manu) - return (index <0) ? 0 : fDigits->UncheckedAt(GetHitIndex(ix,iy)); -} - -Flag_t AliMUONHitMapA1::TestHit(Int_t ix, Int_t iy) -{ - Int_t inf=fHitMap[CheckedIndex(ix, iy)]; - if (inf < 0) { - return used; - } else if (inf == 0) { - return empty; - } else { - return unused; - } -} - +ClassImp(AliMUONHitMap) diff --git a/MUON/AliMUONHitMap.h b/MUON/AliMUONHitMap.h index db51c8b31f5..bc2fb27fa58 100644 --- a/MUON/AliMUONHitMap.h +++ b/MUON/AliMUONHitMap.h @@ -1,57 +1,47 @@ -#ifndef AliMUONHitMap_H -#define AliMUONHitMap_H +#ifndef ALIMUONHITMAP_H +#define ALIMUONHITMAP_H + /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ /* $Id$ */ -#include "AliMUON.h" -#include "TArrayI.h" -typedef enum {empty, used, unused} Flag_t; +#include + +typedef enum {kEmpty, kUsed, kUnused} FlagType; const Int_t kMaxNpadx=1200, kMaxNpady=1200; class AliMUONHitMap : public TObject { public: + // Fill hits from list of digits into hit map virtual void FillHits() =0; - virtual void ClearMap() =0; + // Clear the hit map + virtual void Clear() =0; + // Set a single hit virtual void SetHit(Int_t ix, Int_t iy, Int_t idigit) =0; + // Delete a single hit virtual void DeleteHit(Int_t ix, Int_t iy) =0; + // Get index of hit in the list of digits virtual Int_t GetHitIndex(Int_t ix, Int_t iy) =0; + // Get pointer to digit 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; + // Flag a hit as used + virtual void FlagHit(Int_t ix, Int_t iy) =0; + // Test hit status + virtual FlagType 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 fMaxIndex; - Int_t *fHitMap; //[fMaxIndex] - - public: - AliMUONHitMapA1(AliMUONsegmentation *seg, TObjArray *dig); - virtual ~AliMUONHitMapA1(); - virtual void FillHits(); - virtual void ClearMap(); - virtual void SetHit(Int_t ix, Int_t iy, Int_t idigit); - virtual void DeleteHit(Int_t ix, Int_t iy); - virtual Int_t GetHitIndex(Int_t ix, Int_t iy); - virtual TObject* GetHit(Int_t ix, Int_t); - virtual void FlagHit(Int_t ix, Int_t iy); - virtual Flag_t TestHit(Int_t ix, Int_t iy); - private: - Int_t CheckedIndex(Int_t ix, Int_t iy); - ClassDef(AliMUONHitMapA1,1) // Implements HitMap as a 2-dim array -}; #endif + + + + + + + + + diff --git a/MUON/AliMUONHitMapA1.cxx b/MUON/AliMUONHitMapA1.cxx new file mode 100644 index 00000000000..b06c0143275 --- /dev/null +++ b/MUON/AliMUONHitMapA1.cxx @@ -0,0 +1,155 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.2 2000/06/12 07:58:06 morsch +include TMath.h + +Revision 1.1.2.1 2000/06/09 22:01:09 morsch +Code from AliMUONHitMap.h +Most coding rule violations corrected. + +*/ + +#include "AliMUONHitMapA1.h" +#include "AliMUONSegmentation.h" +#include "AliMUONResponse.h" +#include "AliMUONDigit.h" + +#include +#include + +ClassImp(AliMUONHitMapA1) + + +AliMUONHitMapA1::AliMUONHitMapA1(AliMUONSegmentation *seg, TObjArray *dig) +{ +// Constructor + 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(const AliMUONHitMapA1 & hitMap) +{ +// Dummy copy constructor + ; +} + + +AliMUONHitMapA1::~AliMUONHitMapA1() +{ +// Destructor +// if (fDigits) delete fDigits; + if (fHitMap) delete[] fHitMap; +} + +void AliMUONHitMapA1::Clear() +{ +// Clear hitmap + memset(fHitMap,0,sizeof(int)*fMaxIndex); +} + +Int_t AliMUONHitMapA1::CheckedIndex(Int_t ix, Int_t iy) +{ +// Return checked indices ix, 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() +{ +// Fill hits from digits list + Int_t ndigits = fDigits->GetEntriesFast(); + //printf("\n Filling hits into HitMap\n"); + //printf("FindRawClusters -- ndigits %d \n",ndigits); + if (!ndigits) return; + AliMUONDigit *dig; + for (Int_t ndig=0; ndigUncheckedAt(ndig); + SetHit(dig->fPadX,dig->fPadY,ndig); + } +} + + +void AliMUONHitMapA1::SetHit(Int_t ix, Int_t iy, Int_t idigit) +{ +// Assign digit to hit cell ix,iy +// fHitMap[kMaxNpady*(ix+fNpx)+(iy+fNpy)]=idigit+1; + fHitMap[CheckedIndex(ix, iy)]=idigit+1; +} + +void AliMUONHitMapA1::DeleteHit(Int_t ix, Int_t iy) +{ +// Delete hit at cell ix,iy +// fHitMap[kMaxNpady*(ix+fNpx)+(iy+fNpy)]=0; + fHitMap[CheckedIndex(ix, iy)]=0; +} + +void AliMUONHitMapA1::FlagHit(Int_t ix, Int_t iy) +{ +// Flag hit as used + fHitMap[CheckedIndex(ix, iy)]= + -TMath::Abs(fHitMap[CheckedIndex(ix, iy)]); +} + +Int_t AliMUONHitMapA1::GetHitIndex(Int_t ix, Int_t iy) +{ +// Get absolute value of contents of hit cell ix,iy + return TMath::Abs(fHitMap[CheckedIndex(ix, iy)])-1; +} + +TObject* AliMUONHitMapA1::GetHit(Int_t ix, Int_t iy) +{ + // Get pointer to object at hit cell ix, iy + // Force crash if index does not exist ! (Manu) + Int_t index=GetHitIndex(ix,iy); + return (index <0) ? 0 : fDigits->UncheckedAt(GetHitIndex(ix,iy)); +} + +FlagType AliMUONHitMapA1::TestHit(Int_t ix, Int_t iy) +{ +// Check if hit cell is empty, used or unused +// + Int_t inf=fHitMap[CheckedIndex(ix, iy)]; + if (inf < 0) { + return kUsed; + } else if (inf == 0) { + return kEmpty; + } else { + return kUnused; + } +} + +AliMUONHitMapA1 & AliMUONHitMapA1::operator = (const AliMUONHitMapA1 & rhs) +{ +// Dummy assignment operator + return *this; +} + + diff --git a/MUON/AliMUONHitMapA1.h b/MUON/AliMUONHitMapA1.h new file mode 100644 index 00000000000..dd048f9f286 --- /dev/null +++ b/MUON/AliMUONHitMapA1.h @@ -0,0 +1,57 @@ +#ifndef ALIMUONHITMAPA1_H +#define ALIMUONHITMAPA1_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include "AliMUONHitMap.h" +class AliMUONSegmentation; +class TObjArray; + + + +class AliMUONHitMapA1 : +public AliMUONHitMap +{ + public: + AliMUONHitMapA1(AliMUONSegmentation *seg, TObjArray *dig); + AliMUONHitMapA1(const AliMUONHitMapA1 & hitMap); + + virtual ~AliMUONHitMapA1(); + // Fill hits from list of digits into hit map + virtual void FillHits(); + // Clear the hit map + virtual void Clear(); + // Set a single hit + virtual void SetHit(Int_t ix, Int_t iy, Int_t idigit); + // Delete a single hit + virtual void DeleteHit(Int_t ix, Int_t iy); + // Get index of hit in the list of digits + virtual Int_t GetHitIndex(Int_t ix, Int_t iy); + // Get pointer to digit + virtual TObject* GetHit(Int_t ix, Int_t iy); + // Flag a hit as used + virtual void FlagHit(Int_t ix, Int_t iy); + // Test hit status + virtual FlagType TestHit(Int_t ix, Int_t iy); + // Assignment operator + AliMUONHitMapA1& operator = (const AliMUONHitMapA1& rhs); + + private: + // Check index + Int_t CheckedIndex(Int_t ix, Int_t iy); + private: + AliMUONSegmentation *fSegmentation; // Chamber segmentation + Int_t fNpx; // Maximum number of pads in x + Int_t fNpy; // Maximum number of pads in y + TObjArray *fDigits; // Pointer to digits + Int_t fNdigits; // Number of digits + Int_t *fHitMap; // [fMaxIndex] + Int_t fMaxIndex; // maximum index in hit map + + + ClassDef(AliMUONHitMapA1,1) // Implements HitMap as a 1-dim array +}; +#endif diff --git a/MUON/AliMUONLocalTrigger.cxx b/MUON/AliMUONLocalTrigger.cxx new file mode 100644 index 00000000000..7770c074493 --- /dev/null +++ b/MUON/AliMUONLocalTrigger.cxx @@ -0,0 +1,46 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* + +*/ + +#include "AliMUONLocalTrigger.h" + +ClassImp(AliMUONLocalTrigger); +//---------------------------------------------------------------------- +AliMUONLocalTrigger::AliMUONLocalTrigger() +{ +// constructor + fLoCircuit = 0; + fLoStripX = 0; + fLoDev = 0; + fLoStripY = 0; + fLoLpt = 0; + fLoHpt = 0; + fLoApt = 0; +} +//---------------------------------------------------------------------- +AliMUONLocalTrigger::AliMUONLocalTrigger(Int_t *localtr) +{ +// add a local trigger object + fLoCircuit = localtr[0]; + fLoStripX = localtr[1]; + fLoDev = localtr[2]; + fLoStripY = localtr[3]; + fLoLpt = localtr[4]; + fLoHpt = localtr[5]; + fLoApt = localtr[6]; +} diff --git a/MUON/AliMUONLocalTrigger.h b/MUON/AliMUONLocalTrigger.h new file mode 100644 index 00000000000..0485ea9d159 --- /dev/null +++ b/MUON/AliMUONLocalTrigger.h @@ -0,0 +1,35 @@ +#ifndef ALIMUONLOCALTRIGGER_H +#define ALIMUONLOCALTRIGGER_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* */ + +#include + +class AliMUONLocalTrigger : public TObject { + public: + Int_t fLoCircuit; // circuit number + Int_t fLoStripX; // X strip in MT11 + Int_t fLoDev; // deviation + Int_t fLoStripY; // Y strip in MT11 + Int_t fLoLpt; // Low pt 0 : nothing, 1 : Minus, 2 : Plus, 3 : Undef + Int_t fLoHpt; // High pt 0 : nothing, 1 : Minus, 2 : Plus, 3 : Undef + Int_t fLoApt; // All pt 0 : nothing, 1 : Minus, 2 : Plus, 3 : Undef + + public: + AliMUONLocalTrigger(); + AliMUONLocalTrigger(Int_t *localtr); + virtual ~AliMUONLocalTrigger(){;} + + ClassDef(AliMUONLocalTrigger,1) // reconstructed Local Trigger object + +}; +#endif + + + + + + diff --git a/MUON/AliMUONPadHit.cxx b/MUON/AliMUONPadHit.cxx new file mode 100644 index 00000000000..b8975bb3b26 --- /dev/null +++ b/MUON/AliMUONPadHit.cxx @@ -0,0 +1,38 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 22:02:45 morsch +Was before in DataStructures.cxx + +*/ + +#include "AliMUONPadHit.h" + +ClassImp(AliMUONPadHit) + +//___________________________________________ +AliMUONPadHit::AliMUONPadHit(Int_t *clhits) +{ + fHitNumber=clhits[0]; + fCathode=clhits[1]; + fQ=clhits[2]; + fPadX=clhits[3]; + fPadY=clhits[4]; + fQpad=clhits[5]; + fRSec=clhits[6]; +} + diff --git a/MUON/AliMUONPadHit.h b/MUON/AliMUONPadHit.h new file mode 100644 index 00000000000..62fdf33c3e4 --- /dev/null +++ b/MUON/AliMUONPadHit.h @@ -0,0 +1,31 @@ +#ifndef ALIMUONPADHIT_H +#define ALIMUONPADHIT_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include + + +class AliMUONPadHit : public TObject { +public: + + Int_t fHitNumber; // Hit number + Int_t fCathode; // Cathode number + Int_t fQ ; // Total charge + Int_t fPadX ; // Pad number along X + Int_t fPadY ; // Pad number along Y + Int_t fQpad ; // Charge per pad + Int_t fRSec ; // R -sector of pad + +public: + AliMUONPadHit() { + fHitNumber=fQ=fPadX=fPadY=fQpad=fRSec=0; +} + AliMUONPadHit(Int_t *clhits); + virtual ~AliMUONPadHit() {;} + + ClassDef(AliMUONPadHit,1) // MUON Pad Hit +}; +#endif diff --git a/MUON/AliMUONPoints.cxx b/MUON/AliMUONPoints.cxx new file mode 100644 index 00000000000..6bdc3c1ee78 --- /dev/null +++ b/MUON/AliMUONPoints.cxx @@ -0,0 +1,259 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ +/* +$Log$ +Revision 1.1.2.6 2000/06/09 21:57:40 morsch +Most coding rule violations corrected. + +Revision 1.1.2.5 2000/05/05 11:33:56 morsch +Log inside comments. + +Revision 1.1.2.4 2000/05/05 10:12:09 morsch +Log messages included +*/ + +/////////////////////////////////////////////////////////////////////////////// +// // +// This class contains the points for the ALICE event display // +// // +//Begin_Html +/* + +*/ +//End_Html +// // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "AliMUONPoints.h" +#include "AliMUONDisplay.h" +#include "AliRun.h" +#include "AliMUON.h" +#include "AliMUONChamber.h" +#include "AliMUONSegmentation.h" +#include "AliMUONResponse.h" +#include "AliMUONHit.h" +#include "AliMUONPadHit.h" +#include "AliMUONDigit.h" +#include "AliMUONRawCluster.h" + + +#include +#include +#include +#include +#include +#include +#include +#include + +const Int_t kMaxNipx=400, kMaxNipy=800; + +ClassImp(AliMUONPoints) + +//_____________________________________________________________________________ +AliMUONPoints::AliMUONPoints() +{ + // + // Default constructor + // + fHitIndex = 0; + fTrackIndex = 0; + fDigitIndex = 0; + fMarker[0] = fMarker[1] = fMarker[2]=0; + fMatrix = 0; +} + +//_____________________________________________________________________________ +AliMUONPoints::AliMUONPoints(Int_t npoints) + :AliPoints(npoints) +{ + // + // Standard constructor + // + fHitIndex = 0; + fTrackIndex = 0; + fDigitIndex = 0; + fMarker[0] = fMarker[1] = fMarker[2]=0; + fMatrix = 0; +} + +AliMUONPoints::AliMUONPoints(const AliMUONPoints& points) +{ +// Copy constructor +} + +//_____________________________________________________________________________ +AliMUONPoints::~AliMUONPoints() +{ + // + // Default destructor + // + fHitIndex = 0; + fTrackIndex = 0; + fDigitIndex = 0; + for (Int_t i=0;i<3;i++){ + if (fMarker[i]) delete fMarker[i]; + } + fMatrix = 0; +} + +//_____________________________________________________________________________ +void AliMUONPoints::DumpHit() +{ + // + // Dump hit corresponding to this point + // + AliMUONHit *hit = GetHit(); + if (hit) hit->Dump(); +} + +//_____________________________________________________________________________ +void AliMUONPoints::DumpDigit() +{ + // + // Dump digit corresponding to this point + // + AliMUONDigit *digit = GetDigit(); + if (digit) digit->Dump(); +} + +//_____________________________________________________________________________ +void AliMUONPoints::InspectHit() +{ + // + // Inspect hit corresponding to this point + // + + if (fHitIndex < 0 ) return; + TVirtualPad *padsav = gPad; + AliMUONHit *hit = GetHit(); + if (hit) hit->Inspect(); + TVirtualPad *padinspect = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject("inspect"); + padinspect->cd(); + Float_t xmin = gPad->GetX1(); + Float_t xmax = gPad->GetX2(); + Float_t ymin = gPad->GetY1(); + Float_t ymax = gPad->GetY2(); + Float_t dy = ymax-ymin; + + TPaveText *pad = new TPaveText(xmin, ymin+0.1*dy, xmax, ymin+0.15*dy); + pad->SetBit(kCanDelete); + pad->SetFillColor(42); + pad->Draw(); + char ptitle[100]; + sprintf(ptitle," %s , fTrack: %d fTrackIndex: %d ",GetName(),fIndex,fTrackIndex); + pad->AddText(ptitle); + padinspect->cd(); + padinspect->Update(); + if (padsav) padsav->cd(); + +} + +//_____________________________________________________________________________ +void AliMUONPoints::InspectDigit() +{ + // + // Inspect digit corresponding to this point + // + if (fDigitIndex < 0) return; + TVirtualPad *padsav = gPad; + AliMUONDigit *digit = GetDigit(); + if (digit) digit->Inspect(); + TVirtualPad *padinspect = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject("inspect"); + padinspect->cd(); + Float_t xmin = gPad->GetX1(); + Float_t xmax = gPad->GetX2(); + Float_t ymin = gPad->GetY1(); + Float_t ymax = gPad->GetY2(); + Float_t dy = ymax-ymin; + + TPaveText *pad = new TPaveText(xmin, ymin+0.1*dy, xmax, ymin+0.25*dy); + pad->SetBit(kCanDelete); + pad->SetFillColor(42); + pad->Draw(); + char ptitle[11][100]; + // sprintf(ptitle[11],"Tracks making this digit"); + // pad->AddText(ptitle[11]); + for (int i=0;i<10;i++) { + if (digit->fTracks[i] == 0) continue; + sprintf(ptitle[i],"fTrackIndex: %d Charge: %d",digit->fTracks[i],digit->fTcharges[i]); + pad->AddText(ptitle[i]); + } + padinspect->cd(); + padinspect->Update(); + if (padsav) padsav->cd(); + +} + +//_____________________________________________________________________________ +Int_t AliMUONPoints::GetTrackIndex() +{ + // + // Dump digit corresponding to this point + // + + this->Inspect(); + /* + if (fDigitIndex != 0) { + Int_t ncol=this->fMatrix->GetNcols(); + for (int i=0;ifMatrix))(0,i),(*(this->fMatrix))(1,i)); + } + } + */ + return fTrackIndex; +} + +//_____________________________________________________________________________ +AliMUONHit *AliMUONPoints::GetHit() const +{ + // + // Returns pointer to hit index in AliRun::fParticles + // + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + gAlice->TreeH()->GetEvent(fTrackIndex); + TClonesArray *muonHits = pMUON->Hits(); + Int_t nhits = muonHits->GetEntriesFast(); + if (fHitIndex < 0 || fHitIndex >= nhits) return 0; + return (AliMUONHit*)muonHits->UncheckedAt(fHitIndex); +} + +//_____________________________________________________________________________ +AliMUONDigit *AliMUONPoints::GetDigit() const +{ + // + // Returns pointer to digit index in AliRun::fParticles + // + + AliMUONDisplay *display=(AliMUONDisplay*)gAlice->Display(); + Int_t chamber=display->GetChamber(); + Int_t cathode=display->GetCathode(); + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + TClonesArray *muonDigits = pMUON->DigitsAddress(chamber-1); + Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); + gAlice->TreeD()->GetEvent(nent-2+cathode-1); + //gAlice->TreeD()->GetEvent(cathode); + Int_t ndigits = muonDigits->GetEntriesFast(); + if (fDigitIndex < 0 || fDigitIndex >= ndigits) return 0; + return (AliMUONDigit*)muonDigits->UncheckedAt(fDigitIndex); +} +//_____________________________________________________________________________ + +AliMUONPoints& AliMUONPoints::operator= (const AliMUONPoints& rhs) +{ + return *this; +} diff --git a/MUON/AliMUONpoints.h b/MUON/AliMUONPoints.h similarity index 67% rename from MUON/AliMUONpoints.h rename to MUON/AliMUONPoints.h index ce546c51c79..8f4ba8fb6c1 100644 --- a/MUON/AliMUONpoints.h +++ b/MUON/AliMUONPoints.h @@ -1,47 +1,52 @@ -#ifndef AliMUONpoints_H -#define AliMUONpoints_H +#ifndef ALIMUONPOINTS_H +#define ALIMUONPOINTS_H + /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ /* $Id$ */ -#include "TPolyMarker3D.h" -#include "TMarker3DBox.h" -#include "TMatrix.h" -#include "AliMUON.h" +class AliMUONDigit; +class AliMUONHit; + +class TMatrix; + +#include #include "AliPoints.h" -class AliMUONpoints : public AliPoints { -protected: - Int_t fHitIndex; // Link to hit number - Int_t fTrackIndex; // Link to track number - Int_t fDigitIndex; // Link to digit - TMarker3DBox *fMarker[3]; // pointer to associated 3D-marker - TMatrix *fMatrix; // test -public: - AliMUONpoints(); - AliMUONpoints(Int_t npoints); - virtual ~AliMUONpoints(); +class AliMUONPoints : public AliPoints { + public: + AliMUONPoints(); + AliMUONPoints(Int_t npoints); + AliMUONPoints(const AliMUONPoints& points); + virtual ~AliMUONPoints(); Int_t GetHitIndex() {return fHitIndex;} Int_t GetTrackIndex(); // *MENU* Int_t GetDigitIndex() {return fDigitIndex;} TMarker3DBox *GetMarker(Int_t i) {return fMarker[i];} - AliMUONhit *GetHit() const; - AliMUONdigit *GetDigit() const; + AliMUONHit *GetHit() const; + AliMUONDigit *GetDigit() const; virtual void InspectHit(); // *MENU* virtual void DumpHit(); // *MENU* virtual void InspectDigit(); // *MENU* virtual void DumpDigit(); // *MENU* - virtual void GetCenterOfGravity(); // *MENU* virtual void SetHitIndex(Int_t hitindex) {fHitIndex = hitindex;} virtual void SetTrackIndex(Int_t trackindex) {fTrackIndex = trackindex;} virtual void SetDigitIndex(Int_t digitindex) {fDigitIndex = digitindex;} virtual void Set3DMarker(Int_t i,TMarker3DBox *marker) {fMarker[i] = marker;} virtual void SetMatrix(TMatrix *matrix) {fMatrix = matrix;} - // virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py); + AliMUONPoints& operator = (const AliMUONPoints& rhs); - ClassDef(AliMUONpoints,1) //Class to draw detector clusters (is PolyMarker3D) +protected: + Int_t fHitIndex; // Link to hit number + Int_t fTrackIndex; // Link to track number + Int_t fDigitIndex; // Link to digit + TMarker3DBox *fMarker[3]; // pointer to associated 3D-marker + TMatrix *fMatrix; // test + + ClassDef(AliMUONPoints,1) //Class to draw detector clusters (is PolyMarker3D) }; #endif + diff --git a/MUON/AliMUONRawCluster.cxx b/MUON/AliMUONRawCluster.cxx new file mode 100644 index 00000000000..35a60df2f64 --- /dev/null +++ b/MUON/AliMUONRawCluster.cxx @@ -0,0 +1,164 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 22:04:50 morsch +Was before in DataStructures.cxx + +*/ + +#include "AliMUONRawCluster.h" +#include +#include + +ClassImp(AliMUONRawCluster); + + +AliMUONRawCluster::AliMUONRawCluster() { +// Constructor + fTracks[0]=fTracks[1]=fTracks[2]=-1; + for (int j=0;j<2;j++) { + fQ[j]=0; + fX[j]=0; + fY[j]=0; + fMultiplicity[j]=0; + fPeakSignal[j]=-1; + fChi2[j]=-1; + + for (int k=0;k<50;k++) { + fIndexMap[k][j]=-1; + fOffsetMap[k][j]=0; + fContMap[k][j]=0; + fPhysicsMap[k]=-1; + } + } + fNcluster[0]=fNcluster[1]=-1; +} + +Int_t AliMUONRawCluster::Compare(TObject *obj) +{ + /* + AliMUONRawCluster *raw=(AliMUONRawCluster *)obj; + Float_t r=GetRadius(); + Float_t ro=raw->GetRadius(); + if (r>ro) return 1; + else if (rfY[0]; + if (y>yo) return 1; + else if (y1) { + half=(high+low)/2; + if(y>coord[half]) low=half; + else high=half; + } + return low; +} + +void AliMUONRawCluster::SortMin(Int_t *idx,Float_t *xdarray,Float_t *xarray,Float_t *yarray,Float_t *qarray, Int_t ntr) +{ + // + // 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 +#include + +class AliMUONRawCluster : public TObject { +public: + + Int_t fTracks[3]; //labels of overlapped tracks + Int_t fQ[2] ; // Q of cluster (in ADC counts) + Float_t fX[2] ; // X of cluster + Float_t fY[2] ; // Y of cluster + Int_t fPeakSignal[2]; // Peak signal + Int_t fIndexMap[50][2]; // indeces of digits + Int_t fOffsetMap[50][2]; // Emmanuel special + Float_t fContMap[50][2]; // Contribution from digit + Int_t fPhysicsMap[50]; // Distinguish signal and background contr. + Int_t fMultiplicity[2]; // Cluster multiplicity + Int_t fNcluster[2]; // Number of clusters + Int_t fClusterType; // Cluster type + Float_t fChi2[2]; // Chi**2 of fit + + public: + AliMUONRawCluster(); + virtual ~AliMUONRawCluster() {} + Float_t GetRadius(Int_t i) {return TMath::Sqrt(fX[i]*fX[i]+fY[i]*fY[i]);} + Bool_t IsSortable() const {return kTRUE;} + Int_t Compare(TObject *obj); + Int_t PhysicsContribution(); + static Int_t BinarySearch(Float_t r, TArrayF ccord, Int_t from, Int_t upto); + static void SortMin(Int_t *idx,Float_t *xdarray, Float_t *xarray, + Float_t *yarray, Float_t *qarray,Int_t ntr); + ClassDef(AliMUONRawCluster,1) //Cluster object for set:MUON +}; +#endif + + + + + + diff --git a/MUON/AliMUONReconstHit.cxx b/MUON/AliMUONReconstHit.cxx new file mode 100644 index 00000000000..63d1a398550 --- /dev/null +++ b/MUON/AliMUONReconstHit.cxx @@ -0,0 +1,35 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log $ +*/ + +#include "AliMUONReconstHit.h" + +ClassImp(AliMUONReconstHit) +//___________________________________________ +//_____________________________________________________________________________ +AliMUONReconstHit::AliMUONReconstHit(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]; + } +} diff --git a/MUON/AliMUONReconstHit.h b/MUON/AliMUONReconstHit.h new file mode 100644 index 00000000000..ee2100119b6 --- /dev/null +++ b/MUON/AliMUONReconstHit.h @@ -0,0 +1,31 @@ +#ifndef ALIMUONRECONSTHIT_H +#define ALIMUONRECONSTHIT_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include + +class AliMUONReconstHit : 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: + AliMUONReconstHit() { + 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; + } + AliMUONReconstHit(Int_t *idx, Float_t *x, Float_t *y); + virtual ~AliMUONReconstHit() {} + ClassDef(AliMUONReconstHit,1) // Reconstructed Hit Object for set:MUON +}; +#endif diff --git a/MUON/AliMUONResponse.cxx b/MUON/AliMUONResponse.cxx new file mode 100644 index 00000000000..44911daf7eb --- /dev/null +++ b/MUON/AliMUONResponse.cxx @@ -0,0 +1,26 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 21:31:45 morsch +AliMUONResponse code from AliMUONSegRes.cxx + +*/ + +#include "AliMUONResponse.h" + +ClassImp(AliMUONResponse) + diff --git a/MUON/AliMUONResponse.h b/MUON/AliMUONResponse.h new file mode 100644 index 00000000000..0b5ad31a498 --- /dev/null +++ b/MUON/AliMUONResponse.h @@ -0,0 +1,66 @@ +#ifndef ALIMUONRESPONSE_H +#define ALIMUONRESPONSE_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include "TObject.h" + +class TF1; +class AliMUONChamber; +class AliMUONRecCluster; +class AliMUONSegmentation; + + +class AliMUONResponse : +public TObject { + public: + // + // Configuration methods + // + // Set number of sigmas over which cluster disintegration is performed + virtual void SetSigmaIntegration(Float_t p1) =0; + // Get number of sigmas over which cluster disintegration is performed + virtual Float_t SigmaIntegration() =0; + // Set single electron pulse height (ADCcounts/e) + virtual void SetChargeSlope(Float_t p1) =0; + // Get single electron pulse height (ADCcounts/e) + virtual Float_t ChargeSlope() =0; + // Set sigmas of the charge spread function + virtual void SetChargeSpread(Float_t p1, Float_t p2) =0; + // Get sigma_X of the charge spread function + virtual Float_t ChargeSpreadX() =0; + // Get sigma_Y of the charge spread function + virtual Float_t ChargeSpreadY() =0; + // Set maximum Adc-count value + virtual void SetMaxAdc(Int_t p1) =0; + // Set zero suppression threshold + virtual void SetZeroSuppression(Int_t val) =0; + // Get maximum Adc-count value + virtual Int_t MaxAdc() =0; + // Get maximum zero suppression threshold + virtual Int_t ZeroSuppression() =0; + // Set anode cathode Pitch + virtual void SetPitch(Float_t) =0; + // Get anode cathode Pitch + 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; + // Noise, zero-suppression, adc saturation + virtual Int_t DigitResponse(Int_t digit) =0; + // + ClassDef(AliMUONResponse,1) // Chamber response virtual base class +}; +#endif + + + + + + + diff --git a/MUON/AliMUONResponseTrigger.cxx b/MUON/AliMUONResponseTrigger.cxx new file mode 100644 index 00000000000..ff701acf117 --- /dev/null +++ b/MUON/AliMUONResponseTrigger.cxx @@ -0,0 +1,96 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 21:48:28 morsch +Code from AliMUONSegResTrigger.cxx + +*/ + +#include "AliMUONResponseTrigger.h" +#include "AliMUONSegmentation.h" +#include +#include +#include + + +ClassImp(AliMUONResponseTrigger) + +//------------------------------------------------------------------ +Float_t AliMUONResponseTrigger::IntXY(AliMUONSegmentation * segmentation){ +// Returns 1 or 0 if the current strip is fired or not according +// to the cluster size and the width of the main strip. +// For the time being the probability to fire a neighbour depends +// only on the width of the main strip and is limited to a maximum +// cluster-size of 2. +// The corresponding probabilities are given below (O.Roig PhD Thesis) +// This will be improved in the future by including a parametrization +// of the cluster size as a function of the position of the physical +// hit with respect to the center of the strip. +//------------------------------------------------------------------ +// clust. size = 1 2 3 4 5 >5 +// strip width = 1 | 54.7 | 44.5 | 0.7 | 0.06 | 0.04 | 0.0 | +// strip width = 2 | 89.0 | 10.7 | 0.2 | 0.1 | 0.0 | 0.0 | +// strip width = 4 | 99.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | +//------------------------------------------------------------------ + +// cout << "in AliMUONResponseTrigger::IntXY" << "\n"; + + // get the "parameters" needed to evaluate the strip response + // x1 : hit x(y) position + // x2 : x(y) coordinate of the main strip + // x3 : current strip real x(y) coordinate + // width : width of the main strip + Float_t x1,x2,x3,width; + segmentation->IntegrationLimits(x1,x2,x3,width); + // cout << " x or y main & current = " << x2 << " , " << x3 + // << " width main = " << width << "\n"; + + /* + if (TMath::Abs(x3-x1)Rndm()*100.; + if (iwidth==1) { + if (rand<44.5) { return 1.; } + else { return 0.; } + } else if (iwidth==2) { + if (rand<10.7) { return 1.; } + else { return 0.; } + } else if (iwidth==4) { + if (rand<1.) { return 1.; } + else { return 0.; } + } + } else { return 0.;} + return -1; + */ + return 0; +} + + +//------------------------------------------------------------------ +Int_t AliMUONResponseTrigger::DigitResponse(Int_t digit) +{ +// +// only digital (0/1) information available + if (digit) digit=1; + return digit; +} + + + + + + diff --git a/MUON/AliMUONResponseTrigger.h b/MUON/AliMUONResponseTrigger.h new file mode 100644 index 00000000000..2fc47409ef4 --- /dev/null +++ b/MUON/AliMUONResponseTrigger.h @@ -0,0 +1,34 @@ +#ifndef ALIMUONRESPONSETRIGGER_H +#define ALIMUONRESPONSETRIGGER_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include "AliMUONResponseV0.h" + +class AliMUONResponseTrigger : +public AliMUONResponseV0 { + public: + AliMUONResponseTrigger(){}; + virtual ~AliMUONResponseTrigger(){} + // Charge disintegration + virtual Float_t IntXY(AliMUONSegmentation * segmentation); + virtual Int_t DigitResponse(Int_t digit); + ClassDef(AliMUONResponseTrigger,1) // Implementation of RPC response + +}; +#endif + + + + + + + + + + + + + diff --git a/MUON/AliMUONResponseV0.cxx b/MUON/AliMUONResponseV0.cxx new file mode 100644 index 00000000000..4a7f347c404 --- /dev/null +++ b/MUON/AliMUONResponseV0.cxx @@ -0,0 +1,89 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 21:33:35 morsch +AliMUONResponse code from AliMUONSegResV0.cxx + +*/ + +#include "AliMUONResponseV0.h" +#include "AliMUONSegmentation.h" +#include +#include + + +ClassImp(AliMUONResponseV0) +Float_t AliMUONResponseV0::IntPH(Float_t eloss) +{ + // Calculate charge from given ionization energy loss + 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) +{ +// Calculate charge on current pad according to Mathieson distribution +// + const Float_t kInversePitch = 1/fPitch; +// +// Integration limits defined by segmentation model +// + Float_t xi1, xi2, yi1, yi2; + segmentation->IntegrationLimits(xi1,xi2,yi1,yi2); + xi1=xi1*kInversePitch; + xi2=xi2*kInversePitch; + yi1=yi1*kInversePitch; + yi2=yi2*kInversePitch; +// +// 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))); +} + +Int_t AliMUONResponseV0::DigitResponse(Int_t digit) +{ + // 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); + digit+=(Int_t)noise; + if ( digit <= ZeroSuppression()) digit = 0; + if ( digit > MaxAdc()) digit=MaxAdc(); + return digit; +} + + + + + + + + + diff --git a/MUON/AliMUONResponseV0.h b/MUON/AliMUONResponseV0.h new file mode 100644 index 00000000000..6ec01c0080f --- /dev/null +++ b/MUON/AliMUONResponseV0.h @@ -0,0 +1,94 @@ +#ifndef ALIMUONRESPONSEV0_H +#define ALIMUONRESPONSEV0_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include "AliMUONResponse.h" + +class AliMUONResponseV0 : +public AliMUONResponse { + public: + AliMUONResponseV0(){} + virtual ~AliMUONResponseV0(){} + // + // Configuration methods + // + // Set number of sigmas over which cluster didintegration is performed + virtual void SetSigmaIntegration(Float_t p1) {fSigmaIntegration=p1;} + // Get number of sigmas over which cluster didintegration is performed + virtual Float_t SigmaIntegration() {return fSigmaIntegration;} + // Set single electron pulse height (ADCcounts/e) + virtual void SetChargeSlope(Float_t p1) {fChargeSlope=p1;} + // Get Set single electron pulse height (ADCcounts/e) + virtual Float_t ChargeSlope() {return fChargeSlope;} + // Set sigmas of the charge spread function + virtual void SetChargeSpread(Float_t p1, Float_t p2) + {fChargeSpreadX=p1; fChargeSpreadY=p2;} + // Get sigma_X of the charge spread function + virtual Float_t ChargeSpreadX() {return fChargeSpreadX;} + // Get sigma_Y of the charge spread function + virtual Float_t ChargeSpreadY() {return fChargeSpreadY;} + // Set maximum Adc-count value + virtual void SetMaxAdc(Int_t p1) {fMaxAdc=p1;} + // Set zero suppression threshold + virtual void SetZeroSuppression(Int_t p1) {fZeroSuppression=p1;} + // Get maximum Adc-count value + virtual Int_t MaxAdc() {return fMaxAdc;} + // Get zero suppression threshold + virtual Int_t ZeroSuppression() {return fZeroSuppression;} + // Set anode cathode Pitch + virtual Float_t Pitch() {return fPitch;} + // Get anode cathode Pitch + virtual void SetPitch(Float_t p1) {fPitch=p1;}; + // Set Mathieson parameters + // Mathieson \sqrt{Kx3} + virtual void SetSqrtKx3(Float_t p1) {fSqrtKx3=p1;}; + // Mathieson Kx2 + virtual void SetKx2(Float_t p1) {fKx2=p1;}; + // Mathieson Kx4 + virtual void SetKx4(Float_t p1) {fKx4=p1;}; + // Mathieson \sqrt{Ky3} + virtual void SetSqrtKy3(Float_t p1) {fSqrtKy3=p1;}; + // Mathieson Ky2 + virtual void SetKy2(Float_t p1) {fKy2=p1;}; + // Mathieson Ky4 + 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); + // Noise, zero-suppression, adc saturation + virtual Int_t DigitResponse(Int_t digit); + + ClassDef(AliMUONResponseV0,1) // Implementation of Mathieson response + 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 + Int_t fMaxAdc; // Maximum ADC channel + Int_t fZeroSuppression; // Zero suppression threshold + Float_t fSqrtKx3; // Mathieson \Sqrt{Kx3) + Float_t fKx2; // Mathieson Kx2 + Float_t fKx4; // Mathieson Kx4 + Float_t fSqrtKy3; // Mathieson \Sqrt{Kx3) + Float_t fKy2; // Mathieson Ky2 + Float_t fKy4; // Mathieson Ky4 + Float_t fPitch; // anode-cathode pitch +}; +#endif + + + + + + + + + + + diff --git a/MUON/AliMUONSegResV01.cxx b/MUON/AliMUONSegResV01.cxx index e0ed519e640..ed2dca6fd7b 100644 --- a/MUON/AliMUONSegResV01.cxx +++ b/MUON/AliMUONSegResV01.cxx @@ -13,10 +13,6 @@ * provided "as is" without express or implied warranty. * **************************************************************************/ -/* -$Log$ -*/ - ///////////////////////////////////////////////////// // Segmentation and Response classes version 01 // ///////////////////////////////////////////////////// @@ -32,19 +28,10 @@ $Log$ #include "iostream.h" //___________________________________________ -ClassImp(AliMUONsegmentationV01) - -Float_t AliMUONsegmentationV01::Dpx(Int_t isec) -{ - return fDpxD[isec]; -} +ClassImp(AliMUONSegmentationV01) -Float_t AliMUONsegmentationV01::Dpy(Int_t ) -{ - return fDpy; -} -AliMUONsegmentationV01::AliMUONsegmentationV01() +AliMUONSegmentationV01::AliMUONSegmentationV01() { fNsec=4; fRSec.Set(fNsec); @@ -58,46 +45,65 @@ AliMUONsegmentationV01::AliMUONsegmentationV01() (*fCorr)[1]=0; (*fCorr)[2]=0; } + +Float_t AliMUONSegmentationV01::Dpx(Int_t isec) +{ +// +// Returns x-pad size for given sector isec + return fDpxD[isec]; +} + +Float_t AliMUONSegmentationV01::Dpy(Int_t isec) +{ +// +// Returns y-pad size for given sector isec + return fDpy; +} -void AliMUONsegmentationV01::SetSegRadii(Float_t r[4]) +void AliMUONSegmentationV01::SetSegRadii(Float_t r[4]) { +// +// Set the radii of the segmentation zones for (Int_t i=0; i<4; i++) { fRSec[i]=r[i]; - //printf("\n R %d %f \n",i,fRSec[i]); + printf("\n R %d %f \n",i,fRSec[i]); } } -void AliMUONsegmentationV01::SetPadDivision(Int_t ndiv[4]) +void AliMUONSegmentationV01::SetPadDivision(Int_t ndiv[4]) { // // Defines the pad size perp. to the anode wire (y) for different sectors. -// +// Pad sizes are defined as integral fractions ndiv of a basis pad size +// fDpx +// for (Int_t i=0; i<4; i++) { fNDiv[i]=ndiv[i]; - //printf("\n Ndiv %d %d \n",i,fNDiv[i]); + printf("\n Ndiv %d %d \n",i,fNDiv[i]); } ndiv[0]=ndiv[1]; } -void AliMUONsegmentationV01::Init(AliMUONchamber* ) +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 +// vice versa. +// This version approximates concentric segmentation zones // Int_t isec; - //printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n"); + 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]); + printf("\n test ---dx %d %f \n",i,fDpxD[i]); } } // @@ -115,7 +121,7 @@ void AliMUONsegmentationV01::Init(AliMUONchamber* ) Float_t x=iy*fDpy-fDpy/2; if (x > fRSec[isec]) { fNpxS[isec][iy]=0; - fCx[isec][iy]=0; + fCx[isec][iy]=0; } else { ry=TMath::Sqrt(fRSec[isec]*fRSec[isec]-x*x); if (isec > 1) { @@ -140,14 +146,12 @@ void AliMUONsegmentationV01::Init(AliMUONchamber* ) } } // 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 AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy) { +// Returns sector number for given pad position +// Int_t absix=TMath::Abs(ix); Int_t absiy=TMath::Abs(iy); Int_t isec=0; @@ -160,10 +164,10 @@ Int_t AliMUONsegmentationV01::Sector(Int_t ix, Int_t iy) return isec; } - void AliMUONsegmentationV01:: - GetPadIxy(Float_t x, Float_t y, Int_t &ix, Int_t &iy) +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) +// 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; @@ -187,20 +191,18 @@ Int_t AliMUONsegmentationV01::Sector(Int_t ix, Int_t iy) } else { ix=fNpxS[fNsec-1][absiy]+1; } -// printf("\n something %d %d \n",isec,absiy); - ix = (x>0) ? ix:-ix; } -void AliMUONsegmentationV01:: +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) +// 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 isec=AliMUONSegmentationV01::Sector(ix,iy); // Int_t absix=TMath::Abs(ix); Int_t absiy=TMath::Abs(iy); @@ -212,17 +214,22 @@ GetPadCxy(Int_t ix, Int_t iy, Float_t &x, Float_t &y) } } -void AliMUONsegmentationV01:: +void AliMUONSegmentationV01:: SetPad(Int_t ix, Int_t iy) { + // + // Sets virtual pad coordinates, needed for evaluating pad response + // outside the tracking program GetPadCxy(ix,iy,fx,fy); fSector=Sector(ix,iy); } -void AliMUONsegmentationV01:: +void AliMUONSegmentationV01:: FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) { +// Initialises iteration over pads for charge distribution algorithm +// // // Find the wire position (center of charge distribution) Float_t x0a=GetAnod(xhit); @@ -254,8 +261,11 @@ FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) } -void AliMUONsegmentationV01::NextPad() +void AliMUONSegmentationV01::NextPad() { +// Stepper for the iteration over pads +// +// Step to next pad in the integration region // // Step to next pad in integration region Float_t xc,yc; @@ -271,7 +281,7 @@ void AliMUONsegmentationV01::NextPad() 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) +// get x-pad coordiante for first pad in row (fix) GetPadIxy(fxmin,yc,fix,iyc); } else { printf("\n Error: Stepping outside integration region\n "); @@ -279,15 +289,12 @@ void AliMUONsegmentationV01::NextPad() 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)) + (fSector ==-1 || fSector==0)) NextPad(); - -// printf("\n this pad %f %f %d %d \n",fx,fy,fix,fiy); - } -Int_t AliMUONsegmentationV01::MorePads() +Int_t AliMUONSegmentationV01::MorePads() +// Stopping condition for the iterator over pads // // Are there more pads in the integration region { @@ -298,61 +305,67 @@ Int_t AliMUONsegmentationV01::MorePads() } } -void AliMUONsegmentationV01:: +void AliMUONSegmentationV01:: IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) { +// Returns integration limits for current pad +// x1=fxhit-fx-Dpx(fSector)/2.; x2=x1+Dpx(fSector); y1=fyhit-fy-Dpy(fSector)/2.; y2=y1+Dpy(fSector); } -void AliMUONsegmentationV01:: +void AliMUONSegmentationV01:: Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) { +// Returns list of next neighbours for given Pad (iX, iY) +// const Float_t epsilon=fDpy/1000; Float_t x,y; Int_t ixx, iyy, isec1; // - Int_t isec0=AliMUONsegmentationV01::Sector(iX,iY); + Int_t isec0=AliMUONSegmentationV01::Sector(iX,iY); Int_t i=0; // // step right Xlist[i]=iX+1; + if (Xlist[i]==0) Xlist[i]++; Ylist[i++]=iY; // // step left Xlist[i]=iX-1; + if (Xlist[i]==0) Xlist[i]--; Ylist[i++]=iY; // // step up - AliMUONsegmentationV01::GetPadCxy(iX,iY,x,y); - AliMUONsegmentationV01::GetPadIxy(x+epsilon,y+fDpy,ixx,iyy); + 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); + Ylist[i++]=iyy; + 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; - 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-1; - Ylist[i++]=iY+1; + Ylist[i++]=iyy; - Xlist[i]=ixx-2; - 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; @@ -360,35 +373,39 @@ Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) Xlist[i]=ixx+1; Ylist[i++]=iY+1; } +*/ } + // // step down - AliMUONsegmentationV01::GetPadCxy(iX,iY,x,y); - AliMUONsegmentationV01::GetPadIxy(x+epsilon,y-fDpy,ixx,iyy); + 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); + Ylist[i++]=iyy; + 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-1; - Ylist[i++]=iY-1; + Ylist[i++]=iyy; - Xlist[i]=ixx-2; - 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; @@ -396,13 +413,16 @@ Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) Xlist[i]=ixx+1; Ylist[i++]=iY-1; } - +*/ } *Nlist=i; } -void AliMUONsegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) +void AliMUONSegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) { +// Returns test point on the pad plane. +// Used during determination of the segmoid correction of the COG-method + n=3; x[0]=(fRSec[0]+fRSec[1])/2/TMath::Sqrt(2.); y[0]=x[0]; @@ -412,8 +432,10 @@ void AliMUONsegmentationV01::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) y[2]=x[2]; } -void AliMUONsegmentationV01::Draw(Option_t *) +void AliMUONSegmentationV01::Draw() { +// Draws the segmentation zones +// TBox *box; Float_t dx=0.95/fCx[3][1]/2; @@ -452,13 +474,12 @@ void AliMUONsegmentationV01::Draw(Option_t *) } } } -void AliMUONsegmentationV01::SetCorrFunc(Int_t isec, TF1* func) +void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func) { (*fCorr)[isec]=func; - } -TF1* AliMUONsegmentationV01::CorrFunc(Int_t isec) +TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) { return (TF1*) (*fCorr)[isec]; } diff --git a/MUON/AliMUONSegResV01.h b/MUON/AliMUONSegResV01.h index e2ae2ad001c..7f9b74c6ba5 100644 --- a/MUON/AliMUONSegResV01.h +++ b/MUON/AliMUONSegResV01.h @@ -3,8 +3,6 @@ /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ -/* $Id$ */ - ///////////////////////////////////////////////////// // Segmentation and Response classes version 01 // ///////////////////////////////////////////////////// @@ -15,11 +13,11 @@ #include "TArrayI.h" #include "TObjArray.h" -class AliMUONsegmentationV01 : -public AliMUONsegmentationV0 { +class AliMUONSegmentationV01 : +public AliMUONSegmentationV0 { public: - AliMUONsegmentationV01(); - virtual ~AliMUONsegmentationV01(){} + AliMUONSegmentationV01(); + virtual ~AliMUONSegmentationV01(){} // // Set Chamber Segmentation Parameters // @@ -35,14 +33,10 @@ public AliMUONsegmentationV0 { virtual void GetPadCxy(Int_t ix,Int_t iy,Float_t &x ,Float_t &y ); // // Initialisation - virtual void Init(AliMUONchamber*); + virtual void Init(AliMUONChamber*); // // Get member data // - // Pad size in x - virtual Float_t Dpx(){return AliMUONsegmentationV0::Dpx();} - // Pad size in y - virtual Float_t Dpy(){return AliMUONsegmentationV0::Dpy();} // Pad size in x by Sector virtual Float_t Dpx(Int_t isec); // Pad size in y by Sector @@ -62,6 +56,7 @@ public AliMUONsegmentationV0 { // Get next neighbours virtual void Neighbours (Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]); + // // Current Pad during Integration // current sector virtual Int_t ISector() {return fSector;} @@ -72,43 +67,40 @@ public AliMUONsegmentationV0 { // Current integration limits virtual void IntegrationLimits (Float_t& x1, Float_t& x2, Float_t& y1, Float_t& y2); - // Test points for auto calibration + // Test points for auto calibration void GiveTestPoints(Int_t &n, Float_t *x, Float_t *y); // - // Debugging utilities - virtual void Draw(Option_t *); + // Draw segmentation zones + virtual void Draw(); // Function for systematic corrections + // Set the correction function virtual void SetCorrFunc(Int_t dum, TF1* func); + // Get the correction function virtual TF1* CorrFunc(Int_t); - - - ClassDef(AliMUONsegmentationV01,1) + ClassDef(AliMUONSegmentationV01,1) // Segmentation approximating circular zones with different pad size protected: - // - // Implementation of the segmentation data - // Version 0 models rectangular pads with the same dimensions all - // over the cathode plane - // - // geometry + // Geometry // Int_t fNsec; // Number of sectors - TArrayF fRSec; // sector outer radia - TArrayI fNDiv; // pad size division + TArrayF fRSec; // Sector outer radia + TArrayI fNDiv; // Pad size division TArrayF fDpxD; // y pad width per sector + // Segmentation map 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; + Float_t fxmin; // lower left x + Float_t fxmax; // lower left y + Float_t fymin; // upper right x + Float_t fymax; // upper right y // // Current pad during integration (cursor for disintegration) - Int_t fSector; - TObjArray *fCorr; + Int_t fSector; // Current sector + // + TObjArray *fCorr; // Correction functions }; #endif diff --git a/MUON/AliMUONSegResV04.h b/MUON/AliMUONSegResV04.h deleted file mode 100644 index 5d8f4e4a650..00000000000 --- a/MUON/AliMUONSegResV04.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef MUONSegResV04_H -#define MUONSegResV04_H -/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * See cxx source for full Copyright notice */ - -/* $Id$ */ - -///////////////////////////////////////////////////// -// Segmentation and Response classes version 01 // -///////////////////////////////////////////////////// -#include "AliMUON.h" -#include "AliMUONSegResV01.h" -#include "TArrayF.h" -#include "TArrayI.h" -class AliMUONsegmentationV04 : -public AliMUONsegmentationV01 { - public: - AliMUONsegmentationV04(){} - virtual ~AliMUONsegmentationV04(){} - // Initialisation - virtual void Init(AliMUONchamber*); - // Test points for auto calibration - void GiveTestPoints(Int_t &n, Float_t *x, Float_t *y); - ClassDef(AliMUONsegmentationV04,1) -}; - - -#endif - - - - - - diff --git a/MUON/AliMUONSegResV05.h b/MUON/AliMUONSegResV05.h deleted file mode 100644 index 3b17c497913..00000000000 --- a/MUON/AliMUONSegResV05.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef MUONSegResV05_H -#define MUONSegResV05_H -/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * See cxx source for full Copyright notice */ - -/* $Id$ */ - -///////////////////////////////////////////////////// -// Segmentation and Response classes version 01 // -///////////////////////////////////////////////////// - -#include "AliMUON.h" -#include "AliMUONSegResV02.h" -#include "TArrayF.h" -#include "TArrayI.h" -class AliMUONsegmentationV05 : -public AliMUONsegmentationV02 { - public: - AliMUONsegmentationV05(){} - virtual ~AliMUONsegmentationV05(){} - // Initialisation - virtual void Init(AliMUONchamber*); - // Test points for auto calibration - void GiveTestPoints(Int_t &n, Float_t *x, Float_t *y); - ClassDef(AliMUONsegmentationV05,1) -}; -#endif - - - - - - diff --git a/MUON/AliMUONSegResV1.cxx b/MUON/AliMUONSegResV1.cxx deleted file mode 100644 index b85e4cdc849..00000000000 --- a/MUON/AliMUONSegResV1.cxx +++ /dev/null @@ -1,509 +0,0 @@ -/************************************************************************** - * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * * - * Author: The ALICE Off-line Project. * - * Contributors are mentioned in the code where appropriate. * - * * - * Permission to use, copy, modify and distribute this software and its * - * documentation strictly for non-commercial purposes is hereby granted * - * without fee, provided that the above copyright notice appears in all * - * copies and that both the copyright notice and this permission notice * - * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * - * provided "as is" without express or implied warranty. * - **************************************************************************/ - -/* -$Log$ -*/ - -///////////////////////////////////////////////////////// -// Manager and hits classes for set:MUON version LYON // -///////////////////////////////////////////////////////// - -#include -#include -#include - -//#include "AliMUONv0.h" -#include "AliMUONchamber.h" -#include "AliMUONSegResV1.h" -#include "AliRun.h" -#include "AliMC.h" -#include "iostream.h" - -//___________________________________________ -ClassImp(AliMUONsegmentationV1) - -AliMUONsegmentationV1::AliMUONsegmentationV1() - // initizalize the class with default settings -{ -fNzone=1; -fDAnod=0.0; -fDpx=0.0; -fDpx=0.0; // forces crash if not initialized by user -fNZoneCut[0]=0; -fSensOffset=0; -} - - -void AliMUONsegmentationV1::Init(AliMUONchamber* Chamber) -{ - // valid only for T5/6 - // beware : frMin is SENSITIVE radius by definition. - frSensMin2 = (Chamber->RInner())*(Chamber->RInner()); - frSensMax2 = (Chamber->ROuter())*(Chamber->ROuter()); - fNpx=(Int_t) (Chamber->ROuter()/fDpx) + 1; - fNpy=(Int_t) (Chamber->ROuter()/fDpy) + 1; - // fNwire=3; - DefaultCut(); - fCorr=0; -} - -void AliMUONsegmentationV1::DefaultCut(void) -{ -SetNzone(3); -AddCut(0,5*6,18*8); -AddCut(0,9*6,15*8); -AddCut(0,11*6,12*8); -AddCut(0,12*6,9*8); -AddCut(0,13*6,6*8); -AddCut(1,6*6,20*12); -AddCut(1,12*6,18*12); -AddCut(1,15*6,15*12); -AddCut(1,18*6,12*12); -AddCut(1,21*6,9*12); -SetSensOffset(3.0); -SetDAnod(0.325); -} - -Int_t AliMUONsegmentationV1::GetiAnod(Float_t xhit) -{ -Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1; -return (xhit>0) ? kwire : -kwire ; -} - -Float_t AliMUONsegmentationV1::GetAnod(Float_t xhit) -{ - Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1; // to be compatible ... - return (xhit>0) ? fDAnod*(kwire-0.5)+fSensOffset : -fDAnod*(kwire-0.5)-fSensOffset ; -} - -// For chamber T5/6 p1 and p2 should be same for each zone -void AliMUONsegmentationV1::SetPADSIZ(Float_t p1, Float_t p2) -{ - fDpx=p1; - fDpy=p2; -} - -void AliMUONsegmentationV1:: - GetPadIxy(Float_t x, Float_t y, Int_t &ix, Int_t &iy) -{ -// returns pad coordinates (ix,iy) for given real coordinates (x,y) -// - ix = (x>0)? Int_t((x-fSensOffset)/fDpx)+1 : Int_t((x+fSensOffset)/fDpx)-1; - iy = (y>0)? Int_t((y-fSensOffset)/fDpy)+1 : Int_t((y+fSensOffset)/fDpy)-1; -} - -void AliMUONsegmentationV1:: -GetPadCxy(Int_t ix, Int_t iy, Float_t &x, Float_t &y) -{ -// returns real coordinates (x,y) for given pad coordinates (ix,iy) -// - x = (ix>0) ? (Float_t(ix)-0.5)*fDpx+fSensOffset : (Float_t(ix)+0.5)*fDpx-fSensOffset; - y = (iy>0) ? (Float_t(iy)-0.5)*fDpy+fSensOffset : (Float_t(iy)+0.5)*fDpy-fSensOffset; -} - -void AliMUONsegmentationV1::AddCut(Int_t Zone, Int_t nX, Int_t nY) -{// the pad nX,nY is last INSIDE zone Zone. First pad is labelled 1 and not 0 -if (Zone+1>=fNzone) // no cut for last Zone : it is the natural boundary of the chamber - printf("AliMUONsegmentationV1::AddCut ==> Zone %d not allowed !\n",Zone); -fZoneX[Zone][fNZoneCut[Zone]] = nX; -fZoneY[Zone][fNZoneCut[Zone]] = nY; -fNZoneCut[Zone]++; -} - -Int_t AliMUONsegmentationV1::GetZone(Float_t X, Float_t Y) -{ -Int_t iX, iY; -GetPadIxy(X,Y,iX,iY); -return GetZone( iX , iY ); -} - -Int_t AliMUONsegmentationV1::GetZone(Int_t nX, Int_t nY) -{// Beware : first pad begins at 1 !! -Int_t aX = TMath::Abs(nX); -Int_t aY = TMath::Abs(nY); -Int_t zone=fNzone-1; -for (Int_t iZone=fNzone-2;iZone>=0;iZone--) - { - for (Int_t iCut=0;iCut frSensMax2 || radius2 < frSensMin2 ) - && MorePads() ) - NextPad(); -} - -void AliMUONsegmentationV1::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) -{ - // - // Find the wire position (center of charge distribution) - Float_t x0a=GetAnod(xhit); - fxhit=x0a; - fyhit=yhit; - - // - // and take fNsigma*sigma around this center - Float_t x01=x0a - dx; - Float_t x02=x0a + dx; - Float_t y01=yhit - dy; - Float_t y02=yhit + dy; - - // Do not cross over frames... - if (x01 * x0a < 0) - x01 = TMath::Sign(fSensOffset, x0a); - if (x02 * x0a < 0) - x02 = TMath::Sign(fSensOffset, x0a); - if (y01 * yhit < 0) - y01 = TMath::Sign(fSensOffset, yhit); - if (y02 * yhit < 0) - y02 = TMath::Sign(fSensOffset, yhit); - // - // find the pads over which the charge distributes - GetPadIxy(x01,y01,fixmin,fiymin); - GetPadIxy(x02,y02,fixmax,fiymax); - // - // Set current pad to lower left corner - fix=fixmin; - fiy=fiymin; - SetPadCoord(fix,fiy); -} - -void AliMUONsegmentationV1::NextPad() -{ - // - // Step to next pad in integration region - if (fix != fixmax) { - fix++; - } else if (fiy != fiymax) { - fix=fixmin; - fiy++; - } else - printf("\n Error: Stepping outside integration region\n "); - SetPadCoord(fix,fiy); -} - -Int_t AliMUONsegmentationV1::MorePads() -// -// Are there more pads in the integration region -{ - if (fix == fixmax && fiy == fiymax) { - return 0; - } else { - return 1; - } -} - -Int_t AliMUONsegmentationV1::IsParallel2(Int_t iX, Int_t iY) -// test if the pad is read in parallel for zone 2 -// iX and iY are assumed to be positive and starting at 0 numbering (cF. iX) -// returns 1 or 2 if read in parallel, -// according to the actual number in the chain, 0 else -// -// chainage is result is -// 1 2 3 1 2 3 1 1 1 2 2 2 y -// 7 8 9 10 11 12 0 0 0 0 0 0 ^ -// 4 5 6 4 5 6 1 1 1 2 2 2 +->x -// -{ -if (iY%3==1) return 0; -return (iX%6)/3+1; -} - -Int_t AliMUONsegmentationV1::IsParallel3(Int_t iX, Int_t iY) -// test if the pad is read in parallel for zone 3 -// iX and iY are assumed to be positive and starting at 0 numbering (cF. iX) -// returns 1,2 or 3 if read in parallel, -// according to the actual number in the chain, 0 else -// -// chainage is result is -//16 2 3 1 2 3 1 2 3 0 1 1 1 2 2 2 3 3 -// 7 8 9 10 11 12 13 14 15 0 0 0 0 0 0 0 0 0 -// 4 5 6 4 5 6 4 5 6 1 1 1 2 2 2 3 3 3 -// -{ -if (iY%3==1) return 0; -return (iX%9)/3+1 - (iY%3==2 && iX%3==0); -} - -Int_t AliMUONsegmentationV1::NParallel2(Int_t , 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 ) -{ -// -// 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 ) -{ -// -// Signal will be generated if particle crosses pad boundary or -// boundary between two wires. - Int_t ixt; - Int_t iyt; - GetPadIxy(x,y,ixt,iyt); - Int_t iwt= GetiAnod(x); - - if ((ixt != fixt) || (iyt !=fiyt) || (iwt != fiwt)) { - return 1; - } else { - return 0; - } -} - -void AliMUONsegmentationV1:: -IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) -{ - x1=fxhit-fx-fDpx/2.; - x2=x1+fDpx; - y1=fyhit-fy-fDpy/2.; - y2=y1+fDpy; -} - -void AliMUONsegmentationV1::GetNParallelAndOffset(Int_t iX, Int_t iY,Int_t -*Nparallel, Int_t* Offset) -{ -Int_t wix = TMath::Abs(iX)-1; -Int_t wiy = TMath::Abs(iY)-1; -Int_t zone = GetZone(iX,iY); -switch (zone) { - case 0: - *Nparallel=1; - *Offset=0; - break; - case 1: - *Nparallel = NParallel2(wix,wiy); - (iX>0) ? *Offset =3 : *Offset = -3; - if (IsParallel2(wix,wiy)>1) - printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n"); - break; - case 2: - *Nparallel = NParallel3(wix,wiy); - (iX>0) ? *Offset =3 : *Offset = -3; - if (IsParallel3(wix,wiy)>1) - printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n"); - break; - } -} - - -Float_t AliMUONsegmentationV1::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t *Offset) -// -// Computes the offset for which the physical pad has the minimum distance squared -// (returned value) to the given coordinates -{ -Int_t nPara,offset; -GetNParallelAndOffset(iX,iY,&nPara,&offset); -Float_t d2min=1E10; -for (Int_t i=0;i d2) - { - d2min = d2; - *Offset = i*offset; - } - } -return d2min; -} - -void AliMUONsegmentationV1::CleanNeighbours(Int_t* Nlist, Int_t *Xlist, - Int_t *Ylist) -// In the raw neighbours list, some pads do not exist -// and some others are read in parallel ... -// So we prune non-existing neighbours from the list (event if this should be -// at last not be a problem due to the clustering algorithm...) -{ -Int_t nTot=0; -for (Int_t nList=0;nList<*Nlist;nList++) - { - // prune if it does not exist - if ( Xlist[nList]==0 || Ylist[nList]==0 ) - continue; - // compute true position - Xlist[nTot] = Ix(Xlist[nList],Ylist[nList]) ; - Ylist[nTot] = Ylist[nList] ; - // and prune if it does already exist - Int_t nTest; - for (nTest=0;nTest1) { - Xlist[4]=Xlist[5]=iX+offset;Xlist[6]=iX+offset-1;Xlist[7]=iX+offset+1; - Ylist[4]=iY-1;Ylist[5]=iY+1;Ylist[6]=Ylist[7]=iY; - if (nParallel>2) { - Xlist[8]=Xlist[9]=iX+2*offset;Xlist[10]=iX+2*offset-1;Xlist[11]=iX+2*offset+1; - Ylist[8]=iY-1;Ylist[9]=iY+1;Ylist[10]=Ylist[11]=iY; - } - } -CleanNeighbours(Nlist,Xlist,Ylist); -} - -void AliMUONsegmentationV1:: -NeighboursDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[24], Int_t Ylist[24]) -// returns the X number of pad which has to increment charge -// due to parallel read-out -{ -Int_t nParallel, offset; -GetNParallelAndOffset(iX,iY,&nParallel,&offset); -// -// now fill raw list of neighbours -*Nlist=0; -for (Int_t i=0;iGetZ() - Hit2->GetZ(); + // bending plane + fBendingCoor = Hit1->GetBendingCoor(); + fBendingSlope = (fBendingCoor - Hit2->GetBendingCoor()) / dz; + fBendingImpact = fBendingCoor - Hit1->GetZ() * fBendingSlope; + fBendingCoorReso2 = Hit1->GetBendingReso2(); + fBendingSlopeReso2 = ( Hit1->GetBendingReso2() + + Hit2->GetBendingReso2() ) / dz / dz; + fBendingCoorSlopeReso2 = Hit1->GetBendingReso2() / dz; + // non bending plane + fNonBendingCoor = Hit1->GetNonBendingCoor(); + fNonBendingSlope = (fNonBendingCoor - Hit2->GetNonBendingCoor()) / dz; + fNonBendingImpact = fNonBendingCoor - Hit1->GetZ() * fNonBendingSlope; + fNonBendingCoorReso2 = Hit1->GetNonBendingReso2(); + fNonBendingSlopeReso2 = ( Hit1->GetNonBendingReso2() + + Hit2->GetNonBendingReso2() ) / dz / dz; + fNonBendingCoorSlopeReso2 = Hit1->GetNonBendingReso2() / dz; + // "fInTrack" flag to "kFALSE" + fInTrack = kFALSE; + return; +} + +AliMUONSegment::AliMUONSegment (const AliMUONSegment& MUONSegment) +{ +// Dummy copy constructor +} + +AliMUONSegment & AliMUONSegment::operator=(const AliMUONSegment& MUONSegment) +{ +// Dummy assignment operator + return *this; +} + +// Inline functions for Get and Set +inline AliMUONHitForRec* AliMUONSegment::GetHitForRec1(void) { + // Get fHitForRecPtr1 + return fHitForRecPtr1;} +inline AliMUONHitForRec* AliMUONSegment::GetHitForRec2(void) { + // Get fHitForRecPtr2 + return fHitForRecPtr2;} +inline Double_t AliMUONSegment::GetBendingCoorReso2(void) { + // Get fBendingCoorReso2 + return fBendingCoorReso2;} +inline void AliMUONSegment::SetBendingCoorReso2(Double_t BendingCoorReso2) { + // Set fBendingCoorReso2 + fBendingCoorReso2 = BendingCoorReso2;} +inline Double_t AliMUONSegment::GetNonBendingCoorReso2(void) { + // Get fNonBendingCoorReso2 + return fNonBendingCoorReso2;} +inline void AliMUONSegment::SetNonBendingCoorReso2(Double_t NonBendingCoorReso2) { + // Set fNonBendingCoorReso2 + fNonBendingCoorReso2 = NonBendingCoorReso2;} +inline Double_t AliMUONSegment::GetBendingImpact(void) { + // Get fBendingImpact + return fBendingImpact;} +inline Bool_t AliMUONSegment::GetInTrack(void) { + // Get fInTrack + return fInTrack;} +inline void AliMUONSegment::SetInTrack(Bool_t InTrack) { + // Set fInTrack + fInTrack = InTrack;} + + //__________________________________________________________________________ +Int_t AliMUONSegment::Compare(TObject* Segment) +{ + // "Compare" function to sort with increasing absolute value + // of the "impact parameter" in bending plane. + // Returns -1 (0, +1) if |impact parameter| of current Segment + // is smaller than (equal to, larger than) |impact parameter| of Segment + if (TMath::Abs(((AliMUONSegment*)this)->fBendingSlope) + < TMath::Abs(((AliMUONSegment*)Segment)->fBendingSlope)) + return(-1); + // continuous parameter, hence no need for testing equal case + else return(+1); +} + + //__________________________________________________________________________ +Double_t AliMUONSegment::NormalizedChi2WithSegment(AliMUONSegment* Segment, Double_t Sigma2Cut) +{ + // Calculate the normalized Chi2 between the current Segment (this) + // and the Segment pointed to by "Segment", + // i.e. the square deviations between the coordinates and the slopes, + // in both the bending and the non bending plane, + // divided by the variance of the same quantities and by "Sigma2Cut". + // Returns 5 if none of the 4 quantities is OK, + // something smaller than or equal to 4 otherwise. + // Would it be more correct to use a real chi square + // including the non diagonal term ???? + Double_t chi2, chi2Max, diff, normDiff; + chi2 = 0.0; + chi2Max = 5.0; + // coordinate in bending plane + diff = this->fBendingCoor - Segment->fBendingCoor; + normDiff = diff * diff / + (this->fBendingCoorReso2 + Segment->fBendingCoorReso2) / Sigma2Cut; + if (normDiff > 1.0) return chi2Max; + chi2 = chi2 + normDiff; + // slope in bending plane + diff = this->fBendingSlope - Segment->fBendingSlope; + normDiff = diff * diff / + (this->fBendingSlopeReso2 + Segment->fBendingSlopeReso2) / Sigma2Cut; + if (normDiff > 1.0) return chi2Max; + chi2 = chi2 + normDiff; + // coordinate in non bending plane + diff = this->fNonBendingCoor - Segment->fNonBendingCoor; + normDiff = diff * diff / + (this->fNonBendingCoorReso2 + Segment->fNonBendingCoorReso2) / Sigma2Cut; + if (normDiff > 1.0) return chi2Max; + chi2 = chi2 + normDiff; + // slope in non bending plane + diff = this->fNonBendingSlope - Segment->fNonBendingSlope; + normDiff = diff * diff / + (this->fNonBendingSlopeReso2 + Segment->fNonBendingSlopeReso2) / Sigma2Cut; + if (normDiff > 1.0) return chi2Max; + chi2 = chi2 + normDiff; + return chi2; +} + + //__________________________________________________________________________ +AliMUONSegment* AliMUONSegment::CreateSegmentFromLinearExtrapToStation (Int_t Station, Double_t MCSfactor) +{ + // Extrapolates linearly the current Segment (this) to station (0..) "Station". + // Multiple Coulomb scattering calculated from "MCSfactor" + // corresponding to one chamber, + // with one chamber for the coordinate, two chambers for the angle, + // due to the arrangement in stations. + // Valid from station(1..) 4 to 5 or vice versa. + // Returns the pointer to the created AliMUONSegment object + // corresponding to this extrapolation. + // The caller has the responsibility to delete this object. + AliMUONSegment* extrapSegment = new AliMUONSegment(); // creates empty new segment + // dZ from first hit of current Segment to first chamber of station "Station" + AliMUON *pMUON = (AliMUON*) gAlice->GetModule("MUON"); // necessary ???? + Double_t dZ = + (&(pMUON->Chamber(2 * Station)))->Z() - (this->fHitForRecPtr1)->GetZ(); + // Data in bending plane + // coordinate + extrapSegment->fBendingCoor = this->fBendingCoor + this->fBendingSlope * dZ; + // slope + extrapSegment->fBendingSlope = this->fBendingSlope; + // covariance, including multiple Coulomb scattering over dZ due to one chamber + extrapSegment->fBendingCoorReso2 = this->fBendingCoorReso2 + + (this->fBendingSlopeReso2 + MCSfactor) * dZ * dZ; // missing non diagonal term: "2.0 * this->fBendingCoorSlopeReso2 * dZ" !!!! + extrapSegment->fBendingSlopeReso2 = this->fBendingSlopeReso2 + 2.0 * MCSfactor; + extrapSegment->fBendingCoorSlopeReso2 = + this->fBendingCoorSlopeReso2 + this->fBendingSlopeReso2 * dZ; // missing: contribution from multiple Coulomb scattering !!!! + // Data in non bending plane + // coordinate + extrapSegment->fNonBendingCoor = + this->fNonBendingCoor + this->fNonBendingSlope * dZ; + // slope + extrapSegment->fNonBendingSlope = this->fNonBendingSlope; + // covariance, including multiple Coulomb scattering over dZ due to one chamber + extrapSegment->fNonBendingCoorReso2 = this->fNonBendingCoorReso2 + + (this->fNonBendingSlopeReso2 + MCSfactor) *dZ * dZ; // missing non diagonal term: "2.0 * this->fNonBendingCoorSlopeReso2 * dZ" !!!! + extrapSegment->fNonBendingSlopeReso2 = + this->fNonBendingSlopeReso2 + 2.0 * MCSfactor; + extrapSegment->fNonBendingCoorSlopeReso2 = + this->fNonBendingCoorSlopeReso2 + this->fNonBendingSlopeReso2 * dZ; // missing: contribution from multiple Coulomb scattering !!!! + return extrapSegment; +} + + //__________________________________________________________________________ +AliMUONHitForRec* AliMUONSegment::CreateHitForRecFromLinearExtrapToChamber (Int_t Chamber, Double_t MCSfactor) +{ + // Extrapolates linearly the current Segment (this) to chamber(0..) "Chamber". + // Multiple Coulomb scattering calculated from "MCSfactor" + // corresponding to one chamber. + // Valid from station(1..) 4 to 5 or vice versa. + // Returns the pointer to the created AliMUONHitForRec object + // corresponding to this extrapolation. + // The caller has the responsibility to delete this object. + AliMUONHitForRec* extrapHitForRec = new AliMUONHitForRec(); // creates empty new HitForRec + // dZ from first hit of current Segment to chamber + AliMUON *pMUON = (AliMUON*) gAlice->GetModule("MUON"); // necessary ???? + Double_t dZ = + (&(pMUON->Chamber(Chamber)))->Z() - (this->fHitForRecPtr1)->GetZ(); + // Data in bending plane + // coordinate + extrapHitForRec->SetBendingCoor(this->fBendingCoor + this->fBendingSlope * dZ); + // covariance, including multiple Coulomb scattering over dZ due to one chamber + extrapHitForRec->SetBendingReso2(this->fBendingCoorReso2 + + (this->fBendingSlopeReso2 + MCSfactor) * dZ * dZ); // missing non diagonal term: "2.0 * this->fBendingCoorSlopeReso2 * dZ" !!!! + // Data in non bending plane + // coordinate + extrapHitForRec ->SetNonBendingCoor(this->fNonBendingCoor + + this->fNonBendingSlope * dZ); + // covariance, including multiple Coulomb scattering over dZ due to one chamber + extrapHitForRec-> + SetNonBendingReso2(this->fNonBendingCoorReso2 + + (this->fNonBendingSlopeReso2 + MCSfactor) * dZ * dZ); // missing non diagonal term: "2.0 * this->fNonBendingCoorSlopeReso2 * dZ" !!!! + return extrapHitForRec; +} + + //__________________________________________________________________________ +void AliMUONSegment::UpdateFromStationTrackParam(AliMUONTrackParam *TrackParam, Double_t MCSfactor, Double_t Dz1, Double_t Dz2) +{ + // Fill data members with values calculated from the array of track parameters + // pointed to by "TrackParam" (index = 0 and 1 for first and second chambers + // of the station, respectively). + // Multiple Coulomb scattering is taking into account with "MCSfactor" + // corresponding to one chamber, + // with one chamber for the coordinate, two chambers for the angle, + // due to the arrangement in stations. + // Resolution coming from: + // coordinate in closest station at "Dz1", + // slope between closest stations, with "Dz2" interval between them, + // extrapolation over "Dz" from closest station. + // When called, "fBendingCoorReso2" and "fNonBendingCoorReso2" + // are assumed to be filled + // with the variance on bending and non bending coordinates. + AliMUONTrackParam *param0; + Double_t cReso2, sReso2; + param0 = &(TrackParam[0]); + // Bending plane + fBendingCoor = param0->GetBendingCoor(); // coordinate + fBendingSlope = param0->GetBendingSlope(); // slope + cReso2 = fBendingCoorReso2; + sReso2 = 2.0 * cReso2 / Dz2 / Dz2; + fBendingCoorReso2 = cReso2 + (sReso2 + MCSfactor) * Dz1 * Dz1; + fBendingSlopeReso2 = sReso2 + 2.0 * MCSfactor; + // Non bending plane + fNonBendingCoor = param0->GetNonBendingCoor(); // coordinate + fNonBendingSlope = param0->GetNonBendingSlope(); // slope + cReso2 = fNonBendingCoorReso2; + sReso2 = 2.0 * cReso2 / Dz2 / Dz2; + fNonBendingCoorReso2 = cReso2 + (sReso2 + MCSfactor) * Dz1 * Dz1; + fNonBendingSlopeReso2 = sReso2 + 2.0 * MCSfactor; + return; +} diff --git a/MUON/AliMUONSegment.h b/MUON/AliMUONSegment.h new file mode 100644 index 00000000000..7d971d18396 --- /dev/null +++ b/MUON/AliMUONSegment.h @@ -0,0 +1,68 @@ +#ifndef ALIMUONSEGMENT_H +#define ALIMUONSEGMENT_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/*$Id$*/ + +#include + +class AliMUONHitForRec; +class AliMUONTrackParam; + +class AliMUONSegment : public TObject { + public: + AliMUONSegment(){ + // Constructor + ;} // Constructor + virtual ~AliMUONSegment(){ + // Destructor + ;} // Destructor + AliMUONSegment (const AliMUONSegment& AliMUONSegment); // copy constructor + AliMUONSegment& operator=(const AliMUONSegment& AliMUONSegment); // assignment operator + AliMUONSegment(AliMUONHitForRec* Hit1, AliMUONHitForRec* Hit2); // Constructor from two HitForRec's + + AliMUONHitForRec* GetHitForRec1(void); + AliMUONHitForRec* GetHitForRec2(void); + Double_t GetBendingCoorReso2(void); + void SetBendingCoorReso2(Double_t BendingCoorReso2); + Double_t GetNonBendingCoorReso2(void); + void SetNonBendingCoorReso2(Double_t NonBendingCoorReso2); + Double_t GetBendingImpact(void); + Bool_t GetInTrack(void); + void SetInTrack(Bool_t InTrack); + + AliMUONSegment* CreateSegmentFromLinearExtrapToStation (Int_t Station, Double_t MCSfactor); + Double_t NormalizedChi2WithSegment(AliMUONSegment* Segment, Double_t Sigma2Cut); + AliMUONHitForRec* CreateHitForRecFromLinearExtrapToChamber (Int_t Chamber, Double_t MCSfactor); + void UpdateFromStationTrackParam(AliMUONTrackParam *TrackParam, Double_t MCSfactor, Double_t Dz1, Double_t Dz2); + + // What is necessary for sorting TClonesArray's; sufficient too ???? + Bool_t IsSortable() const { return kTRUE; } + Int_t Compare(TObject* Segment); // "Compare" function for sorting + protected: + private: + AliMUONHitForRec* fHitForRecPtr1; // pointer to HitForRec in first chamber + AliMUONHitForRec* fHitForRecPtr2; // pointer to HitForRec in second chamber + // Bending plane: + Double_t fBendingCoor; // Coordinate in bending plane + Double_t fBendingSlope; // Slope in bending plane + // Covariance in bending plane: + Double_t fBendingCoorReso2; // Covariance(coordinate C1 in first chamber) + Double_t fBendingSlopeReso2; // Covariance(slope) + Double_t fBendingCoorSlopeReso2; // Covariance(C1,slope) + Double_t fBendingImpact; // Impact parameter in bending plane + // Non Bending plane: + Double_t fNonBendingCoor; // Coordinate in non bending plane + Double_t fNonBendingSlope; // Slope in non bending plane + // Covariance in non bending plane: + Double_t fNonBendingCoorReso2; // Covariance(coordinate C1 in first chamber) + Double_t fNonBendingSlopeReso2; // Covariance(slope) + Double_t fNonBendingCoorSlopeReso2; // Covariance(C1,slope) + Double_t fNonBendingImpact; // Impact parameter in non bending plane + Bool_t fInTrack; // TRUE if segment belongs to one track + + ClassDef(AliMUONSegment, 1) // Class definition in ROOT context + }; + +#endif diff --git a/MUON/AliMUONSegmentation.cxx b/MUON/AliMUONSegmentation.cxx new file mode 100644 index 00000000000..6ede1cfea37 --- /dev/null +++ b/MUON/AliMUONSegmentation.cxx @@ -0,0 +1,26 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 21:28:47 morsch +AliMUONSegmentation code from AliMUONSegRes.cxx + +*/ + +#include "AliMUONSegmentation.h" + +ClassImp(AliMUONSegmentation) + diff --git a/MUON/AliMUONSegRes.h b/MUON/AliMUONSegmentation.h similarity index 62% rename from MUON/AliMUONSegRes.h rename to MUON/AliMUONSegmentation.h index 10a0eb08557..8f7bb53cb02 100644 --- a/MUON/AliMUONSegRes.h +++ b/MUON/AliMUONSegmentation.h @@ -1,26 +1,27 @@ -#ifndef MUONSegRes_H -#define MUONSegRes_H +#ifndef ALIMUONSEGMENTATION_H +#define ALIMUONSEGMENTATION_H /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ /* $Id$ */ #include "TObject.h" -#include "TClonesArray.h" -#include "TF1.h" -class AliMUONchamber; + +class TF1; +class AliMUONChamber; +class AliMUONRecCluster; //---------------------------------------------- // // Chamber segmentation virtual base class // -class AliMUONsegmentation : +class AliMUONSegmentation : public TObject { public: // Set Chamber Segmentation Parameters // // Pad size Dx*Dy - virtual void SetPADSIZ(Float_t p1, Float_t p2) =0; + virtual void SetPadSize(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 @@ -33,7 +34,7 @@ public TObject { virtual void GetPadCxy(Int_t ix,Int_t iy,Float_t &x ,Float_t &y )=0; // // Initialisation - virtual void Init(AliMUONchamber*) =0; + virtual void Init(AliMUONChamber*) =0; // // Get member data // @@ -45,13 +46,13 @@ public TObject { 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 + // Maximum number of Pads in x virtual Int_t Npx() =0; - // max number of Pads in y + // Maximum number of Pads in y virtual Int_t Npy() =0; - // set pad position + // Set pad position virtual void SetPad(Int_t, Int_t) =0; - // set hit position + // Set hit position virtual void SetHit(Float_t, Float_t) =0; // @@ -72,6 +73,7 @@ public TObject { // Get next neighbours virtual void Neighbours (Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) =0; + // // Current pad cursor during disintegration // x-coordinate virtual Int_t Ix() =0; @@ -84,57 +86,21 @@ public TObject { // // 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) + // Initialise signal generation 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(Option_t *) = 0; + // Draw the segmentation zones + virtual void Draw() = 0; // Function for systematic corrections + // Set the correction function virtual void SetCorrFunc(Int_t, TF1*) = 0; + // Get the correction Function 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 + ClassDef(AliMUONSegmentation,1) //Segmentation virtual base class }; #endif - - - diff --git a/MUON/AliMUONSegmentationTrigger.cxx b/MUON/AliMUONSegmentationTrigger.cxx new file mode 100644 index 00000000000..39f78e1fb2e --- /dev/null +++ b/MUON/AliMUONSegmentationTrigger.cxx @@ -0,0 +1,330 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 21:47:24 morsch +Code from AliMUONSegResTrigger.cxx + +*/ + +/* +old Log: +AliMUONSegResTrigger.cxx,v $ +Revision 1.1.2.3 2000/04/26 12:32:39 morsch +Mods by P. Crochet: +- adapted to the new Trigger chamber geometry +- method SetZScale removed + +Revision 1.1.2.2 2000/02/21 16:13:33 morsch +Full cluster simulation activated by uncommenting corresponding lines in IntXY() + +Revision 1.1.2.1 2000/02/17 14:32:40 morsch +Draft version from P. Crochet + +*/ + +#include "AliMUONSegmentationTrigger.h" +#include +#include +#include +#include "AliMUONChamber.h" +#include + +ClassImp(AliMUONSegmentationTrigger) + +void AliMUONSegmentationTrigger::Init(AliMUONChamber* Chamber) +{ + // initialize Module geometry + cout << "Initialize Trigger Chamber Module Geometry " << "\n"; + + Float_t zPos=Chamber->Z(); + Float_t z1Pos=1603.5; + fZscale = zPos/z1Pos; + + static Int_t nModule=126; + fgNmodule = nModule; +// conv : line-column (line : from top to bottom, column : from left to right) + static Int_t num[126]= + {11,12,13,14,15,16,17, // right side of the chamber + 21,22,23,24,25,26,27, + 31,32,33,34,35,36,37, + 41,42,43,44,45,46,47, + 51,52,53,54,55,56,57, + 61,62,63,64,65,66,67, + 71,72,73,74,75,76,77, + 81,82,83,84,85,86,87, + 91,92,93,94,95,96,97, + -11,-12,-13,-14,-15,-16,-17, // left side of the chamber + -21,-22,-23,-24,-25,-26,-27, + -31,-32,-33,-34,-35,-36,-37, + -41,-42,-43,-44,-45,-46,-47, + -51,-52,-53,-54,-55,-56,-57, + -61,-62,-63,-64,-65,-66,-67, + -71,-72,-73,-74,-75,-76,-77, + -81,-82,-83,-84,-85,-86,-87, + -91,-92,-93,-94,-95,-96,-97}; + fgNum = num; + + static Int_t nStripX[126]= + {16,16,16,16,16,16,16, // right side of the chamber + 32,32,32,32,32,32,16, + 32,32,32,32,32,32,16, + 48,64,64,32,32,32,16, + 0,64,64,32,32,32,16, + 48,64,64,32,32,32,16, + 32,32,32,32,32,32,16, + 32,32,32,32,32,32,16, + 16,16,16,16,16,16,16, // left side of the chamber + 16,16,16,16,16,16,16, + 32,32,32,32,32,32,16, + 32,32,32,32,32,32,16, + 48,64,64,32,32,32,16, + 0,64,64,32,32,32,16, + 48,64,64,32,32,32,16, + 32,32,32,32,32,32,16, + 32,32,32,32,32,32,16, + 16,16,16,16,16,16,16}; + fgNstripx = nStripX; + + static Int_t nStripY[126]= + { 8, 8, 8, 8, 8, 8,16, // right side of the chamber + 8, 8, 8, 8, 8, 8,16, + 16,16,16,16,16, 8,16, + 16,16,16,16,16, 8,16, + 0, 8,16,16,16, 8,16, + 16,16,16,16,16, 8,16, + 16,16,16,16,16, 8,16, + 8, 8, 8, 8, 8, 8,16, + 8, 8, 8, 8, 8, 8,16, // left side of the chamber + 8, 8, 8, 8, 8, 8,16, // right side of the chamber + 8, 8, 8, 8, 8, 8,16, + 16,16,16,16,16, 8,16, + 16,16,16,16,16, 8,16, + 0, 8,16,16,16, 8,16, + 16,16,16,16,16, 8,16, + 16,16,16,16,16, 8,16, + 8, 8, 8, 8, 8, 8,16, + 8, 8, 8, 8, 8, 8,16}; + fgNstripy = nStripY; + + static Float_t xCmin[126]= + {0.,34.,68.,102.,136.,170.,204., // right + 0.,34.,68.,102.,136.,170.,204., + 0.,34.,68.,102.,136.,170.,204., + 0.,34.,68.,102.,136.,170.,204., + 0.,51.,68.,102.,136.,170.,204., + 0.,34.,68.,102.,136.,170.,204., + 0.,34.,68.,102.,136.,170.,204., + 0.,34.,68.,102.,136.,170.,204., + 0.,34.,68.,102.,136.,170.,204., + -34.,-68.,-102.,-136.,-170.,-204.,-272., //left + -34.,-68.,-102.,-136.,-170.,-204.,-272., + -34.,-68.,-102.,-136.,-170.,-204.,-272., + -34.,-68.,-102.,-136.,-170.,-204.,-272., + 0.,-68.,-102.,-136.,-170.,-204.,-272., + -34.,-68.,-102.,-136.,-170.,-204.,-272., + -34.,-68.,-102.,-136.,-170.,-204.,-272., + -34.,-68.,-102.,-136.,-170.,-204.,-272., + -34.,-68.,-102.,-136.,-170.,-204.,-272.}; + fgXcmin = xCmin; + + static Float_t xCmax[126]= + {34.,68.,102.,136.,170.,204.,272., //right + 34.,68.,102.,136.,170.,204.,272., + 34.,68.,102.,136.,170.,204.,272., + 34.,68.,102.,136.,170.,204.,272., + 0.,68.,102.,136.,170.,204.,272., + 34.,68.,102.,136.,170.,204.,272., + 34.,68.,102.,136.,170.,204.,272., + 34.,68.,102.,136.,170.,204.,272., + 34.,68.,102.,136.,170.,204.,272., + 0.,-34.,-68.,-102.,-136.,-170.,-204., // left + 0.,-34.,-68.,-102.,-136.,-170.,-204., + 0.,-34.,-68.,-102.,-136.,-170.,-204., + 0.,-34.,-68.,-102.,-136.,-170.,-204., + 0.,-51.,-68.,-102.,-136.,-170.,-204., + 0.,-34.,-68.,-102.,-136.,-170.,-204., + 0.,-34.,-68.,-102.,-136.,-170.,-204., + 0.,-34.,-68.,-102.,-136.,-170.,-204., + 0.,-34.,-68.,-102.,-136.,-170.,-204.}; + fgXcmax = xCmax; + + static Float_t yCmin[126]; + static Float_t yCmax[126]; + Float_t y1Cmin[126]; + Float_t y1Cmax[126]; + + Float_t dz=7.2; + Float_t z1PosPlus=z1Pos+dz/2.; + Float_t z1PosMinus=z1Pos-dz/2.; + + Float_t z1pm=z1PosPlus/z1PosMinus; + Float_t z1mp=z1PosMinus/z1PosPlus; + + cout << " fZscale = " << fZscale << "\n"; + +// calculate yCmin and yCmax + for (Int_t i=62; i>=0; i--) { + Int_t j=ModuleNumber(-num[i]); // i == right, j == left + if (Int_t(num[i]/10)==5) { // start with middle chamber + if (num[i]==51) { // special case (empty module) + yCmin[i]=yCmax[i]=yCmin[j]=yCmax[j]=0.; + } else { + y1Cmin[i]=y1Cmin[j]=-34; + y1Cmax[i]=y1Cmax[j]=34; + yCmin[i]=yCmin[j]=-34.; + yCmax[i]=yCmax[j]=34.; + } + } else if (Int_t(num[i]/10)==4) { // up + if (num[i]!=41) { + y1Cmin[i]=y1Cmax[i+7]*z1pm; + y1Cmax[i]=y1Cmin[i]+68.; + yCmin[i]=y1Cmin[i]; + yCmax[i]=yCmin[i]+68.; + + y1Cmin[j]=y1Cmax[j+7]*z1mp; + y1Cmax[j]=y1Cmin[j]+68.; + yCmin[j]=y1Cmin[j]; + yCmax[j]=yCmin[j]+68.; + } else { + y1Cmin[i]=y1Cmin[ModuleNumber(42)]+17; + y1Cmax[i]=y1Cmin[i]+51.; + yCmin[i]=y1Cmin[i]; + yCmax[i]=yCmin[i]+51.; + + y1Cmin[j]=y1Cmin[ModuleNumber(-42)]+17; + y1Cmax[j]=y1Cmin[j]+51.; + yCmin[j]=y1Cmin[j]; + yCmax[j]=yCmin[j]+51.; + } + } else if (Int_t(num[i]/10)==3) { + y1Cmin[i]=y1Cmax[i+7]*z1mp; + y1Cmax[i]=y1Cmin[i]+68.; + yCmin[i]=y1Cmin[i]; + yCmax[i]=yCmin[i]+68.; + + y1Cmin[j]=y1Cmax[j+7]*z1pm; + y1Cmax[j]=y1Cmin[j]+68.; + yCmin[j]=y1Cmin[j]; + yCmax[j]=yCmin[j]+68.; + } else if (Int_t(num[i]/10)==2) { + y1Cmin[i]=y1Cmax[i+7]*z1pm; + y1Cmax[i]=y1Cmin[i]+68.; + yCmin[i]=y1Cmin[i]; + yCmax[i]=yCmin[i]+68.; + + y1Cmin[j]=y1Cmax[j+7]*z1mp; + y1Cmax[j]=y1Cmin[j]+68.; + yCmin[j]=y1Cmin[j]; + yCmax[j]=yCmin[j]+68.; + } else if (Int_t(num[i]/10)==1) { + y1Cmin[i]=y1Cmax[i+7]*z1mp; + y1Cmax[i]=y1Cmin[i]+68.; + yCmin[i]=y1Cmin[i]; + yCmax[i]=yCmin[i]+68.; + + y1Cmin[j]=y1Cmax[j+7]*z1pm; + y1Cmax[j]=y1Cmin[j]+68.; + yCmin[j]=y1Cmin[j]; + yCmax[j]=yCmin[j]+68.; + } + } + + for (Int_t i=0; i<63; i++) { // second loop (fill lower part) + Int_t j=ModuleNumber(-num[i]); // i == right, j == left + if (TMath::Abs(Int_t(num[i]/10))==6) { + yCmin[i]=-yCmax[i-14]; + yCmax[i]=-yCmin[i-14]; + yCmin[j]=-yCmax[j-14]; + yCmax[j]=-yCmin[j-14]; + } else if (TMath::Abs(Int_t(num[i]/10))==7) { + yCmin[i]=-yCmax[i-28]; + yCmax[i]=-yCmin[i-28]; + yCmin[j]=-yCmax[j-28]; + yCmax[j]=-yCmin[j-28]; + } else if (TMath::Abs(Int_t(num[i]/10))==8) { + yCmin[i]=-yCmax[i-42]; + yCmax[i]=-yCmin[i-42]; + yCmin[j]=-yCmax[j-42]; + yCmax[j]=-yCmin[j-42]; + } else if (TMath::Abs(Int_t(num[i]/10))==9) { + yCmin[i]=-yCmax[i-56]; + yCmax[i]=-yCmin[i-56]; + yCmin[j]=-yCmax[j-56]; + yCmax[j]=-yCmin[j-56]; + } + } + + fgYcmin = yCmin; + fgYcmax = yCmax; + + fNpx=124; + fNpy=64; + + cout << "---------------------------------------------------- \n"; + +} + +//------------------------------------------------------------------ +Int_t AliMUONSegmentationTrigger::ModuleNumber(Int_t imodule){ +// returns module number (from 0 to 126) corresponding to module imodule + Int_t imod=0; + for (Int_t i=0; i in SegRes X & Y + // virtual void SetPad(Int_t, Int_t); + // Set hit position + virtual void SetHit(Float_t xhit, Float_t yhit); + + // Current Pad during Integration + // x-coordinate + // virtual Int_t Ix(); + // y-coordinate + // virtual Int_t Iy(); + + ClassDef(AliMUONSegmentationTrigger,1) //Segmentation class for trigger + protected: + // Returns x-strip size for given module imodule + Float_t StripSizeX(Int_t imodule); + // Returns y-strip size for given module imodule + Float_t StripSizeY(Int_t imodule); + protected: +// Geometry Parameters + + Int_t fgNum[126]; // circuit Id. + Int_t fgNmodule; // total number of modules + Int_t fgNstripx[126]; // number of X strip / module + Int_t fgNstripy[126]; // number of Y strip / module + Float_t fgXcmin[126]; // x min position of modules + Float_t fgXcmax[126]; // x max position of modules + Float_t fgYcmin[126]; // y min position of modules + Float_t fgYcmax[126]; // y max position of modules + Float_t fZscale; // scaling factor (Zx/Z1, x=1,2,3,4) + +// Current pad during integration (cursor for disintegration) + Int_t fix; // pad coord. x + Int_t fiy; // pad coord. y + Float_t fx; // real coord. x + Float_t fy; // real ccord. y + + Float_t fxhit; // x-position of hit + Float_t fyhit; // y-position of hit + Int_t fSector;// Segmentation Sector + +}; + +#endif + + + + + + + + + + + + + diff --git a/MUON/AliMUONSegmentationTriggerX.cxx b/MUON/AliMUONSegmentationTriggerX.cxx new file mode 100644 index 00000000000..6007d6657a5 --- /dev/null +++ b/MUON/AliMUONSegmentationTriggerX.cxx @@ -0,0 +1,251 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 21:51:03 morsch +Code from AliMUONSegResTrigger.cxx + +*/ + + +/* +Old Log: +Revision 1.1.2.4 2000/04/26 12:33:25 morsch +Minor changes in some methods (CP) + +Revision 1.1.2.3 2000/03/20 18:14:16 morsch +Missing sector added. + +Revision 1.1.2.2 2000/02/20 07:50:49 morsch +Bugs in Dpx, Dpy and ISector methods corrected (P.C.) + +Revision 1.1.2.1 2000/02/17 14:33:49 morsch +Draft version from P. Crochet + +*/ + +#include "AliMUONSegmentationTriggerX.h" +#include "TMath.h" +#include "TRandom.h" +#include "TArc.h" +#include "AliMUONChamber.h" +#include +ClassImp(AliMUONSegmentationTriggerX) + +void AliMUONSegmentationTriggerX::Init(AliMUONChamber* Chamber) +{ + cout << "Initialize Trigger Chamber Geometry X " << "\n"; + AliMUONSegmentationTrigger::Init(Chamber); + +// calculate x & y position of X strips + for (Int_t imodule=0; imodulefXofxsmin[imodule][istrip]&&xfYofxsmin[imodule][istrip]&&y0) { // strip down in same module + *Nlist=*Nlist+1; + Xlist[*Nlist-1]=absiX; + Ylist[*Nlist-1]=iY-1; + } + + if (iX<0) { // left side of chamber + for (Int_t i=0; i<*Nlist; i++) {Xlist[i]=-Xlist[i];} + } + } +} + +//------------------------------------------------------------------ +void AliMUONSegmentationTriggerX::SetPad(Int_t ix, Int_t iy) +{ + // Sets virtual pad coordinates, needed for evaluating pad response + // outside the tracking program + GetPadCxy(ix,iy,fx,fy); + GetPadIxy(fx,fy,fix,fiy); + fSector=Sector(ix,iy); +} + +//------------------------------------------------------------------ +Int_t AliMUONSegmentationTriggerX::ISector() +{ return fSector;} + +//------------------------------------------------------------------ +Int_t AliMUONSegmentationTriggerX::Ix() +{ return fix;} + +//------------------------------------------------------------------ +Int_t AliMUONSegmentationTriggerX::Iy() +{ return fiy;} + +//------------------------------------------------------------------ +Float_t AliMUONSegmentationTriggerX::Dpx(Int_t isec) +{ // returns x size of x strips for sector isec + + if (isec==1) { + return 17.0*fZscale; + } else if (isec==2) { + return 34.0*fZscale; + } else if (isec==3) { + return 34.0*fZscale; + } else if (isec==4) { + return 34.0*fZscale; + } else if (isec==5) { + return 34.0*fZscale; + } else if (isec==6) { + return 68.0*fZscale; + } else { + return 0.; + } +} + +//------------------------------------------------------------------ +Float_t AliMUONSegmentationTriggerX::Dpy(Int_t isec) +{ // returns y size of x strips for sector isec + // cout << " In AliMUONSegmentationTriggerX::Dpx" << "\n"; + + if (isec==1) { + return 1.0625*fZscale; + } else if (isec==2) { + return 1.0625*fZscale; + } else if (isec==3) { + return 1.0625*fZscale; + } else if (isec==4) { + return 2.125*fZscale; + } else if (isec==5) { + return 4.25*fZscale; + } else if (isec==6) { + return 4.25*fZscale; + } else { + return 0.; + } +} + +//------------------------------------------------------------------ +void AliMUONSegmentationTriggerX::SetHit(Float_t xhit, Float_t yhit) +{ AliMUONSegmentationTrigger::SetHit(xhit,yhit);} + +//------------------------------------------------------------------ +Int_t AliMUONSegmentationTriggerX::Sector(Int_t ix, Int_t iy) +{ +// Returns sector number for given module +// + Int_t absix=TMath::Abs(ix); + Int_t iwidth=Int_t(StripSizeX(absix)); + + if (absix==52) { + return 1; + } else if (absix==41||absix==61) { + return 2; + } else if (iwidth==1) { + return 3; + } else if (iwidth==2) { + return 4; + } else if ((absix>=11&&absix<17)||(absix>=91&&absix<97)) { + return 5; + } else if (iwidth==4) { + return 6; + } else { + return 0; + } +} + +//------------------------------------------------------------------ +void AliMUONSegmentationTriggerX:: +IntegrationLimits(Float_t& x1, Float_t& x2, Float_t& x3, Float_t& width) +{ // returns quantities needed to evaluate neighbour strip response +// cout << " In AliMUONSegmentationTriggerX::IntegrationLimits" << "\n"; + Int_t ix,iy; + Float_t xstrip,ystrip; + GetPadIxy(fxhit,fyhit,ix,iy); + GetPadCxy(ix,iy,xstrip,ystrip); + x1=fyhit; // hit y position + x2=ystrip; // y coordinate of the main strip + x3=fy; // current strip real y coordinate + width=StripSizeX(ix); // width of the main strip +} + + + + + + + + diff --git a/MUON/AliMUONSegmentationTriggerX.h b/MUON/AliMUONSegmentationTriggerX.h new file mode 100644 index 00000000000..08a3d095a7a --- /dev/null +++ b/MUON/AliMUONSegmentationTriggerX.h @@ -0,0 +1,73 @@ +#ifndef ALIMUONSEGMENTATIONTRIGGERX_H +#define ALIMUONSEGMENTATIONTRIGGERX_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include "AliMUONSegmentationTrigger.h" + +class AliMUONChamber; +//---------------------------------------------- +// +// Chamber segmentation virtual base class +// +class AliMUONSegmentationTriggerX : +public AliMUONSegmentationTrigger { + public: + AliMUONSegmentationTriggerX(){} + virtual ~AliMUONSegmentationTriggerX(){} + // 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); + // Pad size Dx*Dy + virtual void SetPadSize(Float_t dp1, Float_t dp2); + // Strip size + virtual Float_t Dpx(Int_t imodule); + virtual Float_t Dpy(Int_t imodule); + // Set pad position + virtual void SetPad(Int_t ix, Int_t iy); + // Set hit position + virtual void SetHit(Float_t xhit, Float_t yhit); + // Current integration parameters + virtual void IntegrationLimits(Float_t& x1, Float_t& x2, Float_t& x3, Float_t& width); + // Current Pad during Integration + // x-coordinate + virtual Int_t Ix(); + // y-coordinate + virtual Int_t Iy(); + // Sector + virtual Int_t ISector(); + // calculate sector from pad coordinates + virtual Int_t Sector(Int_t ix, Int_t iy); + // Get next neighbours + virtual void Neighbours + (Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[2], Int_t Ylist[2]); + + // + // Initialisation + virtual void Init(AliMUONChamber* chamber); + + ClassDef(AliMUONSegmentationTriggerX,1) //Segmentation class for trigger X + + protected: + void IntegrationParam(Float_t& x1, Float_t& x2, Float_t& y1); +// Geometry Parameters + float fXofxsmin[126][64]; // x-min + float fXofxsmax[126][64]; // x-max + float fYofxsmin[126][64]; // y-min + float fYofxsmax[126][64]; // y-max + +// Current pad during integration (cursor for disintegration) + Int_t fix; // pad coord. x + Int_t fiy; // pad coord. y + Float_t fx; // real coord. x + Float_t fy; // real ccord. y + +}; +#endif + + + diff --git a/MUON/AliMUONSegmentationTriggerY.cxx b/MUON/AliMUONSegmentationTriggerY.cxx new file mode 100644 index 00000000000..c96efd44157 --- /dev/null +++ b/MUON/AliMUONSegmentationTriggerY.cxx @@ -0,0 +1,253 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 21:51:58 morsch +Code from AliMUONSegResTriggerY.cxx + +*/ + +/* +Old Log: +Revision 1.1.2.4 2000/05/05 10:17:04 morsch +Y strip numerotation changed (CP) + +Revision 1.1.2.3 2000/04/26 12:33:40 morsch +Minor changes in some methods (CP) + +Revision 1.1.2.2 2000/02/20 07:49:50 morsch +Bugs in Dpx, Dpy and ISector methods corrected (P.C.) + +Revision 1.1.2.1 2000/02/17 14:34:57 morsch +Draft version from P. Crochet + +*/ + +#include "AliMUONSegmentationTriggerY.h" +#include "TMath.h" +#include "TRandom.h" +#include "TArc.h" +#include "AliMUONChamber.h" +#include +ClassImp(AliMUONSegmentationTriggerY) + +void AliMUONSegmentationTriggerY::Init(AliMUONChamber* Chamber) +{ + cout << "Initialize Trigger Chamber Geometry Y " << "\n"; + AliMUONSegmentationTrigger::Init(Chamber); + +// calculate x & y position of Y strips + for (Int_t imodule=0; imodulefXofysmin[imodule][istrip]&&xfYofysmin[imodule][istrip]&&yROuter()/fDpx+1); + fNpy=(Int_t) (Chamber->ROuter()/fDpy+1); +// Initialize inner and outer radius of the sensitive region + fRmin=Chamber->RInner(); + fRmax=Chamber->ROuter(); + fCorr=0; + +} + + +Float_t AliMUONSegmentationV0::GetAnod(Float_t xhit) +{ +// Returns for a hit position xhit the position of the nearest anode wire + Float_t wire= (xhit>0)? Int_t(xhit/fWireD)+0.5:Int_t(xhit/fWireD)-0.5; + return fWireD*wire; +} + +void AliMUONSegmentationV0::SetPadSize(Float_t p1, Float_t p2) +{ +// Sets the padsize +// + 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) +// +// Comments and Critics: + +// The Pad(0,0) does not exist, this causes in the present version errors +// during iteration when used with hits close to zero. +// Since we have frame crosses at x=0 or y=0 this does not cause any problems +// Nevertheless, should be corrected in the next version !! +// The name fRmin is misleading although we use this version with +// a circular chamber geometry. + + 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) +{ + // + // Sets virtual hit position, needed for evaluating pad response + // outside the tracking program + fxhit=xhit; + fyhit=yhit; +} + +void AliMUONSegmentationV0:: +SetPad(Int_t ix, Int_t iy) +{ + // + // Sets virtual pad coordinates, needed for evaluating pad response + // outside the tracking program + GetPadCxy(ix,iy,fx,fy); +} + +void AliMUONSegmentationV0:: +FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) +{ +// Initialises iteration over pads for charge distribution algorithm +// + // + // 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); + // + // Set current pad to lower left corner + fix=fixmin; + fiy=fiymin; + GetPadCxy(fix,fiy,fx,fy); +} + +void AliMUONSegmentationV0::NextPad() +{ + // Stepper for the iteration over pads + // + // Comments and Critics: + // Boundary crossing at x=0 or y=0 not correctly handled ! + // Step to next pad in the 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() +// Stopping condition for the iterator over pads +// +// 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 generation condition during stepping +// 0: don't generate signal +// 1: generate signal +// Comments and critics: + +// Crossing of pad boundary and mid plane between neighbouring wires is checked. +// To correctly simulate the dependence of the spatial resolution on the angle +// of incidence signal must be generated for constant steps on +// the projection of the trajectory along the anode wire. + +// +// 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) +{ +// Returns integration limits for current pad +// + 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[10], Int_t Ylist[10]) +{ +// Returns list of next neighbours for given Pad (iX, iY) +// +// Comments and critics +// "Diagonal" neighbours are not passed +// Is this ok when we search for local maxima ?? +// No test whether neighbours have valid indices id performed + *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; +} + +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::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) +{ +// Returns test point on the pad plane. +// Used during determination of the segmoid correction of the COG-method + n=1; + x[0]=(fRmax+fRmin)/2/TMath::Sqrt(2.); + y[0]=x[0]; +} + +void AliMUONSegmentationV0::Draw() +{ +// Draws the segmentation zones +// + 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(); +} + +AliMUONSegmentationV0& AliMUONSegmentationV0::operator =(const AliMUONSegmentationV0 & rhs) +{ +// Dummy assignment operator + return *this; +} diff --git a/MUON/AliMUONSegResV0.h b/MUON/AliMUONSegmentationV0.h similarity index 51% rename from MUON/AliMUONSegResV0.h rename to MUON/AliMUONSegmentationV0.h index 6c93b49a922..7277c85f8df 100644 --- a/MUON/AliMUONSegResV0.h +++ b/MUON/AliMUONSegmentationV0.h @@ -1,22 +1,28 @@ -#ifndef MUONSegResV0_H -#define MUONSegResV0_H +#ifndef ALIMUONSEGMENTATIONV0_H +#define ALIMUONSEGMENTATIONV0_H /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ /* $Id$ */ -#include "AliMUONSegRes.h" -class AliMUONchamber; +#include "AliMUONSegmentation.h" -class AliMUONsegmentationV0 : -public AliMUONsegmentation { +class AliMUONChamber; +//---------------------------------------------- +// +// Chamber segmentation for homogeneously segmented circular chamber +// +class AliMUONSegmentationV0 : +public AliMUONSegmentation { public: - AliMUONsegmentationV0(){} - virtual ~AliMUONsegmentationV0(){} + AliMUONSegmentationV0(){} + AliMUONSegmentationV0(const AliMUONSegmentationV0 & segmentation); + + virtual ~AliMUONSegmentationV0(){} // Set Chamber Segmentation Parameters // // Pad size Dx*Dy - virtual void SetPADSIZ(Float_t p1, Float_t p2); + virtual void SetPadSize(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 @@ -29,7 +35,7 @@ public AliMUONsegmentation { virtual void GetPadCxy(Int_t ix,Int_t iy,Float_t &x ,Float_t &y ); // // Initialisation - virtual void Init(AliMUONchamber*); + virtual void Init(AliMUONChamber* chamber); // // Get member data // @@ -41,14 +47,14 @@ public AliMUONsegmentation { 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 + // Maximum number of Pads in x virtual Int_t Npx(){return fNpx;} - // max number of Pads in y + // Maximum 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); + // Set pad position + virtual void SetPad(Int_t ix, Int_t iy); + // Set hit position + virtual void SetHit(Float_t xhit, Float_t yhit); // // Iterate over pads // Initialiser @@ -63,11 +69,12 @@ public AliMUONsegmentation { 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, Int_t , + 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]); + // // Current Pad during Integration // x-coordinaten virtual Int_t Ix(){return fix;} @@ -76,7 +83,7 @@ dummy); // current sector virtual Int_t ISector(){return 1;} // calculate sector from pad coordinates - virtual Int_t Sector(Int_t , Int_t ) {return 1;} + 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); @@ -87,22 +94,24 @@ dummy); (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(Option_t *); + // Draw segmentation zones + virtual void Draw(); // Function for systematic corrections - virtual void SetCorrFunc(Int_t, TF1* func) {fCorr=func;} - - virtual TF1* CorrFunc(Int_t) {return fCorr;} - + // Set the correction function + virtual void SetCorrFunc(Int_t dum, TF1* func) {fCorr=func;} + // Get the correction Function + virtual TF1* CorrFunc(Int_t) {return fCorr;} + // assignment operator + AliMUONSegmentationV0& operator=(const AliMUONSegmentationV0& rhs); - ClassDef(AliMUONsegmentationV0,1) - protected: + ClassDef(AliMUONSegmentationV0,1) //Class for homogeneous segmentation + protected: // - // Implementation of the segmentation data + // Implementation of the segmentation class: // Version 0 models rectangular pads with the same dimensions all - // over the cathode plane - // - // geometry + // over the cathode plane. Chamber has circular geometry. + // + // Geometry parameters // Float_t fDpx; // x pad width per sector Float_t fDpy; // y pad base width @@ -120,16 +129,16 @@ dummy); 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 + Int_t fix; // pad coord. x + Int_t fiy; // pad coord. y + Float_t fx; // real coord. x + Float_t fy; // real ccord. y // // Current pad and wire during tracking (cursor at hit centre) // // - Float_t fxhit; - Float_t fyhit; + Float_t fxhit; // x-position of hit + Float_t fyhit; // y-position of hit // Reference point to define signal generation condition Int_t fixt; // pad coord. x Int_t fiyt; // pad coord. y @@ -137,63 +146,6 @@ dummy); Float_t fxt; // x Float_t fyt; // y TF1* fCorr; // correction function - -}; - -class AliMUONresponseV0 : //Mathieson response -public AliMUONresponse { - public: - AliMUONresponseV0(){} - virtual ~AliMUONresponseV0(){} - // - // Configuration methods - // - // Number of sigmas over which cluster didintegration is performed - virtual void SetSigmaIntegration(Float_t p1) {fSigmaIntegration=p1;} - virtual Float_t SigmaIntegration() {return fSigmaIntegration;} - // charge slope in ADC/e - virtual void SetChargeSlope(Float_t p1) {fChargeSlope=p1;} - virtual Float_t ChargeSlope() {return fChargeSlope;} - // sigma of the charge spread function - virtual void SetChargeSpread(Float_t p1, Float_t p2) - {fChargeSpreadX=p1; fChargeSpreadY=p2;} - virtual Float_t ChargeSpreadX() {return fChargeSpreadX;} - virtual Float_t ChargeSpreadY() {return fChargeSpreadY;} - // Adc-count saturation value - virtual void SetMaxAdc(Float_t p1) {fMaxAdc=p1;} - virtual Float_t MaxAdc() {return fMaxAdc;} - // anode cathode Pitch - virtual Float_t Pitch() {return fPitch;} - virtual void SetPitch(Float_t p1) {fPitch=p1;}; - // Mathieson parameters - virtual void SetSqrtKx3(Float_t p1) {fSqrtKx3=p1;}; - virtual void SetKx2(Float_t p1) {fKx2=p1;}; - virtual void SetKx4(Float_t p1) {fKx4=p1;}; - virtual void SetSqrtKy3(Float_t p1) {fSqrtKy3=p1;}; - virtual void SetKy2(Float_t p1) {fKy2=p1;}; - virtual void SetKy4(Float_t p1) {fKy4=p1;}; - - // - // Chamber response methods - // Pulse height from scored quantity (eloss) - virtual Float_t IntPH(Float_t eloss); - // Charge disintegration - virtual Float_t IntXY(AliMUONsegmentation * segmentation); - - ClassDef(AliMUONresponseV0,1) - protected: - Float_t fChargeSlope; // Slope of the charge distribution - Float_t fChargeSpreadX; // Width of the charge distribution in x - Float_t fChargeSpreadY; // Width of the charge distribution in y - Float_t fSigmaIntegration; // Number of sigma's used for charge distribution - Float_t fMaxAdc; // Maximum ADC channel - Float_t fSqrtKx3; // Mathieson parameters for x - Float_t fKx2; - Float_t fKx4; - Float_t fSqrtKy3; // Mathieson parameters for y - Float_t fKy2; - Float_t fKy4; - Float_t fPitch; //anode-cathode pitch }; #endif diff --git a/MUON/AliMUONSegmentationV01.cxx b/MUON/AliMUONSegmentationV01.cxx new file mode 100644 index 00000000000..4df8c6d4129 --- /dev/null +++ b/MUON/AliMUONSegmentationV01.cxx @@ -0,0 +1,504 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.1 2000/06/09 21:37:30 morsch +AliMUONSegmentationV01 code from AliMUONSegResV01.cxx + +*/ + + +///////////////////////////////////////////////////// +// Segmentation and Response classes version 01 // +///////////////////////////////////////////////////// + +#include +#include +#include +#include + +#include "AliMUONSegmentationV01.h" +#include "AliMUON.h" + + + +//___________________________________________ +ClassImp(AliMUONSegmentationV01) + +AliMUONSegmentationV01::AliMUONSegmentationV01(const AliMUONSegmentationV01& segmentation) +{ +// Dummy copy constructor +} +AliMUONSegmentationV01::AliMUONSegmentationV01() +{ +// Default constructor + 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; +} + +Float_t AliMUONSegmentationV01::Dpx(Int_t isec) +{ +// +// Returns x-pad size for given sector isec + return fDpxD[isec]; +} + +Float_t AliMUONSegmentationV01::Dpy(Int_t isec) +{ +// +// Returns y-pad size for given sector isec + return fDpy; +} + +void AliMUONSegmentationV01::SetSegRadii(Float_t r[4]) +{ +// +// Set the radii of the segmentation zones + 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. +// Pad sizes are defined as integral fractions ndiv of a basis pad size +// fDpx +// + 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. +// This version approximates concentric segmentation zones +// + Int_t isec; + printf("\n Initialise segmentation v01 -- test !!!!!!!!!!!!!! \n"); + fNpy=Int_t(fRSec[fNsec-1]/fDpy)+1; + + fDpxD[fNsec-1]=fDpx; + if (fNsec > 1) { + for (Int_t i=fNsec-2; i>=0; i--){ + fDpxD[i]=fDpxD[fNsec-1]/fNDiv[i]; + printf("\n test ---dx %d %f \n",i,fDpxD[i]); + } + } +// +// fill the arrays defining the pad segmentation boundaries + Float_t ry; + Int_t dnx; + Int_t add; +// +// loop over sections + for(isec=0; isec fRSec[isec]) { + fNpxS[isec][iy]=0; + fCx[isec][iy]=0; + } else { + ry=TMath::Sqrt(fRSec[isec]*fRSec[isec]-x*x); + if (isec > 1) { + dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]); + if (isec < fNsec-1) { + if (TMath::Odd((Long_t)dnx)) dnx++; + } + fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx; + fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec]; + } else if (isec == 1) { + dnx= Int_t((ry-fCx[isec-1][iy])/fDpxD[isec]); + fNpxS[isec][iy]=fNpxS[isec-1][iy]+dnx; + add=4 - (fNpxS[isec][iy])%4; + if (add < 4) fNpxS[isec][iy]+=add; + dnx=fNpxS[isec][iy]-fNpxS[isec-1][iy]; + fCx[isec][iy]=fCx[isec-1][iy]+dnx*fDpxD[isec]; + } else { + dnx=Int_t(ry/fDpxD[isec]); + fNpxS[isec][iy]=dnx; + fCx[isec][iy]=dnx*fDpxD[isec]; + } + } + } // y-pad loop + } // sector loop +} + +Int_t AliMUONSegmentationV01::Sector(Int_t ix, Int_t iy) +{ +// Returns sector number for given pad position +// + Int_t absix=TMath::Abs(ix); + Int_t absiy=TMath::Abs(iy); + Int_t isec=0; + for (Int_t i=0; i0)? Int_t(y/fDpy)+1 : Int_t(y/fDpy)-1; + if (iy > fNpy) iy= fNpy; + if (iy < -fNpy) iy=-fNpy; +// +// Find sector isec + Int_t isec=-1; + Float_t absx=TMath::Abs(x); + Int_t absiy=TMath::Abs(iy); + for (Int_t i=0; i < fNsec; i++) { + if (absx <= fCx[i][absiy]) { + isec=i; + break; + } + } + if (isec>0) { + ix= Int_t((absx-fCx[isec-1][absiy])/fDpxD[isec]) + +fNpxS[isec-1][absiy]+1; + } else if (isec == 0) { + ix= Int_t(absx/fDpxD[isec])+1; + } else { + ix=fNpxS[fNsec-1][absiy]+1; + } + 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) +{ + // + // Sets virtual pad coordinates, needed for evaluating pad response + // outside the tracking program + GetPadCxy(ix,iy,fx,fy); + fSector=Sector(ix,iy); +} + + +void AliMUONSegmentationV01:: +FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) +{ +// Initialises iteration over pads for charge distribution algorithm +// + // + // 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() +{ +// Stepper for the iteration over pads +// +// Step to next pad in the integration region + // + // 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 first 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)) + NextPad(); +} + +Int_t AliMUONSegmentationV01::MorePads() +// Stopping condition for the iterator over pads +// +// 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) +{ +// Returns integration limits for current pad +// + 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]) +{ +// Returns list of next neighbours for given Pad (iX, iY) +// + const Float_t kEpsilon=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; + if (Xlist[i]==0) Xlist[i]++; + Ylist[i++]=iY; +// +// step left + Xlist[i]=iX-1; + if (Xlist[i]==0) Xlist[i]--; + Ylist[i++]=iY; +// +// step up + AliMUONSegmentationV01::GetPadCxy(iX,iY,x,y); + AliMUONSegmentationV01::GetPadIxy(x+kEpsilon,y+fDpy,ixx,iyy); + Xlist[i]=ixx; + Ylist[i++]=iyy; + 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++]=iyy; + +// 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+kEpsilon,y-fDpy,ixx,iyy); + Xlist[i]=ixx; + Ylist[i++]=iyy; + 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++]=iyy; + +// 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::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) +{ +// Returns test point on the pad plane. +// Used during determination of the segmoid correction of the COG-method + + 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() +{ +// Draws the segmentation zones +// + TBox *box; + + Float_t dx=0.95/fCx[3][1]/2; + Float_t dy=0.95/(Float_t(Npy()))/2; + Float_t x0,y0,x1,y1; + Float_t xc=0.5; + Float_t yc=0.5; + + for (Int_t iy=1; iySetFillColor(isec+1); + box->Draw(); + + box=new TBox(-x1+xc,y0+yc,-x0+xc,y1+yc); + box->SetFillColor(isec+1); + box->Draw(); + + box=new TBox(x0+xc,-y1+yc,x1+xc,-y0+yc); + box->SetFillColor(isec+1); + box->Draw(); + + box=new TBox(-x1+xc,-y1+yc,-x0+xc,-y0+yc); + box->SetFillColor(isec+1); + box->Draw(); + } + } +} +void AliMUONSegmentationV01::SetCorrFunc(Int_t isec, TF1* func) +{ + (*fCorr)[isec]=func; +} + +TF1* AliMUONSegmentationV01::CorrFunc(Int_t isec) +{ + return (TF1*) (*fCorr)[isec]; +} + +AliMUONSegmentationV01& AliMUONSegmentationV01::operator +=(const AliMUONSegmentationV01 & rhs) +{ +// Dummy assignment operator + return *this; +} diff --git a/MUON/AliMUONSegmentationV01.h b/MUON/AliMUONSegmentationV01.h new file mode 100644 index 00000000000..e63ce2e8951 --- /dev/null +++ b/MUON/AliMUONSegmentationV01.h @@ -0,0 +1,124 @@ +#ifndef ALIMUONSEGMENTATIONV01_H +#define ALIMUONSEGMENTATIONV01_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +///////////////////////////////////////////////////// +// Segmentation and Response classes version 01 // +///////////////////////////////////////////////////// +class AliMUON; +class TArrayF; +class TArrayI; +class TObjArray; + + + +#include "AliMUONSegmentationV0.h" +#include "TArrayI.h" +#include "TArrayF.h" + +class AliMUONSegmentationV01 : +public AliMUONSegmentationV0 { + public: + AliMUONSegmentationV01(); + AliMUONSegmentationV01(const AliMUONSegmentationV01 & segmentation); + + 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* chamber); + // + // 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 ix,Int_t iy); + // + // 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]); + // + // 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); + // + // Draw segmentation zones + virtual void Draw(); + // Function for systematic corrections + // Set the correction function + virtual void SetCorrFunc(Int_t dum, TF1* func); + // Get the correction function + virtual TF1* CorrFunc(Int_t iZone); + // assignment operator + AliMUONSegmentationV01& operator=(const AliMUONSegmentationV01& rhs); + ClassDef(AliMUONSegmentationV01,1) // Segmentation approximating circular zones with different pad size + protected: + // Geometry + // + Int_t fNsec; // Number of sectors + TArrayF fRSec; // Sector outer radia + TArrayI fNDiv; // Pad size division + TArrayF fDpxD; // y pad width per sector + // Segmentation map + 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; // lower left x + Float_t fxmax; // lower left y + Float_t fymin; // upper right x + Float_t fymax; // upper right y + + // + // Current pad during integration (cursor for disintegration) + Int_t fSector; // Current sector + // + TObjArray *fCorr; // Correction functions +}; +#endif + + + + + + + + diff --git a/MUON/AliMUONSegResV02.cxx b/MUON/AliMUONSegmentationV02.cxx similarity index 60% rename from MUON/AliMUONSegResV02.cxx rename to MUON/AliMUONSegmentationV02.cxx index 1c34c51bbc2..d21ebc7165f 100644 --- a/MUON/AliMUONSegResV02.cxx +++ b/MUON/AliMUONSegmentationV02.cxx @@ -15,68 +15,85 @@ /* $Log$ +Revision 1.1.2.1 2000/06/09 21:37:56 morsch +AliMUONSegmentationV02 code from AliMUONSegResV02.cxx + */ + + ///////////////////////////////////////////////////// // Segmentation and Response classes version 02 // ///////////////////////////////////////////////////// -#include -#include -#include -#include "AliMUONSegResV02.h" -#include "AliRun.h" -#include "AliMC.h" + +#include "AliMUONSegmentationV02.h" #include "iostream.h" //___________________________________________ -ClassImp(AliMUONsegmentationV02) +ClassImp(AliMUONSegmentationV02) -void AliMUONsegmentationV02::SetPADSIZ(Float_t p1, Float_t p2) +void AliMUONSegmentationV02::SetPadSize(Float_t p1, Float_t p2) { +// Sets the padsize +// fDpy=p1; fDpx=p2; } -Int_t AliMUONsegmentationV02::Npx() -{return AliMUONsegmentationV01::Npy();} +Int_t AliMUONSegmentationV02::Npx() +// Returns maximum number if pads in x +{return AliMUONSegmentationV01::Npy();} -Int_t AliMUONsegmentationV02::Npy() -{return AliMUONsegmentationV01::Npx();} +Int_t AliMUONSegmentationV02::Npy() +// Returns maximum number if pads in y +{return AliMUONSegmentationV01::Npx();} -Float_t AliMUONsegmentationV02::Dpx(Int_t) +Float_t AliMUONSegmentationV02::Dpx(Int_t isec) +// Returns pad-size in x {return fDpy;} -Float_t AliMUONsegmentationV02::Dpy(Int_t isec) +Float_t AliMUONSegmentationV02::Dpy(Int_t isec) +// Returns pad-size in y {return fDpxD[isec];} +Int_t AliMUONSegmentationV02::Sector(Int_t ix, Int_t iy) +// Returns sector number for given pad position +// +{return AliMUONSegmentationV01::Sector(iy, ix);} -Int_t AliMUONsegmentationV02::Sector(Int_t ix, Int_t iy) -{return AliMUONsegmentationV01::Sector(iy, ix);} +void AliMUONSegmentationV02:: -void AliMUONsegmentationV02:: GetPadIxy(Float_t x, Float_t y, Int_t &ix, Int_t &iy) +// Returns pad coordinates (ix,iy) for given real coordinates (x,y) +// { -AliMUONsegmentationV01::GetPadIxy(y, x, iy, ix); +AliMUONSegmentationV01::GetPadIxy(y, x, iy, ix); // printf("\n x,y,ix,iy %f %f %d %d", x,y,ix,iy); } -void AliMUONsegmentationV02:: +void AliMUONSegmentationV02:: GetPadCxy(Int_t ix, Int_t iy, Float_t &x, Float_t &y) +// Returns real coordinates (x,y) for given pad coordinates (ix,iy) +// { - AliMUONsegmentationV01::GetPadCxy(iy, ix, y, x); -// printf("\n ix,iy,x,y %d %d %f %f ", ix,iy,x,y); + AliMUONSegmentationV01::GetPadCxy(iy, ix, y, x); } -void AliMUONsegmentationV02::SetPad(Int_t ix,Int_t iy) +void AliMUONSegmentationV02::SetPad(Int_t ix,Int_t iy) { + // + // Sets virtual pad coordinates, needed for evaluating pad response + // outside the tracking program GetPadCxy(ix,iy,fx,fy); fSector=Sector(ix,iy); } -void AliMUONsegmentationV02::NextPad() +void AliMUONSegmentationV02::NextPad() { +// Stepper for the iteration over pads +// // // Step to next pad in integration region Float_t xc,yc; @@ -100,14 +117,15 @@ void AliMUONsegmentationV02::NextPad() 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)) + (fSector ==-1 || fSector==0 )) NextPad(); // printf("\n this pad %f %f %d %d \n",fx,fy,fix,fiy); } -Int_t AliMUONsegmentationV02::MorePads() +Int_t AliMUONSegmentationV02::MorePads() +// Stopping condition for the iterator over pads +// // // Are there more pads in the integration region { @@ -118,12 +136,16 @@ Int_t AliMUONsegmentationV02::MorePads() } } -void AliMUONsegmentationV02:: +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; +// Returns list of next neighbours for given Pad (iX, iY) +// + Int_t n; + AliMUONSegmentationV01::Neighbours(iY, iX, &n, Ylist, Xlist); + *Nlist=n; } + + diff --git a/MUON/AliMUONSegResV02.h b/MUON/AliMUONSegmentationV02.h similarity index 75% rename from MUON/AliMUONSegResV02.h rename to MUON/AliMUONSegmentationV02.h index bafd358ada2..2ec2b18c920 100644 --- a/MUON/AliMUONSegResV02.h +++ b/MUON/AliMUONSegmentationV02.h @@ -1,5 +1,5 @@ -#ifndef MUONv02_H -#define MUONv02_H +#ifndef ALIMUONSEGMENTATIONV02_H +#define ALIMUONSEGMENTATIONV02_H /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ @@ -9,17 +9,17 @@ // Segmentation and Response classes version 01 // ///////////////////////////////////////////////////// -#include "AliMUON.h" -#include "TArrayF.h" -#include "TArrayI.h" -#include "AliMUONSegResV01.h" -class AliMUONsegmentationV02 : -public AliMUONsegmentationV01 { + +#include "AliMUONSegmentationV01.h" + +class AliMUONSegmentationV02 : +public AliMUONSegmentationV01 { public: - AliMUONsegmentationV02(){}; - virtual ~AliMUONsegmentationV02(){} + AliMUONSegmentationV02(){}; + virtual ~AliMUONSegmentationV02(){} // - virtual void SetPADSIZ(Float_t p1, Float_t p2); + // Pad size Dx*Dy + virtual void SetPadSize(Float_t p1, Float_t p2); // // Get member data // Pad size in x @@ -42,16 +42,17 @@ public AliMUONsegmentationV01 { 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); + // Set pad position virtual void SetPad(Int_t ix,Int_t iy); // 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]); // Get next neighbours - ClassDef(AliMUONsegmentationV02,1) //Muon chamber segmentation version 02 + ClassDef(AliMUONSegmentationV02,1) // Segmentation approximating circular zones with different pad size }; #endif diff --git a/MUON/AliMUONSegResV04.cxx b/MUON/AliMUONSegmentationV04.cxx similarity index 77% rename from MUON/AliMUONSegResV04.cxx rename to MUON/AliMUONSegmentationV04.cxx index f2f63c40222..77431526f1b 100644 --- a/MUON/AliMUONSegResV04.cxx +++ b/MUON/AliMUONSegmentationV04.cxx @@ -15,36 +15,36 @@ /* $Log$ +Revision 1.1.2.1 2000/06/09 21:38:15 morsch +AliMUONSegmentationV04 code from AliMUONSegResV04.cxx + */ ///////////////////////////////////////////////////// // Segmentation and Response classes version 04 // ///////////////////////////////////////////////////// -#include -#include -#include -#include "AliMUONSegResV04.h" -#include "AliRun.h" -#include "AliMC.h" -#include "iostream.h" +#include "AliMUONSegmentationV04.h" +#include //___________________________________________ -ClassImp(AliMUONsegmentationV04) +ClassImp(AliMUONSegmentationV04) -void AliMUONsegmentationV04::Init(AliMUONchamber* ) +void AliMUONSegmentationV04::Init(AliMUONChamber* Chamber) { - //printf("\n Initialise segmentation v04 \n"); + 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 -// +// +// Segmentation is defined by rectangular modules approximating +// concentric circles as shown below // // PCB module size in cm - const Float_t dxPCB=40, dyPCB=40; + const Float_t kDxPCB=40, kDyPCB=40; // PCB distribution (7 rows with 1+3 segmentation regions) const Int_t kpcb[7][4] = {{1, 2, 2, 2}, {0, 3, 2, 2}, @@ -74,17 +74,17 @@ void AliMUONsegmentationV04::Init(AliMUONchamber* ) // // number of pad rows per PCB // - Int_t NpyPCB=Int_t(dyPCB/fDpy); + Int_t nPyPCB=Int_t(kDyPCB/fDpy); // // maximum number of pad rows - fNpy=7*NpyPCB; + 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]); + printf("\n test ---dx %d %f \n",i,fDpxD[i]); } } // @@ -95,38 +95,30 @@ void AliMUONsegmentationV04::Init(AliMUONchamber* ) for (Int_t irow=0; irow<7; irow++) { // // loop over pads along the anode wires - for (Int_t i=0; i<=NpyPCB; i++) { + 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; + fNpxS[0][iy]=kpcb[irow][0]*Int_t(kDxPCB/fDpxD[0]); + fCx[0][iy]=kpcb[irow][0]*kDxPCB; } else { fNpxS[isec][iy]=fNpxS[isec-1][iy] - +kpcb[irow][isec]*Int_t(dxPCB/fDpxD[isec]); + +kpcb[irow][isec]*Int_t(kDxPCB/fDpxD[isec]); fCx[isec][iy]=fCx[isec-1][iy] - +kpcb[irow][isec]*dxPCB; + +kpcb[irow][isec]*kDxPCB; } } // 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) +void AliMUONSegmentationV04::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) { +// Returns test point on the pad plane. +// Used during determination of the segmoid correction of the COG-method n=3; x[0]=(fCx[1][1]+fCx[0][1])/2/TMath::Sqrt(2.); y[0]=x[0]; @@ -134,9 +126,6 @@ void AliMUONsegmentationV04::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) y[1]=x[1]; x[2]=(fCx[3][1]+fCx[2][1])/2/TMath::Sqrt(2.); y[2]=x[2]; - printf("\n 1%f %f", x[0], y[0]); - printf("\n 2%f %f", x[1], y[1]); - printf("\n 3%f %f\n ", x[2], y[2]); } diff --git a/MUON/AliMUONSegmentationV04.h b/MUON/AliMUONSegmentationV04.h new file mode 100644 index 00000000000..a2379b742fd --- /dev/null +++ b/MUON/AliMUONSegmentationV04.h @@ -0,0 +1,33 @@ +#ifndef ALIMUONSEGMENTATIONV04_H +#define ALIMUONSEGMENTATIONV04_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +///////////////////////////////////////////////////// +// Segmentation and Response classes version 04 // +///////////////////////////////////////////////////// + +#include "AliMUONSegmentationV01.h" + +class AliMUONSegmentationV04 : +public AliMUONSegmentationV01 { + public: + AliMUONSegmentationV04(){} + virtual ~AliMUONSegmentationV04(){} + // Initialisation + virtual void Init(AliMUONChamber* chamber); + // Test points for auto calibration + void GiveTestPoints(Int_t &n, Float_t *x, Float_t *y); + ClassDef(AliMUONSegmentationV04,1) // Segmentation zones are rectangular modules +}; + + +#endif + + + + + + diff --git a/MUON/AliMUONSegResV05.cxx b/MUON/AliMUONSegmentationV05.cxx similarity index 78% rename from MUON/AliMUONSegResV05.cxx rename to MUON/AliMUONSegmentationV05.cxx index 7e91a0449e7..fedb24408a8 100644 --- a/MUON/AliMUONSegResV05.cxx +++ b/MUON/AliMUONSegmentationV05.cxx @@ -15,36 +15,35 @@ /* $Log$ +Revision 1.1.2.1 2000/06/09 21:38:46 morsch +AliMUONSegmentationV05 code from AliMUONSegResV05.cxx + */ ///////////////////////////////////////////////////// -// Segmentation and Response classes version 04 // +// Segmentation and Response classes version 05 // ///////////////////////////////////////////////////// -#include -#include -#include - -#include "AliMUONSegResV05.h" -#include "AliRun.h" -#include "AliMC.h" -#include "iostream.h" +#include "AliMUONSegmentationV05.h" +#include //___________________________________________ -ClassImp(AliMUONsegmentationV05) +ClassImp(AliMUONSegmentationV05) -void AliMUONsegmentationV05::Init(AliMUONchamber* ) +void AliMUONSegmentationV05::Init(AliMUONChamber* Chamber) { - //printf("\n Initialise segmentation v05 \n"); + 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 // +// Segmentation is defined by rectangular modules approximating +// concentric circles as shown below // // PCB module size in cm - const Float_t dxPCB=40, dyPCB=40; + const Float_t kDxPCB=40, kDyPCB=40; // PCB distribution (7 rows with 1+3 segmentation regions) const Int_t kpcb[7][4] = {{1, 2, 2, 2}, {0, 3, 2, 2}, @@ -74,17 +73,17 @@ void AliMUONsegmentationV05::Init(AliMUONchamber* ) // // number of pad rows per PCB // - Int_t NpyPCB=Int_t(dyPCB/fDpy); + Int_t nPyPCB=Int_t(kDyPCB/fDpy); // // maximum number of pad rows - fNpy=7*NpyPCB; + 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]); + printf("\n test ---dx %d %f \n",i,fDpxD[i]); } } // @@ -95,20 +94,20 @@ void AliMUONsegmentationV05::Init(AliMUONchamber* ) for (Int_t irow=0; irow<7; irow++) { // // loop over pads along the anode wires - for (Int_t i=0; i<=NpyPCB; i++) { + 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; + fNpxS[0][iy]=kpcb[irow][0]*Int_t(kDxPCB/fDpxD[0]); + fCx[0][iy]=kpcb[irow][0]*kDxPCB; } else { fNpxS[isec][iy]=fNpxS[isec-1][iy] - +kpcb[irow][isec]*Int_t(dxPCB/fDpxD[isec]); + +kpcb[irow][isec]*Int_t(kDxPCB/fDpxD[isec]); fCx[isec][iy]=fCx[isec-1][iy] - +kpcb[irow][isec]*dxPCB; + +kpcb[irow][isec]*kDxPCB; } } // sectors } // pad raws in module @@ -125,15 +124,13 @@ void AliMUONsegmentationV05::Init(AliMUONchamber* ) */ } -void AliMUONsegmentationV05::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) +void AliMUONSegmentationV05::GiveTestPoints(Int_t &n, Float_t *x, Float_t *y) { +// Returns test point on the pad plane. +// Used during determination of the segmoid correction of the COG-method n=1; x[0]=(fCx[1][1]+fCx[0][1])/2/TMath::Sqrt(2.); y[0]=x[0]; -// x[1]=(fCx[2][1]+fCx[1][1])/2; -// y[1]=x[1]; -// x[2]=(fCx[3][1]+fCx[2][1])/2; -// y[2]=x[2]; } diff --git a/MUON/AliMUONSegmentationV05.h b/MUON/AliMUONSegmentationV05.h new file mode 100644 index 00000000000..6623f30b595 --- /dev/null +++ b/MUON/AliMUONSegmentationV05.h @@ -0,0 +1,31 @@ +#ifndef ALIMUONSEGMENTATIONV05_H +#define ALIMUONSEGMENTATIONV05_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +///////////////////////////////////////////////////// +// Segmentation and Response classes version 05 // +///////////////////////////////////////////////////// + +#include "AliMUONSegmentationV02.h" + +class AliMUONSegmentationV05 : +public AliMUONSegmentationV02 { + public: + AliMUONSegmentationV05(){} + virtual ~AliMUONSegmentationV05(){} + // Initialisation + virtual void Init(AliMUONChamber* chamber); + // Test points for auto calibration + void GiveTestPoints(Int_t &n, Float_t *x, Float_t *y); + ClassDef(AliMUONSegmentationV05,1)// Segmentation zones are rectangular modules +}; +#endif + + + + + + diff --git a/MUON/AliMUONSegmentationV1.cxx b/MUON/AliMUONSegmentationV1.cxx new file mode 100644 index 00000000000..f9d08d492f8 --- /dev/null +++ b/MUON/AliMUONSegmentationV1.cxx @@ -0,0 +1,545 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.2 2000/06/12 07:57:43 morsch +include TMath.cxx + +Revision 1.1.2.1 2000/06/09 21:41:29 morsch +AliMUONSegmentationV1 code from AliMUONSegResV1.cxx + +*/ + + +///////////////////////////////////////////////////////// +// Manager and hits classes for set:MUON version LYON // +///////////////////////////////////////////////////////// + +#include +#include "AliMUONChamber.h" +#include "AliMUONSegmentationV1.h" + +//___________________________________________ +ClassImp(AliMUONSegmentationV1) + +AliMUONSegmentationV1::AliMUONSegmentationV1(const AliMUONSegmentationV1& segmentation) +{ +// Dummy copy constructor +} + + +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) +{ +// Set the default cuts + 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) +{ +// Get anode number + Int_t kwire=Int_t((TMath::Abs(xhit)-fSensOffset)/fDAnod)+1; + return (xhit>0) ? kwire : -kwire ; +} + +Float_t AliMUONSegmentationV1::GetAnod(Float_t xhit) +{ +// Get anode position + 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 ; +} + + +void AliMUONSegmentationV1::SetPadSize(Float_t p1, Float_t p2) +{ +// For chamber T5/6 p1 and p2 should be same for each zone + 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) +{ +// Get segmentation zone + Int_t iX, iY; + GetPadIxy(X,Y,iX,iY); + return GetZone( iX , iY ); +} + +Int_t AliMUONSegmentationV1::GetZone(Int_t nX, Int_t nY) +{ +// Beware : first pad begins at 1 !! + Int_t aX = TMath::Abs(nX); + Int_t aY = TMath::Abs(nY); + Int_t zone=fNzone-1; + for (Int_t iZone=fNzone-2;iZone>=0;iZone--) + { + for (Int_t iCut=0;iCut frSensMax2 || radius2 < frSensMin2 ) + && MorePads() ) + NextPad(); +} + +void AliMUONSegmentationV1::FirstPad(Float_t xhit, Float_t yhit, Float_t dx, Float_t dy) +{ + // + // Find the wire position (center of charge distribution) + Float_t x0a=GetAnod(xhit); + fxhit=x0a; + fyhit=yhit; + // + // and take fNsigma*sigma around this center + Float_t x01=x0a - dx; + Float_t x02=x0a + dx; + Float_t y01=yhit - dy; + Float_t y02=yhit + dy; + + // Do not cross over frames... + if (x01 * x0a < 0) + x01 = TMath::Sign(fSensOffset, x0a); + if (x02 * x0a < 0) + x02 = TMath::Sign(fSensOffset, x0a); + if (y01 * yhit < 0) + y01 = TMath::Sign(fSensOffset, yhit); + if (y02 * yhit < 0) + y02 = TMath::Sign(fSensOffset, yhit); + // + // find the pads over which the charge distributes + GetPadIxy(x01,y01,fixmin,fiymin); + GetPadIxy(x02,y02,fixmax,fiymax); + // + // Set current pad to lower left corner + fix=fixmin; + fiy=fiymin; + SetPadCoord(fix,fiy); +} + +void AliMUONSegmentationV1::NextPad() +{ + // + // Step to next pad in integration region + if (fix != fixmax) { + fix++; + } else if (fiy != fiymax) { + fix=fixmin; + fiy++; + } else + printf("\n Error: Stepping outside integration region\n "); + SetPadCoord(fix,fiy); +} + +Int_t AliMUONSegmentationV1::MorePads() +{ +// +// Are there more pads in the integration region + + if (fix == fixmax && fiy == fiymax) { + return 0; + } else { + return 1; + } +} + +Int_t AliMUONSegmentationV1::IsParallel2(Int_t iX, Int_t iY) +{ +// test if the pad is read in parallel for zone 2 +// iX and iY are assumed to be positive and starting at 0 numbering (cF. iX) +// returns 1 or 2 if read in parallel, +// according to the actual number in the chain, 0 else +// +// chainage is result is +// 1 2 3 1 2 3 1 1 1 2 2 2 y +// 7 8 9 10 11 12 0 0 0 0 0 0 ^ +// 4 5 6 4 5 6 1 1 1 2 2 2 +->x +// + + if (iY%3==1) return 0; + return (iX%6)/3+1; +} + +Int_t AliMUONSegmentationV1::IsParallel3(Int_t iX, Int_t iY) +{ +// test if the pad is read in parallel for zone 3 +// iX and iY are assumed to be positive and starting at 0 numbering (cF. iX) +// returns 1,2 or 3 if read in parallel, +// according to the actual number in the chain, 0 else +// +// chainage is result is +//16 2 3 1 2 3 1 2 3 0 1 1 1 2 2 2 3 3 +// 7 8 9 10 11 12 13 14 15 0 0 0 0 0 0 0 0 0 +// 4 5 6 4 5 6 4 5 6 1 1 1 2 2 2 3 3 3 +// + + if (iY%3==1) return 0; + return (iX%9)/3+1 - (iY%3==2 && iX%3==0); +} + +Int_t AliMUONSegmentationV1::NParallel2(Int_t iX, Int_t iY) +{ +// returns the number of pads connected in parallel for zone 2 +// iX and iY are assumed to be positive and starting at 0 numbering (cF. iX) +// +// result is +// 2 2 2 2 2 2 +// 1 1 1 1 1 1 +// 2 2 2 2 2 2 +// + + if (iY%3==1) return 1; + return 2; +} + +Int_t AliMUONSegmentationV1::NParallel3(Int_t iX, Int_t iY) +{ +// test if the pad is read in parallel for zone 3 +// iX and iY are assumed to be positive and starting at 0 numbering (cF. iX) +// returns 1,2 or 3 if read in parallel, +// according to the actual number in the chain, 0 else +// +// result is +// 1 3 3 2 3 3 2 3 3 +// 1 1 1 1 1 1 1 1 1 +// 3 3 3 3 3 3 3 3 3 +// + + if (iY%3==1) return 1; + if (iY%3==2 && iX%9==0) return 1; + return 3 - (iY%3==2 && iX%3==0); +} + + +Int_t AliMUONSegmentationV1::Ix(Int_t trueX, Int_t trueY) +{ +// returns the X number of pad which corresponds to the logical +// channel, expressed in x and y. + + Int_t wix = TMath::Abs(trueX)-1; + Int_t wiy = TMath::Abs(trueY)-1; + Int_t zone = GetZone(trueX,trueY); + Int_t par3; + switch (zone) { + case 0: return trueX; + case 1: + if (IsParallel2(wix,wiy) == 2) + return (trueX>0)? trueX-3 : trueX+3 ; + return trueX; + case 2: + if ( (par3= IsParallel3(wix,wiy)) ) + return (trueX>0) ? trueX-3*(par3-1) : trueX+3*(par3-1) ; + return trueX ; + default : + printf("Couille dans AliMUONSegmentationV1::ix\n"); + } + return -1; +} + +Int_t AliMUONSegmentationV1::Ix() +{ +// returns the X number of pad which has to increment charge +// due to parallel read-out +return Ix(fix,fiy); +} + +Int_t AliMUONSegmentationV1::ISector() +{ +// This function is of no use for this kind of segmentation. + return GetZone(fix,fiy); +} + +void AliMUONSegmentationV1::SigGenInit(Float_t x,Float_t y,Float_t z) +{ +// +// Initialises pad and wire position during stepping + fxt =x; + fyt =y; + GetPadIxy(x,y,fixt,fiyt); + fiwt= GetiAnod(x); + +} + +Int_t AliMUONSegmentationV1::SigGenCond(Float_t x,Float_t y,Float_t z) +{ +// +// Signal will be generated if particle crosses pad boundary or +// boundary between two wires. + Int_t ixt; + Int_t iyt; + GetPadIxy(x,y,ixt,iyt); + Int_t iwt= GetiAnod(x); + + if ((ixt != fixt) || (iyt !=fiyt) || (iwt != fiwt)) { + return 1; + } else { + return 0; + } +} + +void AliMUONSegmentationV1:: +IntegrationLimits(Float_t& x1,Float_t& x2,Float_t& y1, Float_t& y2) +{ +// Get integration limits + 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) +{ +// Get parallel pad + Int_t wix = TMath::Abs(iX)-1; + Int_t wiy = TMath::Abs(iY)-1; + Int_t zone = GetZone(iX,iY); + switch (zone) { + case 0: + *Nparallel=1; + *Offset=0; + break; + case 1: + *Nparallel = NParallel2(wix,wiy); + (iX>0) ? *Offset =3 : *Offset = -3; + if (IsParallel2(wix,wiy)>1) + printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n"); + break; + case 2: + *Nparallel = NParallel3(wix,wiy); + (iX>0) ? *Offset =3 : *Offset = -3; + if (IsParallel3(wix,wiy)>1) + printf("GetNParallelAndOffset called for existing channel -> answer is crazy\n"); + break; + } +} + + +Float_t AliMUONSegmentationV1::Distance2AndOffset(Int_t iX, Int_t iY, Float_t X, Float_t Y, Int_t *Offset) +{ +// +// Computes the offset for which the physical pad has the minimum distance squared +// (returned value) to the given coordinates + + Int_t nPara,offset; + GetNParallelAndOffset(iX,iY,&nPara,&offset); + Float_t d2min=1E10; + for (Int_t i=0;i d2) + { + d2min = d2; + *Offset = i*offset; + } + } + return d2min; +} + +void AliMUONSegmentationV1::CleanNeighbours(Int_t* Nlist, Int_t *Xlist, + Int_t *Ylist) +{ +// In the raw neighbours list, some pads do not exist +// and some others are read in parallel ... +// So we prune non-existing neighbours from the list (event if this should be +// at last not be a problem due to the clustering algorithm...) + + Int_t nTot=0; + for (Int_t nList=0;nList<*Nlist;nList++) + { + // prune if it does not exist + if ( Xlist[nList]==0 || Ylist[nList]==0 ) + continue; + // compute true position + Xlist[nTot] = Ix(Xlist[nList],Ylist[nList]) ; + Ylist[nTot] = Ylist[nList] ; + // and prune if it does already exist + Int_t nTest; + for (nTest=0;nTest1) { + Xlist[4]=Xlist[5]=iX+offset;Xlist[6]=iX+offset-1;Xlist[7]=iX+offset+1; + Ylist[4]=iY-1;Ylist[5]=iY+1;Ylist[6]=Ylist[7]=iY; + if (nParallel>2) { + Xlist[8]=Xlist[9]=iX+2*offset;Xlist[10]=iX+2*offset-1;Xlist[11]=iX+2*offset+1; + Ylist[8]=iY-1;Ylist[9]=iY+1;Ylist[10]=Ylist[11]=iY; + } + } + CleanNeighbours(Nlist,Xlist,Ylist); +} + +void AliMUONSegmentationV1:: +NeighboursDiag(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[24], Int_t Ylist[24]) +{ +// returns the X number of pad which has to increment charge +// due to parallel read-out + + Int_t nParallel, offset; + GetNParallelAndOffset(iX,iY,&nParallel,&offset); +// +// now fill raw list of neighbours + *Nlist=0; + for (Int_t i=0;i -#include -#include "TVirtualPad.h" -ClassImp(AliMUONTUBE) - -AliMUONTUBE::AliMUONTUBE():TTUBE() -{;} - -//_____________________________________________________________________________ - -AliMUONTUBE::AliMUONTUBE(Text_t *name, Text_t *title, Text_t *material, Float_t rmin, - Float_t rmax, Float_t dz,Float_t aspect): - TTUBE(name, title, material, rmin, rmax, dz, aspect) -{} - -//______________________________________________________________________________ - AliMUONTUBE::AliMUONTUBE(Text_t *name, Text_t *title, Text_t *material, Float_t rmax, - Float_t dz) - : TTUBE(name, title, material, rmax, dz) -{ -} - -//______________________________________________________________________________ - void AliMUONTUBE::Paint(Option_t *option) -{ -//*-*-*-*-*-*-*-*Paint this 3-D shape with its current attributes*-*-*-*-*-*-*-* -//*-* ================================================ - - Int_t i, j; - Int_t n = GetNumberOfDivisions(); - const Int_t numpoints = 4*n; - -//*-* Allocate memory for points *-* - - Float_t *points = new Float_t[3*numpoints]; - if (!points) return; - - SetPoints(points); - - if (gPad->GetView3D()) PaintGLPoints(points); - -//== for (i = 0; i < numpoints; i++) -//== gNode->Local2Master(&points[3*i],&points[3*i]); - - X3DBuffer *buff = new X3DBuffer; - if (buff) { - buff->numPoints = numpoints; - buff->numSegs = n*6; - if (strstr(option, "x3d")) buff->numSegs = n*8; - buff->numPolys = n*4; - } - -//*-* Allocate memory for points *-* - - buff->points = points; - - Int_t c = ((GetLineColor() % 8) - 1) * 4; // Basic colors: 0, 1, ... 7 - if (c < 0) c = 0; - -//*-* Allocate memory for segments *-* - - buff->segs = new Int_t[buff->numSegs*3]; - if (buff->segs) { - for (i = 0; i < 4; i++) { - for (j = 0; j < n; j++) { - buff->segs[(i*n+j)*3 ] = c; - buff->segs[(i*n+j)*3+1] = i*n+j; - buff->segs[(i*n+j)*3+2] = i*n+j+1; - } - buff->segs[(i*n+j-1)*3+2] = i*n; - } - for (i = 4; i < 6; i++) { - for (j = 0; j < n; j++) { - buff->segs[(i*n+j)*3 ] = c+1; - buff->segs[(i*n+j)*3+1] = (i-4)*n+j; - buff->segs[(i*n+j)*3+2] = (i-2)*n+j; - } - } - if (strstr(option, "x3d")) - { - for (i = 6; i < 8; i++) { - for (j = 0; j < n; j++) { - buff->segs[(i*n+j)*3 ] = c; - buff->segs[(i*n+j)*3+1] = 2*(i-6)*n+j; - buff->segs[(i*n+j)*3+2] = (2*(i-6)+1)*n+j; - } - } - } - } -//*-* Allocate memory for polygons *-* - - Int_t indx = 0; - - buff->polys = new Int_t[buff->numPolys*6]; - if (buff->polys) { - for (i = 0; i < 2; i++) { - for (j = 0; j < n; j++) { - indx = 6*(i*n+j); - buff->polys[indx ] = c; - buff->polys[indx+1] = 4; - buff->polys[indx+2] = i*n+j; - buff->polys[indx+3] = (4+i)*n+j; - buff->polys[indx+4] = (2+i)*n+j; - buff->polys[indx+5] = (4+i)*n+j+1; - } - buff->polys[indx+5] = (4+i)*n; - } - for (i = 2; i < 4; i++) { - for (j = 0; j < n; j++) { - indx = 6*(i*n+j); - buff->polys[indx ] = c+(i-2)*2+1; - buff->polys[indx+1] = 4; - buff->polys[indx+2] = (i-2)*2*n+j; - buff->polys[indx+3] = (4+i)*n+j; - buff->polys[indx+4] = ((i-2)*2+1)*n+j; - buff->polys[indx+5] = (4+i)*n+j+1; - } - buff->polys[indx+5] = (4+i)*n; - } - } - - //*-* Paint in the pad - Bool_t rangeView = strcmp(option,"range")==0 ? kTRUE : kFALSE; - PaintShape(buff,rangeView); - - if (strstr(option, "x3d")) { - if(buff && buff->points && buff->segs) - FillX3DBuffer(buff); - else { - gSize3D.numPoints -= buff->numPoints; - gSize3D.numSegs -= buff->numSegs; - gSize3D.numPolys -= buff->numPolys; - } - } - - if (buff->points) delete [] buff->points; - if (buff->segs) delete [] buff->segs; - if (buff->polys) delete [] buff->polys; - if (buff) delete buff; -} - diff --git a/MUON/AliMUONTUBE.h b/MUON/AliMUONTUBE.h deleted file mode 100644 index 2bfcdbdb082..00000000000 --- a/MUON/AliMUONTUBE.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef AliMUONTube_H -#define AliMUONTube_H -/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * See cxx source for full Copyright notice */ - -/* $Id$ */ - -//////////////////////////////////////////////// -// Manager and hits classes for set:MUON // -//////////////////////////////////////////////// -#include "TTUBE.h" - -class AliMUONTUBE : -public TTUBE { - - public: - AliMUONTUBE(); - AliMUONTUBE(Text_t *name, Text_t *title, Text_t *material, Float_t rmin, Float_t rmax, Float_t dz,Float_t aspect); - AliMUONTUBE(Text_t *name, Text_t *title, Text_t *material, Float_t rmax, Float_t dz); - virtual ~AliMUONTUBE(){}; - virtual void Paint(Option_t* option); - ClassDef(AliMUONTUBE,1) -}; -#endif diff --git a/MUON/AliMUONTrack.cxx b/MUON/AliMUONTrack.cxx new file mode 100644 index 00000000000..8a74b212d6a --- /dev/null +++ b/MUON/AliMUONTrack.cxx @@ -0,0 +1,311 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.3 2000/06/12 10:11:34 morsch +Dummy copy constructor and assignment operator added + +Revision 1.1.2.2 2000/06/09 12:58:05 gosset +Removed comment beginnings in Log sections of .cxx files +Suppressed most violations of coding rules + +Revision 1.1.2.1 2000/06/07 14:44:53 gosset +Addition of files for track reconstruction in C++ +*/ + +//__________________________________________________________________________ +// +// Reconstructed track in ALICE dimuon spectrometer +//__________________________________________________________________________ + +#include "AliMUONTrack.h" + +#include + +#include +#include + +#include "AliMUONEventReconstructor.h" +#include "AliMUONHitForRec.h" +#include "AliMUONSegment.h" +#include "AliMUONTrackHit.h" + +static AliMUONTrack *trackBeingFitted; +static AliMUONTrackParam *trackParamBeingFitted; + +// Function to be minimized with Minuit +void TrackChi2(Int_t &NParam, Double_t *Gradient, Double_t &Chi2, Double_t *Param, Int_t Flag); + +ClassImp(AliMUONTrack) // Class implementation in ROOT context + + //__________________________________________________________________________ +AliMUONTrack::AliMUONTrack(AliMUONSegment* BegSegment, AliMUONSegment* EndSegment, AliMUONEventReconstructor* EventReconstructor) +{ + // Constructor from two Segment's + fEventReconstructor = EventReconstructor; // link back to EventReconstructor + // memory allocation for the TClonesArray of reconstructed TrackHit's + fTrackHitsPtr = new TClonesArray("AliMUONTrackHit", 10); + fNTrackHits = 0; + AddSegment(BegSegment); // add hits from BegSegment + AddSegment(EndSegment); // add hits from EndSegment + fTrackHitsPtr->Sort(); // sort TrackHits according to increasing Z + SetTrackParamAtVertex(); // set track parameters at vertex + return; +} + + //__________________________________________________________________________ +AliMUONTrack::AliMUONTrack(AliMUONSegment* Segment, AliMUONHitForRec* HitForRec, AliMUONEventReconstructor* EventReconstructor) +{ + // Constructor from one Segment and one HitForRec + fEventReconstructor = EventReconstructor; // link back to EventReconstructor + // memory allocation for the TClonesArray of reconstructed TrackHit's + fTrackHitsPtr = new TClonesArray("AliMUONTrackHit", 10); + fNTrackHits = 0; + AddSegment(Segment); // add hits from Segment + AddHitForRec(HitForRec); // add HitForRec + fTrackHitsPtr->Sort(); // sort TrackHits according to increasing Z + SetTrackParamAtVertex(); // set track parameters at vertex + return; +} + +AliMUONTrack::AliMUONTrack (const AliMUONTrack& MUONTrack) +{ +// Dummy copy constructor +} + +AliMUONTrack & AliMUONTrack::operator=(const AliMUONTrack& MUONTrack) +{ +// Dummy assignment operator + return *this; +} + +// Inline functions for Get and Set: inline removed because it does not work !!!! +AliMUONTrackParam* AliMUONTrack::GetTrackParamAtVertex(void) { + // Get pointer to fTrackParamAtVertex + return &fTrackParamAtVertex;} +AliMUONTrackParam* AliMUONTrack::GetTrackParamAtFirstHit(void) { + // Get pointer to TrackParamAtFirstHit + return ((AliMUONTrackHit*) (fTrackHitsPtr->First()))->GetTrackParam();} +TClonesArray* AliMUONTrack::GetTrackHitsPtr(void) { + // Get fTrackHitsPtr + return fTrackHitsPtr;} +Int_t AliMUONTrack::GetNTrackHits(void) { + // Get fNTrackHits + return fNTrackHits;} + + //__________________________________________________________________________ +void AliMUONTrack::RecursiveDump(void) +{ + // Recursive dump of AliMUONTrack, i.e. with dump of TrackHit's and HitForRec's + AliMUONTrackHit *trackHit; + AliMUONHitForRec *hitForRec; + cout << "Recursive dump of Track: " << this << endl; + // Track + this->Dump(); + for (Int_t trackHitIndex = 0; trackHitIndex < fNTrackHits; trackHitIndex++) { + trackHit = (AliMUONTrackHit*) ((*fTrackHitsPtr)[trackHitIndex]); + // TrackHit + cout << "TrackHit: " << trackHit << " (index: " << trackHitIndex << ")" << endl; + trackHit->Dump(); + hitForRec = trackHit->GetHitForRecPtr(); + // HitForRec + cout << "HitForRec: " << hitForRec << endl; + hitForRec->Dump(); + } + return; +} + + //__________________________________________________________________________ +void AliMUONTrack::Fit(AliMUONTrackParam *TrackParam, Int_t NParam) +{ + // Fit the current track ("this"), + // starting with track parameters pointed to by "TrackParam", + // and with 3 or 5 parameters ("NParam"): + // 3 if one keeps X and Y fixed in "TrackParam", + // 5 if one lets them vary. + if ((NParam != 3) && (NParam != 5)) { + cout << "ERROR in AliMUONTrack::Fit, NParam = " << NParam; + cout << " , i.e. neither 3 nor 5 ====> EXIT" << endl; + exit(0); // right instruction for exit ???? + } + Int_t error = 0; + Double_t arg[1], benC, errorParam, invBenP, lower, nonBenC, upper, x, y; + TString parName; + TMinuit *minuit = new TMinuit(5); + trackBeingFitted = this; // for the track to be known from the function to minimize + trackParamBeingFitted = TrackParam; // for the track parameters to be known from the function to minimize; possible to use only Minuit parameters ???? + minuit->mninit(5, 10, 7); // sysrd, syswr, syssa: useful ???? + // how to go faster ???? choice of Minuit parameters like EDM ???? + minuit->SetFCN(TrackChi2); + minuit->SetPrintLevel(1); // More printing !!!! + // set first 3 parameters (try with no limits for the search: min=max=0) + minuit->mnparm(0, "InvBenP", + TrackParam->GetInverseBendingMomentum(), + 0.003, 0.0, 0.0, error); + minuit->mnparm(1, "BenS", + TrackParam->GetBendingSlope(), + 0.001, 0.0, 0.0, error); + minuit->mnparm(2, "NonBenS", + TrackParam->GetNonBendingSlope(), + 0.001, 0.0, 0.0, error); + if (NParam == 5) { + // set last 2 parameters (try with no limits for the search: min=max=0) + minuit->mnparm(3, "X", + TrackParam->GetNonBendingCoor(), + 0.03, 0.0, 0.0, error); + minuit->mnparm(4, "Y", + TrackParam->GetBendingCoor(), + 0.10, 0.0, 0.0, error); + } + // search without gradient calculation in the function + minuit->mnexcm("SET NOGRADIENT", arg, 0, error); + // minimization + minuit->mnexcm("MINIMIZE", arg, 0, error); + // exit from Minuit + minuit->mnexcm("EXIT", arg, 0, error); // necessary ???? + // print results + minuit->mnpout(0, parName, invBenP, errorParam, lower, upper, error); + minuit->mnpout(1, parName, benC, errorParam, lower, upper, error); + minuit->mnpout(2, parName, nonBenC, errorParam, lower, upper, error); + if (NParam == 5) { + minuit->mnpout(3, parName, x, errorParam, lower, upper, error); + minuit->mnpout(4, parName, y, errorParam, lower, upper, error); + } + // result of the fit into track parameters + TrackParam->SetInverseBendingMomentum(invBenP); + TrackParam->SetBendingSlope(benC); + TrackParam->SetNonBendingSlope(nonBenC); + if (NParam == 5) { + TrackParam->SetNonBendingCoor(x); + TrackParam->SetBendingCoor(y); + } + trackBeingFitted = NULL; + delete minuit; +} + + //__________________________________________________________________________ +void AliMUONTrack::AddSegment(AliMUONSegment* Segment) +{ + // Add Segment + AddHitForRec(Segment->GetHitForRec1()); // 1st hit + AddHitForRec(Segment->GetHitForRec2()); // 2nd hit +} + + //__________________________________________________________________________ +void AliMUONTrack::AddHitForRec(AliMUONHitForRec* HitForRec) +{ + // Add HitForRec + new ((*fTrackHitsPtr)[fNTrackHits]) AliMUONTrackHit(HitForRec); + fNTrackHits++; +} + + //__________________________________________________________________________ +void AliMUONTrack::SetTrackParamAtHit(Int_t indexHit, AliMUONTrackParam *TrackParam) +{ + // Set track parameters at TrackHit with index "indexHit" + // from the track parameters pointed to by "TrackParam". + AliMUONTrackHit* trackHit = (AliMUONTrackHit*) ((*fTrackHitsPtr)[indexHit]); + trackHit->SetTrackParam(TrackParam); +} + + //__________________________________________________________________________ +void AliMUONTrack::SetTrackParamAtVertex() +{ + // Set track parameters at vertex. + // TrackHit's are assumed to be only in stations(1..) 4 and 5, + // and sorted according to increasing Z.. + // Parameters are calculated from information in HitForRec's + // of first and last TrackHit's. + AliMUONTrackParam *trackParam = + &fTrackParamAtVertex; // pointer to track parameters + // Pointer to HitForRec of first TrackHit + AliMUONHitForRec *firstHit = + ((AliMUONTrackHit*) (fTrackHitsPtr->First()))->GetHitForRecPtr(); + // Pointer to HitForRec of last TrackHit + AliMUONHitForRec *lastHit = + ((AliMUONTrackHit*) (fTrackHitsPtr->Last()))->GetHitForRecPtr(); + // Z difference between first and last hits + Double_t deltaZ = firstHit->GetZ() - lastHit->GetZ(); + // bending slope in stations(1..) 4 and 5 + Double_t bendingSlope = + (firstHit->GetBendingCoor() - lastHit->GetBendingCoor()) / deltaZ; + trackParam->SetBendingSlope(bendingSlope); + // impact parameter + Double_t impactParam = + firstHit->GetBendingCoor() - bendingSlope * firstHit->GetZ(); // same if from firstHit and lastHit ???? + // signed bending momentum + Double_t signedBendingMomentum = + fEventReconstructor->GetBendingMomentumFromImpactParam(impactParam); + trackParam->SetInverseBendingMomentum(1.0 / signedBendingMomentum); + // bending slope at vertex + trackParam-> + SetBendingSlope(bendingSlope + + impactParam / fEventReconstructor->GetSimpleBPosition()); + // non bending slope + Double_t nonBendingSlope = + (firstHit->GetNonBendingCoor() - lastHit->GetNonBendingCoor()) / deltaZ; + trackParam->SetNonBendingSlope(nonBendingSlope); + // vertex coordinates at (0,0,0) + trackParam->SetZ(0.0); + trackParam->SetBendingCoor(0.0); + trackParam->SetNonBendingCoor(0.0); +} + + //__________________________________________________________________________ +void TrackChi2(Int_t &NParam, Double_t *Gradient, Double_t &Chi2, Double_t *Param, Int_t Flag) +{ + // Return the "Chi2" to be minimized with Minuit for track fitting, + // with "NParam" parameters + // and their current values in array pointed to by "Param". + // Assumes that the track hits are sorted according to increasing Z. + // Track parameters at each TrackHit are updated accordingly. + AliMUONTrackHit* hit; + AliMUONTrackParam param1; + Int_t hitNumber; + Double_t zHit; + Chi2 = 0.0; // initialize Chi2 + // copy of track parameters to be fitted + param1 = *trackParamBeingFitted; + // Minuit parameters to be fitted into this copy + param1.SetInverseBendingMomentum(Param[0]); + param1.SetBendingSlope(Param[1]); + param1.SetNonBendingSlope(Param[2]); + if (NParam == 5) { + param1.SetNonBendingCoor(Param[3]); + param1.SetBendingCoor(Param[4]); + } + // Follow track through all planes of track hits + for (hitNumber = 0; hitNumber < trackBeingFitted->GetNTrackHits(); hitNumber++) { + hit = (AliMUONTrackHit*) (*(trackBeingFitted->GetTrackHitsPtr()))[hitNumber]; + zHit = hit->GetHitForRecPtr()->GetZ(); + // do something special if 2 hits with same Z ???? + // security against infinite loop ???? + (¶m1)->ExtrapToZ(zHit); // extrapolation + hit->SetTrackParam(¶m1); + // Increment Chi2 + // done hit per hit, with hit resolution, + // and not with point and angle like in "reco_muon.F" !!!! + // Needs to add multiple scattering contribution ???? + Double_t dX = + hit->GetHitForRecPtr()->GetNonBendingCoor() - (¶m1)->GetNonBendingCoor(); + Double_t dY = + hit->GetHitForRecPtr()->GetBendingCoor() - (¶m1)->GetBendingCoor(); + Chi2 = + Chi2 + + dX * dX / hit->GetHitForRecPtr()->GetNonBendingReso2() + + dY * dY / hit->GetHitForRecPtr()->GetBendingReso2(); + } +} diff --git a/MUON/AliMUONTrack.h b/MUON/AliMUONTrack.h new file mode 100644 index 00000000000..b528237fb18 --- /dev/null +++ b/MUON/AliMUONTrack.h @@ -0,0 +1,54 @@ +#ifndef ALIMUONTRACK_H +#define ALIMUONTRACK_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/*$Id$*/ + +#include +#include +#include "AliMUONTrackHit.h" +#include "AliMUONTrackParam.h" + +class TClonesArray; +class AliMUONEventReconstructor; +class AliMUONHitForRec; +class AliMUONSegment; + +class AliMUONTrack : public TObject { + public: + AliMUONTrack(){ + // Constructor + ;} // Constructor + virtual ~AliMUONTrack(){ + // Destructor + ;} // Destructor + AliMUONTrack (const AliMUONTrack& AliMUONTrack); // copy constructor + AliMUONTrack& operator=(const AliMUONTrack& AliMUONTrack); // assignment operator + + AliMUONTrack(AliMUONSegment* BegSegment, AliMUONSegment* EndSegment, AliMUONEventReconstructor* EventReconstructor); // Constructor from two Segment's + AliMUONTrack(AliMUONSegment* Segment, AliMUONHitForRec* HitForRec, AliMUONEventReconstructor* EventReconstructor); // Constructor from one Segment and one HitForRec + + AliMUONTrackParam* GetTrackParamAtVertex(void); + void SetTrackParamAtVertex(void); + AliMUONTrackParam* GetTrackParamAtFirstHit(void); + TClonesArray* GetTrackHitsPtr(void); + Int_t GetNTrackHits(void); + + void RecursiveDump(void); // Recursive dump (with track hits) + void Fit(AliMUONTrackParam *TrackParam, Int_t NParam); // Fit + void AddSegment(AliMUONSegment* Segment); // Add Segment + void AddHitForRec(AliMUONHitForRec* HitForRec); // Add HitForRec + void SetTrackParamAtHit(Int_t indexHit, AliMUONTrackParam *TrackParam); + + protected: + private: + AliMUONEventReconstructor* fEventReconstructor; // Pointer to EventReconstructor + AliMUONTrackParam fTrackParamAtVertex; // Track parameters at vertex + TClonesArray *fTrackHitsPtr; // Pointer to array of TrackHit's + Int_t fNTrackHits; // Number of TrackHit's + + ClassDef(AliMUONTrack, 1) // Class definition in ROOT context + }; + +#endif diff --git a/MUON/AliMUONTrackHit.cxx b/MUON/AliMUONTrackHit.cxx new file mode 100644 index 00000000000..e9c37ab61ad --- /dev/null +++ b/MUON/AliMUONTrackHit.cxx @@ -0,0 +1,93 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.3 2000/06/12 10:11:45 morsch +Dummy copy constructor and assignment operator added + +Revision 1.1.2.2 2000/06/09 12:58:05 gosset +Removed comment beginnings in Log sections of .cxx files +Suppressed most violations of coding rules + +Revision 1.1.2.1 2000/06/07 14:44:53 gosset +Addition of files for track reconstruction in C++ +*/ + +//__________________________________________________________________________ +// +// Reconstructed track hit in ALICE dimuon spectrometer +//__________________________________________________________________________ + +#include "AliMUONTrackHit.h" + +#include "AliMUONHitForRec.h" + +ClassImp(AliMUONTrackHit) // Class implementation in ROOT context + + //__________________________________________________________________________ +AliMUONTrackHit::AliMUONTrackHit(AliMUONHitForRec* Hit) +{ + // Constructor from the HitForRec pointed to by "Hit" + fHitForRecPtr = Hit; // pointer to HitForRec + // links from/to HitForRec + if (Hit->GetNTrackHits() == 0) { + fPrevTrackHitWithSameHitForRec = NULL; + Hit->SetFirstTrackHitPtr(this); + } + else { + fPrevTrackHitWithSameHitForRec = Hit->GetLastTrackHitPtr(); + fNextTrackHitWithSameHitForRec = NULL; + } + Hit->SetLastTrackHitPtr(this); + fNextTrackHitWithSameHitForRec = NULL; + Hit->SetNTrackHits(Hit->GetNTrackHits() + 1); +} + + +AliMUONTrackHit::AliMUONTrackHit (const AliMUONTrackHit& MUONTrackHit) +{ +// Dummy copy constructor +} + +AliMUONTrackHit & AliMUONTrackHit::operator=(const AliMUONTrackHit& MUONTrackHit) +{ +// Dummy assignment operator + return *this; +} + +// Inline functions for Get and Set +inline AliMUONHitForRec* AliMUONTrackHit::GetHitForRecPtr(void) { + // Get fHitForRecPtr + return fHitForRecPtr;} +inline AliMUONTrackParam* AliMUONTrackHit::GetTrackParam(void) { + // Get pointer to fTrackParam + return &(fTrackParam);} +inline void AliMUONTrackHit::SetTrackParam(AliMUONTrackParam* TrackParam) { + // Set fTrackParam + fTrackParam = *TrackParam;} + + //__________________________________________________________________________ +Int_t AliMUONTrackHit::Compare(TObject* TrackHit) +{ + // "Compare" function to sort with increasing Z. + // Returns -1 (0, +1) if Z of current TrackHit + // is smaller than (equal to, larger than) Z of TrackHit + if (fHitForRecPtr->GetZ() < + ((AliMUONTrackHit*)TrackHit)->fHitForRecPtr->GetZ()) return(-1); + else if (fHitForRecPtr->GetZ() == + ((AliMUONTrackHit*)TrackHit)->fHitForRecPtr->GetZ()) return( 0); + else return(+1); +} diff --git a/MUON/AliMUONTrackHit.h b/MUON/AliMUONTrackHit.h new file mode 100644 index 00000000000..e175df9d60d --- /dev/null +++ b/MUON/AliMUONTrackHit.h @@ -0,0 +1,45 @@ +#ifndef ALIMUONTRACKHIT_H +#define ALIMUONTRACKHIT_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/*$Id$*/ + +#include +#include "AliMUONTrackParam.h" + +class AliMUONHitForRec; + +class AliMUONTrackHit : public TObject { + public: + AliMUONTrackHit(){ + // Constructor + ;} // Constructor + virtual ~AliMUONTrackHit(){ + // Destructor + ;} // Destructor + AliMUONTrackHit (const AliMUONTrackHit& AliMUONTrackHit); // copy constructor + AliMUONTrackHit& operator=(const AliMUONTrackHit& AliMUONTrackHit); // assignment operator + AliMUONTrackHit(AliMUONHitForRec* Hit); // Constructor from one HitForRec + + AliMUONHitForRec* GetHitForRecPtr(void); + AliMUONTrackParam* GetTrackParam(void); + void SetTrackParam(AliMUONTrackParam* TrackParam); + + // What is necessary for sorting TClonesArray's; sufficient too ???? + Bool_t IsSortable () const { + // necessary for sorting TClonesArray of TrackHit's + return kTRUE; } + Int_t Compare(TObject* TrackHit); // "Compare" function for sorting + + protected: + private: + AliMUONTrackParam fTrackParam; // Track parameters + AliMUONHitForRec *fHitForRecPtr; // Pointer to HitForRec + AliMUONTrackHit *fNextTrackHitWithSameHitForRec; // Pointer to next track hit with same HitForRec + AliMUONTrackHit *fPrevTrackHitWithSameHitForRec; // Pointer to previous track hit with same HitForRec + + ClassDef(AliMUONTrackHit, 1) // Class definition in ROOT context + }; + +#endif diff --git a/MUON/AliMUONTrackParam.cxx b/MUON/AliMUONTrackParam.cxx new file mode 100644 index 00000000000..e41ce1724fb --- /dev/null +++ b/MUON/AliMUONTrackParam.cxx @@ -0,0 +1,231 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.3 2000/06/09 21:03:09 morsch +Make includes consistent with new file structure. + +Revision 1.1.2.2 2000/06/09 12:58:05 gosset +Removed comment beginnings in Log sections of .cxx files +Suppressed most violations of coding rules + +Revision 1.1.2.1 2000/06/07 14:44:53 gosset +Addition of files for track reconstruction in C++ +*/ + +//__________________________________________________________________________ +// +// Track parameters in ALICE dimuon spectrometer +//__________________________________________________________________________ + +#include + +#include "AliCallf77.h" +#include "AliMUON.h" +#include "AliMUONHitForRec.h" +#include "AliMUONSegment.h" +#include "AliMUONTrackParam.h" +#include "AliMUONChamber.h" +#include "AliRun.h" + +ClassImp(AliMUONTrackParam) // Class implementation in ROOT context + +#ifndef WIN32 +# define reco_ghelix reco_ghelix_ +#else +# define reco_ghelix RECO_GHELIX +#endif + +extern "C" +{ +void type_of_call reco_ghelix(Double_t &Charge, Double_t &StepLength, Double_t *VGeant3, Double_t *VGeant3New); +} + +// Inline functions for Get and Set: inline removed because it does not work !!!! +Double_t AliMUONTrackParam::GetInverseBendingMomentum(void) { + // Get fInverseBendingMomentum + return fInverseBendingMomentum;} +void AliMUONTrackParam::SetInverseBendingMomentum(Double_t InverseBendingMomentum) { + // Set fInverseBendingMomentum + fInverseBendingMomentum = InverseBendingMomentum;} +Double_t AliMUONTrackParam::GetBendingSlope(void) { + // Get fBendingSlope + return fBendingSlope;} +void AliMUONTrackParam::SetBendingSlope(Double_t BendingSlope) { + // Set fBendingSlope + fBendingSlope = BendingSlope;} +Double_t AliMUONTrackParam::GetNonBendingSlope(void) { + // Get fNonBendingSlope + return fNonBendingSlope;} +void AliMUONTrackParam::SetNonBendingSlope(Double_t NonBendingSlope) { + // Set fNonBendingSlope + fNonBendingSlope = NonBendingSlope;} +Double_t AliMUONTrackParam::GetZ(void) { + // Get fZ + return fZ;} +void AliMUONTrackParam::SetZ(Double_t Z) { + // Set fZ + fZ = Z;} +Double_t AliMUONTrackParam::GetBendingCoor(void) { + // Get fBendingCoor + return fBendingCoor;} +void AliMUONTrackParam::SetBendingCoor(Double_t BendingCoor) { + // Set fBendingCoor + fBendingCoor = BendingCoor;} +Double_t AliMUONTrackParam::GetNonBendingCoor(void) { + // Get fNonBendingCoor + return fNonBendingCoor;} +void AliMUONTrackParam::SetNonBendingCoor(Double_t NonBendingCoor) { + // Set fNonBendingCoor + fNonBendingCoor = NonBendingCoor;} + + //__________________________________________________________________________ +void AliMUONTrackParam::ExtrapToZ(Double_t Z) +{ + // Track parameter extrapolation to the plane at "Z". + // On return, the track parameters resulting from the extrapolation + // replace the current track parameters. + // Use "reco_ghelix" which should be replaced by something else !!!! + if (this->fZ == Z) return; // nothing to be done if same Z + Double_t forwardBackward; // +1 if forward, -1 if backward + if (Z > this->fZ) forwardBackward = 1.0; + else forwardBackward = -1.0; + Double_t temp, vGeant3[7], vGeant3New[7]; // 7 in parameter ???? + Int_t iGeant3, stepNumber; + Int_t maxStepNumber = 5000; // in parameter ???? + // For safety: return kTRUE or kFALSE ???? + // Parameter vector for calling GHELIX in Geant3 + SetGeant3Parameters(vGeant3, forwardBackward); + // For use of reco_ghelix...: invert X and Y, PX/PTOT and PY/PTOT !!!! + temp = vGeant3[0]; vGeant3[0] = vGeant3[1]; vGeant3[1] = temp; + temp = vGeant3[3]; vGeant3[3] = vGeant3[4]; vGeant3[4] = temp; + // charge must be changed with momentum for backward motion + Double_t charge = + forwardBackward * TMath::Sign(Double_t(1.0), this->fInverseBendingMomentum); + Double_t stepLength = 6.0; // in parameter ???? + // Extrapolation loop + stepNumber = 0; + while (((forwardBackward * (vGeant3[2] - Z)) <= 0.0) && + (stepNumber < maxStepNumber)) { + stepNumber++; + // call Geant3 "ghelix" subroutine through a copy in "reco_muon.F": + // the true function should be called, but how ???? and remove prototyping ... + reco_ghelix(charge, stepLength, vGeant3, vGeant3New); + if ((forwardBackward * (vGeant3New[2] - Z)) > 0.0) break; // one is beyond Z + // better use TArray ???? + for (iGeant3 = 0; iGeant3 < 7; iGeant3++) + {vGeant3[iGeant3] = vGeant3New[iGeant3];} + } + // check maxStepNumber ???? + // For use of reco_ghelix...: + // invert back X and Y, PX/PTOT and PY/PTOT, both for vGeant3 and vGeant3New !!!! + temp = vGeant3[0]; vGeant3[0] = vGeant3[1]; vGeant3[1] = temp; + temp = vGeant3New[0]; vGeant3New[0] = vGeant3New[1]; vGeant3New[1] = temp; + temp = vGeant3[3]; vGeant3[3] = vGeant3[4]; vGeant3[4] = temp; + temp = vGeant3New[3]; vGeant3New[3] = vGeant3New[4]; vGeant3New[4] = temp; + // Interpolation back to exact Z (2nd order) + // should be in function ???? using TArray ???? + Double_t dZ12 = vGeant3New[2] - vGeant3[2]; // 1->2 + Double_t dZ1i = Z - vGeant3[2]; // 1-i + Double_t dZi2 = vGeant3New[2] - Z; // i->2 + Double_t xPrime = (vGeant3New[0] - vGeant3[0]) / dZ12; + Double_t xSecond = + ((vGeant3New[3] / vGeant3New[5]) - (vGeant3[3] / vGeant3[5])) / dZ12; + Double_t yPrime = (vGeant3New[1] - vGeant3[1]) / dZ12; + Double_t ySecond = + ((vGeant3New[4] / vGeant3New[5]) - (vGeant3[4] / vGeant3[5])) / dZ12; + vGeant3[0] = vGeant3[0] + xPrime * dZ1i - 0.5 * xSecond * dZ1i * dZi2; // X + vGeant3[1] = vGeant3[1] + yPrime * dZ1i - 0.5 * ySecond * dZ1i * dZi2; // Y + vGeant3[2] = Z; // Z + Double_t xPrimeI = xPrime - 0.5 * xSecond * (dZi2 - dZ1i); + Double_t yPrimeI = yPrime - 0.5 * ySecond * (dZi2 - dZ1i); + vGeant3[5] = + 1.0 / TMath::Sqrt(1.0 + xPrimeI * xPrimeI + yPrimeI * yPrimeI); // PZ/PTOT + vGeant3[3] = xPrimeI * vGeant3[5]; // PX/PTOT + vGeant3[4] = yPrimeI * vGeant3[5]; // PY/PTOT + // Track parameters from Geant3 parameters + GetFromGeant3Parameters(vGeant3, charge); +} + + //__________________________________________________________________________ +void AliMUONTrackParam::SetGeant3Parameters(Double_t *VGeant3, Double_t ForwardBackward) +{ + // Set vector of Geant3 parameters pointed to by "VGeant3" + // from track parameters in current AliMUONTrackParam. + // Since AliMUONTrackParam is only geometry, one uses "ForwardBackward" + // to know whether the particle is going forward (+1) or backward (-1). + VGeant3[0] = this->fNonBendingCoor; // X + VGeant3[1] = this->fBendingCoor; // Y + VGeant3[2] = this->fZ; // Z + Double_t pYZ = TMath::Abs(1.0 / this->fInverseBendingMomentum); + Double_t pZ = + pYZ / TMath::Sqrt(1.0 + this->fBendingSlope * this->fBendingSlope); + VGeant3[6] = + TMath::Sqrt(pYZ * pYZ + + pZ * pZ * this->fNonBendingSlope * this->fNonBendingSlope); // PTOT + VGeant3[5] = ForwardBackward * pZ / VGeant3[6]; // PZ/PTOT + VGeant3[3] = this->fNonBendingSlope * VGeant3[5]; // PX/PTOT + VGeant3[4] = this->fBendingSlope * VGeant3[5]; // PY/PTOT +} + + //__________________________________________________________________________ +void AliMUONTrackParam::GetFromGeant3Parameters(Double_t *VGeant3, Double_t Charge) +{ + // Get track parameters in current AliMUONTrackParam + // from Geant3 parameters pointed to by "VGeant3". + // "InverseBendingMomentum" is signed with "Charge". + this->fNonBendingCoor = VGeant3[0]; // X + this->fBendingCoor = VGeant3[1]; // Y + this->fZ = VGeant3[2]; // Z + Double_t pYZ = VGeant3[6] * TMath::Sqrt(1.0 - VGeant3[3] * VGeant3[3]); + this->fInverseBendingMomentum = Charge / pYZ; + this->fBendingSlope = VGeant3[4] / VGeant3[5]; + this->fNonBendingSlope = VGeant3[3] / VGeant3[5]; +} + + //__________________________________________________________________________ +void AliMUONTrackParam::ExtrapToStation(Int_t Station, AliMUONTrackParam *TrackParam) +{ + // Track parameters extrapolated from current track parameters ("this") + // to both chambers of the station(0..) "Station" + // are returned in the array (dimension 2) of track parameters + // pointed to by "TrackParam" (index 0 and 1 for first and second chambers). + Double_t extZ[2], z1, z2; + Int_t i1, i2; + AliMUON *pMUON = (AliMUON*) gAlice->GetModule("MUON"); // necessary ???? + // range of Station to be checked ???? + z1 = (&(pMUON->Chamber(2 * Station)))->Z(); // Z of first chamber + z2 = (&(pMUON->Chamber(2 * Station + 1)))->Z(); // Z of second chamber + // First and second Z to extrapolate at + if ((z1 > this->fZ) && (z2 > this->fZ)) {i1 = 0; i2 = 1;} + else if ((z1 < this->fZ) && (z2 < this->fZ)) {i1 = 1; i2 = 0;} + else { + cout << "ERROR in AliMUONTrackParam::CreateExtrapSegmentInStation" << endl; + cout << "Starting Z (" << this->fZ << ") in between z1 (" << z1 << + ") and z2 (" << z2 << ") of station(0..) " << Station << endl; + } + extZ[i1] = z1; + extZ[i2] = z2; + // copy of track parameters + TrackParam[i1] = *this; + // first extrapolation + (&(TrackParam[i1]))->ExtrapToZ(extZ[0]); + TrackParam[i2] = TrackParam[i1]; + // second extrapolation + (&(TrackParam[i2]))->ExtrapToZ(extZ[1]); + return; +} + diff --git a/MUON/AliMUONTrackParam.h b/MUON/AliMUONTrackParam.h new file mode 100644 index 00000000000..3ed93358fa9 --- /dev/null +++ b/MUON/AliMUONTrackParam.h @@ -0,0 +1,54 @@ +#ifndef ALIMUONTRACKPARAM_H +#define ALIMUONTRACKPARAM_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/*$Id$*/ + +#include + +class AliMUONHitForRec; +class AliMUONSegment; + +class AliMUONTrackParam : public TObject { + public: + AliMUONTrackParam(){ + // Constructor + ;} // Constructor + virtual ~AliMUONTrackParam(){ + // Destructor + ;} // Destructor + + // Get and Set methods for data + Double_t GetInverseBendingMomentum(void); + void SetInverseBendingMomentum(Double_t InverseBendingMomentum); + Double_t GetBendingSlope(void); + void SetBendingSlope(Double_t BendingSlope); + Double_t GetNonBendingSlope(void); + void SetNonBendingSlope(Double_t NonBendingSlope); + Double_t GetZ(void); + void SetZ(Double_t Z); + Double_t GetBendingCoor(void); + void SetBendingCoor(Double_t BendingCoor); + Double_t GetNonBendingCoor(void); + void SetNonBendingCoor(Double_t NonBendingCoor); + + void ExtrapToZ(Double_t Z); + void ExtrapToStation(Int_t Station, AliMUONTrackParam *TrackParam); + + protected: + private: + Double_t fInverseBendingMomentum; // Inverse bending momentum (GeV/c ** -1) + Double_t fBendingSlope; // Bending slope (cm ** -1) + Double_t fNonBendingSlope; // Non bending slope (cm ** -1) + Double_t fZ; // Z coordinate (cm) + Double_t fBendingCoor; // bending coordinate (cm) + Double_t fNonBendingCoor; // non bending coordinate (cm) + + void SetGeant3Parameters(Double_t *VGeant3, Double_t ForwardBackward); + void GetFromGeant3Parameters(Double_t *VGeant3, Double_t Charge); + + ClassDef(AliMUONTrackParam, 1) // Class definition in ROOT context + }; + +#endif diff --git a/MUON/AliMUONTrackReconstructor.cxx b/MUON/AliMUONTrackReconstructor.cxx new file mode 100644 index 00000000000..45131480324 --- /dev/null +++ b/MUON/AliMUONTrackReconstructor.cxx @@ -0,0 +1,1150 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ +/* +$Log$ +Revision 1.1.2.7 2000/06/09 22:06:29 morsch +Some coding rule violations corrected. Will soon be obsolete. + +Revision 1.1.2.6 2000/05/02 07:15:29 morsch +Put back TH1.h and TH2.h includes. + +Revision 1.1.2.5 2000/02/17 18:12:43 morsch +Corrections in trackf_read_spoint causing segmentation violations in previous version (I. Chevrot) +New histos (I. Chevrot) + +Revision 1.1.2.4 2000/02/15 18:01:08 morsch +Log messages + +Revision 1.1.2.3 2000/02/15 17:59:01 morsch +Log message added + +Revision 1.1.2.2 2000/02/15 18:54:56 morsch +Reference between track contributing to reconstructed hit and particle corrected +*/ + +#include "AliCallf77.h" +#include "AliMUONTrackReconstructor.h" +#include "AliRun.h" +#include "AliMUON.h" +#include "AliMC.h" + +#include "AliMUONHit.h" +#include "AliMUONPadHit.h" +#include "AliMUONDigit.h" +#include "AliMUONRawCluster.h" +#include "AliMUONReconstHit.h" + +#include "AliPDG.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef WIN32 +# define reco_init reco_init_ +# define cutpxz cutpxz_ +# define sigmacut sigmacut_ +# define xpreci xpreci_ +# define ypreci ypreci_ +# define reconstmuon reconstmuon_ +# define reconstmuon2 reconstmuon2_ +# define trackf_read_geant trackf_read_geant_ +# define trackf_read_fit trackf_read_fit_ +# 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 reconstmuon2 RECONSTMUON2 +# define trackf_read_geant TRACKF_READ_GEANT +# define trackf_read_fit TRACKF_READ_FIT +# 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 reconstmuon2(Int_t &, Int_t &, Int_t &); +void type_of_call trackf_read_fit(Int_t &, Int_t &, Int_t &, Int_t *, Double_t *, Double_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();} +void type_of_call fit_trace(Float_t &, Float_t &, Float_t &, Float_t &, Float_t &, Float_t &, Int_t &, Int_t &, Int_t &, Int_t &); +} + +static TTree *pNtupleGlobal; +static TFile *pHfileGlobal; +static TTree *treeK1; +static TTree *TrH1; +static TClonesArray *fHits2; //List of hits for one track only +static TClonesArray *fParticles2; //List of particles in the Kine tree + + +// 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 +} NtupleSt; + +ClassImp(AliMUONTrackReconstructor) + +//___________________________________________________ +AliMUONTrackReconstructor::AliMUONTrackReconstructor() +{ + fSPxzCut = 3.0; + fSSigmaCut = 4.0; + fSXPrec = 0.01; + fSYPrec = 0.144; +} + +//_____________________________________________________________________________ +void AliMUONTrackReconstructor::Reconst2(Int_t &ifit, Int_t &idebug, Int_t &nev) +{ + reconstmuon2(ifit,idebug,nev); +} + +//_____________________________________________________________________________ +void AliMUONTrackReconstructor::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=kTRUE; + static TFile *pFile; + char *addBackground = strstr(option,"Add"); + + if (addBackground ) { // only in case of background with geant hits + if(first) { + fFileName=filename; + cout<<"filename "<cd(); + if(fHits2) fHits2->Clear(); + if(fParticles2) fParticles2->Clear(); + if(TrH1) delete TrH1; + TrH1=0; + if(treeK1) delete treeK1; + treeK1=0; + // Get Hits Tree header from file + char treeName[20]; + sprintf(treeName,"TreeH%d",bgd_ev); + TrH1 = (TTree*)gDirectory->Get(treeName); + // printf("TrH1 %p of treename %s for event %d \n",TrH1,treeName,bgd_ev); + if (!TrH1) { + printf("ERROR: cannot find Hits Tree for event:%d\n",bgd_ev); + } + // set branch addresses + TBranch *branch; + char branchname[30]; + AliMUON *pMUON = (AliMUON*) gAlice->GetModule("MUON"); + sprintf(branchname,"%s",pMUON->GetName()); + if (TrH1 && fHits2) { + branch = TrH1->GetBranch(branchname); + if (branch) branch->SetAddress(&fHits2); + } + TrH1->GetEntries(); + // get the Kine tree + sprintf(treeName,"TreeK%d",bgd_ev); + treeK1 = (TTree*)gDirectory->Get(treeName); + if (!treeK1) { + printf("ERROR: cannot find Kine Tree for event:%d\n",bgd_ev); + } + // set branch addresses + if (treeK1) + treeK1->SetBranchAddress("Particles", &fParticles2); + treeK1->GetEvent(0); + + // get back to the first file + TTree *treeK = gAlice->TreeK(); + TFile *file1 = 0; + if (treeK) file1 = treeK->GetCurrentFile(); + file1->cd(); + + } // end if addBackground + + // call tracking fortran program + reconstmuon(ifit,idebug,nev,idres,ireadgeant); +} + +//________________________________________________________________________________ +void AliMUONTrackReconstructor::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 AliMUONTrackReconstructor::FinishEvent() +{ + TTree *treeK = gAlice->TreeK(); + TFile *file1 = 0; + if (treeK) file1 = treeK->GetCurrentFile(); + file1->cd(); +} + +//_____________________________________ +void AliMUONTrackReconstructor::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 + + pHfileGlobal = new TFile("reconst.root","RECREATE","Ntuple - reconstruction"); + + pNtupleGlobal = new TTree("ntuple","Reconst ntuple"); + pNtupleGlobal->Branch("ievr",&NtupleSt.ievr,"ievr/I"); + pNtupleGlobal->Branch("ntrackr",&NtupleSt.ntrackr,"ntrackr/I"); + pNtupleGlobal->Branch("istatr",&NtupleSt.istatr[0],"istatr[500]/I"); + pNtupleGlobal->Branch("isignr",&NtupleSt.isignr[0],"isignr[500]/I"); + pNtupleGlobal->Branch("pxr",&NtupleSt.pxr[0],"pxr[500]/F"); + pNtupleGlobal->Branch("pyr",&NtupleSt.pyr[0],"pyr[500]/F"); + pNtupleGlobal->Branch("pzr",&NtupleSt.pzr[0],"pzr[500]/F"); + pNtupleGlobal->Branch("zvr",&NtupleSt.zvr[0],"zvr[500]/F"); + pNtupleGlobal->Branch("chi2r",&NtupleSt.chi2r[0],"chi2r[500]/F"); + pNtupleGlobal->Branch("pxv",&NtupleSt.pxv[0],"pxv[500]/F"); + pNtupleGlobal->Branch("pyv",&NtupleSt.pyv[0],"pyv[500]/F"); + pNtupleGlobal->Branch("pzv",&NtupleSt.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 station 1",100,-0.3,0.3); + new TH1F("h112","delta x station 2",100,-0.3,0.3); + new TH1F("h113","delta x station 3",100,-0.3,0.3); + new TH1F("h114","delta x station 4",100,-0.5,0.5); + new TH1F("h115","delta x station 5",100,-0.5,0.5); + new TH1F("h116","delta x station 1",100,-2,2); + new TH1F("h117","delta x station 2",100,-2,2); + new TH1F("h121","delta y station 1",100,-0.04,0.04); + new TH1F("h122","delta y station 2",100,-0.04,0.04); + new TH1F("h123","delta y station 3",100,-0.04,0.04); + new TH1F("h124","delta y station 4",100,-0.04,0.04); + new TH1F("h125","delta y station 5",100,-0.04,0.04); + + /* 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.); + + + new TH2F("h1111","dx vs x station 1",30,-250.,250.,30,-0.5,0.5); + new TH2F("h1112","dx vs x station 2",30,-250.,250.,30,-0.5,0.5); + new TH2F("h1113","dx vs x station 3",30,-250.,250.,30,-0.5,0.5); + new TH2F("h1114","dx vs x station 4",30,-250.,250.,30,-0.5,0.5); + new TH2F("h1115","dx vs x station 5",30,-250.,250.,30,-0.5,0.5); + new TH2F("h1121","dy vs y station 1",30,-250.,250.,30,-0.04,0.04); + new TH2F("h1122","dy vs y station 2",30,-250.,250.,30,-0.04,0.04); + new TH2F("h1123","dy vs y station 3",30,-250.,250.,30,-0.04,0.04); + new TH2F("h1124","dy vs y station 4",30,-250.,250.,30,-0.04,0.04); + new TH2F("h1125","dy vs y station 5",30,-250.,250.,30,-0.04,0.04); + + // 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 + NtupleSt.ievr = ievr; + NtupleSt.ntrackr = ntrackr; + for (Int_t i=0; i<500; i++) { + NtupleSt.istatr[i] = istatr[i]; + NtupleSt.isignr[i] = isignr[i]; + NtupleSt.pxr[i] = pxr[i]; + NtupleSt.pyr[i] = pyr[i]; + NtupleSt.pzr[i] = pzr[i]; + NtupleSt.zvr[i] = zvr[i]; + NtupleSt.chi2r[i] = chi2r[i]; + NtupleSt.pxv[i] = pxv[i]; + NtupleSt.pyv[i] = pyv[i]; + NtupleSt.pzv[i] = pzv[i]; + } + pNtupleGlobal->Fill(); +} + +//________________ +void hist_closed() +{ + // + // write histos and ntuple to "reconst.root" file + pHfileGlobal->Write(); +} + +//________________________________________________________________________ +void trackf_read_fit(Int_t &ievr, Int_t &nev, Int_t &nhittot1, Int_t *izch, Double_t *xgeant, Double_t *ygeant) +{ + + // introduce aliroot variables in fortran common + // tracking study from geant hits + // + + AliMUON *pMUON = (AliMUON*) gAlice->GetModule("MUON"); + TTree *treeH = gAlice->TreeH(); + Int_t ntracks = (Int_t)treeH->GetEntries(); + cout<<"ntrack="<ResetHits(); + treeH->GetEvent(track); + + if (pMUON) { + +// Loop over hits + for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1); + mHit; + mHit=(AliMUONHit*)pMUON->NextHit()) + { + if (mHit->fChamber > 10) continue; + TClonesArray *fPartArray = gAlice->Particles(); + Int_t ftrack = mHit->fTrack; + Int_t id = ((TParticle*) fPartArray->UncheckedAt(ftrack))->GetPdgCode(); + + if (id==kMuonPlus||id==kMuonMinus) { + xgeant[nhittot1] = mHit->fY; + ygeant[nhittot1] = mHit->fX; + izch[nhittot1] = mHit->fChamber; +// printf("id %d ch %d x %f y %f\n",id,izch[nhittot1],xgeant[nhittot1],ygeant[nhittot1]); + nhittot1++; + } + } // hit loop + } // if pMUON + } // track loop + + ievr=nev; + pHfileGlobal->cd(); +} + +//______________________________________________________________________________ +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 *pMUON = (AliMUON*) gAlice->GetModule("MUON"); + + // TTree *treeK = gAlice->TreeK(); + TTree *treeH = gAlice->TreeH(); + Int_t ntracks = (Int_t)treeH->GetEntries(); + cout<<"ntrack="<ResetHits(); + treeH->GetEvent(track); + + if (pMUON) { +// +// Loop over hits +// + for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1); + mHit; + mHit=(AliMUONHit*)pMUON->NextHit()) + { + if (maxidg<=20000) { + + if (mHit->fChamber > 10) continue; + TClonesArray *fPartArray = gAlice->Particles(); + TParticle *particle; + 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); + + */ + itypg[maxidg] = 0; + if (id==kMuonPlus) itypg[maxidg] = 5; + if (id==kMuonMinus) itypg[maxidg] = 6; + + //printf("ich, itypg[maxidg] %d %d\n",izch[maxidg],itypg[maxidg]); + + ptotg[maxidg] = mHit->fPTot; // P of hit + + particle = (TParticle*) fPartArray->UncheckedAt(ftrack); + Float_t thet = particle->Theta(); + thet = thet*180./3.1416; + + //cout<<"chambre "<UncheckedAt(iparent))->GetPdgCode(); + + if (id2==443) id2=114; + else id2=116; + + if (id2==116) { + nres++; + } + //printf("id2 %d\n",id2); + idg[maxidg] = 30000*id1+10000*idum+id2; + + pvert1g[maxidg] = particle->Py(); // Px vertex + pvert2g[maxidg] = particle->Px(); // Py vertex + pvert3g[maxidg] = particle->Pz(); // Pz vertex + zvertg[maxidg] = particle->Vz(); // z vertex + + // cout<<"x="<Clear(); + TrH1->GetEvent(track); + + // Loop over hits + AliMUONHit *mHit; + for (int i=0;iGetEntriesFast();i++) + { + 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=NULL; + 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] = 0; // Px vertex + pvert2g[maxidg] = 0; // Py vertex + pvert3g[maxidg] = 0; // Pz vertex + zvertg[maxidg] = 0; // z vertex + maxidg ++; + + } // check limits (maxidg) + } // hit loop + } // track loop + } // if TrH1 + + ievr = nev; + nhittot1 = maxidg ; + cout<<"nhittot1="<=19) nbres++; + printf("nres, nbres %d %d \n",nres,nbres); + + pHfileGlobal->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 *pMUON = (AliMUON*) gAlice->GetModule("MUON"); + + cout<<"numero de l'evenement "<TreeR(); + Int_t nent=(Int_t)treeR->GetEntries(); + if (nev < 10) + printf("Found %d entries in the tree (must be one per cathode per event! + 1empty)\n", + nent); +// + + Int_t mult1, mult2; + + if (pMUON) { + Int_t mpoi=0; + for (Int_t ich=0;ich<10;ich++) { + printf("chambre %d\n",ich+1); + TClonesArray *reconstPoints = pMUON->RawClustAddress(ich); + + pMUON->ResetRawClusters(); + treeR->GetEvent(nent-1); + Int_t npoints = (Int_t) reconstPoints->GetEntries(); + if (!npoints) continue; + printf("\n ch %d npoints = %d\n",ich+1,npoints); + // Loop over reconstruted points + for (Int_t ipoi=0; ipoiUncheckedAt(ipoi); + + mult1=point->fMultiplicity[0]; + mult2=point->fMultiplicity[1]; + xtrg[mpoi]=(Double_t) point->fY[0]; + ytrg[mpoi]=(Double_t) point->fX[0]; + izch[mpoi]=ich+1; + Int_t itrack = point->fTracks[1]; + Int_t ihit = point->fTracks[0]; + xgeant[mpoi] = 0; + ygeant[mpoi] = 0; + clsize1[mpoi] = mult1; + clsize2[mpoi] = mult2; + Int_t id1, id2, idum; + id1=id2=idum=-1; + itypg[mpoi]=0; + ihit = ihit-1; + if (ihit >=0 && itrack >=0) { + TClonesArray *fPartArray = gAlice->Particles(); + gAlice->ResetHits(); + gAlice->TreeH()->GetEvent(itrack); + TClonesArray *pMUONhits = pMUON->Hits(); + AliMUONHit* mHit; + mHit=(AliMUONHit*) (pMUONhits->UncheckedAt(ihit)); + Int_t id = (Int_t) mHit->fParticle; + xgeant[mpoi] = mHit->fY; + ygeant[mpoi] = mHit->fX; + if (id == kMuonPlus) itypg[mpoi]=5; + if (id == kMuonMinus) itypg[mpoi]=6; + TParticle *particle; + particle = (TParticle*) + (fPartArray->UncheckedAt(mHit->fTrack)); + TParticle* particleM=(TParticle*) + (fPartArray->UncheckedAt(particle->GetFirstMother())); + Int_t iparent=particleM->GetPdgCode(); + printf("\n Particle Id:%d %d \n", id, iparent); + if (iparent == 443) id2=114; + if (iparent == 553) id2=116; + } + id1=itrack; + idum=itrack+1; + idg[mpoi] = 30000*id1+10000*idum+id2; + mpoi++; + } // loop over points + } // loop over chamber + ievr = nev; + cout<<"evenement "<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); +} diff --git a/MUON/AliMUONTrackReconstructor.h b/MUON/AliMUONTrackReconstructor.h new file mode 100644 index 00000000000..7f7608cbc0b --- /dev/null +++ b/MUON/AliMUONTrackReconstructor.h @@ -0,0 +1,40 @@ +#ifndef ALIMUONTRACKRECONSTRUCTOR_H +#define ALIMUONTRACKRECONSTRUCTOR_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include + +class AliMUONTrackReconstructor : public TObject { + public: + // + // Track Reconstruction + AliMUONTrackReconstructor(); + virtual ~AliMUONTrackReconstructor(){;} + 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 Reconst2(Int_t &,Int_t &,Int_t &); + 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;} + private: +// 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; // ????????? + ClassDef(AliMUONTrackReconstructor,1) // Interface to muon tracking code + }; + + +#endif diff --git a/MUON/AliMUONTransientDigit.cxx b/MUON/AliMUONTransientDigit.cxx new file mode 100644 index 00000000000..6d9c7973232 --- /dev/null +++ b/MUON/AliMUONTransientDigit.cxx @@ -0,0 +1,57 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log $ +*/ + +#include "AliMUONTransientDigit.h" +#include + +ClassImp(AliMUONTransientDigit) + + +//____________________________________________________________________________ + +AliMUONTransientDigit::AliMUONTransientDigit(const AliMUONTransientDigit& digit) +{ +// dummy copy constructor +} + + +AliMUONTransientDigit::AliMUONTransientDigit(Int_t ich, Int_t *digits): + AliMUONDigit(digits) +{ + // + // Creates a MUON digit list object + // + + fChamber = ich; + fTrackList = new TObjArray; + +} + +AliMUONTransientDigit::~AliMUONTransientDigit() +{ +delete fTrackList; +} + +AliMUONTransientDigit& AliMUONTransientDigit::operator =(const AliMUONTransientDigit& rhs) +{ +// Dummy assignment operator + return *this; +} + + diff --git a/MUON/AliMUONTransientDigit.h b/MUON/AliMUONTransientDigit.h new file mode 100644 index 00000000000..b3e282adf45 --- /dev/null +++ b/MUON/AliMUONTransientDigit.h @@ -0,0 +1,28 @@ +#ifndef ALIMUONTRANSIENTDIGIT_H +#define ALIMUONTRANSIENTDIGIT_H + +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include "AliMUONDigit.h" +class TObjArray; + + +class AliMUONTransientDigit : public AliMUONDigit { + public: + Int_t fChamber; // chamber number of pad + TObjArray *fTrackList; // List of tracks contributing + public: + AliMUONTransientDigit() {fTrackList=0;} + AliMUONTransientDigit(const AliMUONTransientDigit& digit); + AliMUONTransientDigit(Int_t rpad, Int_t *digits); + virtual ~AliMUONTransientDigit(); + TObjArray *TrackList() {return fTrackList;} + AliMUONTransientDigit & operator =(const AliMUONTransientDigit & rhs); + + ClassDef(AliMUONTransientDigit,1) // Transient digit for set MUON +}; +#endif + diff --git a/MUON/AliMUONTriggerCircuit.cxx b/MUON/AliMUONTriggerCircuit.cxx new file mode 100644 index 00000000000..9da1f761219 --- /dev/null +++ b/MUON/AliMUONTriggerCircuit.cxx @@ -0,0 +1,539 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ +/* + + +*/ +#include "AliRun.h" +#include "AliMUON.h" +#include "AliMUONPoints.h" +#include "AliMUONTriggerCircuit.h" +#include "AliMUONSegmentation.h" +#include "AliMUONResponse.h" +#include "AliMUONChamber.h" +#include "TMath.h" +#include "iostream.h" + +ClassImp(AliMUONTriggerCircuit) + +static Int_t circuitId[234]= +{111, 121, 131, 141, 151, 161, 171, + 211, 212, 221, 222, 231, 232, 241, 242, 251, 252, 261, 262, 271, + 311, 312, 321, 322, 331, 332, 341, 342, 351, 352, 361, 362, 371, + 411, 412, 413, 421, 422, 423, 424, 431, 432, 433, 434, 441, 442, + 451, 452, 461, 462, 471, + 521, 522, 523, 524, 531, 532, 533, 534, 541, 542, 551, 552, 561, 562, 571, + 611, 612, 613, 621, 622, 623, 624, 631, 632, 633, 634, 641, 642, + 651, 652, 661, 662, 671, + 711, 712, 721, 722, 731, 732, 741, 742, 751, 752, 761, 762, 771, + 811, 812, 821, 822, 831, 832, 841, 842, 851, 852, 861, 862, 871, + 911, 921, 931, 941, 951, 961, 971, + -111, -121, -131, -141, -151, -161, -171, + -211, -212, -221, -222, -231, -232, -241, -242, -251, -252, -261, -262, -271, + -311, -312, -321, -322, -331, -332, -341, -342, -351, -352, -361, -362, -371, + -411, -412, -413, -421, -422, -423, -424, -431, -432, -433, -434, -441, -442, + -451, -452, -461, -462, -471, + -521, -522, -523, -524, -531, -532, -533, -534, -541, -542, -551, -552, -561, -562, -571, + -611, -612, -613, -621, -622, -623, -624, -631, -632, -633, -634, -641, -642, + -651, -652, -661, -662, -671, + -711, -712, -721, -722, -731, -732, -741, -742, -751, -752, -761, -762, -771, + -811, -812, -821, -822, -831, -832, -841, -842, -851, -852, -861, -862, -871, + -911, -921, -931, -941, -951, -961, -971}; + +static Int_t moduleId[63]= +{11,12,13,14,15,16,17, + 21,22,23,24,25,26,27, + 31,32,33,34,35,36,37, + 41,42,43,44,45,46,47, + 51,52,53,54,55,56,57, + 61,62,63,64,65,66,67, + 71,72,73,74,75,76,77, + 81,82,83,84,85,86,87, + 91,92,93,94,95,96,97}; + +static Int_t nStripX[63]= +{16,16,16,16,16,16,16, + 32,32,32,32,32,32,16, + 32,32,32,32,32,32,16, + 48,64,64,32,32,32,16, + 0,64,64,32,32,32,16, + 48,64,64,32,32,32,16, + 32,32,32,32,32,32,16, + 32,32,32,32,32,32,16, + 16,16,16,16,16,16,16}; + +static Int_t nStripY[63]= +{8,8,8,8,8,8,16, + 8,8,8,8,8,8,16, + 16,16,16,16,16,8,16, + 16,16,16,16,16,8,16, + 0,8,16,16,16,8,16, + 16,16,16,16,16,8,16, + 16,16,16,16,16,8,16, + 8,8,8,8,8,8,16, + 8,8,8,8,8,8,16}; + +//---------------------------------------------------------------------- +AliMUONTriggerCircuit::AliMUONTriggerCircuit() +{ +// Constructor + fidCircuit=0; + fx2m=0; + fx2ud=0; + fOrMud[0]=fOrMud[1]=0; + for (Int_t i=0; i<4; i++) { + for (Int_t j=0; j<32; j++) { + fXcode[i][j]=0; + fYcode[i][j]=0; + } + } + for (Int_t i=0; i<16; i++) { fXpos11[i]=0.; } + for (Int_t i=0; i<31; i++) { fYpos11[i]=0.; } + for (Int_t i=0; i<63; i++) { fYpos21[i]=0.; } +} + +//---------------------------------------------------------------------- +AliMUONTriggerCircuit::AliMUONTriggerCircuit(const AliMUONTriggerCircuit& MUONTriggerCircuit) +{ +// Dummy copy constructor +} + +//---------------------------------------------------------------------- +AliMUONTriggerCircuit & AliMUONTriggerCircuit::operator=(const AliMUONTriggerCircuit& MUONTriggerCircuit) +{ +// Dummy assignment operator + return *this; +} + +//---------------------------------------------------------------------- +void AliMUONTriggerCircuit::Init(Int_t iCircuit) { +// initialize circuit characteristics + fidCircuit=circuitId[iCircuit]; + LoadX2(); + LoadXCode(); + LoadYCode(); + LoadXPos(); + LoadYPos(); +} + +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::CircuitNumber(Int_t idCircuit){ +// returns circuit number iCircuit (0-234) corresponding to circuit idCircuit + Int_t iCircuit=0; + for (Int_t i=0; i<234; i++) { + if (circuitId[i]==idCircuit) { + iCircuit=i; + break; + } + } + return iCircuit; +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::ModuleNumber(Int_t idModule){ +// returns module number imod (from 0 to 63) corresponding to module idmodule + Int_t absidModule=TMath::Abs(idModule); + Int_t iModule=0; + for (Int_t i=0; i<63; i++) { + if (moduleId[i]==absidModule) { + iModule=i; + break; + } + } + return iModule; +} + +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::Module(Int_t idCircuit) { +// returns ModuleId where Circuit idCircuit is sitting + return Int_t(idCircuit/10); +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::Position(Int_t idCircuit) { +// returns position of idCircuit in correcponding Module + return TMath::Abs(idCircuit)-TMath::Abs(Module(idCircuit))*10; +} + +//---------------------------------------------------------------------- +void AliMUONTriggerCircuit::LoadX2() { +// initialize fx2m, fx2ud and fOrMud + + Int_t idModule=Module(fidCircuit); // corresponding module Id. + Int_t nStrX=nStripX[ModuleNumber(idModule)]; // and its number of X strips + Int_t nStrY=nStripY[ModuleNumber(idModule)]; // and its number of Y strips + Int_t iPosCircuit=Position(fidCircuit); // position of circuit in module + +// first step : look at lower part + if (iPosCircuit==1) { // need to scan lower module + if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) { + fOrMud[0]=1; + Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule); + Int_t nStrD=nStripY[ModuleNumber(idModuleD)]; + + if (nStrY!=nStrD + &&TMath::Abs(idModule)!=42&&TMath::Abs(idModule)!=52) { + if (nStrY==8) fx2m=1; + if (nStrD==8) fx2ud=1; + } + } + + } else { // lower strips within same module + fOrMud[0]=0; + } + +// second step : look at upper part + if ((iPosCircuit==1&&nStrX==16)||(iPosCircuit==2&&nStrX==32)|| + (iPosCircuit==3&&nStrX==48)||(iPosCircuit==4&&nStrX==64)) { + if ((idModule>17||idModule<-17)&&TMath::Abs(idModule)!=61) { + fOrMud[1]=1; + Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule); + Int_t nStrU=nStripY[ModuleNumber(idModuleU)]; + + if (nStrY!=nStrU + &&TMath::Abs(idModule)!=62&&TMath::Abs(idModule)!=52) { + if (nStrY==8) fx2m=1; + if (nStrU==8) fx2ud=1; + } + } + + } else { // upper strips within same module + fOrMud[1]=0; + } +} + +//---------------------------------------------------------------------- +void AliMUONTriggerCircuit::LoadXCode(){ +// assign a Id. number to each X strip of current circuit +// Id.=(corresponding module Id.)*100+(Id. strip of module) + +// first part : fill XMC11 XMC12 and strips 8 to 24 (middle) XMC21 XMC22 + Int_t iStripCircMT1=0, iStripCircMT2=8; + Int_t idModule=Module(fidCircuit); // corresponding module Id. + Int_t nStrX=nStripX[ModuleNumber(idModule)]; // and its number of strips + Int_t iPosCircuit=Position(fidCircuit); // position of circuit in module + Int_t sign=TMath::Abs(idModule)/idModule; // left or right + + for (Int_t istrip=(iPosCircuit-1)*16; + istrip<(iPosCircuit-1)*16+16; istrip++) { + + fXcode[0][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip); + fXcode[1][iStripCircMT1]=sign*(TMath::Abs(idModule)*100+istrip); + fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip); + fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip); + iStripCircMT1++; + iStripCircMT2++; + } + +// second part +// XMC21 XMC22 strips 0 to 7 and 24 to 31 + Int_t idModuleD, idModuleU; + Int_t nStrD, nStrU; + + idModule=Module(fidCircuit); // corresponding module Id. + nStrX=nStripX[ModuleNumber(idModule)]; // number of X strips + sign=TMath::Abs(idModule)/idModule; + +// fill lower part (0 to 7) + if (iPosCircuit==1) { // need to scan lower module + if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) { // non-existing + idModuleD=sign*(TMath::Abs(idModule)+10); // lower module Id + nStrD=nStripX[ModuleNumber(idModuleD)]; // and its number of strips + + iStripCircMT2=0; + for (Int_t istrip=nStrD-8; istrip17||idModule<-17)&&TMath::Abs(idModule)!=61) { + idModuleU=sign*(TMath::Abs(idModule)-10); // upper module Id + nStrU=nStripX[ModuleNumber(idModuleU)]; // and its number of strips + + iStripCircMT2=24; + for (Int_t istrip=0; istrip<8; istrip++) { + fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip); + fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModuleU)*100+istrip); + iStripCircMT2++; + } + } + + } else if ((iPosCircuit==1&&nStrX>16)||(iPosCircuit==2&&nStrX>32)|| + (iPosCircuit==3&&nStrX>48)) { // upper strips within same mod. + + iStripCircMT2=24; + for (Int_t istrip=(iPosCircuit-1)*16+16; + istrip<(iPosCircuit-1)*16+24; istrip++) { + fXcode[2][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip); + fXcode[3][iStripCircMT2]=sign*(TMath::Abs(idModule)*100+istrip); + iStripCircMT2++; + } + } +} + +//---------------------------------------------------------------------- +void AliMUONTriggerCircuit::LoadYCode(){ +// assign a Id. number to each Y strip of current circuit +// Id.=(corresponding module Id.)*100+(Id. strip of module) +// note : for Y plane fill only "central part" of circuit +// (upper and lower parts are filled in PreHandlingY of AliMUONTriggerDecision) + + Int_t idModule=Module(fidCircuit); // corresponding module Id. + Int_t nStrY=nStripY[ModuleNumber(idModule)]; // its number of Y strips + Int_t sign=TMath::Abs(idModule)/idModule; // left or right + + for (Int_t istrip=0; istrip y position of X declusterized strips + + Int_t chamber, cathode; + Int_t code, idModule, idStrip, idSector; + Float_t x, y, width; + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONChamber* iChamber; + AliMUONSegmentation* segmentation; + +// first plane (11) + chamber=11; + cathode=1; + iChamber = &(pMUON->Chamber(chamber-1)); + segmentation=iChamber->SegmentationModel(cathode); + + for (Int_t istrip=0; istrip<16; istrip++) { + code=fXcode[0][istrip]; // decode current strip + idModule=Int_t(code/100); // corresponding module Id. + idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module + idSector=segmentation->Sector(idModule,idStrip); // corresponding sector + width=segmentation->Dpy(idSector); // corresponding strip width + segmentation->GetPadCxy(idModule,idStrip,x,y); // get strip real position + + fYpos11[2*istrip]=y; + if (istrip!=15) fYpos11[2*istrip+1]=y+width/2.; + } + +// second plane (21) + chamber=13; + cathode=1; + iChamber = &(pMUON->Chamber(chamber-1)); + segmentation=iChamber->SegmentationModel(cathode); + + for (Int_t istrip=0; istrip<32; istrip++) { + code=fXcode[2][istrip]; // decode current strip + idModule=Int_t(code/100); // corresponding module Id. + idStrip=TMath::Abs(code-idModule*100); // corresp. strip number in module + idSector=segmentation->Sector(idModule,idStrip); // corresponding sector + width=segmentation->Dpy(idSector); // corresponding strip width + segmentation->GetPadCxy(idModule,idStrip,x,y); // get strip real position + +// using idModule!=0 prevents to fill garbage in case of circuits +// in the first and last rows + if (idModule!=0) { + fYpos21[2*istrip]=y; + if (istrip!=31) fYpos21[2*istrip+1]=y+width/2.; + } + } +} + +//---------------------------------------------------------------------- +void AliMUONTriggerCircuit::LoadXPos(){ +// fill fXpos11 -> x position of Y strips for the first plane only +// fXpos11 contains the x position of Y strip for the current circuit +// taking into account whether or nor not part(s) of the circuit +// (middle, up or down) has(have) 16 strips + + Float_t x, y; + + Int_t chamber=11; + Int_t cathode=2; + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONChamber* iChamber; + AliMUONSegmentation* segmentation; + iChamber = &(pMUON->Chamber(chamber-1)); + segmentation=iChamber->SegmentationModel(cathode); + + Int_t idModule=Module(fidCircuit); // corresponding module Id. + Int_t nStrY=nStripY[ModuleNumber(idModule)]; // number of Y strips + Int_t idSector=segmentation->Sector(idModule,0); // corresp. sector + Float_t width=segmentation->Dpx(idSector); // corresponding strip width + +// first case : up middle and down parts have all 8 or 16 strip + if ((nStrY==16)||(nStrY==8&&fx2m==0&&fx2ud==0)) { + for (Int_t istrip=0; istripGetPadCxy(idModule,istrip,x,y); + fXpos11[istrip]=x; + } +// second case : mixing 8 and 16 strips within same circuit + } else { + for (Int_t istrip=0; istripGetPadCxy(idModule,istrip,x,y); + fXpos11[2*istrip]=x-width/4.; + fXpos11[2*istrip+1]=fXpos11[2*istrip]+width/2.; + } + } +} + +//---------------------------------------------------------------------- +Float_t AliMUONTriggerCircuit::PtCal(Int_t istripX, Int_t idev, Int_t istripY){ +// returns calculated pt for circuit/istripX/idev/istripY according +// to the formula of the TRD. Note : idev (input) is in [0+30] + + // Int_t jdev = idev - 15; // jdev in [-15+15] + Int_t istripX2=istripX+idev+1; // find istripX2 using istripX and idev + + Float_t yPosX1=fYpos11[istripX]; + Float_t yPosX2=fYpos21[istripX2]; + Float_t xPosY1=fXpos11[istripY]; + + Float_t zf=975., z1=1603.5, z2=1703.5; + Float_t thetaDev=(1./zf)*(yPosX1*z2-yPosX2*z1)/(z2-z1); + Float_t xf=xPosY1*zf/z1; + Float_t yf=yPosX2-((yPosX2-yPosX1)*(z2-zf))/(z2-z1); + return (3.*0.3/TMath::Abs(thetaDev)) * TMath::Sqrt(xf*xf+yf*yf)/zf; +} + +//---------------------------------------------------------------------- +//--- methods which return member data related info +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetIdCircuit(){ +// returns circuit Id + return fidCircuit; +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetIdModule(){ +// returns module Id + return Module(fidCircuit); +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetNstripX() { +// returns the number of X strips in the module where the circuit is sitting + return nStripX[ModuleNumber(Module(fidCircuit))]; +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetNstripY() { +// returns the number of Y strips in the module where the circuit is sitting + return nStripY[ModuleNumber(Module(fidCircuit))]; +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetPosCircuit() { +// returns the position of the circuit in its module + return Position(fidCircuit); +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetIdCircuitD(){ +// returns the Id of the circuit down + Int_t idModule=Module(fidCircuit); + Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule); + return (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule); +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetICircuitD(){ +// returns the number of the circuit down + Int_t idModule=Module(fidCircuit); + Int_t idModuleD=(TMath::Abs(idModule)+10)*(TMath::Abs(idModule)/idModule); + Int_t idCircuitD= + (TMath::Abs(idModuleD)*10+1)*(TMath::Abs(idModule)/idModule); + return CircuitNumber(idCircuitD); +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetIdCircuitU(){ +// returns the Id of the circuit up + Int_t idModule=Module(fidCircuit); + Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule); + return (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule); +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetICircuitU(){ +// returns the number of the circuit up + Int_t idModule=Module(fidCircuit); + Int_t idModuleU=(TMath::Abs(idModule)-10)*(TMath::Abs(idModule)/idModule); + Int_t idCircuitU= + (TMath::Abs(idModuleU)*10+1)*(TMath::Abs(idModule)/idModule); + return CircuitNumber(idCircuitU); +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetX2m(){ +// returns fx2m + return fx2m; +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetX2ud(){ +// returns fx2ud + return fx2ud; +} +//---------------------------------------------------------------------- +void AliMUONTriggerCircuit::GetOrMud(Int_t orMud[2]){ +// returns fOrMud + orMud[0]=fOrMud[0]; + orMud[1]=fOrMud[1]; +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetXcode(Int_t chamber, Int_t istrip){ +// returns X code of circuit/chamber/istrip (warning : chamber in [0,3]) + return fXcode[chamber][istrip]; +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerCircuit::GetYcode(Int_t chamber, Int_t istrip){ +// returns Y code of circuit/chamber/istrip (warning : chamber in [0,3]) + return fYcode[chamber][istrip]; +} +//---------------------------------------------------------------------- +Float_t AliMUONTriggerCircuit::GetY11Pos(Int_t istrip){ +// returns Y position of X strip istrip in MC11 + return fYpos11[istrip]; +} +//---------------------------------------------------------------------- +Float_t AliMUONTriggerCircuit::GetY21Pos(Int_t istrip){ +// returns Y position of X strip istrip in MC21 + return fYpos21[istrip]; +} +//---------------------------------------------------------------------- +Float_t AliMUONTriggerCircuit::GetX11Pos(Int_t istrip){ +// returns X position of Y strip istrip in MC11 + return fXpos11[istrip]; +} +//---------------------------------------------------------------------- +//--- end of methods which return member data related info +//---------------------------------------------------------------------- + + + + + + + diff --git a/MUON/AliMUONTriggerCircuit.h b/MUON/AliMUONTriggerCircuit.h new file mode 100644 index 00000000000..55f559d8287 --- /dev/null +++ b/MUON/AliMUONTriggerCircuit.h @@ -0,0 +1,81 @@ +#ifndef ALIMUONTRIGGERCIRCUIT_H +#define ALIMUONTRIGGERCIRCUIT_H + +#include "TObjArray.h" +#include +#include "AliMUONSegmentationTrigger.h" + +class AliMUONSegmentationTrigger; +//---------------------------------------------- +class AliMUONTriggerCircuit : +public TObject { + public: + AliMUONTriggerCircuit(); + virtual ~AliMUONTriggerCircuit(){;} + // copy constructor + AliMUONTriggerCircuit(const AliMUONTriggerCircuit& AliMUONTriggerCircuit); + // assignment operator + AliMUONTriggerCircuit& operator=(const AliMUONTriggerCircuit& AliMUONTriggerCircuit); + + // initializations + void Init(Int_t iCircuit); + + // get calculated pt + Float_t PtCal(Int_t istripX, Int_t idev, Int_t istripY); + + //--- methods which return member data related info + Int_t GetIdCircuit(); + Int_t GetIdModule(); + Int_t GetNstripX(); + Int_t GetNstripY(); + Int_t GetPosCircuit(); + Int_t GetIdCircuitD(); + Int_t GetICircuitD(); + Int_t GetIdCircuitU(); + Int_t GetICircuitU(); + Int_t GetX2m(); + Int_t GetX2ud(); + void GetOrMud(Int_t orMud[2]); + Int_t GetXcode(Int_t chamber, Int_t istrip); + Int_t GetYcode(Int_t chamber, Int_t istrip); + Float_t GetY11Pos(Int_t istrip); + Float_t GetY21Pos(Int_t istrip); + Float_t GetX11Pos(Int_t istrip); + + // Get reference to segmentation model + virtual AliMUONSegmentation* SegmentationModel(Int_t isec) { + return (AliMUONSegmentation *) (*fSegmentation)[isec-1]; + } + + protected: + TObjArray *fSegmentation; // pointer to segmentation + + private: + Int_t CircuitNumber(Int_t idCircuit); + Int_t ModuleNumber(Int_t idModule); + Int_t Module(Int_t idCircuit); + Int_t Position(Int_t idCircuit); + void LoadX2(); + void LoadXCode(); + void LoadYCode(); + void LoadYPos(); + void LoadXPos(); + + ClassDef(AliMUONTriggerCircuit,1) // Trigger Circuit class + + private: + Int_t fidCircuit; // circuit Id number + Int_t fx2m; // internal info needed by TriggerDecision + Int_t fx2ud; // internal info needed by TriggerDecision + Int_t fOrMud[2]; // internal info needed by TriggerDecision + Int_t fXcode[4][32]; // code of X strips + Int_t fYcode[4][32]; // code of Y strips + Float_t fXpos11[16]; // X position of Y strips in MC11 + Float_t fYpos11[31]; // Y position of X strips in MC11 + Float_t fYpos21[63]; // Y position of X strips in MC21 + +}; +#endif + + + diff --git a/MUON/AliMUONTriggerDecision.cxx b/MUON/AliMUONTriggerDecision.cxx new file mode 100644 index 00000000000..d5c7c20fbce --- /dev/null +++ b/MUON/AliMUONTriggerDecision.cxx @@ -0,0 +1,1358 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ +/* +$Log$ +Revision 1.1.2.8 2000/06/14 14:54:34 morsch +Complete redesign, make use of TriggerCircuit and TriggerLut (PC) + +Revision 1.1.2.5 2000/04/26 19:59:57 morsch +Constructor added. + +Revision 1.1.2.4 2000/04/26 12:31:30 morsch +Modifications by P. Crochet: +- adapted to the new Trigger chamber geometry +- condition on soft background added +- contructor added in AliMUONTriggerDecision.h +- single-undefined taken into account in the output of GlobalTrigger() +- some bugs fixed + +Revision 1.1.2.3 2000/03/21 09:29:58 morsch +Put back comments + +Revision 1.1.2.2 2000/03/21 09:24:34 morsch +Author and responsible for the code: Philippe Crochet +*/ + + +#include "AliMUONTriggerDecision.h" +#include "AliMUONTriggerLut.h" +#include "AliMUONHitMapA1.h" +#include "AliRun.h" +#include "AliMUON.h" +#include "AliMUONPoints.h" +#include "AliMUONSegmentation.h" +#include "AliMUONResponse.h" +#include "AliMUONChamber.h" +#include "AliMUONDigit.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//---------------------------------------------------------------------- +ClassImp(AliMUONTriggerDecision) + +//---------------------------------------------------------------------- +AliMUONTriggerDecision::AliMUONTriggerDecision(Int_t iprint) +{ +// Constructor + fiDebug = iprint; // print option +// iprint = 0 : don't print anything +// iprint = 1 : print Global Trigger Output +// iprint = 2 : print Local and Global Trigger Outputs +// iprint = 3 : iprint = 2 + detailed info on X strips +// iprint = 4 : iprint = 2 + detailed info on Y strip +// iprint = 5 : iprint = 2 + detailed info on X and Y strips +// Note : with iprint>2, the strips detailed info is given for all circuits + +// Global Trigger information + for (Int_t i=0; i<3; i++) { // [0] : Low pt, [1] : High pt, [2] : All pt + fGlobalSinglePlus[i]=0; // tot num of single plus + fGlobalSingleMinus[i]=0; // tot num of single minus + fGlobalSingleUndef[i]=0; // tot num of single undefined + fGlobalPairUnlike[i]=0; // tot num of unlike-sign pairs + fGlobalPairLike[i]=0; // tot num of like-sign pairs + } + // Local Trigger information + for (Int_t icirc=0; icirc<234; icirc++){ + fiTrigger[icirc]=0; // trigger or not + fStripX11[icirc]=0; // X strip in MC11 which triggers + fdev[icirc]=0; // deviation which triggers + fStripY11[icirc]=0; // Y strip in MC11 which triggers + for (Int_t i=0; i<2; i++) { // pt information via LuT + fLutLpt[icirc][i]=fLutHpt[icirc][i]=fLutApt[icirc][i]=0; + } + } + // bit pattern + for (Int_t icirc=0; icirc<234; icirc++) { + for (Int_t istrip=0; istrip<16; istrip++) { + fXbit11[icirc][istrip]=fXbit12[icirc][istrip]=0; + fYbit11[icirc][istrip]=fYbit12[icirc][istrip]=0; + fYbit21[icirc][istrip]=fYbit22[icirc][istrip]=0; + fYbit21U[icirc][istrip]=fYbit22U[icirc][istrip]=0; + fYbit21D[icirc][istrip]=fYbit22D[icirc][istrip]=0; + } + for (Int_t istrip=0; istrip<32; istrip++) { + fXbit21[icirc][istrip]=fXbit22[icirc][istrip]=0; + } + } +} + +//---------------------------------------------------------------------- +AliMUONTriggerDecision::~AliMUONTriggerDecision() +{ +// Destructor +} + +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::Trigger(){ +// main method of the class which calls the overall Trigger procedure +// cout << " In AliMUONTriggerDecision::Trigger " << "\n"; + + ResetBit(); + SetBit(); + SetBitUpDownY(); + + Int_t coinc44=0, resetMid=0; // initialize coincidence + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONTriggerCircuit* triggerCircuit; + + for (Int_t icirc=0; icirc<234; icirc++) { // loop on circuits + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + // Int_t idCircuit=triggerCircuit->GetIdCircuit(); + + Int_t minDevStrip[5], minDev[5], coordY[5]; + for (Int_t i=0; i<5; i++) { + minDevStrip[i]=minDev[i]=coordY[i]=0; + } + Int_t x2m=triggerCircuit->GetX2m(); + Int_t x2ud=triggerCircuit->GetX2ud(); + Int_t orMud[2]={0,0}; + triggerCircuit->GetOrMud(orMud); + +// call triggerX + TrigX(fXbit11[icirc],fXbit12[icirc],fXbit21[icirc],fXbit22[icirc], + coinc44, minDevStrip, minDev); +// call triggerY + TrigY(fYbit11[icirc],fYbit12[icirc],fYbit21[icirc],fYbit22[icirc], + fYbit21U[icirc],fYbit21D[icirc],fYbit22U[icirc],fYbit22D[icirc], + x2m,x2ud,orMud,resetMid,coinc44,coordY); +// call LocalTrigger + Int_t iTrigger=0; + LocalTrigger(icirc, minDevStrip, minDev, coordY, iTrigger); + + if (iTrigger==1&&fiDebug>1) { + PrintBitPatXInput(icirc); + PrintBitPatYInput(icirc); + PrintLocalOutput(minDevStrip, minDev, coordY); + } + } // end loop on circuits + +// call Global Trigger + GlobalTrigger(); + // cout << " Leaving AliMUONTriggerDecision::Trigger " << "\n"; +} + +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::ResetBit(){ +// reset bit pattern, global and local trigger output tables to 0 + + for (Int_t icirc=0; icirc<234; icirc++) { + for (Int_t istrip=0; istrip<16; istrip++) { + fXbit11[icirc][istrip]=fXbit12[icirc][istrip]=0; + fYbit11[icirc][istrip]=fYbit12[icirc][istrip]=0; + fYbit21[icirc][istrip]=fYbit22[icirc][istrip]=0; + fYbit21U[icirc][istrip]=fYbit22U[icirc][istrip]=0; + fYbit21D[icirc][istrip]=fYbit22D[icirc][istrip]=0; + } + for (Int_t istrip=0; istrip<32; istrip++) { + fXbit21[icirc][istrip]=fXbit22[icirc][istrip]=0; + } + } + for (Int_t i=0; i<3; i++) { + fGlobalSinglePlus[i]=0; + fGlobalSingleMinus[i]=0; + fGlobalSingleUndef[i]=0; + fGlobalPairLike[i]=0; + fGlobalPairLike[i]=0; + } + for (Int_t icirc=0; icirc<234; icirc++){ + fiTrigger[icirc]=0; + fStripX11[icirc]=0; + fdev[icirc]=0; + fStripY11[icirc]=0; + for (Int_t i=0; i<2; i++) { + fLutLpt[icirc][i]=fLutHpt[icirc][i]=fLutApt[icirc][i]=0; + } + } +} + +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::SetBit(){ +// 1) loop over chambers and cathodes +// 2) load digits +// 3) remove soft background +// 4) set the bit patterns + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONTriggerCircuit* triggerCircuit; + + for (Int_t chamber=11; chamber<15; chamber++){ + for (Int_t cathode=1; cathode<3; cathode++){ + + AliMUONChamber* iChamber; + AliMUONSegmentation* segmentation; + + TClonesArray *muonDigits = pMUON->DigitsAddress(chamber-1); + if (muonDigits == 0) return; + + gAlice->ResetDigits(); + + Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); + gAlice->TreeD()->GetEvent(nent-2+cathode-1); + Int_t ndigits = muonDigits->GetEntriesFast(); + if (ndigits == 0) return; + + iChamber = &(pMUON->Chamber(chamber-1)); + segmentation=iChamber->SegmentationModel(cathode); + AliMUONDigit *mdig; + + for (Int_t digit=0; digitUncheckedAt(digit); +// get the center of the pad Id + Int_t ix=mdig->fPadX; + Int_t iy=mdig->fPadY; +// get the sum of the coded charge +// see coding convention in AliMUONChamberTrigger::DisIntegration + Int_t sumCharge=0; + for (Int_t icharge=0; icharge<10; icharge++) { + sumCharge=sumCharge+mdig->fTcharges[icharge]; + } +// apply condition on soft background + Int_t testCharge=sumCharge-(Int_t(sumCharge/10))*10; + testCharge=sumCharge-testCharge*10; + if(sumCharge<=10||testCharge>0) { +// code pad + Int_t code=TMath::Abs(ix)*100+iy; + if (ix<0) { code=-code; } + + if (cathode==1) { + switch (chamber) + { + case 11: + for (Int_t icirc=0; icirc<234; icirc++) { + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + for (Int_t istrip=0; istrip<16; istrip++) { + if (triggerCircuit->GetXcode(0,istrip)==code) + fXbit11[icirc][istrip]=1; + } + } + break; + case 12: + for (Int_t icirc=0; icirc<234; icirc++) { + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + for (Int_t istrip=0; istrip<16; istrip++) { + if (triggerCircuit->GetXcode(1,istrip)==code) + fXbit12[icirc][istrip]=1; + } + } + break; + case 13: + for (Int_t icirc=0; icirc<234; icirc++) { + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + for (Int_t istrip=0; istrip<32; istrip++) { + if (triggerCircuit->GetXcode(2,istrip)==code) + fXbit21[icirc][istrip]=1; + } + } + break; + case 14: + for (Int_t icirc=0; icirc<234; icirc++) { + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + for (Int_t istrip=0; istrip<32; istrip++) { + if (triggerCircuit->GetXcode(3,istrip)==code) + fXbit22[icirc][istrip]=1; + } + } + break; + } + + } else { // Y plane + switch (chamber) + { + case 11: + for (Int_t icirc=0; icirc<234; icirc++) { + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + Int_t nStrip=triggerCircuit->GetNstripY(); + for (Int_t istrip=0; istripGetYcode(0,istrip)==code) + fYbit11[icirc][istrip]=1; + } + } + break; + case 12: + for (Int_t icirc=0; icirc<234; icirc++) { + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + Int_t nStrip=triggerCircuit->GetNstripY(); + for (Int_t istrip=0; istripGetYcode(1,istrip)==code) + fYbit12[icirc][istrip]=1; + } + } + break; + case 13: + for (Int_t icirc=0; icirc<234; icirc++) { + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + Int_t nStrip=triggerCircuit->GetNstripY(); + for (Int_t istrip=0; istripGetYcode(2,istrip)==code) + fYbit21[icirc][istrip]=1; + } + } + break; + case 14: + for (Int_t icirc=0; icirc<234; icirc++) { + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + Int_t nStrip=triggerCircuit->GetNstripY(); + for (Int_t istrip=0; istripGetYcode(3,istrip)==code) + fYbit22[icirc][istrip]=1; + } + } + break; + } + } // if cathode + } // remove soft background + } // end loop on digit + } // end loop on cathode + } // end loop on chamber +} + +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::SetBitUpDownY(){ +// Set Y bit for up and down parts of circuits + Int_t idModule, nStripX, nStripY, iPosCircuit; + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + + for (Int_t icirc=0; icirc<234; icirc++) { + + AliMUONTriggerCircuit* circuit; // current circuit + AliMUONTriggerCircuit* circuitD; // circuit Down + AliMUONTriggerCircuit* circuitU; // circuit Up + + circuit = &(pMUON->TriggerCircuit(icirc)); + idModule=circuit->GetIdModule(); // corresponding module Id. + nStripX=circuit->GetNstripX(); // number of X strips + nStripY=circuit->GetNstripY(); // number of Y strips + iPosCircuit=circuit->GetPosCircuit(); // position of circuit in module + +// fill lower part + if (iPosCircuit==1) { // need to scan lower module + if(idModule<91&&TMath::Abs(idModule)!=41&&idModule>-91) { + Int_t icircD=circuit->GetICircuitD(); + circuitD = &(pMUON->TriggerCircuit(icircD)); + Int_t nStripD=circuitD->GetNstripY(); + + if (TMath::Abs(idModule)==42) { // shift of +8 bits + for (Int_t istrip=0; istrip17||idModule<-17)&&TMath::Abs(idModule)!=61) { + Int_t icircU=circuit->GetICircuitU(); + circuitU = &(pMUON->TriggerCircuit(icircU)); + Int_t nStripU=circuitU->GetNstripY(); + + if (TMath::Abs(idModule)==62) { // shift of +8 bits + for (Int_t istrip=0; istrip 3/4, 1 coincidence -> 4/4) +//--------------------------------------------------------- +// step # 1 : declustering, reduction DS, calculate sgle & dble +//--------------------------------------------------------- + Int_t ch1e[19], ch2e[20], ch3e[35], ch4e[36]; + Int_t sgleHit1[31], sgleHit2[63]; + Int_t dbleHit1[31], dbleHit2[63]; + + for (Int_t i=0; i<31; i++) { + sgleHit1[i]=0; + dbleHit1[i]=0; + } + for (Int_t i=0; i<63; i++) { + sgleHit2[i]=0; + dbleHit2[i]=0; + } + +//--- inititialize che using chq + for (Int_t i=0; i<19; i++) { + if (i<1||i>16) ch1e[i]=0; + else ch1e[i]=ch1q[i-1]; + } + for (Int_t i=0; i<20; i++) { + if (i<2||i>17) ch2e[i]=0; + else ch2e[i]=ch2q[i-2]; + } + for (Int_t i=0; i<35; i++) { + if (i<1||i>32) ch3e[i]=0; + else ch3e[i]=ch3q[i-1]; + } + for (Int_t i=0; i<36; i++) { + if (i<2||i>33) ch4e[i]=0; + else ch4e[i]=ch4q[i-2]; + } + + +//--- calculate dble & sgle first station + for (Int_t i=0; i<=15; i++) { + sgleHit1[2*i] = (!ch1e[i+1]|(ch1e[i]^ch1e[i+2])) & + (!ch2e[i+2] | (ch2e[i+1]^ch2e[i+3])); + + dbleHit1[2*i] = ch1e[i+1]&!(ch1e[i+2]^ch1e[i]) & + (ch2e[i+2] | (!ch2e[i]&ch2e[i+1]) | (ch2e[i+3]&!ch2e[i+4])); + } + + for (Int_t i=0; i<=14; i++) { + sgleHit1[2*i+1] = (!ch1e[i+1]|!ch1e[i+2]|(ch1e[i]^ch1e[i+3])) & + (!ch2e[i+2] | !ch2e[i+3] | (ch2e[i+1]^ch2e[i+4])); + dbleHit1[2*i+1] = ch1e[i+1]&ch1e[i+2]&!(ch1e[i]^ch1e[i+3]) & + (ch2e[i+2]&(!ch2e[i+1]|!ch2e[i]) | + ch2e[i+3]&(ch2e[i+2]|!ch2e[i+4]|!ch2e[i+5])); + } + +//--- calculate dble & sgle second station + for (Int_t i=0; i<=31; i++) { + sgleHit2[2*i] = (!ch3e[i+1]|(ch3e[i]^ch3e[i+2])) & + (!ch4e[i+2] | (ch4e[i+1]^ch4e[i+3])); + dbleHit2[2*i] = ch3e[i+1]&!(ch3e[i+2]^ch3e[i]) & + (ch4e[i+2] | (!ch4e[i]&ch4e[i+1]) | (ch4e[i+3]&!ch4e[i+4])); + } + + for (Int_t i=0; i<=30; i++) { + sgleHit2[2*i+1] = (!ch3e[i+1]|!ch3e[i+2]|(ch3e[i]^ch3e[i+3])) & + (!ch4e[i+2] | !ch4e[i+3] | (ch4e[i+1]^ch4e[i+4])); + dbleHit2[2*i+1] = ch3e[i+1]&ch3e[i+2]&!(ch3e[i]^ch3e[i+3]) & + (ch4e[i+2]&(!ch4e[i+1]|!ch4e[i]) | + ch4e[i+3]&(ch4e[i+2]|!ch4e[i+4]|!ch4e[i+5])); + } + +//--- + if(fiDebug==3||fiDebug==5) { + cout << "===============================================================" << "\n"; + cout << " X plane after sgle and dble " << " \n"; + cout << " 0987654321098765432109876543210"; + cout << "\n SGLE1 "; + for (Int_t istrip=30; istrip>=0; istrip--) { cout << (!sgleHit1[istrip]); } + cout << "\n DBLE1 "; + for (Int_t istrip=30; istrip>=0; istrip--) { cout << dbleHit1[istrip]; } + cout << "\n SGLE2 "; + for (Int_t istrip=62; istrip>=0; istrip--) { cout << (!sgleHit2[istrip]); } + cout << "\n DBLE2 "; + for (Int_t istrip=62; istrip>=0; istrip--) { cout << dbleHit2[istrip]; } + cout << "\n 210987654321098765432109876543210987654321098765432109876543210" << "\n"; + } + +//--------------------------------------------------------- +// step # 2 : coincidence 3/4 +//--------------------------------------------------------- + Int_t rearImage[31][31]; + for (Int_t i=0; i<31; i++) { + for (Int_t j=0; j<31; j++) { + rearImage[i][j]=0; + } + } + + Int_t notOr1=!dbleHit1[30] & !dbleHit1[29] & !dbleHit1[28] & !dbleHit1[27] & + !dbleHit1[26] & !dbleHit1[25] & !dbleHit1[24] & !dbleHit1[23] & + !dbleHit1[22] & !dbleHit1[21] & !dbleHit1[20] & !dbleHit1[19] & + !dbleHit1[18] & !dbleHit1[17] & !dbleHit1[16] & !dbleHit1[15] & + !dbleHit1[14] & !dbleHit1[13] & !dbleHit1[12] & !dbleHit1[11] & + !dbleHit1[10] & !dbleHit1[9] & !dbleHit1[8] & !dbleHit1[7] & + !dbleHit1[6] & !dbleHit1[5] & !dbleHit1[4] & !dbleHit1[3] & + !dbleHit1[2] & !dbleHit1[1] & !dbleHit1[0] & !coinc44; + + Int_t notOr2= !dbleHit2[62] & !dbleHit2[61] & !dbleHit2[60] & !dbleHit2[59] & + !dbleHit2[58] & !dbleHit2[57] & !dbleHit2[56] & !dbleHit2[55] & + !dbleHit2[54] & !dbleHit2[53] & !dbleHit2[52] & !dbleHit2[51] & + !dbleHit2[50] & !dbleHit2[49] & !dbleHit2[48] & !dbleHit2[47] & + !dbleHit2[46] & !dbleHit2[45] & !dbleHit2[44] & !dbleHit2[43] & + !dbleHit2[42] & !dbleHit2[41] & !dbleHit2[40] & !dbleHit2[39] & + !dbleHit2[38] & !dbleHit2[37] & !dbleHit2[36] & !dbleHit2[35] & + !dbleHit2[34] & !dbleHit2[33] & !dbleHit2[32] & !dbleHit2[31] & + !dbleHit2[30] & !dbleHit2[29] & !dbleHit2[28] & !dbleHit2[27] & + !dbleHit2[26] & !dbleHit2[25] & !dbleHit2[24] & !dbleHit2[23] & + !dbleHit2[22] & !dbleHit2[21] & !dbleHit2[20] & !dbleHit2[19] & + !dbleHit2[18] & !dbleHit2[17] & !dbleHit2[16] & !dbleHit2[15] & + !dbleHit2[14] & !dbleHit2[13] & !dbleHit2[12] & !dbleHit2[11] & + !dbleHit2[10] & !dbleHit2[9] & !dbleHit2[8] & !dbleHit2[7] & + !dbleHit2[6] & !dbleHit2[5] & !dbleHit2[4] & !dbleHit2[3] & + !dbleHit2[2] & !dbleHit2[1] & !dbleHit2[0] & !coinc44; + +// DS reduction + for (Int_t i=0; i<31; i++) { + sgleHit1[i] = !sgleHit1[i]¬Or1; + } + for (Int_t i=0; i<63; i++) { + sgleHit2[i] = !sgleHit2[i]¬Or2; + } + +// extract rearImage + for (Int_t i=0; i<31; i++){ + Int_t tmpSgleHit2[31]; + Int_t tmpDbleHit2[31]; + for (Int_t j=0; j<31; j++){ + tmpSgleHit2[j] = sgleHit2[i+j+1]; + tmpDbleHit2[j] = dbleHit2[i+j+1]; + } + + for (Int_t k=0; k<31; k++) { + rearImage[i][k]=(sgleHit1[i]&tmpDbleHit2[k])| + (dbleHit1[i]&(tmpSgleHit2[k]|tmpDbleHit2[k])); + } + } + + //----------- + if(fiDebug==3||fiDebug==5) { + cout << "===============================================================" << "\n"; + for (Int_t i=30; i>=0; i--) { + cout << i << "\t "; + for (Int_t istrip=31; istrip>=0; istrip--) { + cout << rearImage[i][istrip]; + } + cout << " " << "\n"; + } + } + + +//--------------------------------------------------------- +// step # 3 : calculate deviation +//--------------------------------------------------------- + Int_t dev[31][6]; + for (Int_t i=0; i<31; i++) { + for (Int_t j=0; j<6; j++) { + dev[i][j]=0; + } + } + + for (Int_t i=0; i<31; i++){ + Int_t leftDev[5], rightDev[5]; + Int_t orL1, andL1, andL2, orR1, orR2, andR1, andR2, andR3; + +// calculate Left deviation + orL1=rearImage[i][16]|rearImage[i][18]|rearImage[i][20]|rearImage[i][22]; + andL1=!rearImage[i][17]&!rearImage[i][19]&!rearImage[i][21] & !orL1; + andL2=!rearImage[i][23]&!rearImage[i][24]&!rearImage[i][25]&!rearImage[i][26]; + + leftDev[0] = (rearImage[i][16]|!rearImage[i][17]) & + (rearImage[i][16]|rearImage[i][18]|!rearImage[i][19]& + (rearImage[i][20]|!rearImage[i][21])) & + (orL1|!rearImage[i][23]&(rearImage[i][24]|!rearImage[i][25])) & + (orL1|rearImage[i][24]|rearImage[i][26]|!rearImage[i][27]& + (rearImage[i][28]|!rearImage[i][29])); + + leftDev[1] = !rearImage[i][16] & + !(!rearImage[i][17]&!rearImage[i][18]&!rearImage[i][21]&!rearImage[i][22] & + (!rearImage[i][25]&!rearImage[i][26]&(rearImage[i][27]|rearImage[i][28]))) & + (rearImage[i][17]|rearImage[i][18] | !rearImage[i][19]&!rearImage[i][20]) & + (rearImage[i][17]|rearImage[i][18]|rearImage[i][21]|rearImage[i][22] | + !rearImage[i][23]&!rearImage[i][24]); + + leftDev[2] = (!rearImage[i][16]&!rearImage[i][17]&!rearImage[i][18]) & + (rearImage[i][19]|rearImage[i][20]|rearImage[i][21]|rearImage[i][22] | andL2); + + leftDev[3] = andL1; + + leftDev[4] = + !rearImage[i][27]&!rearImage[i][28]&!rearImage[i][29]&!rearImage[i][30] & + andL1 & andL2; + + // calculate Right deviation + orR1=rearImage[i][8]|rearImage[i][10]|rearImage[i][12]|rearImage[i][14]; + orR2=rearImage[i][8]|rearImage[i][9]|rearImage[i][10]|rearImage[i][11]; + andR1=!rearImage[i][12]&!rearImage[i][13]&!rearImage[i][14]&!rearImage[i][15]; + andR2= + !rearImage[i][8]&!rearImage[i][9]&!rearImage[i][10]&!rearImage[i][11] & andR1; + andR3=!rearImage[i][4]&!rearImage[i][5]&!rearImage[i][6]&!rearImage[i][7]; + + rightDev[0] = !rearImage[i][15]&(rearImage[i][14]|!rearImage[i][13]) & + ((rearImage[i][12]|rearImage[i][14]|!rearImage[i][11]& + (rearImage[i][10]|!rearImage[i][9])) & + ((orR1|!rearImage[i][7]&(rearImage[i][6]|!rearImage[i][5])) & + (orR1|rearImage[i][4]|rearImage[i][6]|!rearImage[i][3]&(rearImage[i][2]| + !rearImage[i][1])))); + + rightDev[1] = !rearImage[i][15]&!rearImage[i][14] & + !(!rearImage[i][4]&!rearImage[i][5]&!rearImage[i][8]&!rearImage[i][9] & + (!rearImage[i][12]&!rearImage[i][13]&(rearImage[i][2]|rearImage[i][3]))) & + (rearImage[i][12]|rearImage[i][13] | !rearImage[i][10]&!rearImage[i][11]) & + (rearImage[i][8]|rearImage[i][9]|rearImage[i][12]|rearImage[i][13] | + !rearImage[i][6]&!rearImage[i][7]); + + rightDev[2] = andR1 & (orR2 | andR3); + rightDev[3] = andR2; + rightDev[4] = + !rearImage[i][0]&!rearImage[i][1]&!rearImage[i][2]&!rearImage[i][3] & + andR2 & andR3 ; + + // compare Left & Right deviations + Int_t tmpLeftDev=0, tmpRightDev=0; + for (Int_t j=0; j<5; j++){ + tmpLeftDev = tmpLeftDev + Int_t(leftDev[j]*pow(2,j)); + tmpRightDev = tmpRightDev + Int_t(rightDev[j]*pow(2,j)); + } + + // assign mimimum deviation do dev[][] + if (tmpLeftDev < tmpRightDev ){ + for (Int_t j=0; j<5; j++){ dev[i][j]=leftDev[j];} + dev[i][5]=1; + } else { + for (Int_t j=0; j<5; j++){ dev[i][j]=rightDev[j];} + dev[i][5]=0; + } + } + +//--- + if(fiDebug==3||fiDebug==5) { + cout << "===============================================================" << "\n"; + for (Int_t i=30; i>=0; i--) { + cout << i << "\t "; + for (Int_t istrip=5; istrip>=0; istrip--) { cout << dev[i][istrip]; } + cout << " " << "\n"; + } + } + +//--------------------------------------------------------- +// step # 4 : sort deviation +//--------------------------------------------------------- + Int_t bga1[16], bga2[8], bga3[4], bga4[2], bga5; + Int_t tmpbga1[16][6], tmpbga2[8][6], tmpbga3[4][6], tmpbga4[2][6], tmpbga5[6]; + Int_t tmpMax[6]={1,1,1,1,1,0}; + + for (Int_t i=0; i<15; i++) { + Sort2x5(dev[2*i],dev[2*i+1],tmpbga1[i],bga1[i]); + } + Sort2x5(dev[30],tmpMax,tmpbga1[15],bga1[15]); + +//-- + if(fiDebug==3||fiDebug==5) { + cout << "===============================================================" << "\n"; + cout << " sorting : 1st level " << "\n"; + for (Int_t i=15; i>=0; i--) { + cout << i << "\t " << bga1[i] << "\t"; + for (Int_t j=5; j>=0; j--) { + cout << tmpbga1[i][j]; + } + cout << " " << "\n"; + } + } + + for (Int_t i=0; i<8; i++) { + Sort2x5(tmpbga1[2*i],tmpbga1[2*i+1],tmpbga2[i],bga2[i]); + } + +//-- + if(fiDebug==3||fiDebug==5) { + cout << "===============================================================" << "\n"; + cout << " sorting : 2nd level " << "\n"; + for (Int_t i=7; i>=0; i--) { + cout << i << "\t " << bga2[i] << "\t"; + for (Int_t j=5; j>=0; j--) { + cout << tmpbga2[i][j]; + } + cout << " " << "\n"; + } + } + + for (Int_t i=0; i<4; i++) { + Sort2x5(tmpbga2[2*i],tmpbga2[2*i+1],tmpbga3[i],bga3[i]); + } + +//-- + if(fiDebug==3||fiDebug==5) { + cout << "===============================================================" << "\n"; + cout << " sorting : 3rd level " << "\n"; + for (Int_t i=3; i>=0; i--) { + cout << i << "\t " << bga3[i] << "\t"; + for (Int_t j=5; j>=0; j--) { + cout << tmpbga3[i][j]; + } + cout << " " << "\n"; + } + } + + for (Int_t i=0; i<2; i++) { + Sort2x5(tmpbga3[2*i],tmpbga3[2*i+1],tmpbga4[i],bga4[i]); + } + +//-- + if(fiDebug==3||fiDebug==5) { + cout << "===============================================================" << "\n"; + cout << " sorting : 4th level " << "\n"; + for (Int_t i=1; i>=0; i--) { + cout << i << "\t " << bga4[i] << "\t"; + for (Int_t j=5; j>=0; j--) { + cout << tmpbga4[i][j]; + } + cout << " " << "\n"; + } + } + + Sort2x5(tmpbga4[0],tmpbga4[1],tmpbga5,bga5); + + // coding from 6 to 5 bits + minDev[4] = tmpbga5[5] | tmpbga5[4]; + for (Int_t i=0; i<4; i++) { + minDev[i]=tmpbga5[i] & !tmpbga5[4]; + } + + // find address of strip with minimum deviation + minDevStrip[4]=bga5; + if (bga5<=1) minDevStrip[3]=bga4[bga5]; + + Int_t tmpAd=minDevStrip[3]+minDevStrip[4]*2; + if (tmpAd<=3) minDevStrip[2]=bga3[tmpAd]; + + tmpAd=minDevStrip[2]+minDevStrip[3]*2+minDevStrip[4]*4; + if (tmpAd<=7) minDevStrip[1]=bga2[tmpAd]; + + tmpAd=minDevStrip[1]+minDevStrip[2]*2+minDevStrip[3]*4+minDevStrip[4]*8; + if (tmpAd<=15) minDevStrip[0]=bga1[tmpAd]; + + if(fiDebug==3||fiDebug==5) { + cout << "===============================================================" << "\n"; + cout << "minDevStrip = "; + for (Int_t i=4; i>=0; i--) {cout << minDevStrip[i];} + cout << " minDev = "; + for (Int_t i=4; i>=0; i--) {cout << minDev[i];} + cout << " " << "\n"; + cout << "===============================================================" << "\n"; + } + +} + +//--------------------------------------------- +void AliMUONTriggerDecision::Sort2x5(Int_t dev1[6], Int_t dev2[6], + Int_t minDev[6], Int_t &dev1GTdev2){ +// returns minimun between dev1 and dev2 + Int_t tmpDev1=0, tmpDev2=0; + for (Int_t j=0; j<5; j++){ + tmpDev1 = tmpDev1 + Int_t(dev1[j]*pow(2,j)); + tmpDev2 = tmpDev2 + Int_t(dev2[j]*pow(2,j)); + } + if (tmpDev1 <= tmpDev2 ){ + for (Int_t j=0; j<=5; j++) { minDev[j]=dev1[j];} + dev1GTdev2=0; + } else { + for (Int_t j=0; j<=5; j++) { minDev[j]=dev2[j];} + dev1GTdev2=1; + } +} + +//---------------------------------------------------------------------- +// y part of trigger Algo +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::TrigY(Int_t y1[16], Int_t y2[16], + Int_t y3[16], Int_t y4[16], + Int_t y3u[16], Int_t y3d[16], + Int_t y4u[16], Int_t y4d[16], + Int_t x2m, Int_t x2ud, Int_t orMud[2], + Int_t resetMid, Int_t coinc44, + Int_t coordY[5]){ +// note : resMid = 1 -> cancel +//--------------------------------------------------------- +// step # 1 : prehandling Y +//--------------------------------------------------------- + for (Int_t i=0; i<16; i++){ + y3[i]=y3[i]&!resetMid; + y4[i]=y4[i]&!resetMid; + } + + Int_t ch1[16], ch2[16], ch3[16], ch4[16]; + + Int_t tmpy3to16[16], tmpy4to16[16]; + Int_t tmpy3uto16[16], tmpy3dto16[16], tmpy4uto16[16], tmpy4dto16[16]; + for (Int_t i=0; i<8; i++){ + ch1[2*i] = y1[i]&x2m | y1[2*i]&!x2m; + ch1[2*i+1] = y1[i]&x2m | y1[2*i+1]&!x2m; + + ch2[2*i] = y2[i]&x2m | y2[2*i]&!x2m; + ch2[2*i+1] = y2[i]&x2m | y2[2*i+1]&!x2m; + + tmpy3to16[2*i] = y3[i]&x2m | y3[2*i]&!x2m; + tmpy3to16[2*i+1] = y3[i]&x2m | y3[2*i+1]&!x2m; + + tmpy4to16[2*i] = y4[i]&x2m | y4[2*i]&!x2m; + tmpy4to16[2*i+1] = y4[i]&x2m | y4[2*i+1]&!x2m; + + tmpy3uto16[2*i] = y3u[i]&x2ud | y3u[2*i]&!x2ud; + tmpy3uto16[2*i+1] = y3u[i]&x2ud | y3u[2*i+1]&!x2ud; + + tmpy4uto16[2*i] = y4u[i]&x2ud | y4u[2*i]&!x2ud; + tmpy4uto16[2*i+1] = y4u[i]&x2ud | y4u[2*i+1]&!x2ud; + + tmpy3dto16[2*i] = y3d[i]&x2ud | y3d[2*i]&!x2ud; + tmpy3dto16[2*i+1] = y3d[i]&x2ud | y3d[2*i+1]&!x2ud; + + tmpy4dto16[2*i] = y4d[i]&x2ud | y4d[2*i]&!x2ud; + tmpy4dto16[2*i+1] = y4d[i]&x2ud | y4d[2*i+1]&!x2ud; + } + + if (orMud[0]==0&&orMud[1]==0){ + for (Int_t i=0; i<16; i++){ + ch3[i] = tmpy3to16[i]; + ch4[i] = tmpy4to16[i]; + } + } + if (orMud[0]==0&&orMud[1]==1){ + for (Int_t i=0; i<16; i++){ + ch3[i] = tmpy3uto16[i]|tmpy3to16[i]; + ch4[i] = tmpy4uto16[i]|tmpy4to16[i]; + } + } + if (orMud[0]==1&&orMud[1]==0){ + for (Int_t i=0; i<16; i++){ + ch3[i] = tmpy3dto16[i]|tmpy3to16[i]; + ch4[i] = tmpy4dto16[i]|tmpy4to16[i]; + } + } + if (orMud[0]==1&&orMud[1]==1){ + for (Int_t i=0; i<16; i++){ + ch3[i] = tmpy3dto16[i]|tmpy3to16[i]|tmpy3uto16[i]; + ch4[i] = tmpy4dto16[i]|tmpy4to16[i]|tmpy4uto16[i]; + } + } + +// debug + if(fiDebug==4||fiDebug==5) { + cout << "===============================================================" << "\n"; + cout << " Y plane after PreHandling x2m x2ud orMud " + << x2m << " , " << x2ud << " , " << orMud[0] << orMud[1] << "\n"; + cout << " "; + for (Int_t istrip=15; istrip>=0; istrip--) { + if (istrip>9) cout << istrip-10*Int_t(istrip/10); + if (istrip<10) cout << istrip; + } + cout << "\n YMC11 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << ch1[istrip]; + } + cout << "\n YMC12 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << ch2[istrip]; + } + cout << "\n YMC21 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << ch3[istrip]; + } + cout << "\n YMC22 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << ch4[istrip]; + } + cout << " \n"; + } +//debug + +//--------------------------------------------------------- +// step # 2 : calculate sgle and dble, apply DS reduction +//--------------------------------------------------------- + Int_t sgle1[16], dble1[16]; + Int_t sgle2[16], dble2[16]; + + // Calculate simple and double hits + for (Int_t i=0; i<16; i++) { + dble1[i] = ch1[i] & ch2[i]; + dble2[i] = ch3[i] & ch4[i]; + + sgle1[i] = (ch1[i]|ch2[i]); + sgle2[i] = (ch3[i]|ch4[i]); + } + + //debug + if(fiDebug==4||fiDebug==5) { + cout << "===============================================================" << "\n"; + cout << " Y plane after sgle dble " << "\n"; + cout << " "; + for (Int_t istrip=15; istrip>=0; istrip--) { + if (istrip>9) { cout << istrip-10*Int_t(istrip/10);} + if (istrip<10) { cout << istrip;} + } + cout << "\n SGLE1 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << sgle1[istrip]; + } + cout << "\n DBLE1 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << dble1[istrip]; + } + cout << "\n SGLE2 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << sgle2[istrip]; + } + cout << "\n DBLE2 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << dble2[istrip]; + } + cout << " \n"; + } + //debug + + // DS Reduction + Int_t notOr1, notOr2; + + notOr1=!dble1[15] & !dble1[14] & !dble1[13] & !dble1[12] & + !dble1[11] & !dble1[10] & !dble1[9] & !dble1[8] & + !dble1[7] & !dble1[6] & !dble1[5] & !dble1[4] & + !dble1[3] & !dble1[2] & !dble1[1] & !dble1[0]; + + notOr2=!dble2[15] & !dble2[14] & !dble2[13] & !dble2[12] & + !dble2[11] & !dble2[10] & !dble2[9] & !dble2[8] & + !dble2[7] & !dble2[6] & !dble2[5] & !dble2[4] & + !dble2[3] & !dble2[2] & !dble2[1] & !dble2[0]; + + for (Int_t i=0; i<16; i++) { + sgle1[i] = sgle1[i] & notOr1 & !coinc44; + sgle2[i] = sgle2[i] & notOr2 & !coinc44; + } + +//--------------------------------------------------------- +// step # 3 : 3/4 coincidence +//--------------------------------------------------------- + Int_t frontImage[16]; + + for (Int_t i=1; i<15; i++) { + frontImage[i] = (dble1[i] | sgle1[i]) & + (dble2[i+1] | dble2[i] | dble2[i-1]) | + dble1[i] & (sgle2[i+1] | sgle2[i] | sgle2[i-1]); + } + frontImage[0] = (dble1[0] | sgle1[0]) & + (dble2[1] | dble2[0]) | dble1[0] & (sgle2[1] | sgle2[0]); + + frontImage[15] = (dble1[15] | sgle1[15]) & + (dble2[15] | dble2[14]) | dble1[15] & (sgle2[15] | sgle2[14]); + + +//debug + if(fiDebug==4||fiDebug==5) { + cout << "===============================================================" << "\n"; + cout << " Y plane frontImage\n"; + cout << " "; + for (Int_t istrip=15; istrip>=0; istrip--) { + if (istrip>9) cout << istrip-10*Int_t(istrip/10); + if (istrip<10) cout << istrip; + } + cout << "\n "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << frontImage[istrip]; + } + cout << "\n"; + } +//debug + +//--------------------------------------------------------- +// step # 4 : Y position +//--------------------------------------------------------- + Int_t or1, or2, and1, and2, and3; + + or1 = frontImage[7]|frontImage[5]|frontImage[3]|frontImage[1]; + or2 = frontImage[7]|frontImage[6]|frontImage[5]|frontImage[4]; + and1 = !frontImage[3]&!frontImage[2]&!frontImage[1]&!frontImage[0]; + and2 = !frontImage[7]&!frontImage[6]&!frontImage[5]&!frontImage[4] & and1; + and3 = !frontImage[11]&!frontImage[10]&!frontImage[9]&!frontImage[8]; + + coordY[0] = !frontImage[0]&(frontImage[1]|!frontImage[2]) & +(frontImage[3]|frontImage[1]|!frontImage[4]&(frontImage[5]|!frontImage[6])) & +(or1|!frontImage[8]&(frontImage[9]|!frontImage[10])) & +(or1|frontImage[11]|frontImage[9]|!frontImage[12]&(frontImage[13]|!frontImage[14])); + + coordY[1] = !frontImage[0]&!frontImage[1] & +!(!frontImage[11]&!frontImage[10]&!frontImage[7]&!frontImage[6] & + !frontImage[3]&!frontImage[2]&(frontImage[13]|frontImage[12])) & + (frontImage[3]|frontImage[2] | !frontImage[5]&!frontImage[4]) & + (frontImage[7]|frontImage[6]|frontImage[3]|frontImage[2] | +!frontImage[9]&!frontImage[8]); + + coordY[2] = and1 & (or2 | and3); + + coordY[3] = and2; + + coordY[4] = !frontImage[15]&!frontImage[14]&!frontImage[13]&!frontImage[12] & + and2 & and3 ; + +} +//---------------------------------------------------------------------- +// end of trigger Algo +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::LocalTrigger(Int_t icirc, + Int_t minDevStrip[5], + Int_t minDev[5], Int_t coordY[5], + Int_t &iTrigger){ +// returns local trigger answer for circuit icirc + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONTriggerCircuit* triggerCircuit; + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + Int_t idCircuit=triggerCircuit->GetIdCircuit(); + + Int_t signDev=minDev[4]; + Int_t deviation=0; + for (Int_t i=0; i<4; i++) { // extract deviation + deviation = deviation+Int_t(minDev[i]*pow(2,i)); + } + + Int_t istripX1Circ=0; + for (Int_t i=0; i<5; i++) { // extract X1 strip fired + istripX1Circ = istripX1Circ+Int_t(minDevStrip[i]*pow(2,i)); + } + + Int_t iStripY=0; + for (Int_t i=0; i<4; i++) { // extract Y strip fired + iStripY = iStripY+Int_t(coordY[i]*pow(2,i)); + } + +// trigger or not + if (signDev==1&&deviation==0) { // something in X ? + iTrigger=0; + } else { + if (coordY[4]==1&&iStripY==15) { // something in Y ? + iTrigger=0; + } else { + iTrigger=1; + } + } + + if (iTrigger==1) { +// fill fiTrigger fStripX11 fStripY11 + fiTrigger[icirc] = 1; + fStripX11[icirc] = istripX1Circ; + fStripY11[icirc] = iStripY; + +// calculate deviation in [0+30] + Int_t sign=0; + if (signDev==0&&deviation!=0) sign=-1; + if (signDev==0&&deviation==0) sign=0; + if (signDev==1) sign=1; + fdev[icirc] = sign * deviation + 15; // fill fdev + +// get Lut output for circuit/istripX/idev/istripY + AliMUONTriggerLut* lut = new AliMUONTriggerLut; + // lut->StartEvent(); + lut->GetLutOutput(icirc,fStripX11[icirc],fdev[icirc],fStripY11[icirc], + fLutLpt[icirc],fLutHpt[icirc],fLutApt[icirc]); + // lut->FinishEvent(); + delete lut; + + if (fiDebug>1) { + Float_t pt= // get ptCal corresponding to istripX1Circ/idev/iStripY + triggerCircuit->PtCal(fStripX11[icirc],fdev[icirc],fStripY11[icirc]); + cout << "-------------------------------------------" << "\n"; + cout << " Local Trigger info for circuit Id " << idCircuit + << " (number " << icirc << ")" << "\n"; + cout << " istripX1 signDev deviation istripY = " + << istripX1Circ << " , " << signDev + << " , " << deviation << " , " << iStripY << "\n"; + cout << " pt = " << pt << " (GeV/c) " << "\n"; + cout << "-------------------------------------------" << "\n"; + cout << " Local Trigger Lut Output = Lpt : " ; + for (Int_t i=1; i>=0; i--) { cout << fLutLpt[icirc][i] ; } + cout << " Hpt : "; + for (Int_t i=1; i>=0; i--) { cout << fLutHpt[icirc][i] ; } + cout << " Apt : "; + for (Int_t i=1; i>=0; i--) { cout << fLutApt[icirc][i] ; } + cout << "\n"; + cout << "-------------------------------------------" << "\n"; + } // fiDebug > 1 + } // local trigger = 1 +} + +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::GlobalTrigger(){ +// loop on Lut[icirc] and give Global Trigger output + + for (Int_t icirc=0; icirc<234; icirc++){ + if (fLutLpt[icirc][0]==1&&fLutLpt[icirc][1]==1) + fGlobalSingleUndef[0] = fGlobalSingleUndef[0] + 1; + if (fLutHpt[icirc][0]==1&&fLutHpt[icirc][1]==1) + fGlobalSingleUndef[1] = fGlobalSingleUndef[1] + 1; + if (fLutApt[icirc][0]==1&&fLutApt[icirc][1]==1) + fGlobalSingleUndef[2] = fGlobalSingleUndef[2] + 1; + + if (fLutLpt[icirc][0]==0&&fLutLpt[icirc][1]==1) + fGlobalSinglePlus[0] = fGlobalSinglePlus[0] + 1; + if (fLutHpt[icirc][0]==0&&fLutHpt[icirc][1]==1) + fGlobalSinglePlus[1] = fGlobalSinglePlus[1] + 1; + if (fLutApt[icirc][0]==0&&fLutApt[icirc][1]==1) + fGlobalSinglePlus[2] = fGlobalSinglePlus[2] + 1; + + if (fLutLpt[icirc][0]==1&&fLutLpt[icirc][1]==0) + fGlobalSingleMinus[0] = fGlobalSingleMinus[0] + 1; + if (fLutHpt[icirc][0]==1&&fLutHpt[icirc][1]==0) + fGlobalSingleMinus[1] = fGlobalSingleMinus[1] + 1; + if (fLutApt[icirc][0]==1&&fLutApt[icirc][1]==0) + fGlobalSingleMinus[2] = fGlobalSingleMinus[2] + 1; + } + + // like sign low, high and all pt + for (Int_t i=0; i<3; i++) { + fGlobalPairLike[i]=fGlobalSingleMinus[i]*(fGlobalSingleMinus[i]-1)/2 + + fGlobalSinglePlus[i]*(fGlobalSinglePlus[i]-1)/2 + + fGlobalSingleUndef[i]*(fGlobalSingleUndef[i]-1)/2 + + fGlobalSingleUndef[i]*fGlobalSinglePlus[i] + + fGlobalSingleUndef[i]*fGlobalSingleMinus[i]; + } + + // unlike sign low, high and all pt + for (Int_t i=0; i<3; i++) { + fGlobalPairUnlike[i]=fGlobalSingleMinus[i]*fGlobalSinglePlus[i] + + fGlobalSingleUndef[i]*(fGlobalSingleUndef[i]-1)/2 + + fGlobalSingleUndef[i]*fGlobalSinglePlus[i] + + fGlobalSingleUndef[i]*fGlobalSingleMinus[i]; + } + + if (fiDebug>=1) { + cout << "\n"; + cout << "===================================================" << "\n"; + cout << " Global Trigger output " << "Low pt High pt All" << "\n"; + cout << " number of Single Plus :\t"; + for (Int_t i=0; i<3; i++) { cout << fGlobalSinglePlus[i] <<"\t";} + cout << "\n"; + cout << " number of Single Minus :\t"; + for (Int_t i=0; i<3; i++) { cout << fGlobalSingleMinus[i] <<"\t";} + cout << "\n"; + cout << " number of Single Undefined :\t"; + for (Int_t i=0; i<3; i++) { cout << fGlobalSingleUndef[i] <<"\t";} + cout << "\n"; + cout << " number of UnlikeSign pair :\t"; + for (Int_t i=0; i<3; i++) { cout << fGlobalPairUnlike[i] <<"\t";} + cout << "\n"; + cout << " number of LikeSign pair :\t"; + for (Int_t i=0; i<3; i++) { cout << fGlobalPairLike[i] <<"\t";} + cout << "\n"; + cout << "===================================================" << "\n"; + } +} + +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::PrintBitPatXInput(Int_t icirc){ +// print bit pattern for X strips + + cout << "-------- TRIGGER INPUT ---------" << "\n"; + cout << "===============================================================" << "\n"; + cout << " 5432109876543210"; + cout << "\n XMC11 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << fXbit11[icirc][istrip]; + } + cout << "\n XMC12 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << fXbit12[icirc][istrip]; + } + cout << "\n XMC21 "; + for (Int_t istrip=31; istrip>=0; istrip--) { + cout << fXbit21[icirc][istrip]; + } + cout << "\n XMC22 "; + for (Int_t istrip=31; istrip>=0; istrip--) { + cout << fXbit22[icirc][istrip]; + } + cout << "\n "; + cout << "10987654321098765432109876543210" << "\n"; +} + +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::PrintBitPatYInput(Int_t icirc){ +// print bit pattern for Y strips + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONTriggerCircuit* triggerCircuit; + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + Int_t idCircuit=triggerCircuit->GetIdCircuit(); + Int_t nStrip=triggerCircuit->GetNstripY(); + + cout << "---------------------------------------------------------------" << "\n"; + cout << " "; + for (Int_t istrip=nStrip-1; istrip>=0; istrip--) { + if (istrip>9) { cout << istrip-10*Int_t(istrip/10);} + if (istrip<10) { cout << istrip;} + } + cout << "\n YMC11 "; + for (Int_t istrip=nStrip-1; istrip>=0; istrip--) { + cout << fYbit11[icirc][istrip]; + } + cout << "\n YMC12 "; + for (Int_t istrip=nStrip-1; istrip>=0; istrip--) { + cout << fYbit12[icirc][istrip]; + } + cout << "\n YMC21 "; + for (Int_t istrip=nStrip-1; istrip>=0; istrip--) { + cout << fYbit21[icirc][istrip]; + } + cout << "\n YMC22 "; + for (Int_t istrip=nStrip-1; istrip>=0; istrip--) { + cout << fYbit22[icirc][istrip]; + } + cout << "\n"; +// tmp + cout << "---------------------------------------------------------------"; + cout << "\n upper part of circuit " << idCircuit ; + cout << "\n UMC21 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << fYbit21U[icirc][istrip]; + } + cout << "\n UMC22 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << fYbit22U[icirc][istrip]; + } + + cout << "\n lower part of circuit " << idCircuit ; + cout << "\n LMC21 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << fYbit21D[icirc][istrip]; + } + cout << "\n LMC22 "; + for (Int_t istrip=15; istrip>=0; istrip--) { + cout << fYbit22D[icirc][istrip]; + } + cout << "\n"; + cout << "===============================================================" << "\n"; +} +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::PrintLocalOutput(Int_t minDevStrip[5], + Int_t minDev[5], + Int_t coordY[5]){ +// print Local trigger output before the LuT step + cout << "===============================================================" << "\n"; + cout << "-------- TRIGGER OUTPUT --------" << "\n"; + cout << "minDevStrip = "; + for (Int_t i=4; i>=0; i--) {cout << minDevStrip[i];} + cout << " minDev = "; + for (Int_t i=4; i>=0; i--) {cout << minDev[i];} + cout << " coordY = "; + for (Int_t i=4; i>=0; i--) {cout << coordY[i];} + cout << " " << "\n"; +} + +//---------------------------------------------------------------------- +//--- methods which return member data related info +//---------------------------------------------------------------------- +Int_t AliMUONTriggerDecision::GetITrigger(Int_t icirc){ +// returns Local Trigger Status + return fiTrigger[icirc]; +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerDecision::GetStripX11(Int_t icirc){ +// returns fStripX11 + return fStripX11[icirc]; +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerDecision::GetDev(Int_t icirc){ +// returns idev + return fdev[icirc]; +} +//---------------------------------------------------------------------- +Int_t AliMUONTriggerDecision::GetStripY11(Int_t icirc){ +// returns fStripY11; + return fStripY11[icirc]; +} +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::GetLutOutput(Int_t icirc, Int_t lpt[2], + Int_t hpt[2], Int_t apt[2]){ +// returns Look up Table output + for (Int_t i=0; i<2; i++) { + lpt[i]=fLutLpt[icirc][i]; + hpt[i]=fLutHpt[icirc][i]; + apt[i]=fLutApt[icirc][i]; + } +} +//---------------------------------------------------------------------- +void AliMUONTriggerDecision::GetGlobalTrigger(Int_t singlePlus[3], + Int_t singleMinus[3], + Int_t singleUndef[3], + Int_t pairUnlike[3], + Int_t pairLike[3]){ +// returns Global Trigger information (0,1,2 : Lpt,Hpt,Apt) + for (Int_t i=0; i<3; i++) { + singlePlus[i] = fGlobalSinglePlus[i]; + singleMinus[i] = fGlobalSingleMinus[i]; + singleUndef[i] = fGlobalSingleUndef[i]; + pairUnlike[i] = fGlobalPairUnlike[i]; + pairLike[i] = fGlobalPairLike[i]; + } +} +//---------------------------------------------------------------------- +//--- end of methods which return member data related info +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +/* +void AliMUONTriggerDecision::AddLocalTrigger(const AliMUONLocalTrigger c){ +// Add a Local Trigger copy to the list + AliMUON *MUON=(AliMUON*)gAlice->GetModule("MUON"); + MUON->AddLocalTrigger(c); + fNLocalTriggers++; +} +*/ diff --git a/MUON/AliMUONTriggerDecision.h b/MUON/AliMUONTriggerDecision.h new file mode 100644 index 00000000000..93959f586b6 --- /dev/null +++ b/MUON/AliMUONTriggerDecision.h @@ -0,0 +1,110 @@ +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ +/* $Id$ */ +#ifndef ALIMUONTRIGGERDECISION_H +#define ALIMUONTRIGGERDECISION_H +//////////////////////////////////////////////// +// MUON Trigger Decision Class // +//////////////////////////////////////////////// +#include "TObject.h" + +class AliMUONHitMapA1; +class TF1; +class TClonesArray; +class AliMUONSegmentation; +class AliMUONResponse; + +class AliMUONTriggerDecision : +public TObject { + public: + AliMUONTriggerDecision(Int_t iprint); // constructor + ~AliMUONTriggerDecision(); // destructor + + void Trigger(); + void ResetBit(); + void SetBit(); + void SetBitUpDownY(); + + void TrigX(Int_t ch1q[16], Int_t ch2q[16], Int_t ch3q[32], Int_t ch4q[32], + Int_t coinc44, Int_t minDevStrip[5], Int_t minDev[5]); + void Sort2x5(Int_t dev1[6], Int_t dev2[6], + Int_t minDev[6], Int_t &dev1GTdev2); + void TrigY(Int_t y1[16], Int_t y2[16], Int_t y3[16], Int_t y4[16], + Int_t y3u[16], Int_t y3d[16], Int_t y4u[16], Int_t y4d[16], + Int_t x2m, Int_t x2ud, Int_t orMud[2], Int_t resetMid, + Int_t coinc44, Int_t coordY[5]); + void LocalTrigger(Int_t icirc, Int_t minDevStrip[5], + Int_t minDev[5], Int_t coordY[5], + Int_t &iTrigger); + void GlobalTrigger(); + + // print-debug + void PrintBitPatXInput(Int_t icirc); + void PrintBitPatYInput(Int_t icirc); + void PrintLocalOutput(Int_t minDevStrip[5], Int_t minDev[5], + Int_t coordY[5]); + + // return member data information + Int_t GetITrigger(Int_t icirc); + Int_t GetStripX11(Int_t icirc); + Int_t GetDev(Int_t icirc); + Int_t GetStripY11(Int_t icirc); + void GetLutOutput(Int_t icirc, Int_t lpt[2], Int_t hpt[2], Int_t apt[2]); + void GetGlobalTrigger(Int_t singlePlus[3], Int_t singleMinus[3], + Int_t singleUndef[3], Int_t pairUnlike[3], + Int_t pairLike[3]); + +// Add a new Local Trigger + // virtual void AddLocalTrigger(const AliMUONLocalTrigger); +// Return pointer to Local Triggers + // TClonesArray* LocalTriggers(){return fLocalTriggers;} + + ClassDef(AliMUONTriggerDecision,1) // Trigger Decision class + + protected: + Int_t fiDebug; // print option + + // Global Trigger information [0] : Low pt, [1] : High pt, [2] : All pt + Int_t fGlobalSinglePlus[3]; // tot num of single plus + Int_t fGlobalSingleMinus[3]; // tot num of single minus + Int_t fGlobalSingleUndef[3]; // tot num of single undefined + Int_t fGlobalPairUnlike[3]; // tot num of unlike-sign pairs + Int_t fGlobalPairLike[3]; // tot num of like-sign pairs + + // Local Trigger information + Int_t fiTrigger[234]; // fiTrigger = 0 : no trigger, 1 : trigger + Int_t fStripX11[234]; // X strip in MC11 which triggers + Int_t fdev[234]; // deviation which triggers + Int_t fStripY11[234]; // Y strip in MC11 which triggers + Int_t fLutLpt[234][2]; // Local Trigger info Low pt + Int_t fLutHpt[234][2]; // Local Trigger info High pt + Int_t fLutApt[234][2]; // Local Trigger info All pt + + // bit pattern + Int_t fXbit11[234][16]; // bit pattern XM11 + Int_t fXbit12[234][16]; // bit pattern XM12 + Int_t fXbit21[234][32]; // bit pattern XM21 + Int_t fXbit22[234][32]; // bit pattern XM22 + Int_t fYbit11[234][16]; // bit pattern YM11 + Int_t fYbit12[234][16]; // bit pattern YM12 + Int_t fYbit21[234][16]; // bit pattern YM21 + Int_t fYbit22[234][16]; // bit pattern YM22 + + Int_t fYbit21U[234][16]; // bit pattern YM21 Up + Int_t fYbit22U[234][16]; // bit pattern YM22 Up + Int_t fYbit21D[234][16]; // bit pattern YM21 Down + Int_t fYbit22D[234][16]; // bit pattern YM22 Down + + // ??? + // TClonesArray* fLocalTriggers; // Local Triggers + // Int_t fNLocalTriggers; // Number of Local Triggers + +}; +#endif + + + + + + + diff --git a/MUON/AliMUONTriggerLut.cxx b/MUON/AliMUONTriggerLut.cxx new file mode 100644 index 00000000000..8b3081ea6e8 --- /dev/null +++ b/MUON/AliMUONTriggerLut.cxx @@ -0,0 +1,260 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ +/* + + +*/ +#include "AliMUONTriggerLut.h" +#include "TTree.h" +#include "AliRun.h" +#include "AliMUON.h" +#include "AliMUONPoints.h" +#include "TMath.h" +#include "TFile.h" +#include "TH3.h" +#include "iostream.h" + +ClassImp(AliMUONTriggerLut) + +//---------------------------------------------------------------------- +AliMUONTriggerLut::AliMUONTriggerLut() { +// constructor + fLptPlus = fLptMinu = fLptUnde = 0; + fHptPlus = fHptMinu = fHptUnde = 0; + fAptPlus = fAptMinu = fAptUnde = 0; +} +//---------------------------------------------------------------------- +AliMUONTriggerLut::~AliMUONTriggerLut() { +// destructor + delete fLptPlus; + delete fLptMinu; + delete fLptUnde; + delete fHptPlus; + delete fHptMinu; + delete fHptUnde; + delete fAptPlus; + delete fAptMinu; + delete fAptUnde; + fLptPlus = fLptMinu = fLptUnde = 0; + fHptPlus = fHptMinu = fHptUnde = 0; + fAptPlus = fAptMinu = fAptUnde = 0; +} + +//---------------------------------------------------------------------- +AliMUONTriggerLut::AliMUONTriggerLut (const AliMUONTriggerLut& MUONTriggerLut) +{ +// Dummy copy constructor +} + +//---------------------------------------------------------------------- +AliMUONTriggerLut & AliMUONTriggerLut::operator=(const AliMUONTriggerLut& MUONTriggerLut) +{ +// Dummy assignment operator + return *this; +} + +//---------------------------------------------------------------------- +void AliMUONTriggerLut::GetLutOutput(Int_t circuit, Int_t xstrip, Int_t idev, + Int_t ystrip, Int_t lutLpt[2], + Int_t lutHpt[2], Int_t lutApt[2]){ +// return output of LuT for corresponding TH3S + + static TFile *fileLut; + static Bool_t first=kTRUE; + if(first) { + cout << " opening MUONTriggerLut.root " << "\n"; + fileLut = new TFile("$(ALICE_ROOT)/MUON/MUONTriggerLut.root","READ"); + first=kFALSE; + } + fileLut->cd(); + +// get the pointers to the TH3S objects of the file + TH3S *lptPlus = (TH3S*)gROOT->FindObject("LptPlus"); + TH3S *lptMinu = (TH3S*)gROOT->FindObject("LptMinu"); + TH3S *lptUnde = (TH3S*)gROOT->FindObject("LptUnde"); + TH3S *hptPlus = (TH3S*)gROOT->FindObject("HptPlus"); + TH3S *hptMinu = (TH3S*)gROOT->FindObject("HptMinu"); + TH3S *hptUnde = (TH3S*)gROOT->FindObject("HptUnde"); + TH3S *aptPlus = (TH3S*)gROOT->FindObject("AptPlus"); + TH3S *aptMinu = (TH3S*)gROOT->FindObject("AptMinu"); + TH3S *aptUnde = (TH3S*)gROOT->FindObject("AptUnde"); + + Int_t bin; + Short_t binc; + Int_t mask = GetMask(ystrip); // get ystrip mask + + // Low pt.............................................. + bin = lptPlus->GetBin(circuit,xstrip,idev); + binc = (Short_t)lptPlus->GetBinContent(bin); + if ((binc & mask)!=0) lutLpt[1]=1; + + bin = lptMinu->GetBin(circuit,xstrip,idev); + binc = (Short_t)lptMinu->GetBinContent(bin); + if ((binc & mask)!=0) lutLpt[0]=1; + + bin = lptUnde->GetBin(circuit,xstrip,idev); + binc = (Short_t)lptUnde->GetBinContent(bin); + if ((binc & mask)!=0) lutLpt[0]=lutLpt[1]=1; + + // High pt............................................. + bin = hptPlus->GetBin(circuit,xstrip,idev); + binc = (Short_t)hptPlus->GetBinContent(bin); + if ((binc & mask)!=0) lutHpt[1]=1; + + bin = hptMinu->GetBin(circuit,xstrip,idev); + binc = (Short_t)hptMinu->GetBinContent(bin); + if ((binc & mask)!=0) lutHpt[0]=1; + + bin = hptUnde->GetBin(circuit,xstrip,idev); + binc = (Short_t)hptUnde->GetBinContent(bin); + if ((binc & mask)!=0) lutHpt[0]=lutHpt[1]=1; + + // All pts............................................. + bin = aptPlus->GetBin(circuit,xstrip,idev); + binc = (Short_t)aptPlus->GetBinContent(bin); + if ((binc & mask)!=0) lutApt[1]=1; + + bin = aptMinu->GetBin(circuit,xstrip,idev); + binc = (Short_t)aptMinu->GetBinContent(bin); + if ((binc & mask)!=0) lutApt[0]=1; + + bin = aptUnde->GetBin(circuit,xstrip,idev); + binc = (Short_t)aptUnde->GetBinContent(bin); + if ((binc & mask)!=0) lutApt[0]=lutApt[1]=1; + +// get back to the first file + TTree *tK = gAlice->TreeK(); + TFile *file1 = 0; + if (tK) file1 = tK->GetCurrentFile(); + file1->cd(); +} + +//---------------------------------------------------------------------- +Int_t AliMUONTriggerLut::GetMask(Int_t ystrip){ +// returns the mask corresponding to ystrip + Int_t tabMask[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + Int_t mask=0; + tabMask[ystrip]=1; + for (Int_t i=0; i<16; i++) { + mask=mask+Int_t(tabMask[i]*pow(2,i)); + } + return mask; +} + +//---------------------------------------------------------------------- +void AliMUONTriggerLut::LoadLut(){ +// !!!!!!! This is dummy version of the LoadLut method !!!!!!! +// !!!!!!! calibration to be done !!!!!!! +// 1) Loop on circuit/Xstrip1/deviation/Ystrip +// 2) get corresponding ptCal from AliMUONTriggerCircuit +// 3) fill histos with cuts on deviation, ptLow and ptHigh +// 4) store histos in a file + + char fileName[60]; + sprintf(fileName,"$(ALICE_ROOT)/MUON/MUONTriggerLut.root"); + cout << " file name is " << fileName << "\n"; + +// open output file containing histos + TFile *hfile = new TFile(fileName,"RECREATE","Trigger Look Up Table"); + + //..........................................circuit/stripX/deviation + TH3S *fLptPlus=new TH3S("LptPlus","LptPlus",234,0,234,31,0,31,31,0,31); + TH3S *fLptMinu=new TH3S("LptMinu","LptMinu",234,0,234,31,0,31,31,0,31); + TH3S *fLptUnde=new TH3S("LptUnde","LptUnde",234,0,234,31,0,31,31,0,31); + + TH3S *fHptPlus=new TH3S("HptPlus","HptPlus",234,0,234,31,0,31,31,0,31); + TH3S *fHptMinu=new TH3S("HptMinu","HptMinu",234,0,234,31,0,31,31,0,31); + TH3S *fHptUnde=new TH3S("HptUnde","HptUnde",234,0,234,31,0,31,31,0,31); + + TH3S *fAptPlus=new TH3S("AptPlus","AptPlus",234,0,234,31,0,31,31,0,31); + TH3S *fAptMinu=new TH3S("AptMinu","AptMinu",234,0,234,31,0,31,31,0,31); + TH3S *fAptUnde=new TH3S("AptUnde","AptUnde",234,0,234,31,0,31,31,0,31); + + Float_t lptTreshold=0.75; + Float_t hptTreshold=1.75; + + AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONTriggerCircuit* triggerCircuit; + + for (Int_t icirc=0; icirc<234; icirc++) { + cout << " Loading LuT for circuit " << icirc << " of 234 " << "\n"; + triggerCircuit = &(pMUON->TriggerCircuit(icirc)); + + for (Int_t istripX=0; istripX<31; istripX++) { + for (Int_t idev=0; idev<31; idev++) { + + Short_t iLptPlus, iLptMinu, iLptUnde; + Short_t iHptPlus, iHptMinu, iHptUnde; + Short_t iAptPlus, iAptMinu, iAptUnde; + iLptPlus = iLptMinu = iLptUnde = 0; + iHptPlus = iHptMinu = iHptUnde = 0; + iAptPlus = iAptMinu = iAptUnde = 0; + + for (Int_t istripY=0; istripY<16; istripY++) { + Float_t pt=triggerCircuit->PtCal(istripX,idev,istripY); + + if (pt>lptTreshold) { + if (idev<15) iLptMinu=iLptMinu+Int_t(pow(2,istripY)); + else if (idev==15) iLptUnde=iLptUnde+Int_t(pow(2,istripY)); + else if (idev>15) iLptPlus=iLptPlus+Int_t(pow(2,istripY)); + } + if (pt>hptTreshold) { + if (idev<15) iHptMinu=iHptMinu+Int_t(pow(2,istripY)); + else if (idev==15) iHptUnde=iHptUnde+Int_t(pow(2,istripY)); + else if (idev>15) iHptPlus=iHptPlus+Int_t(pow(2,istripY)); + } + if (idev<15) iAptMinu=iAptMinu+Int_t(pow(2,istripY)); + else if (idev==15) iAptUnde=iAptUnde+Int_t(pow(2,istripY)); + else if (idev>15) iAptPlus=iAptPlus+Int_t(pow(2,istripY)); + + } // loop on istripY + + Int_t bin; + + bin = fLptMinu->GetBin(icirc,istripX,idev); + fLptMinu->SetBinContent(bin,iLptMinu); + bin = fLptUnde->GetBin(icirc,istripX,idev); + fLptUnde->SetBinContent(bin,iLptUnde); + bin = fLptPlus->GetBin(icirc,istripX,idev); + fLptPlus->SetBinContent(bin,iLptPlus); + + bin = fHptMinu->GetBin(icirc,istripX,idev); + fHptMinu->SetBinContent(bin,iHptMinu); + bin = fHptUnde->GetBin(icirc,istripX,idev); + fHptUnde->SetBinContent(bin,iHptUnde); + bin = fHptPlus->GetBin(icirc,istripX,idev); + fHptPlus->SetBinContent(bin,iHptPlus); + + bin = fAptMinu->GetBin(icirc,istripX,idev); + fAptMinu->SetBinContent(bin,iAptMinu); + bin = fAptUnde->GetBin(icirc,istripX,idev); + fAptUnde->SetBinContent(bin,iAptUnde); + bin = fAptPlus->GetBin(icirc,istripX,idev); + fAptPlus->SetBinContent(bin,iAptPlus); + + } // loop on idev + } // loop on istripX + } // loop on circuit + + hfile->Write(); + hfile->Close(); +} + + + + + + + diff --git a/MUON/AliMUONTriggerLut.h b/MUON/AliMUONTriggerLut.h new file mode 100644 index 00000000000..f598bf85c14 --- /dev/null +++ b/MUON/AliMUONTriggerLut.h @@ -0,0 +1,48 @@ +#ifndef ALIMUONTRIGGERLUT_H +#define ALIMUONTRIGGERLUT_H + +#include "TNamed.h" +#include "TFile.h" +#include "TH3.h" +#include + +//---------------------------------------------- +class AliMUONTriggerLut : +public TNamed { + public: + AliMUONTriggerLut(); // constructor + ~AliMUONTriggerLut(); // destructor + // copy constructor + AliMUONTriggerLut (const AliMUONTriggerLut& AliMUONTriggerLut); + // assignment operator + AliMUONTriggerLut& operator=(const AliMUONTriggerLut& AliMUONTriggerLut); + + void LoadLut(); + + void GetLutOutput(Int_t circuit, Int_t xstrip, Int_t idev, Int_t ystrip, + Int_t lutLpt[2], Int_t lutHpt[2], Int_t lutApt[2]); + + private: + Int_t GetMask(Int_t ystrip); + + ClassDef(AliMUONTriggerLut,1) // Trigger Look up Table class + + private: + TH3S *fLptPlus; //3-d histogram with 234x32x31 bins Low pt Plus + TH3S *fLptMinu; //3-d histogram with 234x32x31 bins Low pt Minus + TH3S *fLptUnde; //3-d histogram with 234x32x31 bins Low pt Undefined + TH3S *fHptPlus; //3-d histogram with 234x32x31 bins High pt Plus + TH3S *fHptMinu; //3-d histogram with 234x32x31 bins High pt Minus + TH3S *fHptUnde; //3-d histogram with 234x32x31 bins High pt Undefined + TH3S *fAptPlus; //3-d histogram with 234x32x31 bins All pt Plus + TH3S *fAptMinu; //3-d histogram with 234x32x31 bins All pt Minus + TH3S *fAptUnde; //3-d histogram with 234x32x31 bins All pt Undefined + +}; +#endif + + + + + + diff --git a/MUON/AliMUONchamber.cxx b/MUON/AliMUONchamber.cxx deleted file mode 100644 index 3f7e1d40f4d..00000000000 --- a/MUON/AliMUONchamber.cxx +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************** - * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * * - * Author: The ALICE Off-line Project. * - * Contributors are mentioned in the code where appropriate. * - * * - * Permission to use, copy, modify and distribute this software and its * - * documentation strictly for non-commercial purposes is hereby granted * - * without fee, provided that the above copyright notice appears in all * - * copies and that both the copyright notice and this permission notice * - * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * - * provided "as is" without express or implied warranty. * - **************************************************************************/ - -/* -$Log$ -*/ - -#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) -{ -// sensitive gas gap - fdGas= 0.5; -// 3% radiation length of aluminum (X0=8.9 cm) - fdAlu= 3.0/100*8.9; -} diff --git a/MUON/AliMUONchamber.h b/MUON/AliMUONchamber.h deleted file mode 100644 index 8e6bb637549..00000000000 --- a/MUON/AliMUONchamber.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef MUONchamber_H -#define MUONchamber_H -/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * See cxx source for full Copyright notice */ - -/* $Id$ */ - -#include "TObjArray.h" -#include "AliMUONSegRes.h" - -class AliMUONClusterFinder; -class AliMUONresponse ; -class AliMUONsegmentation ; - -class AliMUONchamber: -public TObject -{ - public: - AliMUONchamber(); - ~AliMUONchamber(){} -// -// Set and get GEANT id - Int_t GetGid() {return fGid;} - void SetGid(Int_t id) {fGid=id;} -// -// Initialisation and z-Position - void Init(); - void SetZPOS(Float_t p1) {fzPos=p1;} - Float_t ZPosition() {return fzPos;} -// Set inner radius of sensitive volume - void SetRInner(Float_t rmin) {frMin=rmin;} -// Set outer radius of sensitive volum - void SetROuter(Float_t rmax) {frMax=rmax;} - -// Return inner radius of sensitive volume - Float_t RInner() {return frMin;} -// Return outer radius of sensitive volum - Float_t ROuter() {return frMax;} -// -// Configure response model - void ResponseModel(AliMUONresponse* thisResponse) {fResponse=thisResponse;} -// -// Configure segmentation model - void SegmentationModel(Int_t i, AliMUONsegmentation* thisSegmentation) { - (*fSegmentation)[i-1] = thisSegmentation; - } - void ReconstructionModel(AliMUONClusterFinder *thisReconstruction) { - fReconstruction = thisReconstruction; - } - -// -// Get reference to response model - AliMUONresponse* &GetResponseModel(){return fResponse;} -// - AliMUONClusterFinder* &GetReconstructionModel(){return fReconstruction;} -// -// Get reference to segmentation model - AliMUONsegmentation* GetSegmentationModel(Int_t isec) { - return (AliMUONsegmentation *) (*fSegmentation)[isec-1]; - } - TObjArray* GetChamberSegmentation(){return fSegmentation;} - - Int_t Nsec() {return fnsec;} - void SetNsec(Int_t nsec) {fnsec=nsec;} -// -// Member function forwarding to the segmentation and response models -// -// Calculate pulse height from energy loss - Float_t IntPH(Float_t eloss) {return fResponse->IntPH(eloss);} -// -// Ask segmentation if signal should be generated - Int_t SigGenCond(Float_t x, Float_t y, Float_t z) - { - if (fnsec==1) { - return ((AliMUONsegmentation*) (*fSegmentation)[0]) - ->SigGenCond(x, y, z) ; - } else { - return (((AliMUONsegmentation*) (*fSegmentation)[0]) - ->SigGenCond(x, y, z)) || - (((AliMUONsegmentation*) (*fSegmentation)[1]) - ->SigGenCond(x, y, z)) ; - } - } -// -// Initialisation of segmentation for hit - void SigGenInit(Float_t x, Float_t y, Float_t z) - { - - if (fnsec==1) { - ((AliMUONsegmentation*) (*fSegmentation)[0])->SigGenInit(x, y, z) ; - } else { - ((AliMUONsegmentation*) (*fSegmentation)[0])->SigGenInit(x, y, z) ; - ((AliMUONsegmentation*) (*fSegmentation)[1])->SigGenInit(x, y, z) ; - } - } - -// Configuration forwarding -// - void SetSigmaIntegration(Float_t p1) {fResponse->SetSigmaIntegration(p1);} - void SetChargeSlope(Float_t p1) {fResponse->SetChargeSlope(p1);} - void SetChargeSpread(Float_t p1, Float_t p2) {fResponse->SetChargeSpread(p1,p2);} - void SetMaxAdc(Float_t p1) {fResponse->SetMaxAdc(p1);} - - void SetPADSIZ(Int_t isec, Float_t p1, Float_t p2) { - ((AliMUONsegmentation*) (*fSegmentation)[isec-1])->SetPADSIZ(p1,p2); - } -// -// Cluster formation method - void DisIntegration(Float_t, Float_t, Float_t, Int_t&x, Float_t newclust[6][500]); - ClassDef(AliMUONchamber,1) - void InitGeo(Float_t z); - - private: -// GEANT volume if for sensitive volume of this chamber - Int_t fGid; -// z-position of this chamber - Float_t fzPos; // z-position of chambers - Int_t fnsec; // number of segmentation zones - Float_t frMin; // innermost sensitive radius - Float_t frMax; // outermost sensitive radius -// The segmentation models for the cathode planes -// fnsec=1: one plane segmented, fnsec=2: both planes are segmented. - - TObjArray *fSegmentation; - AliMUONClusterFinder *fReconstruction; - AliMUONresponse *fResponse; - - public: - Float_t fdGas; // half gaz gap - Float_t fdAlu; // half Alu width -}; - -#endif diff --git a/MUON/AliMUONdisplay.cxx b/MUON/AliMUONdisplay.cxx deleted file mode 100644 index 97b9a64eae7..00000000000 --- a/MUON/AliMUONdisplay.cxx +++ /dev/null @@ -1,1252 +0,0 @@ -/************************************************************************** - * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * * - * Author: The ALICE Off-line Project. * - * Contributors are mentioned in the code where appropriate. * - * * - * Permission to use, copy, modify and distribute this software and its * - * documentation strictly for non-commercial purposes is hereby granted * - * without fee, provided that the above copyright notice appears in all * - * copies and that both the copyright notice and this permission notice * - * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * - * provided "as is" without express or implied warranty. * - **************************************************************************/ - -/* -$Log$ -Revision 1.9 1999/11/09 07:38:51 fca -Changes for compatibility with version 2.23 of ROOT - -Revision 1.8 1999/09/29 09:24:23 fca -Introduction of the Copyright and cvs Log - -*/ - - -////////////////////////////////////////////////////////////////////////// -// // -// AliDisplay // -// // -// Utility class to display ALICE outline, tracks, hits,.. // -// // -////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "AliRun.h" -#include "AliDetector.h" -#include "AliMUON.h" -#include "AliMUONConst.h" -#include "AliMUONdisplay.h" -#include "AliMUONpoints.h" -#include "TParticle.h" - - - -ClassImp(AliMUONdisplay) - - -//_____________________________________________________________________________ -AliMUONdisplay::AliMUONdisplay() -{ - fPoints = 0; - fPhits = 0; - fRpoints = 0; - fR2points = 0; - fCpoints = 0; - fCanvas = 0; -} - -//_____________________________________________________________________________ -AliMUONdisplay::AliMUONdisplay(Int_t size) -{ -// Create an event display object. -// A canvas named "edisplay" is created with a vertical size in pixels -// -// A QUICK Overview of the Event Display functions -// =============================================== -// -// The event display can ve invoked by executing the macro "display.C" -// A canvas like in the picture below will appear. -// -// On the left side of the canvas, the following buttons appear: -// *Next* to move to the next event -// *Previous* to move to the previous event - -// *Pick* Select this option to be able to point on a track with the -// mouse. Once on the track, use the right button to select -// an action. For example, select SetMarkerAttributes to -// change the marker type/color/size for the track. -// *Zoom* Select this option (default) if you want to zoom. -// To zoom, simply select the selected area with the left button. -// *UnZoom* To revert to the previous picture size. -// -// slider R On the left side, the vertical slider can be used to -// set the default picture size. -// -// When you are in Zoom mode, you can click on the black part of the canvas -// to select special options with the right mouse button. - -// -// When you are in pick mode, you can "Inspect" the object pointed by the mouse. -// When you are on a track, select the menu item "InspectParticle" -// to display the current particle attributes. -// -// You can activate the Root browser by selecting the Inspect menu -// in the canvas tool bar menu. Then select "Start Browser" -// This will open a new canvas with the browser. At this point, you may want -// to display some histograms (from the Trees). Go to the "File" menu -// of the browser and click on "New canvas". -// In the browser, click on item "ROOT files" in the left pane. -// Click on galice.root. -// Click on TH -// Click on TPC for example -// Click on any variable (eg TPC.fX) to histogram the variable. -// -// If you are lost, you can click on HELP in any Root canvas or browser. -//Begin_Html -/* - -*/ -//End_Html - - - fPad = 0; - - gAlice->SetDisplay(this); - - // Initialize display default parameters - SetRange(200,2000); - // Set front view by default - fTheta = 0; - fPhi = -90; - 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; - fRpoints = 0; - fR2points = 0; - fCpoints = 0; - // Create colors - CreateColors(); - // Create display canvas - Int_t ysize = size; - if (ysize < 100) ysize = 750; - Int_t xsize = Int_t(size*830./ysize); - fCanvas = new TCanvas("Canvas", "MUON Clusters Display",14,47,xsize,ysize); - fCanvas->ToggleEventStatus(); - - // Create main display pad - fPad = new TPad("viewpad", "MUON display",0.15,0,0.9,1); - fPad->Draw(); - fPad->Modified(); - fPad->SetFillColor(1); - fPad->SetBorderSize(2); - - fCanvas->cd(); - - // Create colors pad - fColPad = new TPad("colpad", "Colors pad",0.9,0,1,1); - fColPad->Draw(); - fColPad->Modified(); - fColPad->SetFillColor(19); - fColPad->SetBorderSize(2); - fColPad->cd(); - DisplayColorScale(); - - fCanvas->cd(); - - // Create user interface control pad - DisplayButtons(); - fCanvas->cd(); - - // Create Range and mode pad - Float_t dxtr = 0.15; - Float_t dytr = 0.45; - fTrigPad = new TPad("trigger", "range and mode pad",0,0,dxtr,dytr); - fTrigPad->SetEditable(kFALSE); - fTrigPad->Draw(); - fTrigPad->cd(); - fTrigPad->SetFillColor(22); - fTrigPad->SetBorderSize(2); - fRangeSlider = new TSlider("range","range",0.7,0.42,0.9,0.98); - fRangeSlider->SetObject(this); - char pickmode[] = "gAlice->Display()->SetPickMode()"; - Float_t db = 0.09; - fPickButton = new TButton("Pick",pickmode,0.05,0.32,0.65,0.32+db); - fPickButton->SetFillColor(38); - fPickButton->Draw(); - char zoommode[] = "gAlice->Display()->SetZoomMode()"; - fZoomButton = new TButton("Zoom",zoommode,0.05,0.21,0.65,0.21+db); - fZoomButton->SetFillColor(38); - fZoomButton->Draw(); - fArcButton = new TArc(.8,fZoomButton->GetYlowNDC()+0.5*db,0.33*db); - fArcButton->SetFillColor(kGreen); - fArcButton->Draw(); - char butUnzoom[] = "gAlice->Display()->UnZoom()"; - TButton *button = new TButton("UnZoom",butUnzoom,0.05,0.05,0.95,0.15); - button->SetFillColor(38); - button->Draw(); - AppendPad(); // append display object as last object to force selection - - fCanvas->cd(); - fCanvas->Update(); -} - - -//_____________________________________________________________________________ -AliMUONdisplay::~AliMUONdisplay() -{ - // Delete space point structure - if (fPoints) fPoints->Delete(); - delete fPoints; - fPoints = 0; - // - 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; -} - -//_____________________________________________________________________________ -void AliMUONdisplay::Clear(Option_t *) -{ -// Delete graphics temporary objects -} - -//_____________________________________________________________________________ -void AliMUONdisplay::DisplayButtons() -{ -// Create the user interface buttons - - - fButtons = new TPad("buttons", "newpad",0,0.45,0.15,1); - fButtons->SetEditable(kFALSE); - fButtons->Draw(); - fButtons->SetFillColor(38); - fButtons->SetBorderSize(2); - fButtons->cd(); - -// Int_t butcolor = 33; - Float_t dbutton = 0.08; - Float_t y = 0.96; - Float_t dy = 0.014; - Float_t x0 = 0.05; - Float_t x1 = 0.95; - - TButton *button; - char but1[] = "gAlice->Display()->ShowNextEvent(1)"; - button = new TButton("Next",but1,x0,y-dbutton,x1,y); - button->SetFillColor(38); - button->Draw(); - - y -= dbutton +dy; - char but2[] = "gAlice->Display()->ShowNextEvent(-1)"; - button = new TButton("Previous",but2,x0,y-dbutton,x1,y); - button->SetFillColor(38); - button->Draw(); - /* - y -= dbutton +dy; - char but3[] = "gAlice->Display()->SetChamberAndCathode(1,1)"; - button = new TButton("Cham&Cath",but3,x0,y-dbutton,x1,y); - button->SetFillColor(butcolor); - button->Draw(); - */ - // display logo - TDiamond *diamond = new TDiamond(0.05,0.015,0.95,0.22); - diamond->SetFillColor(50); - diamond->SetTextAlign(22); - diamond->SetTextColor(5); - diamond->SetTextSize(0.11); - diamond->Draw(); - diamond->AddText(".. "); - diamond->AddText("ROOT"); - diamond->AddText("MUON"); - diamond->AddText("... "); - diamond->AddText(" "); -} - -//_____________________________________________________________________________ -void AliMUONdisplay::CreateColors() -{ -// Create the colors palette used to display clusters - - Int_t k,i; - Int_t color; - Float_t r,g,b; - - for (k=1;k<=5;k++) { - switch(k) { - case 1: - for (i=1;i<=5;i++) { - r=1.; - g=i*0.2; - b=0.; - color=i; - color=260+23-color; - new TColor(color,r,g,b); - } - break; - case 2: - for (i=1;i<=4;i++) { - r=1.1-i*0.2; - g=1.; - b=0.; - color=i+5; - color=260+23-color; - new TColor(color,r,g,b); - } - break; - case 3: - for (i=1;i<=4;i++) { - r=0.; - g=1.; - b=i*0.2+0.2; - color=i+9; - color=260+23-color; - new TColor(color,r,g,b); - } - break; - case 4: - for (i=1;i<=4;i++) { - r=0.; - g=1.1-i*0.2; - b=1.; - color=i+13; - color=260+23-color; - new TColor(color,r,g,b); - } - break; - case 5: - for (i=1;i<=5;i++) { - r=i*0.2; - g=0.; - b=1.; - color=i+17; - color=260+23-color; - new TColor(color,r,g,b); - } - break; - } - - } - -} - -//_____________________________________________________________________________ -void AliMUONdisplay::DisplayColorScale() -{ - - Int_t i; - Int_t color; - Float_t xlow, ylow, xup, yup, hs; - Float_t x1, y1, x2, y2; - x1 = y1 = 0; - x2 = y2 = 20; - - gPad->SetFillColor(0); - gPad->Clear(); - gPad->Range(x1,y1,x2,y2); - - TText *text = new TText(0,0,""); - text->SetTextFont(61); - 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]; -//*-* draw colortable boxes - hs = (y2-y1)/Float_t(22); - xlow=x1+1; - xup=x2-9; - for (i=0;i<22;i++) { - ylow = y1 + hs*(Float_t(i)); - yup = y1 + hs*(Float_t(i+1)); - color = 261+i; - 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); - box->SetFillColor(color); - box->Draw(); - text->DrawText(xup+4, 0.5*(ylow+yup),label); - } -} - -//______________________________________________________________________________ -Int_t AliMUONdisplay::DistancetoPrimitive(Int_t px, Int_t) -{ -// Compute distance from point px,py to objects in event - - gPad->SetCursor(kCross); - - if (gPad == fTrigPad) return 9999; - - const Int_t big = 9999; - Int_t dist = big; - Float_t xmin = gPad->GetX1(); - Float_t xmax = gPad->GetX2(); - Float_t dx = 0.02*(xmax - xmin); - Float_t x = gPad->AbsPixeltoX(px); - if (x < xmin+dx || x > xmax-dx) return dist; - - if (fZoomMode) return 0; - else return 7; -} - -//_____________________________________________________________________________ -void AliMUONdisplay::Draw(Option_t *) -{ -// Display current event - - fPad->cd(); - - DrawView(fTheta, fPhi, fPsi); - // Display the event number and title - fPad->cd(); - DrawTitle(); -} - - -//_____________________________________________________________________________ -void AliMUONdisplay::DrawClusters() -{ -// Draw clusterss for MUON chambers - - Int_t ndigits, digit; - TObjArray *points; - AliMUONpoints *pm; - - - fClustersCuts = 0; - points = Points(); - if (!points) return; - ndigits = points->GetEntriesFast(); - for (digit=0;digitUncheckedAt(digit); - if (!pm) continue; - Float_t *pxyz; - pxyz=pm->GetP(); - for (Int_t im=0;im<3;im++) { - TMarker3DBox *marker=pm->GetMarker(im); - if (marker) - marker->Draw(); - } - pm->Draw(); - fClustersCuts +=pm->GetN(); - - } -} - -//_____________________________________________________________________________ -void AliMUONdisplay::DrawHits() -{ -// Draw hits for MUON chambers - - LoadHits(fChamber); - - Int_t ntracks, track; - TObjArray *points; - AliMUONpoints *pm; - - fHitsCuts = 0; - points = Phits(); - if (!points) return; - ntracks = points->GetEntriesFast(); - for (track=0;trackUncheckedAt(track); - if (!pm) continue; - pm->Draw(); - fHitsCuts += pm->GetN(); - } -} - - -//_____________________________________________________________________________ -void AliMUONdisplay::DrawCoG() -{ -// Draw hits for MUON chambers - if (!fDrawCoG) return; - LoadCoG(fChamber,fCathode); - - Int_t ncog, icog; - TObjArray *points; - AliMUONpoints *pm; - - points = Rpoints(); - if (!points) return; - ncog = points->GetEntriesFast(); - for (icog=0;icogUncheckedAt(icog); - if (!pm) continue; - pm->Draw(); - } -} -void AliMUONdisplay::DrawCoG2() -{ -// Draw hits for MUON chambers - - if (!fDrawCoG) return; - - - if (fCathode==1) { - LoadCoG2(fChamber,2); - } else if (fCathode==2) { - LoadCoG2(fChamber,1); - } - - Int_t ncog, icog; - TObjArray *points; - AliMUONpoints *pm; - - points = R2points(); - if (!points) return; - ncog = points->GetEntriesFast(); - for (icog=0;icogUncheckedAt(icog); - if (!pm) continue; - pm->Draw(); - } - -} -//_____________________________________________________________________________ -void AliMUONdisplay::DrawCathCor() -{ -// Draw hits for MUON chambers - - if (!fDrawCathCor) return; - - LoadCathCor(fChamber); - - Int_t ncog, icog; - TObjArray *points; - AliMUONpoints *pm; - - points = Cpoints(); - if (!points) return; - ncog = points->GetEntriesFast(); - for (icog=0;icogUncheckedAt(icog); - if (!pm) continue; - pm->Draw(); - } -} -//_____________________________________________________________________________ -//_____________________________________________________________________________ -void AliMUONdisplay::DrawTitle(Option_t *option) -{ -// Draw the event title - - Float_t xmin = gPad->GetX1(); - Float_t xmax = gPad->GetX2(); - Float_t ymin = gPad->GetY1(); - Float_t ymax = gPad->GetY2(); - Float_t dx = xmax-xmin; - Float_t dy = ymax-ymin; - - if (strlen(option) == 0) { - TPaveText *title = new TPaveText(xmin +0.01*dx, ymax-0.09*dy, xmin +0.5*dx, ymax-0.01*dy); - title->SetBit(kCanDelete); - title->SetFillColor(42); - title->Draw(); - char ptitle[100]; - sprintf(ptitle,"Alice event: %d, Run:%d",gAlice->GetHeader()->GetEvent(), gAlice->GetHeader()->GetRun()); - title->AddText(ptitle); - Int_t nparticles = gAlice->Particles()->GetEntriesFast(); - sprintf(ptitle,"Nparticles = %d Nhits = %d Npads fired = %d",nparticles, fHitsCuts,fClustersCuts); - title->AddText(ptitle); - } else { - TPaveLabel *label = new TPaveLabel(xmin +0.01*dx, ymax-0.07*dy, xmin +0.2*dx, ymax-0.01*dy,option); - label->SetBit(kCanDelete); - label->SetFillColor(42); - label->Draw(); - } -} - -//_____________________________________________________________________________ -void AliMUONdisplay::DrawView(Float_t theta, Float_t phi, Float_t psi) -{ -// Draw a view of MUON clusters - - gPad->SetCursor(kWatch); - gPad->SetFillColor(1); - gPad->Clear(); - - Int_t iret=0; - TView *view = new TView(1); - - Float_t range = fRrange*fRangeSlider->GetMaximum(); - view->SetRange(-range,-range,-range,range, range, range); - fZoomX0[0] = -1; - fZoomY0[0] = -1; - fZoomX1[0] = 1; - fZoomY1[0] = 1; - fZooms = 0; - -// Display MUON Chamber Geometry -// gAlice->GetGeometry()->Draw("same"); - char NodeName[7]; - sprintf(NodeName,"MUON%d",100+fChamber); - printf("Node name %s", NodeName); - - TNode *node1=gAlice->GetGeometry()->GetNode(NodeName); - if (node1) node1->Draw("same"); -// ok if I rotate the chamber in a proper way - -//add clusters to the pad - DrawClusters(); - DrawHits(); - DrawCoG(); - DrawCoG2(); - DrawCathCor(); - // add itself to the list (must be last) - AppendPad(); - view->SetView(phi, theta, psi, iret); -} - - -//______________________________________________________________________________ -void AliMUONdisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py) -{ -// Execute action corresponding to the mouse event - - static Float_t x0, y0, x1, y1; - - static Int_t pxold, pyold; - static Int_t px0, py0; - static Int_t linedrawn; - Float_t temp; - - if (px == 0 && py == 0) { //when called by sliders - if (event == kButton1Up) { - Draw(); - } - return; - } - if (!fZoomMode && gPad->GetView()) { - gPad->GetView()->ExecuteRotateView(event, px, py); - return; - } - - // something to zoom ? - gPad->SetCursor(kCross); - - switch (event) { - - case kButton1Down: - gVirtualX->SetLineColor(-1); - gPad->TAttLine::Modify(); //Change line attributes only if necessary - x0 = gPad->AbsPixeltoX(px); - y0 = gPad->AbsPixeltoY(py); - px0 = px; py0 = py; - pxold = px; pyold = py; - linedrawn = 0; - return; - - case kButton1Motion: - if (linedrawn) gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow); - pxold = px; - pyold = py; - linedrawn = 1; - gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow); - return; - - case kButton1Up: - gPad->GetCanvas()->FeedbackMode(kFALSE); - if (px == px0) return; - if (py == py0) return; - x1 = gPad->AbsPixeltoX(px); - y1 = gPad->AbsPixeltoY(py); - - if (x1 < x0) {temp = x0; x0 = x1; x1 = temp;} - if (y1 < y0) {temp = y0; y0 = y1; y1 = temp;} - gPad->Range(x0,y0,x1,y1); - if (fZooms < kMAXZOOM-1) { - fZooms++; - fZoomX0[fZooms] = x0; - fZoomY0[fZooms] = y0; - fZoomX1[fZooms] = x1; - fZoomY1[fZooms] = y1; - } - gPad->Modified(kTRUE); - return; - } - -} - -//___________________________________________ -void AliMUONdisplay::LoadDigits(Int_t chamber, Int_t cathode) -{ -// Read digits info and store x,y,z info in arrays fPoints -// Loop on all detectors - - if (chamber > 10) return; - - fChamber=chamber; - fCathode=cathode; - - ResetPoints(); - - AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); - AliMUONchamber* iChamber; - AliMUONsegmentation* segmentation; - - TClonesArray *MUONdigits = MUON->DigitsAddress(chamber-1); - if (MUONdigits == 0) return; - - gAlice->ResetDigits(); - - Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); - gAlice->TreeD()->GetEvent(nent-2+cathode-1); - //gAlice->TreeD()->GetEvent(cathode); - Int_t ndigits = MUONdigits->GetEntriesFast(); - if (ndigits == 0) return; - if (fPoints == 0) fPoints = new TObjArray(ndigits); - - iChamber = &(MUON->Chamber(chamber-1)); - segmentation=iChamber->GetSegmentationModel(cathode); - //Float_t dpxbig = segmentation->Dpx()/2.; - // Float_t dpy = segmentation->Dpy()/2.; - Float_t zpos=iChamber->ZPosition(); - AliMUONdigit *mdig; - AliMUONpoints *points = 0; - TMarker3DBox *marker=0; - // TMatrix *matrix; - // - //loop over all digits and store their position - // points = new AliMUONpoints(ndigits); - Int_t npoints=1; - for (Int_t digit=0;digitUncheckedAt(digit); - // - // First get all needed parameters - // - Int_t charge=mdig->fSignal; - Int_t index=Int_t(TMath::Log(charge)/(TMath::Log(adc_satm)/22)); - Int_t color=261+index; - if (color>282) color=282; - // get the center of the pad - add on x and y half of pad size - Float_t xpad, ypad; - segmentation->GetPadCxy(mdig->fPadX, mdig->fPadY,xpad, ypad); - // printf("xpad,ypad,zpos,dpx,dpy %f %f %f %f %f\n",xpad,ypad,zpos,dpx,dpy); - Int_t isec=segmentation->Sector(mdig->fPadX, mdig->fPadY); - // printf(" isec %d \n",isec); - Float_t dpx=segmentation->Dpx(isec)/2; - Float_t dpy=segmentation->Dpy(isec)/2; - // printf(" dpx %f \n",dpx); - Int_t nPara, offset; - segmentation->GetNParallelAndOffset(mdig->fPadX,mdig->fPadY, - &nPara,&offset); - // - // Then set the objects - // - points = new AliMUONpoints(npoints); - fPoints->AddAt(points,digit); - - points->SetMarkerColor(color); - points->SetMarkerStyle(21); - points->SetMarkerSize(0.5); - points->SetParticle(-1); - points->SetHitIndex(-1); - points->SetTrackIndex(-1); - points->SetDigitIndex(digit); - points->SetPoint(0,xpad,ypad,zpos); - for (Int_t imark=0;imarkGetPadCxy(mdig->fPadX + imark*offset, mdig->fPadY,xpad, ypad); - marker=new TMarker3DBox(xpad,ypad,zpos,dpx,dpy,0,0,0); - marker->SetLineColor(2); - marker->SetFillStyle(1001); - marker->SetFillColor(color); - marker->SetRefObject((TObject*)points); - points->Set3DMarker(imark, marker); - - } - } -} -//___________________________________________ -void AliMUONdisplay::LoadCoG(Int_t chamber, Int_t cathode) -{ -// Read raw clusters info and store x,y,z info in arrays fRpoints -// Loop on all detectors - - if (chamber > 10) return; - - ResetRpoints(); - - AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); - AliMUONchamber* iChamber; - - TClonesArray *MUONrawclust = MUON->RawClustAddress(chamber-1); - if (MUONrawclust == 0) return; - - MUON->ResetRawClusters(); - - - Int_t nent=(Int_t)gAlice->TreeR()->GetEntries(); - gAlice->TreeR()->GetEvent(nent-2+cathode-1); - //gAlice->TreeR()->GetEvent(cathode); - Int_t nrawcl = MUONrawclust->GetEntriesFast(); - if (nrawcl == 0) return; - if (fRpoints == 0) fRpoints = new TObjArray(nrawcl); - - iChamber = &(MUON->Chamber(chamber-1)); - Float_t zpos=iChamber->ZPosition(); - AliMUONRawCluster *mRaw; - AliMUONpoints *points = 0; - // - //loop over all raw clusters and store their position - points = new AliMUONpoints(nrawcl); - for (Int_t iraw=0;irawUncheckedAt(iraw); - fRpoints->AddAt(points,iraw); - points->SetMarkerColor(51); - points->SetMarkerStyle(2); - points->SetMarkerSize(1.); - points->SetParticle(-1); - points->SetHitIndex(-1); - points->SetTrackIndex(-1); - points->SetDigitIndex(-1); - points->SetPoint(iraw,mRaw->fX,mRaw->fY,zpos); - } -} -//___________________________________________ -void AliMUONdisplay::LoadCoG2(Int_t chamber, Int_t cathode) -{ -// Read raw clusters info and store x,y,z info in arrays fRpoints -// Loop on all detectors - - if (chamber > 10) return; - - ResetR2points(); - - AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); - AliMUONchamber* iChamber; - - TClonesArray *MUONrawclust = MUON->RawClustAddress(chamber-1); - if (MUONrawclust == 0) return; - - MUON->ResetRawClusters(); - - Int_t nent=(Int_t)gAlice->TreeR()->GetEntries(); - gAlice->TreeR()->GetEvent(nent-2+cathode-1); - //gAlice->TreeR()->GetEvent(cathode); - Int_t nrawcl = MUONrawclust->GetEntriesFast(); - if (nrawcl == 0) return; - if (fR2points == 0) fR2points = new TObjArray(nrawcl); - - iChamber = &(MUON->Chamber(chamber-1)); - Float_t zpos=iChamber->ZPosition(); - AliMUONRawCluster *mRaw; - AliMUONpoints *points = 0; - // - //loop over all raw clusters and store their position - points = new AliMUONpoints(nrawcl); - for (Int_t iraw=0;irawUncheckedAt(iraw); - fR2points->AddAt(points,iraw); - points->SetMarkerColor(51); - points->SetMarkerStyle(4); - points->SetMarkerSize(1.3); - points->SetParticle(-1); - points->SetHitIndex(-1); - points->SetTrackIndex(-1); - points->SetDigitIndex(-1); - points->SetPoint(iraw,mRaw->fX,mRaw->fY,zpos); - } -} -//___________________________________________ -void AliMUONdisplay::LoadCathCor(Int_t chamber) -{ -// Read correlation info and store x,y,z info in arrays fCpoints -// Loop on all detectors - - if (chamber > 10) return; - fChamber=chamber; - ResetCpoints(); - - AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); - AliMUONchamber* iChamber; - iChamber = &(MUON->Chamber(chamber-1)); - Float_t zpos=iChamber->ZPosition(); // check with Andreas - - - //new - MUON->GetTreeC(fEvent); - TTree *TC=MUON->TreeC(); - if (!TC) return; - // Int_t nent=(Int_t)TC->GetEntries(); - - TClonesArray *MUONcorrel = MUON->CathCorrelAddress(chamber-1); - if (MUONcorrel == 0) return; - - MUON->ResetCorrelation(); - TC->GetEvent(); - - Int_t ncor = MUONcorrel->GetEntries(); - if (!ncor) return; - if (!fCpoints) fCpoints = new TObjArray(ncor); - - AliMUONcorrelation *mCor; - AliMUONpoints *points = 0; - // - //loop over all raw clusters and store their position - points = new AliMUONpoints(ncor); - for (Int_t icor=0;icorUncheckedAt(icor); - fCpoints->AddAt(points,icor); - points->SetMarkerColor(4); - points->SetMarkerStyle(4); - points->SetMarkerSize(0.8); - points->SetParticle(-1); - points->SetHitIndex(-1); - points->SetTrackIndex(-1); - points->SetDigitIndex(-1); - points->SetPoint(icor,mCor->fX[0],mCor->fY[0],zpos); - } -} - -//___________________________________________ -void AliMUONdisplay::LoadHits(Int_t chamber) -{ -// Read hits info and store x,y,z info in arrays fPhits -// Loop on all detectors - - if (chamber > 10) return; - Int_t track; - - fChamber=chamber; - - ResetPhits(); - - AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); - AliMUONchamber* iChamber; - - iChamber = &(MUON->Chamber(chamber-1)); - Float_t zpos=iChamber->ZPosition(); - - Int_t ntracks = (Int_t)gAlice->TreeH()->GetEntries(); - //Int_t ntrks = gAlice->GetNtrack(); - - - Int_t nthits=0; - for (track=0; trackResetHits(); - gAlice->TreeH()->GetEvent(track); - TClonesArray *MUONhits = MUON->Hits(); - if (MUONhits == 0) return; - nthits += MUONhits->GetEntriesFast(); - } - if (fPhits == 0) fPhits = new TObjArray(nthits); - //printf("nthits %d \n",nthits); - - // old stuff - // - //if (fPhits == 0) fPhits = new TObjArray(ntracks); - /* - TVector *xp = new TVector(20); - TVector *yp = new TVector(20); - // TVector *zp = new TVector(20); - TVector *ptrk = new TVector(20); - TVector *phit = new TVector(20); - */ - // end old stuff - - Int_t nhold=0; - for (track=0; trackResetHits(); - gAlice->TreeH()->GetEvent(track); - TClonesArray *MUONhits = MUON->Hits(); - if (MUONhits == 0) return; - Int_t nhits = MUONhits->GetEntriesFast(); - if (nhits == 0) continue; - AliMUONhit *mHit; - AliMUONpoints *points = 0; - Int_t npoints=1; - for (Int_t hit=0;hitUncheckedAt(hit); - Int_t nch = mHit->fChamber; // chamber number - if (nch != chamber) continue; - // - // Retrieve info and set the objects - // - points = new AliMUONpoints(npoints); - fPhits->AddAt(points,nhold+hit); - points->SetMarkerColor(kRed); - points->SetMarkerStyle(5); - points->SetMarkerSize(1.); - points->SetParticle(mHit->fTrack); - points->SetHitIndex(hit); - points->SetTrackIndex(track); - points->SetDigitIndex(-1); - points->SetPoint(0,mHit->fX,mHit->fY,zpos); - } - nhold+=nhits; - - - // old stuff - /* - Int_t npoints=0; - for (Int_t hit=0;hitUncheckedAt(hit); - Int_t nch = mHit->fChamber; // chamber number - if (nch != chamber) continue; - - (*xp)(npoints)=mHit->fX; - (*yp)(npoints)=mHit->fY; - // (*zp)(npoints)=mHit->fZ; - (*ptrk)(npoints)=Float_t(mHit->GetTrack()); - //(*ptrk)(npoints)=Float_t(mHit->fTrack); - (*phit)(npoints)=Float_t(hit); - printf("hit,(*phit)(npoints), track, trk, fTrack ipart %d %f %d %d %d %f\n",hit,(*phit)(npoints),track,mHit->GetTrack(),mHit->fTrack,mHit->fParticle); - npoints++; - } - if (npoints == 0) continue; - // printf("npoints %d \n",npoints); - points = new AliMUONpoints(npoints); - for (Int_t p=0;pSetMarkerColor(kRed); - points->SetMarkerStyle(5); - points->SetMarkerSize(1.); - points->SetParticle(Int_t((*ptrk)(p))); - Int_t index=points->GetIndex(); - points->SetHitIndex(Int_t((*phit)(p))); - points->SetTrackIndex(track); - printf("p, index, Int_t((*ptrk)(p)), hit, track %d %d %d %d %d \n",p, index,Int_t((*ptrk)(p)),Int_t((*phit)(p)),track); - points->SetDigitIndex(-1); - points->SetPoint(p,(*xp)(p),(*yp)(p),zpos); - // points->SetPoint(p,(*xp)(p),(*yp)(p),(*zp)(p)); - } - xp->Zero(); - yp->Zero(); - // zp->Zero(); - ptrk->Zero(); - phit->Zero(); - fPhits->AddAt(points,track); - // Int_t np=points->GetN(); - // printf("np %d \n",np); - - - */ - // end old stuff - - } - -} - -//_____________________________________________________________________________ -void AliMUONdisplay::Paint(Option_t *) -{ -// Paint miscellaneous items - -} - -//_____________________________________________________________________________ -void AliMUONdisplay::SetPickMode() -{ - fZoomMode = 0; - - fArcButton->SetY1(fPickButton->GetYlowNDC()+0.5*fPickButton->GetHNDC()); - fTrigPad->Modified(); -} - -//_____________________________________________________________________________ -void AliMUONdisplay::SetZoomMode() -{ - fZoomMode = 1; - - fArcButton->SetY1(fZoomButton->GetYlowNDC()+0.5*fZoomButton->GetHNDC()); - fTrigPad->Modified(); -} - -//_____________________________________________________________________________ -void AliMUONdisplay::SetChamberAndCathode(Int_t chamber, Int_t cathode) -{ -// Set chamber and cathode number - fChamber = chamber; - fCathode = cathode; - - if (!fPad) return; - fPad->Clear(); - LoadDigits(chamber,cathode); - Draw(); -} - -//_____________________________________________________________________________ -void AliMUONdisplay::SetRange(Float_t rrange, Float_t zrange) -{ -// Set view range along R and Z - fRrange = rrange; - fZrange = zrange; - - if (!fPad) return; - fPad->Clear(); - Draw(); -} - -//_____________________________________________________________________________ -void AliMUONdisplay::SetView(Float_t theta, Float_t phi, Float_t psi) -{ -// change viewing angles for current event - - fPad->cd(); - fPhi = phi; - fTheta = theta; - fPsi = psi; - Int_t iret = 0; - - TView *view = gPad->GetView(); - if (view) view->SetView(fPhi, fTheta, fPsi, iret); - else Draw(); - - gPad->Modified(); -} - -//_____________________________________________________________________________ -void AliMUONdisplay::ShowNextEvent(Int_t delta) -{ -// Display (current event_number+delta) -// delta = 1 shown next event -// delta = -1 show previous event - if (delta) { - gAlice->Clear(); - Int_t current_event = gAlice->GetHeader()->GetEvent(); - Int_t new_event = current_event + delta; - gAlice->GetEvent(new_event); - fEvent=new_event; - if (!gAlice->TreeD()) return; - } - LoadDigits(fChamber,fCathode); - fPad->cd(); - Draw(); -} - -//______________________________________________________________________________ -void AliMUONdisplay::UnZoom() -{ - if (fZooms <= 0) return; - fZooms--; - TPad *pad = (TPad*)gPad->GetPadSave(); - pad->Range(fZoomX0[fZooms],fZoomY0[fZooms], fZoomX1[fZooms],fZoomY1[fZooms]); - pad->Modified(); -} - -//_____________________________________________________________________________ -void AliMUONdisplay::ResetPoints() -{ - // - // Reset array of points - // - if (fPoints) { - fPoints->Delete(); - delete fPoints; - fPoints = 0; - } -} -//_____________________________________________________________________________ -void AliMUONdisplay::ResetPhits() -{ - // - // Reset array of points - // - if (fPhits) { - fPhits->Delete(); - delete fPhits; - fPhits = 0; - } -} -//_____________________________________________________________________________ -void AliMUONdisplay::ResetRpoints() -{ - // - // Reset array of points - // - if (fRpoints) { - fRpoints->Delete(); - delete fRpoints; - fRpoints = 0; - } -} -//_____________________________________________________________________________ -void AliMUONdisplay::ResetR2points() -{ - // - // Reset array of points - // - if (fR2points) { - fR2points->Delete(); - delete fR2points; - fR2points = 0; - } -} -//_____________________________________________________________________________ -void AliMUONdisplay::ResetCpoints() -{ - // - // Reset array of points - // - if (fCpoints) { - fCpoints->Delete(); - delete fCpoints; - fCpoints = 0; - } -} - - - - - - - - - - - diff --git a/MUON/AliMUONpoints.cxx b/MUON/AliMUONpoints.cxx deleted file mode 100644 index 0813e9d1ea6..00000000000 --- a/MUON/AliMUONpoints.cxx +++ /dev/null @@ -1,451 +0,0 @@ -/************************************************************************** - * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * * - * Author: The ALICE Off-line Project. * - * Contributors are mentioned in the code where appropriate. * - * * - * Permission to use, copy, modify and distribute this software and its * - * documentation strictly for non-commercial purposes is hereby granted * - * without fee, provided that the above copyright notice appears in all * - * copies and that both the copyright notice and this permission notice * - * appear in the supporting documentation. The authors make no claims * - * about the suitability of this software for any purpose. It is * - * provided "as is" without express or implied warranty. * - **************************************************************************/ - -/* -$Log$ -*/ - -/////////////////////////////////////////////////////////////////////////////// -// // -// This class contains the points for the ALICE event display // -// // -//Begin_Html -/* - -*/ -//End_Html -// // -// // -/////////////////////////////////////////////////////////////////////////////// - -#include "AliMUONpoints.h" -#include "AliMUONdisplay.h" -#include "AliRun.h" -#include "TPad.h" -#include "TVirtualPad.h" -#include "TPolyLine3D.h" -#include "TPaveText.h" -#include "TView.h" -#include "TMath.h" - -//const Int_t MAX_Nipx=1026, MAX_Nipy=1026; -const Int_t MAX_Nipx=400, MAX_Nipy=800; - -ClassImp(AliMUONpoints) - -//_____________________________________________________________________________ -AliMUONpoints::AliMUONpoints() -{ - // - // Default constructor - // - fHitIndex = 0; - fTrackIndex = 0; - fDigitIndex = 0; - fMarker[0] = fMarker[1] = fMarker[2]=0; - fMatrix = 0; -} - -//_____________________________________________________________________________ -AliMUONpoints::AliMUONpoints(Int_t npoints) - :AliPoints(npoints) -{ - // - // Standard constructor - // - fHitIndex = 0; - fTrackIndex = 0; - fDigitIndex = 0; - fMarker[0] = fMarker[1] = fMarker[2]=0; - fMatrix = 0; -} - -//_____________________________________________________________________________ -AliMUONpoints::~AliMUONpoints() -{ - // - // Default destructor - // - fHitIndex = 0; - fTrackIndex = 0; - fDigitIndex = 0; - for (Int_t i=0;i<3;i++){ - if (fMarker[i]) delete fMarker[i]; - } - fMatrix = 0; -} - -//_____________________________________________________________________________ -//void AliMUONpoints::ExecuteEvent(Int_t event, Int_t px, Int_t py) -//{ - // - //*-*-*-*-*-*-*-*-*-*Execute action corresponding to one event*-*-*-*-*-*-*-* - //*-* ========================================= - //*-* - //*-* This member function must be implemented to realize the action - //*-* corresponding to the mouse click on the object in the window - //*-* - //*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* -// gPad->SetCursor(kCross); - -//} -//_____________________________________________________________________________ -void AliMUONpoints::DumpHit() -{ - // - // Dump hit corresponding to this point - // - AliMUONhit *hit = GetHit(); - if (hit) hit->Dump(); -} - -//_____________________________________________________________________________ -void AliMUONpoints::DumpDigit() -{ - // - // Dump digit corresponding to this point - // - AliMUONdigit *digit = GetDigit(); - if (digit) digit->Dump(); -} - -//_____________________________________________________________________________ -void AliMUONpoints::InspectHit() -{ - // - // Inspect hit corresponding to this point - // - - if (fHitIndex < 0 ) return; - TVirtualPad *padsav = gPad; - AliMUONhit *hit = GetHit(); - if (hit) hit->Inspect(); - TVirtualPad *padinspect = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject("inspect"); - padinspect->cd(); - Float_t xmin = gPad->GetX1(); - Float_t xmax = gPad->GetX2(); - Float_t ymin = gPad->GetY1(); - Float_t ymax = gPad->GetY2(); - Float_t dy = ymax-ymin; - - TPaveText *pad = new TPaveText(xmin, ymin+0.1*dy, xmax, ymin+0.15*dy); - pad->SetBit(kCanDelete); - pad->SetFillColor(42); - pad->Draw(); - char ptitle[100]; - sprintf(ptitle," %s , fTrack: %d fTrackIndex: %d ",GetName(),fIndex,fTrackIndex); - pad->AddText(ptitle); - padinspect->cd(); - padinspect->Update(); - if (padsav) padsav->cd(); - -} - -//_____________________________________________________________________________ -void AliMUONpoints::InspectDigit() -{ - // - // Inspect digit corresponding to this point - // - if (fDigitIndex < 0) return; - TVirtualPad *padsav = gPad; - AliMUONdigit *digit = GetDigit(); - if (digit) digit->Inspect(); - TVirtualPad *padinspect = (TVirtualPad*)(gROOT->GetListOfCanvases())->FindObject("inspect"); - padinspect->cd(); - Float_t xmin = gPad->GetX1(); - Float_t xmax = gPad->GetX2(); - Float_t ymin = gPad->GetY1(); - Float_t ymax = gPad->GetY2(); - Float_t dy = ymax-ymin; - - TPaveText *pad = new TPaveText(xmin, ymin+0.1*dy, xmax, ymin+0.25*dy); - pad->SetBit(kCanDelete); - pad->SetFillColor(42); - pad->Draw(); - char ptitle[11][100]; - // sprintf(ptitle[11],"Tracks making this digit"); - // pad->AddText(ptitle[11]); - for (int i=0;i<10;i++) { - if (digit->fTracks[i] == 0) continue; - sprintf(ptitle[i],"fTrackIndex: %d Charge: %d",digit->fTracks[i],digit->fTcharges[i]); - pad->AddText(ptitle[i]); - } - padinspect->cd(); - padinspect->Update(); - if (padsav) padsav->cd(); - -} - -//_____________________________________________________________________________ -Int_t AliMUONpoints::GetTrackIndex() -{ - // - // Dump digit corresponding to this point - // - - this->Inspect(); - /* - if (fDigitIndex != 0) { - Int_t ncol=this->fMatrix->GetNcols(); - for (int i=0;ifMatrix))(0,i),(*(this->fMatrix))(1,i)); - } - } - */ - return fTrackIndex; -} - -//_____________________________________________________________________________ -AliMUONhit *AliMUONpoints::GetHit() const -{ - // - // Returns pointer to hit index in AliRun::fParticles - // - AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); - gAlice->TreeH()->GetEvent(fTrackIndex); - TClonesArray *MUONhits = MUON->Hits(); - Int_t nhits = MUONhits->GetEntriesFast(); - if (fHitIndex < 0 || fHitIndex >= nhits) return 0; - return (AliMUONhit*)MUONhits->UncheckedAt(fHitIndex); -} - -//_____________________________________________________________________________ -AliMUONdigit *AliMUONpoints::GetDigit() const -{ - // - // Returns pointer to digit index in AliRun::fParticles - // - - AliMUONdisplay *display=(AliMUONdisplay*)gAlice->Display(); - Int_t chamber=display->GetChamber(); - Int_t cathode=display->GetCathode(); - - AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); - TClonesArray *MUONdigits = MUON->DigitsAddress(chamber-1); - Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); - gAlice->TreeD()->GetEvent(nent-2+cathode-1); - //gAlice->TreeD()->GetEvent(cathode); - Int_t ndigits = MUONdigits->GetEntriesFast(); - if (fDigitIndex < 0 || fDigitIndex >= ndigits) return 0; - return (AliMUONdigit*)MUONdigits->UncheckedAt(fDigitIndex); -} -//_____________________________________________________________________________ -struct Bin { - const AliMUONdigit *dig; - int idx; - Bin() {dig=0; idx=-1;} -}; - -struct PreCluster : public AliMUONreccluster { - const AliMUONdigit* summit; - int idx; - int cut; - int npeaks; - int npoly; - float xpoly[100]; - float ypoly[100]; - float zpoly[100]; - PreCluster() : AliMUONreccluster() {cut=npeaks=npoly=0; - for (int k=0;k<100;k++) { - xpoly[k]=ypoly[k]=zpoly[k]=0; - } - } - -}; -//_____________________________________________________________________________ - -static void FindCluster(AliMUONchamber *iChamber, AliMUONsegmentation *segmentation, int i, int j, Bin bins[][MAX_Nipy], PreCluster &c) - -{ - - // - // Find clusters - // - - - Bin& b=bins[i][j]; - Int_t q=b.dig->fSignal; - - if (q<0) { - q=-q; - c.cut=1; - } - // if (b.idx >= 0 && b.idx != c.idx) { - if (b.idx >= 0 && b.idx > c.idx) { - c.idx=b.idx; - c.npeaks++; - } - - if (q > TMath::Abs(c.summit->fSignal)) c.summit=b.dig; - - Float_t zpos=iChamber->ZPosition(); - - Int_t npx = segmentation->Npx(); - Int_t npy = segmentation->Npy(); - - - // get pad coordinates and prepare the up and down steps - Int_t jup =(j-npy > 0) ? j+1 : j-1; - Int_t jdown=(j-npy > 0) ? j-1 : j+1; - - Float_t x, y; - segmentation->GetPadCxy(i-npx, j-npy,x, y); - Int_t isec0=segmentation->Sector(i-npx,j-npy); - - Float_t dpy = segmentation->Dpy(isec0); - Float_t dpx = segmentation->Dpx(isec0)/16; - Int_t ixx, iyy; - Float_t absx=TMath::Abs(x); - // iup - (y >0) ? segmentation->GetPadIxy(absx+dpx,y+dpy,ixx,iyy) : segmentation->GetPadIxy(absx+dpx,y-dpy,ixx,iyy); - - // Int_t jtest=TMath::Abs(iyy)-npy-1; - - Int_t iup=(x >0) ? ixx+npx : -ixx+npx; - // idown - (y >0) ? segmentation->GetPadIxy(absx+dpx,y-dpy,ixx,iyy) : segmentation->GetPadIxy(absx+dpx,y+dpy,ixx,iyy); - - Int_t idown=(x >0) ? ixx+npx : -ixx+npx; - if (bins[idown][jdown].dig == 0) { - (y >0) ? segmentation->GetPadIxy(absx-dpx,y-dpy,ixx,iyy) : segmentation->GetPadIxy(absx-dpx,y+dpy,ixx,iyy); - idown=(x >0) ? ixx+npx : -ixx+npx; - } - - - // calculate center of gravity - c.npoly++; - if (c.npoly > 100 ) { - printf("FindCluster - npoly >100, npoly %d \n",c.npoly); - c.npoly=100; - } - c.xpoly[c.npoly-1]=x; - c.ypoly[c.npoly-1]=y; - c.zpoly[c.npoly-1]=zpos; - - c.fX += q*x; - c.fY += q*y; - c.fQ += q; - - b.dig = 0; b.idx = c.idx; - - // left and right - if (bins[i-1][j].dig) FindCluster(iChamber,segmentation,i-1,j,bins,c); - if (bins[i+1][j].dig) FindCluster(iChamber,segmentation,i+1,j,bins,c); - // up and down - if (bins[iup][jup].dig) FindCluster(iChamber,segmentation,iup,jup,bins,c); - if (bins[idown][jdown].dig) FindCluster(iChamber,segmentation,idown,jdown,bins,c); - -} - -//_____________________________________________________________________________ - -void AliMUONpoints::GetCenterOfGravity() -{ - // - // simple MUON cluster finder from digits -- finds neighbours and - // calculates center of gravity for the cluster - // - - // const Int_t MAX_Nipx=1026, MAX_Nipy=1026; - - Bin bins[MAX_Nipx][MAX_Nipy]; - - AliMUONdisplay *display=(AliMUONdisplay*)gAlice->Display(); - Int_t chamber=display->GetChamber(); - Int_t cathode=display->GetCathode(); - - AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); - AliMUONchamber *iChamber; - AliMUONsegmentation *segmentation; - iChamber =&(MUON->Chamber(chamber-1)); - segmentation=iChamber->GetSegmentationModel(cathode); - Int_t npx = segmentation->Npx(); - Int_t npy = segmentation->Npy(); - Float_t zpos=iChamber->ZPosition(); - - TClonesArray *MUONdigits = MUON->DigitsAddress(chamber-1); - Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); - gAlice->TreeD()->GetEvent(nent-2+cathode-1); - //gAlice->TreeD()->GetEvent(cathode); - Int_t ndigits = MUONdigits->GetEntriesFast(); - if (fDigitIndex < 0 || fDigitIndex >= ndigits) return; - - AliMUONdigit *dig; - dig=(AliMUONdigit*)MUONdigits->UncheckedAt(fDigitIndex); - Int_t ipx=dig->fPadX; - Int_t ipy=dig->fPadY; - bins[ipx+npx][ipy+npy].dig=dig; - - int ndig; - int ncls=0; - for (ndig=0;ndigUncheckedAt(ndig); - int i=dig->fPadX, j=dig->fPadY; - bins[i+npx][j+npy].dig=dig; - } - PreCluster c; c.summit=bins[ipx+npx][ipy+npy].dig; c.idx=ncls; - FindCluster(iChamber,segmentation,ipx+npx, ipy+npy, bins, c); - - if (c.npeaks>1) { - printf("GetCenterOfGravity -- more than one peak"); - } - c.fX /= c.fQ; - c.fY /= c.fQ; - - c.fTracks[0]=c.summit->fTracks[0]; - c.fTracks[1]=c.summit->fTracks[1]; - c.fTracks[2]=c.summit->fTracks[2]; - ncls++; - AliMUONpoints *points = 0; - points = new AliMUONpoints(1); - points->SetMarkerColor(kYellow); - points->SetMarkerStyle(5); - points->SetMarkerSize(1.); - points->SetPoint(0,c.fX,c.fY,zpos); - points->SetParticle(-1); - points->Draw(); - - TPolyLine3D *pline=0; - /* - pline=new TPolyLine3D(c.npoly); - Int_t np=c.npoly; - TVector *xp=new TVector(c.npoly); - TVector *yp=new TVector(c.npoly); - TVector *zp=new TVector(c.npoly); - for (int i=0;iSetPoint(i,(*xp)(i),(*yp)(i),(*zp)(i)); - //printf("np, i, xp, yp, zp %d %d %f %f %f \n",np,i,(*xp)(i),(*yp)(i),(*zp)(i)); - } - */ - pline=new TPolyLine3D(c.npoly,c.xpoly,c.ypoly,c.zpoly); - pline->SetLineColor(kWhite); - pline->Draw(); - /* - delete xp; - delete yp; - delete zp; - */ - for (int k=0;k +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AliMUONproto.h" +#include "TTUBE.h" +#include "AliMUONClusterFinder.h" +#include "AliRun.h" +#include "AliMC.h" +#include "iostream.h" +#include "AliCallf77.h" +#include "AliConst.h" +#include "chainalice2.h" +#include "AliMUONSegResV1.h" +#include "AliMUONSegResV11.h" + +ClassImp(AliMUONproto) + +//___________________________________________ +AliMUONproto::AliMUONproto() + : AliMUON() +{ + cout << "\n Calling AliMUONproto constructor..." << endl; + + // + // + // +} + +//___________________________________________ +AliMUONproto::AliMUONproto(const char *name, const char *title) + : AliMUON(name,title) +// AliMUON defines everything, but the chamber for NCH=1 +{ + +// z-Positions of Chambers + const Float_t zch[1] = {975.}; +// +// inner diameter + const Float_t dmi[1] = {0.}; +// +// outer diameter + const Float_t dma[1] = {29.2}; +// +// +// Default Parameters for ALICE2 prototype + +// + (*fChambers)[0] = new AliMUONChamber(); + AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[0]; + chamber->SetGid(0); + chamber->SetZPOS(zch[0]); +// + chamber->InitGeo(zch[0]); + chamber->SetRInner(dmi[0]/2); + chamber->SetROuter(dma[0]/2); + + for (int i = 0; i <= 99; i++) { + fThreshold[i] = 0.; + } + +} + +//___________________________________________ +void AliMUONproto::GetRawDigits(Int_t evnb, Int_t *lptr, Int_t ilen) { + + Int_t ip = 0; + Int_t equip = 0; + Int_t nochnl; + Int_t loop; + Int_t val; + Int_t itype; + Int_t id; + Int_t serial; + Int_t equiplen; + + Int_t digits[5]; + + AliMUON* MUON = (AliMUON*)gAlice->GetModule("MUON"); + AliMUONSegmentationV1* seg = (AliMUONSegmentationV1*) Chamber(0).GetSegmentationModel(1); + + Int_t tracks[10]; + Int_t charges[10]; + + for (Int_t i = 0; i < 10; i++) { + tracks[i] = 0; + charges[i] = 0; + } + + Int_t ich = 0; + + nwtype: + + itype = lptr[ip++]; + id = lptr[ip++]; + equiplen = lptr[ip++]; + + if (equiplen < 0 ) return; + + if (itype != (int)(0XCACCA008)) { + ip += equiplen; + if (ip < ilen-2) goto nwtype; + } + else { + serial = id >> 16; + equip = id & 0x1; + if ((serial == 190) && (equip == 1)) { + for (loop = 0; loop < equiplen; loop++) { + nochnl = (lptr[ip] & 0x7ff000 ) >> 12; + val = lptr[ip] & 0x3ff; + // fill digits from raw data according to cathode connexions + if (group[nochnl][2][1]!=0) + digits[0] = group[nochnl][2][1] - 12; + else if (group[nochnl][1][1]!=0) + digits[0] = group[nochnl][1][1] - 12; + else + digits[0] = group[nochnl][0][1] - 12; + digits[1] = group[nochnl][0][0]; + if (digits[0] != seg->Ix(digits[0], digits[1])) + printf("Pb pour ix=%d,iy=%d\n", digits[0], digits[1]); + digits[2] = val; + digits[3] = 0; + digits[4] = 0; + if (digits[2] >= fThreshold[nochnl]) + MUON->AddDigits(ich, tracks, charges, digits); + + ip++; + } + } + else + ip += equiplen; + + if (ip < ilen-2) goto nwtype; + } + + gAlice->TreeD()->Fill(); + MUON->ResetDigits(); + + gAlice->TreeD()->Fill(); + MUON->ResetDigits(); + + char hname[30]; + sprintf(hname, "TreeD%d", evnb); + gAlice->TreeD()->Write(hname); + // reset tree + gAlice->TreeD()->Reset(); + +} + +//___________________________________________ +void AliMUONproto::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2) +{ + Int_t i=2*(id-1); + ((AliMUONChamber*)(*fChambers)[i])->SetPadSize(isec,p1,p2); +} + +//___________________________________________ +void AliMUONproto::SetChargeSlope(Int_t id, Float_t p1) +{ + Int_t i=2*(id-1); + ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1); +} + +//___________________________________________ +void AliMUONproto::SetChargeSpread(Int_t id, Float_t p1, Float_t p2) +{ + Int_t i=2*(id-1); + ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2); +} + +//___________________________________________ +void AliMUONproto::SetMaxAdc(Int_t id, Float_t p1) +{ + Int_t i=2*(id-1); + ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1); +} + +//___________________________________________ +void AliMUONproto::CreateGeometry() +{ + Int_t *idtmed = fIdtmed->GetArray()-1099; +// + Float_t zpos; + Float_t bpar[3]; + Int_t idGas=idtmed[1100]; + + AliMUONChamber *iChamber; +//******************************************************************** +// Prototype ALICE2 ** +//******************************************************************** + iChamber=(AliMUONChamber*) (*fChambers)[0]; + + zpos=iChamber->ZPosition(); +// + const Float_t X_POS = 11*.975/2; //half x + const Float_t Y_POS = 18*.55/2; //half y + const Float_t Z_POS = 0.325; + + bpar[0] = X_POS; + bpar[1] = Y_POS; + bpar[2] = Z_POS; + + gMC->Gsvolu("C01G", "BOX", idGas, bpar, 3); + gMC->Gspos("C01G", 1, "ALIC", -bpar[0], bpar[1], zpos, 0, "ONLY"); +} + +//___________________________________________ +void AliMUONproto::CreateMaterials() +{ + // *** DEFINITION OF AVAILABLE MUON MATERIALS *** + // + // Ar-CO2 gas + Float_t ag1[3] = { 39.95,12.01,16. }; + Float_t zg1[3] = { 18.,6.,8. }; + Float_t wg1[3] = { .8,.0667,.13333 }; + Float_t dg1 = .001821; + + Float_t epsil = .001; // Tracking precision, + Float_t tmaxfd = -20.; // Maximum angle due to field deflection + Float_t stmin = -.8; + Int_t ISXFLD = gAlice->Field()->Integ(); + Float_t SXMGMX = gAlice->Field()->Max(); + + // + // --- Define the various materials for GEANT --- + AliMixture(22, "ArCO2 80%$", ag1, zg1, dg1, 3, wg1); + + // + // Ar/CO2 + AliMedium(1, "ARG_CO2 ", 22, 1, ISXFLD, SXMGMX, tmaxfd, fMaxStepGas, + fMaxDestepAlu, epsil, stmin); + // Air + //AliMedium(1, "AIR_CH_US ", 15, 1, ISXFLD, SXMGMX, tmaxfd, -1., -.3, epsil, stmin); +} + +//___________________________________________ +void AliMUONproto::Init() +{ + printf("\n\n\n Start Init for Prototype ALICE2 - CPC chamber type\n\n\n"); + + // + // Initialize Tracking Chambers + // + + ( (AliMUONChamber*) (*fChambers)[0])->Init(); + + // + // Set the chamber (sensitive region) GEANT identifier + AliMC* gMC = AliMC::GetMC(); + ((AliMUONChamber*)(*fChambers)[0])->SetGid(gMC->VolId("C01G")); + + printf("\n\n\n Finished Init for Prototype ALICE2 - CPC chamber type\n\n\n"); + +} + +//___________________________________________ +void AliMUONproto::StepManager() +{ + Int_t copy, id; + static Int_t idvol; + static Int_t vol[2]; + Int_t ipart; + TLorentzVector pos; + TLorentzVector mom; + Float_t theta,phi; + Float_t destep, step; + + static Float_t eloss, eloss2, xhit, yhit, tlength; + const Float_t big=1.e10; + + // modifs perso + static Float_t hits[14]; + + TClonesArray &lhits = *fHits; + + // + // Set maximum step size for gas + // numed=gMC->GetMedium(); + // + // Only charged tracks + if( !(gMC->TrackCharge()) ) return; + // + // Only gas gap inside chamber + // Tag chambers and record hits when track enters + idvol=-1; + id=gMC->CurrentVolID(copy); + + for (Int_t i=1; i<=NCH; i++) { + if(id==((AliMUONChamber*)(*fChambers)[i-1])->GetGid()){ + vol[0]=i; + idvol=i-1; + } + } + if (idvol == -1) return; + // + // Get current particle id (ipart), track position (pos) and momentum (mom) + gMC->TrackPosition(pos); + gMC->TrackMomentum(mom); + + ipart = gMC->TrackPid(); + //Int_t ipart1 = gMC->IdFromPDG(ipart); + //printf("ich, ipart %d %d \n",vol[0],ipart1); + + // + // momentum loss and steplength in last step + destep = gMC->Edep(); + step = gMC->TrackStep(); + + // + // record hits when track enters ... + if( gMC->IsTrackEntering()) { + gMC->SetMaxStep(fMaxStepGas); + Double_t tc = mom[0]*mom[0]+mom[1]*mom[1]; + Double_t rt = TMath::Sqrt(tc); + Double_t pmom = TMath::Sqrt(tc+mom[2]*mom[2]); + Double_t tx=mom[0]/pmom; + Double_t ty=mom[1]/pmom; + Double_t tz=mom[2]/pmom; + Double_t s=((AliMUONChamber*)(*fChambers)[idvol]) + ->GetResponseModel() + ->Pitch()/tz; + theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg; + phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg; + hits[0] = Float_t(ipart); // Geant3 particle type + hits[1] = pos[0]+s*tx; // X-position for hit + hits[2] = pos[1]+s*ty; // Y-position for hit + hits[3] = pos[2]+s*tz; // Z-position for hit + hits[4] = theta; // theta angle of incidence + hits[5] = phi; // phi angle of incidence + hits[8] = (Float_t) fNclusters; // first padhit + hits[9] = -1; // last pad hit + + // modifs perso + hits[10] = mom[3]; // hit momentum P + hits[11] = mom[0]; // Px/P + hits[12] = mom[1]; // Py/P + hits[13] = mom[2]; // Pz/P + // fin modifs perso + + // phi angle of incidence + tlength = 0; + eloss = 0; + eloss2 = 0; + xhit = pos[0]; + yhit = pos[1]; + // Only if not trigger chamber + if(idvol<10) { + // + // Initialize hit position (cursor) in the segmentation model + ((AliMUONChamber*) (*fChambers)[idvol]) + ->SigGenInit(pos[0], pos[1], pos[2]); + } else { + //geant3->Gpcxyz(); + //printf("In the Trigger Chamber #%d\n",idvol-9); + } + } + eloss2+=destep; + + // + // Calculate the charge induced on a pad (disintegration) in case + // + // Mip left chamber ... + if( gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()){ + gMC->SetMaxStep(big); + eloss += destep; + tlength += step; + + // Only if not trigger chamber + if(idvol<10) { + if (eloss > 0) + MakePadHits(0.5*(xhit+pos[0]),0.5*(yhit+pos[1]),eloss,idvol); + } + + hits[6]=tlength; + hits[7]=eloss2; + if (fNclusters > (Int_t)hits[8]) { + hits[8]= hits[8]+1; + hits[9]= (Float_t) fNclusters; + } + + new(lhits[fNhits++]) + AliMUONHit(fIshunt,gAlice->CurrentTrack(),vol,hits); + eloss = 0; + // + // Check additional signal generation conditions + // defined by the segmentation + // model (boundary crossing conditions) + } else if + (((AliMUONChamber*) (*fChambers)[idvol]) + ->SigGenCond(pos[0], pos[1], pos[2])) + { + ((AliMUONChamber*) (*fChambers)[idvol]) + ->SigGenInit(pos[0], pos[1], pos[2]); +// printf("\n-> MakePadHits, reason special %d",ipart); + if (eloss > 0) + MakePadHits(0.5*(xhit+pos[0]),0.5*(yhit+pos[1]),eloss,idvol); + xhit = pos[0]; + yhit = pos[1]; + eloss = destep; + tlength += step ; + // + // nothing special happened, add up energy loss + } else { + eloss += destep; + tlength += step ; + } +} + +//___________________________________________ +void AliMUONproto::BuildGeometry() +{ + TNode *Node; + TNode *Top; + + const int kColorMUON = kBlue; + // + Top=gAlice->GetGeometry()->GetNode("alice"); + // + // + // + float dx, dy, dz, zpos; + + const Float_t cz[1]={975.}; + + zpos=cz[0]; + + dx=11*.975/2; + dy=18*.55/2; + dz=0.325; + + new TBRIK("C_MUON101","Mother volume for Proto.","void",dx*2,dy*2,dz*2); + TBRIK* PROTO = new TBRIK("PROT", "Proto. Sens. Region","void",dx,dy,dz); + Top->cd(); + Node = new TNode("MUON101","ChamberNode","C_MUON101",0,0,zpos,""); + Node->SetLineColor(kColorMUON); + Node->SetVisibility(0); + fNodes->Add(Node); + Node->cd(); + Node = new TNode("MUON201", "Proto. Sens. Region Node", PROTO, -dx, dy, dz); + Node->SetLineColor(kColorMUON); + +} + +//_____________________________________________________________________________ +void AliMUONproto::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); + + for (Int_t ich = 0; ich < NTrackingCh; 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 (seg) { + rec->SetSegmentation(seg); + rec->SetResponse(response); + rec->SetDigits(MUONdigits); + rec->SetChamber(ich); + rec->FindRawClusters(); + } + + TClonesArray *fRch; + fRch=RawClustAddress(ich); + fRch->Sort(); + // it seems to work + + } // for ich + // fill the tree + gAlice->TreeR()->Fill(); + + ResetRawClusters(); + } // for icat + + char hname[30]; + sprintf(hname,"TreeR%d",nev); + gAlice->TreeR()->Write(hname); + gAlice->TreeR()->Reset(); +} + +//_____________________________________________________________________________ +void AliMUONproto::SetThreshold() +{ + + ifstream inputFile("/home/alice/guernane/aliroot/pro/MUON/crped190.dat", ios::in); + + if (inputFile.fail()) { + cout << "Error opening file" << endl; + exit(2); + } + + char buff[32]; + Int_t Serial; + Int_t Ntrigger; + Int_t Nchannel; + Int_t i1; + Int_t i2; + + inputFile >> buff; + + inputFile >> Serial; + inputFile >> Ntrigger; + inputFile >> Nchannel; + inputFile >> i1; + inputFile >> i2; + + Float_t ped0[Nchannel]; + Float_t sig0[Nchannel]; + Float_t ped1[Nchannel]; + Float_t sig1[Nchannel]; + Int_t ichannel; + + for (Int_t i = 0; i < Nchannel-1; i++) { + ped0[i] = 0; + sig0[i] = 0; + ped1[i] = 0; + sig1[i] = 0; + } + + for (Int_t i = 0; i < Nchannel-1; i++) { + inputFile >> ichannel; + inputFile >> ped0[i]; + inputFile >> sig0[i]; + inputFile >> ped1[i]; + inputFile >> sig1[i]; + fThreshold[i] = fNsigma*sig1[i]; + } + + inputFile.close(); +} diff --git a/MUON/AliMUONproto.h b/MUON/AliMUONproto.h new file mode 100644 index 00000000000..f3ea9ecbb02 --- /dev/null +++ b/MUON/AliMUONproto.h @@ -0,0 +1,36 @@ +#ifndef MUONPROTO_H +#define MUONPROTO_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +#include "AliMUON.h" + +class AliMUONproto : public AliMUON { + public: + AliMUONv2(); + AliMUONv2(const char *name, const char *title); + virtual ~AliMUONv2() {} + virtual void CreateGeometry(); + virtual void CreateMaterials(); + virtual void Init(); + virtual Int_t IsVersion() const {return 2;} + virtual void StepManager(); + void GetRawDigits(Int_t iev, Int_t* ptr, Int_t len); + void SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2); + void SetThreshold(); + void SetNsigma(Int_t nsig) {fNsigma = nsig;}; + void BuildGeometry(); + void SetChargeSlope(Int_t id, Float_t p1); + void SetChargeSpread(Int_t id, Float_t p1, Float_t p2); + void SetMaxAdc(Int_t id, Float_t p1); + void FindClusters(Int_t, Int_t); + + private: + ClassDef(AliMUONproto,1) // Hits manager for set:MUON version 2 + protected: + Int_t fNsigma; + Float_t fThreshold[100]; +}; +#endif diff --git a/MUON/AliMUONv0.cxx b/MUON/AliMUONv0.cxx index 3818dac5ef3..482bd86f322 100644 --- a/MUON/AliMUONv0.cxx +++ b/MUON/AliMUONv0.cxx @@ -15,6 +15,26 @@ /* $Log$ +Revision 1.8.4.9 2000/06/12 19:20:49 morsch +Constructor sets default geometry, segmentation and response parameters. + +Revision 1.8.4.8 2000/06/09 21:55:28 morsch +Most coding rule violations corrected. + +Revision 1.8.4.7 2000/05/02 13:15:18 morsch +Coding rule violations RS3, RN13 corected + +Revision 1.8.4.6 2000/05/02 10:24:26 morsch +Public access to fdGas and fdAlu of AliMUONChamber replaced by getters. + +Revision 1.8.4.5 2000/04/26 19:58:47 morsch +Obsolete reference to trig_ removed. + +Revision 1.8.4.4 2000/04/19 19:42:47 morsch +change NCH to kNCH + +Revision 1.8.4.3 2000/02/17 08:17:43 morsch +Gammas and neutrons are also scored in the stepmanager */ ///////////////////////////////////////////////////////// @@ -25,23 +45,33 @@ $Log$ #include #include #include +#include #include "AliMUONv0.h" +#include "AliMUONChamber.h" #include "AliRun.h" #include "AliMC.h" -#include "iostream.h" +#include "AliMUONHit.h" +#include "AliMUONPadHit.h" #include "AliCallf77.h" #include "AliConst.h" - -#define trig trig_ - -extern "C" void type_of_call trig(float (*)[4], float (*)[4], int& iflag); +#include "AliMUONResponseV0.h" +#include "AliMUONResponseTrigger.h" +#include "AliMUONSegmentationV0.h" +#include "AliMUONSegmentationV01.h" +#include "AliMUONSegmentationV02.h" +#include "AliMUONSegmentationV04.h" +#include "AliMUONSegmentationV05.h" +#include "AliMUONSegmentationTrigger.h" +#include "AliMUONSegmentationTriggerX.h" +#include "AliMUONSegmentationTriggerY.h" ClassImp(AliMUONv0) //___________________________________________ AliMUONv0::AliMUONv0() : AliMUON() { +// Constructor fChambers = 0; } @@ -49,1472 +79,396 @@ AliMUONv0::AliMUONv0() : AliMUON() AliMUONv0::AliMUONv0(const char *name, const char *title) : AliMUON(name,title) { -// -// z-Positions of Chambers -// const Float_t zch[7]={515., 690., 962.85, 1249., 1449., 1610, 1710.}; - const Float_t zch[7]={515., 690., 975., 1249., 1449., 1610, 1710.}; -// -// inner diameter - const Float_t dmi[7]={ 35., 47., 66., 80., 80., 96., 101.96}; -// -// outer diameter - const Float_t dma[7]={183., 245., 316.6, 520., 520., 824., 874.}; -// - Int_t k; +// Constructor + fChambers = 0; - fChambers = new TObjArray(14); + SetIshunt(0); + SetMaxStepGas(0.1); + SetMaxStepAlu(0.1); +// +// Version 0 +// +// First define the number of planes that are segmented (1 or 2) by a call +// to SetNsec. +// Then chose for each chamber (chamber plane) the segmentation +// and response model. +// They should be equal for the two chambers of each station. In a future +// version this will be enforced. +// +// + Int_t chamber; + Int_t station; +// Default response + AliMUONResponseV0* response0 = new AliMUONResponseV0; + response0->SetSqrtKx3(0.7131); + response0->SetKx2(1.0107); + response0->SetKx4(0.4036); + response0->SetSqrtKy3(0.7642); + response0->SetKy2(0.9706); + response0->SetKy4(0.3831); + response0->SetPitch(0.25); + response0->SetSigmaIntegration(10.); + response0->SetChargeSlope(50); + response0->SetChargeSpread(0.18, 0.18); + response0->SetMaxAdc(4096); + response0->SetZeroSuppression(6); +//-------------------------------------------------------- +// Configuration for Chamber TC1/2 (Station 1) ---------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Float_t rseg1[4]={17.5, 55.2, 71.3, 95.5}; + Int_t nseg1[4]={4, 4, 2, 1}; +// + chamber=1; +//^^^^^^^^^ + SetNsec(chamber-1,2); +// + AliMUONSegmentationV01 *seg11=new AliMUONSegmentationV01; - for (Int_t i=0; i<7; i++) { - for (Int_t j=0; j< 2; j++) { -// -// -// Default Parameters for Muon Tracking Stations - k=2*i+j; -// - (*fChambers)[k] = new AliMUONchamber(); - AliMUONchamber* chamber = (AliMUONchamber*) (*fChambers)[k]; - chamber->SetGid(0); - chamber->SetZPOS(zch[i]); -// - chamber->InitGeo(zch[i]); - chamber->SetRInner(dmi[i]/2); - chamber->SetROuter(dma[i]/2); -// - } // Chamber j in - } // Station i - fMaxStepGas=0.01; - fMaxStepAlu=0.1; - fMaxDestepGas=-1; - fMaxDestepAlu=-1; -} - -//___________________________________________ -void AliMUONv0::Trigger(Float_t (*x)[4], Float_t (*y)[4], Int_t& iflag) -{ - trig(x,y,iflag); -} - -//___________________________________________ -void AliMUONv0::CreateGeometry() -{ - Int_t *idtmed = fIdtmed->GetArray()-1099; -// -// Note: all chambers have the same structure, which could be -// easily parameterised. This was intentionally not done in order -// to give a starting point for the implementation of the actual -// design of each station. - -// Distance between Stations -// - Float_t bpar[3]; - Float_t tpar[3]; - Float_t pgpar[10]; - Float_t zpos1, zpos2, zfpos; - Float_t dframep=3.; // Value for station 3 should be 6 ... - Float_t dframep1=3.; - Bool_t frames=kTRUE; - - - Float_t dframez=0.9; - Float_t dr; - Float_t dstation[5]={8., 8., 24.3, 8., 8.}; - // Float_t dstation[5]={20., 20., 24.3, 20., 20.}; - // Float_t dstation[5]={20., 100., 100., 100., 100.}; - -// -// Rotation matrices in the x-y plane - Int_t idrotm[1199]; -// phi= 0 deg - AliMatrix(idrotm[1100], 90., 0., 90., 90., 0., 0.); -// phi= 90 deg - AliMatrix(idrotm[1101], 90., 90., 90., 180., 0., 0.); -// phi= 180 deg - AliMatrix(idrotm[1102], 90., 180., 90., 270., 0., 0.); -// phi= 270 deg - AliMatrix(idrotm[1103], 90., 270., 90., 0., 0., 0.); -// - Float_t phi=2*TMath::Pi()/12/2; - -// -// pointer to the current chamber -// pointer to the current chamber - Int_t idAlu1=idtmed[1103]; - Int_t idAlu2=idtmed[1104]; -// Int_t idAlu1=idtmed[1100]; -// Int_t idAlu2=idtmed[1100]; - Int_t idAir=idtmed[1100]; - Int_t idGas=idtmed[1105]; - - - AliMUONchamber *iChamber; -//******************************************************************** -// Station 1 ** -//******************************************************************** -// CONCENTRIC - iChamber=(AliMUONchamber*) (*fChambers)[0]; - zpos1=iChamber->ZPosition()-dstation[0]/2; - zpos2=zpos1+dstation[0]; - zfpos=-(iChamber->fdGas+dframez)/2; - -// -// Mother volume - tpar[0] = iChamber->RInner()-dframep1; - tpar[1] = (iChamber->ROuter()+dframep1)/TMath::Cos(phi); - //tpar[2] = dstation[0]/2; - tpar[2] = dstation[0]/4; - - gMC->Gsvolu("C01M", "TUBE", idAir, tpar, 3); - gMC->Gsvolu("C02M", "TUBE", idAir, tpar, 3); - gMC->Gspos("C01M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); - gMC->Gspos("C02M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); -// Aluminium frames -// Outer frames - pgpar[0] = 360/12/2; - pgpar[1] = 360.; - pgpar[2] = 12.; - pgpar[3] = 2; - pgpar[4] = -dframez/2; - pgpar[5] = iChamber->ROuter(); - pgpar[6] = pgpar[5]+dframep1; - pgpar[7] = +dframez/2; - pgpar[8] = pgpar[5]; - pgpar[9] = pgpar[6]; - gMC->Gsvolu("C01O", "PGON", idAlu1, pgpar, 10); - gMC->Gsvolu("C02O", "PGON", idAlu1, pgpar, 10); - gMC->Gspos("C01O",1,"C01M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C01O",2,"C01M", 0.,0.,+zfpos, 0,"ONLY"); - gMC->Gspos("C02O",1,"C02M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C02O",2,"C02M", 0.,0.,+zfpos, 0,"ONLY"); -// -// Inner frame - tpar[0]= iChamber->RInner()-dframep1; - tpar[1]= iChamber->RInner(); - tpar[2]= dframez/2; - gMC->Gsvolu("C01I", "TUBE", idAlu1, tpar, 3); - gMC->Gsvolu("C02I", "TUBE", idAlu1, tpar, 3); - - gMC->Gspos("C01I",1,"C01M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C01I",2,"C01M", 0.,0.,+zfpos, 0,"ONLY"); - gMC->Gspos("C02I",1,"C02M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C02I",2,"C02M", 0.,0.,+zfpos, 0,"ONLY"); -// -// Frame Crosses - if (frames) { - - bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; - bpar[1] = dframep1/2; - bpar[2] = dframez/2; - gMC->Gsvolu("C01B", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C02B", "BOX", idAlu1, bpar, 3); - - gMC->Gspos("C01B",1,"C01M", +iChamber->RInner()+bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C01B",2,"C01M", -iChamber->RInner()-bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C01B",3,"C01M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C01B",4,"C01M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C01B",5,"C01M", +iChamber->RInner()+bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C01B",6,"C01M", -iChamber->RInner()-bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C01B",7,"C01M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C01B",8,"C01M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - - gMC->Gspos("C02B",1,"C02M", +iChamber->RInner()+bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C02B",2,"C02M", -iChamber->RInner()-bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C02B",3,"C02M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C02B",4,"C02M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C02B",5,"C02M", +iChamber->RInner()+bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C02B",6,"C02M", -iChamber->RInner()-bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C02B",7,"C02M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C02B",8,"C02M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - } -// -// Chamber Material represented by Alu sheet - tpar[0]= iChamber->RInner(); - tpar[1]= iChamber->ROuter(); - tpar[2] = (iChamber->fdGas+iChamber->fdAlu)/2; - gMC->Gsvolu("C01A", "TUBE", idAlu2, tpar, 3); - gMC->Gsvolu("C02A", "TUBE",idAlu2, tpar, 3); - gMC->Gspos("C01A", 1, "C01M", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C02A", 1, "C02M", 0., 0., 0., 0, "ONLY"); -// -// Sensitive volumes - // tpar[2] = iChamber->fdGas; - tpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C01G", "TUBE", idtmed[1108], tpar, 3); - gMC->Gsvolu("C02G", "TUBE", idtmed[1108], tpar, 3); - gMC->Gspos("C01G", 1, "C01A", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C02G", 1, "C02A", 0., 0., 0., 0, "ONLY"); -// -// Frame Crosses to be placed inside gas - if (frames) { - - dr = (iChamber->ROuter() - iChamber->RInner()); - bpar[0] = TMath::Sqrt(dr*dr-dframep1*dframep1/4)/2; - bpar[1] = dframep1/2; - bpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C01F", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C02F", "BOX", idAlu1, bpar, 3); - - gMC->Gspos("C01F",1,"C01G", +iChamber->RInner()+bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C01F",2,"C01G", -iChamber->RInner()-bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C01F",3,"C01G", 0, +iChamber->RInner()+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C01F",4,"C01G", 0, -iChamber->RInner()-bpar[0] , 0, -idrotm[1101],"ONLY"); - - gMC->Gspos("C02F",1,"C02G", +iChamber->RInner()+bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C02F",2,"C02G", -iChamber->RInner()-bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C02F",3,"C02G", 0, +iChamber->RInner()+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C02F",4,"C02G", 0, -iChamber->RInner()-bpar[0] , 0, - idrotm[1101],"ONLY"); - } - -// -// -//******************************************************************** -// Station 2 ** -//******************************************************************** - iChamber=(AliMUONchamber*) (*fChambers)[2]; - zpos1=iChamber->ZPosition()-dstation[1]/2; - zpos2=zpos1+dstation[1]; - zfpos=-(iChamber->fdGas+dframez)/2; - -// -// Mother volume - tpar[0] = iChamber->RInner()-dframep; - tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); - //tpar[2] = dstation[1]/2; - tpar[2] = dstation[1]/4; - - gMC->Gsvolu("C03M", "TUBE", idAir, tpar, 3); - gMC->Gsvolu("C04M", "TUBE", idAir, tpar, 3); - gMC->Gspos("C03M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); - gMC->Gspos("C04M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); -// Aluminium frames -// Outer frames - pgpar[0] = 360/12/2; - pgpar[1] = 360.; - pgpar[2] = 12.; - pgpar[3] = 2; - pgpar[4] = -dframez/2; - pgpar[5] = iChamber->ROuter(); - pgpar[6] = pgpar[5]+dframep; - pgpar[7] = +dframez/2; - pgpar[8] = pgpar[5]; - pgpar[9] = pgpar[6]; - gMC->Gsvolu("C03O", "PGON", idAlu1, pgpar, 10); - gMC->Gsvolu("C04O", "PGON", idAlu1, pgpar, 10); - gMC->Gspos("C03O",1,"C03M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C03O",2,"C03M", 0.,0.,+zfpos, 0,"ONLY"); - gMC->Gspos("C04O",1,"C04M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C04O",2,"C04M", 0.,0.,+zfpos, 0,"ONLY"); -// -// Inner frame - tpar[0]= iChamber->RInner()-dframep; - tpar[1]= iChamber->RInner(); - tpar[2]= dframez/2; - gMC->Gsvolu("C03I", "TUBE", idAlu1, tpar, 3); - gMC->Gsvolu("C04I", "TUBE", idAlu1, tpar, 3); - - gMC->Gspos("C03I",1,"C03M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C03I",2,"C03M", 0.,0.,+zfpos, 0,"ONLY"); - gMC->Gspos("C04I",1,"C04M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C04I",2,"C04M", 0.,0.,+zfpos, 0,"ONLY"); -// -// Frame Crosses - if (frames) { - - bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; - bpar[1] = dframep/2; - bpar[2] = dframez/2; - gMC->Gsvolu("C03B", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C04B", "BOX", idAlu1, bpar, 3); - - gMC->Gspos("C03B",1,"C03M", +iChamber->RInner()+bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C03B",2,"C03M", -iChamber->RInner()-bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C03B",3,"C03M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C03B",4,"C03M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C03B",5,"C03M", +iChamber->RInner()+bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C03B",6,"C03M", -iChamber->RInner()-bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C03B",7,"C03M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C03B",8,"C03M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - - gMC->Gspos("C04B",1,"C04M", +iChamber->RInner()+bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C04B",2,"C04M", -iChamber->RInner()-bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C04B",3,"C04M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C04B",4,"C04M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C04B",5,"C04M", +iChamber->RInner()+bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C04B",6,"C04M", -iChamber->RInner()-bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C04B",7,"C04M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C04B",8,"C04M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - } -// -// Chamber Material represented by Alu sheet - tpar[0]= iChamber->RInner(); - tpar[1]= iChamber->ROuter(); - tpar[2] = (iChamber->fdGas+iChamber->fdAlu)/2; - gMC->Gsvolu("C03A", "TUBE", idAlu2, tpar, 3); - gMC->Gsvolu("C04A", "TUBE", idAlu2, tpar, 3); - gMC->Gspos("C03A", 1, "C03M", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C04A", 1, "C04M", 0., 0., 0., 0, "ONLY"); -// -// Sensitive volumes - // tpar[2] = iChamber->fdGas; - tpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C03G", "TUBE", idGas, tpar, 3); - gMC->Gsvolu("C04G", "TUBE", idGas, tpar, 3); - gMC->Gspos("C03G", 1, "C03A", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C04G", 1, "C04A", 0., 0., 0., 0, "ONLY"); - - if (frames) { -// -// Frame Crosses to be placed inside gas - dr = (iChamber->ROuter() - iChamber->RInner()); - bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; - bpar[1] = dframep/2; - bpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C03F", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C04F", "BOX", idAlu1, bpar, 3); - - gMC->Gspos("C03F",1,"C03G", +iChamber->RInner()+bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C03F",2,"C03G", -iChamber->RInner()-bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C03F",3,"C03G", 0, +iChamber->RInner()+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C03F",4,"C03G", 0, -iChamber->RInner()-bpar[0] , 0, -idrotm[1101],"ONLY"); - - gMC->Gspos("C04F",1,"C04G", +iChamber->RInner()+bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C04F",2,"C04G", -iChamber->RInner()-bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C04F",3,"C04G", 0, +iChamber->RInner()+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C04F",4,"C04G", 0, -iChamber->RInner()-bpar[0] , 0, - idrotm[1101],"ONLY"); - } - - -#ifdef FUTURE -//******************************************************************** -// Station 3 ** -//******************************************************************** -// CONCENTRIC - iChamber=(AliMUONchamber*) (*fChambers)[4]; - zpos1=iChamber->ZPosition(); // 975-13.75 - zpos2=zpos1 // +dstation; - +24.3; -// -// Mother volume - tpar[0] = iChamber->RInner()-dframep; - tpar[1]= TMath::Sqrt((iChamber->ROuter()+dframep)*(iChamber->ROuter()+dframep) + dframep*dframep) ; - - tpar[2] = // 3.; - 5.325*2; - gMC->Gsvolu("C05M", "TUBE", idAir, tpar, 3); - gMC->Gsvolu("C06M", "TUBE", idAir, tpar, 3); - gMC->Gspos("C05M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); - gMC->Gspos("C06M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); + seg11->SetSegRadii(rseg1); + seg11->SetPadSize(3, 0.5); + seg11->SetDAnod(3.0/3./4); + seg11->SetPadDivision(nseg1); + + SetSegmentationModel(chamber-1, 1, seg11); // -// Mother volume for one quadrant - tspar[0]= tpar[0]; - tspar[1]= tpar[1]; - tspar[2]= // dframez; - 5.325; - tspar[3] = 0.-TMath::ATan2(dframep/2.,iChamber->RInner()-dframep)*180/kPI; - tspar[4] = 90.+TMath::ATan2(dframep/2,iChamber->RInner()-dframep)*180/kPI; - gMC->Gsvolu("C05Q", "TUBS", idAir, tspar, 5); - gMC->Gsvolu("C06Q", "TUBS", idAir, tspar, 5); -// Position the four quadrants - gMC->Gspos("C05Q",1,"C05M", 0., 0., 5.325, idrotm[1100], "ONLY"); - gMC->Gspos("C05Q",2,"C05M", 0., 0.,-5.325, idrotm[1101], "ONLY"); - gMC->Gspos("C05Q",3,"C05M", 0., 0., 5.325, idrotm[1102], "ONLY"); - gMC->Gspos("C05Q",4,"C05M", 0., 0.,-5.325, idrotm[1103], "ONLY"); + AliMUONSegmentationV02 *seg12=new AliMUONSegmentationV02; + seg12->SetSegRadii(rseg1); + seg12->SetPadSize(0.75, 2.0); + seg12->SetDAnod(3.0/3./4); + seg12->SetPadDivision(nseg1); + + SetSegmentationModel(chamber-1, 2, seg12); + + SetResponseModel(chamber-1, response0); + + chamber=2; +//^^^^^^^^^ +// + SetNsec(chamber-1,2); +// + AliMUONSegmentationV01 *seg21=new AliMUONSegmentationV01; + seg21->SetSegRadii(rseg1); + seg21->SetPadSize(3, 0.5); + seg21->SetDAnod(3.0/3./4); + seg21->SetPadDivision(nseg1); + SetSegmentationModel(chamber-1, 1, seg21); +// + AliMUONSegmentationV02 *seg22=new AliMUONSegmentationV02; + seg22->SetSegRadii(rseg1); + seg22->SetPadSize(0.75, 2.); + seg22->SetDAnod(3.0/3./4); + seg22->SetPadDivision(nseg1); + SetSegmentationModel(chamber-1, 2, seg22); + + SetResponseModel(chamber-1, response0); +// +//-------------------------------------------------------- +// Configuration for Chamber TC3/4 ----------------------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Float_t rseg2[4]={23.5, 47.1, 87.7, 122.5}; + Int_t nseg2[4]={4, 4, 2, 1}; +// + chamber=3; +//^^^^^^^^^ + SetNsec(chamber-1,2); +// + AliMUONSegmentationV01 *seg31=new AliMUONSegmentationV01; + seg31->SetSegRadii(rseg2); + seg31->SetPadSize(6, 0.5); + seg31->SetDAnod(3.0/3./4); + seg31->SetPadDivision(nseg2); + SetSegmentationModel(chamber-1, 1, seg31); +// + AliMUONSegmentationV02 *seg32=new AliMUONSegmentationV02; + seg32->SetSegRadii(rseg2); + seg32->SetPadSize(0.75, 4.); + seg32->SetPadDivision(nseg2); + seg32->SetDAnod(3.0/3./4); + + SetSegmentationModel(chamber-1, 2, seg32); + + SetResponseModel(chamber-1, response0); + + chamber=4; +//^^^^^^^^^ +// + SetNsec(chamber-1,2); +// + AliMUONSegmentationV01 *seg41=new AliMUONSegmentationV01; + seg41->SetSegRadii(rseg2); + seg41->SetPadSize(6, 0.5); + seg41->SetDAnod(3.0/3./4); + seg41->SetPadDivision(nseg2); + SetSegmentationModel(chamber-1, 1, seg41); +// + AliMUONSegmentationV02 *seg42=new AliMUONSegmentationV02; + seg42->SetSegRadii(rseg2); + seg42->SetPadSize(0.75, 4.); + seg42->SetPadDivision(nseg2); + seg42->SetDAnod(3.0/3./4); + + SetSegmentationModel(chamber-1, 2, seg42); + + SetResponseModel(chamber-1, response0); + + +//-------------------------------------------------------- +// Configuration for Chamber TC5/6 ----------------------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + chamber=5; +//^^^^^^^^^ + SetNsec(chamber-1,2); +// + AliMUONSegmentationV01 *seg51=new AliMUONSegmentationV01; + seg51->SetSegRadii(rseg2); + seg51->SetPadSize(6, 0.5); + seg51->SetDAnod(3.0/3./4); + seg51->SetPadDivision(nseg2); + SetSegmentationModel(chamber-1, 1, seg51); +// + AliMUONSegmentationV02 *seg52=new AliMUONSegmentationV02; + seg52->SetSegRadii(rseg2); + seg52->SetPadSize(0.75, 4.); + seg52->SetPadDivision(nseg2); + seg52->SetDAnod(3.0/3./4); + + SetSegmentationModel(chamber-1, 2, seg52); + SetResponseModel(chamber-1, response0); + + chamber=6; +//^^^^^^^^^ +// + SetNsec(chamber-1,2); +// + AliMUONSegmentationV01 *seg61=new AliMUONSegmentationV01; + seg61->SetSegRadii(rseg2); + seg61->SetPadSize(6, 0.5); + seg61->SetDAnod(3.0/3./4); + seg61->SetPadDivision(nseg2); + SetSegmentationModel(chamber-1, 1, seg61); +// + AliMUONSegmentationV02 *seg62=new AliMUONSegmentationV02; + seg62->SetSegRadii(rseg2); + seg62->SetPadSize(0.75, 4.); + seg62->SetPadDivision(nseg2); + seg62->SetDAnod(3.0/3./4); + + SetSegmentationModel(chamber-1, 2, seg62); + + SetResponseModel(chamber-1, response0); - gMC->Gspos("C06Q",1,"C06M", 0., 0., 5.325, idrotm[1100], "ONLY"); - gMC->Gspos("C06Q",2,"C06M", 0., 0.,-5.325, idrotm[1101], "ONLY"); - gMC->Gspos("C06Q",3,"C06M", 0., 0., 5.325, idrotm[1102], "ONLY"); - gMC->Gspos("C06Q",4,"C06M", 0., 0.,-5.325, idrotm[1103], "ONLY"); -// Aluminium frames -// Outer frame - tspar[0]= iChamber->ROuter(); - tspar[1]= iChamber->ROuter()+dframep; - tspar[3] = 0.; - tspar[4] = 90.; - gMC->Gsvolu("C05O", "TUBS", idAir, tspar, 5); - gMC->Gsvolu("C06O", "TUBS", idAir, tspar, 5); - gMC->Gspos("C05O",1,"C05Q", 0.,0.,0., 0,"ONLY"); - gMC->Gspos("C06O",1,"C06Q", 0.,0.,0., 0,"ONLY"); -// -// Inner frame - tspar[0]= iChamber->RInner()-dframep; - tspar[1]= iChamber->RInner(); - gMC->Gsvolu("C05I", "TUBS", idAir, tspar, 5); - gMC->Gsvolu("C06I", "TUBS", idAir, tspar, 5); - gMC->Gspos("C05I",1,"C05Q", 0.,0.,0., 0,"ONLY"); - gMC->Gspos("C06I",1,"C06Q", 0.,0.,0., 0,"ONLY"); -// -// Boundary half frame - bpar[0] = (iChamber->ROuter() +dframep*2 - iChamber->RInner())/2; - bpar[1] = dframep/4; - bpar[2] = 5.325; - gMC->Gsvolu("C05B", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C06B", "BOX", idAlu1, bpar, 3); -//place 2 boudaries - gMC->Gspos("C05B",1,"C05Q", iChamber->RInner()+bpar[0] ,-bpar[1],0., idrotm[1100],"ONLY"); - gMC->Gspos("C05B",2,"C05Q", -bpar[1],iChamber->RInner()+bpar[0] ,0., idrotm[1101],"ONLY"); - gMC->Gspos("C06B",1,"C06Q", iChamber->RInner()+bpar[0] ,-bpar[1],0., idrotm[1100],"ONLY"); - gMC->Gspos("C06B",2,"C06Q", -bpar[1],iChamber->RInner()+bpar[0] ,0., idrotm[1101],"ONLY"); -// -// Boundary second half frame (should not overlapp with sensitive surface, nor frames) -// Effective outer radius due to circle effect - rMax = TMath::Sqrt( - iChamber->ROuter()*iChamber->ROuter() - dframep*dframep ); - bpar[0] = (rMax - iChamber->RInner() ) /2; - bpar[2] = (5.325- (0.055 + 0.325)) / 2; - gMC->Gsvolu("C05H", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C06H", "BOX", idAlu1, bpar, 3); -//place 2 boudaries - gMC->Gspos("C05H",1,"C05Q", rMin+bpar[0],bpar[1], 0.055+0.325+bpar[2] , idrotm[1100],"ONLY"); - gMC->Gspos("C05H",2,"C05Q", rMin+bpar[0],bpar[1],-(0.055+0.325+bpar[2]), idrotm[1100],"ONLY"); - gMC->Gspos("C05H",3,"C05Q", bpar[1],rMin+bpar[0], 0.055+0.325+bpar[2] , idrotm[1101],"ONLY"); - gMC->Gspos("C05H",4,"C05Q", bpar[1],rMin+bpar[0],-(0.055+0.325+bpar[2]), idrotm[1101],"ONLY"); - gMC->Gspos("C06H",1,"C06Q", rMin+bpar[0],bpar[1], 0.055+0.325+bpar[2] , idrotm[1100],"ONLY"); - gMC->Gspos("C06H",2,"C06Q", rMin+bpar[0],bpar[1],-(0.055+0.325+bpar[2]), idrotm[1100],"ONLY"); - gMC->Gspos("C06H",3,"C06Q", bpar[1],rMin+bpar[0], 0.055+0.325+bpar[2] , idrotm[1101],"ONLY"); - gMC->Gspos("C06H",4,"C06Q", bpar[1],rMin+bpar[0],-(0.055+0.325+bpar[2]), idrotm[1101],"ONLY"); -// -// Chamber Material represented by Alu sheet - // tspar[2] = (iChamber->fdAlu)+(iChamber->fdGas); - tspar[0]= iChamber->RInner(); - tspar[1]= iChamber->ROuter(); - tspar[2] = 0.055 + 0.325; - gMC->Gsvolu("C05A", "TUBS", idAlu2, tspar, 5); - gMC->Gsvolu("C06A", "TUBS", idAlu2, tspar, 5); - gMC->Gspos("C05A", 1, "C05Q", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C06A", 1, "C06Q", 0., 0., 0., 0, "ONLY"); -// -// Sensitive volumes - // tpar[2] = iChamber->fdGas; - tspar[2] = 0.325; - gMC->Gsvolu("C05G", "TUBS", idGas, tspar, 5); - gMC->Gsvolu("C06G", "TUBS", idGas, tspar, 5); - gMC->Gspos("C05G", 1, "C05A", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C06G", 1, "C06A", 0., 0., 0., 0, "ONLY"); -// -// Overwrite sensitive volume with ALU -// Overwrite Gaz volume - bpar[2] = 0.325; - gMC->Gsvolu("C05Z", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C06Z", "BOX", idAlu1, bpar, 3); - gMC->Gspos("C05Z",1,"C05G", rMin+bpar[0] ,bpar[1],0., idrotm[1100],"ONLY"); - gMC->Gspos("C05Z",2,"C05G", bpar[1], rMin+bpar[0] ,0., idrotm[1101],"ONLY"); - gMC->Gspos("C06Z",1,"C06G", rMin+bpar[0] ,bpar[1],0., idrotm[1100],"ONLY"); - gMC->Gspos("C06Z",2,"C06G", bpar[1], rMin+bpar[0] ,0., idrotm[1101],"ONLY"); -#else -//******************************************************************** -// Station 3 ** -//******************************************************************** - iChamber=(AliMUONchamber*) (*fChambers)[4]; - zpos1=iChamber->ZPosition()-dstation[2]/2; - zpos2=zpos1+dstation[2]; - zfpos= // -(iChamber->fdGas+dframez)/2; - - ( 0.65 + 5.)/2; -// -// Mother volume - tpar[0] = iChamber->RInner()-dframep; - tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); - tpar[2] = // dstation[3]/2; - dstation[2]/4; - gMC->Gsvolu("C05M", "TUBE", idAir, tpar, 3); - gMC->Gsvolu("C06M", "TUBE", idAir, tpar, 3); - gMC->Gspos("C05M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); - gMC->Gspos("C06M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); -// Aluminium frames -// Outer frames - pgpar[0] = 360/12/2; - pgpar[1] = 360.; - pgpar[2] = 12.; - pgpar[3] = 2; - pgpar[4] = // -dframez/2; - - 5./2; - pgpar[5] = iChamber->ROuter(); - pgpar[6] = pgpar[5]+dframep; - pgpar[7] = // +dframez/2; - 5./2; - pgpar[8] = pgpar[5]; - pgpar[9] = pgpar[6]; - gMC->Gsvolu("C05O", "PGON", idAlu1, pgpar, 10); - gMC->Gsvolu("C06O", "PGON", idAlu1, pgpar, 10); - gMC->Gspos("C05O",1,"C05M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C05O",2,"C05M", 0.,0.,+zfpos, 0,"ONLY"); - gMC->Gspos("C06O",1,"C06M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C06O",2,"C06M", 0.,0.,+zfpos, 0,"ONLY"); -// -// Inner frame - tpar[0]= iChamber->RInner()-dframep; - tpar[1]= iChamber->RInner(); - tpar[2]= // dframez/2; - 5./2; - gMC->Gsvolu("C05I", "TUBE", idAlu1, tpar, 3); - gMC->Gsvolu("C06I", "TUBE", idAlu1, tpar, 3); - gMC->Gspos("C05I",1,"C05M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C05I",2,"C05M", 0.,0.,+zfpos, 0,"ONLY"); - gMC->Gspos("C06I",1,"C06M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C06I",2,"C06M", 0.,0.,+zfpos, 0,"ONLY"); // -// Frame Crosses - if (frames) { - bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; - bpar[1] = dframep/2; - bpar[2] = // dframez/2; - 5./2; - gMC->Gsvolu("C05B", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C06B", "BOX", idAlu1, bpar, 3); +// Station 3 + station=3; + SetPadSize(station, 1, 0.975, 0.55); - gMC->Gspos("C05B",1,"C05M", +iChamber->RInner()+bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C05B",2,"C05M", -iChamber->RInner()-bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C05B",3,"C05M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C05B",4,"C05M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C05B",5,"C05M", +iChamber->RInner()+bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C05B",6,"C05M", -iChamber->RInner()-bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C05B",7,"C05M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C05B",8,"C05M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); +//-------------------------------------------------------- +// Configuration for Chamber TC7/8 (Station 4) ---------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - gMC->Gspos("C06B",1,"C06M", +iChamber->RInner()+bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C06B",2,"C06M", -iChamber->RInner()-bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C06B",3,"C06M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C06B",4,"C06M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C06B",5,"C06M", +iChamber->RInner()+bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C06B",6,"C06M", -iChamber->RInner()-bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C06B",7,"C06M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C06B",8,"C06M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, - idrotm[1101],"ONLY"); - } - + Int_t nseg4[4]={4, 4, 2, 1}; + chamber=7; +//^^^^^^^^^ + SetNsec(chamber-1,2); // -// Chamber Material represented by Alu sheet - tpar[0]= iChamber->RInner(); - tpar[1]= iChamber->ROuter(); - tpar[2] = // (iChamber->fdGas+iChamber->fdAlu)/2; - 0.65 + 0.055; - gMC->Gsvolu("C05A", "TUBE", idAlu2, tpar, 3); - gMC->Gsvolu("C06A", "TUBE", idAlu2, tpar, 3); - gMC->Gspos("C05A", 1, "C05M", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C06A", 1, "C06M", 0., 0., 0., 0, "ONLY"); -// -// Sensitive volumes - tpar[2] = // iChamber->fdGas/2; - 0.65/2; - gMC->Gsvolu("C05G", "TUBE", idGas, tpar, 3); - gMC->Gsvolu("C06G", "TUBE", idGas, tpar, 3); - gMC->Gspos("C05G", 1, "C05A", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C06G", 1, "C06A", 0., 0., 0., 0, "ONLY"); -// -// Frame Crosses to be placed inside gas - if (frames) { - dr = (iChamber->ROuter() - iChamber->RInner()); - bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; - bpar[1] = dframep/2; - bpar[2] = // iChamber->fdGas/2; - 0.65/2; - gMC->Gsvolu("C05F", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C06F", "BOX", idAlu1, bpar, 3); - - gMC->Gspos("C05F",1,"C05G", +iChamber->RInner()+bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C05F",2,"C05G", -iChamber->RInner()-bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C05F",3,"C05G", 0, +iChamber->RInner()+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C05F",4,"C05G", 0, -iChamber->RInner()-bpar[0] , 0, -idrotm[1101],"ONLY"); + AliMUONSegmentationV04 *seg71=new AliMUONSegmentationV04; + seg71->SetPadSize(10.,0.5); + seg71->SetDAnod(0.25); + seg71->SetPadDivision(nseg4); + SetSegmentationModel(chamber-1, 1, seg71); + AliMUONSegmentationV05 *seg72=new AliMUONSegmentationV05; + seg72->SetPadSize(1,10); + seg72->SetDAnod(0.25); + seg72->SetPadDivision(nseg4); + SetSegmentationModel(chamber-1, 2, seg72); + + SetResponseModel(chamber-1, response0); + + chamber=8; +//^^^^^^^^^ + SetNsec(chamber-1,2); + AliMUONSegmentationV04 *seg81=new AliMUONSegmentationV04; + seg81->SetPadSize(10., 0.5); + seg81->SetPadDivision(nseg4); + seg81->SetDAnod(0.25); + SetSegmentationModel(chamber-1, 1, seg81); + + AliMUONSegmentationV05 *seg82=new AliMUONSegmentationV05; + seg82->SetPadSize(1, 10); + seg82->SetPadDivision(nseg4); + seg82->SetDAnod(0.25); + SetSegmentationModel(chamber-1, 2, seg82); + + SetResponseModel(chamber-1, response0); +//-------------------------------------------------------- +// Configuration for Chamber TC9/10 (Station 5) --------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + chamber=9; +//^^^^^^^^^ + SetNsec(chamber-1,2); +// + AliMUONSegmentationV04 *seg91=new AliMUONSegmentationV04; + seg91->SetPadSize(10.,0.5); + seg91->SetDAnod(0.25); + seg91->SetPadDivision(nseg4); + SetSegmentationModel(chamber-1, 1, seg91); + + AliMUONSegmentationV05 *seg92=new AliMUONSegmentationV05; + seg92->SetPadSize(1,10); + seg92->SetDAnod(0.25); + seg92->SetPadDivision(nseg4); + + SetSegmentationModel(chamber-1, 2, seg92); + + SetResponseModel(chamber-1, response0); + + chamber=10; +//^^^^^^^^^ + SetNsec(chamber-1,2); + AliMUONSegmentationV04 *seg101=new AliMUONSegmentationV04; + seg101->SetPadSize(10., 0.5); + seg101->SetPadDivision(nseg4); + seg101->SetDAnod(0.25); + SetSegmentationModel(chamber-1, 1, seg101); + + AliMUONSegmentationV05 *seg102=new AliMUONSegmentationV05; + seg102->SetPadSize(1,10); + seg102->SetPadDivision(nseg4); + seg102->SetDAnod(0.25); + SetSegmentationModel(chamber-1, 2, seg102); + + SetResponseModel(chamber-1, response0); - gMC->Gspos("C06F",1,"C06G", +iChamber->RInner()+bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C06F",2,"C06G", -iChamber->RInner()-bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C06F",3,"C06G", 0, +iChamber->RInner()+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C06F",4,"C06G", 0, -iChamber->RInner()-bpar[0] , 0, - idrotm[1101],"ONLY"); +//-------------------------------------------------------- +// Configuration for Trigger staions --------------------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + AliMUONResponseTrigger* responseTrigger0 = new AliMUONResponseTrigger; + + chamber=11; + SetNsec(chamber-1,2); + AliMUONSegmentationTriggerX *seg111=new AliMUONSegmentationTriggerX; + SetSegmentationModel(chamber-1, 1, seg111); + AliMUONSegmentationTriggerY *seg112=new AliMUONSegmentationTriggerY; + SetSegmentationModel(chamber-1, 2, seg112); + + SetResponseModel(chamber-1, responseTrigger0); + + chamber=12; + SetNsec(chamber-1,2); + AliMUONSegmentationTriggerX *seg121=new AliMUONSegmentationTriggerX; + SetSegmentationModel(chamber-1, 1, seg121); + AliMUONSegmentationTriggerY *seg122=new AliMUONSegmentationTriggerY; + SetSegmentationModel(chamber-1, 2, seg122); + + SetResponseModel(chamber-1, responseTrigger0); + + chamber=13; + SetNsec(chamber-1,2); + AliMUONSegmentationTriggerX *seg131=new AliMUONSegmentationTriggerX; + SetSegmentationModel(chamber-1, 1, seg131); + AliMUONSegmentationTriggerY *seg132=new AliMUONSegmentationTriggerY; + SetSegmentationModel(chamber-1, 2, seg132); + SetResponseModel(chamber-1, responseTrigger0); + + chamber=14; + SetNsec(chamber-1,2); + AliMUONSegmentationTriggerX *seg141=new AliMUONSegmentationTriggerX; + SetSegmentationModel(chamber-1, 1, seg141); + AliMUONSegmentationTriggerY *seg142=new AliMUONSegmentationTriggerY; + SetSegmentationModel(chamber-1, 2, seg142); + + SetResponseModel(chamber-1, responseTrigger0); } -#endif - -//******************************************************************** -// Station 4 ** -//******************************************************************** - iChamber=(AliMUONchamber*) (*fChambers)[6]; - zpos1=iChamber->ZPosition()-dstation[3]/2; - zpos2=zpos1+dstation[3]; - zfpos=-(iChamber->fdGas+dframez)/2; - -// -// Mother volume - tpar[0] = iChamber->RInner()-dframep; - tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); - //tpar[2] = dstation[3]/2; - tpar[2] = dstation[3]/4; - - gMC->Gsvolu("C07M", "TUBE", idAir, tpar, 3); - gMC->Gsvolu("C08M", "TUBE", idAir, tpar, 3); - gMC->Gspos("C07M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); - gMC->Gspos("C08M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); -// Aluminium frames -// Outer frames - pgpar[0] = 360/12/2; - pgpar[1] = 360.; - pgpar[2] = 12.; - pgpar[3] = 2; - pgpar[4] = -dframez/2; - pgpar[5] = iChamber->ROuter(); - pgpar[6] = pgpar[5]+dframep; - pgpar[7] = +dframez/2; - pgpar[8] = pgpar[5]; - pgpar[9] = pgpar[6]; - gMC->Gsvolu("C07O", "PGON", idAlu1, pgpar, 10); - gMC->Gsvolu("C08O", "PGON", idAlu1, pgpar, 10); - gMC->Gspos("C07O",1,"C07M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C07O",2,"C07M", 0.,0.,+zfpos, 0,"ONLY"); - gMC->Gspos("C08O",1,"C08M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C08O",2,"C08M", 0.,0.,+zfpos, 0,"ONLY"); -// -// Inner frame - tpar[0]= iChamber->RInner()-dframep; - tpar[1]= iChamber->RInner(); - tpar[2]= dframez/2; - gMC->Gsvolu("C07I", "TUBE", idAlu1, tpar, 3); - gMC->Gsvolu("C08I", "TUBE", idAlu1, tpar, 3); - - gMC->Gspos("C07I",1,"C07M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C07I",2,"C07M", 0.,0.,+zfpos, 0,"ONLY"); - gMC->Gspos("C08I",1,"C08M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C08I",2,"C08M", 0.,0.,+zfpos, 0,"ONLY"); -// -// Frame Crosses - if (frames) { - bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; - bpar[1] = dframep/2; - bpar[2] = dframez/2; - gMC->Gsvolu("C07B", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C08B", "BOX", idAlu1, bpar, 3); - - gMC->Gspos("C07B",1,"C07M", +iChamber->RInner()+bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C07B",2,"C07M", -iChamber->RInner()-bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C07B",3,"C07M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C07B",4,"C07M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C07B",5,"C07M", +iChamber->RInner()+bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C07B",6,"C07M", -iChamber->RInner()-bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C07B",7,"C07M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C07B",8,"C07M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - - gMC->Gspos("C08B",1,"C08M", +iChamber->RInner()+bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C08B",2,"C08M", -iChamber->RInner()-bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C08B",3,"C08M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C08B",4,"C08M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C08B",5,"C08M", +iChamber->RInner()+bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C08B",6,"C08M", -iChamber->RInner()-bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C08B",7,"C08M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C08B",8,"C08M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, - idrotm[1101],"ONLY"); - } - - -// -// Chamber Material represented by Alu sheet - tpar[0]= iChamber->RInner(); - tpar[1]= iChamber->ROuter(); - tpar[2] = (iChamber->fdGas+iChamber->fdAlu)/2; - gMC->Gsvolu("C07A", "TUBE", idAlu2, tpar, 3); - gMC->Gsvolu("C08A", "TUBE", idAlu2, tpar, 3); - gMC->Gspos("C07A", 1, "C07M", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C08A", 1, "C08M", 0., 0., 0., 0, "ONLY"); -// -// Sensitive volumes - // tpar[2] = iChamber->fdGas; - tpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C07G", "TUBE", idGas, tpar, 3); - gMC->Gsvolu("C08G", "TUBE", idGas, tpar, 3); - gMC->Gspos("C07G", 1, "C07A", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C08G", 1, "C08A", 0., 0., 0., 0, "ONLY"); -// -// Frame Crosses to be placed inside gas - if (frames) { - dr = (iChamber->ROuter() - iChamber->RInner()); - bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; - bpar[1] = dframep/2; - bpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C07F", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C08F", "BOX", idAlu1, bpar, 3); - - gMC->Gspos("C07F",1,"C07G", +iChamber->RInner()+bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C07F",2,"C07G", -iChamber->RInner()-bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C07F",3,"C07G", 0, +iChamber->RInner()+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C07F",4,"C07G", 0, -iChamber->RInner()-bpar[0] , 0, -idrotm[1101],"ONLY"); - - gMC->Gspos("C08F",1,"C08G", +iChamber->RInner()+bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C08F",2,"C08G", -iChamber->RInner()-bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C08F",3,"C08G", 0, +iChamber->RInner()+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C08F",4,"C08G", 0, -iChamber->RInner()-bpar[0] , 0, -idrotm[1101],"ONLY"); - } -//******************************************************************** -// Station 5 ** -//******************************************************************** - iChamber=(AliMUONchamber*) (*fChambers)[8]; - zpos1=iChamber->ZPosition()-dstation[4]/2; - zpos2=zpos1+dstation[4]; - zfpos=-(iChamber->fdGas+dframez)/2; - -// -// Mother volume - tpar[0] = iChamber->RInner()-dframep; - tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); - //tpar[2] = dstation[4]/2; - tpar[2] = dstation[4]/4; - - gMC->Gsvolu("C09M", "TUBE", idAir, tpar, 3); - gMC->Gsvolu("C10M", "TUBE", idAir, tpar, 3); - gMC->Gspos("C09M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); - gMC->Gspos("C10M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); -// Aluminium frames -// Outer frames - pgpar[0] = 360/12/2; - pgpar[1] = 360.; - pgpar[2] = 12.; - pgpar[3] = 2; - pgpar[4] = -dframez/2; - pgpar[5] = iChamber->ROuter(); - pgpar[6] = pgpar[5]+dframep; - pgpar[7] = +dframez/2; - pgpar[8] = pgpar[5]; - pgpar[9] = pgpar[6]; - gMC->Gsvolu("C09O", "PGON", idAlu1, pgpar, 10); - gMC->Gsvolu("C10O", "PGON", idAlu1, pgpar, 10); - gMC->Gspos("C09O",1,"C09M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C09O",2,"C09M", 0.,0.,+zfpos, 0,"ONLY"); - gMC->Gspos("C10O",1,"C10M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C10O",2,"C10M", 0.,0.,+zfpos, 0,"ONLY"); -// -// Inner frame - tpar[0]= iChamber->RInner()-dframep; - tpar[1]= iChamber->RInner(); - tpar[2]= dframez/2; - gMC->Gsvolu("C09I", "TUBE", idAlu1, tpar, 3); - gMC->Gsvolu("C10I", "TUBE", idAlu1, tpar, 3); - - gMC->Gspos("C09I",1,"C09M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C09I",2,"C09M", 0.,0.,+zfpos, 0,"ONLY"); - gMC->Gspos("C10I",1,"C10M", 0.,0.,-zfpos, 0,"ONLY"); - gMC->Gspos("C10I",2,"C10M", 0.,0.,+zfpos, 0,"ONLY"); - - if (frames) { -// -// Frame Crosses - - bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; - bpar[1] = dframep/2; - bpar[2] = dframez/2; - gMC->Gsvolu("C09B", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C10B", "BOX", idAlu1, bpar, 3); - - gMC->Gspos("C09B",1,"C09M", +iChamber->RInner()+bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C09B",2,"C09M", -iChamber->RInner()-bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C09B",3,"C09M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C09B",4,"C09M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C09B",5,"C09M", +iChamber->RInner()+bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C09B",6,"C09M", -iChamber->RInner()-bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C09B",7,"C09M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C09B",8,"C09M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - - gMC->Gspos("C10B",1,"C10M", +iChamber->RInner()+bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C10B",2,"C10M", -iChamber->RInner()-bpar[0] , 0,-zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C10B",3,"C10M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C10B",4,"C10M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C10B",5,"C10M", +iChamber->RInner()+bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C10B",6,"C10M", -iChamber->RInner()-bpar[0] , 0,+zfpos, -idrotm[1100],"ONLY"); - gMC->Gspos("C10B",7,"C10M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, -idrotm[1101],"ONLY"); - gMC->Gspos("C10B",8,"C10M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, - idrotm[1101],"ONLY"); - } - - -// -// Chamber Material represented by Alu sheet - tpar[0]= iChamber->RInner(); - tpar[1]= iChamber->ROuter(); - tpar[2] = (iChamber->fdGas+iChamber->fdAlu)/2; - gMC->Gsvolu("C09A", "TUBE", idAlu2, tpar, 3); - gMC->Gsvolu("C10A", "TUBE", idAlu2, tpar, 3); - gMC->Gspos("C09A", 1, "C09M", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C10A", 1, "C10M", 0., 0., 0., 0, "ONLY"); -// -// Sensitive volumes - // tpar[2] = iChamber->fdGas; - tpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C09G", "TUBE", idGas, tpar, 3); - gMC->Gsvolu("C10G", "TUBE", idGas, tpar, 3); - gMC->Gspos("C09G", 1, "C09A", 0., 0., 0., 0, "ONLY"); - gMC->Gspos("C10G", 1, "C10A", 0., 0., 0., 0, "ONLY"); +void AliMUONv0::CreateGeometry() +{ +// Creates coarse geometry for hit density simulations + Int_t *idtmed = fIdtmed->GetArray()-1099; // -// Frame Crosses to be placed inside gas - if (frames) { - dr = (iChamber->ROuter() - iChamber->RInner()); - bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; - bpar[1] = dframep/2; - bpar[2] = iChamber->fdGas/2; - gMC->Gsvolu("C09F", "BOX", idAlu1, bpar, 3); - gMC->Gsvolu("C10F", "BOX", idAlu1, bpar, 3); - - gMC->Gspos("C09F",1,"C09G", +iChamber->RInner()+bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C09F",2,"C09G", -iChamber->RInner()-bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C09F",3,"C09G", 0, +iChamber->RInner()+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C09F",4,"C09G", 0, -iChamber->RInner()-bpar[0] , 0, -idrotm[1101],"ONLY"); - - gMC->Gspos("C10F",1,"C10G", +iChamber->RInner()+bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C10F",2,"C10G", -iChamber->RInner()-bpar[0] , 0, 0, -idrotm[1100],"ONLY"); - gMC->Gspos("C10F",3,"C10G", 0, +iChamber->RInner()+bpar[0] , 0, -idrotm[1101],"ONLY"); - gMC->Gspos("C10F",4,"C10G", 0, -iChamber->RInner()-bpar[0] , 0, -idrotm[1101],"ONLY"); + Float_t zpos, dAlu, tpar[3]; + Int_t idAir=idtmed[1100]; + Int_t idAlu=idtmed[1103]; + + AliMUONChamber *iChamber; + // Loop over all chambers (tracking and trigger) + for (Int_t ch = 0; ch < kNCH; ch++) { + char alu[8]; + char gas[8]; + + iChamber=(AliMUONChamber*) (*fChambers)[ch]; + // Z of the chamber + zpos=iChamber->Z(); + dAlu=iChamber->DAlu(); + if (ch < kNTrackingCh) { + // tracking chambers + sprintf(alu,"CA0%1d",ch); + sprintf(gas,"CG0%1d",ch); + } else { + // trigger chambers + sprintf(alu,"CA%2d",ch); + sprintf(gas,"CG%2d",ch); + } +// + printf("\n %d, %s, %s \n ", ch, alu, gas); + + tpar[0] = iChamber->RInner(); + tpar[1] = iChamber->ROuter(); + tpar[2] = (dAlu+0.2)/2.; + if (ch !=4 && ch !=5) { + gMC->Gsvolu(alu, "TUBE", idAlu, tpar, 3); + tpar[2] = 0.1; + gMC->Gsvolu(gas, "TUBE", idAir, tpar, 3); + } else { + gMC->Gsvolu(alu, "TUBE", idAlu, tpar, 3); + tpar[2] = 0.1; + gMC->Gsvolu(gas, "TUBE", idAir, tpar, 3); + } + gMC->Gspos(gas, 1, alu, 0., 0., 0., 0, "ONLY"); + gMC->Gspos(alu, 1, "ALIC", 0., 0., zpos, 0, "ONLY"); + iChamber->SetGid(gMC->VolId(gas)); } - -/////////////////////////////////////// -// GEOMETRY FOR THE TRIGGER CHAMBERS // -/////////////////////////////////////// - -// Distance between planes inside each trigger station - const Float_t DTPLANES = 15.; - -// Parameters of the Trigger Chambers - //Station 1 - - const Float_t X_MC1_MIN=38.; - const Float_t X_MC1_MED=51.; - const Float_t X_MC1_MAX=272.; - const Float_t Y_MC1_MIN=34.; - const Float_t Y_MC1_MAX=51.; - const Float_t R_MIN1=48.; - const Float_t R_MAX1=64.; - -// Station 1 - iChamber=(AliMUONchamber*) (*fChambers)[10]; - zpos1=iChamber->ZPosition(); - zpos2=zpos1+DTPLANES; - -// Mother volume definition - tpar[0] = iChamber->RInner(); - tpar[1] = iChamber->ROuter(); - tpar[2] = 0.4; - gMC->Gsvolu("CM11", "TUBE", idAir, tpar, 3); - gMC->Gsvolu("CM12", "TUBE", idAir, tpar, 3); - -// Definition of the flange between the beam shielding and the RPC - tpar[0]= R_MIN1; - tpar[1]= R_MAX1; - tpar[2]= 0.4; - - gMC->Gsvolu("CF1A", "TUBE", idAlu1, tpar, 3); //Al - gMC->Gspos("CF1A", 1, "CM11", 0., 0., 0., 0, "MANY"); - gMC->Gspos("CF1A", 2, "CM12", 0., 0., 0., 0, "MANY"); - -// Definition of prototype for chambers in the first plane - - tpar[0]= 0.; - tpar[1]= 0.; - tpar[2]= 0.; - - gMC->Gsvolu("CC1A", "BOX ", idAlu1, tpar, 0); //Al - gMC->Gsvolu("CB1A", "BOX ", idtmed[1107], tpar, 0); //Bakelite - gMC->Gsvolu("CG1A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer - -// chamber type A - tpar[0] = -1.; - tpar[1] = -1.; - - const Float_t X_MC1A=X_MC1_MED+(X_MC1_MAX-X_MC1_MED)/2.; - const Float_t Y_MC1A=0.; - const Float_t Z_MC1A=0.; - - tpar[2] = 0.1; - gMC->Gsposp("CG1A", 1, "CB1A", 0., 0., 0., 0, "ONLY",tpar,3); - tpar[2] = 0.3; - gMC->Gsposp("CB1A", 1, "CC1A", 0., 0., 0., 0, "ONLY",tpar,3); - tpar[2] = 0.4; - tpar[0] = (X_MC1_MAX-X_MC1_MED)/2.; - tpar[1] = Y_MC1_MIN; - gMC->Gsposp("CC1A", 1, "CM11",X_MC1A,Y_MC1A,Z_MC1A, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 2, "CM11",-X_MC1A,Y_MC1A,Z_MC1A, 0, "ONLY", tpar, 3); - -// chamber type B - tpar[0] = (X_MC1_MAX-X_MC1_MIN)/2.; - tpar[1] = (Y_MC1_MAX-Y_MC1_MIN)/2.; - - const Float_t X_MC1B=X_MC1_MIN+tpar[0]; - const Float_t Y_MC1B=Y_MC1_MIN+tpar[1]; - const Float_t Z_MC1B=0.; - - gMC->Gsposp("CC1A", 3, "CM11",X_MC1B,Y_MC1B,Z_MC1B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 4, "CM11",-X_MC1B,Y_MC1B,Z_MC1B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 5, "CM11",X_MC1B,-Y_MC1B,Z_MC1B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 6, "CM11",-X_MC1B,-Y_MC1B,Z_MC1B, 0, "ONLY", tpar, 3); - -// chamber type C - tpar[0] = X_MC1_MAX/2; - tpar[1] = Y_MC1_MAX/2; - - const Float_t X_MC1C=tpar[0]; - const Float_t Y_MC1C=Y_MC1_MAX+tpar[1]; - const Float_t Z_MC1C=0.; - - gMC->Gsposp("CC1A", 7, "CM11",X_MC1C,Y_MC1C,Z_MC1C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 8, "CM11",-X_MC1C,Y_MC1C,Z_MC1C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 9, "CM11",X_MC1C,-Y_MC1C,Z_MC1C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 10, "CM11",-X_MC1C,-Y_MC1C,Z_MC1C, 0, "ONLY", tpar, 3); - -// chamber type D - tpar[0] = X_MC1_MAX/2.; - tpar[1] = Y_MC1_MIN; - - const Float_t X_MC1D=tpar[0]; - const Float_t Z_MC1D=0.; - - Float_t Y_MC1D=4.*Y_MC1_MIN; - gMC->Gsposp("CC1A", 11, "CM11",X_MC1D,Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 12, "CM11",X_MC1D,-Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 13, "CM11",-X_MC1D,Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 14, "CM11",-X_MC1D,-Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - - Y_MC1D=6.*Y_MC1_MIN; - gMC->Gsposp("CC1A", 15, "CM11",X_MC1D,Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 16, "CM11",X_MC1D,-Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 17, "CM11",-X_MC1D,Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 18, "CM11",-X_MC1D,-Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - - Y_MC1D=8.*Y_MC1_MIN; - gMC->Gsposp("CC1A", 19, "CM11",X_MC1D,Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 20, "CM11",X_MC1D,-Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 21, "CM11",-X_MC1D,Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC1A", 22, "CM11",-X_MC1D,-Y_MC1D,Z_MC1D, 0, "ONLY", tpar, 3); - -// Positioning first plane in ALICE - gMC->Gspos("CM11", 1, "ALIC", 0., 0., zpos1, 0, "ONLY"); - -// End of geometry definition for the first plane - -// Station 1 - plan 2 - same RPCs as plan 1 ==> small non covered area -// Y position moved (ratio zpos2/zpos1) - const Float_t Z_1S2=zpos2/zpos1; - -// Definition of prototype for chambers in the second plane - - tpar[0]= 0.; - tpar[1]= 0.; - tpar[2]= 0.; - - gMC->Gsvolu("CC2A", "BOX ", idAlu1, tpar, 0); //Al - gMC->Gsvolu("CB2A", "BOX ", idtmed[1107], tpar, 0); //Bakelite - gMC->Gsvolu("CG2A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer - -// chamber type A - tpar[0] = -1.; - tpar[1] = -1.; - - const Float_t X_MC2A=X_MC1A; - const Float_t Y_MC2A=0.; - const Float_t Z_MC2A=0.; - - tpar[2] = 0.1; - gMC->Gsposp("CG2A", 1, "CB2A", 0., 0., 0., 0, "ONLY",tpar,3); - tpar[2] = 0.3; - gMC->Gsposp("CB2A", 1, "CC2A", 0., 0., 0., 0, "ONLY",tpar,3); - tpar[2] = 0.4; - tpar[0] = (X_MC1_MAX-X_MC1_MED)/2.; - tpar[1] = Y_MC1_MIN; - gMC->Gsposp("CC2A", 1, "CM12",X_MC2A,Y_MC2A,Z_MC2A, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 2, "CM12",-X_MC2A,Y_MC2A,Z_MC2A, 0, "ONLY", tpar, 3); - -// chamber type B - tpar[0] = (X_MC1_MAX-X_MC1_MIN)/2.; - tpar[1] = (Y_MC1_MAX-Y_MC1_MIN)/2.; - - const Float_t X_MC2B=X_MC1B; - const Float_t Y_MC2B=2.*Y_MC1_MIN*Z_1S2-Y_MC1_MIN*1.5+Y_MC1_MAX*0.5; - const Float_t Z_MC2B=0.; - - gMC->Gsposp("CC2A", 3, "CM12",X_MC2B,Y_MC2B,Z_MC2B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 4, "CM12",-X_MC2B,Y_MC2B,Z_MC2B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 5, "CM12",X_MC2B,-Y_MC2B,Z_MC2B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 6, "CM12",-X_MC2B,-Y_MC2B,Z_MC2B, 0, "ONLY", tpar, 3); - -// chamber type C - tpar[0] = X_MC1_MAX/2; - tpar[1] = Y_MC1_MAX/2; - - const Float_t X_MC2C=X_MC1C; - const Float_t Y_MC2C=2.*Y_MC1_MIN*Z_1S2-Y_MC1_MIN*2.+Y_MC1_MAX*1.5; - const Float_t Z_MC2C=0.; - - gMC->Gsposp("CC2A", 7, "CM12",X_MC2C,Y_MC2C,Z_MC2C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 8, "CM12",-X_MC2C,Y_MC2C,Z_MC2C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 9, "CM12",X_MC2C,-Y_MC2C,Z_MC2C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 10, "CM12",-X_MC2C,-Y_MC2C,Z_MC2C, 0, "ONLY", tpar, 3); - -// chamber type D - tpar[0] = X_MC1_MAX/2.; - tpar[1] = Y_MC1_MIN; - - const Float_t X_MC2D=X_MC1D; - const Float_t Z_MC2D=0.; - - Float_t Y_MC2D=4.*Y_MC1_MIN*Z_1S2; - gMC->Gsposp("CC2A", 11, "CM12",X_MC2D,Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 12, "CM12",X_MC2D,-Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 13, "CM12",-X_MC2D,Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 14, "CM12",-X_MC2D,-Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - - Y_MC2D=6.*Y_MC1_MIN*Z_1S2; - gMC->Gsposp("CC2A", 15, "CM12",X_MC2D,Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 16, "CM12",X_MC2D,-Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 17, "CM12",-X_MC2D,Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 18, "CM12",-X_MC2D,-Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - - Y_MC2D=8.*Y_MC1_MIN*Z_1S2; - gMC->Gsposp("CC2A", 19, "CM12",X_MC2D,Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 20, "CM12",X_MC2D,-Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 21, "CM12",-X_MC2D,Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC2A", 22, "CM12",-X_MC2D,-Y_MC2D,Z_MC2D, 0, "ONLY", tpar, 3); - - gMC->Gspos("CM12", 1, "ALIC", 0., 0., zpos2, 0, "ONLY"); - -// Station 2 - iChamber=(AliMUONchamber*) (*fChambers)[12]; - Float_t zpos3=iChamber->ZPosition(); - Float_t zpos4=zpos3+DTPLANES; - -// Parameters of the Trigger Chambers - //Station 2 - const Float_t X_MC3_MIN=X_MC1_MIN*zpos3/zpos1; - const Float_t X_MC3_MED=X_MC1_MED*zpos3/zpos1; - const Float_t X_MC3_MAX=X_MC1_MAX*zpos3/zpos1; - const Float_t Y_MC3_MIN=Y_MC1_MIN*zpos3/zpos1; - const Float_t Y_MC3_MAX=Y_MC1_MAX*zpos3/zpos1; - const Float_t R_MIN3=R_MIN1*zpos3/zpos1; - const Float_t R_MAX3=R_MAX1*zpos3/zpos1; - -// Mother volume definition - tpar[0] = iChamber->RInner(); - tpar[1] = iChamber->ROuter(); - tpar[2] = 0.4; - gMC->Gsvolu("CM21", "TUBE", idAir, tpar, 3); - gMC->Gsvolu("CM22", "TUBE", idAir, tpar, 3); - -// Definition of the flange between the beam shielding and the RPC - tpar[0]= R_MIN3; - tpar[1]= R_MAX3; - tpar[2]= 0.4; - - gMC->Gsvolu("CF2A", "TUBE", idAlu1, tpar, 3); //Al - gMC->Gspos("CF2A", 1, "CM21", 0., 0., 0., 0, "MANY"); - gMC->Gspos("CF2A", 2, "CM22", 0., 0., 0., 0, "MANY"); - -// Definition of prototype for chambers in the third plane - - tpar[0]= 0.; - tpar[1]= 0.; - tpar[2]= 0.; - - gMC->Gsvolu("CC3A", "BOX ", idAlu1, tpar, 0); //Al - gMC->Gsvolu("CB3A", "BOX ", idtmed[1107], tpar, 0); //Bakelite - gMC->Gsvolu("CG3A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer - -// chamber type A - tpar[0] = -1.; - tpar[1] = -1.; - - const Float_t X_MC3A=X_MC3_MED+(X_MC3_MAX-X_MC3_MED)/2.; - const Float_t Y_MC3A=0.; - const Float_t Z_MC3A=0.; - - tpar[2] = 0.1; - gMC->Gsposp("CG3A", 1, "CB3A", 0., 0., 0., 0, "ONLY",tpar,3); - tpar[2] = 0.3; - gMC->Gsposp("CB3A", 1, "CC3A", 0., 0., 0., 0, "ONLY",tpar,3); - tpar[0] = (X_MC3_MAX-X_MC3_MED)/2.; - tpar[1] = Y_MC3_MIN; - tpar[2] = 0.4; - gMC->Gsposp("CC3A", 1, "CM21",X_MC3A,Y_MC3A,Z_MC3A, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 2, "CM21",-X_MC3A,Y_MC3A,Z_MC3A, 0, "ONLY", tpar, 3); - -// chamber type B - tpar[0] = (X_MC3_MAX-X_MC3_MIN)/2.; - tpar[1] = (Y_MC3_MAX-Y_MC3_MIN)/2.; - - const Float_t X_MC3B=X_MC3_MIN+tpar[0]; - const Float_t Y_MC3B=Y_MC3_MIN+tpar[1]; - const Float_t Z_MC3B=0.; - - gMC->Gsposp("CC3A", 3, "CM21",X_MC3B,Y_MC3B,Z_MC3B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 4, "CM21",-X_MC3B,Y_MC3B,Z_MC3B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 5, "CM21",X_MC3B,-Y_MC3B,Z_MC3B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 6, "CM21",-X_MC3B,-Y_MC3B,Z_MC3B, 0, "ONLY", tpar, 3); - -// chamber type C - tpar[0] = X_MC3_MAX/2.; - tpar[1] = Y_MC3_MAX/2.; - - const Float_t X_MC3C=tpar[0]; - const Float_t Y_MC3C=Y_MC3_MAX+tpar[1]; - const Float_t Z_MC3C=0.; - - gMC->Gsposp("CC3A", 7, "CM21",X_MC3C,Y_MC3C,Z_MC3C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 8, "CM21",-X_MC3C,Y_MC3C,Z_MC3C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 9, "CM21",X_MC3C,-Y_MC3C,Z_MC3C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 10, "CM21",-X_MC3C,-Y_MC3C,Z_MC3C, 0, "ONLY", tpar, 3); - -// chamber type D - tpar[0] = X_MC3_MAX/2.; - tpar[1] = Y_MC3_MIN; - - const Float_t X_MC3D=tpar[0]; - const Float_t Z_MC3D=0.; - - Float_t Y_MC3D=4.*Y_MC3_MIN; - gMC->Gsposp("CC3A", 11, "CM21",X_MC3D,Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 12, "CM21",X_MC3D,-Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 13, "CM21",-X_MC3D,Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 14, "CM21",-X_MC3D,-Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - - Y_MC3D=6.*Y_MC3_MIN; - gMC->Gsposp("CC3A", 15, "CM21",X_MC3D,Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 16, "CM21",X_MC3D,-Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 17, "CM21",-X_MC3D,Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 18, "CM21",-X_MC3D,-Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - - Y_MC3D=8.*Y_MC3_MIN; - gMC->Gsposp("CC3A", 19, "CM21",X_MC3D,Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 20, "CM21",X_MC3D,-Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 21, "CM21",-X_MC3D,Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC3A", 22, "CM21",-X_MC3D,-Y_MC3D,Z_MC3D, 0, "ONLY", tpar, 3); - -// Positioning third plane in ALICE - gMC->Gspos("CM21", 1, "ALIC", 0., 0., zpos3, 0, "ONLY"); - -// End of geometry definition for the third plane - -// Station 2 - plan 4 - same RPCs as plan 3 ==> small non covered area -// Y position moved (ratio zpos4/zpos3) - const Float_t Z_3S4=zpos4/zpos3; - -// Definition of prototype for chambers in the fourth plane - - tpar[0]= 0.; - tpar[1]= 0.; - tpar[2]= 0.; - - gMC->Gsvolu("CC4A", "BOX ", idAlu1, tpar, 0); //Al - gMC->Gsvolu("CB4A", "BOX ", idtmed[1107], tpar, 0); //Bakelite - gMC->Gsvolu("CG4A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer - -// chamber type A - tpar[0] = -1.; - tpar[1] = -1.; - - const Float_t X_MC4A=X_MC3A; - const Float_t Y_MC4A=0.; - const Float_t Z_MC4A=0.; - - tpar[2] = 0.1; - gMC->Gsposp("CG4A", 1, "CB4A", 0., 0., 0., 0, "ONLY",tpar,3); - tpar[2] = 0.3; - gMC->Gsposp("CB4A", 1, "CC4A", 0., 0., 0., 0, "ONLY",tpar,3); - tpar[2] = 0.4; - tpar[0] = (X_MC3_MAX-X_MC3_MED)/2.; - tpar[1] = Y_MC3_MIN; - gMC->Gsposp("CC4A", 1, "CM22",X_MC4A,Y_MC4A,Z_MC4A, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 2, "CM22",-X_MC4A,Y_MC4A,Z_MC4A, 0, "ONLY", tpar, 3); - -// chamber type B - tpar[0] = (X_MC3_MAX-X_MC3_MIN)/2.; - tpar[1] = (Y_MC3_MAX-Y_MC3_MIN)/2.; - - const Float_t X_MC4B=X_MC3B; - const Float_t Y_MC4B=2.*Y_MC3_MIN*Z_3S4-Y_MC3_MIN*1.5+Y_MC3_MAX*0.5; - const Float_t Z_MC4B=0.; - - gMC->Gsposp("CC4A", 3, "CM22",X_MC4B,Y_MC4B,Z_MC4B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 4, "CM22",-X_MC4B,Y_MC4B,Z_MC4B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 5, "CM22",X_MC4B,-Y_MC4B,Z_MC4B, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 6, "CM22",-X_MC4B,-Y_MC4B,Z_MC4B, 0, "ONLY", tpar, 3); - -// chamber type C - tpar[0] = X_MC3_MAX/2; - tpar[1] = Y_MC3_MAX/2; - - const Float_t X_MC4C=X_MC3C; - const Float_t Y_MC4C=2.*Y_MC3_MIN*Z_3S4-Y_MC3_MIN*2.+Y_MC3_MAX*1.5; - const Float_t Z_MC4C=0.; - - gMC->Gsposp("CC4A", 7, "CM22",X_MC4C,Y_MC4C,Z_MC4C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 8, "CM22",-X_MC4C,Y_MC4C,Z_MC4C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 9, "CM22",X_MC4C,-Y_MC4C,Z_MC4C, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 10, "CM22",-X_MC4C,-Y_MC4C,Z_MC4C, 0, "ONLY", tpar, 3); - -// chamber type D - tpar[0] = X_MC3_MAX/2.; - tpar[1] = Y_MC3_MIN; - - const Float_t X_MC4D=X_MC3D; - const Float_t Z_MC4D=0.; - - Float_t Y_MC4D=4.*Y_MC3_MIN*Z_3S4; - gMC->Gsposp("CC4A", 11, "CM22",X_MC4D,Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 12, "CM22",X_MC4D,-Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 13, "CM22",-X_MC4D,Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 14, "CM22",-X_MC4D,-Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - - Y_MC4D=6.*Y_MC3_MIN*Z_3S4; - gMC->Gsposp("CC4A", 15, "CM22",X_MC4D,Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 16, "CM22",X_MC4D,-Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 17, "CM22",-X_MC4D,Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 18, "CM22",-X_MC4D,-Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - - Y_MC4D=8.*Y_MC3_MIN*Z_3S4; - gMC->Gsposp("CC4A", 19, "CM22",X_MC4D,Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 20, "CM22",X_MC4D,-Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 21, "CM22",-X_MC4D,Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - gMC->Gsposp("CC4A", 22, "CM22",-X_MC4D,-Y_MC4D,Z_MC4D, 0, "ONLY", tpar, 3); - - gMC->Gspos("CM22", 1, "ALIC", 0., 0., zpos4, 0, "ONLY"); - } - //___________________________________________ void AliMUONv0::CreateMaterials() { - // *** DEFINITION OF AVAILABLE MUON MATERIALS *** - // - // Ar-CO2 gas - Float_t ag1[3] = { 39.95,12.01,16. }; - Float_t zg1[3] = { 18.,6.,8. }; - Float_t wg1[3] = { .8,.0667,.13333 }; - Float_t dg1 = .001821; - // - // Ar-buthane-freon gas -- trigger chambers - Float_t atr1[4] = { 39.95,12.01,1.01,19. }; - Float_t ztr1[4] = { 18.,6.,1.,9. }; - Float_t wtr1[4] = { .56,.1262857,.2857143,.028 }; - Float_t dtr1 = .002599; - // - // Ar-CO2 gas - Float_t agas[3] = { 39.95,12.01,16. }; - Float_t zgas[3] = { 18.,6.,8. }; - Float_t wgas[3] = { .74,.086684,.173316 }; - Float_t dgas = .0018327; - // - // Ar-Isobutane gas (80%+20%) -- tracking - Float_t ag[3] = { 39.95,12.01,1.01 }; - Float_t zg[3] = { 18.,6.,1. }; - Float_t wg[3] = { .8,.057,.143 }; - Float_t dg = .0019596; - // - // Ar-Isobutane-Forane-SF6 gas (49%+7%+40%+4%) -- trigger - Float_t atrig[5] = { 39.95,12.01,1.01,19.,32.066 }; - Float_t ztrig[5] = { 18.,6.,1.,9.,16. }; - Float_t wtrig[5] = { .49,1.08,1.5,1.84,0.04 }; - Float_t dtrig = .0031463; - // - // bakelite - - Float_t abak[3] = {12.01 , 1.01 , 16.}; - Float_t zbak[3] = {6. , 1. , 8.}; - Float_t wbak[3] = {6. , 6. , 1.}; - Float_t dbak = 1.4; - - Float_t epsil, stmin, deemax, tmaxfd, stemax; - - Int_t ISXFLD = gAlice->Field()->Integ(); - Float_t SXMGMX = gAlice->Field()->Max(); - // - // --- Define the various materials for GEANT --- - AliMaterial(9, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2); - AliMaterial(10, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2); +// Creates materials for coarse geometry AliMaterial(15, "AIR$ ", 14.61, 7.3, .001205, 30423.24, 67500); - AliMixture(19, "Bakelite$", abak, zbak, dbak, -3, wbak); - AliMixture(20, "ArC4H10 GAS$", ag, zg, dg, 3, wg); - AliMixture(21, "TRIG GAS$", atrig, ztrig, dtrig, -5, wtrig); - AliMixture(22, "ArCO2 80%$", ag1, zg1, dg1, 3, wg1); - AliMixture(23, "Ar-freon $", atr1, ztr1, dtr1, 4, wtr1); - AliMixture(24, "ArCO2 GAS$", agas, zgas, dgas, 3, wgas); + AliMaterial(9, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2); - epsil = .001; // Tracking precision, - stemax = -1.; // Maximum displacement for multiple scat - tmaxfd = -20.; // Maximum angle due to field deflection - deemax = -.3; // Maximum fractional energy loss, DLS - stmin = -.8; - // - // Air - AliMedium(1, "AIR_CH_US ", 15, 1, ISXFLD, SXMGMX, tmaxfd, stemax, deemax, epsil, stmin); - // - // Aluminum + Float_t epsil = .001; // Tracking precision, + Float_t stemax = -1.; // Maximum displacement for multiple scat + Float_t tmaxfd = -20.; // Maximum angle due to field deflection + Float_t deemax = -.3; // Maximum fractional energy loss, DLS + Float_t stmin = -.8; + Int_t isxfld = gAlice->Field()->Integ(); + Float_t sxmgmx = gAlice->Field()->Max(); - AliMedium(4, "ALU_CH_US ", 9, 0, ISXFLD, SXMGMX, tmaxfd, fMaxStepAlu, - fMaxDestepAlu, epsil, stmin); - AliMedium(5, "ALU_CH_US ", 10, 0, ISXFLD, SXMGMX, tmaxfd, fMaxStepAlu, - fMaxDestepAlu, epsil, stmin); // - // Ar-isoC4H10 gas - - AliMedium(6, "AR_CH_US ", 20, 1, ISXFLD, SXMGMX, tmaxfd, fMaxStepGas, - fMaxDestepGas, epsil, stmin); -// - // Ar-Isobuthane-Forane-SF6 gas - - AliMedium(7, "GAS_CH_TRIGGER ", 21, 1, ISXFLD, SXMGMX, tmaxfd, stemax, deemax, epsil, stmin); - - AliMedium(8, "BAKE_CH_TRIGGER ", 19, 0, ISXFLD, SXMGMX, tmaxfd, fMaxStepAlu, - fMaxDestepAlu, epsil, stmin); - - AliMedium(9, "ARG_CO2 ", 22, 1, ISXFLD, SXMGMX, tmaxfd, fMaxStepGas, + // Air + AliMedium(1, "AIR_CH_US ", 15, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin); + AliMedium(4, "ALU_CH_US ", 9, 0, isxfld, sxmgmx, tmaxfd, fMaxStepAlu, fMaxDestepAlu, epsil, stmin); } -//___________________________________________ - void AliMUONv0::Init() { - printf("\n\n\n Start Init for version 0 - CPC chamber type\n\n\n"); - // // Initialize Tracking Chambers // - for (Int_t i=0; iInit(); + printf("\n\n\n Start Init for version 0 - CPC chamber type\n\n\n"); + for (Int_t i=0; iInit(); } - - // - // Set the chamber (sensitive region) GEANT identifier - AliMC* gMC = AliMC::GetMC(); - ((AliMUONchamber*)(*fChambers)[0])->SetGid(gMC->VolId("C01G")); - ((AliMUONchamber*)(*fChambers)[1])->SetGid(gMC->VolId("C02G")); - ((AliMUONchamber*)(*fChambers)[2])->SetGid(gMC->VolId("C03G")); - ((AliMUONchamber*)(*fChambers)[3])->SetGid(gMC->VolId("C04G")); - ((AliMUONchamber*)(*fChambers)[4])->SetGid(gMC->VolId("C05G")); - ((AliMUONchamber*)(*fChambers)[5])->SetGid(gMC->VolId("C06G")); - ((AliMUONchamber*)(*fChambers)[6])->SetGid(gMC->VolId("C07G")); - ((AliMUONchamber*)(*fChambers)[7])->SetGid(gMC->VolId("C08G")); - ((AliMUONchamber*)(*fChambers)[8])->SetGid(gMC->VolId("C09G")); - ((AliMUONchamber*)(*fChambers)[9])->SetGid(gMC->VolId("C10G")); - ((AliMUONchamber*)(*fChambers)[10])->SetGid(gMC->VolId("CG1A")); - ((AliMUONchamber*)(*fChambers)[11])->SetGid(gMC->VolId("CG2A")); - ((AliMUONchamber*)(*fChambers)[12])->SetGid(gMC->VolId("CG3A")); - ((AliMUONchamber*)(*fChambers)[13])->SetGid(gMC->VolId("CG4A")); - - printf("\n\n\n Finished Init for version 0 - CPC chamber type\n\n\n"); } -//___________________________________________ void AliMUONv0::StepManager() { +// +// Step manager for hit density simulations Int_t copy, id; static Int_t idvol; static Int_t vol[2]; @@ -1522,30 +476,19 @@ void AliMUONv0::StepManager() TLorentzVector pos; TLorentzVector mom; Float_t theta,phi; - Float_t destep, step; - - static Float_t eloss, eloss2, xhit, yhit, tlength; - const Float_t big=1.e10; // modifs perso - static Float_t hits[14]; + static Float_t hits[15]; TClonesArray &lhits = *fHits; - - // - // Set maximum step size for gas - // numed=gMC->GetMedium(); - // - // Only charged tracks - if( !(gMC->TrackCharge()) ) return; // // Only gas gap inside chamber // Tag chambers and record hits when track enters idvol=-1; id=gMC->CurrentVolID(copy); - for (Int_t i=1; i<=NCH; i++) { - if(id==((AliMUONchamber*)(*fChambers)[i-1])->GetGid()){ + for (Int_t i=1; i<=kNCH; i++) { + if(id==((AliMUONChamber*)(*fChambers)[i-1])->GetGid()){ vol[0]=i; idvol=i-1; } @@ -1557,110 +500,42 @@ void AliMUONv0::StepManager() gMC->TrackMomentum(mom); ipart = gMC->TrackPid(); - //Int_t ipart1 = gMC->IdFromPDG(ipart); - //printf("ich, ipart %d %d \n",vol[0],ipart1); - - // - // momentum loss and steplength in last step - destep = gMC->Edep(); - step = gMC->TrackStep(); - // // record hits when track enters ... +// if( !(gMC->TrackCharge()) ) return; if( gMC->IsTrackEntering()) { - gMC->SetMaxStep(fMaxStepGas); Double_t tc = mom[0]*mom[0]+mom[1]*mom[1]; Double_t rt = TMath::Sqrt(tc); - Double_t pmom = TMath::Sqrt(tc+mom[2]*mom[2]); - Double_t tx=mom[0]/pmom; - Double_t ty=mom[1]/pmom; - Double_t tz=mom[2]/pmom; - Double_t s=((AliMUONchamber*)(*fChambers)[idvol]) - ->GetResponseModel() - ->Pitch()/tz; theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg; phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg; - hits[0] = Float_t(ipart); // Geant3 particle type - hits[1] = pos[0]+s*tx; // X-position for hit - hits[2] = pos[1]+s*ty; // Y-position for hit - hits[3] = pos[2]+s*tz; // Z-position for hit - hits[4] = theta; // theta angle of incidence - hits[5] = phi; // phi angle of incidence - hits[8] = (Float_t) fNclusters; // first padhit - hits[9] = -1; // last pad hit - - // modifs perso - hits[10] = mom[3]; // hit momentum P - hits[11] = mom[0]; // Px/P - hits[12] = mom[1]; // Py/P - hits[13] = mom[2]; // Pz/P - // fin modifs perso - - // phi angle of incidence - tlength = 0; - eloss = 0; - eloss2 = 0; - xhit = pos[0]; - yhit = pos[1]; - // Only if not trigger chamber - if(idvol<10) { - // - // Initialize hit position (cursor) in the segmentation model - ((AliMUONchamber*) (*fChambers)[idvol]) - ->SigGenInit(pos[0], pos[1], pos[2]); - } else { - //geant3->Gpcxyz(); - //printf("In the Trigger Chamber #%d\n",idvol-9); - } - } - eloss2+=destep; - - // - // Calculate the charge induced on a pad (disintegration) in case - // - // Mip left chamber ... - if( gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()){ - gMC->SetMaxStep(big); - eloss += destep; - tlength += step; + hits[0] = Float_t(ipart); // Geant3 particle type + hits[1] = pos[0]; // X-position for hit + hits[2] = pos[1]; // Y-position for hit + hits[3] = pos[2]; // Z-position for hit + hits[4] = theta; // theta angle of incidence + hits[5] = phi; // phi angle of incidence + hits[8] = -1; // first padhit + hits[9] = -1; // last pad hit + + // modifs personel + hits[10] = mom[3]; // hit Energy + hits[11] = mom[0]; // Px + hits[12] = mom[1]; // Py + hits[13] = mom[2]; // Pz + hits[14] = gMC->TrackTime(); - // Only if not trigger chamber - if(idvol<10) { - if (eloss > 0) - MakePadHits(0.5*(xhit+pos[0]),0.5*(yhit+pos[1]),eloss,idvol); - } - - hits[6]=tlength; - hits[7]=eloss2; - if (fNclusters > (Int_t)hits[8]) { - hits[8]= hits[8]+1; - hits[9]= (Float_t) fNclusters; - } - + // fin modifs perso new(lhits[fNhits++]) - AliMUONhit(fIshunt,gAlice->CurrentTrack(),vol,hits); - eloss = 0; - // - // Check additional signal generation conditions - // defined by the segmentation - // model (boundary crossing conditions) - } else if - (((AliMUONchamber*) (*fChambers)[idvol]) - ->SigGenCond(pos[0], pos[1], pos[2])) - { - ((AliMUONchamber*) (*fChambers)[idvol]) - ->SigGenInit(pos[0], pos[1], pos[2]); -// printf("\n-> MakePadHits, reason special %d",ipart); - if (eloss > 0) - MakePadHits(0.5*(xhit+pos[0]),0.5*(yhit+pos[1]),eloss,idvol); - xhit = pos[0]; - yhit = pos[1]; - eloss = destep; - tlength += step ; - // - // nothing special happened, add up energy loss - } else { - eloss += destep; - tlength += step ; + AliMUONHit(fIshunt,gAlice->CurrentTrack(),vol,hits); + } } + + + + + + + + + diff --git a/MUON/AliMUONv0.h b/MUON/AliMUONv0.h index c3b6bc80b9e..60de2f7ba1d 100644 --- a/MUON/AliMUONv0.h +++ b/MUON/AliMUONv0.h @@ -1,5 +1,6 @@ -#ifndef MUONV0_H -#define MUONV0_H +#ifndef ALIMUONV0_H +#define ALIMUONV0_H + /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * See cxx source for full Copyright notice */ @@ -10,7 +11,6 @@ ///////////////////////////////////////////////////////// #include "AliMUON.h" -#include "AliMUONClusterFinder.h" class AliMUONv0 : public AliMUON { public: AliMUONv0(); @@ -21,7 +21,6 @@ public: virtual void Init(); virtual Int_t IsVersion() const {return 0;} virtual void StepManager(); - virtual void Trigger(Float_t (*)[4], Float_t (*)[4], Int_t& iflag); private: ClassDef(AliMUONv0,1) //Hits manager for set:MUON version 0 }; diff --git a/MUON/AliMUONv1.cxx b/MUON/AliMUONv1.cxx new file mode 100644 index 00000000000..b37974bf808 --- /dev/null +++ b/MUON/AliMUONv1.cxx @@ -0,0 +1,1657 @@ +/************************************************************************** + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* +$Log$ +Revision 1.1.2.14 2000/06/14 14:37:25 morsch +Initialization of TriggerCircuit added (PC) + +Revision 1.1.2.13 2000/06/09 21:55:47 morsch +Most coding rule violations corrected. + +Revision 1.1.2.12 2000/05/05 11:34:29 morsch +Log inside comments. + +Revision 1.1.2.11 2000/05/05 10:06:48 morsch +Coding Rule violations regarding trigger section corrected (CP) +Log messages included. +*/ + +///////////////////////////////////////////////////////// +// Manager and hits classes for set:MUON version 0 // +///////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +#include "AliMUONv1.h" +#include "AliRun.h" +#include "AliMC.h" +#include "AliCallf77.h" +#include "AliConst.h" +#include "AliMUONChamber.h" +#include "AliMUONHit.h" +#include "AliMUONPadHit.h" + +ClassImp(AliMUONv1) + +//___________________________________________ +AliMUONv1::AliMUONv1() : AliMUON() +{ +// Constructor + fChambers = 0; +} + +//___________________________________________ +AliMUONv1::AliMUONv1(const char *name, const char *title) + : AliMUON(name,title) +{ +// Constructor +} + +//___________________________________________ +void AliMUONv1::CreateGeometry() +{ +// +// Note: all chambers have the same structure, which could be +// easily parameterised. This was intentionally not done in order +// to give a starting point for the implementation of the actual +// design of each station. + Int_t *idtmed = fIdtmed->GetArray()-1099; + +// Distance between Stations +// + Float_t bpar[3]; + Float_t tpar[3]; + Float_t pgpar[10]; + Float_t zpos1, zpos2, zfpos; + Float_t dframep=.001; // Value for station 3 should be 6 ... + Float_t dframep1=.001; +// Bool_t frames=kTRUE; + Bool_t frames=kFALSE; + + Float_t dframez=0.9; + Float_t dr; + Float_t dstation; + +// +// Rotation matrices in the x-y plane + Int_t idrotm[1199]; +// phi= 0 deg + AliMatrix(idrotm[1100], 90., 0., 90., 90., 0., 0.); +// phi= 90 deg + AliMatrix(idrotm[1101], 90., 90., 90., 180., 0., 0.); +// phi= 180 deg + AliMatrix(idrotm[1102], 90., 180., 90., 270., 0., 0.); +// phi= 270 deg + AliMatrix(idrotm[1103], 90., 270., 90., 0., 0., 0.); +// + Float_t phi=2*TMath::Pi()/12/2; + +// +// pointer to the current chamber +// pointer to the current chamber + Int_t idAlu1=idtmed[1103]; + Int_t idAlu2=idtmed[1104]; +// Int_t idAlu1=idtmed[1100]; +// Int_t idAlu2=idtmed[1100]; + Int_t idAir=idtmed[1100]; + Int_t idGas=idtmed[1105]; + + + AliMUONChamber *iChamber, *iChamber1, *iChamber2; +//******************************************************************** +// Station 1 ** +//******************************************************************** +// CONCENTRIC + // indices 1 and 2 for first and second chambers in the station + // iChamber (first chamber) kept for other quanties than Z, + // assumed to be the same in both chambers + iChamber1 = iChamber = (AliMUONChamber*) (*fChambers)[0]; + iChamber2 =(AliMUONChamber*) (*fChambers)[1]; + zpos1=iChamber1->Z(); + zpos2=iChamber2->Z(); + dstation = zpos2 - zpos1; + zfpos=-(iChamber->DGas()+dframez+iChamber->DAlu())/2; + +// +// Mother volume + tpar[0] = iChamber->RInner()-dframep1; + tpar[1] = (iChamber->ROuter()+dframep1)/TMath::Cos(phi); + tpar[2] = dstation/4; + + gMC->Gsvolu("C01M", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("C02M", "TUBE", idAir, tpar, 3); + gMC->Gspos("C01M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); + gMC->Gspos("C02M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); +// Aluminium frames +// Outer frames + pgpar[0] = 360/12/2; + pgpar[1] = 360.; + pgpar[2] = 12.; + pgpar[3] = 2; + pgpar[4] = -dframez/2; + pgpar[5] = iChamber->ROuter(); + pgpar[6] = pgpar[5]+dframep1; + pgpar[7] = +dframez/2; + pgpar[8] = pgpar[5]; + pgpar[9] = pgpar[6]; + gMC->Gsvolu("C01O", "PGON", idAlu1, pgpar, 10); + gMC->Gsvolu("C02O", "PGON", idAlu1, pgpar, 10); + gMC->Gspos("C01O",1,"C01M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C01O",2,"C01M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C02O",1,"C02M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C02O",2,"C02M", 0.,0.,+zfpos, 0,"ONLY"); +// +// Inner frame + tpar[0]= iChamber->RInner()-dframep1; + tpar[1]= iChamber->RInner(); + tpar[2]= dframez/2; + gMC->Gsvolu("C01I", "TUBE", idAlu1, tpar, 3); + gMC->Gsvolu("C02I", "TUBE", idAlu1, tpar, 3); + + gMC->Gspos("C01I",1,"C01M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C01I",2,"C01M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C02I",1,"C02M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C02I",2,"C02M", 0.,0.,+zfpos, 0,"ONLY"); +// +// Frame Crosses + if (frames) { + + bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; + bpar[1] = dframep1/2; + bpar[2] = dframez/2; + gMC->Gsvolu("C01B", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C02B", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C01B",1,"C01M", +iChamber->RInner()+bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C01B",2,"C01M", -iChamber->RInner()-bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C01B",3,"C01M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C01B",4,"C01M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C01B",5,"C01M", +iChamber->RInner()+bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C01B",6,"C01M", -iChamber->RInner()-bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C01B",7,"C01M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C01B",8,"C01M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + + gMC->Gspos("C02B",1,"C02M", +iChamber->RInner()+bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C02B",2,"C02M", -iChamber->RInner()-bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C02B",3,"C02M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C02B",4,"C02M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C02B",5,"C02M", +iChamber->RInner()+bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C02B",6,"C02M", -iChamber->RInner()-bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C02B",7,"C02M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C02B",8,"C02M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + } +// +// Chamber Material represented by Alu sheet + tpar[0]= iChamber->RInner(); + tpar[1]= iChamber->ROuter(); + tpar[2] = (iChamber->DGas()+iChamber->DAlu())/2; + gMC->Gsvolu("C01A", "TUBE", idAlu2, tpar, 3); + gMC->Gsvolu("C02A", "TUBE",idAlu2, tpar, 3); + gMC->Gspos("C01A", 1, "C01M", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C02A", 1, "C02M", 0., 0., 0., 0, "ONLY"); +// +// Sensitive volumes + // tpar[2] = iChamber->DGas(); + tpar[2] = iChamber->DGas()/2; + gMC->Gsvolu("C01G", "TUBE", idtmed[1108], tpar, 3); + gMC->Gsvolu("C02G", "TUBE", idtmed[1108], tpar, 3); + gMC->Gspos("C01G", 1, "C01A", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C02G", 1, "C02A", 0., 0., 0., 0, "ONLY"); +// +// Frame Crosses to be placed inside gas + if (frames) { + + dr = (iChamber->ROuter() - iChamber->RInner()); + bpar[0] = TMath::Sqrt(dr*dr-dframep1*dframep1/4)/2; + bpar[1] = dframep1/2; + bpar[2] = iChamber->DGas()/2; + gMC->Gsvolu("C01F", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C02F", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C01F",1,"C01G", +iChamber->RInner()+bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C01F",2,"C01G", -iChamber->RInner()-bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C01F",3,"C01G", 0, +iChamber->RInner()+bpar[0] , 0, + idrotm[1101],"ONLY"); + gMC->Gspos("C01F",4,"C01G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); + + gMC->Gspos("C02F",1,"C02G", +iChamber->RInner()+bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C02F",2,"C02G", -iChamber->RInner()-bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C02F",3,"C02G", 0, +iChamber->RInner()+bpar[0] , 0, + idrotm[1101],"ONLY"); + gMC->Gspos("C02F",4,"C02G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); + } + +// +// +//******************************************************************** +// Station 2 ** +//******************************************************************** + // indices 1 and 2 for first and second chambers in the station + // iChamber (first chamber) kept for other quanties than Z, + // assumed to be the same in both chambers + iChamber1 = iChamber = (AliMUONChamber*) (*fChambers)[2]; + iChamber2 =(AliMUONChamber*) (*fChambers)[3]; + zpos1=iChamber1->Z(); + zpos2=iChamber2->Z(); + dstation = zpos2 - zpos1; + zfpos=-(iChamber->DGas()+dframez+iChamber->DAlu())/2; + +// +// Mother volume + tpar[0] = iChamber->RInner()-dframep; + tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); + tpar[2] = dstation/4; + + gMC->Gsvolu("C03M", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("C04M", "TUBE", idAir, tpar, 3); + gMC->Gspos("C03M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); + gMC->Gspos("C04M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); +// Aluminium frames +// Outer frames + pgpar[0] = 360/12/2; + pgpar[1] = 360.; + pgpar[2] = 12.; + pgpar[3] = 2; + pgpar[4] = -dframez/2; + pgpar[5] = iChamber->ROuter(); + pgpar[6] = pgpar[5]+dframep; + pgpar[7] = +dframez/2; + pgpar[8] = pgpar[5]; + pgpar[9] = pgpar[6]; + gMC->Gsvolu("C03O", "PGON", idAlu1, pgpar, 10); + gMC->Gsvolu("C04O", "PGON", idAlu1, pgpar, 10); + gMC->Gspos("C03O",1,"C03M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C03O",2,"C03M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C04O",1,"C04M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C04O",2,"C04M", 0.,0.,+zfpos, 0,"ONLY"); +// +// Inner frame + tpar[0]= iChamber->RInner()-dframep; + tpar[1]= iChamber->RInner(); + tpar[2]= dframez/2; + gMC->Gsvolu("C03I", "TUBE", idAlu1, tpar, 3); + gMC->Gsvolu("C04I", "TUBE", idAlu1, tpar, 3); + + gMC->Gspos("C03I",1,"C03M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C03I",2,"C03M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C04I",1,"C04M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C04I",2,"C04M", 0.,0.,+zfpos, 0,"ONLY"); +// +// Frame Crosses + if (frames) { + + bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; + bpar[1] = dframep/2; + bpar[2] = dframez/2; + gMC->Gsvolu("C03B", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C04B", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C03B",1,"C03M", +iChamber->RInner()+bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C03B",2,"C03M", -iChamber->RInner()-bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C03B",3,"C03M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C03B",4,"C03M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C03B",5,"C03M", +iChamber->RInner()+bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C03B",6,"C03M", -iChamber->RInner()-bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C03B",7,"C03M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C03B",8,"C03M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + + gMC->Gspos("C04B",1,"C04M", +iChamber->RInner()+bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C04B",2,"C04M", -iChamber->RInner()-bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C04B",3,"C04M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C04B",4,"C04M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C04B",5,"C04M", +iChamber->RInner()+bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C04B",6,"C04M", -iChamber->RInner()-bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C04B",7,"C04M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C04B",8,"C04M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + } +// +// Chamber Material represented by Alu sheet + tpar[0]= iChamber->RInner(); + tpar[1]= iChamber->ROuter(); + tpar[2] = (iChamber->DGas()+iChamber->DAlu())/2; + gMC->Gsvolu("C03A", "TUBE", idAlu2, tpar, 3); + gMC->Gsvolu("C04A", "TUBE", idAlu2, tpar, 3); + gMC->Gspos("C03A", 1, "C03M", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C04A", 1, "C04M", 0., 0., 0., 0, "ONLY"); +// +// Sensitive volumes + // tpar[2] = iChamber->DGas(); + tpar[2] = iChamber->DGas()/2; + gMC->Gsvolu("C03G", "TUBE", idGas, tpar, 3); + gMC->Gsvolu("C04G", "TUBE", idGas, tpar, 3); + gMC->Gspos("C03G", 1, "C03A", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C04G", 1, "C04A", 0., 0., 0., 0, "ONLY"); + + if (frames) { +// +// Frame Crosses to be placed inside gas + dr = (iChamber->ROuter() - iChamber->RInner()); + bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; + bpar[1] = dframep/2; + bpar[2] = iChamber->DGas()/2; + gMC->Gsvolu("C03F", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C04F", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C03F",1,"C03G", +iChamber->RInner()+bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C03F",2,"C03G", -iChamber->RInner()-bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C03F",3,"C03G", 0, +iChamber->RInner()+bpar[0] , 0, + idrotm[1101],"ONLY"); + gMC->Gspos("C03F",4,"C03G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); + + gMC->Gspos("C04F",1,"C04G", +iChamber->RInner()+bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C04F",2,"C04G", -iChamber->RInner()-bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C04F",3,"C04G", 0, +iChamber->RInner()+bpar[0] , 0, + idrotm[1101],"ONLY"); + gMC->Gspos("C04F",4,"C04G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); + } + +//******************************************************************** +// Station 3 ** +//******************************************************************** + // indices 1 and 2 for first and second chambers in the station + // iChamber (first chamber) kept for other quanties than Z, + // assumed to be the same in both chambers + iChamber1 = iChamber = (AliMUONChamber*) (*fChambers)[4]; + iChamber2 =(AliMUONChamber*) (*fChambers)[5]; + zpos1=iChamber1->Z(); + zpos2=iChamber2->Z(); + dstation = zpos2 - zpos1; + + zfpos=-(iChamber->DGas()+dframez+iChamber->DAlu())/2; +// +// Mother volume + tpar[0] = iChamber->RInner()-dframep; + tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); + tpar[2] = dstation/4; + gMC->Gsvolu("C05M", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("C06M", "TUBE", idAir, tpar, 3); + gMC->Gspos("C05M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); + gMC->Gspos("C06M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); +// Aluminium frames +// Outer frames + pgpar[0] = 360/12/2; + pgpar[1] = 360.; + pgpar[2] = 12.; + pgpar[3] = 2; + pgpar[4] = -dframez/2; + pgpar[5] = iChamber->ROuter(); + pgpar[6] = pgpar[5]+dframep; + pgpar[7] = +dframez/2; + pgpar[8] = pgpar[5]; + pgpar[9] = pgpar[6]; + gMC->Gsvolu("C05O", "PGON", idAlu1, pgpar, 10); + gMC->Gsvolu("C06O", "PGON", idAlu1, pgpar, 10); + gMC->Gspos("C05O",1,"C05M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C05O",2,"C05M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C06O",1,"C06M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C06O",2,"C06M", 0.,0.,+zfpos, 0,"ONLY"); +// +// Inner frame + tpar[0]= iChamber->RInner()-dframep; + tpar[1]= iChamber->RInner(); + tpar[2]= dframez/2; + gMC->Gsvolu("C05I", "TUBE", idAlu1, tpar, 3); + gMC->Gsvolu("C06I", "TUBE", idAlu1, tpar, 3); + + gMC->Gspos("C05I",1,"C05M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C05I",2,"C05M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C06I",1,"C06M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C06I",2,"C06M", 0.,0.,+zfpos, 0,"ONLY"); +// +// Frame Crosses + if (frames) { + bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; + bpar[1] = dframep/2; + bpar[2] = dframez/2; + gMC->Gsvolu("C05B", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C06B", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C05B",1,"C05M", +iChamber->RInner()+bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C05B",2,"C05M", -iChamber->RInner()-bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C05B",3,"C05M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C05B",4,"C05M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C05B",5,"C05M", +iChamber->RInner()+bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C05B",6,"C05M", -iChamber->RInner()-bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C05B",7,"C05M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C05B",8,"C05M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + + gMC->Gspos("C06B",1,"C06M", +iChamber->RInner()+bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C06B",2,"C06M", -iChamber->RInner()-bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C06B",3,"C06M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C06B",4,"C06M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C06B",5,"C06M", +iChamber->RInner()+bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C06B",6,"C06M", -iChamber->RInner()-bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C06B",7,"C06M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C06B",8,"C06M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + } + + +// +// Chamber Material represented by Alu sheet + tpar[0]= iChamber->RInner(); + tpar[1]= iChamber->ROuter(); + tpar[2] = (iChamber->DGas()+iChamber->DAlu())/2; + gMC->Gsvolu("C05A", "TUBE", idAlu2, tpar, 3); + gMC->Gsvolu("C06A", "TUBE", idAlu2, tpar, 3); + gMC->Gspos("C05A", 1, "C05M", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C06A", 1, "C06M", 0., 0., 0., 0, "ONLY"); +// +// Sensitive volumes + tpar[2] = iChamber->DGas()/2.; + gMC->Gsvolu("C05G", "TUBE", idGas, tpar, 3); + gMC->Gsvolu("C06G", "TUBE", idGas, tpar, 3); + gMC->Gspos("C05G", 1, "C05A", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C06G", 1, "C06A", 0., 0., 0., 0, "ONLY"); +// +// Frame Crosses to be placed inside gas + if (frames) { + dr = (iChamber->ROuter() - iChamber->RInner()); + bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; + bpar[1] = dframep/2; + bpar[2] = iChamber->DGas()/2; + gMC->Gsvolu("C05F", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C06F", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C05F",1,"C05G", +iChamber->RInner()+bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C05F",2,"C05G", -iChamber->RInner()-bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C05F",3,"C05G", 0, +iChamber->RInner()+bpar[0] , 0, + idrotm[1101],"ONLY"); + gMC->Gspos("C05F",4,"C05G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); + + gMC->Gspos("C06F",1,"C06G", +iChamber->RInner()+bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C06F",2,"C06G", -iChamber->RInner()-bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C06F",3,"C06G", 0, +iChamber->RInner()+bpar[0] , 0, + idrotm[1101],"ONLY"); + gMC->Gspos("C06F",4,"C06G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); +} + +//******************************************************************** +// Station 4 ** +//******************************************************************** + // indices 1 and 2 for first and second chambers in the station + // iChamber (first chamber) kept for other quanties than Z, + // assumed to be the same in both chambers + iChamber1 = iChamber = (AliMUONChamber*) (*fChambers)[6]; + iChamber2 =(AliMUONChamber*) (*fChambers)[7]; + zpos1=iChamber1->Z(); + zpos2=iChamber2->Z(); + dstation = zpos2 - zpos1; + zfpos=-(iChamber->DGas()+dframez+iChamber->DAlu())/2; + +// +// Mother volume + tpar[0] = iChamber->RInner()-dframep; + tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); + tpar[2] = dstation/4; + + gMC->Gsvolu("C07M", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("C08M", "TUBE", idAir, tpar, 3); + gMC->Gspos("C07M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); + gMC->Gspos("C08M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); +// Aluminium frames +// Outer frames + pgpar[0] = 360/12/2; + pgpar[1] = 360.; + pgpar[2] = 12.; + pgpar[3] = 2; + pgpar[4] = -dframez/2; + pgpar[5] = iChamber->ROuter(); + pgpar[6] = pgpar[5]+dframep; + pgpar[7] = +dframez/2; + pgpar[8] = pgpar[5]; + pgpar[9] = pgpar[6]; + gMC->Gsvolu("C07O", "PGON", idAlu1, pgpar, 10); + gMC->Gsvolu("C08O", "PGON", idAlu1, pgpar, 10); + gMC->Gspos("C07O",1,"C07M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C07O",2,"C07M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C08O",1,"C08M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C08O",2,"C08M", 0.,0.,+zfpos, 0,"ONLY"); +// +// Inner frame + tpar[0]= iChamber->RInner()-dframep; + tpar[1]= iChamber->RInner(); + tpar[2]= dframez/2; + gMC->Gsvolu("C07I", "TUBE", idAlu1, tpar, 3); + gMC->Gsvolu("C08I", "TUBE", idAlu1, tpar, 3); + + gMC->Gspos("C07I",1,"C07M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C07I",2,"C07M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C08I",1,"C08M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C08I",2,"C08M", 0.,0.,+zfpos, 0,"ONLY"); +// +// Frame Crosses + if (frames) { + bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; + bpar[1] = dframep/2; + bpar[2] = dframez/2; + gMC->Gsvolu("C07B", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C08B", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C07B",1,"C07M", +iChamber->RInner()+bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C07B",2,"C07M", -iChamber->RInner()-bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C07B",3,"C07M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C07B",4,"C07M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C07B",5,"C07M", +iChamber->RInner()+bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C07B",6,"C07M", -iChamber->RInner()-bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C07B",7,"C07M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C07B",8,"C07M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + + gMC->Gspos("C08B",1,"C08M", +iChamber->RInner()+bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C08B",2,"C08M", -iChamber->RInner()-bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C08B",3,"C08M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C08B",4,"C08M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C08B",5,"C08M", +iChamber->RInner()+bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C08B",6,"C08M", -iChamber->RInner()-bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C08B",7,"C08M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C08B",8,"C08M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + } + + +// +// Chamber Material represented by Alu sheet + tpar[0]= iChamber->RInner(); + tpar[1]= iChamber->ROuter(); + tpar[2] = (iChamber->DGas()+iChamber->DAlu())/2; + gMC->Gsvolu("C07A", "TUBE", idAlu2, tpar, 3); + gMC->Gsvolu("C08A", "TUBE", idAlu2, tpar, 3); + gMC->Gspos("C07A", 1, "C07M", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C08A", 1, "C08M", 0., 0., 0., 0, "ONLY"); +// +// Sensitive volumes + // tpar[2] = iChamber->DGas(); + tpar[2] = iChamber->DGas()/2; + gMC->Gsvolu("C07G", "TUBE", idGas, tpar, 3); + gMC->Gsvolu("C08G", "TUBE", idGas, tpar, 3); + gMC->Gspos("C07G", 1, "C07A", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C08G", 1, "C08A", 0., 0., 0., 0, "ONLY"); +// +// Frame Crosses to be placed inside gas + if (frames) { + dr = (iChamber->ROuter() - iChamber->RInner()); + bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; + bpar[1] = dframep/2; + bpar[2] = iChamber->DGas()/2; + gMC->Gsvolu("C07F", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C08F", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C07F",1,"C07G", +iChamber->RInner()+bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C07F",2,"C07G", -iChamber->RInner()-bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C07F",3,"C07G", 0, +iChamber->RInner()+bpar[0] , 0, + idrotm[1101],"ONLY"); + gMC->Gspos("C07F",4,"C07G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); + + gMC->Gspos("C08F",1,"C08G", +iChamber->RInner()+bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C08F",2,"C08G", -iChamber->RInner()-bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C08F",3,"C08G", 0, +iChamber->RInner()+bpar[0] , 0, + idrotm[1101],"ONLY"); + gMC->Gspos("C08F",4,"C08G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); + } +//******************************************************************** +// Station 5 ** +//******************************************************************** + // indices 1 and 2 for first and second chambers in the station + // iChamber (first chamber) kept for other quanties than Z, + // assumed to be the same in both chambers + iChamber1 = iChamber = (AliMUONChamber*) (*fChambers)[8]; + iChamber2 =(AliMUONChamber*) (*fChambers)[9]; + zpos1=iChamber1->Z(); + zpos2=iChamber2->Z(); + dstation = zpos2 - zpos1; + zfpos=-(iChamber->DGas()+dframez+iChamber->DAlu())/2; + +// +// Mother volume + tpar[0] = iChamber->RInner()-dframep; + tpar[1] = (iChamber->ROuter()+dframep)/TMath::Cos(phi); + tpar[2] = dstation/4; + + gMC->Gsvolu("C09M", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("C10M", "TUBE", idAir, tpar, 3); + gMC->Gspos("C09M", 1, "ALIC", 0., 0., zpos1 , 0, "ONLY"); + gMC->Gspos("C10M", 1, "ALIC", 0., 0., zpos2 , 0, "ONLY"); +// Aluminium frames +// Outer frames + pgpar[0] = 360/12/2; + pgpar[1] = 360.; + pgpar[2] = 12.; + pgpar[3] = 2; + pgpar[4] = -dframez/2; + pgpar[5] = iChamber->ROuter(); + pgpar[6] = pgpar[5]+dframep; + pgpar[7] = +dframez/2; + pgpar[8] = pgpar[5]; + pgpar[9] = pgpar[6]; + gMC->Gsvolu("C09O", "PGON", idAlu1, pgpar, 10); + gMC->Gsvolu("C10O", "PGON", idAlu1, pgpar, 10); + gMC->Gspos("C09O",1,"C09M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C09O",2,"C09M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C10O",1,"C10M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C10O",2,"C10M", 0.,0.,+zfpos, 0,"ONLY"); +// +// Inner frame + tpar[0]= iChamber->RInner()-dframep; + tpar[1]= iChamber->RInner(); + tpar[2]= dframez/2; + gMC->Gsvolu("C09I", "TUBE", idAlu1, tpar, 3); + gMC->Gsvolu("C10I", "TUBE", idAlu1, tpar, 3); + + gMC->Gspos("C09I",1,"C09M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C09I",2,"C09M", 0.,0.,+zfpos, 0,"ONLY"); + gMC->Gspos("C10I",1,"C10M", 0.,0.,-zfpos, 0,"ONLY"); + gMC->Gspos("C10I",2,"C10M", 0.,0.,+zfpos, 0,"ONLY"); + + if (frames) { +// +// Frame Crosses + + bpar[0] = (iChamber->ROuter() - iChamber->RInner())/2; + bpar[1] = dframep/2; + bpar[2] = dframez/2; + gMC->Gsvolu("C09B", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C10B", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C09B",1,"C09M", +iChamber->RInner()+bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C09B",2,"C09M", -iChamber->RInner()-bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C09B",3,"C09M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C09B",4,"C09M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C09B",5,"C09M", +iChamber->RInner()+bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C09B",6,"C09M", -iChamber->RInner()-bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C09B",7,"C09M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C09B",8,"C09M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + + gMC->Gspos("C10B",1,"C10M", +iChamber->RInner()+bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C10B",2,"C10M", -iChamber->RInner()-bpar[0] , 0,-zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C10B",3,"C10M", 0, +iChamber->RInner()+bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C10B",4,"C10M", 0, -iChamber->RInner()-bpar[0] ,-zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C10B",5,"C10M", +iChamber->RInner()+bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C10B",6,"C10M", -iChamber->RInner()-bpar[0] , 0,+zfpos, + idrotm[1100],"ONLY"); + gMC->Gspos("C10B",7,"C10M", 0, +iChamber->RInner()+bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + gMC->Gspos("C10B",8,"C10M", 0, -iChamber->RInner()-bpar[0] ,+zfpos, + idrotm[1101],"ONLY"); + } + + +// +// Chamber Material represented by Alu sheet + tpar[0]= iChamber->RInner(); + tpar[1]= iChamber->ROuter(); + tpar[2] = (iChamber->DGas()+iChamber->DAlu())/2; + gMC->Gsvolu("C09A", "TUBE", idAlu2, tpar, 3); + gMC->Gsvolu("C10A", "TUBE", idAlu2, tpar, 3); + gMC->Gspos("C09A", 1, "C09M", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C10A", 1, "C10M", 0., 0., 0., 0, "ONLY"); +// +// Sensitive volumes + // tpar[2] = iChamber->DGas(); + tpar[2] = iChamber->DGas()/2; + gMC->Gsvolu("C09G", "TUBE", idGas, tpar, 3); + gMC->Gsvolu("C10G", "TUBE", idGas, tpar, 3); + gMC->Gspos("C09G", 1, "C09A", 0., 0., 0., 0, "ONLY"); + gMC->Gspos("C10G", 1, "C10A", 0., 0., 0., 0, "ONLY"); +// +// Frame Crosses to be placed inside gas + if (frames) { + dr = (iChamber->ROuter() - iChamber->RInner()); + bpar[0] = TMath::Sqrt(dr*dr-dframep*dframep/4)/2; + bpar[1] = dframep/2; + bpar[2] = iChamber->DGas()/2; + gMC->Gsvolu("C09F", "BOX", idAlu1, bpar, 3); + gMC->Gsvolu("C10F", "BOX", idAlu1, bpar, 3); + + gMC->Gspos("C09F",1,"C09G", +iChamber->RInner()+bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C09F",2,"C09G", -iChamber->RInner()-bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C09F",3,"C09G", 0, +iChamber->RInner()+bpar[0] , 0, + idrotm[1101],"ONLY"); + gMC->Gspos("C09F",4,"C09G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); + + gMC->Gspos("C10F",1,"C10G", +iChamber->RInner()+bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C10F",2,"C10G", -iChamber->RInner()-bpar[0] , 0, 0, + idrotm[1100],"ONLY"); + gMC->Gspos("C10F",3,"C10G", 0, +iChamber->RInner()+bpar[0] , 0, + idrotm[1101],"ONLY"); + gMC->Gspos("C10F",4,"C10G", 0, -iChamber->RInner()-bpar[0] , 0, + idrotm[1101],"ONLY"); + } + +/////////////////////////////////////// +// GEOMETRY FOR THE TRIGGER CHAMBERS // +/////////////////////////////////////// + +// 03/00 P. Dupieux : introduce a slighly more realistic +// geom. of the trigger readout planes with +// 2 Zpos per trigger plane (alternate +// between left and right of the trigger) + +// Parameters of the Trigger Chambers + + + const Float_t kXMC1MIN=34.; + const Float_t kXMC1MED=51.; + const Float_t kXMC1MAX=272.; + const Float_t kYMC1MIN=34.; + const Float_t kYMC1MAX=51.; + const Float_t kRMIN1=50.; + const Float_t kRMAX1=62.; + const Float_t kRMIN2=50.; + const Float_t kRMAX2=66.; + +// zposition of the middle of the gas gap in mother vol + const Float_t kZMCm=-3.6; + const Float_t kZMCp=+3.6; + + +// TRIGGER STATION 1 - TRIGGER STATION 1 - TRIGGER STATION 1 + + // iChamber 1 and 2 for first and second chambers in the station + // iChamber (first chamber) kept for other quanties than Z, + // assumed to be the same in both chambers + iChamber1 = iChamber = (AliMUONChamber*) (*fChambers)[10]; + iChamber2 =(AliMUONChamber*) (*fChambers)[11]; + + // 03/00 + // zpos1 and zpos2 are now the middle of the first and second + // plane of station 1 : + // zpos1=(16075+15995)/2=16035 mm, thick/2=40 mm + // zpos2=(16225+16145)/2=16185 mm, thick/2=40 mm + // + // zpos1m=15999 mm , zpos1p=16071 mm (middles of gas gaps) + // zpos2m=16149 mm , zpos2p=16221 mm (middles of gas gaps) + // rem : the total thickness accounts for 1 mm of al on both + // side of the RPCs (see zpos1 and zpos2), as previously + + zpos1=iChamber1->Z(); + zpos2=iChamber2->Z(); + + +// Mother volume definition + tpar[0] = iChamber->RInner(); + tpar[1] = iChamber->ROuter(); + tpar[2] = 4.0; + gMC->Gsvolu("CM11", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("CM12", "TUBE", idAir, tpar, 3); + +// Definition of the flange between the beam shielding and the RPC + tpar[0]= kRMIN1; + tpar[1]= kRMAX1; + tpar[2]= 4.0; + + gMC->Gsvolu("CF1A", "TUBE", idAlu1, tpar, 3); //Al + gMC->Gspos("CF1A", 1, "CM11", 0., 0., 0., 0, "MANY"); + gMC->Gspos("CF1A", 2, "CM12", 0., 0., 0., 0, "MANY"); + + +// FIRST PLANE OF STATION 1 + +// ratios of zpos1m/zpos1p and inverse for first plane + Float_t zmp=(zpos1-3.6)/(zpos1+3.6); + Float_t zpm=1./zmp; + + +// Definition of prototype for chambers in the first plane + + tpar[0]= 0.; + tpar[1]= 0.; + tpar[2]= 0.; + + gMC->Gsvolu("CC1A", "BOX ", idAlu1, tpar, 0); //Al + gMC->Gsvolu("CB1A", "BOX ", idtmed[1107], tpar, 0); //Bakelite + gMC->Gsvolu("CG1A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer + +// chamber type A + tpar[0] = -1.; + tpar[1] = -1.; + + const Float_t kXMC1A=kXMC1MED+(kXMC1MAX-kXMC1MED)/2.; + const Float_t kYMC1Am=0.; + const Float_t kYMC1Ap=0.; + + tpar[2] = 0.1; + gMC->Gsposp("CG1A", 1, "CB1A", 0., 0., 0., 0, "ONLY",tpar,3); + tpar[2] = 0.3; + gMC->Gsposp("CB1A", 1, "CC1A", 0., 0., 0., 0, "ONLY",tpar,3); + + tpar[2] = 0.4; + tpar[0] = (kXMC1MAX-kXMC1MED)/2.; + tpar[1] = kYMC1MIN; + + gMC->Gsposp("CC1A", 1, "CM11",kXMC1A,kYMC1Am,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 2, "CM11",-kXMC1A,kYMC1Ap,kZMCp, 0, "ONLY", tpar, 3); + +// chamber type B + Float_t tpar1save=tpar[1]; + Float_t y1msave=kYMC1Am; + Float_t y1psave=kYMC1Ap; + + tpar[0] = (kXMC1MAX-kXMC1MIN)/2.; + tpar[1] = (kYMC1MAX-kYMC1MIN)/2.; + + const Float_t kXMC1B=kXMC1MIN+tpar[0]; + const Float_t kYMC1Bp=(y1msave+tpar1save)*zpm+tpar[1]; + const Float_t kYMC1Bm=(y1psave+tpar1save)*zmp+tpar[1]; + + gMC->Gsposp("CC1A", 3, "CM11",kXMC1B,kYMC1Bp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 4, "CM11",-kXMC1B,kYMC1Bm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 5, "CM11",kXMC1B,-kYMC1Bp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 6, "CM11",-kXMC1B,-kYMC1Bm,kZMCm, 0, "ONLY", tpar, 3); + +// chamber type C (end of type B !!) + tpar1save=tpar[1]; + y1msave=kYMC1Bm; + y1psave=kYMC1Bp; + + tpar[0] = kXMC1MAX/2; + tpar[1] = kYMC1MAX/2; + + const Float_t kXMC1C=tpar[0]; +// warning : same Z than type B + const Float_t kYMC1Cp=(y1psave+tpar1save)*1.+tpar[1]; + const Float_t kYMC1Cm=(y1msave+tpar1save)*1.+tpar[1]; + + gMC->Gsposp("CC1A", 7, "CM11",kXMC1C,kYMC1Cp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 8, "CM11",-kXMC1C,kYMC1Cm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 9, "CM11",kXMC1C,-kYMC1Cp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 10, "CM11",-kXMC1C,-kYMC1Cm,kZMCm, 0, "ONLY", tpar, 3); + +// chamber type D, E and F (same size) + tpar1save=tpar[1]; + y1msave=kYMC1Cm; + y1psave=kYMC1Cp; + + tpar[0] = kXMC1MAX/2.; + tpar[1] = kYMC1MIN; + + const Float_t kXMC1D=tpar[0]; + const Float_t kYMC1Dp=(y1msave+tpar1save)*zpm+tpar[1]; + const Float_t kYMC1Dm=(y1psave+tpar1save)*zmp+tpar[1]; + + gMC->Gsposp("CC1A", 11, "CM11",kXMC1D,kYMC1Dm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 12, "CM11",-kXMC1D,kYMC1Dp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 13, "CM11",kXMC1D,-kYMC1Dm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 14, "CM11",-kXMC1D,-kYMC1Dp,kZMCp, 0, "ONLY", tpar, 3); + + + tpar1save=tpar[1]; + y1msave=kYMC1Dm; + y1psave=kYMC1Dp; + const Float_t kYMC1Ep=(y1msave+tpar1save)*zpm+tpar[1]; + const Float_t kYMC1Em=(y1psave+tpar1save)*zmp+tpar[1]; + + gMC->Gsposp("CC1A", 15, "CM11",kXMC1D,kYMC1Ep,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 16, "CM11",-kXMC1D,kYMC1Em,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 17, "CM11",kXMC1D,-kYMC1Ep,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 18, "CM11",-kXMC1D,-kYMC1Em,kZMCm, 0, "ONLY", tpar, 3); + + tpar1save=tpar[1]; + y1msave=kYMC1Em; + y1psave=kYMC1Ep; + const Float_t kYMC1Fp=(y1msave+tpar1save)*zpm+tpar[1]; + const Float_t kYMC1Fm=(y1psave+tpar1save)*zmp+tpar[1]; + + gMC->Gsposp("CC1A", 19, "CM11",kXMC1D,kYMC1Fm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 20, "CM11",-kXMC1D,kYMC1Fp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 21, "CM11",kXMC1D,-kYMC1Fm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC1A", 22, "CM11",-kXMC1D,-kYMC1Fp,kZMCp, 0, "ONLY", tpar, 3); + +// Positioning first plane in ALICE + gMC->Gspos("CM11", 1, "ALIC", 0., 0., zpos1, 0, "ONLY"); + +// End of geometry definition for the first plane of station 1 + + + +// SECOND PLANE OF STATION 1 : proj ratio = zpos2/zpos1 + + const Float_t kZ12=zpos2/zpos1; + +// Definition of prototype for chambers in the second plane of station 1 + + tpar[0]= 0.; + tpar[1]= 0.; + tpar[2]= 0.; + + gMC->Gsvolu("CC2A", "BOX ", idAlu1, tpar, 0); //Al + gMC->Gsvolu("CB2A", "BOX ", idtmed[1107], tpar, 0); //Bakelite + gMC->Gsvolu("CG2A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer + +// chamber type A + tpar[0] = -1.; + tpar[1] = -1.; + + const Float_t kXMC2A=kXMC1A*kZ12; + const Float_t kYMC2Am=0.; + const Float_t kYMC2Ap=0.; + + tpar[2] = 0.1; + gMC->Gsposp("CG2A", 1, "CB2A", 0., 0., 0., 0, "ONLY",tpar,3); + tpar[2] = 0.3; + gMC->Gsposp("CB2A", 1, "CC2A", 0., 0., 0., 0, "ONLY",tpar,3); + + tpar[2] = 0.4; + tpar[0] = ((kXMC1MAX-kXMC1MED)/2.)*kZ12; + tpar[1] = kYMC1MIN*kZ12; + + gMC->Gsposp("CC2A", 1, "CM12",kXMC2A,kYMC2Am,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 2, "CM12",-kXMC2A,kYMC2Ap,kZMCp, 0, "ONLY", tpar, 3); + + +// chamber type B + + tpar[0] = ((kXMC1MAX-kXMC1MIN)/2.)*kZ12; + tpar[1] = ((kYMC1MAX-kYMC1MIN)/2.)*kZ12; + + const Float_t kXMC2B=kXMC1B*kZ12; + const Float_t kYMC2Bp=kYMC1Bp*kZ12; + const Float_t kYMC2Bm=kYMC1Bm*kZ12; + gMC->Gsposp("CC2A", 3, "CM12",kXMC2B,kYMC2Bp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 4, "CM12",-kXMC2B,kYMC2Bm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 5, "CM12",kXMC2B,-kYMC2Bp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 6, "CM12",-kXMC2B,-kYMC2Bm,kZMCm, 0, "ONLY", tpar, 3); + + +// chamber type C (end of type B !!) + + tpar[0] = (kXMC1MAX/2)*kZ12; + tpar[1] = (kYMC1MAX/2)*kZ12; + + const Float_t kXMC2C=kXMC1C*kZ12; + const Float_t kYMC2Cp=kYMC1Cp*kZ12; + const Float_t kYMC2Cm=kYMC1Cm*kZ12; + gMC->Gsposp("CC2A", 7, "CM12",kXMC2C,kYMC2Cp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 8, "CM12",-kXMC2C,kYMC2Cm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 9, "CM12",kXMC2C,-kYMC2Cp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 10, "CM12",-kXMC2C,-kYMC2Cm,kZMCm, 0, "ONLY", tpar, 3); + +// chamber type D, E and F (same size) + + tpar[0] = (kXMC1MAX/2.)*kZ12; + tpar[1] = kYMC1MIN*kZ12; + + const Float_t kXMC2D=kXMC1D*kZ12; + const Float_t kYMC2Dp=kYMC1Dp*kZ12; + const Float_t kYMC2Dm=kYMC1Dm*kZ12; + gMC->Gsposp("CC2A", 11, "CM12",kXMC2D,kYMC2Dm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 12, "CM12",-kXMC2D,kYMC2Dp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 13, "CM12",kXMC2D,-kYMC2Dm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 14, "CM12",-kXMC2D,-kYMC2Dp,kZMCp, 0, "ONLY", tpar, 3); + + const Float_t kYMC2Ep=kYMC1Ep*kZ12; + const Float_t kYMC2Em=kYMC1Em*kZ12; + gMC->Gsposp("CC2A", 15, "CM12",kXMC2D,kYMC2Ep,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 16, "CM12",-kXMC2D,kYMC2Em,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 17, "CM12",kXMC2D,-kYMC2Ep,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 18, "CM12",-kXMC2D,-kYMC2Em,kZMCm, 0, "ONLY", tpar, 3); + + + const Float_t kYMC2Fp=kYMC1Fp*kZ12; + const Float_t kYMC2Fm=kYMC1Fm*kZ12; + gMC->Gsposp("CC2A", 19, "CM12",kXMC2D,kYMC2Fm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 20, "CM12",-kXMC2D,kYMC2Fp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 21, "CM12",kXMC2D,-kYMC2Fm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC2A", 22, "CM12",-kXMC2D,-kYMC2Fp,kZMCp, 0, "ONLY", tpar, 3); + +// Positioning second plane of station 1 in ALICE + + gMC->Gspos("CM12", 1, "ALIC", 0., 0., zpos2, 0, "ONLY"); + +// End of geometry definition for the second plane of station 1 + + + +// TRIGGER STATION 2 - TRIGGER STATION 2 - TRIGGER STATION 2 + + // 03/00 + // zpos3 and zpos4 are now the middle of the first and second + // plane of station 2 : + // zpos3=(17075+16995)/2=17035 mm, thick/2=40 mm + // zpos4=(17225+17145)/2=17185 mm, thick/2=40 mm + // + // zpos3m=16999 mm , zpos3p=17071 mm (middles of gas gaps) + // zpos4m=17149 mm , zpos4p=17221 mm (middles of gas gaps) + // rem : the total thickness accounts for 1 mm of al on both + // side of the RPCs (see zpos3 and zpos4), as previously + iChamber1 = iChamber = (AliMUONChamber*) (*fChambers)[12]; + iChamber2 =(AliMUONChamber*) (*fChambers)[13]; + Float_t zpos3=iChamber1->Z(); + Float_t zpos4=iChamber2->Z(); + + +// Mother volume definition + tpar[0] = iChamber->RInner(); + tpar[1] = iChamber->ROuter(); + tpar[2] = 4.0; + + gMC->Gsvolu("CM21", "TUBE", idAir, tpar, 3); + gMC->Gsvolu("CM22", "TUBE", idAir, tpar, 3); + +// Definition of the flange between the beam shielding and the RPC +// ???? interface shielding + + tpar[0]= kRMIN2; + tpar[1]= kRMAX2; + tpar[2]= 4.0; + + gMC->Gsvolu("CF2A", "TUBE", idAlu1, tpar, 3); //Al + gMC->Gspos("CF2A", 1, "CM21", 0., 0., 0., 0, "MANY"); + gMC->Gspos("CF2A", 2, "CM22", 0., 0., 0., 0, "MANY"); + + + +// FIRST PLANE OF STATION 2 : proj ratio = zpos3/zpos1 + + const Float_t kZ13=zpos3/zpos1; + +// Definition of prototype for chambers in the first plane of station 2 + tpar[0]= 0.; + tpar[1]= 0.; + tpar[2]= 0.; + + gMC->Gsvolu("CC3A", "BOX ", idAlu1, tpar, 0); //Al + gMC->Gsvolu("CB3A", "BOX ", idtmed[1107], tpar, 0); //Bakelite + gMC->Gsvolu("CG3A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer + + +// chamber type A + tpar[0] = -1.; + tpar[1] = -1.; + + const Float_t kXMC3A=kXMC1A*kZ13; + const Float_t kYMC3Am=0.; + const Float_t kYMC3Ap=0.; + + tpar[2] = 0.1; + gMC->Gsposp("CG3A", 1, "CB3A", 0., 0., 0., 0, "ONLY",tpar,3); + tpar[2] = 0.3; + gMC->Gsposp("CB3A", 1, "CC3A", 0., 0., 0., 0, "ONLY",tpar,3); + + tpar[2] = 0.4; + tpar[0] = ((kXMC1MAX-kXMC1MED)/2.)*kZ13; + tpar[1] = kYMC1MIN*kZ13; + gMC->Gsposp("CC3A", 1, "CM21",kXMC3A,kYMC3Am,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 2, "CM21",-kXMC3A,kYMC3Ap,kZMCp, 0, "ONLY", tpar, 3); + + +// chamber type B + tpar[0] = ((kXMC1MAX-kXMC1MIN)/2.)*kZ13; + tpar[1] = ((kYMC1MAX-kYMC1MIN)/2.)*kZ13; + + const Float_t kXMC3B=kXMC1B*kZ13; + const Float_t kYMC3Bp=kYMC1Bp*kZ13; + const Float_t kYMC3Bm=kYMC1Bm*kZ13; + gMC->Gsposp("CC3A", 3, "CM21",kXMC3B,kYMC3Bp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 4, "CM21",-kXMC3B,kYMC3Bm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 5, "CM21",kXMC3B,-kYMC3Bp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 6, "CM21",-kXMC3B,-kYMC3Bm,kZMCm, 0, "ONLY", tpar, 3); + + +// chamber type C (end of type B !!) + tpar[0] = (kXMC1MAX/2)*kZ13; + tpar[1] = (kYMC1MAX/2)*kZ13; + + const Float_t kXMC3C=kXMC1C*kZ13; + const Float_t kYMC3Cp=kYMC1Cp*kZ13; + const Float_t kYMC3Cm=kYMC1Cm*kZ13; + gMC->Gsposp("CC3A", 7, "CM21",kXMC3C,kYMC3Cp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 8, "CM21",-kXMC3C,kYMC3Cm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 9, "CM21",kXMC3C,-kYMC3Cp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 10, "CM21",-kXMC3C,-kYMC3Cm,kZMCm, 0, "ONLY", tpar, 3); + + +// chamber type D, E and F (same size) + + tpar[0] = (kXMC1MAX/2.)*kZ13; + tpar[1] = kYMC1MIN*kZ13; + + const Float_t kXMC3D=kXMC1D*kZ13; + const Float_t kYMC3Dp=kYMC1Dp*kZ13; + const Float_t kYMC3Dm=kYMC1Dm*kZ13; + gMC->Gsposp("CC3A", 11, "CM21",kXMC3D,kYMC3Dm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 12, "CM21",-kXMC3D,kYMC3Dp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 13, "CM21",kXMC3D,-kYMC3Dm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 14, "CM21",-kXMC3D,-kYMC3Dp,kZMCp, 0, "ONLY", tpar, 3); + + const Float_t kYMC3Ep=kYMC1Ep*kZ13; + const Float_t kYMC3Em=kYMC1Em*kZ13; + gMC->Gsposp("CC3A", 15, "CM21",kXMC3D,kYMC3Ep,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 16, "CM21",-kXMC3D,kYMC3Em,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 17, "CM21",kXMC3D,-kYMC3Ep,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 18, "CM21",-kXMC3D,-kYMC3Em,kZMCm, 0, "ONLY", tpar, 3); + + const Float_t kYMC3Fp=kYMC1Fp*kZ13; + const Float_t kYMC3Fm=kYMC1Fm*kZ13; + gMC->Gsposp("CC3A", 19, "CM21",kXMC3D,kYMC3Fm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 20, "CM21",-kXMC3D,kYMC3Fp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 21, "CM21",kXMC3D,-kYMC3Fm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC3A", 22, "CM21",-kXMC3D,-kYMC3Fp,kZMCp, 0, "ONLY", tpar, 3); + + +// Positioning first plane of station 2 in ALICE + + gMC->Gspos("CM21", 1, "ALIC", 0., 0., zpos3, 0, "ONLY"); + +// End of geometry definition for the first plane of station 2 + + + + +// SECOND PLANE OF STATION 2 : proj ratio = zpos4/zpos1 + + const Float_t kZ14=zpos4/zpos1; + +// Definition of prototype for chambers in the second plane of station 2 + + tpar[0]= 0.; + tpar[1]= 0.; + tpar[2]= 0.; + + gMC->Gsvolu("CC4A", "BOX ", idAlu1, tpar, 0); //Al + gMC->Gsvolu("CB4A", "BOX ", idtmed[1107], tpar, 0); //Bakelite + gMC->Gsvolu("CG4A", "BOX ", idtmed[1106], tpar, 0); //Gas streamer + +// chamber type A + tpar[0] = -1.; + tpar[1] = -1.; + + const Float_t kXMC4A=kXMC1A*kZ14; + const Float_t kYMC4Am=0.; + const Float_t kYMC4Ap=0.; + + tpar[2] = 0.1; + gMC->Gsposp("CG4A", 1, "CB4A", 0., 0., 0., 0, "ONLY",tpar,3); + tpar[2] = 0.3; + gMC->Gsposp("CB4A", 1, "CC4A", 0., 0., 0., 0, "ONLY",tpar,3); + + tpar[2] = 0.4; + tpar[0] = ((kXMC1MAX-kXMC1MED)/2.)*kZ14; + tpar[1] = kYMC1MIN*kZ14; + gMC->Gsposp("CC4A", 1, "CM22",kXMC4A,kYMC4Am,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 2, "CM22",-kXMC4A,kYMC4Ap,kZMCp, 0, "ONLY", tpar, 3); + + +// chamber type B + tpar[0] = ((kXMC1MAX-kXMC1MIN)/2.)*kZ14; + tpar[1] = ((kYMC1MAX-kYMC1MIN)/2.)*kZ14; + + const Float_t kXMC4B=kXMC1B*kZ14; + const Float_t kYMC4Bp=kYMC1Bp*kZ14; + const Float_t kYMC4Bm=kYMC1Bm*kZ14; + gMC->Gsposp("CC4A", 3, "CM22",kXMC4B,kYMC4Bp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 4, "CM22",-kXMC4B,kYMC4Bm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 5, "CM22",kXMC4B,-kYMC4Bp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 6, "CM22",-kXMC4B,-kYMC4Bm,kZMCm, 0, "ONLY", tpar, 3); + + +// chamber type C (end of type B !!) + tpar[0] =(kXMC1MAX/2)*kZ14; + tpar[1] = (kYMC1MAX/2)*kZ14; + + const Float_t kXMC4C=kXMC1C*kZ14; + const Float_t kYMC4Cp=kYMC1Cp*kZ14; + const Float_t kYMC4Cm=kYMC1Cm*kZ14; + gMC->Gsposp("CC4A", 7, "CM22",kXMC4C,kYMC4Cp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 8, "CM22",-kXMC4C,kYMC4Cm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 9, "CM22",kXMC4C,-kYMC4Cp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 10, "CM22",-kXMC4C,-kYMC4Cm,kZMCm, 0, "ONLY", tpar, 3); + + +// chamber type D, E and F (same size) + tpar[0] = (kXMC1MAX/2.)*kZ14; + tpar[1] = kYMC1MIN*kZ14; + + const Float_t kXMC4D=kXMC1D*kZ14; + const Float_t kYMC4Dp=kYMC1Dp*kZ14; + const Float_t kYMC4Dm=kYMC1Dm*kZ14; + gMC->Gsposp("CC4A", 11, "CM22",kXMC4D,kYMC4Dm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 12, "CM22",-kXMC4D,kYMC4Dp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 13, "CM22",kXMC4D,-kYMC4Dm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 14, "CM22",-kXMC4D,-kYMC4Dp,kZMCp, 0, "ONLY", tpar, 3); + + const Float_t kYMC4Ep=kYMC1Ep*kZ14; + const Float_t kYMC4Em=kYMC1Em*kZ14; + gMC->Gsposp("CC4A", 15, "CM22",kXMC4D,kYMC4Ep,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 16, "CM22",-kXMC4D,kYMC4Em,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 17, "CM22",kXMC4D,-kYMC4Ep,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 18, "CM22",-kXMC4D,-kYMC4Em,kZMCm, 0, "ONLY", tpar, 3); + + const Float_t kYMC4Fp=kYMC1Fp*kZ14; + const Float_t kYMC4Fm=kYMC1Fm*kZ14; + gMC->Gsposp("CC4A", 19, "CM22",kXMC4D,kYMC4Fm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 20, "CM22",-kXMC4D,kYMC4Fp,kZMCp, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 21, "CM22",kXMC4D,-kYMC4Fm,kZMCm, 0, "ONLY", tpar, 3); + gMC->Gsposp("CC4A", 22, "CM22",-kXMC4D,-kYMC4Fp,kZMCp, 0, "ONLY", tpar, 3); + + +// Positioning second plane of station 2 in ALICE + + gMC->Gspos("CM22", 1, "ALIC", 0., 0., zpos4, 0, "ONLY"); + +// End of geometry definition for the second plane of station 2 + +// End of trigger geometry definition + +} + + + +//___________________________________________ +void AliMUONv1::CreateMaterials() +{ + // *** DEFINITION OF AVAILABLE MUON MATERIALS *** + // + // Ar-CO2 gas + Float_t ag1[3] = { 39.95,12.01,16. }; + Float_t zg1[3] = { 18.,6.,8. }; + Float_t wg1[3] = { .8,.0667,.13333 }; + Float_t dg1 = .001821; + // + // Ar-buthane-freon gas -- trigger chambers + Float_t atr1[4] = { 39.95,12.01,1.01,19. }; + Float_t ztr1[4] = { 18.,6.,1.,9. }; + Float_t wtr1[4] = { .56,.1262857,.2857143,.028 }; + Float_t dtr1 = .002599; + // + // Ar-CO2 gas + Float_t agas[3] = { 39.95,12.01,16. }; + Float_t zgas[3] = { 18.,6.,8. }; + Float_t wgas[3] = { .74,.086684,.173316 }; + Float_t dgas = .0018327; + // + // Ar-Isobutane gas (80%+20%) -- tracking + Float_t ag[3] = { 39.95,12.01,1.01 }; + Float_t zg[3] = { 18.,6.,1. }; + Float_t wg[3] = { .8,.057,.143 }; + Float_t dg = .0019596; + // + // Ar-Isobutane-Forane-SF6 gas (49%+7%+40%+4%) -- trigger + Float_t atrig[5] = { 39.95,12.01,1.01,19.,32.066 }; + Float_t ztrig[5] = { 18.,6.,1.,9.,16. }; + Float_t wtrig[5] = { .49,1.08,1.5,1.84,0.04 }; + Float_t dtrig = .0031463; + // + // bakelite + + Float_t abak[3] = {12.01 , 1.01 , 16.}; + Float_t zbak[3] = {6. , 1. , 8.}; + Float_t wbak[3] = {6. , 6. , 1.}; + Float_t dbak = 1.4; + + Float_t epsil, stmin, deemax, tmaxfd, stemax; + + Int_t iSXFLD = gAlice->Field()->Integ(); + Float_t sXMGMX = gAlice->Field()->Max(); + // + // --- Define the various materials for GEANT --- + AliMaterial(9, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2); + AliMaterial(10, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2); + AliMaterial(15, "AIR$ ", 14.61, 7.3, .001205, 30423.24, 67500); + AliMixture(19, "Bakelite$", abak, zbak, dbak, -3, wbak); + AliMixture(20, "ArC4H10 GAS$", ag, zg, dg, 3, wg); + AliMixture(21, "TRIG GAS$", atrig, ztrig, dtrig, -5, wtrig); + AliMixture(22, "ArCO2 80%$", ag1, zg1, dg1, 3, wg1); + AliMixture(23, "Ar-freon $", atr1, ztr1, dtr1, 4, wtr1); + AliMixture(24, "ArCO2 GAS$", agas, zgas, dgas, 3, wgas); + + epsil = .001; // Tracking precision, + stemax = -1.; // Maximum displacement for multiple scat + tmaxfd = -20.; // Maximum angle due to field deflection + deemax = -.3; // Maximum fractional energy loss, DLS + stmin = -.8; + // + // Air + AliMedium(1, "AIR_CH_US ", 15, 1, iSXFLD, sXMGMX, tmaxfd, stemax, deemax, epsil, stmin); + // + // Aluminum + + AliMedium(4, "ALU_CH_US ", 9, 0, iSXFLD, sXMGMX, tmaxfd, fMaxStepAlu, + fMaxDestepAlu, epsil, stmin); + AliMedium(5, "ALU_CH_US ", 10, 0, iSXFLD, sXMGMX, tmaxfd, fMaxStepAlu, + fMaxDestepAlu, epsil, stmin); + // + // Ar-isoC4H10 gas + + AliMedium(6, "AR_CH_US ", 20, 1, iSXFLD, sXMGMX, tmaxfd, fMaxStepGas, + fMaxDestepGas, epsil, stmin); +// + // Ar-Isobuthane-Forane-SF6 gas + + AliMedium(7, "GAS_CH_TRIGGER ", 21, 1, iSXFLD, sXMGMX, tmaxfd, stemax, deemax, epsil, stmin); + + AliMedium(8, "BAKE_CH_TRIGGER ", 19, 0, iSXFLD, sXMGMX, tmaxfd, fMaxStepAlu, + fMaxDestepAlu, epsil, stmin); + + AliMedium(9, "ARG_CO2 ", 22, 1, iSXFLD, sXMGMX, tmaxfd, fMaxStepGas, + fMaxDestepAlu, epsil, stmin); +} + +//___________________________________________ + +void AliMUONv1::Init() +{ + // + // Initialize Tracking Chambers + // + + printf("\n\n\n Start Init for version 1 - CPC chamber type\n\n\n"); + + for (Int_t i=0; iInit(); + } + + // + // Set the chamber (sensitive region) GEANT identifier + AliMC* gMC = AliMC::GetMC(); + ((AliMUONChamber*)(*fChambers)[0])->SetGid(gMC->VolId("C01G")); + ((AliMUONChamber*)(*fChambers)[1])->SetGid(gMC->VolId("C02G")); + ((AliMUONChamber*)(*fChambers)[2])->SetGid(gMC->VolId("C03G")); + ((AliMUONChamber*)(*fChambers)[3])->SetGid(gMC->VolId("C04G")); + ((AliMUONChamber*)(*fChambers)[4])->SetGid(gMC->VolId("C05G")); + ((AliMUONChamber*)(*fChambers)[5])->SetGid(gMC->VolId("C06G")); + ((AliMUONChamber*)(*fChambers)[6])->SetGid(gMC->VolId("C07G")); + ((AliMUONChamber*)(*fChambers)[7])->SetGid(gMC->VolId("C08G")); + ((AliMUONChamber*)(*fChambers)[8])->SetGid(gMC->VolId("C09G")); + ((AliMUONChamber*)(*fChambers)[9])->SetGid(gMC->VolId("C10G")); + ((AliMUONChamber*)(*fChambers)[10])->SetGid(gMC->VolId("CG1A")); + ((AliMUONChamber*)(*fChambers)[11])->SetGid(gMC->VolId("CG2A")); + ((AliMUONChamber*)(*fChambers)[12])->SetGid(gMC->VolId("CG3A")); + ((AliMUONChamber*)(*fChambers)[13])->SetGid(gMC->VolId("CG4A")); + + printf("\n\n\n Finished Init for version 0 - CPC chamber type\n\n\n"); + + //cp + printf("\n\n\n Start Init for Trigger Circuits\n\n\n"); + for (Int_t i=0; iInit(i); + } + printf(" Finished Init for Trigger Circuits\n\n\n"); + //cp + +} + +//___________________________________________ +void AliMUONv1::StepManager() +{ + Int_t copy, id; + static Int_t idvol; + static Int_t vol[2]; + Int_t ipart; + TLorentzVector pos; + TLorentzVector mom; + Float_t theta,phi; + Float_t destep, step; + + static Float_t eloss, eloss2, xhit, yhit, tof, tlength; + const Float_t kBig=1.e10; + + // modifs perso + static Float_t hits[15]; + + TClonesArray &lhits = *fHits; + + // + // Set maximum step size for gas + // numed=gMC->GetMedium(); + // + // Only charged tracks + if( !(gMC->TrackCharge()) ) return; + // + // Only gas gap inside chamber + // Tag chambers and record hits when track enters + idvol=-1; + id=gMC->CurrentVolID(copy); + + for (Int_t i=1; i<=kNCH; i++) { + if(id==((AliMUONChamber*)(*fChambers)[i-1])->GetGid()){ + vol[0]=i; + idvol=i-1; + } + } + if (idvol == -1) return; + // + // Get current particle id (ipart), track position (pos) and momentum (mom) + gMC->TrackPosition(pos); + gMC->TrackMomentum(mom); + + ipart = gMC->TrackPid(); + //Int_t ipart1 = gMC->IdFromPDG(ipart); + //printf("ich, ipart %d %d \n",vol[0],ipart1); + + // + // momentum loss and steplength in last step + destep = gMC->Edep(); + step = gMC->TrackStep(); + + // + // record hits when track enters ... + if( gMC->IsTrackEntering()) { + gMC->SetMaxStep(fMaxStepGas); + Double_t tc = mom[0]*mom[0]+mom[1]*mom[1]; + Double_t rt = TMath::Sqrt(tc); + Double_t pmom = TMath::Sqrt(tc+mom[2]*mom[2]); + Double_t tx=mom[0]/pmom; + Double_t ty=mom[1]/pmom; + Double_t tz=mom[2]/pmom; + Double_t s=((AliMUONChamber*)(*fChambers)[idvol]) + ->ResponseModel() + ->Pitch()/tz; + theta = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg; + phi = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg; + hits[0] = Float_t(ipart); // Geant3 particle type + hits[1] = pos[0]+s*tx; // X-position for hit + hits[2] = pos[1]+s*ty; // Y-position for hit + hits[3] = pos[2]+s*tz; // Z-position for hit + hits[4] = theta; // theta angle of incidence + hits[5] = phi; // phi angle of incidence + hits[8] = (Float_t) fNPadHits; // first padhit + hits[9] = -1; // last pad hit + + // modifs perso + hits[10] = mom[3]; // hit momentum P + hits[11] = mom[0]; // Px/P + hits[12] = mom[1]; // Py/P + hits[13] = mom[2]; // Pz/P + // fin modifs perso + tof=gMC->TrackTime(); + hits[14] = tof; // Time of flight + // phi angle of incidence + tlength = 0; + eloss = 0; + eloss2 = 0; + xhit = pos[0]; + yhit = pos[1]; + // Only if not trigger chamber + if(idvol<10) { + // + // Initialize hit position (cursor) in the segmentation model + ((AliMUONChamber*) (*fChambers)[idvol]) + ->SigGenInit(pos[0], pos[1], pos[2]); + } else { + //geant3->Gpcxyz(); + //printf("In the Trigger Chamber #%d\n",idvol-9); + } + } + eloss2+=destep; + + // + // Calculate the charge induced on a pad (disintegration) in case + // + // Mip left chamber ... + if( gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()){ + gMC->SetMaxStep(kBig); + eloss += destep; + tlength += step; + + Float_t x0,y0; + + if(idvol<10) { +// tracking chambers + x0 = 0.5*(xhit+pos[0]); + y0 = 0.5*(yhit+pos[1]); + } else { +// trigger chambers + x0=xhit; + y0=yhit; + } + + + if (eloss >0) MakePadHits(x0,y0,eloss,tof,idvol); + + + hits[6]=tlength; + hits[7]=eloss2; + if (fNPadHits > (Int_t)hits[8]) { + hits[8]= hits[8]+1; + hits[9]= (Float_t) fNPadHits; + } + + new(lhits[fNhits++]) + AliMUONHit(fIshunt,gAlice->CurrentTrack(),vol,hits); + eloss = 0; + // + // Check additional signal generation conditions + // defined by the segmentation + // model (boundary crossing conditions) + } else if + (((AliMUONChamber*) (*fChambers)[idvol]) + ->SigGenCond(pos[0], pos[1], pos[2])) + { + ((AliMUONChamber*) (*fChambers)[idvol]) + ->SigGenInit(pos[0], pos[1], pos[2]); +// printf("\n-> MakePadHits, reason special %d",ipart); + if (eloss > 0 && idvol < 10) + MakePadHits(0.5*(xhit+pos[0]),0.5*(yhit+pos[1]),eloss,tof,idvol); + xhit = pos[0]; + yhit = pos[1]; + eloss = destep; + tlength += step ; + // + // nothing special happened, add up energy loss + } else { + eloss += destep; + tlength += step ; + } +} + + diff --git a/MUON/AliMUONv1.h b/MUON/AliMUONv1.h new file mode 100644 index 00000000000..70c5ffe43c2 --- /dev/null +++ b/MUON/AliMUONv1.h @@ -0,0 +1,34 @@ +#ifndef ALIMUONV1_H +#define ALIMUONV1_H +/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +///////////////////////////////////////////////////////// +// Manager and hits classes for set:MUON version 0 // +///////////////////////////////////////////////////////// + +#include "AliMUON.h" + +class AliMUONv1 : public AliMUON { +public: + AliMUONv1(); + AliMUONv1(const char *name, const char *title); + virtual ~AliMUONv1() {} + virtual void CreateGeometry(); + virtual void CreateMaterials(); + virtual void Init(); + virtual Int_t IsVersion() const {return 1;} + virtual void StepManager(); +private: + ClassDef(AliMUONv1,1) //Hits manager for set:MUON version 0 +}; +#endif + + + + + + + diff --git a/MUON/Config.C b/MUON/Config.C new file mode 100644 index 00000000000..1578552351f --- /dev/null +++ b/MUON/Config.C @@ -0,0 +1,784 @@ +enum gentype_t {hijing, gun, box, pythia, param, cocktail, fluka, halo, ntuple, scan, doublescan}; + +gentype_t gentype=pythia; +//Int_t ntracks=2828*20; +Int_t ntracks=200; +void Config() +{ + +new AliGeant3("C++ Interface to Geant3"); + +//======================================================================= +// Create the output file + +TFile *rootfile = new TFile("galice.root","recreate"); +rootfile->SetCompressionLevel(2); +TGeant3 *geant3 = (TGeant3*)gMC; + + +//======================================================================= +// ******* GEANT STEERING parameters FOR ALICE SIMULATION ******* + geant3->fGctrak->maxnst=1000000; + +geant3->SetTRIG(1); //Number of events to be processed +geant3->SetSWIT(4,100); +geant3->SetDEBU(0,0,1); +geant3->SetDCAY(1); +geant3->SetPAIR(1); +geant3->SetCOMP(1); +geant3->SetPHOT(1); +geant3->SetPFIS(0); +geant3->SetDRAY(1); +geant3->SetANNI(1); +geant3->SetBREM(1); +geant3->SetMUNU(1); +geant3->SetCKOV(0); +geant3->SetHADR(4); //Select pure GEANH (HADR 1) or GEANH/NUCRIN (HADR 3) +geant3->SetLOSS(1); +geant3->SetMULS(1); +geant3->SetRAYL(0); +geant3->SetAUTO(0); //Select automatic STMIN etc... calc. (AUTO 1) or manual (AUTO 0) +geant3->SetABAN(0); //Restore 3.16 behaviour for abandoned tracks +geant3->SetOPTI(2); //Select optimisation level for GEANT geometry searches (0,1,2) +Float_t cut = 1.e-1; // 100MeV cut by default +Float_t tofmax = 1.e10; +// GAM ELEC NHAD CHAD MUON EBREM MUHAB EDEL MUDEL MUPA TOFMAX +geant3->SetCUTS(1.e-4, 1.e-4, 1.e-3, 1.e-4, 1.e-4, cut, cut, cut, cut, cut, 1.e-5); + + gAlice->TrackingLimits( 700, 2200); + +// +//======================================================================= +// ************* STEERING parameters FOR ALICE SIMULATION ************** +// --- Specify event type to be tracked through the ALICE setup +// --- All positions are in cm, angles in degrees, and P and E in GeV + + switch(gentype) + { + case gun: +//********************************************* +// Example for Fixed Particle Gun * +//********************************************* + AliGenFixed *gener = new AliGenFixed(ntracks); + gener->SetMomentum(3); + gener->SetPhiRange(0); + gener->SetThetaRange(0); + gener->SetOrigin(0,0,0); //vertex position + gener->SetPart(kProton); //GEANT particle type + break; + case box: +//********************************************* +// Example for Moving Particle Gun * +//********************************************* + AliGenBox *gener = new AliGenBox(ntracks); + gener->SetMomentumRange(3,4); + gener->SetPhiRange(-360,360); + gener->SetThetaRange(2., 10.); + gener->SetOrigin(25,25,510.5); + gener->SetVertexSmear(perTrack); + //vertex position + gener->SetSigma(1.8, 1.8,0); //Sigma in (X,Y,Z) (cm) on IP position + gener->SetPart(kProton); //GEANT particle type + break; + case scan: +//********************************************* +// Scanning on a grid * +//********************************************* + AliGenScan *gener = new AliGenScan(-1); + gener->SetMomentumRange(20,20); + gener->SetPhiRange(90,90); + gener->SetThetaRange(0,0); + //vertex position + gener->SetSigma(3,3,0); //Sigma in (X,Y,Z) (cm) on IP position + gener->SetPart(kMuonMinus); + gener->SetRange(20, -100, 100, 20, -100, 100, 1, 500, 500); + break; + case doublescan: +//********************************************* +// Scanning on a grid * +//********************************************* + AliGenDoubleScan *gener = new AliGenDoubleScan(-1); + gener->SetMomentumRange(4,4); + gener->SetPhiRange(0,360); + gener->SetThetaRange(0,0); + //vertex position + gener->SetSigma(3,3,0); //Sigma in (X,Y,Z) (cm) on IP position + gener->SetPart(8); + gener->SetRange(20, -100, 100, 20, -100, 100, 1, 500, 500); + gener->SetDistance(1); + + break; + + case hijing: + AliGenHIJINGpara *gener = new AliGenHIJINGpara(ntracks); + gener->SetMomentumRange(0,999); + gener->SetPhiRange(0,360); + gener->SetThetaRange(0.104,33.52); + gener->SetOrigin(0,0,0); //vertex position + gener->SetSigma(0,0,5.6); //Sigma in (X,Y,Z) (cm) on IP position + break; + + case pythia: +//******************************************** +// Example for Charm Production with Pythia * +//******************************************** + + AliGenPythia *gener = new AliGenPythia(ntracks); + gener->SetMomentumRange(0,999); + gener->SetPhiRange(0,360); + gener->SetThetaRange(0., 180.); + gener->SetYRange(-10,10); + gener->SetPtRange(0,100); + gener->SetOrigin(0,0,0); // vertex position + gener->SetVertexSmear(perEvent); + gener->SetSigma(0,0,5.6); // Sigma in (X,Y,Z) (cm) on IP position +// gener->SetStrucFunc(DO_Set_1); + gener->SetProcess(mb); + gener->SetEnergyCMS(5500.); + break; + + case param: +//******************************************************* +// Example for J/psi Production from Parameterisation * +//******************************************************* + typedef Double_t (*GenFunc) (Double_t *, Double_t *); + AliGenParam *gener = + new AliGenParam(ntracks,upsilon_p, + AliGenMUONlib::GetPt(upsilon_p), + AliGenMUONlib::GetY(upsilon_p), + AliGenMUONlib::GetIp(upsilon_p)); + + +// AliGenParam *gener = new AliGenParam(ntracks, jpsi_p); + gener->SetMomentumRange(0,999); + gener->SetPhiRange(0,360); + gener->SetYRange(2.5,4); + gener->SetThetaRange(2,9); + gener->SetPtRange(0,10); + gener->SetOrigin(0,0,0); //vertex position + gener->SetSigma(0,0,0); //Sigma in (X,Y,Z) (cm) on IP position + gener->SetForceDecay(dimuon); + gener->SetCutOnChild(0); + gener->SetTrackingFlag(0); + + break; + + case fluka: +//******************************************************* +// Example for a FLUKA Boundary Source * +//******************************************************* + AliGenFLUKAsource *gener = new AliGenFLUKAsource(-1); + gener->AddFile("$(ALICE_ROOT)/data/all32.root"); + rootfile->cd(); + gener->SetPartFlag(7); + gener->SetMomentumRange(0,999); + gener->SetPhiRange(0,360); + gener->SetThetaRange(0., 180.); + gener->SetAgeMax(1.e-5); + +// 31.7 events + gener->SetFraction(0.0315); + break; + + case ntuple: +//******************************************************* +// Example for reading from a external file * +//******************************************************* + AliGenExtFile *gener = new AliGenExtFile(-1); + gener->SetFileName("$(ALICE_ROOT)/data/pbpb.root"); + gener->SetThetaRange(0.104,33.52); + gener->SetOrigin(0,0,0); //vertex position + gener->SetSigma(0,0,5.6); //Sigma in (X,Y,Z) (cm) on IP position + gener->SetVertexSmear(perTrack); + gener->SetTrackingFlag(1); + break; + + case halo: +//******************************************************* +// Example for Tunnel Halo Source * +//******************************************************* + AliGenHalo *gener = new AliGenHalo(ntracks); + gener->SetFileName("/h1/morsch/marsip/marsip5.mu"); + break; + + case cocktail: +//******************************************************* +// Example for a Cocktail * +//******************************************************* + AliGenCocktail *gener = new AliGenCocktail(); + gener->SetMomentumRange(0,10); + gener->SetPhiRange(0,360); + gener->SetThetaRange(45.,135); + + pions = new AliGenParam(100, pion_p); +// kaons = new AliGenParam(10 , kaon_p); +// protons = new AliGenParam(10 , proton_p); + gener->AddGenerator(pions , "Pions" , 100); +// gener->AddGenerator(kaons , "Kaons" , 10); +// gener->AddGenerator(protons, "Protons", 10); + + break; + } + +// Activate this line if you want the vertex smearing to happen +// track by track +// + +gener->Init(); +gAlice->SetField(-2,1); //Specify maximum magnetic field in Tesla (neg. ==> default field) +Int_t iFRAME =0; +Int_t iMAG =1; +Int_t iITS =0; +Int_t iTPC =0; +Int_t iTOF =0; +Int_t iRICH =0; +Int_t iZDC =0; +Int_t iCASTOR =0; +Int_t iTRD =0; +Int_t iABSO =0; +Int_t iDIPO =1; +Int_t iHALL =1; +Int_t iSHIL =0; +Int_t iPIPE =1; +Int_t iFMD =0; +Int_t iMUON =1; +Int_t iPHOS =0; +Int_t iPMD =0; + +//=================== Alice BODY parameters ============================= +AliBODY *BODY = new AliBODY("BODY","Alice envelop"); + +if(iFRAME) { +//=================== FRAME parameters ============================ +AliFRAME *FRAME = new AliFRAMEv0("FRAME","Space Frame"); +} + +if(iMAG) { +//=================== MAG parameters ============================ +// --- Start with Magnet since detector layouts may be depending --- +// --- on the selected Magnet dimensions --- +AliMAG *MAG = new AliMAG("MAG","Magnet"); +} + +if(iITS) { +//=================== ITS parameters ============================ +// +// EUCLID is a flag to output (=1) both geometry and media to two ASCII files +// (called by default ITSgeometry.euc and ITSgeometry.tme) in a format +// understandable to the CAD system EUCLID. The default (=0) means that you +// dont want to use this facility. +// + AliITS *ITS = new AliITSv5("ITS","normal ITS"); + ITS->SetEUCLID(0); +} + +if(iTPC) { +//============================ TPC parameters ================================ +// --- This allows the user to specify sectors for the SLOW (TPC geometry 2) +// --- Simulator. SecAL (SecAU) <0 means that ALL lower (upper) +// --- sectors are specified, any value other than that requires at least one +// --- sector (lower or upper)to be specified! +// --- Reminder: sectors 1-24 are lower sectors (1-12 -> z>0, 13-24 -> z<0) +// --- sectors 25-72 are the upper ones (25-48 -> z>0, 49-72 -> z<0) +// --- SecLows - number of lower sectors specified (up to 6) +// --- SecUps - number of upper sectors specified (up to 12) +// --- Sens - sensitive strips for the Slow Simulator !!! +// --- This does NOT work if all S or L-sectors are specified, i.e. +// --- if SecAL or SecAU < 0 +// +// +//----------------------------------------------------------------------------- + + AliTPC *TPC = new AliTPCv3("TPC","Normal TPC"); + AliTPCD *paramd = TPC->GetDigParam(); + AliTPCParam *param = &(paramd->GetParam()); + +// Set geometrical parameters + + param->SetSectorAngles(40.,0.,20.,10.); + param->SetInnerRadiusLow(83.7); + param->SetInnerRadiusUp(132.9); + param->SetOuterRadiusLow(146.9); + param->SetOuterRadiusUp(249.4); + param->SetInSecLowEdge(81.6); + param->SetInSecUpEdge(135.); + param->SetOuSecLowEdge(144.2); + param->SetOuSecUpEdge(252.1); + param->SetEdge(1.5); + param->SetDeadZone(1.15); + param->Update(); + +// set gas mixture + + TPC->SetGasMixt(2,20,10,-1,0.9,0.1,0.); + TPC->SetSecAL(1); + TPC->SetSecAU(1); + TPC->SetSecLows(0, -1, -1, -1, -1, -1); + TPC->SetSecUps(18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + TPC->SetSens(-1); +} + +if(iTOF) { +//=================== TOF parameters ============================ + AliTOF *TOF = new AliTOFv2("TOF","normal TOF"); +} + +if(iRICH) { +//=================== RICH parameters =========================== + AliRICH *RICH = new AliRICHv0("RICH","normal RICH"); + + RICH->SetSMAXAR(0.03); + RICH->SetSMAXAL(-1); +// +// Version 0 +// Default Segmentation + AliRICHsegmentationV0* RsegV0 = new AliRICHsegmentationV0; + RsegV0->SetPadSize(.8, .8); + RsegV0->SetDAnod(0.8/3); +// Default Response + AliRICHresponseV0* Rresponse0 = new AliRICHresponseV0; + AliRICHresponseCkv* RresponseCkv = new AliRICHresponseCkv; + +//------------------------Chambers 0-6 ---------------------------- + for (Int_t i=0; i<7; i++) { + RICH->SetSegmentationModel(i, 1, RsegV0); + RICH->SetResponseModel(i, mip , Rresponse0); + RICH->SetResponseModel(i, cerenkov, RresponseCkv); + RICH->Chamber(i).SetRSIGM(5.); + RICH->Chamber(i).SetMUCHSP(20.); + RICH->Chamber(i).SetMUSIGM(0.18, 0.18); + RICH->Chamber(i).SetMAXADC( 1024); + RICH->Chamber(i).SetSqrtKx3(0.77459667); + RICH->Chamber(i).SetKx2(0.962); + RICH->Chamber(i).SetKx4(0.379); + RICH->Chamber(i).SetSqrtKy3(0.77459667); + RICH->Chamber(i).SetKy2(0.962); + RICH->Chamber(i).SetKy4(0.379); + RICH->Chamber(i).SetPitch(0.25); + RICH->SetNsec(i,1); + } +} + +if(iZDC) { +//=================== ZDC parameters ============================ + + AliZDC *ZDC = new AliZDCv1("ZDC","normal ZDC"); +} + +if(iCASTOR) { +//=================== CASTOR parameters ============================ + + AliCASTOR *CASTOR = new AliCASTORv1("CASTOR","normal CASTOR"); +} + +if(iTRD) { +//=================== TRD parameters ============================ + + AliTRD *TRD = new AliTRDv2("TRD","TRD version 2"); +} + + +if(iABSO) { +//=================== ABSO parameters ============================ + AliABSO *ABSO = new AliABSOv1("ABSO","Muon Absorber"); +} + +if(iDIPO) { +//=================== DIPO parameters ============================ + + AliDIPO *DIPO = new AliDIPOv2("DIPO","Dipole version 2"); +} + +if(iHALL) { +//=================== HALL parameters ============================ + AliHALL *HALL = new AliHALL("HALL","Alice Hall"); +} + + + +if(iSHIL) { +//=================== SHIL parameters ============================ + AliSHIL *SHIL = new AliSHILv1("SHIL","Shielding"); +} + + +if(iPIPE) { +//=================== PIPE parameters ============================ + AliPIPE *PIPE = new AliPIPEv0("PIPE","Beam Pipe"); +} + + +if(iFMD) { +//=================== FMD parameters ============================ + AliFMD *FMD = new AliFMDv1("FMD","normal FMD"); +} + +if(iMUON) { +//=================== MUON parameters =========================== + +AliMUON *MUON = new AliMUONv1("MUON","normal MUON"); + MUON->SetIshunt(0); + MUON->SetMaxStepGas(0.1); + MUON->SetMaxStepAlu(0.1); +// +// Version 0 +// +// First define the number of planes that are segmented (1 or 2) by a call +// to SetNsec. +// Then chose for each chamber (chamber plane) the segmentation +// and response model. +// They should be equal for the two chambers of each station. In a future +// version this will be enforced. +// +// + Int_t chamber; + Int_t station; +// Default response + AliMUONResponseV0* response0 = new AliMUONResponseV0; + response0->SetSqrtKx3(0.7131); + response0->SetKx2(1.0107); + response0->SetKx4(0.4036); + response0->SetSqrtKy3(0.7642); + response0->SetKy2(0.9706); + response0->SetKy4(0.3831); + response0->SetPitch(0.25); + response0->SetSigmaIntegration(10.); + response0->SetChargeSlope(50); + response0->SetChargeSpread(0.18, 0.18); + response0->SetMaxAdc(4096); + response0->SetZeroSuppression(6); +//-------------------------------------------------------- +// Configuration for Chamber TC1/2 (Station 1) ---------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Float_t rseg1[4]={17.5, 55.2, 71.3, 95.5}; + Int_t nseg1[4]={4, 4, 2, 1}; +// + chamber=1; +//^^^^^^^^^ + MUON->SetNsec(chamber-1,2); +// + AliMUONSegmentationV01 *seg11=new AliMUONSegmentationV01; + + seg11->SetSegRadii(rseg1); + seg11->SetPadSize(3, 0.5); + seg11->SetDAnod(3.0/3./4); + seg11->SetPadDivision(nseg1); + + MUON->SetSegmentationModel(chamber-1, 1, seg11); +// + AliMUONSegmentationV02 *seg12=new AliMUONSegmentationV02; + seg12->SetSegRadii(rseg1); + seg12->SetPadSize(0.75, 2.0); + seg12->SetDAnod(3.0/3./4); + seg12->SetPadDivision(nseg1); + + MUON->SetSegmentationModel(chamber-1, 2, seg12); + + MUON->SetResponseModel(chamber-1, response0); + + chamber=2; +//^^^^^^^^^ +// + MUON->SetNsec(chamber-1,2); +// + AliMUONSegmentationV01 *seg21=new AliMUONSegmentationV01; + seg21->SetSegRadii(rseg1); + seg21->SetPadSize(3, 0.5); + seg21->SetDAnod(3.0/3./4); + seg21->SetPadDivision(nseg1); + MUON->SetSegmentationModel(chamber-1, 1, seg21); +// + AliMUONSegmentationV02 *seg22=new AliMUONSegmentationV02; + seg22->SetSegRadii(rseg1); + seg22->SetPadSize(0.75, 2.); + seg22->SetDAnod(3.0/3./4); + seg22->SetPadDivision(nseg1); + MUON->SetSegmentationModel(chamber-1, 2, seg22); + + MUON->SetResponseModel(chamber-1, response0); +// +//-------------------------------------------------------- +// Configuration for Chamber TC3/4 ----------------------- +///^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +// Float_t rseg2[4]={23.5, 87.7, 122.4, 122.5}; + Float_t rseg2[4]={23.5, 47.1, 87.7, 122.5}; + Int_t nseg2[4]={4, 4, 2, 1}; +// + chamber=3; +//^^^^^^^^^ + MUON->SetNsec(chamber-1,2); +// + AliMUONSegmentationV01 *seg31=new AliMUONSegmentationV01; + seg31->SetSegRadii(rseg2); + seg31->SetPadSize(6, 0.5); + seg31->SetDAnod(3.0/3./4); + seg31->SetPadDivision(nseg2); + MUON->SetSegmentationModel(chamber-1, 1, seg31); +// + AliMUONSegmentationV02 *seg32=new AliMUONSegmentationV02; + seg32->SetSegRadii(rseg2); + seg32->SetPadSize(0.75, 4.); + seg32->SetPadDivision(nseg2); + seg32->SetDAnod(3.0/3./4); + + MUON->SetSegmentationModel(chamber-1, 2, seg32); + + MUON->SetResponseModel(chamber-1, response0); + + chamber=4; +//^^^^^^^^^ +// + MUON->SetNsec(chamber-1,2); +// + AliMUONSegmentationV01 *seg41=new AliMUONSegmentationV01; + seg41->SetSegRadii(rseg2); + seg41->SetPadSize(6, 0.5); + seg41->SetDAnod(3.0/3./4); + seg41->SetPadDivision(nseg2); + MUON->SetSegmentationModel(chamber-1, 1, seg41); +// + AliMUONSegmentationV02 *seg42=new AliMUONSegmentationV02; + seg42->SetSegRadii(rseg2); + seg42->SetPadSize(0.75, 4.); + seg42->SetPadDivision(nseg2); + seg42->SetDAnod(3.0/3./4); + + MUON->SetSegmentationModel(chamber-1, 2, seg42); + + MUON->SetResponseModel(chamber-1, response0); + + +//-------------------------------------------------------- +// Configuration for Chamber TC5/6 ----------------------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + seg5 = new AliMUONSegmentationV1; + AliMUONResponseV0* response5 = new AliMUONResponseV0; + // K3 = 0.62 + response5->SetSqrtKx3(0.78740079); + response5->SetKx2(0.95237319); // 0.5 * kPI * (1- 0.5*sqrtky3 ) + response5->SetKx4(0.37480633); // 0.25/TMath::ATan(sqrtkx3) + // K3 = 0.55 + response5->SetSqrtKy3(0.74161985); + response5->SetKy2(0.98832946); + response5->SetKy4(0.39177817); + response5->SetPitch(0.325); + response5->SetSigmaIntegration(10.); + response5->SetChargeSlope(50); + response5->SetChargeSpread(0.4, 0.4); + response5->SetMaxAdc(4096); + response5->SetZeroSuppression(6); + + + chamber=5; + MUON->SetNsec(chamber-1,1); + MUON->SetSegmentationModel(chamber-1, 1, seg5); + MUON->SetResponseModel(chamber-1, response5); + + chamber=6; + MUON->SetNsec(chamber-1,1); + MUON->SetSegmentationModel(chamber-1, 1, seg5); + MUON->SetResponseModel(chamber-1, response5); +// +// Station 3 + station=3; + MUON->SetPadSize(station, 1, 0.975, 0.55); + +//-------------------------------------------------------- +// Configuration for Chamber TC7/8 (Station 4) ---------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + Int_t nseg4[4]={4, 4, 2, 1}; + + chamber=7; +//^^^^^^^^^ + MUON->SetNsec(chamber-1,2); +// + AliMUONSegmentationV04 *seg71=new AliMUONSegmentationV04; + seg71->SetPadSize(10.,0.5); + seg71->SetDAnod(0.25); + seg71->SetPadDivision(nseg4); + MUON->SetSegmentationModel(chamber-1, 1, seg71); + AliMUONSegmentationV05 *seg72=new AliMUONSegmentationV05; + seg72->SetPadSize(1,10); + seg72->SetDAnod(0.25); + seg72->SetPadDivision(nseg4); + MUON->SetSegmentationModel(chamber-1, 2, seg72); + + MUON->SetResponseModel(chamber-1, response0); + + chamber=8; +//^^^^^^^^^ + MUON->SetNsec(chamber-1,2); + AliMUONSegmentationV04 *seg81=new AliMUONSegmentationV04; + seg81->SetPadSize(10., 0.5); + seg81->SetPadDivision(nseg4); + seg81->SetDAnod(0.25); + MUON->SetSegmentationModel(chamber-1, 1, seg81); + + AliMUONSegmentationV05 *seg82=new AliMUONSegmentationV05; + seg82->SetPadSize(1, 10); + seg82->SetPadDivision(nseg4); + seg82->SetDAnod(0.25); + MUON->SetSegmentationModel(chamber-1, 2, seg82); + + MUON->SetResponseModel(chamber-1, response0); +//-------------------------------------------------------- +// Configuration for Chamber TC9/10 (Station 5) --------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + chamber=9; +//^^^^^^^^^ + MUON->SetNsec(chamber-1,2); +// + AliMUONSegmentationV04 *seg91=new AliMUONSegmentationV04; + seg91->SetPadSize(10.,0.5); + seg91->SetDAnod(0.25); + seg91->SetPadDivision(nseg4); + MUON->SetSegmentationModel(chamber-1, 1, seg91); + + AliMUONSegmentationV05 *seg92=new AliMUONSegmentationV05; + seg92->SetPadSize(1,10); + seg92->SetDAnod(0.25); + seg92->SetPadDivision(nseg4); + + MUON->SetSegmentationModel(chamber-1, 2, seg92); + + MUON->SetResponseModel(chamber-1, response0); + + chamber=10; +//^^^^^^^^^ + MUON->SetNsec(chamber-1,2); + AliMUONSegmentationV04 *seg101=new AliMUONSegmentationV04; + seg101->SetPadSize(10., 0.5); + seg101->SetPadDivision(nseg4); + seg101->SetDAnod(0.25); + MUON->SetSegmentationModel(chamber-1, 1, seg101); + + AliMUONSegmentationV05 *seg102=new AliMUONSegmentationV05; + seg102->SetPadSize(1,10); + seg102->SetPadDivision(nseg4); + seg102->SetDAnod(0.25); + MUON->SetSegmentationModel(chamber-1, 2, seg102); + + MUON->SetResponseModel(chamber-1, response0); + +//-------------------------------------------------------- +// Configuration for Trigger staions --------------------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + AliMUONResponseTrigger* responseTrigger0 = new AliMUONResponseTrigger; + + chamber=11; + MUON->SetNsec(chamber-1,2); + AliMUONSegmentationTriggerX *seg111=new AliMUONSegmentationTriggerX; + MUON->SetSegmentationModel(chamber-1, 1, seg111); + AliMUONSegmentationTriggerY *seg112=new AliMUONSegmentationTriggerY; + MUON->SetSegmentationModel(chamber-1, 2, seg112); + + MUON->SetResponseModel(chamber-1, responseTrigger0); + + chamber=12; + MUON->SetNsec(chamber-1,2); + AliMUONSegmentationTriggerX *seg121=new AliMUONSegmentationTriggerX; + MUON->SetSegmentationModel(chamber-1, 1, seg121); + AliMUONSegmentationTriggerY *seg122=new AliMUONSegmentationTriggerY; + MUON->SetSegmentationModel(chamber-1, 2, seg122); + + MUON->SetResponseModel(chamber-1, responseTrigger0); + + chamber=13; + MUON->SetNsec(chamber-1,2); + AliMUONSegmentationTriggerX *seg131=new AliMUONSegmentationTriggerX; + MUON->SetSegmentationModel(chamber-1, 1, seg131); + AliMUONSegmentationTriggerY *seg132=new AliMUONSegmentationTriggerY; + MUON->SetSegmentationModel(chamber-1, 2, seg132); + MUON->SetResponseModel(chamber-1, responseTrigger0); + + chamber=14; + MUON->SetNsec(chamber-1,2); + AliMUONSegmentationTriggerX *seg141=new AliMUONSegmentationTriggerX; + MUON->SetSegmentationModel(chamber-1, 1, seg141); + AliMUONSegmentationTriggerY *seg142=new AliMUONSegmentationTriggerY; + MUON->SetSegmentationModel(chamber-1, 2, seg142); + + MUON->SetResponseModel(chamber-1, responseTrigger0); + +} + + +if(iPHOS) { +//=================== PHOS parameters =========================== + +AliPHOS *PHOS = new AliPHOSv1("PHOS","normal PHOS"); +// * PHOSflags: YES: X<>0 NO: X=0 +// * PHOSflags(1) : -----X Create branch for TObjArray of AliPHOSCradle +// * ----X- Create file (ftn03 on HP-UX) with list of SHAKER particles (7Mb/event) +// * +PHOS->SetFlags(000001); +PHOS->SetRadius(460); //Distance from beam to PHOS crystals. +// (crystal_side_size,crystal_length,wrap_thikness,air_thikness,PIN_size,PIN length) +PHOS->SetCell(2.2, 18., 0.01, 0.01, 1., 0.1); +PHOS->SetCradleSize(104, 88, 4); // Nz (along beam), Nphi, Ncradles +PHOS->SetCradleA(0); //Angle between Cradles +PHOS->SetCPV(1., 2.); //CPV thikness, CPV-PHOS distance +// * =============== +// * PHOS extra parameters (contact Maxim Volkov volkov@mail.cern.ch) +// * 1. STE_THICK Steel cover thickness +// * 2. SUP_Y Crystal support height +// * 3. FTIU_THICK Thermo Insulating outer cover Upper plate thickness +// * 4. UFP_Y Upper Polystyrene Foam plate thickness +// * 5. TCB_THICK Thermo insulating Crystal Block wall thickness +// * 6. UCP_Y Upper Cooling Plate thickness +// * 7. ASP_Y Al Support Plate thickness +// * 8. TIP_Y Lower Thermo Insulating Plate thickness +// * 9. TXP_Y Lower Textolit Plate thickness +PHOS->SetExtra(0.001, 6.95, 4., 5., 2., 0.06, 10., 3., 1.); +PHOS->SetTextolitWall(209., 71., 250.); //Textolit Wall box dimentions +PHOS->SetInnerAir(206., 66., 244.); //Inner AIR volume dimensions +// * =============================== +// * 1. FTI_X Foam Thermo Insulating outer cover dimensions +// * 2. FTI_Y ==//== +// * 3. FTI_Z ==//== +// * 4. FTI_R Distance from IP to Foam Thermo Insulating top plate +PHOS->SetFoam(214.6, 80., 260., 467.); +// ================================= +// ******************************************************************************* +// * KINE 700 - SHAKER generator +// * KINE 700 x y z NDNDY YLIM PTLIM ChargeFlag +// * JWEAK=0 +// * JPI0=JETA=1 +// * JPIC=JPRO=JKAC=JKA0=JRHO=JOME=JPHI=JPSI=JDRY=ChargeFlag +// * Int_t JWEI; // Unweighted generation +// * Int_t NDNDY; // Density of charged particles +// * Float_t YLIM; // Rapidity Limit +// * Float_t PTLIM; // Pt limit in GeV/c +// * Int_t JWEAK; // Disable weak decays +// * Int_t JPI0; // pi0 generation +// * Int_t JETA; // eta generation +// * Int_t JPIC; // pi+/- generation +// * Int_t JPRO; // proton generation +// * Int_t JKAC; // K+/- generation +// * Int_t JKA0; // K0 generation +// * Int_t JRHO; // rho generation +// * Int_t JOME; // omega generation +// * Int_t JPHI; // phi generation +// * Int_t JPSI; // J/psi generation +// * Int_t JDRY; // Drell-Yan generation +// * KINE 700 5. 175. 0. 800. 1.5 5. 1. +// ******************************************************************************* +} + +if(iPMD) { +//=================== PMD parameters ============================ + +// Must be defined AFTER PHOS +AliPMD *PMD = new AliPMDv1("PMD","normal PMD"); +PMD->SetPAR(1., 1., 0.8, 0.02); +PMD->SetIN(6., 20., 600., 27., 27.); +PMD->SetGEO(0.0, 0.2, 4.); +PMD->SetPadSize(0.8, 1.0, 1.2, 1.5); +} +} + + + + diff --git a/MUON/MUONConfig.C b/MUON/MUONConfig.C new file mode 100644 index 00000000000..a5eb180b248 --- /dev/null +++ b/MUON/MUONConfig.C @@ -0,0 +1,412 @@ +void Config() +{ + +new TGeant3("C++ Interface to Geant3"); + +//======================================================================= +// Create the output file + +TFile *rootfile = new TFile("galice.root","recreate"); +rootfile->SetCompressionLevel(2); +TGeant3 *geant3 = (TGeant3*)gMC; + +//======================================================================= +// ******* GEANT STEERING parameters FOR ALICE SIMULATION ******* +geant3->SetTRIG(1); //Number of events to be processed +geant3->SetSWIT(4,10); +geant3->SetDEBU(0,0,1); +//geant3->SetSWIT(2,2); +geant3->SetDCAY(0); +geant3->SetPAIR(0); +geant3->SetCOMP(0); +geant3->SetPHOT(0); +geant3->SetPFIS(0); +geant3->SetDRAY(0); +geant3->SetANNI(0); +geant3->SetBREM(0); +geant3->SetMUNU(1); +geant3->SetCKOV(1); +geant3->SetHADR(0); //Select pure GEANH (HADR 1) or GEANH/NUCRIN (HADR 3) +geant3->SetLOSS(1); +geant3->SetMULS(1); +geant3->SetRAYL(1); +geant3->SetAUTO(1); //Select automatic STMIN etc... calc. (AUTO 1) or manual (AUTO 0) +geant3->SetABAN(0); //Restore 3.16 behaviour for abandoned tracks +geant3->SetOPTI(2); //Select optimisation level for GEANT geometry searches (0,1,2) +Float_t cut = 1.e-3; // 1MeV cut by default +Float_t tofmax = 1.e10; +// GAM ELEC NHAD CHAD MUON EBREM MUHAB EDEL MUDEL MUPA TOFMAX +geant3->SetCUTS(cut,cut, cut, cut, cut, cut, cut, cut, cut, cut, tofmax); +// +//======================================================================= +// ************* STEERING parameters FOR ALICE SIMULATION ************** +// --- Specify event type to be tracked through the ALICE setup +// --- All positions are in cm, angles in degrees, and P and E in GeV +// +//********************************************* +// Example for Fixed Particle Gun * +//********************************************* +//AliGenFixed *gener = new AliGenFixed(200); +//gener->SetMomentumRange(0,999); +//gener->SetPhiRange(0,0); +//gener->SetThetaRange(5., 5.); +//gener->SetOrigin(0,0,0); //vertex position +//gener->SetPart(14) //GEANT particle type + +//********************************************* +// Example for Moving Particle Gun * +//********************************************* +/* +AliGenBox *gener = new AliGenBox(500); +gener->SetMomentumRange(0,10); +gener->SetPhiRange(0,360); +gener->SetThetaRange(2., 10.); +gener->SetOrigin(0,0,0); + //vertex position +gener->SetSigma(0,0,5.6); //Sigma in (X,Y,Z) (cm) on IP position +gener->SetPart(14) //GEANT particle type + */ +//************************************** +// Example for HIJING Parameterisation * +//************************************** +/* +AliGenHIJINGpara *gener = new AliGenHIJINGpara(84210); +gener->SetMomentumRange(0,999); +gener->SetPhiRange(0,360); +gener->SetThetaRange(0.28,179.72); +gener->SetOrigin(0,0,0); //vertex position +gener->SetSigma(0,0,0); //Sigma in (X,Y,Z) (cm) on IP position +/* +//******************************************** +// Example for Charm Production with Pythia * +//******************************************** +*/ +/* +AliGenPythia *gener = new AliGenPythia(200); +gener->SetMomentumRange(0,999); +gener->SetPhiRange(0,360); +gener->SetThetaRange(0., 180.); +gener->SetYRange(2,5); +gener->SetOrigin(0,0,0); // vertex position +gener->SetSigma(0,0,5.6); // Sigma in (X,Y,Z) (cm) on IP position +gener->SetProcess(AliGenPythia::jpsi); +gener->ForceDecay(AliGenPythia::dimuon); + +//******************************************************* +// Example for J/psi Production from Parameterisation * +//******************************************************* +/* + AliGenParam *gener = new AliGenParam(1000, 443); + gener->SetMomentumRange(0,999); + gener->SetPhiRange(0,360); + gener->SetYRange(2,4); + gener->SetPtRange(1,10); + gener->SetOrigin(0,0,0); //vertex position + gener->SetSigma(0,0,5.6); //Sigma in (X,Y,Z) (cm) on IP position + +//******************************************************* +// Example for a FLUKA Boundary Source * +//******************************************************* +/* +AliGenFLUKAsource *gener = new AliGenFLUKAsource(1000); +gener->SetPartFlag(9); +gener->SetMomentumRange(0,999); +gener->SetPhiRange(0,360); +gener->SetThetaRange(0., 180.); + */ +//******************************************************* +// Example for a Cocktail * +//******************************************************* + +AliGenCocktail *gener = new AliGenCocktail(); + +gener->SetMomentumRange(0,999); +gener->SetPhiRange(0,360); +gener->SetYRange(-4,4); +gener->SetPtRange(0,10); +gener->SetOrigin(0,0,0); //vertex position +gener->SetSigma(0,0,5.6); //Sigma in (X,Y,Z) (cm) on IP position +// + AliGenPythia *jpsi = new AliGenPythia(200); + + jpsi->SetProcess(AliGenPythia::jpsi); + jpsi->ForceDecay(AliGenPythia::dimuon); + + AliGenPythia *beauty = new AliGenPythia(200); + beauty->SetProcess(AliGenPythia::beauty_unforced); + beauty->ForceDecay(AliGenPythia::semielectronic); + + AliGenPythia *charm = new AliGenPythia(200); + charm->SetProcess(AliGenPythia::charm_unforced); + charm->ForceDecay(AliGenPythia::semimuonic); + charm->SetPtHard(5,10); + + AliGenParam *jpsi_to_muons = new AliGenParam(100,443); + jpsi_to_muons->ForceDecay(AliGenParam::dimuon); + + AliGenParam *jpsi_to_electrons = new AliGenParam(100,443); + jpsi_to_electrons->ForceDecay(AliGenParam::dielectron); + + AliGenParam *phi_to_electrons = new AliGenParam(100,333); + phi_to_electrons->ForceDecay(AliGenParam::dielectron); + +// gener->AddGenerator(jpsi,"Jpsi",1.); +// gener->AddGenerator(beauty,"Beauty",1.); +// gener->AddGenerator(charm,"Charm",1.); +// gener->AddGenerator(jpsi_to_muons,"Jpsi_to_Muons",1.); + gener->AddGenerator(jpsi_to_electrons,"Jpsi_to_Electrons",1.); + // gener->AddGenerator(phi_to_electrons,"Phi_to_Electrons",1.); +// +gener->Init(); +//************************************************************************** +// Specify maximum magnetic field in Tesla (neg. ==> default field) +gAlice->SetField(-999,2); +// gAlice->TrackingLimits(2000.,200); + +//=================== Alice BODY parameters ============================= + +AliBODY *BODY = new AliBODY("BODY","Alice envelop"); +/* +AliFRAME *FRAME = new AliFRAMEv0("FRAME", "Space Frame"); + +/* +//=================== ABSO parameters ============================ + +AliABSO *ABSO = new AliABSO("ABSO","Muon Absorber"); + +//=================== DIPO parameters ============================ + +AliDIPO *DIPO = new AliDIPOv2("DIPO","Dipole version 2"); + +//=================== SHIL parameters ============================ + +AliSHIL *SHIL = new AliSHIL("SHIL","Shielding"); + +//=================== PIPE parameters ============================ +*/ +// AliPIPE *PIPE = new AliPIPEv0("PIPE","Beam Pipe"); +/* +*/ +//=================== MUON parameters =========================== + + +AliMUON *MUON = new AliMUONv0("MUON","normal MUON"); + +MUON->SetSMAXAR(0.03); +MUON->SetSMAXAL(-1); +// +// Version 0 +// +// First define the number of planes that are segmented (1 or 2) by a call +// to SetNsec. +// Then chose for each chamber (chamber plane) the segmentation +// and response model. +// They should be equal for the two chambers of each station. In a future +// version this will be enforced. +// +// + Int_t chamber; + Int_t station; +// Default Segmentation + AliMUONSegmentationV0* segV0 = new AliMUONSegmentationV0; +// Default response + AliMUONResponseV0* response0 = new AliMUONResponseV0; + response0->SetSqrtKx3(0.761577); + response0->SetKx2(0.972655); + response0->SetKx4(0.3841); + response0->SetSqrtKy3(0.714143); + response0->SetKy2(1.0099); + response0->SetKy4(0.403); + response0->SetPitch(0.25); + response0->SetRSIGM(10.); + response0->SetMUCHSP(5.); + response0->SetMUSIGM(0.18, 0.18); + response0->SetMAXADC( 1024); +//-------------------------------------------------------- +// Configuration for Chamber TC1/2 (Station 1) ---------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Float_t rseg[4]={17.5, 55.2, 71.3, 95.5}; + Int_t nseg[4]={4, 4, 2, 1}; + + chamber=1; +//^^^^^^^^^ + MUON->SetNsec(chamber-1,2); +// + AliMUONSegmentationV01 *seg11=new AliMUONSegmentationV01; + seg11->SetSegRadii(rseg); + seg11->SetPADSIZ(3.048, 0.508); + seg11->SetPadDivision(nseg); + MUON->SetSegmentationModel(chamber-1, 1, seg11); +// + AliMUONSegmentationV01 *seg12=new AliMUONSegmentationV01; + seg12->SetSegRadii(rseg); + seg12->SetPADSIZ(2.032, 0.762); + seg12->SetPadDivision(nseg); + + MUON->SetSegmentationModel(chamber-1, 2, seg12); + + chamber=2; +//^^^^^^^^^ + MUON->SetNsec(chamber-1,2); + MUON->SetSegmentationModel(chamber-1, 1, seg11); + MUON->SetSegmentationModel(chamber-1, 2, seg12); + + station=1; +//^^^^^^^^^ + MUON->SetResponseModel(0, response0); + MUON->SetResponseModel(1, response0); +// +//-------------------------------------------------------- +// Configuration for Chamber TC3/4 ----------------------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + chamber=3; + MUON->SetNsec(chamber-1,1); + AliMUONSegmentationV0 *seg34=new AliMUONSegmentationV0; + seg34->SetDAnod(0.51/3.); + + MUON->SetSegmentationModel(chamber-1, 1, seg34); + MUON->SetResponseModel(chamber-1, response0); + + chamber=4; + MUON->SetNsec(chamber-1,1); + MUON->SetSegmentationModel(chamber-1, 1, seg34); + MUON->SetResponseModel(chamber-1, response0); +// +// Station 2 + station=2; + MUON->SetPADSIZ(station, 1, 0.75, 0.51); + MUON->SetMUCHSP(station, 5.); + MUON->SetMUSIGM(station, 0.18, 0.18); + MUON->SetRSIGM(station, 10.); + MUON->SetMAXADC(station, 1024); + +// +//-------------------------------------------------------- +// Configuration for Chamber TC5/6 ----------------------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + seg5 = new AliMUONSegmentationV1; + AliMUONresponseV0* response5 = new AliMUONresponseV0; + // K3 = 0.62 + response5->SetSqrtKx3(0.78740079); + response5->SetKx2(0.95237319); // 0.5 * kPI * (1- 0.5*sqrtky3 ) + response5->SetKx4(0.37480633); // 0.25/TMath::ATan(sqrtkx3) + // K3 = 0.55 + response5->SetSqrtKy3(0.74161985); + response5->SetKy2(0.98832946); + response5->SetKy4(0.39177817); + response5->SetPitch(0.325); + response5->SetRSIGM(10.); + response5->SetMUCHSP(5.); + response5->SetMUSIGM( 0.4, 0.4); + response5->SetMAXADC( 1024); + + chamber=5; + MUON->SetNsec(chamber-1,1); + MUON->SetSegmentationModel(chamber-1, 1, seg5); + MUON->SetResponseModel(chamber-1, response5); + + chamber=6; + MUON->SetNsec(chamber-1,1); + MUON->SetSegmentationModel(chamber-1, 1, seg5); + MUON->SetResponseModel(chamber-1, response5); +// +// Station 3 + station=3; + MUON->SetPADSIZ(station, 1, 0.975, 0.55); + +// +//-------------------------------------------------------- +// Configuration for Chamber TC7/8/9/10------------------- +//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + chamber=7; + MUON->SetNsec(chamber-1,1); + AliMUONSegmentationV0 *seg78=new AliMUONSegmentationV0; + seg78->SetDAnod(0.51/3.); + + MUON->SetSegmentationModel(chamber-1, 1, seg78); + MUON->SetResponseModel(chamber-1, response0); + + chamber=8; + MUON->SetNsec(chamber-1,1); + MUON->SetSegmentationModel(chamber-1, 1, seg78); + MUON->SetResponseModel(chamber-1, response0); +// +// Station 4 + station=4; + MUON->SetPADSIZ(station, 1, 0.75, 0.5); + + chamber=9; + MUON->SetNsec(chamber-1,1); + AliMUONSegmentationV0 *seg910=new AliMUONSegmentationV0; + seg910->SetDAnod(0.51/3.); + + MUON->SetSegmentationModel(chamber-1, 1, seg910); + MUON->SetResponseModel(chamber-1, response0); + + chamber=10; + MUON->SetNsec(chamber-1,1); + MUON->SetSegmentationModel(chamber-1, 1, seg910); + MUON->SetResponseModel(chamber-1, response0); +// +// Station 5 + station=5; + MUON->SetPADSIZ(station, 1, 0.75, 0.5); + + chamber=11; + MUON->SetNsec(chamber-1,1); + AliMUONSegmentationV0 *seg1112=new AliMUONSegmentationV0; + seg1112->SetDAnod(0.51/3.); + + MUON->SetSegmentationModel(chamber-1, 1, seg1112); + MUON->SetResponseModel(chamber-1, response0); + + chamber=12; + MUON->SetNsec(chamber-1,1); + MUON->SetSegmentationModel(chamber-1, 1, seg1112); + MUON->SetResponseModel(chamber-1, response0); +// +// Trigger Station 1 + station=6; + MUON->SetPADSIZ(station, 1, 0.75, 0.5); + + chamber=13; + MUON->SetNsec(chamber-1,1); + AliMUONSegmentationV0 *seg1314=new AliMUONSegmentationV0; + seg1314->SetDAnod(0.51/3.); + + MUON->SetSegmentationModel(chamber-1, 1, seg1314); + MUON->SetResponseModel(chamber-1, response0); + + chamber=14; + MUON->SetNsec(chamber-1,1); + MUON->SetSegmentationModel(chamber-1, 1, seg1314); + MUON->SetResponseModel(chamber-1, response0); +// +// Trigger Station 2 + station=7; + MUON->SetPADSIZ(station, 1, 0.75, 0.5); +} + + + + + + + + + + + + + + + + + + + + + diff --git a/MUON/MUONLinkDef.h b/MUON/MUONLinkDef.h index f0bb90e6e09..daf08445eb1 100644 --- a/MUON/MUONLinkDef.h +++ b/MUON/MUONLinkDef.h @@ -1,39 +1,49 @@ #ifdef __CINT__ -/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * - * See cxx source for full Copyright notice */ - -/* $Id$ */ - #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; -#pragma link C++ enum Cluster_t; #pragma link C++ class AliMUON-; #pragma link C++ class AliMUONv0; -#pragma link C++ class AliMUONhit; -#pragma link C++ class AliMUONdigit; -#pragma link C++ class AliMUONlist; -#pragma link C++ class AliMUONcluster; -#pragma link C++ class AliMUONreccluster; -#pragma link C++ class AliMUONsegmentation; -#pragma link C++ class AliMUONresponse; -#pragma link C++ class AliMUONsegmentationV0; -#pragma link C++ class AliMUONresponseV0; -#pragma link C++ class AliMUONsegmentationV01; -#pragma link C++ class AliMUONsegmentationV02; -#pragma link C++ class AliMUONsegmentationV04; -#pragma link C++ class AliMUONsegmentationV05; -#pragma link C++ class AliMUONsegmentationV1; -#pragma link C++ class AliMUONchamber; -#pragma link C++ class AliMUONpoints; -#pragma link C++ class AliMUONdisplay; -#pragma link C++ class AliMUONClusterFinder; -#pragma link C++ class AliMUONClusterFinderv0; -#pragma link C++ class AliMUONcorrelation; +#pragma link C++ class AliMUONv1; +#pragma link C++ class AliMUONHit; +#pragma link C++ class AliMUONPadHit; +#pragma link C++ class AliMUONDigit; +#pragma link C++ class AliMUONTransientDigit; +#pragma link C++ class AliMUONReconstHit; #pragma link C++ class AliMUONRawCluster; +#pragma link C++ class AliMUONGlobalTrigger; +#pragma link C++ class AliMUONLocalTrigger; +#pragma link C++ class AliMUONSegmentation; +#pragma link C++ class AliMUONResponse; +#pragma link C++ class AliMUONSegmentationV0; +#pragma link C++ class AliMUONResponseV0; +#pragma link C++ class AliMUONResponseTrigger; +#pragma link C++ class AliMUONSegmentationV01; +#pragma link C++ class AliMUONSegmentationV02; +#pragma link C++ class AliMUONSegmentationV04; +#pragma link C++ class AliMUONSegmentationV05; +#pragma link C++ class AliMUONSegmentationV1; +#pragma link C++ class AliMUONSegmentationTrigger; +#pragma link C++ class AliMUONSegmentationTriggerX; +#pragma link C++ class AliMUONSegmentationTriggerY; +#pragma link C++ class AliMUONChamber; +#pragma link C++ class AliMUONChamberTrigger; +#pragma link C++ class AliMUONPoints; +#pragma link C++ class AliMUONDisplay; +#pragma link C++ class AliMUONClusterFinder; +#pragma link C++ class AliMUONClusterFinderVS; #pragma link C++ class AliMUONHitMap; #pragma link C++ class AliMUONHitMapA1; -#pragma link C++ class AliMUONTUBE; +#pragma link C++ class AliMUONTrackReconstructor; +#pragma link C++ class AliMUONTriggerCircuit; +#pragma link C++ class AliMUONTriggerLut; +#pragma link C++ class AliMUONTriggerDecision; +#pragma link C++ class AliMUONEventReconstructor-; +#pragma link C++ class AliMUONHitForRec; +#pragma link C++ class AliMUONSegment; +#pragma link C++ class AliMUONTrack; +#pragma link C++ class AliMUONTrackHit; +#pragma link C++ class AliMUONTrackParam; #endif @@ -41,3 +51,4 @@ + diff --git a/MUON/MUONRawDigit.C b/MUON/MUONRawDigit.C new file mode 100644 index 00000000000..8bd09986ce6 --- /dev/null +++ b/MUON/MUONRawDigit.C @@ -0,0 +1,125 @@ +#include "iostream.h" +#include "/home/alice/guernane/date/tmp/ionlx/event.h" +#include "/home/alice/guernane/date/tmp/ionlx/monitor.h" + +//======================================================================= +// +// The following macro is used to read raw data from run#.raw files +// generated by DATE acquisition package. It was written using +// Guy Jacquet (IPN Lyon) monitoring code. +// +// 1-Feb-2000 Rachid GUERNANE, IPN Lyon, France +// +// + +void MUONRawDigit (Int_t evNumber1 = 0, Int_t evNumber2 = 0, char* dataSource="/home/alice/guernane/test/run3403_Linux.raw") +{ + +// Dynamically link some shared libs + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile* file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (file) file->Close(); + file = new TFile("galice.root", "UPDATE"); + +// Get AliRun object from file or create it if not on file + + if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + } + + AliMUONv2* MUON = (AliMUONv2*)gAlice->GetModule("MUON"); + +// +// Start Event Loop +// + + static int ilen; + int status; + + + status = monitorSetDataSource(dataSource); + + if (status != 0) { + fprintf( stderr, + "Error in monitorSetDataSource: %s\n", + monitorSetDataSource(status)); + } + + status = monitorDeclareMp("Retrieve Raw Data"); + + if (status != 0) { + fprintf( stderr, + "Error in monitorDeclareMp: %s\n", + monitorSetDataSource(status)); + } + + Int_t nev = 0; + Int_t iev = 0; + + for (; iev <= evNumber2 && nev < evNumber2*20; nev++) { + +// +// Raw event decoding +// + + void *ptr; + struct eventStruct *rawevent; + + status = monitorGetEventDynamic(&ptr); + + if (status != 0) { + fprintf( stderr, + "Error in monitorGetEventDynamic: %s\n", + monitorDecodeError(status)); + exit(1); + } + + rawevent = (struct eventStruct*)ptr; + + ilen = (rawevent->eventHeader.size - rawevent->eventHeader.headLen)/4; + + if (rawevent->eventHeader.type == PHYSICS_EVENT) { + iev = rawevent->eventHeader.nbInRun; + gAlice->GetEvent(iev-1); + printf("\nEvent No.: %d\n", iev); + printf("--------------------------------------------\n"); + + int* lptr = (int*)&rawevent->rawData[0]; + + MUON->GetRawDigits(iev-1, lptr, ilen); + + } + + free(ptr); + + } +// +// End Event loop +// + + file->Close(); + +} + + + + + + + + + + + + + + diff --git a/MUON/MUONTestTrigger.C b/MUON/MUONTestTrigger.C new file mode 100644 index 00000000000..1d19421103f --- /dev/null +++ b/MUON/MUONTestTrigger.C @@ -0,0 +1,110 @@ +#include "iostream.h" +// example of macro which retrieves the Trigger Output from galice.root + +void MUONTestTrigger (Int_t evNumber1=0,Int_t evNumber2=0) +{ +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Dynamically link some shared libs + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (file) file->Close(); + file = new TFile("galice.root","READ"); + +// Get AliRun object from file or create it if not on file + printf ("I'm after Map \n"); + if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + } + printf ("I'm after gAlice \n"); +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + for (int nev=evNumber1; nev<= evNumber2; nev++) { + Int_t nparticles = gAlice->GetEvent(nev); + cout << "nev npart =" << nev << " , " << nparticles << "\n"; + if (nev < evNumber1) continue; + if (nparticles <= 0) return; + + Int_t nbytes = 0; + AliMUONGlobalTrigger *gloTrg; + AliMUONLocalTrigger *locTrg; + +// Get pointers to Alice detectors and Triggers containers + AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON"); + TClonesArray *globalTrigger = MUON->GlobalTrigger(); + TClonesArray *localTrigger = MUON->LocalTrigger(); + + TTree *TR = gAlice->TreeR(); + TBranch *gbranch = TR->GetBranch("MUONGlobalTrigger"); + TBranch *lbranch = TR->GetBranch("MUONLocalTrigger"); + gbranch->SetAddress(&globalTrigger); + lbranch->SetAddress(&localTrigger); + + Int_t nent = TR->GetEntries(); + cout << ">>> " << nent << " entries found in TreeR of event " + << nev << "\n"; + Int_t nb = 0; + + for (Int_t n=1; nResetTrigger(); + nbytes += TR->GetEvent(n); + + Int_t nglobals = globalTrigger->GetEntries(); // should be = 1 + Int_t nlocals = localTrigger->GetEntries(); // who knows ? + + for (Int_t i=0; i>> Output for Global Trigger " << "\n"; + + gloTrg = (AliMUONGlobalTrigger*)globalTrigger->UncheckedAt(i); + + cout << "fSinglePlusLpt = " << gloTrg->fSinglePlusLpt << "\n"; + cout << "fSinglePlusHpt = " << gloTrg->fSinglePlusHpt << "\n"; + cout << "fSinglePlusApt = " << gloTrg->fSinglePlusApt << "\n"; + + cout << "fSingleMinusLpt = " << gloTrg->fSingleMinusLpt << "\n"; + cout << "fSingleMinusHpt = " << gloTrg->fSingleMinusHpt << "\n"; + cout << "fSingleMinusApt = " << gloTrg->fSingleMinusApt << "\n"; + + cout << "fSingleUndefLpt = " << gloTrg->fSingleUndefLpt << "\n"; + cout << "fSingleUndefHpt = " << gloTrg->fSingleUndefHpt << "\n"; + cout << "fSingleUndefApt = " << gloTrg->fSingleUndefApt << "\n"; + + cout << "fPairLikeLpt = " << gloTrg->fPairLikeLpt << "\n"; + cout << "fPairLikeHpt = " << gloTrg->fPairLikeHpt << "\n"; + cout << "fPairLikeApt = " << gloTrg->fPairLikeApt << "\n"; + + cout << "fPairUnlikeLpt = " << gloTrg->fPairUnlikeLpt << "\n"; + cout << "fPairUnlikeHpt = " << gloTrg->fPairUnlikeHpt << "\n"; + cout << "fPairUnlikeApt = " << gloTrg->fPairUnlikeApt << "\n"; + } // end of loop on Global Trigger + + for (Int_t i=0; i>> Output for Local Trigger # " << i << "\n"; + + locTrg = (AliMUONLocalTrigger*)localTrigger->UncheckedAt(i); + + cout << "fLoCircuit = " << locTrg->fLoCircuit << "\n"; + cout << "fLoStripX = " << locTrg->fLoStripX << "\n"; + cout << "fLoDev = " << locTrg->fLoDev << "\n"; + cout << "fLoStripY = " << locTrg->fLoStripY << "\n"; + cout << "fLoLpt = " << locTrg->fLoLpt << "\n"; + cout << "fLoHpt = " << locTrg->fLoHpt << "\n"; + cout << "fLoApt = " << locTrg->fLoApt << "\n"; + + } // end of loop on Local Trigger + } // end of loop on entries of TreeR + } // loop on event + +// store histos in ouput file + hfile->Write(); +} + + + + diff --git a/MUON/MUONTriggerLut.C b/MUON/MUONTriggerLut.C new file mode 100644 index 00000000000..5b8af8eb2e5 --- /dev/null +++ b/MUON/MUONTriggerLut.C @@ -0,0 +1,34 @@ +#include "iostream.h" +//--------------------------------------------------------- +// this macro is used to generate the Trigger Look up Table +// and store the TH3S histos in the MUONTriggerLut.root file +//--------------------------------------------------------- +void MUONTriggerLut() +{ +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Dynamically link some shared libs + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (file) file->Close(); + file = new TFile("galice.root","READ"); + +// Get AliRun object from file or create it if not on file + printf ("I'm after Map \n"); + if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + } + printf ("I'm after gAlice \n"); +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + AliMUONTriggerLut* Lut= new AliMUONTriggerLut; + Lut->LoadLut(); +} + + diff --git a/MUON/MUONTriggerLut.root b/MUON/MUONTriggerLut.root new file mode 100644 index 0000000000000000000000000000000000000000..d45ee19f2741393daf5d697da2e5d5cc26557e48 GIT binary patch literal 47713 zcmeFZcT`i|*DgvIkzSN;K~ba&gbpGKuXI6b4813z8hQsQ(gdUnC`bT-&_l0MRI1Vm zRRn|(I-$ea(f9X#=iD*wU-#Ve*I|rgv)6oPTl1M~?d-5|b9R17L}YlIh=}MR5m5t# zh^T%V_&peS5d*IQvVVU84*zdI>qI1g2*Hvr%0T4#N9!R0O8#8M0cP`17~yW?<}PgQ z;6XT8z#Ob>gst41t?X@H3M;`JbOHauPBxyxn)=#Wf8L(EIoR3RxM?6>3b_G7mVeK0 zXgE7VZ|J++cy3|&|C?DNVnPEt6nUdon>BZm`U~r4vAmvS@#5P=bT@^z?+?}T3Q3%HlmM7~uHr@@LBOHAJN9oi7pAEE%aDa2W z2ZuCZ>3lTcE&J=dBy8#J)a+-wwT!wc{0ud(Vdf_Q@juTmmTJ6OUdOSK|LZRwz0rM* z#IO5Ez~Jp9tfv0B*i+tdf<~eSN>U#(csu=tGfT&4)DRVx$ zxW08Yp&`8E%fv6ZKJU>B=f+ePJwX0-$!C}cadtl@MswD{CUI~d?d#2~`})sG?> zt-+E5_OHU`Bee>?iBB4C^|O2bKyqFsRIK*?)oJAW$eih9>GKhlzmnp$Ra^S)b`BQq z$plMgs`C3+LkDt2%a>M5VH}g)rpetNv39IXaJR`@|93J0tAxq?_3vaZ{jCBJ1EC73 zf2$z$w+b)*R^fl2;_AwpBWm}n8r-w%MW4HqzGG&UT_4D^2%9ZBZY8uVJyUi zeFS8FLqllLf!a86pAMy~EC@yHI%Ih6DdV9ryyaZ^VpUlF2P+su;4majX%W3#ZIKmQ z>u=s8PIED~A%rw9!+Czi8;Tk;{6lj*j&^vHV5DcPsm{)*x(l%?gqGC+*V?~EH>QQiql3|t?$KPs^Fl`o z=sB=^hu!x*t$6eDo|N8+lF>%EHlng8whovg;D-nbYn5DckWn`Dp_ zBhTDDXUFtQ2gW-1Im7*D%`AO8#dj-soNTBDDg+Y;z}X*0@Iv-$z23jpMf!axet7qa z0oKSh+ojP@)|)&6IMVd~)ScZ%y;MxJ3@6H9|c75Nqq*143zIq9l_1D zir@p;qL`t#Wy9lxm##~)SvJ-_AotsE2pF)zOt7=sO?cx@K_UfzOKmFoMBDe8UfcLf z>`GWt4t2%Mp*&@b*#GKtDF(Z8at9eyh057AoM_0Ga|?LIx20bHs|}o<~|`xp?;me$!G=!)&(e}1!#s(Y{Y7` zTk)m7Gqd2>%orOy;MY)Uf|@Aag7Nv{ zD!904O0Ja*z>BX1w+GcEo98Ur#?z=mn*BXWi6F--TYSoxwP~~ugIHe$p3$$Wd(tDM zein^7+p(8cZoP5nL6))JQW1rSRcvH?S#JRe^}jFk*)0~0uP<01W)6>4f;pB#O+>;M z8|bGP?AJ7n4dX~=4OoYtgAH$XLVgR0*U@VTQA~8%oiTlA5kMj|@^m$h*i9c3R*+0^*j77xa=7Vt7Ez+^2reRSkxvO)N-#>f9h}dG@tb7>( z%NAmoA7d`V00nEzMiDlT8)JV==dtI)&GE3sm*Vr3fuRHgzNdndw%&$tY-xVvBIV8%jo{j`TX8)9 zOyaM27|)Vp%E&S66=vageb{&%e|c*FQGG)$Xd!P5+Pq$&{4uk54Q4#P-tyiNBNxw? z&GY5;>ShVFU!m%;uT7_X?&wK=D^gv5tO$=@Y6n3lFjpvCymTF z$XT%C12BEDiapFtPMOUYN16!%)MNV-wu5nEa;k3z#Mqx)sh;U&E}5i=yHPNq5HWiN zcEPDvK8{Z>$-O)!gK^c>$JiQvXA33-khON)0PpU@8z3Zhc^%0)x0u;7=wAvDvaqS++C7fi)0{u0XZ$O*SCyvE^}A zYn3(O51RQ(7{BaJ3S_ulFJ9B&88huT?uobhwZ`E`XOArzJ&ZfJy7v_QIdT)#8ruxx z8j!Ke#}f5ZW+tc~9Mg(TSYE`l2+-0nI8jv9HiWla%aQA1@1LO;7o@_YH=C*5(R)2H`GMp0bieGM4* z-$Wo-9!=BE&0Dss-$7mPU%!i4@HDF8jwp6MEhWM?iYmmlSH(ep*eo~tdpYHen_eoZ zkT$>e#XcPRX5^Z!IkM{6d2JfW+>MIlhGTNfN+s?f5$?llYU|!6^yWMD+zq~ff8M1J zs2q_GCpU~aP(2FmOrxmEiru?{Zp0oh)y2-L!~H`)2I!1q(nE%BR49HxeNfU34B;!k zwxZqF0kh*dQ^1H+c70==+;MCDwj2a8KW76F{0N%XF6N2oy5xp%a*RhA++}*1xCoKZ zPu$pcDz?th7swh8xP3)FJcB6hVm5+EUje*QKLN*w-vPf9%RlSCwpE(7pbHj*lwo=B zHd5l#z0C6r5dlJ{8T7Bw+%zY!W_Vtz@B@QM&hjgLii?AyX~q^*L%Fs(_$vXcSl*RorzSh8@SQ^!dn=RFBlt-5&}q_-OfevouPqN=g^ET8 z6qLd@YnPV&$mV6*0$64pbbC{R3j!| z*klX?m1{4mFnEHCw+u@x)on*IkdEy{~Vws>%v*Ff+KTj`oTg=dRdCpHZbLGO+i3 zORo|mh&(09Q%LRT0E@jF)QwtT6e-=b>}&@}?2JS9vd3grg}u*UgYDq#gpFr+E>6;v zrM%3l9e;8OJ%BbN-n~nk=7UwrCKaDSLCKMqt34p1c0mwpNhHpl%WK{#x2$;a;C37v zCfuH*}#U%C1vZsqp!`Z5}kM-jHPiw3>#X$Zldb4z3 z=sJIpC|=5krq2x7yBO>Z6Z)oYAB{kKMMKJ<oGBs zq`>ofwZ}h{&vR4HaKK4j5_3?8LMdr~L%eqfxMpg2F31=kf}3sFnIy8x&YukhqQ@zU zR0;Np^Y|k%Zsi~=*wilsSEj*p!*TOv3nc~LwKZO}Q$A`I9lD<@ijO^d43Q?l^Ze`n z#0G*JtgXR)10mOZ4?>S#(YJ;T&2;UqnKxRIpros^@3KRBuhc5HWnIg~1qq*;4c5ha zgwZq*w-eYWyt9%PvNs;sm9Rh#9)wT7T%?9UK6vjIH!Q~@_NP%_nEh&kkC;`%)3B_5 zq)zsY`;z0GL@-bK=CaIkB;2RJXN)D|0Mk;BVo47fZTLyE>#gmi{u+&L zp2ODzT3QXA(MZ|_ZshzEup1o)*kAo>>6Z04k1BEQt+<2bG`Q3%<7O#T6FJX?@TW!7 zRoB7%hs4zNafE%&RKWFe8cJ5Ce}n0~Zf*>6Z?Vd@0%1)G_}W-c?w32tR%hZuF;WZW zC;AD37v%$$>AS@m#N88y!E_ToWHH;lRvw?9rao--XF1eIqAb|^3PgUKaf8Q2$d`3l z_Zjpef6bk|VYdKco(qOyVR z>cJl-kPiL0O4FYx7+7WD_r;?Ml@>7NuC7N#2CS9-Rg<|B8XPP7GIRv)HZW5u(JiWtUF~81 z+9HNEAFz4zpof{e%O9dg?AwhtD?)Mm_8md>Xpp$d0i@ zB#t(i*iW)s$sWs6I0K+tlb&{58ivc8Gz0NL&7yO5BP`ceW;-lp8=QRrpUBACQBayY zo8Q474y1^kNdDbN5Z~eDGX#R*pXz1+1FEq>;LN)5ZxaP_SuqVy_#JszK#QkSmr07a5*% zzoXhbL4 zG!^$Vi(@{cvm^F2;AdaacbgPBjm2J#kg1+s)2QlGgi+CAa$VyE&FD*}!sXGEjV0K> zxwym$ri4qMsLI`&QsCt^##_YWp61-LKfkTFg~%$Mv-15>K*?@xQoE|T_D!m`zw*Er zHdu^(h1{q@&KG-g*DlElgli+;=a;T{JoK6YO*j&ADMl{5cQClylO3NPVhArlAnsy( z!0^yjgZiNn9|c>gS=(NtBwT@JXlc;CUmvra0o+^t4Jp_!)W@`@YaNOnFu(xOjbV>7 zHQMVD{@G5A(_+NKr8^FK&irlJgXtl)lQLm&@N^z(LgAV(62RVW z;10~y9V_Jz7+zHI9lnHA$>Zm((fYqCCd9gUUn~G?U@|5^5U){j*|2bWFAtGrfzGqb zT9>s%v*GX3_K~~3tnsew$DG3W-o(xY?Uq)F@U~fw*&*4oMJ&5~an)K#4g_Q^-HHjdK%dg%-OW($KYS8N zExBg9lEKW1payrV;A1e=Mag-;=+jr_BFk59TIXK zJ5qyEx#lM}9P>Jm(gNeEB}uEhX-;hMfKu=VArq@c)Z~e3Fx;a5WxXBk3b>0$AbvN7 zhYD?cbG!DRNv97ei!ZZzG_|jxT9bz~A~O%TEiC#-X9)hn(++vE@+wCGX@A&-m|xi*hiDBU&f+a z3sDPs$TqR;hbK}PJV1k2yYK~8ZS#ntDi(9?!$Q8Tn7dn~;8v%Tn!hqO?e{)<^K9Dl zewgzAjF?9_pnJG$olFprR&Fcsh6yME7BBBK0}{Y%Eck)Fx|s@RnSpmHYiKLn1B(u* zu%lYRbckiQp&dK|p~!w!&0sqqnYekBjg>VTk6E^z83S0@u8~R5ni~-&{N4zJ;_?L_ zoLzcwHUn_GuR6+3E*L(%j_74U-Vn)t$U!@?b8sDu?v>XQ8RpI2Ci^5w9=uIPJ4vxO z&$zFIY4ai(%?ttF;jCx)o?j1fBO!5nx~Uqba8e|ga%x6Q zQh*6)6F(CVSJ=&Uz?XRh119gF>F_T}-N1vW>|wZ~dBz5{e@=b+v8{E6|M6wOlu$+2 zM=?yxxYP`u6uIg>dXRoildI83OOkwa0-3Ycxr)9nLL+K5XBUSma_})#15{i-NWHSb zyhWJY1&7%bEM>=;7eC%*&vuo>AU_OpLSk}ISck1ah&xHhQixOurofJ_qjK0yJEB%U z*PCXrE)zaHWVbOn-1S?m`F^ne@a6sIMa5NUm{0eki?F*^gG?5a zc0jid)ROjiQ6;rLxj%uQ1Vj4qs)(#v|9L+SsqP2Cu9BHZy785sY{NB~BYEP#SPa@9 zZ(!JYbn!LUt{>DqoX~aza*44aA%qXfx$fI1zCU2Jv6|MhaxaWNx_ZEMW|4k<&En$$ z6WCM>Z8~c4rnI(QBWJPBL2^C?`Cg)#IKq6AHB`{~wiC1w&VJnNn;F7`Zc2C zCHxI*{51*x-Q}>cGDCWEj-Q8Wwp)NBM9}?$W5Cx3-0wEsPoZr+h|VRYBj3{oO`{$@t79mG<*WPe7uW z29OwO98G!WwYW3!U{@-)XyZl&-*|4{uW_H3k?)`Ou%zMVpXcz1XjRD3i|Lsf<*qiN zwrd75_~N_xfIIH-2B|&|#$W~VQll%BF?s@Yk3W9iSA!T22i?SdatOG4+2zw9BWrB|R(Lr(eQm$CqVuzUE{&O-G|FhXX zja}g0r3AylxQ3l4*YzGTt%?`)V&Dkw`*W43Y`}PMBtOF#yaXyv;}5+p?}tx!X~H0>s2I&}<4;hZjTd4x!2GXOdHwa?n;o>pkA005 z0<7^Xe?YC)yZ4W1`v7_WWFzFAF6c|raUC+gH(hVL#w#zCO#kTZhDBw+(nJU4gzGXe+>J*{WEXVHVwN; zFIH=Ga{t9hRUs&uz=Hw0WpML%mfkly;<1OvHTLWi+G85S&<~GyUH|0fY71@8lMp=G zuQ3G=5(*G@eH@C+KC|u@Z@#Jql)CHBR287TE*u;)FF41bSRf7VNM8+%cy1Rj`1Qx} zN0M^^}O8VIWz&T3JAIDftxPGYY3G6{P9x3G3VcjKe>%E z)Y#?MYDTt+63SA5rVBd^&@*|&{=LE$yWQVK8L%*+{gbueMp;?~R*dd9U;2hW*~y>! zaQ>~&{%^j?WAR+8{;`FLq4H0xVKajZ|G^*pUPxN!N6sxrDNURS#Qhhivwgk{L=cHYx^V8|)5j=!^ErZRT(&PF+6d_sl*{5dkh zBcjTYkU|=79vHj&AcfLyI}=OTw8&F1?C8F)P7{X&$`;PGgqBrD|-_jqD#qAm{!(a8i17X%JazBf7CgoY;#J>dd7Ahb!I7y!LwN<;g3yd z)5Co7a`1Y-kaEtax*uB6M8DlY zfdy&DWC9*9U2pfpeg~EHxG8hOjsl9>HG#1A23EDeEv{CXfD<`*Bh6GrVWMdng|GY(jTBTHjgPO zQaEzseR;ssw?bVgP4V@p%>xYNmi*5{>0$17OO7U{iMk-8_%$^>W=Y%4 zMH$Wq`%>yO)dKf)U;E;IE2)Cf2RTXT#!h9l+`*_3iyp{m5WB{{7dFxR?EDR%mJazH zOpvBkA=KP3bAyp?a%bAm%CnV^qoni>qh@2ast>jMTSdzZc`c#tjevwC972v16#D@c z=P!u*5vdBp0q{X#0FJRU7(e_qT;qeU`QE`L+CShaN-&&Pt6BDadpO3cb8Nt0;>+|- zWwQscJVB85-#JBN6)9MB%Fpl<;y#!?Co*9Tu0IAt`viqC*u#Ofp-iMFPhW0hCAUcI z-6A62PpVqzaiNh>uvsQLZepsw3~6oh30mGVCJ;9&vBmj_(v|Fmyui!9Bnj+-4PzU#(0&Wh zfB9%PD9`XGi~~!L41?W&nFmI%a=p$%bN^-K45!@Vsd#OpoPK)d@{US1y{WU z5b$d6mG3>xg2SQl<`GJ0Z+U>Z(Y|1GOT{x;cq8=4`r?*=@Z)O->)E$-MQCDUr{E@E z@74z`h5!CJ`z3|YQmBe&jqvTKiB#oH^pI)HgZ;lC9#$hKKIM{HSVhnb+JZoR!*8@$ zLA~*b!WraYpT?d4i035-8{uaJKV@&Z#u_zbJu<_;p1-R0GfsNY+2BtBV<#pS_83wW z@VZ=%N$Gi^9er2Bmh*rLd9RucNiJ;Znb|;qd$C)Lxt5t@+4p{_dqQjG#?BSTQ>`5G z*UPgre@2W^54-iKinNjbs6;oT&9As5!H}F?2fOw9opDd+U%SXRiHKSOgrJ=eC$YNJ zax;CkLe+%@Y5sXk%wwMSK^5@T!n(t{%=$hUNaFilN;#_tNa?WK5VPL%;2GJE)D=RQ zDQ$#_%mEKNxHwwrM@j|2VmT1a;6(7o^-P0pN(x_i&!F6l`wjzmaJ1`&L+=EBihNi# zbhesPoaTjo+t&RVU;sS#UQ%#INfpLrcuh~_?2&q>7zqE^*I7@*2)X}dOjKp6Aa-S* z2aRq>YZoc)MWQMy(3~a3rT5?0`gQMz2-;rsNRmDl1cO!O=vvce#XAwHsh@3$<+L-%LFK*M>IBn%;w@W$JM-CM$dTn zHP(Zzt^4IKrV<3v0B|hcs|2Or)aUSqWw+zoj{Eex;PIN@-S^gK8&F2ZantOfD&Tb% z*~bUtHF227Oi;MZkt;N2$>|J@*ld`papRNj%{hCyejo83)im0|$t3Ienzt!n;gDpJ zJ3E(3Ae9tt7D;)6W%r6J7OmJT32N%|*0BBNn7bNB_|7&W#q-rFdkEshWkQ_OO4SD) zWysx%;2J1eygY_#;m$or?geY%H<>v;N<9J#1^fm*v2{IArCKz-ssrse9 zf+e&#xqUF8)Z=>9v5RpA|^*9Kw~LZNCe>D`Rm&>fFx0Pi^ZdNertd!igxUGf{hV+{Vhh|c1ukdGmLvJXGaTAzYrmQA1=*DZ&w@JlUkeJE z+hQ|#&X&`PSNKG zR2v_rj*VS;gGndpEt#>wvU3dHtr!#g+Q}`)b zD+YXMQodNfBx+mSdLB=GuEBj_GL=SQSB*3(|Y?Mqh|hXOb|hIP1K6jC>CDtGPs*xH(FUm9<1SF5lQ`PUJvSA7SWJ{)GbMQ`)a zzhlu&nOkzU8fIUI%w=(qzAMOq?o@lXG3~==agz!so?4kkhTOYtuB3$@;cS{LM%=5Z zQeXI8pix7eR`@ZNixf2p&MJ5g?RQv2gAAwSmh9SErdMA}LwDdH`f8$JuFds2iGtS6 zTGk8p%e|hVixl&AV2ZeU?p_|7&?b`FZ{=wq8E!-1jw<{&R+c&MUjU^uSxX@wUdm_foU z7l&3A=>YmLrX(~iu&)qOUUNEJhYt>FY#kZnI-n6=96&q?G|AYbR53E24oyJN@5Zws zik2>pUE-H=y0=rjO~!@2*pkOs6n*=~#&ETZW2{wA7k~1wS_He&sZibQ6#co+Yx>AV zuwC!l1COQl@a6!)&mWR4jPrlJS*k38!sIT^4KN$o@+nz2z^)AWYh$dx6&TyLSRBXv zt+Z=#IdwyxVC^>-dz;&O#k`f%A~q5g0D)X4K%G`jcD@thvzv2+%(ubrkC7Z`1#Tv@ zmACC*rqVKhE=@gvNA{d1HaJZ*c=f@tjsahGYBNIe&|cgv1-NH=YQUc#{b59H>7A{0 zW_V~Uz@0D8hSwQ5VSm}6km1#bgC!O9yiUL5BV(b znA27W1S;cH%AnaCD;)exVuuGj%RJYDI;EbK@$=mWfU4*w{iaM@yoNK-k75|-o>Ga! z5Cv{S3jZ2W$(mA$4PaQYl7@2Hgvh^Un`amdEIxf#hj{C&8c=_M?PS zR*9@Hgi!^<+Y)789skS6{!+@tsdBZ7t7qF2Fs}DCWg_XwH`S|%JX9+zl#(0 zq%Wg9rgqZ2Bok6jou$`GisiGo#g@#kTzOxnvTpfy2g^t^ZS-pH!&6AB3+&@Sg9%%F zdN+YpfO5{nPK8KOaZg3UQ;6s33qRogYM;152*cHfX0cw~Z_OH4;E(yASNErO7NX+6 z&%TmUv3A7DBexl1%88C0J4KPFQxG)q&8cPeV~(tn#0hTveWLU!pLmCJN}SdFjvY6K_G z-E^5hOn!08fbpU-%wJ!{M=;{KdK)9eSh7|(Q&8|Ks%|_qp{Cp>;~&LwF3!k>w`|X< z`2IOKRWC|U7G&^sNUd3PR=Q_cgEME(vA=R-K>+HMZgFnd^4?bO%?3>>tp8ieKOayt zdNGr(&O|&=i(cl^ulEwu(MAs(LBJkJ-stg>|DVQ}-t6tZ-@IP1?TvQ#y{r>62?IKS zD!@A0_Zw#N9Ju?VislXm1BC(EBDa&**_(V@fG^d6(*G%C?Dh12OP)U2J&uD;+@vNz z1FYBR>uP}M{&g3P4~erN28?TK;ON82hYWc5&vPZQM!TY1(%{;Ds z;(=rrG(8%H!^{)T5^Iv6GnX#` zx1)LsCqc~@vErT`!Rf1W3-*BQM`Of4h`V@3^YZ?UEJrk#hE;Iw2Tj{!NwvfbO(m#g zv?{CsLBo7U0+VfieC^KDe&mhjgPjn;lz;ls@cBVl;IJW`j{k6Ld*kGf0U_;|u7?nT{l9w{V8 z)~`-_llaH06wFI6O4H6qa&4`ijZQnGMzNvKV`ccQ`z-Fd{(S!FzN?^J&Nil!Yj8DQ zdaNW_O}FM?<9sMzku;F=+uTL!#fIW(aqD^Qg=kG)AnSI|MOR+nvdH1Z>DGJ#sF#%|ennqsbL(11K~K3wB%TLdJZX*zcjJ_-p8J(XQje}_R*_aLcv0R zhRBLl^HFkn^2h5LmtjRUFI2P}>Z2X~y;Z<_lQkkiQ7xQ}d$HWI8>oC{J2s}Y?HCgU z|JB4P9Uz3W;lVpUpR^=65#{QdWq)VyozvfnF`4a0JcZvIw2xZy<)6@H7xt%7uxm)v zHQ%8c%1kQiH#tdpvZyo8?&E%sie6fZYnA3m;ESgUT z0S$S&q|uYm)C2wHF&c1F{A5^AF^@D!S0sP*Lx%UmMKv+RdO?WY6j8+1n^paFoqoBX zS)^ie(@i$6$1Dr)IpZA{93Xt7^mx6eIkAv!#wxw4iK@r6Fr+esAh5f1ML!rup#te>?6y2$q48CLewD@Z=~1-lACt5_b7X5^sVPR`H^df z)sue!xjLHTvE$Fw=z~nc}s}^rhL+*T8uiBQM>$ez3OfO&;nwG`*~9(%^@a920^p$6yA3* z{5Q+qU2+uOauEB&g8H17_*)ny;|<4w){R!h^9N)zYe@;RZ%3bJPD(9zVlGT>KdXr*^|erLI4@$J@| z*p=4m4>_}S8imYWo=ca>;kUuUS@0MN*Od339iGU(700ZaSp%h38-mrlkL=b?5y>Q- z#v!v&L+OuliucDTz~pBsN-==J^5}E!+!82NlI{qWO)x}CeMmNV<@8JqUVe4oM+JJL zn{iL;ZL$wEv@|3Ddt(4Nn_u;8)#WI8(hT$`Aws6Z$9b*Qx^3Q5E)61%N~D?B(&_qRZ-wHw}hF!ESLGOO{Tbj{1os1w&_KsVB~x! zzt!AS`KjOqV$e*W%*@abSRR3Vwn~2k;K1Sqc1H$6ep~Vj0r`8W{rsb|?lp&nDH-Ep zCZq%pBy&s~hH6JtE#ZHoBUW$KJt{MCxMhRzNnt571+4*>9mecW{ zSM&F`)&3wLw%FQTA2ZXls{Pnc5~2xBl6T|wSuG++@v<3mRb!H$n006@6s^$;OUa%k z24CKz)5eD;OO_u#k7|;Puxft^Q>{oXvG-3Mw7>i~#XQGwlj(QIaK2rBLI9$60Q3@6 zEFa$1t$5YyGA+5>ORnzRwHR>{c)9+BGtJ|aNPoL5hP3&cO-?RSCNrbbP*UDLTk&qs z18dW$O^vL^3|#k#9niM`QzaGt;xutVUwhhbv_% zhOEc>rez=hlA&#=Y=c85;jDNq+7QztXjDdi^g?TQ61Baod_cE3>PnAjD0U zUACWU@RwiT9DV=8QIeE%V9oz2pd{?dHM$S28CaijQ;8-t1>@W^<9O`n-wTmuz(qk` zLqO?RW;1xeo&iYIlu_nBc3drMvT-TKfY7#gwxjsI>6S|R*1r3Gi_kM+gY+{xsFFYV zGAby)R5mW6u|JZ&evAwG-8-ax_`IKPsX;9m3-JB;D`^eB>>ET$FjrVvQ7K~XdOb>) zh}`D)UBAlk3VuKqzb$ri4@3Sv^+V1USc|ps!-$|=^<~AJdrFFIVIHTcFhfTiIMwhA zHc1V)+FO%MBDXJ~thm6$>iekSIdpE|v#+*7o_zLmN6%Hdx5rB{pau5|#yuuI>p3TI zQB8v37yeB-^&!Pp^;WcQdD)of^OWL!+t5)z3xzyQpXeI0vt3`q)8~o0b|9nvYs+F& zHfFe&n=*zReH6t<>zhIE=Y*Pm@+k#2WQu9p=jl3wsyaN0^Mf|8-TAG3AcedFf9@-m zX}r)FWO9y7e%~5xcy`Z==61dZ&1gDH%awcN+J!VjVGj(UE58Oxyi6_T^qwgGEODZ; z{YZ8OX_9%|UM$ZCX$nbI<5;>}bLvOi;HUVhhBFT*oMaeXLDodebNqbEQCkf+)6-=5 z?0%U2^>x!uN4OjW72X#Zg+g4NLs{Lw~9!dPBv+Ivf;a_4Q->aPCjuhDb zy*kxIy+4Dxan88&jsNu%Qw+coW0Ly&%JP7LgVXv>`=!V@V8MBI2UrWdkPoH#SOtuX5 zInul)*~T<$W~I&nSbQsi1%xM#hV{COwUwdwzWvb%)fxKV#X@NlS%CCXmdM+e9sZ31 zlC2`^X`o$nHn3X1Uq%cs_Lg|p6?0E=USz&um2DfixK;o*naRj5;}9!it*0O;Yi|yH zq+{z4x@4@}{XWp#H?4ixTfRZ<<;y7E(gxDQ*=R`z$nc;sTefF{yN<>0=L976bizo# zyphoxyOw;6-(?@vj?c;9JuJFcu0TaU8_%#3y5wW+rlfZv z|2>*(&!%o3()_;rJQ^T;b9006dk?cBY@wq_{dtF4`>g-K>4~O$%>c}{s~9tz|2^KT zIMdS1;rDysQEw}CwHcYR*|p{QeaPkGl{x2*iI1SP{u0Bl(1*bOSF3KTH)^NWJlW^N zkZ%qUS2d#IDee@kIE&&#vO$s@k1`EH&IiIijN7S&0-*e+jbg-5SO@^}M}l7Pl%*sv z?$Pm(?7iQ^l9mX;v{$nDE);RwvOIZ`+1UT>SMFI8NEdyN!m^T~+J zVV-2+3K}xHu1{%Rdn56TYVFGsmOm0-tH0Li3r!hQFRa04 zJ#fjh-6qI~WPo*@`CaZ+PZA>hmsm~Zi4#k4xFqc7Z9ii~b^ z|H{4E^b0PBZ4Xi8a^4#@2{Y{kY$|#v z#a~3T{OaPqcYYirfH=_M?B88; z)Ms@xdt@s8K8hvLIk&xOr?%oT=SfxzbOIcnq}#;ZH>X`jv&R#Ak30rW7gJS%r{ZFH zQiFdT2YvM`)BdsG;%g}oROCn3-B-W&jZIg|=J%!^D*lMnZJWUV5BAb?7FY2KwRZ+nNklum>5CuXNA@ri6qErP!uaW>Egiw;uK}117S|AC8rXn>2 zqy!KM+#Ni>-}BtN?jLvE^}O%9-n*`A;m)4eRXRXYWM;<$;D2Yt`n8zt zGkia0j>iINgM|ZzCr@1KzW1jSK*BDm!*i+SY>U#EIPJ3UnQ5Zc*TA>g0;WwX3C+Kk zc8jEoR_h$AddW3wCXH#l4IR@5H=f0zPi>|SawsYcw%G?#oZESP&WWh%Tq#@A31S6< zJR30WK-rw2*<@$$zj4*g{HQOxiL^kggd4$qZPoHFgkc{6{+I1>Kf><9q;Vn^8eSZn z*b~GP9Qn?m0Ol1Wr>8XTiTlNemU~BbZ=u$ITI@YDO^^{Wx`K&_efWY_^SGL}z%@aNug>o87IjWq9vVI>w z&`dc~8h^~TQ+ATpI&wRCbFJl_Bcwn-h|5wBE-wwxHNip5M5LI@)t3;^0shTtG#AFmdxEt~r+G29_nkx2}V>=;0VDrRDw#2syH&-hF z8e3=6oQs{5VFkRS=Zr?`f{93KZnl>YuiksFne)|J>OuSdS|3c3%=ndHaVD_xU{e9e zeh^OiTq;yHz_%4ES!+sjVcFe6 z!par?0fE48PgOLlACC=gSps3MsiUHxX?G)u!oQj^*1Y>*ifQ@Ty?krnQkf=6-R;79 zA5vKtWdrs8*ua5__`Qv&7bFx5i_4$pcY&K*?oME&s%ImdQs97Be|Kc{5|9mrPu zMOj1K!vb+OW9+X>J9vcrkU1$1ofKr#Z_f5mEo35opOS;$ZIR^cdfoQ} zV=DfQeN6u>E%K_ni4l@KV$#L7QT@@?4_5#Lq+QeHl_vf;g~dij;G7_I%o7d3NF)6m z;Co!AIZr&pya{O(X2+wG7+*p6v##e&KjM>DqK%Btd>P+cy;K(Ffvj#lndWcb(#aQKpEGjK2Ycs!e%6>q9SgboZiR4eb?6Axb> zQbnft01hUVO@5d75a(2Fjn-tltTI37F#oN{GW_d|;!+|c6$7`7IM7Bgl8SwX9tk~M zT?pV0OQ9MZC{)mrx5G3J&u=;o>53_+UcqP|m<;~C-I-g0NA{4=_D8T2G?N{(+sM=J z@1c&*z$5WG)}@0v0GM$}>>p=jmj#*uR?)*q#~dq6Lx746$;H2)PyhI1{9A@;SIsXW z0x%0BZh&M2Dz}oF8mhzwuK6t6;F58Tk1h)Tc9vnw!W6M}Y`c7+*rV@RbLA zG{S|3Tg_m#L|vFC+6Z0WhL5Mq!a=Y@{$_P*Jh?#cVAp2T2o%?(E~J~RbC$N|`=qh8 z$O==>ex1w-Ffi+G;uLHi0Sd@ z(pBu`GW=&c*z*%t%RJA!nssSAvG>W8BgeIqx5_F_y_v@W+rMWD8QgJ~vwC|Xw&PycVXKDnDPRZdeuPA zkQ3f|X8|I`2o$&kC;}n+l+643zz7{||IU{6JDYX2{GNsJXE*dGURw>7l#Fp)EIG_3 z-W;2Za?wu383XLL28cJ#t>*xq@IGc~bZ(-YP_WNC(a`3Oi=cOo+?MPCsC9 z#rxY8IZK@;$NlJS*L5}$$$J|8@Pvgg%?x0Y7V6C>@*iRo?fH+IaY~1Q<}9HRV4wrqmLnfXdvW^rcxo;<{07ws&1DI+R2Xr|cT;Py2>_Op zcj?bU{CkM!L>i=xd1%;7=V^!CPRKk17*ZJkDZ94wS{5DHNP=_mI_Gh5z@W`ef8MZV zNNC~y)DHAR05S3GAr?5E8sum&V;8Q`2$G*SSdIFXEQeF6>uwl-L{L?c1q$)1CCO~toPZT>TYM*Y!)z^$3k0%#@j!hwlwOj-zB2`!*#dV(6m6nyz-a#M4AqC zDa?$mu?ft?06d8hsmy_|BY$~eDN}C!*eBI$kpKcy$S1n$U^Tn5**FS&KB(*QfSL$7 zPCr03IVOic80#jS`3$?D?-sRD1Ug@*{KL}4+M06{EQ?gRCtIJA{QGgnfdWXo#PabO zas>!qbjsS5vj%lq15grzn7TU(JDAT8T?n^ER|P+R?*BLh(ozM|Fjtq}$@|Yf4g%sk zUt79D(SLk{457atIA3=1j4YRBLI84Vc<#7M(VVn_RCe}{Mne}pj;5UY z=heYa^bm|={L~PKN05Uh)7PZSP>)cK=u=~-kE3pB`eU9&lomYJQyzgot!OlQ=^h)v zc+(>AV{-Oy!e!ibnD* zlm@WNxO9@vO7Op5vjZ zK8>6b_4pT6!N^Dw+4mI=MXCmNJi;_^S8DU*zms#2I$55lY>K&R`MzkXn{9hQTaC*F z^c}~XHt{d2gFlpdPm$A=T-r~1!*#C_vaLMK-sz~nlgGZMy~H-CssBXLbj&wxPo_gQ zt|e8gaAI8Q|NIYrH5bJjzPE%nMn{-ppTi$>Aij;MkHFsp25j9X5&7H2Y@W=>+S!2` zitrD!!|pNy*c=+_+;|JwP;`?oJs1lX&b%4Irp03utV`06X-F6OOqqlmn(&Jg0F?l4 z9P#**xU%6y*ew8b#E<|(f9V`*FXZv~lZUJuv&VLIB;N1_m~nm)!q)mS`~@6w2l7*x zkRM_y&rvpP+!e_EI+;V|75gZdW^L^oP44wieoQdoBk7BNF^aBmfn%G}v!mB{1$Xk~Vy+JqjHoSqb zT`2%@TzF8 zgb780dQc0)fmZhI#{27;3V(_$ak{K`0WHj&L@oR z^y$dSi{!St_8J5=PzI;9sypfhH6%?ooar%md|CK>nNL;l_cK;Ke+8#m?PytV--DjL zE|Xv7=|Y!q)qbZ7-G;TpdW%-nV)+pQfZj`rm|GY$L5{Yc$&}Wo9A)i zQapoyWe5Oc!MV3Gp9j@O&;<}}Gr?(-s~GvWud{=VOk-S2E}3;^*Cj}?y3be#>i%JJ zT1aq#?op(G{#dVLrH`#Td`9G8zxnyHSj}w4AVbP8-c=%Oa1nX{trIuR zo_B()SE5aUwP=&m8h`=MBCq`Q<5usU7jG2}dQF{1m7eK0Z>ea>8TX$L2ew0QTKw=R z$5m(7C6WF6h--PG0fb$)nd#);Z<;@U$Fa>Zg5Gu{yevGXjb7_LoZxt#oQFKKmoRdd zfjwohmrN5ZVS21FC{9x_lerB=ujw;ijEQO(!|1 z!*k7|CB5_$TGC`5Iz@(c1vQ3Q%TJ=;$>A=_vTtQ*Gk;LrN30Wa7q zfCLzOUL)kNuF0=sUwOX6mfLuuZU;>4L4WZ7OGXiRoWo8J{*-3?!*8himtL;PR#gz3 zh)@h_DNPt0=f-dyHi`;!zbANQq%$4wK&b;qsNlwlkA$@__#&^(N3915i+O+n>vPH# zTn(O6bw<+6!wF9s0gb?sPPh>!yD4o(1Y_9xCl4F@5C@=Z7lz7@ykHOEb65frT8NLv z3_P!0dkH&jAx~iAxL%IEyHUWt3iy2{+R3Bz^7ficj?UdEBTI(#)p7X4#t2l)z#HerrE0i65)z>|FWHoE1(g#GRmj#Aa2@Psx8<%iW zUBi(KqYhO$M9?pg&bi>WxG>c&x>faO_dO;QS|OmXwh<}XiK)hh0?AZoXh_1z%pm5C zS0U3m3ONM>>92@FpVivh1Xdf=MmhrogKmj3zc$c>#ef+{Pu3<^Pco$FwN=zfAw)>s zrI(7py)sX2lv|n<398d0gYoI-Sz%cJPmQ?==gqU6os`csnEu&ybv?59*xMk}IYv2Y z!cn~IYN+Ob70=DJQkvY`FhZc(z@!vHFNo`h)#3h719bb%$}HZ}LY&CU;u*`POmw5L zNz6(mghqejs#UnAYH*?JYKz;}{F9e&X~2M{=IifL3{ShA;`{rK#dRek8CHfgD_noh zI}M!T`;@#!ZdJ*P?VEDrv*ML3zV%9OW-}efO}u^(9J!w-Rop0Q95Z9Ze}l);Y0l)Y zuB+kGm`Kkb=TQ+alq<6)u>cO@lUq#~l|#gHXeQ6#_*{#d+(fx}pa+8DoOd5c+%D1=^s^!=hz%ASV;?0i{Y*Z!=RgDu(g zSYQ0!3lZw`Akcn7+tXc;`#Aj(YQ!&RQPt@#rfxiYE;%RU?05luTmg_mypnnZip;e~>%ey#IwFFGL5nyU{gnNdrTdd#sGR^h$8W@a(vZ zkR9WPqqjtZ31r&tY zEZl5*TowN#kV{P-=kEflY*1@TxKi_m`e6gMVXj=Ui(q=?(U+hp|az- z5b((pTSYQlV~2XW$CRqhj5?tGFO3*&DH9GjIUc@POvv@L)$Y>6s+S1MLxJ{;kRXCPsqWHiNkq7n8SNglxp{*; zK4Cg?7wRr^>xQ0Y&GqY^9(7jaaSvp+Rls0y=Cy^YN5gNU~6MqMR{+&7i#v!bF zr@07HxEXT4IWNbfx279qrb>Q;k%AiLA);bIy7Ha2ZtktuWMm1L$t*9_DXuV}9O`b2 zLTm(BK7I=YQMa1%tA*I26-Mvrp~L)#E+zx_2gU>m&lsGL5ES)UAX)KvJoxPwh! z_w)gX`+NBwGf42^J?^fjUMigB`u3VNEnrUvUUD6O2d|rc5VKrv*4g(!ZZ7rN^#!R1 za*?O)ZI$%)qDd3KEbN=VV#L5se)`^$mUv9DcT;)AEk(QaZ^!Ag8VF!?W7nBCW-0^> z%qP1W6jq$4&+6~}Joj?f2DST`q}{?6?EbC{m0dGJe-yVAogn;8h;hHC*gJbX;Kl}3BTWTf*nxaGO=XNI6Io(kn&;PJ`(%hxTj?F9mKMay@2wK*_ zmxUj~o4%*Lv(}V*MT+*#^Zpf}cRrX$$Ee7}(L<-)zNLA`L+m+8IS5xh?^o$O?4D<- zwc)9)+RG(9UZF{TOr*GD4rj06e<*)=>Fe5hZ1Z@4vy7}^5Yt)U$x(mV>Y;=O#a3xQ z|45*|+!pD{cHSz({)2CYGnSNODra}4E_ZIablg8amzP0GS=q{> z?NI(`@_%X4rmZhA;tSrZTv2N}t_SGXFpVPSTQ!O6nI65;VT{vR<1;lnNkLp55+wc) zTlb*LsDqh%fumO+CSX|-nMRyXx^D`szA$aKtJTpD3cJJDR1mW9ag(2>iRfa>7-id#XmVpe=b8S#A+un8 z^#Z5q=!XXvYsNh)chXiD6?}uXM)?UF8yaeuUr5>v2HF#TXVy| zZ;{~l!fH4JY?oArp~h-X{dNxE8?>{+idK@0n){XU|5zU?rmoBr*UMTdUP;O_EG;{< zQ3wEH9x0q^K;iFDbaR=IL%JNF-9Fw)FFy4z?Y7%FCfg8bJ+_fvP8hk5#SL<6>(G2U z?#BWBt^YcgR50;zlfrmQ_^|~GnrCHG-Ws_<7j;F+7hY};!*pytrCF`IZNPJX4?*~6 zmYU2pJ|(TMY&Bw3O3Cq6s%%wi*uE-$+#f;f{U(oEJ{@~Q(TZ~$K@`B&yDew?-yH4L zN)U1JJ`iT-9>k)V(drApKCaXA4$UOX0_6pCqfMzdny}3@deR84kE4_qor-AWsMzq9 z{g|JQiDZFo<1CwtRIE!?WZoTX8y57tun?!t%SMae(nM{lYrGVWDu3#;&hdJfkY-g~ zM6vy!NY)jv5qDlZ6qx+)eBY`>r&Q3256JSnct5^s7s|aVU2X-d?x!)N;VR!=nhIsq zstw`rWLLvC9wh|pAo7Ca;mHNAOGSd@a1H>0yiE{`x+Kj=kop%?ae9*5l1gXmG17wk zrJ|T#s@CCk8AeKJu5t7~l>(+nl2=3=h2A)OKe^i0Q=`}dMU5pQtm;`gq|CUL@~286 z$3M?i0{5ktMY04$zX2V=w;f}()MO9$oU>+6kMZJ#*`0%yr2r-VEGnq?`g31b?e~+) zvq%c_U7}~Vq7&HI@t-M%7&!N=*^6T{ec|ls3J6PoB0iGg(w3a}{*dQ>C#aXKrC504 zbWeVx$mnATH51{XpL2HLcZL+}CiEzwOjUL`MMJUhFuypwOiY3Od-|+aHdXn7dyk?M zE&nj8ll~K*XC9=PdnQ>1H#6|mbcz`YF)nGyF**)LP*-8s(JR4P^1wcJZ_)q0FjNjV zInkLrl*@wU7^`hluRU^h;_f$xZjjYfeA|Y*e>@|-rzgca{hoPsazWBn29WNCCboqp z+>kt0C^~%tg-$oS4ORu z%XnH46@r`%WdEP9%l~;R&AF^X-g?-rj25f7{&!7A{Y0mXstiXHJ-UZ8wq=0k_PAwB zoc8DrI}Nln@vXeAFLAml8fawO{uJz0TVMObL8o=@a_&xxe63aPoJp%>$`xM%X0bW8 zPWooU!QAYTYb%+Yf~6LgqCK#YE0D;_!b$>nr#n|?Mkhs03a2dPE@Mm2YoO%)?+Jve z;KVyA?q(EoBISAz_BzlQ5Y8zA#{~ zf#){44(>m<+206mHRgZ(l^1iQ@hIoTR_zaD^6@|X`mP@mE=j72;rp8Xa-)yj-)!;F z)K}oIo5zoFiLS(l)Vwa}&SU&_ZLaxda$H7)dPt$uz>rQ)qw z_G7h5L!v_2DEw>F<;!Xnwf^c0-lg2zbngJwpM{}!p+E25pJ zRC9GtDM;EWFhww|iA9{K?toHoN`JsXpfLYu|I16#I;uxa^NR!h>pw>HXnsz|oPe32 zouvH}BB39#*sm;M=R|@Nze6UcC4pbcgP}hiMo#kvy_x;+v&^%JqhF(v zEOzEZStH)zKP4kJGwpYm_gLG_B}wtU@_XA2&zm=G5t^*8yRgNF5f8`T=Zc!IuSIRo z=tUiG-ZYw+*bv=I^aMUKGQ{HeU#PJEEAn4a14F3knCER5^I6P~Z9SeAnNv(qZdKVL z6V?pL{LTc~P?ZTFXl^px&g}oo)7jm|J^>`J4Y3i#%2J$$#wVj6qbMM8B5+J&Ca(MyEBW>JA+ialU$E zv)uiTu}D|)LSco7=uA~RmpG!Gq*4Ggq7Bz9C9gYBvwnCcc2*7KKvULTsaX#}84N(u zR$qpv$aCRp$x0c_$iMrjVxs@m?{-O@0!q%HU0I|J!1VWV1+gtlXs_=DWI})nv0Ct+cCvaO-2Ij#zl;f%YYIjst+zW_tD2Ybk(hl;Z1E-w|v zS^8Hld5ms=+?TeC+Uqk1yY8%K$8BqY9)M`kV;%##vg*SDDvNMhYYd6zIxs11)Zyo- zT8&s+@d^Yy$Oh~CBv;C0@WVoZL z%4eWfBWJ)L*Np?&jw>4`6d_@KAH2Mz(Lze&jhCBm(N=;LHOH%O%cuaSk%h{x_f!)) zdjCOD+i?@3UdI^!JUyTDyr}*7S4+~YO929Sd%vI+H89Nds;knTcP9hCuP~*qD7c}< zXkQ)ZK_NvW^=aL zu6T1sVvcs-#!z?n1-rVkkvr?em6fahu$jv3o3Zw*^9uHj9JfUes`p+r3IfpxH%no?ibs%3YEj6I2qHHP? zzX4KD74P;B%r_eW)dkvB2}1*CR=nJdsrs1{=NWfX@H=Nc<_7%}6`<6_ys7N2dbG!b z83w5bu0B_7M{QAVT>T8!%-W-m^ERAgi)W(y(Todr4P|2CI8%H zv!;-3B!sG^tt|n;57WlknJZ+08r@MT{F0Xt)@DW$vedfM#+%txTD;qH#24x*Fmy)2oj; zj;>W8qdYdc18KsW3Df#QL*oRlz`1WVA%#V!mLeFLcd)# zCiTU;iSene)zJbW*;k6NA#w&GQrm@w+x^6T|9Q7=F<975PkG^BJHw6U-hAhxN~Rk& z13w33fIjNQk@?x0G*}g)5#Qk!48ye79Nl^wCSg}LE#~Gv*GG37F_O`8(|p0*SmrP0 z=@AT@T)=m9hQPGzAgi|_qRZ_i%|ObOF6t%-lCP39C9Lc%6}iXw>L;do-eJ zyXa;(t660*Fy*FouVjnfM_2P3UH=_;ZuD zL}J<6ku#zu3H>Pmh$Q91b{MOqGr%CEl|*R^fci!%O!|5Z-exQ0+EUlDkiMcVMXP$! zxlRSTb)&{-D+HWM9}s`@$O0dmK{n#&p5QqxR1McKfydR8Ea(l>9Cp)*R$<$rO54XO z_}w2I96Ay{f@)6^sa(o@#kLjfAcPJ0W$JQCt)Tl)5*|e8arZK&xi$(alcwAr;7j(b zF}|eYj6MuV_JScBvNKr?S9={)#q*1-bPDJgVXUG=14zcY*w3a~ zBv<%p@2@WAZ1hI%M)DNTyx5e%!8n3|QHF>;^(v^qEt@*(U~f+B{V*SbjdfM@cam=( za1QHQnW6`ihTpq;{lIr@sm_ng6ew$>(Sq*qP#sdK8>a8b`1{^sN>Ddf&f2t?b?3{* zfO}N=gsmOtf=$mD=4yR?mVH_W>_WWHXx9?F3 zhnd^3zJMWc4@ld*Ko*35GzKTkD<|r*^-+0EL^VW3%8WrHez=nk*NiBy!@p4`wS8fJ zV-qXDR7~4Xx_F{g@5eb<<)i0FH4AIzL6DKaJ7vIh_NhVY;tAQh_nrjs;|v5MsWH@8Od{~U97jn`y85g(WkrJyrSZr%pJU9aVTma~ zE{XPGr*A4RoH;S|sT`5z5?W4A&Im9F9z3u(e{$4KX+lI$!REo#j-PO7S@vq)77UxH zayV|<*E0yx>>V3!YtCmZwKN^l2gOB!W z&Vd+(?wz8}W)#9r!xCoy+5y+KVmkEjpiXX-zMy-)JR+=Mb;>nM_tMPu5Pj3RHs-`S zIl`B!EX4rf`Wd-L=@CA@c2x)!Nrs@hua?%wFJgWhI_>Tm7`?a28PRQYGns5}Rpy&@ zqBk!+cs|=RxMd{{PIgozl&P%$1PzrmBIH`86|aygcz4T)E&VVoBr-On z3TeN2BxUUbzG6X=RQQE~Wj@8PlQbFWbOFE_jC;Jvrlw3W5gZJnCCJ=^7pqU~t5zYB zfUr3>J`TZUn&+fjs^_x0@us8~;;^LsoD)FK#oHO!209al%duXA7lh5!ob#-FM2bnY zTrRm$^nwyRhD?mq(v3SX27wDg&ytGZsiiG`}ujzhSr~EG^yD@z(i}Yl-G@+ z$_#grmI06%tkKJKc%V*89<43lk%7A{vmSxjX#LrA1xu8m=Seg4il_csswtxZAD7!o z{&AST6^o>dPJ3-v&9+O}+SG!#3Yc>?S}v=xcw*k_!2H;Kr;D26*bN|Urs#s9WzQY8 zyHuW~fvV7+>4!~%d>d;U%f53K$j=k&-P!oMi*$JRc#+G`tX4$|xeH3V-!5Teb5`rA zes0c`uSz@cx)@Cv<;lChWCcU?O;FfyC##g+pXng8Vb!X{!ajWnOM)nuTNR`O@z&JF z<`8idX6u%nT<)r3qFc7oi1~U(v1sP~2M?5BmEn9{GaiM&MFrpRqo9$1 z7w83L6K$1_PB6FI=^Gc(8}(^vtH}eaq_#@x{Ul*PS^RKs%_Ev*sXOseI7vvuK6`DJ zr64h_aceK>*@$KV;$THX{AUC2hLy`#J^{rbBW?b&suYsn_fm`c*z2_->+2bI*sYq9Gj5&#y0Cr``#`3WPIV zr>=oQY^e8HYP`NpQ%C9Z(~@z3aH1Q=@N-ZnFNHk3;~8-gYfXm_XkCQOA%nvIhAr*g zbLvic*`jxMNHHa#<`#aXESv_$Kl-v0q|Dhhi1JizR9)=;`S5HgElzixied)x^>?CZ z9a6LCCfr-ZK?<#`EW|l>Udz#^`Ti7JeI>P9+*2F^yJy@OpE3ENuB~v;FIa5+QGrQ7 zFSodC>b&IGcAY=nxjH@=L>{I2j!|5f^!Oh9fW+24m&9D0_p_li-^e4;tVP}eOq4kZ3MbGN>k+gtttxn4=4;KLtZTI-)r7ZJAM8@(0 z5VwQkWJ>tbS`QF~S|jPY6aq_PIy(tmX{wl$?SJ2{`n8G;dRQxQt?0)tNF0JbtDUG4 zwP7TP9rO?dWxU^(M7W}ycg6q)D39nR?(&ao!wh>-iZ-nZXd*u`X}tnTBPN=s6cW5& zB{M2*C|pRpET!i%C>7R45r*r*HE(c_pDebifBYKlBWNnoG*gQ*+|MC*I}@9%Z|Z3a z8p*0;xXdp88TM^1akn83S$WQrXu1VsuD%t#Jt9=aaQS2zJ$@Yy(k8w!*Fsn(%ygqz z<|HANH1jh^LrX9>oYoMB?>;{q{=x%=G&Xe`NaeM?Epr^WR1|-%<~goQGZK%>M-CPy z(1GM_&^8)L5@-1cf^O}Rz8Q3MTBfRai7|?ja&$7yx4AAL4#Nr%*lv`k)?0?lZA+rU z(r!fk8#X9>B^(q&yA5H<#wgwbwjz7gG9lEcf$(j3V`z!G*9D+M1a8< zHhUxm;}HafgimN$;VTh0KwB02hU||C>euHYR|07bZ}2m{PPx25)_`te=Ok=ZmlUps zwkF{L!CZWTB+Ew(G_{QP5rc_lybU|PItfVK7{LEZ_%>ym*8Uedh<@CFFq;XDEbK|M?M03+2eHuS-y!Y>;8I5%T!9tE1nGPG#LPR&3 zQ~z}m)r6;I{p)03h&5-F1GXy`JQ+4SJvr+ek8BPg1e1zK%}Kmp~T&5zkvh$Vu#Ir0W#)rtEJAHiJ9Bp{oD> z>(uO=*qZrJfcURi=llPsjiy}D_dI(%2M+La{Ey4xu}MIY{$p8u|DB+~viLvm1nuGb zwJcs=w$KTA@f9NX2dU}k?+TFvH!obcd+4jgwcC&J=S$L_#eC5PzdUX|d`I^CDZld9 zYW$eE=Dm&l&{<;rh-RVYR@l1#a9I*7ZhpAvYLq2=RUE^z_HN!wjo9FcVA7je?fw%4 zs%H4kMeVJs;-0&AZ!wgiAgXRiOMRidge*W|4DuzIsP6+xIq> z_DZg+m4)mEGy;p_f{25ybGtBxUxcyu*WO+k&KCo$)vAH#qI&}yUAvR^m7X{JFRuIk zpS1skOT970=`9C&g_E%PAO38Q3fbcSv^T`B2;Y>Q0EU|VL*>5@7l1_IjC~;f`*2@& z;$ugE_c`023ga$z6O!l#BiaT?#$}@MHwx1|80e9{)~mj&3kMd7&BrAf+ZPZqOXCOV zTkNIdpxlVdJ^NWoF9N{8TBB27D*keVzA5Od9jWby0!aLM00>wyy>Pf()}qDz*p{s< z`HZ|`qq7j*$$@EhgjY{@7SIZ@~|^Xz|kubRmLCKMR3nlL##AA zH1K5sJey@DJQR3#J?E*M-6E-g2_L5ZW}u(ll1MpcYO!EM6n^(ecofp~quzk-h;aMV zNC7A;K+Ymq$rC^3V?Hr14lAveY1XH01RW|04hgkOV#J@P*fIwSKn09=F|sY|39AL) z;otrmfQz{6P5zmWU$%z%Hp=7N@sGY4gHYThJPQfHJ6aBf^Vg1-_ zU$6UR!5N}0+7~ZmhfQQABq=?YKohshL~n=W!5K*knokpQ%r}OMn57#M|)9?5TbD_|}7@Xi0Km$Qee1 zXPXC&C)06B14Xn*_|iW!cz^07)dKU6ipNwxg|Iv8hF>L~<-BvuVPfHEv7>zny!Q^J zu+hJ}*4q>{Etv6}q0dn=it*qrBH*^A|69a{%#wo?#xQ6mknfdc^q#{)xmk8^@R@Oy zIk|0JOhf08M`n?a%5@7bi_&PTZ2kslN$3z4M457xJd&*0vrNgaQ@NA4RmZJ& zQ+DYOYy;yb9I-o+nsTSnvzXLd276^$qM((%UKxH3|Hyy}y=zq;Q9qD#rxD8+$y`Vz z`oA$hYjpv!3*0(cG){?eOjEHr8>uPd(O^+?f66U)pJ*IRbE#}*>fmfgorJ8_b}5n+ z(K|>&S2Iod3%f1b9+txGR*&4duDOlu=;SBf-trND7wbBeCP`jhdn*BLDbY1G?$yHX ziCdn~1CK-$P}r)EfFv04?-zC#m{#K-k){)_q_K7LDbGfs!73xVchEeN6FhQL)|z~~ z?Bd%L6}0wKdNLU`7_>6!j5-_@ojAVF@(ub6QCQLG=z@^s2I&(SWn8 zm90-^^<2VWG`_CuJll~|)?lX)(b{USYVVLy-93RAmA5k93_}vF>khYVDLs0m!PA1a z9O7t#s9sk{DY>0tUZNm+0X?fV6X@=pNLk;qdBBQ$_wXk15#e-o&`1fMtU5Mj+^6z4 z$ZfSmA)*D2ZG(A66vG?e+lC-eG?=NTzJkQ*u^Az6hJ}v;Fw6bK3BrT`PYN~uM3%Y_ z!60Lk>?{x(nq;oJb&3sXU)avb78f8AXYDga${s7SMD3FUiol6?55VneriXyUM~(9T zSne(&Z#+`BrV3g9A`ujBS|TR-%d4<9cF`xkdc9<|KPh_A7x*|cD-aF z3Wkp&D@`EV;WjgIAL-mpYKLY}H>7(mkWhGp`WxTjc_Sy6ZeO%1cU?(zr4g>u-gR|yYvF#QQ{&vcOp>yn zpA|NtW%%{tja(yEO=U#D$arM9R!Y7D(L!ZUgVuoQ1xtjlAJCXv-t0w|+|lfq2x zqhMfHmSSy<3=z$f-qk7G%7gLnCr{^2f9B{1uk5EjC=!5+nsR0;pC0pbz2T`1rPf@h zmEOA)sgx^QRXs%D11?x2xl2r_`F%ZU(OznU4(d4F3&&FL+|@hU7W(9AQ;c+M`%PIveVCd01}1MXdA)Mi%9Iv2ILxsb*i z%VrirYSRJ#&RlR-!@>3Wk}@kMuw^?sYu*aaQn{TGda)=fQG%VxTjz{g{7;$l_2i}p z-Wmm4$<#3k>K`Jw1LN$dDLV`jPhDgw7l|E^}G7~11AY&4hBtV$@ zL_ooq5=bJ6Nt8h#F${))5P^4t^y}BIu3Fpm)_R|9e%y0&?mm0E=bXLoIeVW@PWDp( z@!Fxi9z3bPp9GUlvHw`s!C`RN<%bSc564l7(u1ru8EhEegoDRm%a>#G_BkLYYH?<= zrxy%o>$h>LPIlttJWjTjK>$zUGfAmDC=0w)QEZ?u39;%P8Z@)u-a1rWMua9I0`tS( z-aN<+@?(|`v4XtCLjWVTm`{{uE;LXLG4i)L6j~gTbvQ!A z^LxITP-Xtu(8QE*pgNUbQct_Jif2IOmPlftD{at&*~a-nLiu?}2LTW^R(uoRntB-L zY_p5LeG$Ca-INzXPu^*agnv#abj8i?QGZh;wIOjf4ft#y0^fw*sCfd0czsSs@(TY! zvJA_4#tN3_I5pr56}G%_H&Kiwwb5yL8e{hi?53ZyK5$biv_R{D1*O4v6j@~mL$zR- zL=g(rE}r6PyPk@oi+qUJ^&3uRUQ(8uy{feOFnkP^*M?qQS)n{#@RWa~Wjl4K;atij zp(|5MZ{xF>V7YZbo%{*A5!exu<03rA0S>Go-oq=1Bvp-j*{&+K3rVKfihNCN>|_FPez#$iy$^qGYA8gY zHcu;0OwI+ZO)}6~T8u~?w21oBlz@;8$6jq$qaIm57wdUBWCbLk)bh}QG0TUrfl3cP zamo|sY}P_q+b&eG+nzrXM?Hv_4@X~O+`q)E@@cgtylULE&5j{mKm zTh_!?zoB+b=+Hx4NO|1dxAkJ075)V&Gkjt;SRa{|ybE2#w_-EOnFMAV&clar;}kDv zsuUI9%O<|7;ogfjaz|O(`zTvP6es`)c4wF1l!nyC-R^-b-!O3sDGkr%9ri&fkx;G{ z(+mR=9cUR(C>JG>(lV(TB7u08ErPR@@F_!|E-yZ;(p@gwnJ0S+pPT(LZw z63;}Z?Ncq=CuQU5w@4?QMSfy1()#>Ywy8uBTi#Sqe+kSa;RPEeIvem@!6Lx0dCDUw z4K86z$rFt@ zWvcvkc~EIBFB3T$D6AYeoD3sojAk=p2m28V&5c}hz5NUO?JNDh1-*B_72wKYJdT** zo+hoP1@u|EX^9Ze@{tbYw|13fQ_P;7e_~q}+b(R}MqFT?YyoS=p5TM}*Jnde^v(D! zbN0DbG)Q3o%5zn_2P&q4Hzs_Z41wo*zr>WtlSgkVzvl7GNMKqa0J!C7ZVOeYa5CeL zfi41Wy$FQQENYygI6`!U{L0`m+dan@8 z(4N$lD4rhu#U3KbJuQUKzHa;@h%q(xla~M@%{)Nnw2;Edz=dkrjrl~`wpCf{`hkzB zAayn-84zrCUNLQHkS5RK4#au7A{$b}p#D`fU_&r*K?%7?HAd>|uBkvOVN^eFs=w=G zpLP5CNe0bD-bC=}Nob;3x{(Xq%N;9-A2xlr9X*-P-+{)A^oNP6Bo%62Nae?x@l69O zIfHC~6}!T2;;EiAC;mm|mktF**;icUCOXNt<~BGCOm32v4lYed-axL%J=%pxHVKcF zm}9t|VB$QbS55C*KUUe5#NoSBhgGvmlN}0n@hlLfS7GHHDfNyg0 z5`a%?1mF{ke?M@_4H|0ZX`2zC(zpJ9E|S0TT%XCB`S8VS~Ch{n9zX? z6BYRHUmL75beWl$GWB?$-2d@i2mP|SjJSbMM+*u@^EYi0Xhu~7`VA%WP{q!m7thEB z74sFgS-P5YMOEnro;&wBnSh0u#90#mc*3l5#8{S|(qUTI0kLh16@Pzhq_?Sqnx4jz zsaRKP9}ZADiluPoym(gK97=ZL?wP^7@vl+`%QJaAWSBq+Be_g`w@=QI)m+0u|!hb%BN@PEdq63R5 zCW|GIVq&Vhu$R_le{tObAWzH4Z_VWUx<<_o2B1g!@9DpDT)+FygWHZVYsd9+4QH}e zILW&WOx-A3m#Js$9C21%l9s=LWGwNneFSF>PTfDAMo1|rfaN7fWDch$PQfIx)<$zL zg6r&>3L{{#`1zi5UFbRnx^8sP3L}e&!k<>m^o(=p5kVT;TnAZTi`t>o@1>aHo?A5gJ2tv1s1! zzPZ+^@86bp%;k^ZSY!c-T_V_RlJ)){V`u@HA@nTn-reHA|551xWKMoxY>tZD@t3Mz z-ADdX)o&h7Z@#Kt;UdrFNLZTXzhq))2Z4!rF_UN_vB z8?!9pBk6H3$9d0xeU>jeasHp{ZeNBKAWBC<*mWD842bdK0mNu%6RprLcJk50xT-@n zs?nGv@8eVu=&j8`jTpbdDHR8WSj|0Lh!JO?#j`avr=|pARiCXDHzgv0Fcng7L7Va* zO6khEqEmJ!Ya~fcl95&-+C1@6iZ>n2sw+vOROvh5g?!R2TpF z?Dpn&oxkSp-)NHmGIPJ#d-)Tn>d)oBzEavV^I_FWB4CEz(f|2Z45RobCT3wR05CC& zYXOqCU!FE$?{a&;&V|SStXM`^zB1+UmL$ZO&OZ!}eto$mEVzM`IA+|tnZ=x->sNL| zZmlR=7v8Umy|w*A^Nk0ky!4hMB)NZn-oiq_E?STZ*D`dYNn9JY-k~XdU@mt4Njo+n z4(r?Qxr0Nny3ugTd`kqC+m=hO7Ajqp@z7~+=N@|u_nl_tE+SiUbaU`CLBY}sV(1*c zZcp40T~?PXiH4VIGDn(TVP;>crT>0_F_ZZJaTdCYslf-;7h50fFkqv{&V z^uJ%;|1gL1$GpfMIy!HE1PltDw<`2=b{pzM>j2%Tnhj9izr@=K86LbJgo_G}i~@a$ z#A}P=;YfHe2p$;$4-LkG4um5;BO;0Lzm-f_`&%<$1Ka@H;)-^u| z-<$9g@C6SMXr?V+^K6;dJVoO*ql;g28SGetID("AliRun") < 0) { - gSystem->Load("$ALITOP/cern.so/lib/libpdfDUMMY.so"); - gSystem->Load("$ALITOP/cern.so/lib/libPythia.so"); - gSystem->Load("$ROOTSYS/lib/libEG.so"); - gSystem->Load("$ROOTSYS/lib/libEGPythia.so"); - gSystem->Load("libGeant3Dummy.so"); //a dummy version of Geant3 - gSystem->Load("PHOS/libPHOSdummy.so"); //the standard Alice classes - gSystem->Load("libgalice.so"); // the standard Alice classes - } + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } else { + delete gAlice; + gAlice = 0; + } // // Connect the Root Galice file containing Geometry, Kine and Hits TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); @@ -35,7 +33,6 @@ void MUONcombi (Int_t evNumber=0) if (gAlice) printf("AliRun object found on file\n"); if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); } -// TClonesArray &Partarray = *(gAlice->Particles()); TClonesArray *PartArray = gAlice->Particles(); TParticle *Part; @@ -46,14 +43,18 @@ void MUONcombi (Int_t evNumber=0) // // TH1F *dmass = new TH1F("dmass","Dimuon-Mass Distribution" + ,25,0.,5.); + TH1F *dmassc = new TH1F("dmassc","Dimuon-Mass Distribution" + ,50,0.,10.); + TH1F *dmassd = new TH1F("dmassd","Dimuon-Mass Distribution" ,50,0.,10.); + TH1F *pt = new TH1F("pt","pT-single" ,50,0.,10.); // // Generator Loop // - AliGenCocktailEntry *Entry, *e1, *e2; AliGenCocktail* Cocktail = (AliGenCocktail*) gAlice->Generator(); // Single Generator @@ -64,55 +65,60 @@ void MUONcombi (Int_t evNumber=0) Entry->PrintInfo(); } // Pairs of Generators - // // Initialize Combinator - DimuonCombinator Combinator = DimuonCombinator(PartArray); - Combinator->SetEtaCut(-4, 4); - Combinator->SetPtMin(0.5); + AliDimuCombinator* Combinator = new AliDimuCombinator(PartArray); + Combinator->SetEtaCut(-5, 5); + Combinator->SetPtMin(0.0); Int_t i=0; // // Single Muon Loop // -/* + Combinator->ResetRange(); + + - for(Muon=Combinator.FirstMuon(); + for(Muon=Combinator->FirstMuon(); Muon; - Muon=Combinator.NextMuon()) { + Muon=Combinator->NextMuon()) { // - Int_t chfirst= Muon->GetFirstChild(); - Int_t chlast = Muon->GetLastChild(); - Int_t parent = Muon->GetParent(); - Float_t ptm = Muon->GetPT(); - Float_t eta = Muon->GetEta(); + Int_t chfirst= Muon->GetFirstDaughter(); + Int_t chlast = Muon->GetLastDaughter(); + Int_t parent = Muon->GetFirstMother(); + Float_t ptm = Muon->Pt(); + Float_t eta = Muon->Eta(); printf("\n Particle %d Parent %d first child %d last child %d", i,parent, chfirst, chlast); printf("\n Particle pt, eta: %f , %f ",pt,eta); i++; } -*/ // // Di-Muon Loop Float_t pt1,pt2; TParticle* Muon1, *Muon2; -/* + Combinator->ResetRange(); +/* for (Combinator->FirstMuonPairSelected(Muon1,Muon2); (Muon1 && Muon2); Combinator->NextMuonPairSelected(Muon1,Muon2)) { - pt1=Muon1->GetPT(); - pt2=Muon2->GetPT(); + pt1=Muon1->Pt(); + pt2=Muon2->Pt(); Float_t mass=Combinator->Mass(Muon1, Muon2); Float_t wgt =Combinator->Weight(Muon1, Muon2); pt->Fill(pt1, wgt); pt->Fill(pt2, wgt); Float_t smeared_mass=mass; Combinator->SmearGauss(0.05*mass, smeared_mass); - dmass->Fill(smeared_mass , wgt); + if (Combinator->Correlated(Muon1, Muon2)) { + dmassc->Fill(mass, wgt); + } else { + dmass->Fill(mass, wgt); + } } */ // @@ -133,18 +139,26 @@ void MUONcombi (Int_t evNumber=0) (Muon1 && Muon2); Combinator->NextMuonPairSelected(Muon1,Muon2)) { - pt1=Muon1->GetPT(); - pt2=Muon2->GetPT(); + pt1=Muon1->Pt(); + pt2=Muon2->Pt(); Float_t mass=Combinator->Mass(Muon1, Muon2); Float_t wgt =Combinator->Weight(Muon1, Muon2); pt->Fill(pt1, wgt); pt->Fill(pt2, wgt); Float_t smeared_mass=mass; Combinator->SmearGauss(0.05*mass, smeared_mass); - dmass->Fill(smeared_mass , wgt); + Float_t DecayWeight= + Combinator->Decay_Prob(Muon2)* + Combinator->Decay_Prob(Muon2); +// if (TMath::Min(pt1,pt2) > -0.5*TMath::Max(pt1,pt2)+2.) { + if (Combinator->Correlated(Muon1, Muon2)) { + dmassc->Fill(smeared_mass, wgt); + } + dmass->Fill(smeared_mass, wgt); + dmassd->Fill(smeared_mass, wgt*DecayWeight); +// } } // Dimuon Loop }// Generator Loop - // //Create a canvas, set the view range, show histograms // @@ -168,9 +182,24 @@ void MUONcombi (Int_t evNumber=0) pt->Draw(); pad12->cd(); + pad12->SetLogy(0); dmass->SetFillColor(42); dmass->SetXTitle("m (GeV)"); dmass->Draw(); + + pad13->cd(); + pad13->SetLogy(0); + dmassc->SetFillColor(42); + dmassc->SetXTitle("m (GeV)"); + dmassc->Draw(); + + pad14->cd(); + pad14->SetLogy(0); + dmassd->SetFillColor(42); + dmassd->SetXTitle("m (GeV)"); + dmassd->Draw(); + + } diff --git a/MUON/MUONdigit.C b/MUON/MUONdigit.C index a1e3e8a14e1..da09f6ab5f7 100644 --- a/MUON/MUONdigit.C +++ b/MUON/MUONdigit.C @@ -1,13 +1,48 @@ #include "iostream.h" -void MUONdigit (Int_t evNumber1=0,Int_t evNumber2=0,Int_t nsignal =25) +void MUONdigit (Int_t evNumber1=0, Int_t evNumber2=9, Int_t ibg=1, Int_t bgr=10) { -///////////////////////////////////////////////////////////////////////// -// This macro is a small example of a ROOT macro -// illustrating how to read the output of GALICE -// and do some analysis. -// -///////////////////////////////////////////////////////////////////////// + ////////////////////////////////////// + // // + // ROOT macro for ALICE Dimuon Arm: // + // Digitization // + // // + ////////////////////////////////////// + // + // Adds the tree TD for digits (charges deposited on pads) + // to the ROOT file "galice.root" + // containing the signal hit coordinates from simulation (tree TH). + // Eventually (argument "ibg"), background hits are also taken into account, + // from the ROOT file "galice_bgr.root". + // + // Arguments: + // evNumber1 = first event number to digitize in file "galice.root" + // evNumber2 = last event number to digitize in file "galice.root" + // ibg = 0 if no background hits to be taken into account; + // = 1 if background hits to be taken into account + // in file "galice_bgr.root" + // bgr : used only if "ibg" = 1 + // = number of events in the background file "galice_bgr.root"; + // the signal events are divided into "bgr" successive parts, + // all events of each part are associated + // with the same background event, + // starting with event number 0, + // incrementing it by 1 for the next part. + // Strictly speaking, "bgr" can be smaller than + // the number of events in the background file, + // in which case one will only use + // the first "bgr" events of the background file. + // But it SHOULD NOT BE LARGER THAN + // THE NUMBER OF EVENTS IN THE BACKGROUND FILE. + // + // Input file(s): + // "galice.root" for signal + // "galice_bgr.root" for background (used only if "ibg" = 1) + // + // Output file: + // "galice.root" + // + //__________________________________________________________________________ // Dynamically link some shared libs @@ -16,15 +51,11 @@ void MUONdigit (Int_t evNumber1=0,Int_t evNumber2=0,Int_t nsignal =25) loadlibs(); } - // Connect the Root Galice file containing Geometry, Kine and Hits TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); if (file) file->Close(); file = new TFile("galice.root","UPDATE"); - file->ls(); - - printf ("I'm after Map \n"); // Get AliRun object from file or create it if not on file @@ -36,25 +67,27 @@ void MUONdigit (Int_t evNumber1=0,Int_t evNumber2=0,Int_t nsignal =25) printf ("I'm after gAlice \n"); AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); + // // Event Loop // - Int_t nbgr_ev=0; + Int_t nbgr_ev = 0; - for (int nev=0; nev<= evNumber2; nev++) { + for (int nev=evNumber1; nev<= evNumber2; nev++) { Int_t nparticles = gAlice->GetEvent(nev); cout << "nev " <Digitise(nev,nbgr_ev,"Add"," ","galice_bgr.root"); - if (MUON) MUON->Digitise(nev,nbgr_ev,"rien"," ","galice_bgr.root"); -// char hname[30]; -// sprintf(hname,"TreeD%d",nev); -// file->ls(); + nbgr_ev = Int_t(nev*bgr/(evNumber2+1)); + + if (ibg) { + printf("nbgr_ev %d\n",nbgr_ev); + if (MUON) MUON->Digitise(nev,nbgr_ev,"Add"," ","galice_bgr.root"); + } else { + if (MUON) MUON->Digitise(nev,nbgr_ev,"rien"," ","galice_bgr.root"); + } + } // event loop file->Close(); } diff --git a/MUON/MUONdigits.C b/MUON/MUONdigits.C deleted file mode 100644 index 0e8ad708abc..00000000000 --- a/MUON/MUONdigits.C +++ /dev/null @@ -1,266 +0,0 @@ -void MUONdigits (Int_t evNumber1=0,Int_t evNumber2=0,Int_t nCathode=1) -{ -///////////////////////////////////////////////////////////////////////// -// This macro is a small example of a ROOT macro -// illustrating how to read the output of GALICE -// and do some analysis. -// -///////////////////////////////////////////////////////////////////////// - -// Dynamically link some shared libs - - if (gClassTable->GetID("AliRun") < 0) { - gSystem->Load("$ALITOP/cern.so/lib/libpdfDUMMY.so"); - gSystem->Load("$ALITOP/cern.so/lib/libPythia.so"); - gSystem->Load("$ROOTSYS/lib/libEG.so"); - gSystem->Load("$ROOTSYS/lib/libEGPythia.so"); - gSystem->Load("libGeant3Dummy.so"); //a dummy version of Geant3 - gSystem->Load("PHOS/libPHOSdummy.so"); //the standard Alice classes - gSystem->Load("libgalice.so"); //the standard Alice classes - } - - -// Connect the Root Galice file containing Geometry, Kine and Hits - - TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); - if (file) file->Close(); - file = new TFile("galice.root","UPDATE"); - file->ls(); - // file->Map(); - - printf ("I'm after Map \n"); - -// Get AliRun object from file or create it if not on file - - if (!gAlice) { - gAlice = (AliRun*)file->Get("gAlice"); - if (gAlice) printf("AliRun object found on file\n"); - if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); - } - printf ("I'm after gAlice \n"); - - AliMUON *MUON = gAlice->GetDetector("MUON"); - - AliMUONchamber* iChamber; - AliMUONsegmentation* segmentation; - - Int_t Npx[10]; - Int_t Npy[10]; - Int_t trk[50]; - Int_t chtrk[50]; - - - Int_t nxmax=1026; - Int_t nymax=1026; - AliMUONlist *elem[10*1026*1026]; - AliMUONlist **ppe=elem; - TObjArray *obj=new TObjArray; - - Int_t digits[3]; - // fill the info array - TVector *trinfo; - trinfo=new TVector(2); - -// -// Loop over events -// - - Int_t Nh=0; - Int_t Nh1=0; - for (int nev=0; nev<= evNumber2; nev++) { - Int_t nparticles = gAlice->GetEvent(nev); - cout << "nev " <TreeH(); - Int_t ntracks = TH->GetEntries(); - Int_t Nc=0; - // - Int_t counter=0; - - // loop over cathodes - for (int icat=0;icatResetHits(); - Int_t nbytes += TH->GetEvent(track); - if (MUON) { - for(AliMUONhit* mHit=(AliMUONhit*)MUON->FirstHit(-1); - mHit; - mHit=(AliMUONhit*)MUON->NextHit()) - { - Int_t nch = mHit->fChamber; // chamber number - Float_t x = mHit->fX; // x-pos of hit - Float_t y = mHit->fY; // y-pos -// -// - if (nch >10) continue; - - iChamber = &(MUON->Chamber(nch-1)); - response=iChamber->GetResponseModel(); - - Int_t nsec=iChamber->Nsec(); - Int_t rmin = (Int_t)iChamber->frMin; - Int_t rmax = (Int_t)iChamber->frMax; -// -// - for (AliMUONcluster* mPad=(AliMUONcluster*)MUON->FirstPad(mHit); - mPad; - mPad=(AliMUONcluster*)MUON->NextPad()) - { - Int_t cathode = mPad->fCathode; // chamber number - Int_t nhit = mPad->fHitNumber; // hit number - Int_t qtot = mPad->fQ; // charge - Int_t ipx = mPad->fPadX; // pad number on X - Int_t ipy = mPad->fPadY; // pad number on Y - Int_t iqpad = mPad->fQpad; // charge per pad - Int_t izone = mPad->fRSec; // r-pos of pad -// -// - if (cathode != (icat+1)) continue; - segmentation=iChamber->GetSegmentationModel(cathode); - Int_t Npx[nch-1] = segmentation->Npx(); - Int_t Npy[nch-1] = segmentation->Npy(); - - Int_t npx=Npx[nch-1]; - Int_t npy=Npy[nch-1]; - Float_t thex, they; - - segmentation->GetPadCxy(ipx,ipy,thex,they); - Float_t rpad=TMath::Sqrt(thex*thex+they*they); - - if (rpad < rmin || iqpad ==0 || rpad > rmax) continue; - - - trinfo(0)=(Float_t)track; - trinfo(1)=(Float_t)iqpad; - - digits[0]=ipx; - digits[1]=ipy; - digits[2]=iqpad; - - // build the list of fired pads and update the info - AliMUONlist *pdigit= - elem[(nch-1)*(1026*1026)+(ipy+npy)*1026+(ipx+npx)]; - if (pdigit==0) { - obj->AddAtAndExpand(new AliMUONlist(nch-1,digits),counter); - counter++; - Int_t last=obj->GetLast(); - pdigit=(AliMUONlist*)obj->At(last); - elem[(nch-1)*(1026*1026)+(ipy+npy)*1026+(ipx+npx)]=pdigit; - // list of tracks - TObjArray *trlist=(TObjArray*)pdigit->TrackList(); - trlist->Add(trinfo); - } else { - // update charge - (*pdigit).fSignal+=iqpad; - // update list of tracks - TObjArray* trlist=(TObjArray*)pdigit->TrackList(); - Int_t last_entry=trlist->GetLast(); - TVector *ptrk=(TVector*)trlist->At(last_entry); - 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) { - printf("Attention - nptracks > 2 %d \n",nptracks); - printf("cat,nch,ix,iy %d %d %d %d \n",icat+1,nch,ipx,ipy); - for (Int_t tr=0;trAt(tr); - trk[tr]=Int_t(pptrk(0)); - chtrk[tr]=Int_t(pptrk(1)); - } - } // end if nptracks - } // end if pdigit - } //end loop over clusters - } // hit loop - } // if MUON - } // track loop - - Int_t tracks[10]; - Int_t charges[10]; - cout<<"start filling digits "<GetEntriesFast(); - printf(" nentries %d \n",nentries); - - // start filling the digits - - for (Int_t nent=0;nentAt(nent); - if (address==0) continue; - // do zero-suppression and signal truncation - Int_t ich=address->fRpad; - Int_t q=address->fSignal; - // if ( q <= zero_supm || rpad > 55) continue; - if ( q <= zero_supm ) continue; - if ( q > adc_satm) q=adc_satm; - digits[0]=address->fPadX; - digits[1]=address->fPadY; - digits[2]=q; - - TObjArray* trlist=(TObjArray*)address->TrackList(); - Int_t nptracks=trlist->GetEntriesFast(); - // this was changed to accomodate the real number of tracks - if (nptracks > 10) { - cout<<"Attention - nptracks > 3 "< 2) { - printf("Attention - nptracks > 2 %d \n",nptracks); - printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q); - } - for (Int_t tr=0;trAt(tr); - Int_t entries=pp->GetNrows(); - tracks[tr]=Int_t(pp(0)); - charges[tr]=Int_t(pp(1)); - } //end loop over list of tracks for one pad - - // fill digits - MUON->AddDigits(ich,tracks,charges,digits); - } - cout<<"I'm out of the loops for digitisation"<TreeD()->Fill(); - TTree *TD=gAlice->TreeD(); - int ndig=TD->GetEntries(); - cout<<"number of digits "<DigitsAddress(i); - int ndig=fDch->GetEntriesFast(); - printf (" i, ndig %d %d \n",i,ndig); - } - MUON->ResetDigits(); - obj->Clear(); - } //end loop over cathodes - char hname[30]; - sprintf(hname,"TreeD%d",nev); - gAlice->TreeD()->Write(hname); - file->ls(); - } // event loop - file->Close(); -// cout<<"END digitisation "<GetEvent(nevent); diff --git a/MUON/MUONdoubles.C b/MUON/MUONdoubles.C new file mode 100644 index 00000000000..3ee075c930a --- /dev/null +++ b/MUON/MUONdoubles.C @@ -0,0 +1,298 @@ +#include "iostream.h" + +void MUONdoubles (Int_t evNumber1=0,Int_t evNumber2=0) +{ + { + hprof = new TProfile("hprof","Profile dmin vs r",24,0,120,0,50); + } + hdist1 = new TH1F("hdist1","distance",100,0,10); + hdist2 = new TH1F("hdist2","distance",100,0,10); + Float_t a1=3.7/TMath::Sqrt(4); + Float_t a2=26/TMath::Sqrt(4); + for (Int_t i=1; i<10000; i++) { + Float_t x1,x2,y1,y2; + x1 = (2*gRandom->Rndm(i)-1.)*a1; + x2 = (2*gRandom->Rndm(i)-1.)*a1; + y1 = (2*gRandom->Rndm(i)-1.)*a1; + y2 = (2*gRandom->Rndm(i)-1.)*a1; + Float_t d=TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); + hdist1->Fill(d,1); + } + Float_t xh[100], yh[100]; + for (Int_t k=0; k<1000; k++) { + for (Int_t i=0; i<100; i++) { + xh[i] = (2*gRandom->Rndm(i)-1.)*a2; + yh[i] = (2*gRandom->Rndm(i)-1.)*a2; + } + Float_t x1,y1; + + for (Int_t i=0; i<10; i++) { + Float_t dmin=1000; + x1 = (2*gRandom->Rndm(i)-1.)*a2; + y1 = (2*gRandom->Rndm(i)-1.)*a2; + for (Int_t j=0; j<100; j++) { + Float_t d=TMath::Sqrt((x1-xh[j])*(x1-xh[j])+(y1-yh[j])*(y1-yh[j])); + if (dFill(dmin,1); + } + } + + + +///////////////////////////////////////////////////////////////////////// +// This macro is a small example of a ROOT macro +// illustrating how to read the output of GALICE +// and do some analysis. +// +///////////////////////////////////////////////////////////////////////// + +// Dynamically link some shared libs + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (!file) file = new TFile("galice.root","UPDATE"); + +// Get AliRun object from file or create it if not on file + + if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + } +// +// Set reconstruction models +// +// Get pointers to Alice detectors and Digits containers + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); +// +// Book some histograms + TH1F *Hcentre[10], *Hall[10], *Hcfrac[10], *Htail[10], *Htfrac[10]; + TH1F *Hdcut[10], *Hdall[10], *Hdfrac[10]; + + for (Int_t i=0; i<10; i++) { + Hcentre[i] = new TH1F("Hcentre","Hit Distribution",26,0,260); + Hcentre[i]->SetFillColor(0); + Hcentre[i]->SetXTitle("R (cm)"); + + Hall[i] = new TH1F("Hall","Hit Distribution",26,0,260); + Hall[i]->SetFillColor(0); + Hall[i]->SetXTitle("R (cm)"); + + Hcfrac[i] = new TH1F("Hcfrag","Hit Distribution",26,0,260); + Hcfrac[i]->SetFillColor(0); + Hcfrac[i]->SetXTitle("R (cm)"); + + Htail[i] = new TH1F("Htail","Hit Distribution",26,0,260); + Htail[i]->SetFillColor(0); + Htail[i]->SetXTitle("R (cm)"); + + Htfrac[i] = new TH1F("Htfrag","Hit Distribution",26,0,260); + Htfrac[i]->SetFillColor(0); + Htfrac[i]->SetXTitle("R (cm)"); + + Hdall[i] = new TH1F("Hdall","Hit Distribution",26,0,260); + Hdall[i]->SetFillColor(0); + Hdall[i]->SetXTitle("R (cm)"); + + Hdcut[i] = new TH1F("Hdcut","Hit Distribution",26,0,260); + Hdcut[i]->SetFillColor(0); + Hdcut[i]->SetXTitle("R (cm)"); + + Hdfrac[i] = new TH1F("Hdfrac","Hit Distribution",26,0,260); + Hdfrac[i]->SetFillColor(0); + Hdfrac[i]->SetXTitle("R (cm)"); + + } + +// +// Loop over events +// + Int_t Nh=0; + Int_t Nh1=0; + for (int nev=0; nev<= evNumber2; nev++) { + Int_t nparticles = gAlice->GetEvent(nev); + cout << "nev " << nev <TreeH(); + Int_t ntracks = TH->GetEntries(); + cout<<"ntracks "<Particles(); + TTree *TD = gAlice->TreeD(); + Int_t nent=TD->GetEntries(); + printf("Found %d entries in the tree (must be one per cathode per event!)\n",nent); + Float_t x[2000]; + Float_t y[2000]; + Int_t nhit=0; + + if (MUON) { +// +// Loop on chambers and on cathode planes +// + TTree *TH = gAlice->TreeH(); + Int_t ntracks = TH->GetEntries(); + +// +// Loop over Hits +// + for (i=0; i<1000; i++) { + Float_t r =100.*gRandom->Rndm(i); + Float_t phi=2.*TMath::Pi()*gRandom->Rndm(i); + Float_t xr=r*TMath::Sin(phi); + Float_t yr=r*TMath::Cos(phi); + Hdall[0]->Fill(r,1.); + Float_t dmin=100000.; + + if (i==0) { + for (Int_t track=0; trackResetHits(); + Int_t nbytes += TH->GetEvent(track); + for(AliMUONHit* mHit=(AliMUONHit*)MUON->FirstHit(-1); + mHit; + mHit=(AliMUONHit*)MUON->NextHit()) + { + Int_t nch = mHit->fChamber; // chamber number + if (nch!=1) continue; + + x[nhit] = mHit->fX; // x-pos of hit + y[nhit] = mHit->fY; // y-pos + nhit++; + } // hit loop + } // track loop + } else { + for (Int_t nh=0; nhFill(r,1.); + } // hit loop + } // i==0 + if (r>20) hprof->Fill(r,dmin,1); + } // random loop + Int_t icat=0; + gAlice->ResetDigits(); + gAlice->TreeD()->GetEvent(icat+1); // spurious +1 ... + + for (Int_t ich=0;ich<1;ich++) { + AliMUONChamber iChamber= MUON->Chamber(ich); + TClonesArray *MUONdigits = MUON->DigitsAddress(ich); + if (MUONdigits == 0) continue; + // + // Get ready the current chamber stuff + // + AliMUONResponse* response = iChamber.GetResponseModel(); + AliMUONSegmentation* seg = iChamber.GetSegmentationModel(icat+1); + HitMap = new AliMUONHitMapA1(seg, MUONdigits); + HitMap->FillHits(); + Int_t nxmax=seg->Npx(); + Int_t nymax=seg->Npy(); +// +// generate random positions on the chamber +// + for (Int_t i=0; i<4000; i++) { + Int_t ix = 2*Int_t((gRandom->Rndm(i)-0.5)*nxmax); + Int_t iy = 2*Int_t((gRandom->Rndm(i)-0.5)*nymax); + +// test for centre overlap +// + Float_t xp,yp; + seg->GetPadCxy(ix,iy,xp,yp); + Float_t r=TMath::Sqrt(xp*xp+yp*yp); + if (TMath::Abs(xp)>3 && TMath::Abs(yp)>3) + Hall[ich]->Fill(r,1.); + if (HitMap->TestHit(ix,iy) != 0) { + Hcentre[ich]->Fill(r,1.); + } +// test for neighbour overlap +// + Int_t nn; + Int_t X[20], Y[20]; + seg->Neighbours(ix,iy,&nn,X,Y); + Bool_t hit=false; + + for (Int_t j=0; jTestHit(X[j],Y[j]) != 0) hit=true; + } + if (hit && HitMap->TestHit(ix,iy) == 0) Htail[ich]->Fill(r,1.); + } //random loop + delete HitMap; + } // chamber loop + } // event loop + } // if MUON + + for (Int_t ich=0; ich<10; ich++) { + Hcfrac[ich]->Divide(Hcentre[ich],Hall[ich]); + Htfrac[ich]->Divide(Htail[ich],Hall[ich]); + Hdfrac[ich]->Divide(Hdcut[ich],Hdall[ich]); + } + + TCanvas *c1 = new TCanvas("c1","Hit Densities",400,10,600,700); + pad11 = new TPad("pad11"," ",0.01,0.51,0.49,0.99); + pad12 = new TPad("pad12"," ",0.51,0.51,0.99,0.99); + pad13 = new TPad("pad13"," ",0.01,0.01,0.49,0.49); + pad14 = new TPad("pad14"," ",0.51,0.01,0.99,0.49); + pad11->SetFillColor(0); + pad12->SetFillColor(0); + pad13->SetFillColor(0); + pad14->SetFillColor(0); + pad11->Draw(); + pad12->Draw(); + pad13->Draw(); + pad14->Draw(); + + pad11->cd(); + Hcentre[0]->Draw(); + + pad12->cd(); + Hall[0]->Draw(); + + pad13->cd(); + Hcfrac[0]->Draw(); + + pad14->cd(); + Htfrac[0]->Draw(); + + TCanvas *c2 = new TCanvas("c2","Hit Densities",400,10,600,700); + pad21 = new TPad("pad21"," ",0.01,0.51,0.49,0.99); + pad22 = new TPad("pad22"," ",0.51,0.51,0.99,0.99); + pad23 = new TPad("pad23"," ",0.01,0.01,0.49,0.49); + pad24 = new TPad("pad24"," ",0.51,0.01,0.99,0.49); + pad21->SetFillColor(0); + pad22->SetFillColor(0); + pad23->SetFillColor(0); + pad24->SetFillColor(0); + pad21->Draw(); + pad22->Draw(); + pad23->Draw(); + pad24->Draw(); + + pad21->cd(); + hdist1->Draw(); + + pad22->cd(); + hdist2->Draw(); + + pad23->cd(); + Hdfrac[0]->Draw(); + + pad24->cd(); + hprof->Draw(); + file->Close(); +} + diff --git a/MUON/MUONhitrectest.C b/MUON/MUONhitrectest.C new file mode 100644 index 00000000000..defe38d4bf1 --- /dev/null +++ b/MUON/MUONhitrectest.C @@ -0,0 +1,186 @@ +#include "iostream.h" + +void MUONhitrectest (Int_t evNumber1=0,Int_t evNumber2=0) +{ +///////////////////////////////////////////////////////////////////////// +// This macro is a small example of a ROOT macro +// illustrating how to read the output of GALICE +// and do some analysis. +// +///////////////////////////////////////////////////////////////////////// + +// Dynamically link some shared libs + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (!file) file = new TFile("galice.root"); + +// Get AliRun object from file or create it if not on file + + if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + } +// Create some histograms + + TH2F *h21 = new TH2F("h21","Hits",100,-100,100,100,-100,100); + TH2F *h22 = new TH2F("h22","CoG ",100,-100,100,100,-100,100); + TH1F *h1 = new TH1F("h1","Multiplicity",30,-0.5,29.5); + TH1F *hmult = new TH1F("hmult","Multiplicity",30,-0.5,29.5); + TH1F *hresx = new TH1F("hresx","Residuals",100,-1,1); + TH1F *hresy = new TH1F("hresy","Residuals",100,-10.,10); + TH1F *hresym = new TH1F("hresym","Residuals",100,-500,500); + TH1F *hpos = new TH1F("hnpos","Possibilities",10,-0.5,9.5); + TH2F *hchi1 = new TH2F("hchi1","Chi2 vs Residuals",100,0,0.2,100,-500,500); + TH2F *hchi2 = new TH2F("hchi2","Chi2 vs Residuals",100,0,20,100,-500,500); +// +// Loop over events +// + Int_t Nh=0; + Int_t Nh1=0; + + for (int nev=0; nev<= evNumber2; nev++) { + Int_t nparticles = gAlice->GetEvent(nev); + cout << "nev " << nev <TreeH(); + Int_t ntracks = TH->GetEntries(); + cout<<"ntracks "<GetModule("MUON"); + TClonesArray *Particles = gAlice->Particles(); + TTree *TR = gAlice->TreeR(); + Int_t nent=TR->GetEntries(); + printf("Found %d entries in the tree (must be one per cathode per event! + 1empty)\n",nent); + if (MUON) { + Float_t xc[2000], yc[2000], itrc[2000]; + TClonesArray *MUONrawclust = MUON->RawClustAddress(0); + nbytes += TR->GetEvent(1); + Int_t nrawcl = MUONrawclust->GetEntries(); + AliMUONRawCluster *mRaw; + for (Int_t iraw=0; iraw < nrawcl; iraw++) { + mRaw = (AliMUONRawCluster*)MUONrawclust->UncheckedAt(iraw); + xc[iraw]=mRaw->fX[1]; + yc[iraw]=mRaw->fY[0]; + itrc[iraw]=mRaw->fTracks[1]; + } // cluster + + gAlice->ResetHits(); + for (Int_t itrack=0; itrackGetEvent(itrack); + Int_t nhit=MUON->Hits()->GetEntriesFast(); + for(AliMUONHit* mHit=(AliMUONHit*)MUON->FirstHit(itrack); + mHit; + mHit=(AliMUONHit*)MUON->NextHit()) + { + Int_t nch = mHit->fChamber; // chamber number + Float_t x = mHit->fX; // x-pos of hit + Float_t y = mHit->fY; // y-pos + Int_t ip = mHit->fParticle; + if (ip != kMuonPlus && ip != kMuonMinus) continue; + if (nch != 1) continue; + Float_t dmin=1.e8; + Int_t imin=-1; +// +// Loop over clusters + Int_t npos=0; + + for (Int_t i=0; iUncheckedAt(imin); + Int_t track=mRaw->fTracks[1]; + Float_t xrec=mRaw->fX[1]; + Float_t yrec=mRaw->fY[0]; + Float_t x_res=xrec-x; + Float_t y_res=yrec-y; + hresx->Fill(x_res,1.); + hresy->Fill(y_res,1.); + hpos->Fill(Float_t(npos), 1.); + hresym->Fill(y_res*1.e4,1.); + if (npos == 0) { + printf("No cluster %d %f %f %d\n", + itrack, x, y, nhit); + h21->Fill(x,y,1.); + } + + + + } // hits + } // tracks + } // end if MUON + } // event loop + TCanvas *c1 = new TCanvas("c1","Charge and Residuals",400,10,600,700); + c1->Divide(2,2); + c1->cd(1); + hresx->SetFillColor(42); + hresx->SetXTitle("xrec-x"); + hresx->Draw(); + + c1->cd(2); + hresy->SetFillColor(42); + hresy->SetXTitle("yrec-y"); + hresy->Draw(); + + c1->cd(3); + hpos->SetFillColor(42); + hpos->SetXTitle("Possibilities"); + hpos->Draw(); + + c1->cd(4); + hresym->SetFillColor(42); + hresym->SetXTitle("yrec-y"); + hresym->Fit("gaus"); + hresym->Draw(); + + TCanvas *c2 = new TCanvas("c2","Charge and Residuals",400,10,600,700); + c2->Divide(2,2); + + c2->cd(1); + h21->SetFillColor(42); + h21->SetXTitle("x"); + h21->SetYTitle("y"); + h21->Draw(); + + c2->cd(2); + hmult->SetFillColor(42); + hmult->SetXTitle("multiplicity"); + hmult->Draw(); + + c2->cd(3); + hchi1->SetFillColor(42); + hchi1->SetXTitle("chi2"); + hchi1->Draw(); + + c2->cd(4); + hchi2->SetFillColor(42); + hchi2->SetXTitle("chi2"); + hchi2->Draw(); + +} + + + diff --git a/MUON/MUONhits.C b/MUON/MUONhits.C new file mode 100644 index 00000000000..78fcd144d76 --- /dev/null +++ b/MUON/MUONhits.C @@ -0,0 +1,226 @@ +void MUONhits (Int_t evNumber1=0,Int_t evNumber2=0, Int_t ic=1) +{ +///////////////////////////////////////////////////////////////////////// +// This macro is a small example of a ROOT macro +// illustrating how to read the output of GALICE +// and do some analysis. +// +///////////////////////////////////////////////////////////////////////// + +// Dynamically link some shared libs + Float_t rmin[14] = {17.5, 17.5, 23.5, 23.5, 33.5, 33.5, 43., 43., 50., 50, + 56.1, 56.1, 59.6, 59.6}; + Float_t rmax[14] = {81.6, 81.6, 109.3, 109.3, 154.4, 154.4, 197.8, + 197.8, 229.5, 229.5, 254., 254, 270., 270.}; + + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + + + if (!file) { + printf("\n Creating galice.root \n"); + file = new TFile("galice.root"); + } else { + printf("\n galice.root found in file list"); + } + file->ls(); +// + TDatabasePDG* DataBase = new TDatabasePDG(); + +// Get AliRun object from file or create it if not on file + if (!gAlice) { + gAlice = (AliRun*)(file->Get("gAlice")); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) { + printf("\n create new gAlice object"); + gAlice = new AliRun("gAlice","Alice test program"); + } + } + +// Create some histograms + + TH1F *Hits[14], *HitDensity[14]; + TH1F *Hits_g[14], *HitDensity_g[14]; + TH1F *Hits_n[14], *HitDensity_n[14]; + TH1F *Mom[14], *Mom_g[14], *Mom_n[14]; + + for (Int_t i=0; i<14; i++) { + Hits[i] = new TH1F("hits1","Hit Distribution",30,0,300); + Hits[i]->SetFillColor(0); + Hits[i]->SetXTitle("R (cm)"); + + HitDensity[i] = new TH1F("dhits1","Hit Density",30,0,300); + HitDensity[i]->SetFillColor(0); + HitDensity[i]->SetXTitle("R (cm)"); + + Hits_g[i] = new TH1F("hits1","Hit Distribution",30,0,300); + Hits_g[i]->SetFillColor(0); + Hits_g[i]->SetXTitle("R (cm)"); + + HitDensity_g[i] = new TH1F("dhits1","Hit Density",30,0,300); + HitDensity_g[i]->SetFillColor(0); + HitDensity_g[i]->SetXTitle("R (cm)"); + + Mom[i] = new TH1F("mom","Energy",70,-6,1); + Mom[i]->SetFillColor(0); + Mom[i]->SetXTitle("E (GeV)"); + + Mom_g[i] = new TH1F("mom","Energy",70,-6,1); + Mom_g[i]->SetFillColor(0); + Mom_g[i]->SetXTitle("E (GeV)"); + + Mom_n[i] = new TH1F("mom","Energy",70,-6,1); + Mom_n[i]->SetFillColor(0); + Mom_n[i]->SetXTitle("E (GeV)"); + + Hits_n[i] = new TH1F("hits1","Hit Distribution",30,0,300); + Hits_n[i]->SetFillColor(0); + Hits_n[i]->SetXTitle("R (cm)"); + + HitDensity_n[i] = new TH1F("dhits1","Hit Density",30,0,300); + HitDensity_n[i]->SetFillColor(0); + HitDensity_n[i]->SetXTitle("R (cm)"); + } + + TH1F *theta = new TH1F("theta","Theta distribution",180,0,180); + + TH1F *emult = new TH1F("emult","Event Multiplicity",100,0,1000); + AliMUONChamber* iChamber; + AliMUONSegmentation* seg; + +// +// Loop over events +// + Float_t dpx[2], dpy[2]; + Int_t mdig =0; + Int_t nhit=0; + + for (Int_t nev=0; nev<= evNumber2; nev++) { + Int_t nparticles = gAlice->GetEvent(nev); + if (nev < evNumber1) continue; + if (nparticles <= 0) return; + + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); + printf("\n track %d %d \n ", nev, MUON); + + TTree *TH = gAlice->TreeH(); + Int_t ntracks = TH->GetEntries(); +// +// Loop over events +// + Int_t EvMult=0; + + for (Int_t track=0; trackResetHits(); + Int_t nbytes += TH->GetEvent(track); + if (MUON) { +// +// Loop over hits +// + Int_t NperCh=0; + + for(AliMUONHit* mHit=(AliMUONHit*)MUON->FirstHit(-1); + mHit; + mHit=(AliMUONHit*)MUON->NextHit()) + { + Int_t nch = mHit->fChamber; // chamber number + Float_t x = mHit->fX; // x-pos of hit + Float_t y = mHit->fY; // y-pos + Float_t Eloss = mHit->fEloss; + Float_t Theta = mHit->fTheta; + Float_t Particle = mHit->fParticle; + Float_t P = + TMath::Sqrt(mHit->fCxHit*mHit->fCxHit+ + mHit->fCyHit*mHit->fCyHit+ + mHit->fCzHit*mHit->fCzHit); + TParticlePDG* Part = DataBase->GetParticle(Particle); + Double_t mass = Part->Mass(); + + if (nch >13) continue; + if (nch ==1) EvMult++; + if (mHit->fAge > 5.e-6) continue; + + Float_t r=TMath::Sqrt(x*x+y*y); + if (nch ==0) continue; + + if (r < rmin[nch-1]) continue; + if (r > rmax[nch-1]) continue; + + Float_t wgt=1/(2*10*TMath::Pi()*r)/(evNumber2+1); + + Float_t Ekin=TMath::Sqrt(P*P+mass*mass)-mass; + if (Particle == 2112) { + Hits_n[nch-1]->Fill(r,(float) 1); + HitDensity_n[nch-1]->Fill(r,wgt); + Mom_n[nch-1]->Fill(TMath::Log10(Ekin),1); + } else if (Particle == 22) { + Hits_g[nch-1]->Fill(r,(float) 1); + HitDensity_g[nch-1]->Fill(r,wgt); + Mom_g[nch-1]->Fill(TMath::Log10(Ekin),1); + } else { + Hits[nch-1]->Fill(r,(float) 1); + HitDensity[nch-1]->Fill(r,wgt); + Mom[nch-1]->Fill(TMath::Log10(Ekin),1); + } + } // hit loop + } // if MUON + } // track loop + } + +//Create a canvas, set the view range, show histograms + Int_t k; + TCanvas *c1 = new TCanvas("c1","Hit Densities",400,10,600,700); + c1->Divide(2,4); + for (k=0; k<7; k++) { + c1->cd(k+1); + HitDensity[2*k]->Draw(); + } + + TCanvas *c2 = new TCanvas("c2","Hit Densities (gamma)",400,10,600,700); + c2->Divide(2,4); + for (k=0; k<7; k++) { + c2->cd(k+1); + HitDensity_g[2*k]->Draw(); + } + + TCanvas *c3 = new TCanvas("c3","Hit Densities (neutron)",400,10,600,700); + c3->Divide(2,4); + for (k=0; k<7; k++) { + c3->cd(k+1); + HitDensity_n[2*k]->Draw(); + } + + TCanvas *c4 = new TCanvas("c4","Energy (charged)",400,10,600,700); + c4->Divide(2,4); + for (k=0; k<7; k++) { + c4->cd(k+1); + Mom[2*k]->Draw(); + } + + TCanvas *c5 = new TCanvas("c5","Energy (gamma)",400,10,600,700); + c5->Divide(2,4); + for (k=0; k<7; k++) { + c5->cd(k+1); + Mom_g[2*k]->Draw(); + } + + TCanvas *c6 = new TCanvas("c6","Energy (gamma)",400,10,600,700); + c6->Divide(2,4); + for (k=0; k<7; k++) { + c6->cd(k+1); + Mom_n[2*k]->Draw(); + } +} + + + + + + + diff --git a/MUON/MUONlist2digits.C b/MUON/MUONlist2digits.C deleted file mode 100644 index ac708b5b4e1..00000000000 --- a/MUON/MUONlist2digits.C +++ /dev/null @@ -1,333 +0,0 @@ -void MUONlist2digits (Int_t evNumber1=0,Int_t evNumber2=0,Int_t nCathode=1) -{ -///////////////////////////////////////////////////////////////////////// -// This macro is a small example of a ROOT macro -// illustrating how to read the output of GALICE -// and do some analysis. -// -///////////////////////////////////////////////////////////////////////// - -// Dynamically link some shared libs - - - if (gClassTable->GetID("AliRun") < 0) { - gSystem->Load("$ALITOP/cern.so/lib/libpdfDUMMY.so"); - gSystem->Load("$ALITOP/cern.so/lib/libPythia.so"); - gSystem->Load("$ROOTSYS/lib/libEG.so"); - gSystem->Load("$ROOTSYS/lib/libEGPythia.so"); - gSystem->Load("libGeant3Dummy.so"); //a dummy version of Geant3 - gSystem->Load("PHOS/libPHOSdummy.so"); //the standard Alice classes - gSystem->Load("libgalice.so"); // the standard Alice classes - } - -// Connect the Root Galice file containing Geometry, Kine and Hits - - TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); - if (file) file->Close(); - file = new TFile("galice.root","UPDATE"); - file->ls(); - file->Map(); - - printf ("I'm after Map \n"); - -// Get AliRun object from file or create it if not on file - - if (!gAlice) { - gAlice = (AliRun*)file->Get("gAlice"); - if (gAlice) printf("AliRun object found on file\n"); - if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); - } - printf ("I'm after gAlice \n"); - - AliMUON *MUON = gAlice->GetDetector("MUON"); - - // AliMUONchamber& iChamber; - AliMUONchamber* iChamber; - AliMUONsegmentation* segmentation; - - const Float_t rmin[10] = {17.5,17.5,23.5,23.5,33.5,33.5,43,43,50,50}; - const Float_t rmax[10] = {91.5,91.5,122.5,122.5,173,173,221,221,256.5,256.5}; - - - Int_t Npx[10]; - Int_t Npy[10]; - - - for ( int i=0;i<10;i++) { - Npx[i]=(Int_t)rmax[i]/0.75; - Npy[i]=(Int_t)rmax[i]/0.5; - } - - Int_t nxmax=1026; - Int_t nymax=1026; - AliMUONlist *elem[10][1026][1026]; - TObjArray *obj=new TObjArray; - - Int_t digits[3]; -// -// Loop over events -// - - Int_t Nh=0; - Int_t Nh1=0; - for (int nev=0; nev<= evNumber2; nev++) { - Int_t nparticles = gAlice->GetEvent(nev); - cout << "nev " << nev <TreeH(); - Int_t ntracks = TH->GetEntries(); - Int_t Nc=0; - // - Int_t counter=0; - - for (int icat=0;icatResetHits(); - Int_t nbytes += TH->GetEvent(track); - if (MUON) { - for(AliMUONhit* mHit=(AliMUONhit*)MUON->FirstHit(-1); - mHit; - mHit=(AliMUONhit*)MUON->NextHit()) - { - Int_t nch = mHit->fChamber; // chamber number - Float_t x = mHit->fX; // x-pos of hit - Float_t y = mHit->fY; // y-pos - - iChamber = &(MUON->Chamber(nch-1)); - response=iChamber->GetResponseModel(); - - Int_t nsec=iChamber->Nsec(); - // Int_t rmin = (Int_t)iChamber->frMin; - // Int_t rmax = (Int_t)iChamber->frMax; -// -// - for (AliMUONcluster* mPad=(AliMUONcluster*)MUON->FirstPad(mHit); - mPad; - mPad=(AliMUONcluster*)MUON->NextPad()) - { - Int_t cathode = mPad->fCathode; // chamber number - Int_t nhit = mPad->fHitNumber; // hit number - Int_t qtot = mPad->fQ; // charge - Int_t ipx = mPad->fPadX; // pad number on X - Int_t ipy = mPad->fPadY; // pad number on Y - Int_t iqpad = mPad->fQpad; // charge per pad - Int_t rpad = mPad->fRpad; // r-pos of pad -// -// - if (cathode != (icat+1)) continue; - segmentation=iChamber->GetSegmentationModel(cathode); - // Int_t Npx[nch-1] = segmentation->Npx(); - // Int_t Npy[nch-1] = segmentation->Npy(); - - if (cathode==1) { - Int_t npx=Npx[nch-1]; - Int_t npy=Npy[nch-1]; - } else { - Int_t npx=Npy[nch-1]; - Int_t npy=Npx[nch-1]; - } - - // printf("nch, cathode, rmin, rmax, npx, npy %d %d %d %d %d %d\n", - // nch,cathode,rmin,rmax,npx,npy); - - // printf("icat, iqpad, ipx, ipy %d %d %d %d \n", - // icat, iqpad, ipx, ipy); - - - // check boundaries - if (rpad < rmin[nch-1] || iqpad ==0 || rpad > rmax[nch-1]) continue; - // if (rpad < rmin[nch-1] || iqpad ==0 || rpad > 81.65) continue; - // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue; - - // fill the info array - TVector *trinfo; - trinfo=new TVector(2); - - trinfo(0)=(Float_t)track; - trinfo(1)=(Float_t)iqpad; - - // Int_t digits[3]; - digits[0]=ipx; - digits[1]=ipy; - digits[2]=iqpad; - - - Int_t trk[50]; - Int_t chtrk[50]; - - // build the list of fired pads and update the info - AliMUONlist *pdigit=elem[nch-1][ipy+npy][ipx+npx]; - if (pdigit==0) { - obj->AddAtAndExpand(new AliMUONlist(rpad,digits),counter); - counter++; - // Int_t nentrobj=obj->GetEntriesFast(); - Int_t last=obj->GetLast(); - pdigit=(AliMUONlist*)obj->At(last); - elem[nch-1][ipy+npy][ipx+npx]=pdigit; - // Int_t q=pdigit->fSignal; - // list of tracks - TObjArray *trlist=(TObjArray*)pdigit->TrackList(); - trlist->Add(trinfo); - } else { - // update charge - (*pdigit).fSignal+=iqpad; - // update list of tracks - TObjArray* trlist=(TObjArray*)pdigit->TrackList(); - Int_t nptracks=trlist->GetEntriesFast(); - for (Int_t tr=0;trAt(tr); - Int_t entries=ptrk->GetNrows(); - TVector &vtrk = *ptrk; - trk[tr]=(Int_t)vtrk(0); - chtrk[tr]=(Int_t)vtrk(1); - if (trk[tr]==track) { - chtrk[tr]+=iqpad; - trlist->RemoveAt(tr); - trinfo(0)=trk[tr]; - trinfo(1)=chtrk[tr]; - trlist->AddAt(trinfo,tr); - } else { - trlist->Add(trinfo); - } - } //end loop over list of tracks for one pad - } // end if pdigit - - - } //end loop over clust - - } // hit loop - } // if MUON - } // track loop - - Int_t tracks[10]; - Int_t charges[10]; - cout<<"start filling digits "<fRpad; - Int_t q=address->fSignal; - if ( q <= zero_supm || rpad > 55) continue; - // if ( q <= zero_supm ) continue; - if ( q > adc_satm) q=adc_satm; - digits[0]=(*address).fPadX; - digits[1]=(*address).fPadY; - digits[2]=address->fSignal; - - TObjArray* trlist=(TObjArray*)address->TrackList(); - Int_t nptracks=trlist->GetEntriesFast(); - // this should be changed to accomodate the real number of tracks - if (nptracks > 10) { - cout<<"Attention - nptracks > 3 "<At(tr); - Int_t entries=pp->GetNrows(); - TVector &v2 = *pp; - tracks[tr]=(Int_t)v2(0); - charges[tr]=(Int_t)v2(1); - } //end loop over list of tracks for one pad - - // fill digits - MUON->AddDigits(id+1,tracks,charges,digits); - nd++; - - } // end loop over ix - } // end loop over iy - cout<<"I'm out of the loops over pads"<TreeD()->Fill(); - TTree *TD=gAlice->TreeD(); - int ndig=TD->GetEntries(); - cout<<"number of digits "<Dch1())->GetEntriesFast(); - cout<<"number of digits 1 "<Dch2())->GetEntriesFast(); - cout<<"number of digits 2 "<Dch3())->GetEntriesFast(); - cout<<"number of digits 3 "<Dch4())->GetEntriesFast(); - cout<<"number of digits 4 "<Dch5())->GetEntriesFast(); - cout<<"number of digits 5 "<Dch6())->GetEntriesFast(); - cout<<"number of digits 6 "<Dch7())->GetEntriesFast(); - cout<<"number of digits 7 "<Dch8())->GetEntriesFast(); - cout<<"number of digits 8 "<Dch9())->GetEntriesFast(); - cout<<"number of digits 9 "<Dch10())->GetEntriesFast(); - cout<<"number of digits 10 "<ResetDigits(); - - - // char hname[30]; - // sprintf(hname,"TreeD%d",nev); - // gAlice->TreeD()->Write(hname); - - } //end loop over cathodes - - char hname[30]; - sprintf(hname,"TreeD%d",nev); - gAlice->TreeD()->Write(hname); - // MUON->ResetDigits(); - // if (CathodeIndex) CathodeIndex->Clear(); - - // file->Write(); - - file->ls(); - file->Map(); - } // event loop - - // delete [] CathodeIndex; - - file->Close(); - cout<<"END digitisation "<GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (!file) file = new TFile("galice.root"); + +// Get AliRun object from file or create it if not on file + + if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + } +// Create some histograms + + TH2F *h21 = new TH2F("h21","Hits",100,-100,100,100,-100,100); + TH2F *h22 = new TH2F("h22","CoG ",100,-100,100,100,-100,100); + TH1F *h1 = new TH1F("h1","Multiplicity",30,-0.5,29.5); + TH1F *hmult = new TH1F("hmult","Multiplicity",30,-0.5,29.5); + TH1F *hresx = new TH1F("hresx","Residuals",100,-4,4); + TH1F *hresy = new TH1F("hresy","Residuals",100,-.1,.1); + TH1F *hresym = new TH1F("hresym","Residuals",100,-500,500); +// +// Loop over events +// + Int_t Nh=0; + Int_t Nh1=0; + for (int nev=0; nev<= evNumber2; nev++) { + Int_t nparticles = gAlice->GetEvent(nev); + cout << "nev " << nev <TreeH(); + Int_t ntracks = TH->GetEntries(); + cout<<"ntracks "<GetModule("MUON"); + TClonesArray *Particles = gAlice->Particles(); + TTree *TR = gAlice->TreeR(); + Int_t nent=TR->GetEntries(); + printf("Found %d entries in the tree (must be one per cathode per event! + 1empty)\n",nent); + if (MUON) { + for (Int_t ich=0;ich<1;ich++) { + TClonesArray *MUONrawclust = MUON->RawClustAddress(ich); + TClonesArray *MUONdigits = MUON->DigitsAddress(ich); + for (Int_t icat=1; icat<2; icat++) { + MUON->ResetRawClusters(); + nbytes += TR->GetEvent(icat); + Int_t nrawcl = MUONrawclust->GetEntries(); + printf( + "Found %d raw-clusters for cathode %d in chamber %d \n" + ,nrawcl,icat,ich+1); + + + gAlice->ResetDigits(); + + Int_t nent=(Int_t)gAlice->TreeD()->GetEntries(); + gAlice->TreeD()->GetEvent(nent-2+icat-1); + Int_t ndigits = MUONdigits->GetEntriesFast(); + printf( + "Found %d digits for cathode %d in chamber %d \n" + ,ndigits,icat,ich+1); + + + Int_t TotalMult =0; + + for (Int_t iraw=0; iraw < nrawcl; iraw++) { + mRaw = (AliMUONRawCluster*)MUONrawclust->UncheckedAt(iraw); + Int_t mult=mRaw->fMultiplicity; + h1->Fill(mult,float(1)); + TotalMult+=mult; + Int_t itrack=mRaw->fTracks[0]; + Float_t xrec=mRaw->fX; + Float_t yrec=mRaw->fY; + Float_t R=TMath::Sqrt(xrec*xrec+yrec*yrec); + if (R > 55.2) continue; + if (itrack ==1) continue; + Float_t res[2]; + Int_t nres=0; + nbytes=0; + gAlice->ResetHits(); + Int_t nbytes += TH->GetEvent(itrack); + + for(AliMUONHit* mHit=(AliMUONHit*)MUON->FirstHit(-1); + mHit; + mHit=(AliMUONHit*)MUON->NextHit()) + { + Int_t nch = mHit->fChamber; // chamber number + Float_t x = mHit->fX; // x-pos of hit + Float_t y = mHit->fY; // y-pos + if (nch==(ich+1)){ + hresx->Fill(xrec-x,float(1)); + hresy->Fill(yrec-y,float(1)); + if ((yrec-y)*1e4 <500 ) + hresym->Fill((yrec-y)*1e4,float(1)); + if (TMath::Abs(yrec-y)>.02) { + h22->Fill(mRaw->fX,mRaw->fY,float(1)); + hmult->Fill(mult,float(1)); + } + } // chamber + } //hit + } //iraw + printf("Total Cluster Multiplicity %d \n" , TotalMult); + } // icat + } // ich + } // end if MUON + } // event loop + TCanvas *c1 = new TCanvas("c1","Charge and Residuals",400,10,600,700); + pad11 = new TPad("pad11"," ",0.01,0.51,0.49,0.99); + pad12 = new TPad("pad12"," ",0.51,0.51,0.99,0.99); + pad13 = new TPad("pad13"," ",0.01,0.01,0.49,0.49); + pad14 = new TPad("pad14"," ",0.51,0.01,0.99,0.49); + pad11->SetFillColor(11); + pad12->SetFillColor(11); + pad13->SetFillColor(11); + pad14->SetFillColor(11); + pad11->Draw(); + pad12->Draw(); + pad13->Draw(); + pad14->Draw(); + + pad11->cd(); + hresx->SetFillColor(42); + hresx->SetXTitle("xrec-x"); + hresx->Draw(); + + pad12->cd(); + hresy->SetFillColor(42); + hresy->SetXTitle("yrec-y"); + hresy->Draw(); + + pad13->cd(); + h1->SetFillColor(42); + h1->SetXTitle("multiplicity"); + h1->Draw(); + + pad14->cd(); + hresym->SetFillColor(42); + hresym->SetXTitle("yrec-y"); + hresym->Fit("gaus"); + hresym->Draw(); + TCanvas *c2 = new TCanvas("c2","Charge and Residuals",400,10,600,700); + pad21 = new TPad("pad21"," ",0.01,0.51,0.49,0.99); + pad22 = new TPad("pad22"," ",0.51,0.51,0.99,0.99); + pad23 = new TPad("pad23"," ",0.01,0.01,0.49,0.49); + pad24 = new TPad("pad24"," ",0.51,0.01,0.99,0.49); + pad21->SetFillColor(11); + pad22->SetFillColor(11); + pad23->SetFillColor(11); + pad24->SetFillColor(11); + pad21->Draw(); + pad22->Draw(); + pad23->Draw(); + pad24->Draw(); + + pad21->cd(); + h22->SetFillColor(42); + h22->SetXTitle("x"); + h22->SetYTitle("y"); + h22->Draw(); + + pad22->cd(); + hmult->SetFillColor(42); + hmult->SetXTitle("multiplicity"); + hmult->Draw(); + +} + + + diff --git a/MUON/MUONocc.C b/MUON/MUONocc.C new file mode 100644 index 00000000000..b0a3af92453 --- /dev/null +++ b/MUON/MUONocc.C @@ -0,0 +1,297 @@ +void MUONocc (Int_t evNumber1=0,Int_t evNumber2=0, Int_t ic=1) +{ +///////////////////////////////////////////////////////////////////////// +// This macro is a small example of a ROOT macro +// illustrating how to read the output of GALICE +// and do some analysis. +// +///////////////////////////////////////////////////////////////////////// + +// Dynamically link some shared libs + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + + + if (!file) { + printf("\n Creating galice.root \n"); + file = new TFile("galice.root"); + } else { + printf("\n galice.root found in file list"); + } + file->ls(); + +// Get AliRun object from file or create it if not on file + if (!gAlice) { + gAlice = (AliRun*)(file->Get("gAlice")); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) { + printf("\n create new gAlice object"); + gAlice = new AliRun("gAlice","Alice test program"); + } + } + +// Create some histograms + + TH1F *Hits[10], *HitDensity[10], *Occ0[10],*Occ1[10], *Mult[10]; + for (Int_t i=0; i<10; i++) { + Hits[i] = new TH1F("hits1","Hit Distribution",26,0,260); + Hits[i]->SetFillColor(0); + Hits[i]->SetXTitle("R (cm)"); + + HitDensity[i] = new TH1F("dhits1","Hit Density Distribution",26,0,260); + HitDensity[i]->SetFillColor(0); + HitDensity[i]->SetXTitle("R (cm)"); + + Occ0[i] = new TH1F("occ0","Occupancy Density",26,0,260); + Occ0[i] -> SetFillColor(0); + Occ0[i] -> SetXTitle("R (cm)"); + Occ1[i] = new TH1F("occ1","Occupancy",26,0,260); + Occ1[i] -> SetFillColor(0); + Occ1[i] -> SetXTitle("R (cm)"); + Occ1[i] -> SetYTitle("Occupancy"); + Mult[i] = new TH1F("mult","Mult distribution",26,0,260); + Mult[i] -> SetFillColor(0); + Mult[i] -> SetXTitle("R (cm)"); + } + + + TH1F *theta = new TH1F("theta","Theta distribution",180,0,180); + + TH1F *emult = new TH1F("emult","Event Multiplicity",100,0,1000); + AliMUONChamber* iChamber; + AliMUONSegmentation* seg; + +// +// Loop over events +// + Float_t dpx[2], dpy[2]; + Int_t mdig =0; + Int_t nhit=0; + + for (Int_t nev=0; nev<= evNumber2; nev++) { + Int_t nparticles = gAlice->GetEvent(nev); + if (nev < evNumber1) continue; + if (nparticles <= 0) return; + + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); + printf("\n track %d %d \n ", nev, MUON); + + TTree *TH = gAlice->TreeH(); + Int_t ntracks = TH->GetEntries(); +// +// Loop over events +// + Int_t EvMult=0; + + for (Int_t track=0; trackResetHits(); + Int_t nbytes += TH->GetEvent(track); + if (MUON) { +// +// Loop over hits +// + Int_t NperCh=0; + + for(AliMUONHit* mHit=(AliMUONHit*)MUON->FirstHit(-1); + mHit; + mHit=(AliMUONHit*)MUON->NextHit()) + { + Int_t nch = mHit->fChamber; // chamber number + Float_t x = mHit->fX; // x-pos of hit + Float_t y = mHit->fY; // y-pos + Float_t Eloss = mHit->fEloss; + Float_t Theta = mHit->fTheta; + theta->Fill(Theta,(float) 1); + if (nch >10) continue; + if (nch ==1) EvMult++; +// +// + iChamber = & MUON->Chamber(nch-1); + response= iChamber.GetResponseModel(); + seg = iChamber.GetSegmentationModel(1); + NperCh++; + Int_t i,j; + seg->GetPadIxy(x,y,i,j); + Int_t isec = seg->Sector(i,j); + if (isec ==1 && nch==ic) nhit++; + + Float_t a=seg->Dpx(isec)*seg->Dpy(isec); + Float_t r=TMath::Sqrt(x*x+y*y); + Float_t wgt=1/(2*10*TMath::Pi()*r)/(evNumber2+1); + wgt=wgt*(1.+24./(2.*TMath::Pi()*r)); + Hits[nch-1]->Fill(r,(float) 1); + HitDensity[nch-1]->Fill(r,wgt); + Occ0[nch-1]->Fill(r,wgt*a); + } // hit loop + } // if MUON + } // track loop + emult->Fill(Float_t(EvMult), (Float_t) 1); + + Int_t iseg=1; + + for (Int_t ich=0; ich<10; ich++) { + iChamber = & MUON->Chamber(ich); + seg=iChamber.GetSegmentationModel(iseg); + gAlice->ResetDigits(); + gAlice->TreeD()->GetEvent(iseg); + TClonesArray *MUONDigits = MUON->DigitsAddress(ich); + Int_t Ndigits=MUONDigits->GetEntriesFast(); + AliMUONDigit* dig; + printf("\n Reading %d digits\n", Ndigits); + if (MUONDigits) { + for (Int_t ndig=0; ndigUncheckedAt(ndig); + Int_t i=dig->fPadX; + Int_t j=dig->fPadY; + Float_t x,y; + seg->GetPadCxy(i,j,x,y); + Int_t isec = seg->Sector(i,j); + Float_t a=seg->Dpx(isec)*seg->Dpy(isec); + Float_t r=TMath::Sqrt(x*x+y*y); +// if (r<25) +// printf("\n Sector,a %d %f", isec,a); + if (isec==1) mdig++; + + Float_t wgt; + wgt=1/(2.*10.*TMath::Pi()*r)/(evNumber2+1)*a; +// Take into account inefficiency due to frames + wgt=wgt*(1.+24./(2.*TMath::Pi()*r)); + Occ1[ich]->Fill(r,wgt); + } // digit loop + Mult[ich]->Divide(Occ1[ich],Occ0[ich]); + } // chamber loop + } // if MUONDigits + } // event loop +// + printf("\n hits, digits %d %d\n ", nhit, mdig); + + + +//Create a canvas, set the view range, show histograms + TCanvas *c1 = new TCanvas("c1","Hit Densities",400,10,600,700); + pad11 = new TPad("pad11"," ",0.01,0.51,0.49,0.99); + pad12 = new TPad("pad12"," ",0.51,0.51,0.99,0.99); + pad13 = new TPad("pad13"," ",0.01,0.01,0.49,0.49); + pad14 = new TPad("pad14"," ",0.51,0.01,0.99,0.49); + pad11->SetFillColor(0); + pad12->SetFillColor(0); + pad13->SetFillColor(0); + pad14->SetFillColor(0); + pad11->Draw(); + pad12->Draw(); + pad13->Draw(); + pad14->Draw(); + + pad11->cd(); + HitDensity[0]->Draw(); + pad12->cd(); + HitDensity[1]->Draw(); + pad13->cd(); + HitDensity[2]->Draw(); + pad14->cd(); + HitDensity[3]->Draw(); + + TCanvas *c2 = new TCanvas("c2","Hit Densities",400,10,600,700); + pad21 = new TPad("pad21"," ",0.01,0.51,0.49,0.99); + pad22 = new TPad("pad22"," ",0.51,0.51,0.99,0.99); + pad23 = new TPad("pad23"," ",0.01,0.01,0.49,0.49); + pad24 = new TPad("pad24"," ",0.51,0.01,0.99,0.49); + pad21->SetFillColor(0); + pad22->SetFillColor(0); + pad23->SetFillColor(0); + pad24->SetFillColor(0); + pad21->Draw(); + pad22->Draw(); + pad23->Draw(); + pad24->Draw(); + + pad21->cd(); + HitDensity[4]->Draw(); + pad22->cd(); + HitDensity[5]->Draw(); + pad23->cd(); + HitDensity[6]->Draw(); + pad24->cd(); + HitDensity[7]->Draw(); + + TCanvas *c3 = new TCanvas("c3","Hit Densities",400,10,600,700); + pad31 = new TPad("pad31"," ",0.01,0.51,0.49,0.99); + pad32 = new TPad("pad32"," ",0.51,0.51,0.99,0.99); + pad33 = new TPad("pad33"," ",0.01,0.01,0.49,0.49); + pad34 = new TPad("pad34"," ",0.51,0.01,0.99,0.49); + pad31->SetFillColor(0); + pad32->SetFillColor(0); + pad33->SetFillColor(0); + pad34->SetFillColor(0); + pad31->Draw(); + pad32->Draw(); + pad33->Draw(); + pad34->Draw(); + + pad31->cd(); + HitDensity[8]->Draw(); + pad32->cd(); + HitDensity[9]->Draw(); + + TCanvas *c4 = new TCanvas("c4","Occupancies",400,10,600,700); + pad41 = new TPad("pad41"," ",0.01,0.51,0.49,0.99); + pad42 = new TPad("pad42"," ",0.51,0.51,0.99,0.99); + pad43 = new TPad("pad43"," ",0.01,0.01,0.49,0.49); + pad44 = new TPad("pad44"," ",0.51,0.01,0.99,0.49); + pad41->SetFillColor(0); + pad42->SetFillColor(0); + pad43->SetFillColor(0); + pad44->SetFillColor(0); + pad41->Draw(); + pad42->Draw(); + pad43->Draw(); + pad44->Draw(); + + + pad41->cd(); + Occ1[0]->Draw(); + pad42->cd(); + Occ1[2]->Draw(); + pad43->cd(); + Occ1[4]->Draw(); + pad44->cd(); + Occ1[6]->Scale(1.25); + Occ1[6]->Draw(); + + TCanvas *c5 = new TCanvas("c5","Occupancies",400,10,600,700); + pad51 = new TPad("pad41"," ",0.01,0.51,0.49,0.99); + pad52 = new TPad("pad42"," ",0.51,0.51,0.99,0.99); + pad53 = new TPad("pad43"," ",0.01,0.01,0.49,0.49); + pad54 = new TPad("pad44"," ",0.51,0.01,0.99,0.49); + pad51->SetFillColor(0); + pad52->SetFillColor(0); + pad53->SetFillColor(0); + pad54->SetFillColor(0); + pad51->Draw(); + pad52->Draw(); + pad53->Draw(); + pad54->Draw(); + + + pad51->cd(); + Occ1[8]->Scale(1.25); + + Occ1[8]->Draw(); +} + + + + + + + + + + diff --git a/MUON/MUONrawclusters.C b/MUON/MUONrawclusters.C index fa854493424..00e005dac76 100644 --- a/MUON/MUONrawclusters.C +++ b/MUON/MUONrawclusters.C @@ -2,12 +2,25 @@ void MUONrawclusters (Int_t evNumber1=0,Int_t evNumber2=0) { -///////////////////////////////////////////////////////////////////////// -// This macro is a small example of a ROOT macro -// illustrating how to read the output of GALICE -// and do some analysis. -// -///////////////////////////////////////////////////////////////////////// + ////////////////////////////////////// + // // + // ROOT macro for ALICE Dimuon Arm: // + // Clusterization of digits // + // // + ////////////////////////////////////// + // + // Adds the tree TR for raw clusters + // to the ROOT file "galice.root" + // containing the digits (tree TD). + // + // Arguments: + // evNumber1 = first event number to act on in file "galice.root" + // evNumber2 = last event number to act on in file "galice.root" + // + // Input/output file: + // "galice.root" + // + //__________________________________________________________________________ // Dynamically link some shared libs @@ -28,113 +41,47 @@ void MUONrawclusters (Int_t evNumber1=0,Int_t evNumber2=0) if (gAlice) printf("AliRun object found on file\n"); if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); } -// + // Set reconstruction models // // Get pointers to Alice detectors and Digits containers AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); - - RecModel1 = new AliMUONClusterFinder(); - RecModel1->SetNperMax(90); - //RecModel1->SetClusterSize(12); - RecModel1->SetClusterSize(100); - RecModel1->SetDeclusterFlag(0); - MUON->SetReconstructionModel(0,RecModel1); - - RecModel2 = new AliMUONClusterFinder(); - RecModel2->SetNperMax(90); - //RecModel2->SetClusterSize(12); - RecModel2->SetClusterSize(100); - RecModel2->SetDeclusterFlag(0); - MUON->SetReconstructionModel(1,RecModel2); - - RecModel3 = new AliMUONClusterFinder(); - RecModel3->SetNperMax(90); - //RecModel3->SetClusterSize(12); - RecModel3->SetClusterSize(100); - RecModel3->SetDeclusterFlag(0); - MUON->SetReconstructionModel(2,RecModel3); - - RecModel4 = new AliMUONClusterFinder(); - RecModel4->SetNperMax(90); - //RecModel4->SetClusterSize(12); - RecModel4->SetClusterSize(100); - RecModel4->SetDeclusterFlag(0); - MUON->SetReconstructionModel(3,RecModel4); - - //RecModel5 = new AliMUONClusterFinderv0(); - RecModel5 = new AliMUONClusterFinder(); - RecModel5->SetNperMax(90); - //RecModel5->SetClusterSize(15); - RecModel5->SetClusterSize(100); - RecModel5->SetDeclusterFlag(0); - MUON->SetReconstructionModel(4,RecModel5); - - //RecModel6 = new AliMUONClusterFinderv0(); - RecModel6 = new AliMUONClusterFinder(); - RecModel6->SetNperMax(90); - //RecModel6->SetClusterSize(15); - RecModel6->SetClusterSize(100); - RecModel6->SetDeclusterFlag(0); - MUON->SetReconstructionModel(5,RecModel6); - - RecModel7 = new AliMUONClusterFinder(); - RecModel7->SetNperMax(90); - //RecModel7->SetClusterSize(9); - RecModel7->SetClusterSize(100); - RecModel7->SetDeclusterFlag(0); - MUON->SetReconstructionModel(6,RecModel7); - - RecModel8 = new AliMUONClusterFinder(); - RecModel8->SetNperMax(90); - //RecModel8->SetClusterSize(9); - RecModel8->SetClusterSize(100); - RecModel8->SetDeclusterFlag(0); - MUON->SetReconstructionModel(7,RecModel8); - - RecModel9 = new AliMUONClusterFinder(); - RecModel9->SetNperMax(90); - //RecModel9->SetClusterSize(9); - RecModel9->SetClusterSize(100); - RecModel9->SetDeclusterFlag(0); - MUON->SetReconstructionModel(8,RecModel9); - - RecModel10 = new AliMUONClusterFinder(); - RecModel10->SetNperMax(90); - // RecModel1->SetClusterSize(9); - RecModel1->SetClusterSize(100); - RecModel10->SetDeclusterFlag(0); - MUON->SetReconstructionModel(9,RecModel10); - - + for (Int_t i=0; i<10; i++) { + AliMUONChamber* iChamber= &(MUON->Chamber(i)); + AliMUONResponse* response = iChamber->ResponseModel(); + AliMUONSegmentation* seg1 = iChamber->SegmentationModel(1); + AliMUONSegmentation* seg2 = iChamber->SegmentationModel(2); +// + RecModel = new AliMUONClusterFinderVS(); + RecModel->SetNperMax(90); + RecModel->SetClusterSize(100); + RecModel->SetDeclusterFlag(0); + RecModel->SetSegmentation(seg1,seg2); + RecModel->SetResponse(response); +// RecModel->SetTracks(16,17); +// RecModel->SetTracks(266,267); + MUON->SetReconstructionModel(i,RecModel); + } // // Loop over events // Int_t Nh=0; Int_t Nh1=0; - for (int nev=0; nev<= evNumber2; nev++) { + for (int nev=evNumber1; nev<= evNumber2; nev++) { Int_t nparticles = gAlice->GetEvent(nev); cout << "nev " << nev <TreeH(); - Int_t ntracks = TH->GetEntries(); - cout<<"ntracks "<Particles(); TTree *TD = gAlice->TreeD(); Int_t nent=TD->GetEntries(); - //printf("Found %d entries in the tree (must be one per cathode per event!)\n",nent); if (MUON) { MUON->FindClusters(nev,nent-2); } // end if MUON } // event loop - //file->ls(); + file->Close(); } diff --git a/MUON/MUONcathcorel.C b/MUON/MUONrechits.C similarity index 93% rename from MUON/MUONcathcorel.C rename to MUON/MUONrechits.C index 46213327f80..f72b3684c66 100644 --- a/MUON/MUONcathcorel.C +++ b/MUON/MUONrechits.C @@ -1,6 +1,6 @@ #include "iostream.h" -void MUONcathcorel (Int_t evNumber1=0,Int_t evNumber2=9) +void MUONrechits (Int_t evNumber1=0,Int_t evNumber2=0) { ///////////////////////////////////////////////////////////////////////// // This macro is a small example of a ROOT macro @@ -45,7 +45,7 @@ void MUONcathcorel (Int_t evNumber1=0,Int_t evNumber2=9) cout << "nparticles " <CathodeCorrelation(nev); + MUON->ReconstructHits(nev); } // event loop file->Close(); } diff --git a/MUON/MUONstraggling.C b/MUON/MUONstraggling.C new file mode 100644 index 00000000000..1674453f456 --- /dev/null +++ b/MUON/MUONstraggling.C @@ -0,0 +1,190 @@ + TH1F *mass1 = new TH1F("mass1","Invariant Mass",120,0,12); + TH1F *mass2 = new TH1F("mass2","Invariant Mass",100,9.0,10.5); + TH1F *mass3 = new TH1F("mass3","Invariant Mass",100,2.5,3.5); +void MUONstraggling (Int_t evNumber1=0,Int_t evNumber2=0) +{ +///////////////////////////////////////////////////////////////////////// +// This macro is a small example of a ROOT macro +// illustrating how to read the output of GALICE +// and do some analysis. +// +///////////////////////////////////////////////////////////////////////// + +// Dynamically link some shared libs + static Float_t xmuon, ymuon; + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + + + if (!file) { + printf("\n Creating galice.root \n"); + file = new TFile("galice.root"); + } else { + printf("\n galice.root found in file list"); + } + file->ls(); + +// Get AliRun object from file or create it if not on file + if (!gAlice) { + gAlice = (AliRun*)(file->Get("gAlice")); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) { + printf("\n Create new gAlice object"); + gAlice = new AliRun("gAlice","Alice test program"); + } + } + + +// Create some histograms + + + AliMUONChamber* iChamber; +// +// Loop over events +// + Int_t Nh=0; + Int_t Nh1=0; + for (Int_t nev=0; nev<= evNumber2; nev++) { + Int_t nparticles = gAlice->GetEvent(nev); + //cout << "nparticles " << nparticles <GetModule("MUON"); + + + TTree *TH = gAlice->TreeH(); + Int_t ntracks = TH->GetEntries(); +// +// Loop over tracks +// + + Float_t pups[4]={0,0,0,0}; + for (Int_t track=0; trackResetHits(); + Int_t nbytes += TH->GetEvent(track); + + + if (MUON) { + for(AliMUONHit* mHit=(AliMUONHit*)MUON->FirstHit(-1); + mHit; + mHit=(AliMUONHit*)MUON->NextHit()) + { + Int_t nch = mHit->fChamber; // chamber number + Float_t x = mHit->fX; // x-pos of hit + Float_t y = mHit->fY; // y-pos + Float_t z = mHit->fZ; // y-pos + Float_t p=mHit->fPTot; + Float_t px=mHit->fCxHit; + Float_t py=mHit->fCyHit; + Float_t pz=mHit->fCzHit; + + if (nch != 1) continue; + + Int_t ipart = mHit->fParticle; + TClonesArray *fPartArray = gAlice->Particles(); + TParticle *Part; + Int_t ftrack = mHit->fTrack; + Part = (TParticle*) fPartArray->UncheckedAt(ftrack); + Int_t ipart = Part->GetPdgCode(); + TParticle *Mother; + Float_t px0=Part->Px(); + Float_t py0=Part->Py(); + Float_t pz0=Part->Pz(); + Float_t e0=Part->Energy(); + + if (ipart == kMuonPlus || ipart == kMuonMinus) { +// +// Branson Correction +// + Float_t zch=505.; + Float_t r=TMath::Sqrt(x*x+y*y); + Float_t zb; + + if (r<26.3611) { + zb=466.; + } else { + zb=441.; + } + + Float_t xb=x-(zch-zb)*px/pz; + Float_t yb=y-(zch-zb)*py/pz; + Float_t tx=xb/zb; + Float_t ty=yb/zb; + pz=zb*p/TMath::Sqrt(zb*zb+xb*xb+yb*yb); + px=pz*tx; + py=pz*ty; + +// +// Energy Correction +// +// + Float_t corr=(p+CorrectP(p,mHit->fTheta))/p; + pups[0]+=p*corr; + pups[1]+=px*corr; + pups[2]+=py*corr; + pups[3]+=pz*corr; + } + } // hits + } // if MUON + } // tracks + Float_t mass=TMath::Sqrt(pups[0]*pups[0]-pups[1]*pups[1]-pups[2]*pups[2]-pups[3]*pups[3]); + mass1->Fill(mass, 1.); + mass2->Fill(mass, 1.); + mass3->Fill(mass, 1.); + } // event +//Create a canvas, set the view range, show histograms + TCanvas *c1 = new TCanvas("c1","Vertices from electrons and positrons",400,10,600,700); + c1->Divide(2,2); + + c1->cd(1); + mass1->SetFillColor(42); + mass1->SetXTitle("Mass (GeV)"); + mass1->Draw(); + + c1->cd(2); + mass2->SetFillColor(42); + mass2->SetXTitle("Mass (GeV)"); + mass2->Draw(); + + c1->cd(3); + mass3->SetFillColor(42); + mass3->SetXTitle("Mass (GeV)"); + mass3->Draw(); + +} + + + +Float_t CorrectP(Float_t p, Float_t theta) +{ + if (theta<3.) { +//W + if (p<15) { + return 2.737+0.0494*p-0.001123*p*p; + } else { + return 3.0643+0.01346*p; + } + } else { +//Pb + if (p<15) { + return 2.1380+0.0351*p-0.000853*p*p; + } else { + return 2.407+0.00702*p; + } + } +} + + + + + + diff --git a/MUON/MUONtestabso.C b/MUON/MUONtestabso.C index e8c4fb4f001..8a8feaffcde 100644 --- a/MUON/MUONtestabso.C +++ b/MUON/MUONtestabso.C @@ -8,7 +8,8 @@ void MUONtestabso (Int_t evNumber1=0,Int_t evNumber2=0) ///////////////////////////////////////////////////////////////////////// // Dynamically link some shared libs - + static Float_t xmuon, ymuon; + if (gClassTable->GetID("AliRun") < 0) { gROOT->LoadMacro("loadlibs.C"); loadlibs(); @@ -32,128 +33,241 @@ void MUONtestabso (Int_t evNumber1=0,Int_t evNumber2=0) gAlice = (AliRun*)(file->Get("gAlice")); if (gAlice) printf("AliRun object found on file\n"); if (!gAlice) { - printf("\n create new gAlice object"); + printf("\n Create new gAlice object"); gAlice = new AliRun("gAlice","Alice test program"); } } - printf ("I'm after gAlice \n"); // Create some histograms - TH1F *zv = new TH1F("zv","z vertex" - ,100,450..,506.); - TH1F *xv = new TH1F("xv","x vertex" - ,140,-70.,70.); - TH1F *yv = new TH1F("yv","y vertex" - ,140,-70.,70.); + TH1F *zv = new TH1F("zv","z vertex" ,140,470.,505.); + TH1F *xv = new TH1F("xv","x vertex" ,140,-70.,70.); + TH1F *yv = new TH1F("yv","y vertex", 140,-70.,70.); + + TH1F *ip = new TH1F("ip","geant part",50,0.,10.); + TH2F *rzv = new TH2F("rzv","R-z vert",100,502,504.,100,0.,100.); + + TH1F *ptUps = new TH1F("ptUps","pT Upsilon",50,0.,25.); + TH1F *hde = new TH1F("hde","dE",200,0.,50); + TH1F *hde2 = new TH1F("hde2","dE",100,1.5,5.5); + TH2F *hdevsn = new TH2F("hdevsn","dE vs N electron",100,0.,15., 20, 0.,20.); - TH1F *ip = new TH1F("ip","geant part" - ,50,0.,10.); - TH2F *rzv = new TH2F("rzv","R-z vert" - ,100,500.,506.,50,0.,50.); + TH1F *ekine = new TH1F("ekine","E_kin electrons",70,-5,2); + TH1F *etheta = new TH1F("etheta","Theta electrons",90,0,90); + TH1F *edr = new TH1F("edr","Distance to muon",100,0,10); - AliMUONchamber* iChamber; + TH1F *de = new TH1F("de","correction",100,-1,1); + + TH1F *dtheta = new TH1F("dtheta","Delta Theta" ,200,-5.,5.); + AliMUONChamber* iChamber; // // Loop over events // Int_t Nh=0; Int_t Nh1=0; + Int_t Nel1=0; + Int_t Nel2=0; + Int_t Nel3=0; + Int_t Nel4=0; + for (Int_t nev=0; nev<= evNumber2; nev++) { - cout << "nev " << nev <GetEvent(nev); - cout << "nparticles " << nparticles <GetModule("MUON"); - printf("\n nev %d \n ", nev); + TTree *TH = gAlice->TreeH(); Int_t ntracks = TH->GetEntries(); // // Loop over tracks // + + Float_t dE; + for (Int_t track=0; trackResetHits(); Int_t nbytes += TH->GetEvent(track); if (MUON) { - for(AliMUONhit* mHit=(AliMUONhit*)MUON->FirstHit(-1); + for(AliMUONHit* mHit=(AliMUONHit*)MUON->FirstHit(-1); mHit; - mHit=(AliMUONhit*)MUON->NextHit()) + mHit=(AliMUONHit*)MUON->NextHit()) { Int_t nch = mHit->fChamber; // chamber number Float_t x = mHit->fX; // x-pos of hit Float_t y = mHit->fY; // y-pos Float_t z = mHit->fZ; // y-pos - - if (nch > 1) continue; - - Int_t ipart = mHit->fParticle; - TClonesArray *fPartArray = gAlice->Particles(); - TParticle *Part; - Int_t ftrack = mHit->fTrack; - Part = (TParticle*) fPartArray->UncheckedAt(ftrack); - //Int_t id = ((TParticle*) fPartArray->UncheckedAt(ftrack))->GetPdgCode(); - ip->Fill((float)ipart); - - if (ipart > 3) continue; - - Float_t xvert = Part->Vx(); // vertex - Float_t yvert = Part->Vy(); // vertex - Float_t zvert = Part->Vz(); // z vertex - xv->Fill(xvert); - yv->Fill(yvert); - zv->Fill(zvert); - Float_t rvert=TMath::Sqrt(xvert*xvert+yvert*yvert); - rzv->Fill(zvert,rvert); - - } - - } - } - } + + if (nch != 1) continue; + + Int_t ipart = mHit->fParticle; + TClonesArray *fPartArray = gAlice->Particles(); + TParticle *Part; + Int_t ftrack = mHit->fTrack; + Part = (TParticle*) fPartArray->UncheckedAt(ftrack); + Int_t ipart = Part->GetPdgCode(); + ip->Fill((float)ipart); + TParticle *Mother; + + Float_t px0=Part->Px(); + Float_t py0=Part->Py(); + Float_t pz0=Part->Pz(); + Float_t thetax0=TMath::ATan2(px0,pz0); + Float_t thetay0=TMath::ATan2(py0,pz0); + + if (ipart == kMuonPlus || ipart == kMuonMinus) { +// Int_t imo = Part->GetFirstMother(); +// Mother = (TParticle*) fPartArray->UncheckedAt(imo); +// Float_t pt = Mother->Pt(); +// ptUps->Fill(pt, (float) 1); + Float_t E=Part->Energy(); + Float_t Eloc=mHit->fPTot; + Float_t corr=Eloc+CorrectP(Eloc,mHit->fTheta); + printf("\n %f %f %f", E, Eloc, corr); + de->Fill(E-corr,1.); + dE = E-Eloc; + if (dE<50) hde->Fill(dE, (float) 1); + if (dE<5.5) hde2->Fill(dE, (float) 1); + xmuon=mHit->fX; + ymuon=mHit->fY; + Float_t thetax=TMath::ATan2(mHit->fCxHit, mHit->fPTot); + Float_t thetay=TMath::ATan2(mHit->fCyHit, mHit->fPTot); + dtheta->Fill((thetax-thetax0)*1000., 1.); + dtheta->Fill((thetay-thetay0)*1000., 1.); + } + + if (ipart == kElectron || ipart == kPositron) { + + + Float_t xvert = Part->Vx(); // vertex + Float_t yvert = Part->Vy(); // vertex + Float_t zvert = Part->Vz(); // z vertex + if (zvert < 503 && mHit->fTheta<90) { + Nelt++; + Float_t px = Part->Px(); + Float_t py = Part->Py(); + Float_t pz = Part->Pz(); + Float_t Ek = Part->Energy()-Part->GetMass(); + + Int_t imo = Part->GetFirstMother(); + Mother = (TParticle*) fPartArray->UncheckedAt(imo); + Int_t imot = Mother->GetPdgCode(); + xv->Fill(xvert); + yv->Fill(yvert); + zv->Fill(zvert); + Float_t rvert=TMath::Sqrt(xvert*xvert+yvert*yvert); + rzv->Fill(zvert,rvert); + ekine->Fill(TMath::Log10(Ek),1.); + etheta->Fill(mHit->fTheta,1.); + Float_t ex=mHit->fX; + Float_t ey=mHit->fY; + dr=TMath::Sqrt((ex-xmuon)*(ex-xmuon)+(ey-ymuon)*(ey-ymuon)); + edr->Fill(dr,1.); + + } + } + + } // hits + } // if MUON + if (Nelt == 1) Nel1++; + if (Nelt == 2) Nel2++; + if (Nelt == 3) Nel3++; + if (Nelt > 3) Nel4++; + hdevsn->Fill(dE, (float) Nelt, (float) 1); + + } // tracks + + } // event //Create a canvas, set the view range, show histograms TCanvas *c1 = new TCanvas("c1","Vetices from electrons and positrons",400,10,600,700); - pad11 = new TPad("pad11"," ",0.01,0.51,0.49,0.99); - pad12 = new TPad("pad12"," ",0.51,0.51,0.99,0.99); - pad13 = new TPad("pad13"," ",0.01,0.01,0.49,0.49); - pad14 = new TPad("pad14"," ",0.51,0.01,0.99,0.49); - pad11->SetFillColor(11); - pad12->SetFillColor(11); - pad13->SetFillColor(11); - pad14->SetFillColor(11); - pad11->Draw(); - pad12->Draw(); - pad13->Draw(); - pad14->Draw(); + c1->Divide(2,2); - pad11->cd(); + c1->cd(1); ip->SetFillColor(42); ip->SetXTitle("ipart"); ip->Draw(); - pad12->cd(); + c1->cd(2); xv->SetFillColor(42); xv->SetXTitle("xvert"); xv->Draw(); - pad13->cd(); + c1->cd(3); yv->SetFillColor(42); yv->SetXTitle("yvert"); yv->Draw(); - pad14->cd(); + c1->cd(4); zv->SetFillColor(42); zv->SetXTitle("zvert"); zv->Draw(); - TCanvas *c2 = new TCanvas("c2","R-Z vertex distribution",400,10,600,700); + TCanvas *c2 = new TCanvas("c2"," ",400,10,600,700); + c2->Divide(2,2); + c2->cd(1); rzv->SetXTitle("zvert"); rzv->SetYTitle("rvert"); rzv->Draw(); + + c2->cd(2); + ptUps->SetXTitle("pt"); + ptUps->Draw(); + + c2->cd(3); + hde->SetXTitle("dE"); + hde->Draw(); + + + c2->cd(4); + hde2->SetXTitle("dE"); + hde2->Draw(); + TCanvas *c3 = new TCanvas("c3"," ",400,10,600,700); + c3->Divide(2,2); + c3->cd(1); + ekine->SetXTitle("E_kin"); + ekine->Draw(); + + c3->cd(2); + etheta->SetXTitle("Theta"); + etheta->Draw(); + + c3->cd(3); + edr->SetXTitle("Distance to muon"); + edr->Draw(); + + c3->cd(4); + dtheta->SetXTitle(" "); + dtheta->Draw(); + +} + +Float_t CorrectP(Float_t p, Float_t theta) +{ + printf("\n %f%", theta); + + if (theta<3.) { +//W + if (p<15) { + return 2.737+0.0494*p-0.001123*p*p; + } else { + return 3.0643+0.01346*p; + } + } else { +//Pb + if (p<15) { + return 2.1380+0.0351*p-0.000853*p*p; + } else { + return 2.407+0.00702*p; + } + } } + diff --git a/MUON/MUONtestrawclust.C b/MUON/MUONtestrawclust.C new file mode 100644 index 00000000000..9ebd6e6310d --- /dev/null +++ b/MUON/MUONtestrawclust.C @@ -0,0 +1,171 @@ +#include "iostream.h" + +void MUONtestrawclust (Int_t evNumber1=0,Int_t evNumber2=0, Int_t ich1=0, Int_t ich2=0) +{ +///////////////////////////////////////////////////////////////////////// +// This macro is a small example of a ROOT macro +// illustrating how to read the output of GALICE +// and do some analysis. +// +///////////////////////////////////////////////////////////////////////// + +// Dynamically link some shared libs + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (!file) file = new TFile("galice.root"); + +// Get AliRun object from file or create it if not on file + + if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + } +// Create some histograms + + TH2F *h21 = new TH2F("h21","Hits",100,-100,100,100,-100,100); + TH2F *h22 = new TH2F("h22","CoG ",100,-100,100,100,-100,100); + TH1F *h1 = new TH1F("h1","Multiplicity",30,-0.5,29.5); + TH1F *hmult = new TH1F("hmult","Multiplicity",30,-0.5,29.5); + TH1F *hresx = new TH1F("hresx","Residuals",100,-4,4); + TH1F *hresy = new TH1F("hresy","Residuals",100,-.1,.1); + TH1F *hresym = new TH1F("hresym","Residuals",100,-500,500); + TH2F *hchi1 = new TH2F("hchi1","Chi2 vs Residuals",100,0,0.2,100,-500,500); + TH2F *hchi2 = new TH2F("hchi2","Chi2 vs Residuals",100,0,20,100,-500,500); +// +// Loop over events +// + Int_t Nh=0; + Int_t Nh1=0; + for (int nev=evNumber1; nev<= evNumber2; nev++) { + Int_t nparticles = gAlice->GetEvent(nev); + cout << "nev " << nev <TreeH(); + Int_t ntracks = TH->GetEntries(); + cout<<"ntracks "<GetModule("MUON"); + TClonesArray *Particles = gAlice->Particles(); + TTree *TR = gAlice->TreeR(); + Int_t nent=TR->GetEntries(); + printf("Found %d entries in the tree (must be one per cathode per event! + 1empty)\n",nent); + if (MUON) { + for (Int_t ich=ich1;ich<=ich2;ich++) { + TClonesArray *MUONrawclust = MUON->RawClustAddress(ich); + // printf ("MUONrawclust %p \n",MUONrawclust); + + for (Int_t icat=1; icat<2; icat++) { + MUON->ResetRawClusters(); + nbytes += TR->GetEvent(icat); + Int_t nrawcl = MUONrawclust->GetEntries(); + printf("Found %d raw clusters for cathode %d in chamber %d \n" + ,nrawcl,icat,ich+1); + for (Int_t iraw=0; iraw < nrawcl; iraw++) { + mRaw = (AliMUONRawCluster*)MUONrawclust->UncheckedAt(iraw); + Int_t mult=mRaw->fMultiplicity[1]; + Int_t itrack=mRaw->fTracks[1]; + printf("\n mult1 mult2 %d %d chi2 %f itrack %d" + ,mRaw->fMultiplicity[0], mRaw->fMultiplicity[1], mRaw->fChi2[0], itrack); + h1->Fill(mult,float(1)); + + Float_t xrec=mRaw->fX[1]; + Float_t yrec=mRaw->fY[0]; + Float_t R=TMath::Sqrt(xrec*xrec+yrec*yrec); + Int_t nres=0; + nbytes=0; + gAlice->ResetHits(); + Int_t nbytes += TH->GetEvent(itrack); + + for(AliMUONHit* mHit=(AliMUONHit*)MUON->FirstHit(-1); + mHit; + mHit=(AliMUONHit*)MUON->NextHit()) + { + Int_t nch = mHit->fChamber; // chamber number + Float_t x = mHit->fX; // x-pos of hit + Float_t y = mHit->fY; // y-pos + if (nch==(ich+1)){ + hresx->Fill(xrec-x,float(1)); + hresy->Fill(yrec-y,float(1)); + hchi1->Fill(mRaw->fChi2[0],(yrec-y)*1e4,float(1)); + hchi2->Fill(mRaw->fChi2[0],(yrec-y)*1e4,float(1)); + + if ((yrec-y)*1e4 <500 ) + hresym->Fill((yrec-y)*1e4,float(1)); + if (mRaw->fChi2[0]>.3) { + h22->Fill(mRaw->fX[1],mRaw->fY[0],float(1)); + hmult->Fill(mult,float(1)); + } + } // chamber + } //hit + } //iraw + } // icat + } // ich + } // end if MUON + } // event loop + TCanvas *c1 = new TCanvas("c1","Charge and Residuals",400,10,600,700); + c1->Divide(2,2); + c1->cd(1); + hresx->SetFillColor(42); + hresx->SetXTitle("xrec-x"); + hresx->Draw(); + + c1->cd(2); + hresy->SetFillColor(42); + hresy->SetXTitle("yrec-y"); + hresy->Draw(); + + c1->cd(3); + h1->SetFillColor(42); + h1->SetXTitle("multiplicity"); + h1->Draw(); + + c1->cd(4); + hresym->SetFillColor(42); + hresym->SetXTitle("yrec-y"); + hresym->Fit("gaus"); + hresym->Draw(); + + TCanvas *c2 = new TCanvas("c2","Charge and Residuals",400,10,600,700); + c2->Divide(2,2); + + c2->cd(1); + h22->SetFillColor(42); + h22->SetXTitle("x"); + h22->SetYTitle("y"); + h22->Draw(); + + c2->cd(2); + hmult->SetFillColor(42); + hmult->SetXTitle("multiplicity"); + hmult->Draw(); + + c2->cd(3); + hchi1->SetFillColor(42); + hchi1->SetXTitle("chi2"); + hchi1->Draw(); + + c2->cd(4); + hchi2->SetFillColor(42); + hchi2->SetXTitle("chi2"); + hchi2->Draw(); + +} + + + diff --git a/MUON/MUONtestzaza.C b/MUON/MUONtestzaza.C deleted file mode 100644 index 43d8a29b297..00000000000 --- a/MUON/MUONtestzaza.C +++ /dev/null @@ -1,87 +0,0 @@ -// option 1 : idres=114 if j/psi -// idres=116 if upsilon - -// option 2 : ireadgeant=1 if geant hits -// ireadgeant=0 if space points - -// option 3 : ibgr=1 if upsilon+background (option 3 usefull only for geant hits) -// ibgr=0 if no background - -void MUONtestzaza (Int_t evNumber1=0, Int_t evNumber2=99, Int_t idres=116, Int_t ireadgeant=1, Int_t ibgr=0) -{ -///////////////////////////////////////////////////////////////////////// -// This macro is a small example of a ROOT macro -// illustrating how to read the output of GALICE -// and do some analysis. -// -///////////////////////////////////////////////////////////////////////// - -// Dynamically link some shared libs - - if (gClassTable->GetID("AliRun") < 0) { - gROOT->LoadMacro("loadlibs.C"); - loadlibs(); - } -// Connect the Root Galice file containing Geometry, Kine and Hits - - TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); - - if (!file) { - printf("\n Creating galice.root \n"); - file = new TFile("galice.root"); - } else { printf("\n galice.root found in file list"); - } - // file->ls(); - -// Get AliRun object from file or create it if not on file - if (!gAlice) { - gAlice = (AliRun*)(file->Get("gAlice")); - if (gAlice) printf("AliRun object found on file\n"); - if (!gAlice) { - printf("\n create new gAlice object"); - gAlice = new AliRun("gAlice","Alice test program"); - } - } - - Double_t seff = 0.95; - Double_t sb0 = 0.7; - Double_t sbl3 = 0.2; - - Int_t ifit = 0; - Int_t idebug = 1; - - AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); - - Int_t nparticles = gAlice->GetEvent(evNumber1); - if (nparticles <= 0) return; - MUON->Init(seff,sb0,sbl3); -// Loop over events -// - Int_t inev_bgd=0; - Int_t nev_bgd=4; - - for (Int_t nev= evNumber1; nev<= evNumber2; nev++) - { - printf("nev=%d\n",nev); - if (nev != evNumber1) Int_t nparticles = gAlice->GetEvent(nev); - if (nev < evNumber1) continue; - if (nparticles <= 0) return; - MUON->FinishEvent(); - if (ireadgeant==1 && ibgr==1) { - if (inev_bgd==nev_bgd) inev_bgd=0; - MUON->Reconst(ifit,idebug,inev_bgd,nev,idres,ireadgeant,"Add","galice_bgr.root"); - inev_bgd++; - } - else - MUON->Reconst(ifit,idebug,inev_bgd,nev,idres,ireadgeant,"rien1","rien2"); - MUON->FinishEvent(); - - - - } // event loop - - MUON->Close(); -} - - - diff --git a/MUON/MUONtracking.C b/MUON/MUONtracking.C new file mode 100644 index 00000000000..80a47cabdc8 --- /dev/null +++ b/MUON/MUONtracking.C @@ -0,0 +1,131 @@ +void MUONtracking (Int_t evNumber1=0, Int_t evNumber2=99, Int_t idres=116, Int_t ireadgeant=1, Int_t ibgr=1, Int_t nev_bgd=10) +{ + ////////////////////////////////////// + // // + // ROOT macro for ALICE Dimuon Arm: // + // Track reconstruction // + // // + ////////////////////////////////////// + // + // Reconstructs tracks from events in the ROOT file "galice.root". + // Track reconstruction is performed (argument "ireadgeant") + // either directly from GEANT hits (tree TH), + // or from raw clusters (tree TR) constructed from digits (tree TD). + // Eventually (argument "ibgr"), background GEANT hits + // are also taken into account from the ROOT file "galice_bgr.root". + // + // Arguments: + // evNumber1 = first event number to act on in file "galice.root" + // evNumber2 = last event number to act on in file "galice.root" + // idres : used for statistics + // = 116 for Upsilon + // = 114 for J/Psi + // ireadgeant = 1 to reconstruct tracks directly from GEANT hits + // = 0 to reconstruct tracks from raw clusters + // ibg : used only if "ireadgeant" = 1 + // = 0 if no background GEANT hits to be taken into account; + // = 1 if background GEANT hits + // to be taken into account in file "galice_bgr.root" + // used only if "ireadgeant" = 1 + // nev_bgd : used only if "ireadgeant" = 1 and "ibg" = 1 + // = number of events in the background file "galice_bgr.root"; + // successive signal events are mixed + // with different background events in file "galice_bgr.root", + // starting from event number 0, + // incrementing it by 1 till event number ("nev_bgd" - 1), + // continuing with event number 0 and so on. + // Strictly speaking, "nev_bgd" can be smaller than + // the number of events in the background file, + // in which case one will only use + // the first "nev_bgd" events of the background file. + // But it SHOULD NOT BE LARGER THAN + // THE ACTUAL NUMBER OF EVENTS IN THE BACKGROUND FILE. + // + // Input file(s): + // "galice.root" for GEANT hits or raw clusters + // "galice_bgr.root" for background GEANT hits + // (used only if "ireadgeant" = 1 and "ibg" = 1) + // + // Output file: + // "reconst.root" for ROOT ntuples + // + //__________________________________________________________________________ + +// Dynamically link some shared libs + + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } +// Connect the Root Galice file containing Geometry, Kine and Hits + + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + + if (!file) { + printf("\n Creating galice.root \n"); + file = new TFile("galice.root"); + } else { printf("\n galice.root found in file list"); + } + +// Get AliRun object from file or create it if not on file + if (!gAlice) { + gAlice = (AliRun*)(file->Get("gAlice")); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) { + printf("\n create new gAlice object"); + gAlice = new AliRun("gAlice","Alice test program"); + } + } + +// seff = efficiency per chamber (ireadgeant=1) + Double_t seff = 1; + // Double_t seff = 1.; +// sb0 = magn. field in dipole, sbl3 = magn. field in L3 +// necessary for trackfinding only. + Double_t sb0 = 0.7; + Double_t sbl3 = 0.2; + +// ifit = 0 trackfinding only +// ifit = 1 trackfinding + fit + Int_t ifit = 1; +// idebug = 0,1,2 print level for reco_muon.F + Int_t idebug = 1; + + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); + AliMUONTrackReconstructor *Reconstruction = new AliMUONTrackReconstructor(); + Int_t nparticles = gAlice->GetEvent(evNumber1); + if (nparticles <= 0) return; + + Reconstruction->Init(seff,sb0,sbl3); + +// Loop over events +// + Int_t inev_bgd=0; + + for (Int_t nev= evNumber1; nev<= evNumber2; nev++) + { + printf("nev=%d\n",nev); + if (nev != evNumber1) Int_t nparticles = gAlice->GetEvent(nev); + if (nev < evNumber1) continue; + if (nparticles <= 0) return; + Reconstruction->FinishEvent(); + if (ireadgeant==1 && ibgr==1) { + if (inev_bgd==nev_bgd) inev_bgd=0; + Reconstruction->Reconst(ifit,idebug,inev_bgd,nev,idres,ireadgeant,"Add","galice_bgr.root"); + Reconstruction->FinishEvent(); + inev_bgd++; + } + else { + // printf("ireadgeant=%d\n",ireadgeant); + Reconstruction->Reconst(ifit,idebug,inev_bgd,nev,idres,ireadgeant,"rien1","rien2"); + Reconstruction->FinishEvent(); + + } + + } // event loop + + Reconstruction->Close(); +} + + + diff --git a/MUON/MUONtrigger.C b/MUON/MUONtrigger.C new file mode 100644 index 00000000000..ed1bd1242aa --- /dev/null +++ b/MUON/MUONtrigger.C @@ -0,0 +1,53 @@ +#include "iostream.h" +//Add the Trigger output in the tree TR of the ROOT file galice.root + +void MUONtrigger (Int_t evNumber1=0, Int_t evNumber2=0) +{ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Dynamically link some shared libs + if (gClassTable->GetID("AliRun") < 0) { + gROOT->LoadMacro("loadlibs.C"); + loadlibs(); + } + +// Connect the Root Galice file containing Geometry, Kine and Hits + TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject("galice.root"); + if (file) file->Close(); + file = new TFile("galice.root","UPDATE"); + +// Get AliRun object from file or create it if not on file + if (!gAlice) { + gAlice = (AliRun*)file->Get("gAlice"); + if (gAlice) printf("AliRun object found on file\n"); + if (!gAlice) gAlice = new AliRun("gAlice","Alice test program"); + } + printf ("I'm after gAlice \n"); + + AliMUON *MUON = (AliMUON*) gAlice->GetModule("MUON"); +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + for (int nev=evNumber1; nev<= evNumber2; nev++) { // event loop + Int_t nparticles = gAlice->GetEvent(nev); + cout << "nev " <Trigger(nev); + + } // event loop + file->Close(); +} + + + + + + + + + + + + + + diff --git a/MUON/Makefile b/MUON/Makefile index 4b395ca008e..08c726e3f9b 100644 --- a/MUON/Makefile +++ b/MUON/Makefile @@ -9,16 +9,32 @@ PACKAGE = MUON # C++ sources -SRCS = AliMUONchamber.cxx AliMUONSegResV0.cxx AliMUONSegResV01.cxx \ - AliMUONSegResV02.cxx AliMUONSegResV04.cxx AliMUONSegResV05.cxx\ - AliMUONSegResV1.cxx AliMUON.cxx AliMUONv0.cxx \ - AliMUONdisplay.cxx AliMUONpoints.cxx \ - AliMUONClusterFinder.cxx AliMUONClusterFinderv0.cxx \ - AliMUONHitMap.cxx AliMUONTUBE.cxx +SRCS = AliMUONChamber.cxx AliMUONChamberTrigger.cxx \ + AliMUONSegmentation.cxx AliMUONSegmentationV0.cxx\ + AliMUONResponse.cxx AliMUONResponseV0.cxx \ + AliMUONSegmentationV01.cxx \ + AliMUONSegmentationV02.cxx AliMUONSegmentationV04.cxx \ + AliMUONSegmentationV05.cxx\ + AliMUONSegmentationTrigger.cxx AliMUONResponseTrigger.cxx\ + AliMUONSegmentationTriggerX.cxx AliMUONSegmentationTriggerY.cxx \ + AliMUONSegmentationV1.cxx AliMUON.cxx AliMUONv0.cxx AliMUONv1.cxx\ + AliMUONDisplay.cxx AliMUONPoints.cxx \ + AliMUONClusterFinderVS.cxx AliMUONClusterFinder.cxx \ + AliMUONHitMap.cxx AliMUONHitMapA1.cxx \ + AliMUONHit.cxx AliMUONPadHit.cxx AliMUONDigit.cxx \ + AliMUONTransientDigit.cxx AliMUONRawCluster.cxx \ + AliMUONReconstHit.cxx \ + AliMUONTrackReconstructor.cxx \ + AliMUONEventReconstructor.cxx \ + AliMUONTriggerDecision.cxx \ + AliMUONHitForRec.cxx AliMUONSegment.cxx \ + AliMUONTrack.cxx AliMUONTrackHit.cxx AliMUONTrackParam.cxx \ + AliMUONTriggerCircuit.cxx AliMUONTriggerLut.cxx \ + AliMUONGlobalTrigger.cxx AliMUONLocalTrigger.cxx \ # C++ Headers -HDRS = $(SRCS:.cxx=.h) AliMUONConst.h MUONLinkDef.h +HDRS = $(SRCS:.cxx=.h) MUONLinkDef.h # Library dictionary @@ -28,7 +44,7 @@ DICTO = $(patsubst %.cxx,tgt_$(ALICE_TARGET)/%.o,$(DICT)) # Fortran sources -FSRCS = algo.F reco_muon.F +FSRCS = reco_muon.F # FORTRAN Objectrs @@ -77,3 +93,4 @@ include $(ALICE_ROOT)/conf/GeneralMacros -include tgt_$(ALICE_TARGET)/Make-depend +# DO NOT DELETE diff --git a/MUON/abso_dedx.C b/MUON/abso_dedx.C new file mode 100644 index 00000000000..1b795d413c3 --- /dev/null +++ b/MUON/abso_dedx.C @@ -0,0 +1,54 @@ +void abso_dedx() +{ + TGeant3 *geant3 = (TGeant3*)gMC; + Float_t tkin[100], valPb[100], valW[100], val1[100], val2[100]; + Float_t val3[100], val4[100], val5[100], pcut[5]; + Int_t ipart=5; + char chmeca[4]; + strcpy(chmeca,"LOSS"); + Int_t ixst, i; + Int_t kdim=100; + + for (i=0; i< kdim; i++) { + tkin[i]=Float_t(i+1)*2.; + } +// Carbon + geant3->Gftmat( 4, ipart, chmeca, kdim, tkin, val1, pcut, ixst); +// Concrete + geant3->Gftmat(25, ipart, chmeca, kdim, tkin, val2, pcut, ixst); +// Ch2 + geant3->Gftmat(28, ipart, chmeca, kdim, tkin, val3, pcut, ixst); +// Lead + geant3->Gftmat(16, ipart, chmeca, kdim, tkin, val4, pcut, ixst); +// W + geant3->Gftmat(13, ipart, chmeca, kdim, tkin, val5, pcut, ixst); + + for (i=0; i< kdim; i++) { + valPb[i]=(225.*val1[i]+153.*val2[i]+15.*val3[i]+20*val4[i])/1000.; + } + + for (i=0; i< kdim; i++) { + valW[i]=(225.*val1[i]+153.*val2[i]+35*val5[i])/1000.; + } + + + TGraph* dedx1 = new TGraph(kdim, tkin, valPb); + TGraph* dedx2 = new TGraph(kdim, tkin, valW); + + TCanvas *c1=new TCanvas("c1","dedx",400,10,600,700); + dedx1->SetFillColor(42); + dedx1->SetMarkerColor(4); + dedx1->SetMarkerStyle(21); + dedx1->Draw("AC"); + dedx1->GetHistogram()->SetXTitle("Kinetic Energy (GeV)"); + dedx1->GetHistogram()->SetYTitle("Mean Energy Loss (GeV)"); + + TCanvas *c2=new TCanvas("c2","dedx",400,10,600,700); + dedx2->SetFillColor(42); + dedx2->SetMarkerColor(4); + dedx2->SetMarkerStyle(21); + dedx2->Draw("AC"); + dedx2->GetHistogram()->SetXTitle("Kinetic Energy (GeV)"); + dedx2->GetHistogram()->SetYTitle("Mean Energy Loss (GeV)"); + + } diff --git a/MUON/algo.F b/MUON/algo.F deleted file mode 100644 index 9381b6b17e7..00000000000 --- a/MUON/algo.F +++ /dev/null @@ -1,2153 +0,0 @@ - SUBROUTINE trig(y,x,iflag) -C -C *** DIGITISATION FOR THE MUON RAW DATA AFTER EACH EVENT *** -C *** NVE 24-SEP-1990 CERN GENEVA *** -C -C CALLED BY : GUDIGI -C ORIGIN : NICK VAN EIJNDHOVEN -C -c -c version 2 (open geom + L.U.T. + option DS on) -c Input : Hits on the muon trigger chambers (RPCs) from GALICE -c Output : muon trigger decision (Unlike Sign) L0 low and high Pt -c -c 1- TRIGMAP --> DESCRIBE MUON trigger GEOMETRY -c 2- REMPL --> FILL bit pattern of MUON trigger CIRCUITS -c 3- ALGO --> INDICATE MUON trigger DECISION -c -c - - real x(4,1000),y(4,1000) ! 1000=nhitmax - common/debug/idebug - - data nhitmax/1000/ ! max possible number of hits - data idebug/0/ ! for debuging - -c call hropen(99,'hist','hist_paw.hbook',' ',1024,ISTAT) -c open(UNIT=99,file='hist_paw.hbook',recl=1024,form='unformatted', -c + access='direct',status='unknown') -c call hlimit(500000) -c call hbook2(1,'X-Y hits plane 1(1600)',100,-300.,300., -c + 100,-300.,300.,0.) -c call hbook2(2,'X-Y hits plane 2(1615)',100,-300.,300., -c + 100,-300.,300.,0.) -c call hbook2(3,'X-Y hits plane 3(1700)',100,-300.,300., -c + 100,-300.,300.,0.) -c call hbook2(4,'X-Y hits plane 4(1715)',100,-300.,300., -c + 100,-300.,300.,0.) -cc -c call hbook1(10,'NUM of non-empty circuits',346,0.,346.,0.) -c call hbook1(11,'DISTR of non-empty circuits', -c + 346,-173.,173.,0.) -c call hbook1(12,'NUM of non-empty X circuits',346,0.,346.,0.) -c call hbook1(13,'NUM of non-empty Y circuits',346,0.,346.,0.) -cc -c -cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -c Describe trigger geometry - call TRIGMAPP -c -c Hits on trigger chambers (RPCs) from GALICE are passed through -c x(iplan,ihit) and y(iplan,ihit) -c with iplan=1-4 corresp. to Z=1600,1615,1700,1715 cm respectively -c ihit =number associated to a hit (ihit<1000, see nhitmax) -c -c -c init -c do iplan=1,4 -c do ihit=1,nhitmax -c x(iplan,ihit)=0 -c y(iplan,ihit)=0 -c enddo -c enddo -c -c for debugging proposes : ex of test sequences -c call seqtest - -c for debugging proposes : test full evt pbpb simulated with geant -c call FULLEVT - -c -c Associate Hits to circuits (bit pattern) - call REMPL(x,y,nhitmax) -c Look for possible triggers (L0 , Low and High Pt cut at present) - call ALGO(itrigR,itrigL0,itrigH0) - -c TRIGGER ? - - print *,' ' - print *,'DIMUON TRIGGER - DIMUON TRIGGER' - print *,'ROAD +/-8 ',itrigR - print *,'Low pt L0 ',itrigL0 - print *,'High pt L0 ',itrigH0 - -c call hrfile(99,'hist','n') -c call hrout(0,icycle,' ') -c call hrend('hist') -c stop - iflag=100*itrigH0+10*itrigL0+itrigR - end -c -c -c - subroutine TRIGMAPP -c -c to be called at a begining of a run for dimuon trigger GEOM MAPing -c -c -c integer NUM(173),CODEX(173),CODEY(173) !173=Ncirc -c real xcmax(4,173),xcmin(4,173), -c + ycmax(4,173),ycmin(4,173), -c + xycmax(4,173),xycmin(4,173) -c real xwi_c(173),xwi_m(173),xwi_p(173),ywi(173) -c integer nstrip_c(173),nstrip_p(173),nstrip_m(173) -c -c common/TRIGMAP/xcmax,xcmin,ycmax,ycmin,xycmax,xycmin, -c + CODEX,CODEY, -c + xwi_c,xwi_m,xwi_p,ywi, -c + nstrip_c,nstrip_m,nstrip_p, -c + NUM,Z1,Z2,Z3,Z4,Ncirc - - common/TRIGMAP/xcmax(4,173),xcmin(4,173),ycmax(4,173), - + ycmin(4,173),xycmax(4,173),xycmin(4,173), - + CODEX(173),CODEY(173), - + xwi_c(173),xwi_m(173),xwi_p(173),ywi(173), - + nstrip_c(173),nstrip_m(173),nstrip_p(173), - + NUM(173),Z1,Z2,Z3,Z4,Ncirc - integer nstrip_c,nstrip_p,nstrip_m - integer NUM,CODEX,CODEY,Ncirc - - common/debug/idebug - - integer ixwi_c,ixwi_p,ixwi_m - integer iywi,iywi_c,iywi_p,iywi_m,ixyco_m,ixyco_p - - data Z1,Z2,Z3,Z4 /1600.,1615.,1700.,1715./ - data Ncirc /173/ !Half L0 circuits Y>0 (TOT=346 ) -c -c -c -c METHOD : coding from down to up for X -c coding only Y>0 (if Y<0, NUM-->-NUM) -c -c with NUM = CODE of TRIGGER CIRCUIT -c -cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -cXXXXXXXXXX -c -c MC1 plane 1 -c X11max higher X limit of the circuit -c X11min lower X limit of the circuit -c -c MC1 plane 2 -c X12max=X11max*Z2/Z1 -c X12min=X11min*Z2/Z1 -c -c MC2 plane 1 -c X21max=(X11max+8*XWI_p)*Z3/Z1 ex : CODEX=221 --> XWI_c = 2.12 -c X21min=(X11min-8*XWI_m)*Z3/Z1 --> XWI_p = 1.06 -c --> XWI_m = 2.12 -c ex : CODEX=224 --> XWI_c = 2.12 -c --> XWI_p = 4.24 -c --> XWI_m = 2.12 -c ex : CODEX=440 --> XWI_c = 4.24 -c --> XWI_p = 0. -c --> XWI_m = 4.24 -c -c MC2 plane 2 -c X22max=(X11max+8*XWI_p)*Z4/Z1 -c X22min=(X11min-8*XWI_m)*Z4/Z1 -c -ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -cYYYYYYYYYYY -c -c MC1 plane 1 -c Y11max higher Y limit of the circuit -c Y11min lower Y limit of the circuit -c XY11max higher X limit of the circuit (in Y) -c XY11min lower X limit of the circuit (in Y) -c -c MC1 plane 2 -c Y12max=Y11max*Z2/Z1 -c Y12min=Y11min*Z2/Z1 -c XY12max=XY11max*Z2/Z1 -c XY12min=XY11min*Z2/Z1 -c -c MC2 plane 1 -c Y21max=Y11max*Z3/Z1 -c Y21min=Y11min*Z3/Z1 -c XY21max(n)=XY11max(n) *Z3/Z1 if IXYCO_p=0 -c XY11max(n+1)*Z3/Z1 if IXYCO_p=1 -c XY21min(n)=XY11min(n) *Z3/Z1 if IXYCO_m=0 -c XY11min(n-1)*Z3/Z1 if IXYCO_m=1 -c -c MC2 plane 2 -c Y22max=Y11max*Z4/Z1 -c Y22min=Y11min*Z4/Z1 -c XY22max(n)=XY11max(n) *Z4/Z1 if IXYCO_p=0 -c XY11max(n+1)*Z4/Z1 if IXYCO_p=1 -c XY22min(n)=XY11min(n) *Z4/Z1 if IXYCO_m=0 -c XY11min(n-1)*Z4/Z1 if IXYCO_m=1 -c -c -c CODEY=C1*1000+C2-*100+C2c*10+C2+*1 -c with C1=2/4 for strip width 2.12/4.24 on MC1 -c C2-,C2c,C2+=0/1/2/3 on MC2 -c 0--> nothing 1-->4strips 2-->8strips 3-->16strips -c ex : CODEY=2332 -c C1=2.12 (MC1 plane 1) -c C2-= 16 strips (MC2) -c C2c= 16 strips (MC2) -c C2+= 8 strips (MC2) -c IXYCO_p, IXYCO_m : 0/1 if C2+,C2- =/# 0 -c -ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -c -c numerotation 1/2 plane (-xxx for other 1/2 plane) -c -c X -c ^ -c ! -c ! 121 221 321 421 521 621 715 815 915 1008 -c ! 120 620 714 814 914 1007 -c ! 119 619 713 813 913 1007 -c ! 118 618 712 812 912 1006 -c ! 117 617 711 811 911 1006 -c ! 116 616 710 810 910 1005 -c ! 115 615 710 810 910 1005 -c ! 114 214 314 414 614 709 809 909 1005 -c ! 313 413 513 613 709 809 909 1005 -c ! 412 512 612 708 808 908 1004 -c ! Beam 411 511 611 708 808 908 1004 --------> Y -c ! Shield 410 510 610 707 807 907 1004 -c ! 409 509 609 707 807 907 1004 -c ! 308 408 508 608 706 806 906 1003 -c ! 107 207 307 407 607 706 906 906 1003 -c ! 106 606 705 805 905 1003 -c ! 105 605 705 805 905 1003 -c ! 104 604 704 804 904 1002 -c ! 103 603 703 803 903 1002 -c ! 102 602 702 802 902 1001 -c ! 101 601 701 801 901 1001 -c ! 100 200 300 400 500 600 700 800 900 1000 -c -c -cccccccccccccccccccccccccc DATAs CIRCUITS 100-107 114-121 ccccccccccccccccccc - - data (NUM(NN),NN=1,16) /100,101,102,103,104,105,106,107,114,115, - + 116,117,118,119,120,121/ - - data (CODEX(NN),NN=1,16) /042,422,222,222,221,211,111,110, - + 011,111,112,122,222,222,224,240/ - - data (CODEY(NN),NN=1,16) /4011,4110,4012,2122,2222, - + 2220,2020,2020, - + 2020,2020,2022,2222,2221,4210,4011,4110/ - - data (xcmax(1,NN),NN=1,16) /-238,-204,-170,-136,-102,-85, - + -68,-51, - + 68,85,102,136,170,204,238,306/ - - data (xcmin(1,NN),NN=1,16) /-306,-238,-204,-170,-136, - + -102,-85,-68, - + 51,68,85,102,136,170,204,238/ - - data (ycmax(1,NN),NN=1,16) /17,17,17,17,17,17,17,17, - + 17,17,17,17,17,17,17,17/ - - data (ycmin(1,NN),NN=1,16) /0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/ - - - data (xycmax(1,NN),NN=1,16) /-238,-170,-170,-136,-102, - + -51,-51,-51, - + 102,102,102,136,170,238,238,306/ - - data (xycmin(1,NN),NN=1,16) /-306,-238,-238,-170,-136, - + -102,-102,-102, - + 51,51,51,102,136,170,170,238/ - - -cccccccccccccccccccccccccc DATAs CIRCUITS 200-207 214-221 ccccccccccccccccccc - - data (NUM(NN),NN=17,32) /200,201,202,203,204,205,206,207,214,215, - + 216,217,218,219,220,221/ - - data (CODEX(NN),NN=17,32) /042,422,222,222,221,211,111,110, - + 011,111,112,122,222,222,224,240/ - - data (CODEY(NN),NN=17,32) /4011,4110,4012,2122,2222, - + 2220,2020,2020, - + 2020,2020,2022,2222,2221,4210,4011,4110/ - - data (xcmax(1,NN),NN=17,32) /-238,-204,-170,-136,-102, - + -85,-68,-51, - + 68,85,102,136,170,204,238,306/ - - data (xcmin(1,NN),NN=17,32) /-306,-238,-204,-170,-136, - + -102,-85,-68, - + 51,68,85,102,136,170,204,238/ - - data (ycmax(1,NN),NN=17,32) /34,34,34,34,34,34,34, - + 34,34,34,34,34,34,34,34,34/ - - data (ycmin(1,NN),NN=17,32) /17,17,17,17,17,17,17, - + 17,17,17,17,17,17,17,17,17/ - - data (xycmax(1,NN),NN=17,32) /-238,-170,-170,-136,-102, - + -51,-51,-51, - + 102,102,102,136,170,238,238,306/ - - data (xycmin(1,NN),NN=17,32) /-306,-238,-238,-170,-136, - + -102,-102,-102, - + 51,51,51,102,136,170,170,238/ - - -cccccccccccccccccccccccccc DATAs CIRCUITS 300-308 313-321 ccccccccccccccccccc - - data (NUM(NN),NN=33,50) /300,301,302,303,304,305,306,307,308, - + 313,314,315,316,317,318,319,320,321/ - - data (CODEX(NN),NN=33,50) /042,422,222,222,221,211,111,111,110, - + 011,111,111,112,122,222,222,224,240/ - - data (CODEY(NN),NN=33,50) /4011,4110,4012,2122,2222,2220, - + 2022,2220,2020, - + 2020,2022,2220,2022,2222,2221,4210,4011,4110/ - - data (xcmax(1,NN),NN=33,50) /-238,-204,-170,-136,-102,-85, - + -68,-51,-34, - + 51,68,85,102,136,170,204,238,306/ - - data (xcmin(1,NN),NN=33,50) /-306,-238,-204,-170,-136, - + -102,-85,-68,-51, - + 34,51,68,85,102,136,170,204,238/ - - data (ycmax(1,NN),NN=33,50) /51,51,51,51,51,51,51, - + 51,51,51,51,51,51,51,51,51,51,51/ - - data (ycmin(1,NN),NN=33,50) /34,34,34,34,34,34,34, - + 34,34,34,34,34,34,34,34,34,34,34/ - - data (xycmax(1,NN),NN=33,50) /-238,-170,-170,-136,-102, - + -68,-68,-34,-34, - + 68,68,102,102,136,170,238,238,306/ - - data (xycmin(1,NN),NN=33,50) /-306,-238,-238,-170,-136, - + -102,-102,-68,-68, - + 34,34,68,68,102,136,170,170,238/ - - -cccccccccccccccccccccccccc DATAs CIRCUITS 400 - 421 ccccccccccccccccccccccccc - - data (NUM(NN),NN=51,72) /400,401,402,403,404,405,406, - + 407,408,409,410, - + 411,412,413,414,415,416,417,418,419,420,421/ - - data (CODEX(NN),NN=51,72) /042,422,222,222,221,211,111,111,111, - + 111,111, - + 111,111,111,111,111,112,122,222,222,224,240/ - - data (CODEY(NN),NN=51,72) /4011,4110,4012,2122,2222,2220, - + 2022,2220,2022, - + 2220,2022,2220,2022, - + 2220,2022,2220,2022,2222,2221,4210,4011,4110/ - - data (xcmax(1,NN),NN=51,72) /-238,-204,-170,-136,-102,-85, - + -68,-51,-34, - + -17,0,17,34, - + 51,68,85,102,136,170,204,238,306/ - - data (xcmin(1,NN),NN=51,72) /-306,-238,-204,-170,-136,-102, - + -85,-68,-51, - + -34,-17,0,17, - + 34,51,68,85,102,136,170,204,238/ - - data (ycmax(1,NN),NN=51,72) /68,68,68,68,68,68,68,68,68,68,68, - + 68,68,68,68,68,68,68,68,68,68,68/ - - data (ycmin(1,NN),NN=51,72) /51,51,51,51,51,51,51,51,51,51,51, - + 51,51,51,51,51,51,51,51,51,51,51/ - - data (xycmax(1,NN),NN=51,72) /-238,-170,-170,-136,-102,-68, - + -68,-34,-34, - + 0,0,34,34, - + 68,68,102,102,136,170,238,238,306/ - - data (xycmin(1,NN),NN=51,72) /-306,-238,-238,-170,-136, - + -102,-102,-68,-68, - + -34,-34,0,0, - + 34,34,68,68,102,136,170,170,238/ - - -cccccccccccccccccccccccccc DATAs CIRCUITS 500 - 521 ccccccccccccccccccccccccc - - data (NUM(NN),NN=73,94) /500,501,502,503,504,505,506, - + 507,508,509,510, - + 511,512,513,514,515,516,517,518,519,520,521/ - - data (CODEX(NN),NN=73,94) /042,422,222,222,221,211,111, - + 111,111,111,111, - + 111,111,111,111,111,112,122,222,222,224,240/ - - data (CODEY(NN),NN=73,94) /4011,4110,4012,2122,2222, - + 2220,2022,2220,2022, - + 2220,2022,2220,2022, - + 2220,2022,2220,2022,2222,2221,4210,4011,4110/ - - data (xcmax(1,NN),NN=73,94) /-238,-204,-170,-136, - + -102,-85,-68,-51,-34, - + -17,0,17,34, - + 51,68,85,102,136,170,204,238,306/ - - data (xcmin(1,NN),NN=73,94) /-306,-238,-204,-170,-136, - + -102,-85,-68,-51, - + -34,-17,0,17, - + 34,51,68,85,102,136,170,204,238/ - - data (ycmax(1,NN),NN=73,94) /85,85,85,85,85,85,85,85,85,85,85, - + 85,85,85,85,85,85,85,85,85,85,85/ - - data (ycmin(1,NN),NN=73,94) /68,68,68,68,68,68,68,68,68,68,68, - + 68,68,68,68,68,68,68,68,68,68,68/ - - data (xycmax(1,NN),NN=73,94) /-238,-170,-170,-136,-102, - + -68,-68,-34,-34, - + 0,0,34,34, - + 68,68,102,102,136,170,238,238,306/ - - data (xycmin(1,NN),NN=73,94) /-306,-238,-238,-170, - + -136,-102,-102,-68, - + -68,-34,-34,0,0, - + 34,34,68,68,102,136,170,170,238/ - - -cccccccccccccccccccccccccc DATAs CIRCUITS 600 - 621 ccccccccccccccccccccccccc - - data (NUM(NN),NN=95,116)/600,601,602,603,604,605,606, - + 607,608,609,610, - + 611,612,613,614,615,616,617,618,619,620,621/ - - data (CODEX(NN),NN=95,116)/042,422,222,222,221,211,111, - + 111,111,111,111, - + 111,111,111,111,111,112,122,222,222,224,240/ - - data (CODEY(NN),NN=95,116)/4011,4110,4012,2122,2222, - + 2220,2022,2220,2022, - + 2220,2022,2220,2022, - + 2220,2022,2220,2022,2222,2221,4210,4011,4110/ - - data (xcmax(1,NN),NN=95,116)/-238,-204,-170,-136, - + -102,-85,-68,-51,-34, - + -17,0,17,34, - + 51,68,85,102,136,170,204,238,306/ - - data (xcmin(1,NN),NN=95,116)/-306,-238,-204,-170,-136, - + -102,-85,-68,-51, - + -34,-17,0,17, - + 34,51,68,85,102,136,170,204,238/ - - data (ycmax(1,NN),NN=95,116)/102,102,102,102,102,102, - + 102,102,102,102, - + 102,102,102,102,102,102,102,102,102,102,102,102/ - - data (ycmin(1,NN),NN=95,116)/85,85,85,85,85,85,85,85,85,85,85, - + 85,85,85,85,85,85,85,85,85,85,85/ - - data (xycmax(1,NN),NN=95,116)/-238,-170,-170,-136,-102,-68, - + -68,-34,-34, - + 0,0,34,34, - + 68,68,102,102,136,170,238,238,306/ - - data (xycmin(1,NN),NN=95,116)/-306,-238,-238,-170,-136, - + -102,-102,-68, - + -68,-34,-34,0,0, - + 34,34,68,68,102,136,170,170,238/ - - -cccccccccccccccccccccccccc DATAs CIRCUITS 700 - 715 ccccccccccccccccccccccccc - - data (NUM(NN),NN=117,132)/700,701,702,703,704,705,706,707, - + 708,709,710,711,712,713,714,715/ - - data (CODEX(NN),NN=117,132)/042,422,222,222,222,222,222,222, - + 222,222,222,222,222,222,224,240/ - - data (CODEY(NN),NN=117,132)/4022,4220,4023,2233,2333, - + 2333,2333,2333, - + 2333,2333,2333,2333,2332,4320,4022,4220/ - - data (xcmax(1,NN),NN=117,132)/-238,-204,-170,-136,-102,-68,-34,0, - + 34,68,102,136,170,204,238,306/ - - data (xcmin(1,NN),NN=117,132)/-306,-238,-204,-170,-136, - + -102,-68,-34, - + 0,34,68,102,136,170,204,238/ - - data (ycmax(1,NN),NN=117,132)/136,136,136,136,136,136,136,136, - + 136,136,136,136,136,136,136,136/ - - data (ycmin(1,NN),NN=117,132)/102,102,102,102,102,102,102,102, - + 102,102,102,102,102,102,102,102/ - - data (xycmax(1,NN),NN=117,132)/-238,-170,-170, - + -136,-102,-68,-34,0, - + 34,68,102,136,170,238,238,306/ - - data (xycmin(1,NN),NN=117,132)/-306,-238,-238,-170, - + -136,-102,-68,-34, - + 0,34,68,102,136,170,170,238/ - - - -cccccccccccccccccccccccccc DATAs CIRCUITS 800 - 815 ccccccccccccccccccccccccc - - data (NUM(NN),NN=133,148)/800,801,802,803,804,805,806,807, - + 808,809,810,811,812,813,814,815/ - - data (CODEX(NN),NN=133,148)/042,422,222,222,222,222,222,222, - + 222,222,222,222,222,222,224,240/ - - data (CODEY(NN),NN=133,148)/4022,4220,4023,2233,2333, - + 2333,2333,2333, - + 2333,2333,2333,2333,2332,4320,4022,4220/ - - data (xcmax(1,NN),NN=133,148)/-238,-204,-170,-136,-102,-68,-34,0, - + 34,68,102,136,170,204,238,306/ - - data (xcmin(1,NN),NN=133,148)/-306,-238,-204,-170, - +-136,-102,-68,-34, - + 0,34,68,102,136,170,204,238/ - - data (ycmax(1,NN),NN=133,148)/170,170,170,170,170,170,170,170, - + 170,170,170,170,170,170,170,170/ - - data (ycmin(1,NN),NN=133,148)/136,136,136,136,136,136,136,136, - + 136,136,136,136,136,136,136,136/ - - data (xycmax(1,NN),NN=133,148)/-238,-170,-170,-136, - +-102,-68,-34,0, - + 34,68,102,136,170,238,238,306/ - - data (xycmin(1,NN),NN=133,148)/-306,-238,-238,-170, - + -136,-102,-68,-34, - + 0,34,68,102,136,170,170,238/ - - -cccccccccccccccccccccccccc DATAs CIRCUITS 900 - 915 ccccccccccccccccccccccccc - - data (NUM(NN),NN=149,164)/900,901,902,903,904,905,906,907, - + 908,909,910,911,912,913,914,915/ - - data (CODEX(NN),NN=149,164)/042,422,222,222,222,222,222,222, - + 222,222,222,222,222,222,224,240/ - - data (CODEY(NN),NN=149,164)/4022,4220,4022,4220, - +4022,4220,4022,4220, - + 4022,4220,4022,4220,4022,4220,4022,4220/ - - data (xcmax(1,NN),NN=149,164)/-238,-204,-170,-136,-102,-68, - +-34,0, - + 34,68,102,136,170,204,238,306/ - - data (xcmin(1,NN),NN=149,164)/-306,-238,-204,-170,-136,-102, - + -68,-34, - + 0,34,68,102,136,170,204,238/ - - data (ycmax(1,NN),NN=149,164)/204,204,204,204,204,204,204,204, - + 204,204,204,204,204,204,204,204/ - - data (ycmin(1,NN),NN=149,164)/170,170,170,170,170,170,170,170, - + 170,170,170,170,170,170,170,170/ - - data (xycmax(1,NN),NN=149,164)/-238,-170,-170,-102,-102, - +-34,-34,34, - + 34,102,102,170,170,238,238,306/ - - data (xycmin(1,NN),NN=149,164)/-306,-238,-238,-170,-170, - +-102,-102,-34, - + -34,34,34,102,102,170,170,238/ - - -cccccccccccccccccccccccccc DATAs CIRCUITS 1000 - 1008 ccccccccccccccccccccccc - - data (NUM(NN),NN=165,173)/1000,1001,1002,1003,1004,1005, - + 1006,1007,1008/ - - data (CODEX(NN),NN=165,173)/044,444,444,444,444,444,444,444,440/ - - data (CODEY(NN),NN=165,173)/4033,4333,4333,4333,4333,4333, - + 4333,4333,4330/ - - data (xcmax(1,NN),NN=165,173)/-238,-170,-102,-34, - + 34,102,170,238,306/ - - data (xcmin(1,NN),NN=165,173)/-306,-238,-170,-102,-34, - + 34,102,170,238/ - - data (ycmax(1,NN),NN=165,173)/272,272,272,272,272,272, - +272,272,272/ - - data (ycmin(1,NN),NN=165,173)/204,204,204,204,204,204, - +204,204,204/ - - data (xycmax(1,NN),NN=165,173)/-238,-170,-102,-34, - + 34,102,170,238,306/ - - data (xycmin(1,NN),NN=165,173)/-306,-238,-170,-102,-34, - + 34,102,170,238/ - -ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc - -calculate other quantities associated to a circuit on the other planes -c - - do i=1,ncirc !loop on all circuits (Y>0) -c -c DECODE CODEX -c - ixwi_m=CODEX(i)/100 !Dividing integers - ixwi_c=(CODEX(i)-ixwi_m*100)/10 - ixwi_p=CODEX(i)-ixwi_m*100-ixwi_c*10 -c - if(ixwi_m.eq.0)then - xwi_m(i)=0. - elseif(ixwi_m.eq.1)then - xwi_m(i)=1.0625 - elseif(ixwi_m.eq.2)then - xwi_m(i)=2.125 - elseif(ixwi_m.eq.4)then - xwi_m(i)=4.25 - else - print *,'WARNING :: BAD CODEX value' - endif - - if(ixwi_c.eq.0)then - xwi_c(i)=0. - elseif(ixwi_c.eq.1)then - xwi_c(i)=1.0625 - elseif(ixwi_c.eq.2)then - xwi_c(i)=2.125 - elseif(ixwi_c.eq.4)then - xwi_c(i)=4.25 - else - print *,'WARNING :: BAD CODEX value' - endif - - if(ixwi_p.eq.0)then - xwi_p(i)=0. - elseif(ixwi_p.eq.1)then - xwi_p(i)=1.0625 - elseif(ixwi_p.eq.2)then - xwi_p(i)=2.125 - elseif(ixwi_p.eq.4)then - xwi_p(i)=4.25 - else - print *,'WARNING :: BAD CODEX value' - endif - -c ready to calculate XGEOM parameters - - xcmax(2,i)=Z2/Z1*(xcmax(1,i)) - xcmin(2,i)=Z2/Z1*(xcmin(1,i)) -c -c - xcmax(3,i)=Z3/Z1*(xcmax(1,i)+8*XWI_p(i)) - xcmin(3,i)=Z3/Z1*(xcmin(1,i)-8*XWI_m(i)) -c - xcmax(4,i)=Z4/Z1*(xcmax(1,i)+8*XWI_p(i)) - xcmin(4,i)=Z4/Z1*(xcmin(1,i)-8*XWI_m(i)) -c -c -c DECODE CODEY -c - iywi=CODEY(i)/1000 !Dividing integers - iywi_m=(CODEY(i)-iywi*1000)/100 - iywi_c=(CODEY(i)-iywi*1000-iywi_m*100)/10 - iywi_p=CODEY(i)-iywi*1000-iywi_m*100-iywi_c*10 - - if(iywi.eq.2)then - ywi(i)=2.125 - elseif(iywi.eq.4)then - ywi(i)=4.25 - else - print *,'WARNING :: BAD CODEY value' - endif - - if(iywi_m.eq.0)then - ixyco_m=0 - nstrip_m(i)=0 - elseif(iywi_m.eq.1)then - ixyco_m=1 - nstrip_m(i)=4 - elseif(iywi_m.eq.2)then - ixyco_m=1 - nstrip_m(i)=8 - elseif(iywi_m.eq.3)then - ixyco_m=1 - nstrip_m(i)=16 - else - print *,'WARNING :: BAD CODEY value' - endif - - if(iywi_c.eq.0)then - nstrip_c(i)=0 - elseif(iywi_c.eq.1)then - nstrip_c(i)=4 - elseif(iywi_c.eq.2)then - nstrip_c(i)=8 - elseif(iywi_c.eq.3)then - nstrip_c(i)=16 - else - print *,'WARNING :: BAD CODEY value' - endif - - if(iywi_p.eq.0)then - ixyco_p=0 - nstrip_p(i)=0 - elseif(iywi_p.eq.1)then - ixyco_p=1 - nstrip_p(i)=4 - elseif(iywi_p.eq.2)then - ixyco_p=1 - nstrip_p(i)=8 - elseif(iywi_p.eq.3)then - ixyco_p=1 - nstrip_p(i)=16 - else - print *,'WARNING :: BAD CODEY value' - endif - -c ready to calculate YGEOM parameters - - - ycmax(2,i)=Z2/Z1*(ycmax(1,i)) - ycmin(2,i)=Z2/Z1*(ycmin(1,i)) - xycmax(2,i)=Z2/Z1*(xycmax(1,i)) - xycmin(2,i)=Z2/Z1*(xycmin(1,i)) - - ycmax(3,i)=Z3/Z1*(ycmax(1,i)) - ycmin(3,i)=Z3/Z1*(ycmin(1,i)) - - if(ixyco_p.eq.0)then - xycmax(3,i)=Z3/Z1*(xycmax(1,i)) - else - xycmax(3,i)=Z3/Z1*(xycmax(1,i+1)) - endif - - if(ixyco_m.eq.0)then - xycmin(3,i)=Z3/Z1*(xycmin(1,i)) - else - xycmin(3,i)=Z3/Z1*(xycmin(1,i-1)) - endif - - ycmax(4,i)=Z4/Z1*(ycmax(1,i)) - ycmin(4,i)=Z4/Z1*(ycmin(1,i)) - - if(ixyco_p.eq.0)then - xycmax(4,i)=Z4/Z1*(xycmax(1,i)) - else - xycmax(4,i)=Z4/Z1*(xycmax(1,i+1)) - endif - - if(ixyco_m.eq.0)then - xycmin(4,i)=Z4/Z1*(xycmin(1,i)) - else - xycmin(4,i)=Z4/Z1*(xycmin(1,i-1)) - endif -c -c - enddo !loop on trigger boards -c - return - end -c -cc - subroutine REMPL(x,y,nhitmax) -c Associate hits to circuits (bit pattern) - - real x(4,1000),y(4,1000) ! 1000=nhitmax - - real xu(346),yu(346) ! something in x / y - integer*4 bitpx(4,346),bitpy(4,346) ! bit-pattern in x / y code DECIMAL - common /hitcirc/xu,yu,bitpx,bitpy - -c integer NUM(173),CODEX(173),CODEY(173) !173=Ncirc -c real xcmax(4,173),xcmin(4,173), -c + ycmax(4,173),ycmin(4,173), -c + xycmax(4,173),xycmin(4,173) -c real xwi_c(173),xwi_m(173),xwi_p(173),ywi(173) -c integer nstrip_c(173),nstrip_p(173),nstrip_m(173) -c -c common/TRIGMAP/xcmax,xcmin,ycmax,ycmin,xycmax,xycmin, -c + CODEX,CODEY, -c + xwi_c,xwi_m,xwi_p,ywi, -c + nstrip_c,nstrip_m,nstrip_p, -c + NUM,Z1,Z2,Z3,Z4,Ncirc - common/TRIGMAP/xcmax(4,173),xcmin(4,173),ycmax(4,173), - + ycmin(4,173),xycmax(4,173),xycmin(4,173), - + CODEX(173),CODEY(173), - + xwi_c(173),xwi_m(173),xwi_p(173),ywi(173), - + nstrip_c(173),nstrip_m(173),nstrip_p(173), - + NUM(173),Z1,Z2,Z3,Z4,Ncirc - integer nstrip_c,nstrip_p,nstrip_m - integer NUM,CODEX,CODEY,Ncirc - - - common/debug/idebug - - character*32 i2bin - - -cinit - do icircT=1,(ncirc*2) - xu(icircT)=0 - yu(icircT)=0 - do iplan=1,4 - bitpx(iplan,icircT)=0 - bitpy(iplan,icircT)=0 - enddo - enddo -c -c fill the hits in histograms -c -c do iplan=1,4 -c do ihit=1,nhitmax -c if (x(iplan,ihit).ne.0.or.y(iplan,ihit).ne.0) -c + call hfill(iplan,x(iplan,ihit),y(iplan,ihit),1.) -c enddo -c enddo -c -c fill the circuits in X and Y -c - do iplan=1,4 - do ihit=1,nhitmax - if (x(iplan,ihit).ne.0.or.y(iplan,ihit).ne.0)then !save CPU time -c print *,iplan,ihit,x(iplan,ihit),y(iplan,ihit) -c -ccccccccccccccccccccc BIT PATTERN in X cccccccccccccccccccccccccccc -c - do icirc=1,ncirc - yabs=abs(y(iplan,ihit)) - if(x(iplan,ihit).ge.xcmin(iplan,icirc).and. - + x(iplan,ihit).lt.xcmax(iplan,icirc))then - if(yabs.ge.ycmin(iplan,icirc).and. - + yabs.lt.ycmax(iplan,icirc))then - if(y(iplan,ihit).ge.0)xu(icirc)=1 - if(y(iplan,ihit).lt.0)xu(icirc+ncirc)=1 -c - if(iplan.eq.1)then - X11=x(iplan,ihit)-xcmin(iplan,icirc) - nx11=ifix(X11/xwi_c(icirc))+1 !no of hitten strip - - if(nX11.le.0.or.nX11.ge.17) - + print *,'WARNING : NX11 out of range',NX11 - - if(y(iplan,ihit).ge.0) - + call sbit1(bitpx(iplan,icirc),nx11) !sets bit pos nx11 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpx(iplan,icirc+ncirc),nx11) - - - if (idebug.eq.2)then - print *,' ' - print *,'iplan,ihit,icirc,NUM=',iplan,ihit,icirc,num(icirc) - print *,'x y xcmin xcmax ycmin ycmax ',x(iplan,ihit), - + y(iplan,ihit),xcmin(iplan,icirc),xcmax(iplan,icirc), - + ycmin(iplan,icirc),ycmax(iplan,icirc) - print *,'X11 nX11 xwidth=',X11,nX11,xwi_c(icirc) - print *,'bitpx(iplan,icirc) ', - + i2bin(bitpx(iplan,icirc),16) - print *,'bitpx(iplan,icirc+ncirc) ', - + i2bin(bitpx(iplan,icirc+ncirc),16) - endif - - elseif(iplan.eq.2)then -c - X12=x(iplan,ihit)-xcmin(iplan,icirc) - nx12=ifix(X12/(xwi_c(icirc)*Z2/Z1))+1 !no of hitten strip - if(nX12.le.0.or.nX12.ge.17) - + print *,'WARNING : NX12 out of range',NX12 - - if(y(iplan,ihit).ge.0) - + call sbit1(bitpx(iplan,icirc),nx12) !sets bit pos nx12 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpx(iplan,icirc+ncirc),nx12) - - - if (idebug.eq.2)then - print *,' ' - print *,'iplan,ihit,icirc,NUM=',iplan,ihit,icirc,num(icirc) - print *,'x y xcmin xcmax ycmin ycmax ',x(iplan,ihit), - + y(iplan,ihit),xcmin(iplan,icirc),xcmax(iplan,icirc), - + ycmin(iplan,icirc),ycmax(iplan,icirc) - print *,'X12 nX12 xwidth',X12,nX12,xwi_c(icirc) - print *,'bitpx(iplan,icirc) ', - + i2bin(bitpx(iplan,icirc),16) - print *,'bitpx(iplan,icirc+ncirc) ', - + i2bin(bitpx(iplan,icirc+ncirc),16) - endif - - elseif(iplan.eq.3)then -c - X21=x(iplan,ihit)-xcmin(iplan,icirc) - if(X21.le.(xwi_m(icirc)*8*Z3/Z1))then - nX21=ifix(X21/(xwi_m(icirc)*Z3/Z1))+1 !no of hitten strip - elseif - + (X21.le.((xwi_m(icirc)*8+xwi_c(icirc)*16)*Z3/Z1))then - XX21=X21-xwi_m(icirc)*8*Z3/Z1 - nX21=ifix(XX21/(xwi_c(icirc)*Z3/Z1))+1+8 - else - XXX21=X21-(xwi_m(icirc)*8+xwi_c(icirc)*16)*Z3/Z1 - nX21=ifix(XXX21/(xwi_p(icirc)*Z3/Z1))+1+8+16 - endif - - if(nX21.le.0.or.nX21.ge.33) - + print *,'WARNING : NX21 out of range',NX21 - - if(y(iplan,ihit).ge.0) - + call sbit1(bitpx(iplan,icirc),nX21) !sets bit pos nX21 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpx(iplan,icirc+ncirc),nX21) - - - if (idebug.eq.2)then - print *,' ' - print *,'iplan,ihit,icirc,NUM=',iplan,ihit,icirc,num(icirc) - print *,'x y xcmin xcmax ycmin ycmax ',x(iplan,ihit), - + y(iplan,ihit),xcmin(iplan,icirc),xcmax(iplan,icirc), - + ycmin(iplan,icirc),ycmax(iplan,icirc) - print *,'X21 nX21 xwidth-c xwidth-m xwidth-p =', - + X21,nX21,xwi_c(icirc),xwi_m(icirc),xwi_p(icirc) - print *,'bitpx(iplan,icirc) ', - + i2bin(bitpx(iplan,icirc),32) - print *,'bitpx(iplan,icirc+ncirc) ', - + i2bin(bitpx(iplan,icirc+ncirc),32) - endif - - elseif(iplan.eq.4)then -c - x22=x(iplan,ihit)-xcmin(iplan,icirc) - if(x22.le.(xwi_m(icirc)*8*Z4/Z1))then - nx22=ifix(x22/(xwi_m(icirc)*Z4/Z1))+1 !no of hitten strip - elseif - + (x22.le.((xwi_m(icirc)*8+xwi_c(icirc)*16)*Z4/Z1))then - Xx22=x22-xwi_m(icirc)*8*Z4/Z1 - nx22=ifix(Xx22/(xwi_c(icirc)*Z4/Z1))+1+8 - else - XXx22=x22-(xwi_m(icirc)*8+xwi_c(icirc)*16)*Z4/Z1 - nx22=ifix(XXx22/(xwi_p(icirc)*Z4/Z1))+1+8+16 - endif - - if(nx22.le.0.or.nx22.ge.33) - + print *,'WARNING : Nx22 out of range',Nx22 - - if(y(iplan,ihit).ge.0) - + call sbit1(bitpx(iplan,icirc),nx22) !sets bit pos nx22 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpx(iplan,icirc+ncirc),nx22) - - - - if (idebug.eq.2)then - print *,' ' - print *,'iplan,ihit,icirc,NUM=',iplan,ihit,icirc,num(icirc) - print *,'x y xcmin xcmax ycmin ycmax ',x(iplan,ihit), - + y(iplan,ihit),xcmin(iplan,icirc),xcmax(iplan,icirc), - + ycmin(iplan,icirc),ycmax(iplan,icirc) - print *,'x22 nx22 xwidth-c xwidth-m xwidth-p =', - + x22,nx22,xwi_c(icirc),xwi_m(icirc),xwi_p(icirc) - print *,'bitpx(iplan,icirc) ', - + i2bin(bitpx(iplan,icirc),32) - print *,'bitpx(iplan,icirc+ncirc) ', - + i2bin(bitpx(iplan,icirc+ncirc),32) - endif - - - endif - endif - endif - -ccccccccccccccccccccc BIT PATTERN in Y cccccccccccccccccccccccccccc - - if(x(iplan,ihit).ge.xycmin(iplan,icirc).and. - + x(iplan,ihit).lt.xycmax(iplan,icirc))then - if(yabs.ge.ycmin(iplan,icirc).and. - + yabs.lt.ycmax(iplan,icirc))then - if(y(iplan,ihit).ge.0)yu(icirc)=1 - if(y(iplan,ihit).lt.0)yu(icirc+ncirc)=1 -c - if(iplan.eq.1)then - Y11=yabs-ycmin(iplan,icirc) - nY11=ifix(Y11/ywi(icirc))+1 !no of hitten strip - nstrip=nstrip_c(icirc) - if(nY11.le.0.or.nY11.ge.(nstrip+1)) - + print *,'WARNING : NY11 out of range',NY11 - - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY11) !sets bit pos nY11 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY11) - - - if (idebug.eq.2)then - print *,' ' - print *,'iplan,ihit,icirc,NUM=',iplan,ihit,icirc,num(icirc) - print *,'x y xycmin xycmax ycmin ycmax ',x(iplan,ihit), - + y(iplan,ihit),xycmin(iplan,icirc),xycmax(iplan,icirc), - + ycmin(iplan,icirc),ycmax(iplan,icirc) - print *,'Y11 nY11 nstripy ywidth=', - + Y11,nY11,nstrip,ywi(icirc) - print *,'bitpy(iplan,icirc) ', - + i2bin(bitpy(iplan,icirc),nstrip) - print *,'bitpy(iplan,icirc+ncirc) ', - + i2bin(bitpy(iplan,icirc+ncirc),nstrip) - endif - - - elseif(iplan.eq.2)then -c - Y12=yabs-ycmin(iplan,icirc) - nY12=ifix(Y12/(ywi(icirc)*Z2/Z1))+1 !no of hitten strip - nstrip=nstrip_c(icirc) - if(nY12.le.0.or.nY12.ge.(nstrip+1)) - + print *,'WARNING : NY12 out of range',NY12 - - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY12) !sets bit pos nY12 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY12) - - - if (idebug.eq.2)then - print *,' ' - print *,'iplan,ihit,icirc,NUM=',iplan,ihit,icirc,num(icirc) - print *,'x y xycmin xycmax ycmin ycmax ',x(iplan,ihit), - + y(iplan,ihit),xycmin(iplan,icirc),xycmax(iplan,icirc), - + ycmin(iplan,icirc),ycmax(iplan,icirc) - print *,'Y12 nY12 nstripy ywidth=', - + Y12,nY12,nstrip,ywi(icirc) - print *,'bitpy(iplan,icirc) ', - + i2bin(bitpy(iplan,icirc),nstrip) - print *,'bitpy(iplan,icirc+ncirc) ', - + i2bin(bitpy(iplan,icirc+ncirc),nstrip) - endif - - elseif(iplan.eq.3)then -c - Y21=yabs-ycmin(iplan,icirc) - nstrip=nstrip_c(icirc) - nY21=ifix(Y21/(ywi(icirc)*Z3/Z1))+1 !no of hitten strip - if(nY21.le.0.or.nY21.ge.(nstrip+1)) - + print *,'WARNING : NY21 out of range',NY21 - - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY21) !sets bit pos nY21 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY21) - -c various Y strip width in the same circuit - if(nstrip_p(icirc).ne.0.and.nstrip_p(icirc).lt.nstrip)then - xyextrap=xycmax(1,icirc)*Z3/Z1 - if(x(iplan,ihit).gt.xyextrap)then - if((mod(ny21,2)).eq.1)then - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY21+1) !sets bit pos nY21+1 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY21+1) - endif - if((mod(ny21,2)).eq.0)then - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY21-1) !sets bit pos nY21-1 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY21-1) - endif - endif - endif - - if(nstrip_m(icirc).ne.0.and.nstrip_m(icirc).lt.nstrip)then - xyextram=xycmin(1,icirc)*Z3/Z1 - if(x(iplan,ihit).lt.xyextram)then - if((mod(ny21,2)).eq.1)then - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY21+1) !sets bit pos nY21+1 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY21+1) - endif - if((mod(ny21,2)).eq.0)then - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY21-1) !sets bit pos nY21-1 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY21-1) - endif - endif - endif - - if (idebug.eq.2)then - print *,' ' - print *,'iplan,ihit,icirc,NUM=',iplan,ihit,icirc,num(icirc) - print *,'x y xycmin xycmax ycmin ycmax ',x(iplan,ihit), - + y(iplan,ihit),xycmin(iplan,icirc),xycmax(iplan,icirc), - + ycmin(iplan,icirc),ycmax(iplan,icirc) - print *,'Y21 nY21 nstripc ywidth= nstripm nstripp', - + Y21,nY21,nstrip,ywi(icirc),nstrip_m(icirc),nstrip_p(icirc) - print *,'bitpy(iplan,icirc) ', - + i2bin(bitpy(iplan,icirc),nstrip) - print *,'bitpy(iplan,icirc+ncirc) ', - + i2bin(bitpy(iplan,icirc+ncirc),nstrip) - if(nstrip_p(icirc).ne.0.and.nstrip_p(icirc).lt.nstrip)then - print *,'special changt de largeur Y : p plus larges' - print *,'xyextrap, mod(ny21,2)=',xyextrap, mod(ny21,2) - endif - if(nstrip_m(icirc).ne.0.and.nstrip_m(icirc).lt.nstrip)then - print *,'special changt de largeur Y : m plus larges' - print *,'xyextram, mod(ny21,2)=',xyextrap, mod(ny21,2) - endif - endif - - elseif(iplan.eq.4)then -c - Y22=yabs-ycmin(iplan,icirc) - nstrip=nstrip_c(icirc) - nY22=ifix(Y22/(ywi(icirc)*Z4/Z1))+1 !no of hitten strip - if(nY22.le.0.or.nY22.ge.(nstrip+1)) - + print *,'WARNING : NY22 out of range',NY22 - - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY22) !sets bit pos nY22 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY22) -c -c various Y strip width in the same circuit - if(nstrip_p(icirc).ne.0.and.nstrip_p(icirc).lt.nstrip)then - xyextrap=xycmax(1,icirc)*Z4/Z1 - if(x(iplan,ihit).gt.xyextrap)then - if((mod(ny22,2)).eq.1)then - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY22+1) !sets bit pos nY22+1 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY22+1) - endif - if((mod(ny22,2)).eq.0)then - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY22-1) !sets bit pos nY22-1 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY22-1) - endif - endif - endif - - if(nstrip_m(icirc).ne.0.and.nstrip_m(icirc).lt.nstrip)then - xyextram=xycmin(1,icirc)*Z4/Z1 - if(x(iplan,ihit).lt.xyextram)then - if((mod(ny22,2)).eq.1)then - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY22+1) !sets bit pos nY22+1 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY22+1) - endif - if((mod(ny22,2)).eq.0)then - if(y(iplan,ihit).ge.0) - + call sbit1(bitpy(iplan,icirc),nY22-1) !sets bit pos nY22-1 =1 - if(y(iplan,ihit).lt.0) - + call sbit1(bitpy(iplan,icirc+ncirc),nY22-1) - endif - endif - endif - - - if (idebug.eq.2)then - print *,' ' - print *,'iplan,ihit,icirc,NUM=',iplan,ihit,icirc,num(icirc) - print *,'x y xycmin xycmax ycmin ycmax ',x(iplan,ihit), - + y(iplan,ihit),xycmin(iplan,icirc),xycmax(iplan,icirc), - + ycmin(iplan,icirc),ycmax(iplan,icirc) - print *,'Y22 nY22 nstripc ywidth= nstripm nstripp', - + Y22,nY22,nstrip,ywi(icirc),nstrip_m(icirc),nstrip_p(icirc) - print *,'bitpy(iplan,icirc) ', - + i2bin(bitpy(iplan,icirc),nstrip) - print *,'bitpy(iplan,icirc+ncirc) ', - + i2bin(bitpy(iplan,icirc+ncirc),nstrip) - if(nstrip_p(icirc).ne.0.and.nstrip_p(icirc).lt.nstrip)then - print *,'special changt de largeur Y : p plus larges' - print *,'xyextrap, mod(ny22,2)=',xyextrap,mod(ny22,2) - endif - if(nstrip_m(icirc).ne.0.and.nstrip_m(icirc).lt.nstrip)then - print *,'special changt de largeur Y : m plus larges' - print *,'xyextram, mod(ny22,2)=',xyextrap, mod(ny22,2) - endif - endif - - - endif !iplan=1-4 -c - endif - endif -c - enddo !circuit - endif !x-y ne 0 - enddo !hits - enddo !plan - - - return - end -c -cc - subroutine ALGO(itrigR,itrigL0,itrigH0) - - -cc -c integer NUM(173),CODEX(173),CODEY(173) !173=Ncirc -c real xcmax(4,173),xcmin(4,173), -c + ycmax(4,173),ycmin(4,173), -c + xycmax(4,173),xycmin(4,173) -c real xwi_c(173),xwi_m(173),xwi_p(173),ywi(173) -c integer nstrip_c(173),nstrip_p(173),nstrip_m(173) -c -c common/TRIGMAP/xcmax,xcmin,ycmax,ycmin,xycmax,xycmin, -c + CODEX,CODEY, -c + xwi_c,xwi_m,xwi_p,ywi, -c + nstrip_c,nstrip_m,nstrip_p, -c + NUM,Z1,Z2,Z3,Z4,Ncirc - common/TRIGMAP/xcmax(4,173),xcmin(4,173),ycmax(4,173), - + ycmin(4,173),xycmax(4,173),xycmin(4,173), - + CODEX(173),CODEY(173), - + xwi_c(173),xwi_m(173),xwi_p(173),ywi(173), - + nstrip_c(173),nstrip_m(173),nstrip_p(173), - + NUM(173),Z1,Z2,Z3,Z4,Ncirc - integer nstrip_c,nstrip_p,nstrip_m - integer NUM,CODEX,CODEY,Ncirc - - common/debug/idebug - -cc - real xu(346),yu(346) ! something in x / y - integer*4 bitpx(4,346),bitpy(4,346) ! bit-pattern in x / y code DECIMAL - - common /hitcirc/xu,yu,bitpx,bitpy - - character*32 i2bin - - integer*4 dble1_0,dble1_1_14,dble1_15 - integer*4 dble2_0,dble2_1_30,dble2_31 - integer*4 sgle1_0,sgle1_1_14,sgle1_15 - integer*4 sgle2_0,sgle2_1_30,sgle2_31 - integer*4 sgle1A,sgle1B,sgle2A,sgle2B - integer*4 x1_1,x1_2a,x1_2b,x1_2c,x2_1,x2_2a,x2_2b,x2_2c - integer*4 dblex1(346),dblex2(346) - integer*4 sglex1(346),sglex2(346) - integer*4 dbley1(346),dbley2(346) - integer*4 sgley1(346),sgley2(346) - integer*4 thrl(346) - integer*4 co_l(16,346),co_y(16,346) - integer*4 ib,jb,iabit,ibbit,icbit,ibit_l,ibit_y - integer*4 sign_l(346),val_y(346) - integer*4 sign_lv -c L0 L.U.T. (et L2) - integer*4 dnp,dnm,dsup,dinf - integer*4 dev_2(346),num_x2(346),num_y2(346),signdev_2(346) - integer*4 devmin(16),stripnum(16),idevmin(16) - real yL2(346),x1L2(346),x2L2(346) -c - JBIT (IZW,IZP) = IBITS (IZW,IZP-1,1) - JBYT (IZW,IZP,NZB) = IBITS (IZW,IZP-1,NZB) - - - -c Threshold Road MAX +/-8 - data thrl /346*131071/ ! +/- 8 strips -c data thrl /346*4064/ ! +/- 3 strips -c -c Datas for L.U.T. calculations - data zF /975./ - data ptcalLow,ptcalHigh /.60,1.6/ -c -c init -c - do k=1,346 - sign_l(k)=0 - val_y(k)=0 - yL2(k)=0 - x1L2(k)=0 - x2L2(k)=0 - enddo -c -c histogram number and distribution of hitten circuits -c - - nHxcirc=0 - nHycirc=0 - nHcirc=0 - do icircT=1,ncirc*2 - if(xu(icircT).eq.1)nHxcirc=nHxcirc+1 - if(yu(icircT).eq.1)nHycirc=nHycirc+1 - if(xu(icircT).eq.1.or.yu(icircT).eq.1)nHcirc=nHcirc+1 !circuit non-vide - if(xu(icircT).eq.1.or.yu(icircT).eq.1)then - if(icircT.le.ncirc)then -c call hf1(11,float(icircT),1.) - else -c call hf1(11,-float(icircT-ncirc),1.) - endif - endif - enddo -c call hf1(10,float(nHcirc),1.) -c call hf1(12,float(nHxcirc),1.) -c call hf1(13,float(nHycirc),1.) - -c -c Calculate Singles and Doubles (including MINI-ROADS) -c - do icircT=1,ncirc*2 - if(xu(icircT).eq.1)then !loop on non-empty X circuit -c -c memo : integer=ibits(integer,start_pos,lenght), start_pos_min=0 -c -c MC1 - x1_1=ibits(bitpx(1,icircT),0,1) - x1_2a=ibits(bitpx(2,icircT),0,1) - x1_2b=ibits(bitpx(2,icircT),1,1) - dble1_0=iand(x1_1,ior(x1_2a,x1_2b)) - - x1_1 =ibits(bitpx(1,icircT),1,14) - x1_2a=ibits(bitpx(2,icircT),0,14) - x1_2b=ibits(bitpx(2,icircT),1,14) - x1_2c=ibits(bitpx(2,icircT),2,14) - dble1_1_14=iand(x1_1,ior(x1_2a,ior(x1_2b,x1_2c))) - - x1_1=ibits(bitpx(1,icircT),15,1) - x1_2a=ibits(bitpx(2,icircT),14,1) - x1_2b=ibits(bitpx(2,icircT),15,1) - dble1_15=iand(x1_1,ior(x1_2a,x1_2b)) - - dblex1(icircT)=dble1_0+2*dble1_1_14+(2**15)*dble1_15 !dble X on MC1 - - x1_1=ibits(bitpx(1,icircT),0,16) - sgle1A=ieor(x1_1,dblex1(icircT)) - - x1_2a=ibits(dblex1(icircT),0,1) - x1_2b=ibits(dblex1(icircT),1,1) - sgle1_0=ior(x1_2a,x1_2b) - - x1_2a=ibits(dblex1(icircT),0,14) - x1_2b=ibits(dblex1(icircT),1,14) - x1_2c=ibits(dblex1(icircT),2,14) - sgle1_1_14=ior(x1_2a,ior(x1_2b,x1_2c)) - - x1_2a=ibits(dblex1(icircT),14,1) - x1_2b=ibits(dblex1(icircT),15,1) - sgle1_15=ior(x1_2a,x1_2b) - - sgle1B=sgle1_0+2*sgle1_1_14+(2**15)*sgle1_15 - sgle1B=not(sgle1B) - sgle1B=iand(sgle1B,bitpx(2,icircT)) - - sglex1(icircT)=ior(sgle1A,sgle1B) !sgle X on MC1 - - - - dbley1(icircT)=iand(bitpy(1,icircT),bitpy(2,icircT)) !dble Y on MC1 - sgley1(icircT)= - + ieor(ior(bitpy(1,icircT),bitpy(2,icircT)),dbley1(icircT))!sgle Y on MC1 - - - if(idebug.eq.3)then - if(icircT.le.ncirc)then - nocirc=NUM(icircT) - else - nocirc=-NUM(icircT-ncirc) - endif - print *,' ' - print *,'no circuit ',icircT,nocirc - print *,'bitpx(1,icircT) ',i2bin(bitpx(1,icircT),16) - print *,'bitpx(2,icircT) ',i2bin(bitpx(2,icircT),16) - print *,'dblex1(icircT) ',i2bin(dblex1(icircT),16) - print *,'sglex1(icircT) ',i2bin(sglex1(icircT),16) - print *,' ' - print *,'bitpy(1,icircT) ',i2bin(bitpy(1,icircT),16) - print *,'bitpy(2,icircT) ',i2bin(bitpy(2,icircT),16) - print *,'dbley1(icircT) ',i2bin(dbley1(icircT),16) - print *,'sgley1(icircT) ',i2bin(sgley1(icircT),16) - - endif - - -c MC2 - x2_1=ibits(bitpx(3,icircT),0,1) - x2_2a=ibits(bitpx(4,icircT),0,1) - x2_2b=ibits(bitpx(4,icircT),1,1) - dble2_0=iand(x2_1,ior(x2_2a,x2_2b)) - - x2_1 =ibits(bitpx(3,icircT),1,30) - x2_2a=ibits(bitpx(4,icircT),0,30) - x2_2b=ibits(bitpx(4,icircT),1,30) - x2_2c=ibits(bitpx(4,icircT),2,30) - dble2_1_30=iand(x2_1,ior(x2_2a,ior(x2_2b,x2_2c))) - - x2_1=ibits(bitpx(3,icircT),31,1) - x2_2a=ibits(bitpx(4,icircT),30,1) - x2_2b=ibits(bitpx(4,icircT),31,1) - dble2_31=iand(x2_1,ior(x2_2a,x2_2b)) - - dblex2(icircT)=dble2_0+2*dble2_1_30+(2**31)*dble2_31 !dble X on MC2 - - x2_1=ibits(bitpx(3,icircT),0,32) - sgle2A=ieor(x2_1,dblex2(icircT)) - - x2_2a=ibits(dblex2(icircT),0,1) - x2_2b=ibits(dblex2(icircT),1,1) - sgle2_0=ior(x2_2a,x2_2b) - - x2_2a=ibits(dblex2(icircT),0,30) - x2_2b=ibits(dblex2(icircT),1,30) - x2_2c=ibits(dblex2(icircT),2,30) - sgle2_1_30=ior(x2_2a,ior(x2_2b,x2_2c)) - - x2_2a=ibits(dblex2(icircT),30,1) - x2_2b=ibits(dblex2(icircT),31,1) - sgle2_31=ior(x2_2a,x2_2b) - - sgle2B=sgle2_0+2*sgle2_1_30+(2**31)*sgle2_31 - sgle2B=not(sgle2B) - sgle2B=iand(sgle2B,bitpx(4,icircT)) - - sglex2(icircT)=ior(sgle2A,sgle2B) !sgle X on MC2 - - - dbley2(icircT)=iand(bitpy(3,icircT),bitpy(4,icircT)) !dble Y on MC2 - sgley2(icircT)= - + ieor(ior(bitpy(3,icircT),bitpy(4,icircT)),dbley2(icircT))!sgle Y on MC2 - - - if(idebug.eq.3)then - print*,' ' - print *,'bitpx(3,icircT) ',i2bin(bitpx(3,icircT),32) - print *,'bitpx(4,icircT) ',i2bin(bitpx(4,icircT),32) - print *,'dblex2(icircT) ',i2bin(dblex2(icircT),32) - print *,'sglex2(icircT) ',i2bin(sglex2(icircT),32) - print *,' ' - print *,'bitpy(3,icircT) ',i2bin(bitpy(3,icircT),16) - print *,'bitpy(4,icircT) ',i2bin(bitpy(4,icircT),16) - print *,'dbley2(icircT) ',i2bin(dbley2(icircT),16) - print *,'sgley2(icircT) ',i2bin(sgley2(icircT),16) - endif - - endif !non-empty X circuit - enddo !circuits -c -c -c method DS (X only) : reduce the sensibility of the trigger to single hits -c without loosing signal -c - do icircT=1,ncirc*2 - if(xu(icircT).eq.1)then !loop on non-empty X circuit to save CPU time - if(dblex1(icircT).ne.0)sglex1(icircT)=0 - if(dblex2(icircT).ne.0)sglex2(icircT)=0 - endif - enddo -c -c -c -c coincidence 3/4 in +/- 8 strips road -c - do icircT=1,2*ncirc - if(xu(icircT).eq.1)then !loop on non-empty X circuit - do ib=1,16 - do jb=ib,ib+16 - iabit=iand(jbit(sglex1(icircT),ib),jbit(dblex2(icircT),jb)) - ibbit=ior(jbit(sglex2(icircT),jb),jbit(dblex2(icircT),jb)) - icbit=ior(iabit,iand(ibbit,jbit(dblex1(icircT),ib))) - ibit_l=iand(icbit,jbit(thrl(icircT),jb-ib+1)) - call sbit(ibit_l,co_l(ib,icircT),jb-ib+1) - enddo - enddo - - if(idebug.eq.4)then - if (xu(icircT).ne.0)then - if(icircT.le.ncirc)then - nocirc=NUM(icircT) - else - nocirc=-NUM(icircT-ncirc) - endif - print *,' ' - print *,'no circuit ',icircT,nocirc - print *,'sglex1(icircT) ',i2bin(sglex1(icircT),16) - print *,'dblex1(icircT) ',i2bin(dblex1(icircT),16) - print *,'sglex2(icircT) ',i2bin(sglex2(icircT),32) - print *,'dblex2(icircT) ',i2bin(dblex2(icircT),32) - print *,' ' - print *,'thrl(icircT) ',i2bin(thrl(icircT),17) - do ib=1,16 - print *,'co_l(ib,icircT) ',i2bin(co_l(ib,icircT),17) - enddo - - endif - endif -c -c signe info (X) before L.U.T. -c - ibit_l=0 - do ib=1,16 - ibit_l=ior(ibit_l,co_l(ib,icircT)) - enddo - ibgauche=ibits(ibit_l,9,8) - ibcentre=ibits(ibit_l,8,1) - ibdroite=ibits(ibit_l,0,8) - if(ibgauche.eq.0.and.ibcentre.eq.0.and.ibdroite.eq.0)then - sign_l(icircT)=0 !00 - elseif(ibgauche.eq.0.and.ibcentre.eq.0)then - sign_l(icircT)=1 !01 - elseif(ibdroite.eq.0.and.ibcentre.eq.0)then - sign_l(icircT)=2 !10 - else - sign_l(icircT)=3 !11 - endif - - - if(idebug.eq.4)then - if (xu(icircT).ne.0)then - print*,' ' - print *,'sign_l(icircT) ',i2bin(sign_l(icircT),2) - endif - endif - endif !non-empty X circuits - enddo !circuits -c -c coincidences 3/4 Y (constant ROAD +/- 1) -c - do icircT=1,ncirc*2 - if(xu(icircT).eq.1)then !loop on non-empty X circuit - -c - if(icircT.le.ncirc)then - nstripy=nstrip_c(icircT) - else - nstripy=nstrip_c(icircT-ncirc) - endif -c - do ib=1,nstripy - do jb=ib,ib+2 !+/- 1 strip - - iabit=iand(jbit(sgley1(icircT),ib),jbit(2*dbley2(icircT),jb)) - ibbit=ior(jbit(2*sgley2(icircT),jb),jbit(2*dbley2(icircT),jb)) - ibit_y=ior(iabit,iand(ibbit,jbit(dbley1(icircT),ib))) - call sbit(ibit_y,co_y(ib,icircT),jb-ib+1) - enddo - enddo -c validation Y (OUTPUT L0 Y) - ibit_y=0 - do ib=1,nstripy - ibit_y=ior(ibit_y,co_y(ib,icircT)) - enddo - - - if(ibit_y.eq.0)then - val_y(icircT)=0 !nothing in Y - else - val_y(icircT)=1 !something in Y - endif - - if(idebug.eq.5)then - if (xu(icircT).ne.0)then - if(icircT.le.ncirc)then - nocirc=NUM(icircT) - else - nocirc=-NUM(icircT-ncirc) - endif - print *,' ' - print *,'no circuit ',icircT,nocirc - print *,'sgley1(icircT) ',i2bin(sgley1(icircT),nstripy) - print *,'dbley1(icircT) ',i2bin(dbley1(icircT),nstripy) - print *,'sgley2(icircT) ',i2bin(sgley2(icircT),nstripy) - print *,'dbley2(icircT) ',i2bin(dbley2(icircT),nstripy) - print *,' ' - do ib=1,nstripy - print *,'co_y(ib,icircT) ',i2bin(co_y(ib,icircT),3) - enddo - print *,' ' - print *,'val_y(icircT) ',i2bin(val_y(icircT),1) - - endif - endif - endif !non-empty X circuits - enddo !circuits -c -cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -c infos in +/- 8 road are available : sign_l(346) and val_y(346) -c where sign_l = 2 bits integer (00 nothing, 01 right dev., -c 10 left dev., 11 zero dev. or ambiguity) -c and val_y=0 (nothing) or 1 (validation of X) -cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -c -c Calculate trigger response in +/-8 strip road (for debugging) -c - igl_0=0 - idl_0=0 - igh_0=0 - idh_0=0 - il_0=0 - ih_0=0 - itrigR=0 - - - - do icircT=1,2*ncirc - if(xu(icircT).eq.1)then !loop on non-empty X circuit - -c with Y validation - sign_lv=sign_l(icircT)*val_y(icircT) - if (sign_lv.eq.1.or.sign_lv.eq.3)idl_0=idl_0+1 - if (sign_lv.eq.2.or.sign_lv.eq.3)igl_0=igl_0+1 - if (sign_lv.ge.1)il_0=il_0+1 - - endif !non-empty X circuits - enddo !circuits - - - if(il_0.ge.2.and. - + idl_0.ne.0.and.igl_0.ne.0)itrigR=1 !U.S. trigger Road +/-8 -* if(il_0.ge.1)itrigR=1 -c -c -c -c -c INTERFACE L0-L.U.T. (and L2) in X : -c nO CIRCUIT + Hitten STRIP (MC1) + DEVMIN (MC2) + SIGNDEV -c -c L.U.T. (and L2) calculation ARE done only if a LOCAL trigger -c in +/-8 strips (sign_lv.ne.0) is found -c -c - do icircT=1,ncirc*2 - sign_lv=sign_l(icircT)*val_y(icircT) - if(sign_lv.ne.0)then !local trigger +/- 8 strips -c - do ib=1,16 - if(co_l(ib,icircT).eq.0)then - devmin(ib)=100 !dummy - elseif(iand(256,co_l(ib,icircT)).ne.0)then - devmin(ib)=0 !central strip - elseif(iand(128,co_l(ib,icircT)).ne.0)then - devmin(ib)=-1 ! DOWN priority and <0 - elseif(iand(512,co_l(ib,icircT)).ne.0)then - devmin(ib)=1 ! UP >0 (convention x>0) - elseif(iand(64,co_l(ib,icircT)).ne.0)then - devmin(ib)=-2 - elseif(iand(1024,co_l(ib,icircT)).ne.0)then - devmin(ib)=2 - elseif(iand(32,co_l(ib,icircT)).ne.0)then - devmin(ib)=-3 - elseif(iand(2048,co_l(ib,icircT)).ne.0)then - devmin(ib)=3 - elseif(iand(16,co_l(ib,icircT)).ne.0)then - devmin(ib)=-4 - elseif(iand(4096,co_l(ib,icircT)).ne.0)then - devmin(ib)=4 - elseif(iand(8,co_l(ib,icircT)).ne.0)then - devmin(ib)=-5 - elseif(iand(8192,co_l(ib,icircT)).ne.0)then - devmin(ib)=5 - elseif(iand(4,co_l(ib,icircT)).ne.0)then - devmin(ib)=-6 - elseif(iand(16384,co_l(ib,icircT)).ne.0)then - devmin(ib)=6 - elseif(iand(2,co_l(ib,icircT)).ne.0)then - devmin(ib)=-7 - elseif(iand(32768,co_l(ib,icircT)).ne.0)then - devmin(ib)=7 - elseif(iand(1,co_l(ib,icircT)).ne.0)then - devmin(ib)=-8 - elseif(iand(65536,co_l(ib,icircT)).ne.0)then - devmin(ib)=8 - endif - enddo -c order deviation (cf CERNLIB) - do ib =1,16 - idevmin(ib)=iabs(devmin(ib)) - enddo - call SORTZV(idevmin,stripnum,16,-1,0,0) -c - num_x2(icircT)=stripnum(1) - dev_2(icircT)=devmin(stripnum(1)) - if(dev_2(icirct).lt.0)then - signdev_2(icircT)=1 - elseif(dev_2(icirct).eq.0)then - signdev_2(icircT)=3 - else - signdev_2(icircT)=2 - endif - - -c -c -c INTERFACE L0-L.U.T. (and L2) in Y : nO CIRCUIT + Hitten STRIP (MC1) -c - if(icircT.le.ncirc)then - nstripy=nstrip_c(icircT) - else - nstripy=nstrip_c(icircT-ncirc) - endif -c - do ib=nstripy,1,-1 !keep lower weight (convention) - if(co_y(ib,icircT).ne.0)num_y2(icircT)=ib - enddo - - - - if(idebug.eq.6)then - if(icircT.le.ncirc)then - nocirc=NUM(icircT) - else - nocirc=-NUM(icircT-ncirc) - endif - print *,' ' - print *,'no circuit ',icircT,nocirc - do ib=1,16 - print *,'strip no ',ib,': ',i2bin(co_l(ib,icircT),17), - + ' dev_min=',devmin(ib) - enddo - print *,'num_x2(icircT)= ',num_x2(icircT) - print *,' dev_2(icircT)= ',dev_2(icircT) -c - print *,' ' - do ib=1,nstripy - print *,'strip no ',ib,': ', - + i2bin(co_y(ib,icircT),3) - enddo - print *,'num_y2(icircT)= ',num_y2(icircT) - endif - - - endif !end local trigger +/- 8 strips - enddo - -c -c -cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -c Datas for L0===>L.U.T. (and L2) : -c icircT -c num_x2(icircT)===>X MC1 -c dev_2(icircT) ===>X MC2 -c signdev_2(icircT)===>sign dev_2(icircT) -c num_y2(icircT)===>Y MC1 -ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc -c -c Now calculate X MC1 and X MC2 and Y MC1 -c ===> Back to trigger GEOMETRY -c - do icircT=1,2*ncirc - sign_lv=sign_l(icircT)*val_y(icircT) - if(sign_lv.ne.0)then !local trigger +/- 8 strips -calculation of YL2 (middle of the strip) - if(icircT.le.ncirc)then !Y>0 - yL2(icircT)=ycmin(1,icircT)+ywi(icircT)*(num_y2(icircT)-.5) - else ! Y<0 - yL2(icircT)=-ycmin(1,icircT-ncirc) - + -ywi(icircT-ncirc)*(num_y2(icircT)-.5) - endif - -calculation of X1L2 (MC1) (middle of the strip) - if(icircT.le.ncirc)then ! Y>0 - x1L2(icircT)=xcmin(1,icircT)+xwi_c(icircT)*(num_x2(icircT)-.5) - else ! Y<0 - x1L2(icircT)=xcmin(1,icircT-ncirc) - + +xwi_c(icircT-ncirc)*(num_x2(icircT)-.5) - endif - -calculation of X2L2 (MC2) (middle of the strip) - - if(icircT.le.ncirc)then - xxwi_c=xwi_c(icircT) - xxwi_p=xwi_p(icircT) - xxwi_m=xwi_m(icircT) - else - xxwi_c=xwi_c(icircT-ncirc) - xxwi_p=xwi_p(icircT-ncirc) - xxwi_m=xwi_m(icircT-ncirc) - endif - - if(dev_2(icircT).ge.0)then - Dnp=16-num_x2(icircT) - Dnm=0 !RAZ, not used - dsup=dev_2(icircT)-Dnp - dinf=0 !RAZ, not used - if(dsup.le.0)then - x2L2(icircT)=(x1L2(icircT)+xxwi_c*dev_2(icircT))*Z3/Z1 - else - x2L2(icircT)=(x1L2(icircT)+xxwi_c*Dnp+xxwi_p*dsup)*Z3/Z1 - endif - else - Dnp=0 !RAZ, not used - Dnm=num_x2(icircT)-1 - dinf=iabs(dev_2(icircT))-Dnm - dsup=0 !RAZ, not used - if(dinf.le.0)then - x2L2(icircT)=(x1L2(icircT)-xxwi_c*iabs(dev_2(icircT)))*Z3/Z1 - else - x2L2(icircT)=(x1L2(icircT)-xxwi_c*Dnm-xxwi_m*dinf)*Z3/Z1 - endif - endif - - if(idebug.eq.7)then - if(icircT.le.ncirc)then - nocirc=NUM(icircT) - yywi=ywi(icircT) - else - nocirc=-NUM(icircT-ncirc) - yywi=ywi(icircT-ncirc) - endif - print *,' ' - print *,'no circuit ',icircT,nocirc - print *,'num_y2 ywi yL2 = ',num_y2(icircT),yywi,yL2(icircT) - print *,'num_x2 xwiC x1L2 = ', - + num_x2(icircT),xxwi_c,x1L2(icircT) - print *,'dev_2 DnP Dnm dsup dinf ', - + dev_2(icircT),Dnp,Dnm,dsup,dinf - print *,'xwiM xwiC xwiP x2L2 = ', - + xxwi_m,xxwi_c,xxwi_p,x2L2(icircT) - print *,'sign dev =',i2bin(sign_lv,2) - endif - - endif !end local trigger +/- 8 strips - enddo !circuits - -c -c -ccc NOW pt calculation (for the L.U.T) -c -cinit - idlc_2p=0 - idhc_2p=0 - idlc_2m=0 - idhc_2m=0 - idlc_2=0 - idhc_2=0 -c - do icircT=1,2*ncirc - sign_lv=sign_l(icircT)*val_y(icircT) - if(sign_lv.ne.0)then !local pt trigger +/- 8 strips -c calculate tetadev (x-z plane) - anum=z3*(x2L2(icircT)-x1L2(icircT))/(z3-z1) - anum=anum-x2L2(icircT) - tetadev=anum/zF -c calculate ptcalc (need rF) - xF=(x2L2(icircT)-x1L2(icircT))*(z3-zF)/(z3-z1) - xF=x2L2(icircT)-xF - yF=yL2(icircT)*zF/z1 - rF=sqrt(xF*xF+yF*yF) - if(abs(tetadev).ge.0.00001)then - ptcalc=(rF/zF)*abs(0.9/tetadev) - else ! infinity - ptcalc=10000. - endif - -c for L0 pt cut using the sign of the deviation signdev_2(icircT) - - if (ptcalc.ge.ptcalLow.and. - + (signdev_2(icircT).eq.1.or.signdev_2(icircT).eq.3)) - + idlc_2p=idlc_2p+1 - if (ptcalc.ge.ptcalLow.and. - + (signdev_2(icircT).eq.2.or.signdev_2(icircT).eq.3)) - + idlc_2m=idlc_2m+1 - if (ptcalc.ge.ptcalLow.and.signdev_2(icircT).ge.1) - + idlc_2=idlc_2+1 - - if (ptcalc.ge.ptcalHigh.and. - + (signdev_2(icircT).eq.1.or.signdev_2(icircT).eq.3)) - + idhc_2p=idhc_2p+1 - if (ptcalc.ge.ptcalHigh.and. - + (signdev_2(icircT).eq.2.or.signdev_2(icircT).eq.3)) - + idhc_2m=idhc_2m+1 - if (ptcalc.ge.ptcalHigh.and.signdev_2(icircT).ge.1) - + idhc_2=idhc_2+1 - - if(idebug.eq.8)then - if(icircT.le.ncirc)then - nocirc=NUM(icircT) - else - nocirc=-NUM(icircT-ncirc) - endif - print *,' ' - print *,'no circuit ',icircT,nocirc - print *,'compteurs trigger L0 (boucle circuit ) ' - print *,'signdev_2 =',i2bin(signdev_2(icircT),2) - print *,'ptcalc,ptcalLow',ptcalc,ptcalLow - print *,'LOW pt calc + et -, mult:',idlc_2p,idlc_2m,idlc_2 - print *,'ptcalc,ptcalHigh',ptcalc,ptcalHigh - print *,'HIGH pt calc + et -, mult:',idhc_2p,idhc_2m,idhc_2 - endif - - - endif !end local trigger +/- 8 strips - enddo !circuits - -c -c for L0 L.U.T. trigger response -c - itrigL0=0 - itrigH0=0 - - if(idlc_2.ge.2.and. - + idlc_2p.ne.0.and.idlc_2m.ne.0)itrigL0=1 - if(idhc_2.ge.2.and. - + idhc_2p.ne.0.and.idhc_2m.ne.0)itrigH0=1 -* if(idlc_2.ge.1)itrigL0=1 -* if(idhc_2.ge.1)itrigH0=1 -c - return - end -c -c -cc - subroutine seqtest - - real x(4,1000),y(4,1000) ! 1000=nhitmax - common /hitRPC/ x,y -c -c generation of test sequence of hits for debuging proposes -c - x(1,1)= 58.8 - y(1,1)=-52.3 - x(2,1)= 60.6 - y(2,1)=-52.7 - x(3,1)= 64.8 - y(3,1)=-55.5 - x(4,1)= 65.5 - y(4,1)=-56.0 - - x(1,2)=-105.4 - y(1,2)=-26.7 - x(2,2)=-106.7 - y(2,2)=-27.0 - x(3,2)=-114.4 - y(3,2)=-28.9 - x(4,2)=-115.7 - y(4,2)=-29.2 - - return - end -c -c -c -c function that returns a string corresp. to the integer coded in bits -c - CHARACTER*(*) FUNCTION i2bin(iw,kbit) -c i2bin='' ??????????????? - - i2bin=' ' - do ib= 0,kbit-1 - if(ibits(iw,ib,1).eq.0)then - i2bin='0'//i2bin - else - i2bin='1'//i2bin - endif - enddo - return - end - - SUBROUTINE SORTZV (A,INDEX,N1,MODE,NWAY,NSORT) -C -C CERN PROGLIB# M101 SORTZV .VERSION KERNFOR 3.15 820113 -C ORIG. 02/10/75 -C - DIMENSION A(N1),INDEX(N1) -C -C - N = N1 - IF (N.LE.0) RETURN - IF (NSORT.NE.0) GO TO 2 - DO 1 I=1,N - 1 INDEX(I)=I -C - 2 IF (N.EQ.1) RETURN - IF (MODE) 10,20,30 - 10 CALL SORTTI (A,INDEX,N) - GO TO 40 -C - 20 CALL SORTTC(A,INDEX,N) - GO TO 40 -C - 30 CALL SORTTF (A,INDEX,N) -C - 40 IF (NWAY.EQ.0) GO TO 50 - N2 = N/2 - DO 41 I=1,N2 - ISWAP = INDEX(I) - K = N+1-I - INDEX(I) = INDEX(K) - 41 INDEX(K) = ISWAP - 50 RETURN - END -* ======================================== - SUBROUTINE SORTTF (A,INDEX,N1) -C - DIMENSION A(N1),INDEX(N1) -C - N = N1 - DO 3 I1=2,N - I3 = I1 - I33 = INDEX(I3) - AI = A(I33) - 1 I2 = I3/2 - IF (I2) 3,3,2 - 2 I22 = INDEX(I2) - IF (AI.LE.A (I22)) GO TO 3 - INDEX (I3) = I22 - I3 = I2 - GO TO 1 - 3 INDEX (I3) = I33 - 4 I3 = INDEX (N) - INDEX (N) = INDEX (1) - AI = A(I3) - N = N-1 - IF (N-1) 12,12,5 - 5 I1 = 1 - 6 I2 = I1 + I1 - IF (I2.LE.N) I22= INDEX(I2) - IF (I2-N) 7,9,11 - 7 I222 = INDEX (I2+1) - IF (A(I22)-A(I222)) 8,9,9 - 8 I2 = I2+1 - I22 = I222 - 9 IF (AI-A(I22)) 10,11,11 - 10 INDEX(I1) = I22 - I1 = I2 - GO TO 6 - 11 INDEX (I1) = I3 - GO TO 4 - 12 INDEX (1) = I3 - RETURN - END -* ======================================== - SUBROUTINE SORTTI (A,INDEX,N1) -C - INTEGER A,AI - DIMENSION A(N1),INDEX(N1) -C - N = N1 - DO 3 I1=2,N - I3 = I1 - I33 = INDEX(I3) - AI = A(I33) - 1 I2 = I3/2 - IF (I2) 3,3,2 - 2 I22 = INDEX(I2) - IF (AI.LE.A (I22)) GO TO 3 - INDEX (I3) = I22 - I3 = I2 - GO TO 1 - 3 INDEX (I3) = I33 - 4 I3 = INDEX (N) - INDEX (N) = INDEX (1) - AI = A(I3) - N = N-1 - IF (N-1) 12,12,5 - 5 I1 = 1 - 6 I2 = I1 + I1 - IF (I2.LE.N) I22= INDEX(I2) - IF (I2-N) 7,9,11 - 7 I222 = INDEX (I2+1) - IF (A(I22)-A(I222)) 8,9,9 - 8 I2 = I2+1 - I22 = I222 - 9 IF (AI-A(I22)) 10,11,11 - 10 INDEX(I1) = I22 - I1 = I2 - GO TO 6 - 11 INDEX (I1) = I3 - GO TO 4 - 12 INDEX (1) = I3 - RETURN - END -* ======================================== - SUBROUTINE SORTTC (A,INDEX,N1) -C - INTEGER A,AI - DIMENSION A(N1),INDEX(N1) -C - N = N1 - DO 3 I1=2,N - I3 = I1 - I33 = INDEX(I3) - AI = A(I33) - 1 I2 = I3/2 - IF (I2) 3,3,2 - 2 I22 = INDEX(I2) - IF(ICMPCH(AI,A(I22)))3,3,21 - 21 INDEX (I3) = I22 - I3 = I2 - GO TO 1 - 3 INDEX (I3) = I33 - 4 I3 = INDEX (N) - INDEX (N) = INDEX (1) - AI = A(I3) - N = N-1 - IF (N-1) 12,12,5 - 5 I1 = 1 - 6 I2 = I1 + I1 - IF (I2.LE.N) I22= INDEX(I2) - IF (I2-N) 7,9,11 - 7 I222 = INDEX (I2+1) - IF (ICMPCH(A(I22),A(I222))) 8,9,9 - 8 I2 = I2+1 - I22 = I222 - 9 IF (ICMPCH(AI,A(I22))) 10,11,11 - 10 INDEX(I1) = I22 - I1 = I2 - GO TO 6 - 11 INDEX (I1) = I3 - GO TO 4 - 12 INDEX (1) = I3 - RETURN - END -* ======================================== - FUNCTION ICMPCH(IC1,IC2) -C FUNCTION TO COMPARE TWO 4 CHARACTER EBCDIC STRINGS - IC1,IC2 -C ICMPCH=-1 IF HEX VALUE OF IC1 IS LESS THAN IC2 -C ICMPCH=0 IF HEX VALUES OF IC1 AND IC2 ARE THE SAME -C ICMPCH=+1 IF HEX VALUES OF IC1 IS GREATER THAN IC2 - I1=IC1 - I2=IC2 - IF(I1.GE.0.AND.I2.GE.0)GOTO 40 - IF(I1.GE.0)GOTO 60 - IF(I2.GE.0)GOTO 80 - I1=-I1 - I2=-I2 - IF(I1-I2)80,70,60 - 40 IF(I1-I2)60,70,80 - 60 ICMPCH=-1 - RETURN - 70 ICMPCH=0 - RETURN - 80 ICMPCH=1 - RETURN - END - - - SUBROUTINE SBIT (IT,IZW,IZP) -C -C CERN PROGLIB# M421 SBIT .VERSION KERNFOR 4.23 891215 -C MOD. true default 24/2/89, JZ -C -C This non-ANSI code is a default which may be slow, if so -C it should be replaced by a machine-specific fast routine - - IF(IAND(IT,1).EQ.0) THEN - IZW = IBCLR(IZW,IZP-1) - ELSE - IZW = IBSET(IZW,IZP-1) - ENDIF - - END - - SUBROUTINE SBIT1 (IZW,IZP) -C -C CERN PROGLIB# M421 SBIT1 .VERSION KERNFOR 4.23 891215 -C MOD. true default 24/2/89, JZ -C -C This non-ANSI code is a default which may be slow, if so -C it should be replaced by a machine-specific fast routine - - IZW = IBSET (IZW, IZP-1) - - END - diff --git a/MUON/dedx.C b/MUON/dedx.C new file mode 100644 index 00000000000..d50efc2be06 --- /dev/null +++ b/MUON/dedx.C @@ -0,0 +1,36 @@ +void dedx(Int_t imate) +{ + TGeant3 *geant3 = (TGeant3*)gMC; + Float_t tkin[100], value[100], pcut[5]; + Int_t ipart=5; + char chmeca[4]; + strcpy(chmeca,"LOSS"); + Int_t ixst, i; + Int_t kdim=100; + + for (i=0; i< kdim; i++) { + tkin[i]=Float_t(i)*1.+1; + } + geant3->Gftmat(imate, ipart, chmeca, kdim, tkin, value, pcut, ixst); + for (i=0; i< kdim; i++) { + printf("\n Energy %f dE/dx %f", tkin[i], value[i]); + } + TGraph* dedx = new TGraph(kdim, tkin, value); + TCanvas *c1=new TCanvas("c1","dedx",400,10,600,700); + dedx->SetFillColor(42); + dedx->SetMarkerColor(4); + dedx->SetMarkerStyle(21); + dedx->Draw("AC"); + dedx->GetHistogram()->SetXTitle("Kinetic Energy (GeV)"); + dedx->GetHistogram()->SetYTitle("dE/dx "); + } + + + + + + + + + + diff --git a/MUON/masse.C b/MUON/masse.C new file mode 100644 index 00000000000..3b25899a78f --- /dev/null +++ b/MUON/masse.C @@ -0,0 +1,195 @@ +{ +////////////////////////////////////////////////////////// +// This file has been automatically generated +// (Wed Jun 16 15:35:08 1999 by ROOT version 2.21/07) +// from TTree ntuple/Reconst ntuple +// found on file: reconst.root +////////////////////////////////////////////////////////// + +//Reset ROOT and connect tree file +gROOT->Reset(); + +TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("reconst.root"); +if (!f) { + f = new TFile("reconst.root"); +} + +TTree *ntuple = (TTree*)gDirectory->Get("ntuple"); + +TPostScript ps("mass.ps",112); +//ps->Open("mass.ps"); +//Declaration of leaves types +Int_t ntrack=500; + +Int_t ievr; +Int_t ntrackr; +Int_t istatr[ntrack]; +Int_t isignr[ntrack]; +Float_t pxr[ntrack]; +Float_t pyr[ntrack]; +Float_t pzr[ntrack]; +Float_t zvr[ntrack]; +Float_t chi2r[ntrack]; + +//Set branch addresses +ntuple->SetBranchAddress("ievr",&ievr); +ntuple->SetBranchAddress("ntrackr",&ntrackr); +ntuple->SetBranchAddress("istatr",&istatr); +ntuple->SetBranchAddress("isignr",&isignr); +ntuple->SetBranchAddress("pxr",&pxr); +ntuple->SetBranchAddress("pyr",&pyr); +ntuple->SetBranchAddress("pzr",&pzr); +ntuple->SetBranchAddress("zvr",&zvr); +ntuple->SetBranchAddress("chi2r",&chi2r); + +// This is the loop skeleton +// To read only selected branches, Insert statements like: +// ntuple->SetBranchStatus("*",0); // disable all branches +// ntuple->SetBranchStatus("branchname",1); // activate branchname + +TH1F *h1 = new TH1F("h1","mass",240,0.,12.); +TH1F *h2 = new TH1F("h2","mass good muon",240,0.,12.); +// Upsilon mass cut +TH1F *h5 = new TH1F("h5"," Mass Upsilon",70,8.,11.); +// J/psi mass cut +//TH1F *h5 = new TH1F("h5"," Mass J/psi",120,1.,5.); +TH1F *h3 = new TH1F("h3","Pt",100,0.,20.); +TH1F *h4 = new TH1F("h4","Pt bon muon",100,0.,20.); + +gStyle->SetOptFit(); +//gStyle->SetOptStat(0000); +gStyle->SetOptStat(10001110); + +Float_t mass = 1.; +Float_t amassmu = 0.10566; +Float_t Chi2Cut = 100.; +Float_t PtCut = 0.; +//Float_t MassMin = 8.96; +//Float_t MassMax = 9.96; +// Upsilon +Float_t MassMin = 8.5; +Float_t MassMax = 10.5; +// J/psi +//Float_t MassMin = 2.5; +//Float_t MassMax = 3.8; + +//Float_t Chi2Cut = 999.; + +Int_t nentries = ntuple->GetEntries(); + +Int_t nbytes = 0; +Int_t nbtrack[50]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +Int_t compt = 0; +Int_t Nres = 0; + +// Good muons +for (Int_t iev=0; ievGetEvent(iev); +// ntuple->SetBranchStatus("main",1); + ntuple->SetBranchStatus("*",1); + + //printf("\n"); + // printf("ntrackr=%d\n",ntrackr); + + if(ntrackr < 50) nbtrack[ntrackr]=nbtrack[ntrackr]+1 ; + + + for (Int_t i=0; i<(ntrackr-1); i++) { + + Float_t px1 = pxr[i] ; + Float_t py1 = pyr[i] ; + Float_t pz1 = pzr[i] ; + Float_t Pt1 = TMath::Sqrt(px1*px1+py1*py1) ; + +// if (chi2r[i] < Chi2Cut && istatr[i] == 1 && Pt1 > PtCut) { + h4->Fill(Pt1); + + for (Int_t j=i+1; j PtCut ) { + if (isignr[i]!=isignr[j]) { + Float_t p12 = px1*px1+py1*py1+pz1*pz1; + Float_t p22 = px2*px2+py2*py2+pz2*pz2; + Float_t e1 = TMath::Sqrt(amassmu*amassmu+p12); + Float_t e2 = TMath::Sqrt(amassmu*amassmu+p22); + Float_t amass = TMath::Sqrt((e1+e2)*(e1+e2)-(px1+px2)*(px1+px2)-(py1+py2)*(py1+py2)-(pz1+pz2)*(pz1+pz2)); +// printf("amass=%f\n",amass); + h2->Fill(amass); + if (amass<11. && amass>8.) compt++; + } + } + } + } + + + + + // All tracks + for (Int_t i=0; i<(ntrackr-1); i++) { + Float_t px1 = pxr[i] ; + Float_t py1 = pyr[i] ; + Float_t pz1 = pzr[i] ; + Float_t Pt1 = TMath::Sqrt(px1*px1+py1*py1) ; + if (chi2r[i] < Chi2Cut && Pt1 > PtCut) { + h3->Fill(Pt1); + for (Int_t j=i+1; j PtCut) { + if (isignr[i]!=isignr[j]) { + Float_t p12 = px1*px1+py1*py1+pz1*pz1; + Float_t p22 = px2*px2+py2*py2+pz2*pz2; + Float_t e1 = TMath::Sqrt(amassmu*amassmu+p12); + Float_t e2 = TMath::Sqrt(amassmu*amassmu+p22); + Float_t amass = TMath::Sqrt((e1+e2)*(e1+e2)-(px1+px2)*(px1+px2)-(py1+py2)*(py1+py2)-(pz1+pz2)*(pz1+pz2)); + // printf("amass=%f\n",amass); + h1->Fill(amass); + if (amass > MassMin && amass < MassMax) { + // if (ntrackr==2) h5->Fill(amass); + h5->Fill(amass); +// if (amass < 9.715 && amass > 9.205) + if (amass < 9.766 && amass > 9.154) + { + printf("amass=%f\n",amass); + Nres++; + } + } + } + } + } + } + } +} + +// printf("compt= %d\n",compt); + +for (Int_t i = 0 ; i<50 ; i++) +{ + + printf(" nb of events= %d with %d tracks \n",nbtrack[i], i) ; + +} +g1= new TF1("g1","gaus",9.30,9.75) ; +//g1= new TF1("g1","gaus",8.7,10.2) ; +//g1= new TF1("g1","gaus",2.95,3.25) ; +h5->Fit("g1","R0") ; +h5->SetXTitle("Mass (GeV/c^2!)"); +h5->Draw(); +printf("Nombre de resonances : %d\n",Nres); + +ps->Close(); +} + + + + + + + + diff --git a/MUON/reco_muon.F b/MUON/reco_muon.F index 830b3bc9dde..06895f122d6 100644 --- a/MUON/reco_muon.F +++ b/MUON/reco_muon.F @@ -85,6 +85,10 @@ IMPLICIT DOUBLE PRECISION(A-H,O-Z) COMMON/DEBEVT/IDEBUG + common/dstation/idstation + +* idsation = 8 + idstation = 20 IDEBUG=IDEBUGC @@ -112,36 +116,23 @@ PARAMETER(NBSTATION=5) * -- COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) - - DATA DZ_PL/8.,8.,24.3,8.,8./ -** DATA DZ_PL/8.,8.,8.,8.,8./ -* DATA DZ_PL/20.,20.,20.,20.,20./ -* DATA DZ_PL/20.,20.,24.3,20.,20./ -* DATA DZ_PL/20.,40.,40.,40.,40./ -* DATA DZ_PL/20.,50.,50.,50.,50./ -* DATA DZ_PL/20.,55.,55.,55.,55./ -* DATA DZ_PL/20.,60.,60.,60.,60./ -* DATA DZ_PL/20.,80.,80.,80.,80./ -* DATA DZ_PL/20.,100.,100.,100.,100./ - - DATA ZPLANE/-511.,-686.0,-962.7,-1245.,-1445./ ! dstation=8cm - -* DATA ZPLANE/-507.5,-682.5,-967.5,-1241.5,-1441.5/ ! dstation=20cm CCC -* DATA ZPLANE/-505.,-680.,-965.,-1239.,-1439./ ! dstation=20cm -** DATA ZPLANE/-511.,-686.0,-971.,-1245.,-1445./ ! dstation=8cm -* DATA ZPLANE/-511.,-686.0,-962.7,-1245.,-1445./ ! dstation=8cm -* DATA ZPLANE/-505.,-680.,-962.7,-1239.,-1439./ ! dstation=20cm -* DATA ZPLANE/-505.,-670.,-954.,-1229.,-1429./ ! dstation=40cm -* DATA ZPLANE/-505.,-665.,-949.,-1224.,-1424./ ! dstation=50cm -* DATA ZPLANE/-505.,-663.,-947.,-1222.,-1422./ ! dstation=50cm -* DATA ZPLANE/-505.,-660.,-944.,-1219.,-1419./ ! dstation=60cm -* DATA ZPLANE/-505.,-650.,-935.,-1209.,-1409./ ! dstation=80cm -* DATA ZPLANE/-505.,-640.,-925.,-1199.,-1399./ ! dstation=100cm - -** DATA ZPLANE/-507.,-682.0,-950.7,-1241.,-1441./ - -** DATA ZCOIL,ZMAGEND/-825.0,-1125./ ! Constant field 3 Tm +* ZPLANE = position de la premiere chambre de chaque station +* exemple (pour la premiere station) : +* zch (dans AliMUONv0) = 540 (position du centre des 2 chambres) +* implique : +* ZPLANE = -530 si DZ_PL = 20cm + +* dstation = 8cm : +* DATA DZ_PL/8.,8.,8.,8.,8./ +* DATA ZPLANE/-511.,-686.0,-971.,-1245.,-1445./ + +* dstation=20cm : + DATA DZ_PL/20.,20.,20.,20.,20./ + DATA ZPLANE/-518.,-680.,-965.,-1239.,-1439./ +* end if + +* DATA ZCOIL,ZMAGEND/-825.0,-1125./ ! Constant field 3 Tm DATA ZCOIL,ZMAGEND/-805.0,-1233./ ! CCC magn. field map M.B ** DATA ZCOIL,ZMAGEND/-795.1,-1242.9/ ! CCC magn. field map M.B @@ -167,8 +158,7 @@ COMMON/TRACKFI/EFF,EFF1,EFF2,XPREC,YPREC,PHIPREC,ALAMPREC, & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP -** SIGCUT = SSIGCUT - SIGCUT=5. ! CCC + SIGCUT = SSIGCUT END @@ -180,8 +170,7 @@ COMMON/TRACKFI/EFF,EFF1,EFF2,XPREC,YPREC,PHIPREC,ALAMPREC, & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP -** XPREC = SXPREC - XPREC = 0.01 ! CCC + XPREC = SXPREC END @@ -194,7 +183,6 @@ & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP YPREC = SYPREC -** YPREC = 0.2 ! CCC END @@ -309,7 +297,7 @@ DATA B0,BL3/7.,2.0/ ! Magnetic field in the dipole & L3 in kgauss DATA ZMAGS/805.0D0/,ZMAGE/1233.0D0/,ZABS/503.D0/ ! CCC not used when ! magn. field map -** DATA ZMAGS/825.0D0/,ZMAGE/1125.0D0/,ZABS/503.D0/ +* DATA ZMAGS/825.0D0/,ZMAGE/1125.0D0/,ZABS/503.D0/ DATA XMAG/190.0D0/ ** DATA XPREC/0.0100D0/,YPREC/0.144337D0/ ! CCC @@ -325,6 +313,10 @@ ZPLANEP(J) = -ZPLANE(I)+DZ_PL(I) ENDDO + do i=1,10 + print*,'zplanep(',i,')=',ZPLANEP(I) + end do + PCUT = 3. ! Coupure en PXZ muon (GeV/c) PTCUT = 0. ! Coupure en Pt muon (GeV/c) @@ -419,7 +411,7 @@ CALL TRACKF_READ_GEANT(ITYPG,XTRG,YTRG,PTOTG,IDG,IZCH,PVERT1G, & PVERT2G,PVERT3G,ZVERTG,NHITTOT1,CX,CY,CZ,IEVR,NEV, & XGEANT,YGEANT,CLSIZE1,CLSIZE2) - ELSE + ELSE ! reconstructed hits CALL TRACKF_READ_SPOINT(ITYPG,XTRG,YTRG,PTOTG,IDG,IZCH,PVERT1G, & PVERT2G,PVERT3G,ZVERTG,NHITTOT1,CX,CY,CZ,IEVR,NEV, & XGEANT,YGEANT,CLSIZE1,CLSIZE2) @@ -439,12 +431,6 @@ call chfill(108,sngl(zvertg(i)),R1,R2) call chfill(109,sngl(ytrg(i)),R1,R2) call chfill(110,sngl(xtrg(i)),R1,R2) - dx=xgeant(i)-xtrg(i) - dy=ygeant(i)-ytrg(i) - call chfill(111,sngl(dy),R1,R2) - call chfill(112,sngl(dx),R1,R2) - call chfill(119+int(zch(i)),sngl(dy),R1,R2) - call chfill(129+int(zch(i)),sngl(dx),R1,R2) enddo do i=1,NHITTOT1 @@ -475,8 +461,8 @@ * * HITS GEANT initiaux par chambre COMMON/RHITG/ITYPG(MAXIDG),XTRG(MAXIDG),YTRG(MAXIDG), - & PTOTG(MAXIDG),IDG(MAXIDG),IZCH(MAXIDG), - & PVERT1G(MAXIDG),PVERT2G(MAXIDG),PVERT3G(MAXIDG), + & PTOTG(MAXIDG),IDG(MAXIDG),IZCH(MAXIDG), + & PVERT1G(MAXIDG),PVERT2G(MAXIDG),PVERT3G(MAXIDG), & ZVERTG(MAXIDG),NHITTOT1,CX(MAXIDG),CY(MAXIDG),CZ(MAXIDG), & XGEANT(MAXIDG),YGEANT(MAXIDG),CLSIZE1(MAXIDG),CLSIZE2(MAXIDG) @@ -494,6 +480,7 @@ & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) * COMMON/DEBEVT/IDEBUG + common/dstation/idstation * DIMENSION RMIN(NBCHAMBER),RMAX1(NBCHAMBER) DIMENSION XMA(NBCHAMBER,MAXHITCH),YMA(NBCHAMBER,MAXHITCH), @@ -509,16 +496,18 @@ * Chambre 10 deg. DATA RMAX1/91.5,91.5,122.5,122.5,158.3,158.3,260.,260.,260.,260./ * Zone de recherche entre deux plans d'une station -** DATA DXMAX/2.,1.5,2.5,3.,3./ - DATA DXMAX/1.5,1.5,3.,6.,6./ ! J psi 20cm -** DATA DXMAX/1.,1.,1.,1.,1./ ! Upsilon dz_ch = 8 cm -** DATA DYMAX/0.22,0.22,0.21,0.21,0.21/ ! CCC Upsilon dz_ch = 8cm -** DATA DXMAX/1.,1.,1.5,2.,2./ ! Upsilon dz_ch = 20 cm + +* if (idstation.eq.8) then +* DATA DXMAX/1.,1.,1.2,2.4,2.4/ ! dz_ch = 8 cm +* else if (idstation.eq.20) then + DATA DXMAX/1.5,1.5,3.,6.,6./ ! dz_ch = 20cm +* end if + DATA DYMAX/0.22,0.22,0.22,0.22,0.22/ ! CCC Upsilon dz_ch = 20 cm -** DATA DXMAX/5.,5.,5.,5.,5./ -** DATA DXMAX/10.,10.,10.,10.,10./ - DATA R1,R2/0.,1./ + DATA R1,R2/0.,1./ + + ICH = 0 DO IZ=1,5 ICH = ICH+1 @@ -529,14 +518,13 @@ IF (IZ.GT.2) RMIN(ICH) = 30. ENDDO -* Initialisations +* Initialisations DO ICH = 1,10 NHIT(ICH) = 0 ENDDO -* 1 ere boucle Lecture des hits initiaux +* 1 ere boucle de lecture des hits initiaux - print*,'TRACKF_STAT NHITTOT1=',NHITTOT1 IF (IREADGEANT.EQ.1) THEN DO I = 1,2 @@ -547,6 +535,12 @@ IMU = 0 DO I = 1,NHITTOT1 ICH = IZCH(I) + IZ = INT(FLOAT(ICH+1)/2.) + IMOD = MOD(ICH,2) + + IF (IMOD.NE.0.AND.IZ.LE.5) THEN + CALL CHFILL2(1000+IZ,SNGL(XGEANT(I)),SNGL(YGEANT(I)),R2) + ENDIF IF (ICH.EQ.9) THEN ISTAK = IDG(I) ISTAK = MOD(ISTAK,30000) @@ -569,6 +563,8 @@ ICH = IZCH(I) + IF (ICH.GT.10) GO TO 1 + IF (IREADGEANT.EQ.1) THEN ! GEANT hits IF (ICH.EQ.9.OR.ICH.EQ.10) THEN @@ -578,17 +574,40 @@ & (YGEANT(I)-VRES(2,IM))**2) IF (DNU.LT.DNUM) DNUM = DNU ENDDO - IF (DNUM.GT.20.) GO TO 1 + IF (DNUM.GT.50.) GO TO 1 ! discard hits far from MUONS ENDIF - CALL RANNOR(RN1,RN2) ! CCCC - X = XGEANT(I) + RN1 * XPREC - Y = YGEANT(I) + RN2 * YPREC + CALL RANNOR(RN1,RN2) ! CCC + X = XGEANT(I) + Y = YGEANT(I) +* X = XGEANT(I) + RN1 * XPREC +* Y = YGEANT(I) + RN2 * YPREC * efficacite des chambres IEFFI(I) = 1 RN = RNDM() IF (RN.GT.EFF) IEFFI(I) = 0 +** IF (ICH.EQ.9.OR.ICH.EQ.10) THEN +** PRINT *,' HIT GEANT',' ICH=',ICH,' I=',I,' X =',X,' Y=', +** & Y,' IDG=',IDG(I) +** ENDIF + + IF (ITYPG(I).EQ.5.OR.ITYPG(I).EQ.6) THEN + ISTAK = IDG(I) + ISTAK = MOD(ISTAK,30000) + ISTAK = MOD(ISTAK,10000) + IF (ISTAK.EQ.IDRES) then + dx=xgeant(i)-x + dy=ygeant(i)-y + IZ = INT(FLOAT(IZCH(i)+1)/2.) + ichx=110+IZ + ichy=120+IZ + call chfill(ichx,sngl(dy),R1,R2) + call chfill(ichy,sngl(dx),R1,R2) + if (iz.eq.1) call chfill(116,sngl(dy),R1,R2) + if (iz.eq.2) call chfill(117,sngl(dy),R1,R2) + end if + end if ELSE ! reconstructed hits @@ -597,18 +616,40 @@ X = XTRG(I) Y = YTRG(I) +* étude des hits geant avec un seul fichier +* CALL RANNOR(RN1,RN2) ! CCCC +* X = XGEANT(I) + RN1 * XPREC +* Y = YGEANT(I) + RN2 * YPREC + + IF (ITYPG(I).EQ.5.OR.ITYPG(I).EQ.6) THEN + ISTAK = IDG(I) + ISTAK = MOD(ISTAK,30000) + ISTAK = MOD(ISTAK,10000) + + IF (ISTAK.EQ.IDRES) then + dx=xgeant(i)-x + dy=ygeant(i)-y + IZ = INT(FLOAT(IZCH(i)+1)/2.) + ichx=110+IZ + ichy=120+IZ + call chfill(ichx,sngl(dy),R1,R2) + call chfill(ichy,sngl(dx),R1,R2) + if (iz.eq.1) call chfill(116,sngl(dy),R1,R2) + if (iz.eq.2) call chfill(117,sngl(dy),R1,R2) + end if + end if + ENDIF R = SQRT(X**2+Y**2) - IF (R.LT.RMIN(ICH).OR.R.GT.RMAX1(ICH)) then - if (ich.le.10.and.i.le.28) then - print*,'* chambre ',ich,' * hit ',i - print*,'ityp=',itypg(i) - print*,'x=',X,' y=',Y - print*,'R=',R,' RMIN=',RMIN(ICH),' RMAX1=',RMAX1(ICH) - endif - GO TO 1 - end if +** IF (R.LT.RMIN(ICH).OR.R.GT.RMAX1(ICH)) then +** if (ich.le.10) then +** print*,'* chambre ',ich,' * hit ',i +** print*,'ityp=',itypg(i),' x=',X,' y=',Y +** print*,'R=',R,' RMIN=',RMIN(ICH),' RMAX1=',RMAX1(ICH) +** endif +** GO TO 1 ! CCC +** end if NHIT(ICH) = NHIT(ICH)+1 IH(ICH,NHIT(ICH)) = I @@ -618,15 +659,15 @@ 1 CONTINUE ENDDO - + * Association des hits entre chambres d'une station II = 0 ! nombre de hits GEANT par station - DO ICH1 = 1,10,2 + DO ICH1 = 1,10,2 ! loop on chamber IZ = INT(FLOAT(ICH1+1)/2.) JHIT(IZ) = 0 ICH2 = ICH1+1 - DO I1 = 1,NHIT(ICH1) + DO I1 = 1,NHIT(ICH1) ! loop on hits in 1st chamber II = II+1 IFIND = 0 I = IH(ICH1,I1) @@ -649,7 +690,7 @@ XEXT1 = (ZPLANE(IZ)-DZ_PL(IZ))/ZPLANE(IZ)*X1 YEXT1 = (ZPLANE(IZ)-DZ_PL(IZ))/ZPLANE(IZ)*Y1 - DO I2 = 1,NHIT(ICH2) + DO I2 = 1,NHIT(ICH2) ! loop on hits in 2nd chamber J = IH(ICH2,I2) IF (IEFFI(J).EQ.1) THEN @@ -682,13 +723,14 @@ YMR(IZ,JHIT(IZ),1) = Y1 XMR(IZ,JHIT(IZ),2) = X2 YMR(IZ,JHIT(IZ),2) = Y2 + IP(IZ,JHIT(IZ)) = II ISTAK = ID2 ISTAK = MOD(ISTAK,30000) ISTAK = MOD(ISTAK,10000) IF ((ITYPG(J).EQ.5.OR.ITYPG(J).EQ.6).AND. - & ISTAK.EQ.IDRES) THEN ! upsilon + & ISTAK.EQ.IDRES) THEN ! upsilon or J/psi ITYP(II) = ITYPG(J) XTR(II) = XTRG(J) @@ -701,14 +743,12 @@ ZVERT(II) = ZVERTG(J) ENDIF - - IP(IZ,JHIT(IZ)) = II ENDIF ENDIF - ENDDO + ENDDO ! loop on hits in 2nd chamber - IF (IFIND.EQ.0) THEN + IF (IFIND.EQ.0) THEN ! No possible association JHIT(IZ) = JHIT(IZ)+1 XM(IZ,JHIT(IZ)) = X1 YM(IZ,JHIT(IZ)) = Y1 @@ -721,19 +761,19 @@ XMR(IZ,JHIT(IZ),2) = 0. YMR(IZ,JHIT(IZ),2) = 0. ENDIF - CALL CHFILL2(1000+IZ,SNGL(X1),SNGL(Y1),R2) ENDIF - ENDDO - ENDDO + ENDDO ! end loop on hits in 1st chamber + ENDDO ! end loop on chamber -* On conserve les HITS de la 2nde chambre des stations - DO ICH = 2,10,2 +* On conserve les HITS (x,y) de la 2nde chambre des stations + + DO ICH = 2,10,2 ! Loop on 2nd chambers IZ = INT(FLOAT(ICH+1)/2.) - DO I = 1,NHIT(ICH) + DO I = 1,NHIT(ICH) ! Loop on hits J = IH(ICH,I) - IF (IMARK(ICH,I).EQ.0) THEN + IF (IMARK(ICH,I).EQ.0) THEN ! hit not already associated II = II+1 @@ -762,23 +802,27 @@ YMR(IZ,JHIT(IZ),2) = YMA(ICH,I) ENDIF ENDIF - ENDDO - ENDDO + ENDDO ! End loop on hits + ENDDO ! End loop on 2nd chambers - NHITTOT = II + NHITTOT = II ! total number of hits in stations * IF (IDEBUG.GE.2) THEN PRINT *,'TRACKF_STAT nb hits:',NHITTOT ENDIF -** DO IZ = 1,NBSTATION +** DO IZ = 5,5 ** PRINT *,' IZ=',IZ,' JHIT(IZ)=',JHIT(IZ) ** DO J = 1,JHIT(IZ) ** II = IP(IZ,J) -** print*,'II=',II -** PRINT *,' ID(II)=',ID(II) +** PRINT *,' HIT ASS.',' IZ=',IZ,' II=',II,' X =', +** & XM(IZ,J),' Y=',YM(IZ,J),' ID=',ID(II) +** PRINT *,' HIT ASS.',' IZ=',IZ,' II=',II,' X1 =', +** & XMR(IZ,J,1),' Y1=',YMR(IZ,J,1),' ID=',ID(II) +** PRINT *,' HIT ASS.',' IZ=',IZ,' II=',II,' X2 =', +** & XMR(IZ,J,2),' Y2=',YMR(IZ,J,2),' ID=',ID(II) ** ENDDO ** ENDDO @@ -810,8 +854,8 @@ * * HITS GEANT initiaux par chambre COMMON/RHITG/ITYPG(MAXIDG),XTRG(MAXIDG),YTRG(MAXIDG), - & PTOTG(MAXIDG),IDG(MAXIDG),IZCH(MAXIDG), - & PVERT1G(MAXIDG),PVERT2G(MAXIDG),PVERT3G(MAXIDG), + & PTOTG(MAXIDG),IDG(MAXIDG),IZCH(MAXIDG), + & PVERT1G(MAXIDG),PVERT2G(MAXIDG),PVERT3G(MAXIDG), & ZVERTG(MAXIDG),NHITTOT1,CX(MAXIDG),CY(MAXIDG),CZ(MAXIDG), & XGEANT(MAXIDG),YGEANT(MAXIDG),CLSIZE1(MAXIDG),CLSIZE2(MAXIDG) @@ -841,7 +885,7 @@ DIMENSION DIST(2),NMUON(2),NHITMUON(2,5),NMUONGOOD(2) -* REAL*4 RNDM,RN,RN1,RN2,R1,R2 + REAL*4 RNDM,RN,RN1,RN2,R1,R2 * Chambre 10 deg. DATA RMAX1/91.5,91.5,122.5,122.5,158.3,158.3,260.,260.,260.,260./ @@ -1193,25 +1237,30 @@ & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP * COMMON/DEBEVT/IDEBUG + common/dstation/idstation - DIMENSION PEST(5),PSTEP(5),NERR(NBSTATION) + DIMENSION PEST(5),PSTEP(5),NERR(NBSTATION),IFIND2(10),NMU45(2) + DIMENSION NMU345(2),NMUONF(2) * REAL*4 R2 DATA R2/1./ ** GEANT informations DO I = 1,MAXTRK - IT_LIST(I)= 0 + IT_LIST(I)= 0 ! ID of the GEANT tracks ENDDO DO I = 1,MAXHITTOT - ITRACK(I) = 0 + ITRACK(I) = 0 ! Track number associated to hit number I ENDDO + NTRTOT = 0 * BOUCLE SUR LES HITS - DO IH = 1,NHITTOT DO IT = 1,NTRTOT - IF (ID(IH).EQ.IT_LIST(IT)) GOTO 4 + IF (ID(IH).EQ.IT_LIST(IT)) THEN + IT1 = IT + GOTO 4 + ENDIF ENDDO NTRTOT = NTRTOT +1 ! NB de trace GEANT IT_LIST(NTRTOT) = ID(IH) ! ID DE LA TRACE NTRTOT @@ -1219,27 +1268,23 @@ DO II=1,NBSTATION ITTROUGH(NTRTOT,II) = 0 ENDDO - IT = NTRTOT - 4 IT_NP(IT) = IT_NP(IT)+1 - ITTROUGH(IT,IZST(IH))=IH ! =IH si la trace IT touche le plan IZST - ITRACK(IH) = IT + IT1 = NTRTOT + 4 IT_NP(IT1) = IT_NP(IT1)+1 ! Number of crossed stations per track + ITTROUGH(IT1,IZST(IH))=IH ! =IH si la trace IT touche le plan IZST + ITRACK(IH) = IT1 ENDDO IF (IDEBUG.GE.2) THEN PRINT *,'RECO_TRACKF nb total de trace GEANT:',NTRTOT ENDIF + NTRPART=0 NTRMU = 0 DO IT = 1,NTRTOT -* print*,'(ITTROUGH(IT,1)=',ITTROUGH(IT,1) -* print*,'(ITTROUGH(IT,2)=',ITTROUGH(IT,2) -* print*,'(ITTROUGH(IT,3)=',ITTROUGH(IT,3) -* print*,'(ITTROUGH(IT,4)=',ITTROUGH(IT,4) -* print*,'(ITTROUGH(IT,5)=',ITTROUGH(IT,5) ITCHECK(IT) = 0 IF ((ITTROUGH(IT,1)*ITTROUGH(IT,2)*ITTROUGH(IT,3)* & ITTROUGH(IT,4)*ITTROUGH(IT,5)).NE.0) - & THEN + & THEN ! track crossing all stations NTRPART=NTRPART+1 IH = ITTROUGH(IT,NBSTATION) IF (ITYP(IH).EQ.5.OR.ITYP(IH).EQ.6) THEN @@ -1251,10 +1296,7 @@ thet=datan2(pt,pvert3(ih))*180/3.1416 pp=sqrt(pt**2+pvert3(ih)**2) -* print*,'istak=',istak - IF (ISTAK.EQ.IDRES) THEN ! psi or upsilon - print*,'resonance' NTRMU = NTRMU+1 NTRMUALL = NTRMUALL+1 ITCHECK(IT) = 1 @@ -1277,7 +1319,6 @@ NCAN = 0 * Recherche 5 -> 4 - CALL ORDONNE_HIT(5,HCUT) DO IH = 1,INDEXMAX @@ -1288,27 +1329,11 @@ X2 = XM(5,JJ)-(ZPLANE(5)-ZPLANE(4)+DZ_PL(4))*TAN(PHM(5,JJ)) Y2 = YM(5,JJ)+(ZPLANE(5)-ZPLANE(4)+DZ_PL(4))*TAN(ALM(5,JJ)) & /COS(PHM(5,JJ)) + * Domaine de recherche dans la st. 4 HCONST = 0.0136*SQRT(0.06)/HTOP ! -> X/X0=0.03 % / chamber EPH2 = 2.0*PHIPREC**2 + (HCONST*HHIT(JJ))**2 EAL2 = 2.0*ALAMPREC**2 + (HCONST*HHIT(JJ))**2 -** 29.07 - EXM2 = 2.0*(XPREC/SQRT(2.))**2 - & + (ZPLANE(5)-ZPLANE(4))**2/2.*EPH2 - EYM2 = 2.0*YPREC**2 + (ZPLANE(5)-ZPLANE(4))**2/2.*EAL2 - P1 = PTOT(IP(5,JJ)) - CALL CHFILL2(2500,SNGL(P1),SNGL(HHIT(JJ)),1.) - CALL CHFILL2(2501,SNGL(P1),SNGL(HHIT(JJ)**2),1.) - CALL CHFILL2(2502,SNGL(P1),SNGL(EPH2),1.) - CALL CHFILL2(2503,SNGL(P1),SNGL(EAL2),1.) - CALL CHFILL2(2504,SNGL(P1),SNGL(EXM2),1.) - CALL CHFILL2(2505,SNGL(P1),SNGL(EYM2),1.) - - CALL CHFILL2(2507,SNGL(P1),SNGL(SQRT(EPH2)),1.) - CALL CHFILL2(2508,SNGL(P1),SNGL(SQRT(EAL2)),1.) - CALL CHFILL2(2509,SNGL(P1),SNGL(SQRT(EXM2)),1.) - CALL CHFILL2(2510,SNGL(P1),SNGL(SQRT(EYM2)),1.) -** end 29.07 EXM12 = (PHIPREC**2+(HCONST*HHIT(JJ))**2)* & (ZPLANE(5)-ZPLANE(4))**2 + XPREC**2 EYM12 = (ALAMPREC**2+(HCONST*HHIT(JJ))**2)* @@ -1324,14 +1349,7 @@ EY1 = SIGCUT*SQRT(EYM12) EX2 = SIGCUT*SQRT(EXM22) EY2 = SIGCUT*SQRT(EYM22) -** 29.07 - EXM = SIGCUT*SQRT(EXM2) - EYM = SIGCUT*SQRT(EYM2) - CALL CHFILL2(2511,SNGL(P1),SNGL(EPH),1.) - CALL CHFILL2(2512,SNGL(P1),SNGL(EAL),1.) - CALL CHFILL2(2513,SNGL(P1),SNGL(EXM),1.) - CALL CHFILL2(2514,SNGL(P1),SNGL(EYM),1.) -** end 29.07 + ** P2 = (HTOP/HHIT(JJ))**2 ** EPH=SIGCUT*SQRT(9.14D-7+1.2D-3/P2) @@ -1344,18 +1362,20 @@ * renvoie le num de hit de 4 le plus pres dans le domaine de recherche CALL DISTMIN4(X1,Y1,PHM(5,JJ),ALM(5,JJ),4,EX1,EY1,EPH,EAL, - & IFIND) + & IFIND,IFIND2) P1 = PTOT(IP(5,JJ)) CALL CHECK_HISTO4(11,4,IFIND,5,JJ,X1,Y1,PHM(5,JJ),ALM(5,JJ),P1, & EX1,EY1,EPH,EAL) IF (IFIND.GT.0) THEN - CALL STOCK_CANDIDAT(5,JJ,4,IFIND,EX1,EY1,EPH,EAL,NCAN,1) + CALL STOCK_CANDIDAT(5,JJ,4,IFIND,IFIND2,EX1,EY1,EPH,EAL, + & NCAN,1) ELSE - CALL DISTMIN2(X1,Y1,X2,Y2,4,EX1,EY1,EX2,EY2,IFIND) + CALL DISTMIN2(X1,Y1,X2,Y2,4,EX1,EY1,EX2,EY2,IFIND,IFIND2) CALL CHECK_HISTO2(0,4,IFIND,5,JJ,X1,Y1,X2,Y2,P1,EX1,EY1, & EX2,EY2) IF (IFIND.GT.0) THEN - CALL STOCK_CANDIDAT(5,JJ,4,IFIND,EX1,EY1,EPH,EAL,NCAN,2) + CALL STOCK_CANDIDAT(5,JJ,4,IFIND,IFIND2,EX1,EY1,EPH,EAL, + & NCAN,2) ENDIF ENDIF ENDDO @@ -1385,24 +1405,6 @@ ** & *EAL2 EPH2 = 2.0*PHIPREC**2 + (HCONST*HHIT(JJ))**2 EAL2 = 2.0*ALAMPREC**2 + (HCONST*HHIT(JJ))**2 -** 29.07 - EXM2 = 2.0*(XPREC/SQRT(2.))**2 - & + (ZPLANE(5)-ZPLANE(4))**2/2.*EPH2 - EYM2 = 2.0*YPREC**2 + (ZPLANE(5)-ZPLANE(4))**2/2.*EAL2 - P1 = PTOT(IP(4,JJ)) - CALL CHFILL2(2400,SNGL(P1),SNGL(HHIT(JJ)),1.) - CALL CHFILL2(2401,SNGL(P1),SNGL(HHIT(JJ)**2),1.) - CALL CHFILL2(2402,SNGL(P1),SNGL(EPH2),1.) - CALL CHFILL2(2403,SNGL(P1),SNGL(EAL2),1.) - CALL CHFILL2(2404,SNGL(P1),SNGL(EXM2),1.) - CALL CHFILL2(2405,SNGL(P1),SNGL(EYM2),1.) - - CALL CHFILL2(2407,SNGL(P1),SNGL(SQRT(EPH2)),1.) - CALL CHFILL2(2408,SNGL(P1),SNGL(SQRT(EAL2)),1.) - CALL CHFILL2(2409,SNGL(P1),SNGL(SQRT(EXM2)),1.) - CALL CHFILL2(2410,SNGL(P1),SNGL(SQRT(EYM2)),1.) -** end 29.07 - EXM12 = (PHIPREC**2+(HCONST*HHIT(JJ))**2)* & (ZPLANE(5)-ZPLANE(4))**2 + XPREC**2 EYM12 = (ALAMPREC**2+(HCONST*HHIT(JJ))**2)* @@ -1418,14 +1420,7 @@ EY1 = SIGCUT*SQRT(EYM12) EX2 = SIGCUT*SQRT(EXM22) EY2 = SIGCUT*SQRT(EYM22) -** 29.07 - EXM = SIGCUT*SQRT(EXM2) - EYM = SIGCUT*SQRT(EYM2) - CALL CHFILL2(2411,SNGL(P1),SNGL(EPH),1.) - CALL CHFILL2(2412,SNGL(P1),SNGL(EAL),1.) - CALL CHFILL2(2413,SNGL(P1),SNGL(EXM),1.) - CALL CHFILL2(2414,SNGL(P1),SNGL(EYM),1.) -** end 29.07 + ** P2 = (HTOP/HHIT(JJ))**2 @@ -1436,23 +1431,38 @@ ** EX2=EX1 ** EY2=EY2 * Renvoie le num de hit de 5 le plus pres dans le domaine de recherche - CALL DISTMIN2(X1,Y1,X2,Y2,5,EX1,EY1,EX2,EY2,IFIND) + CALL DISTMIN2(X1,Y1,X2,Y2,5,EX1,EY1,EX2,EY2,IFIND,IFIND2) P1 = PTOT(IP(4,JJ)) CALL CHECK_HISTO2(0,5,IFIND,4,JJ,X1,Y1,X2,Y2,P1,EX1,EY1, & EX2,EY2) IF (IFIND.GT.0) THEN DO ICAN=1,NCAN IF (IFIND.EQ.JCAN(5,ICAN).AND.JJ.EQ.JCAN(4,ICAN)) GOTO 40 - IF (ABS(XM(5,JCAN(5,ICAN))-XM(5,IFIND)).LT.XPREC/10.) +** IF (JJ.EQ.JCAN(4,ICAN).AND. +** & ABS(XM(5,JCAN(5,ICAN))-XM(5,IFIND)).LT.XPREC/10.) +** & GO TO 40 ! elimine les doubles comptages de traces ccc +** IF (IFIND.EQ.JCAN(5,ICAN).AND. +** & ABS(XM(4,JCAN(4,ICAN))-XM(4,JJ)).LT.XPREC/10.) +** & GO TO 40 ! elimine les doubles comptages de traces ccc + + DIST1 = SQRT(((XM(5,JCAN(5,ICAN))-XM(5,IFIND)) + & /(0.1*XPREC))**2+((YM(5,JCAN(5,ICAN))-YM(5,IFIND)) + & /(0.1*YPREC))**2) + DIST2 = SQRT(((XM(4,JCAN(4,ICAN))-XM(4,JJ)) + & /(0.1*XPREC))**2+((YM(4,JCAN(4,ICAN))-YM(4,JJ)) + & /(0.1*YPREC))**2) + IF (DIST1.LT.2..AND.DIST2.LT.2.) & GO TO 40 ! elimine les doubles comptages de traces ccc ENDDO - CALL STOCK_CANDIDAT(4,JJ,5,IFIND,EX1,EY1,EPH,EAL,NCAN,3) + CALL STOCK_CANDIDAT(4,JJ,5,IFIND,IFIND2,EX1,EY1,EPH,EAL,NCAN + & ,3) ENDIF 40 CONTINUE ENDDO - NMU45 = 0 + NMU45(1) = 0 + NMU45(2) = 0 DO ICAN = 1,NCAN JJ4 = JCAN(4,ICAN) JJ5 = JCAN(5,ICAN) @@ -1462,32 +1472,38 @@ IT = ITRACK(IP(5,JJ5)) IF (ITCHECK(IT).EQ.1) THEN IF (ID4.EQ.ID5) THEN - NMU45 = NMU45 + 1 + IF (ITYP(IP(5,JJ5)).EQ.5) NMU45(1) = 1 + IF (ITYP(IP(5,JJ5)).EQ.6) NMU45(2) = 1 ENDIF ENDIF ENDIF ENDDO - IF (NMU45.GE.2) NRES(1) = NRES(1)+1 + IF (NMU45(1).GE.1.AND.NMU45(2).EQ.1) NRES(1) = NRES(1)+1 IF (IDEBUG.GE.2) THEN PRINT *,'RECO_TRACKF nb candidat recherche 4->5 et 5->4 :' & ,NCAN PRINT *,'RECO_TRACKF nb of good muons 4->5 et 5->4 :' - & ,NMU45 + & ,(NMU45(1)+NMU45(2)) ENDIF - NMU345 = 0 + + NMU345(1) = 0 + NMU345(2) = 0 * * -- Boucle sur les candidats (4,5) NCAN * DO I = 1,NBSTATION NERR(I) = 0 ENDDO - NMUONF = 0 + NMUONF(1) = 0 + NMUONF(2) = 0 NGHOST = 0 NTRACKF = 0 +** GO TO 125 ! CCC + DO ICAN = 1,NCAN JJ1 = 0 JJ2 = 0 @@ -1559,42 +1575,23 @@ * -- Recherche dans la station 3 P2 = (1.0D0 + TALAM45**2)/(PXZINV45**2) ! P**2 -** EPH=SIGCUT*SQRT(3.6D-6+0.011/P2) -** EAL=SIGCUT*SQRT(6.85D-4) -** EXM=SIGCUT*SQRT(0.034+446./P2) -** EYM=SIGCUT*SQRT(0.049+354./P2) - EPH=SIGCUT*SQRT(4.1D-7+0.015/P2) - EAL=SIGCUT*SQRT(1.04D-4) - EXM=SIGCUT*SQRT(0.0+459./P2) - EYM=SIGCUT*SQRT(0.042+345./P2) + + if (idstation.eq.8) then ! DZ_CH = 8 CM + EPH=SIGCUT*SQRT(3.6D-6+0.011/P2) + EAL=SIGCUT*SQRT(6.85D-4) + EXM=SIGCUT*SQRT(0.034+446./P2) + EYM=SIGCUT*SQRT(0.049+354./P2) + else if (idstation.eq.20) then ! DZ_CH = 20 CM + EPH=SIGCUT*SQRT(4.1D-7+0.015/P2) + EAL=SIGCUT*SQRT(1.04D-4) + EXM=SIGCUT*SQRT(0.0+459./P2) + EYM=SIGCUT*SQRT(0.042+345./P2) + end if + EEXM(3) = EXM/SIGCUT EEYM(3) = EYM/SIGCUT EEPH(3) = EPH/SIGCUT EEAL(3) = EAL/SIGCUT -** 29.07 - CALL CHF1(2301,SNGL(SQRT(P2)),1.) - P1 = PTOT(IP(5,JJ5)) - CALL CHFILL2(2311,SNGL(P1),SNGL(EPH),1.) - CALL CHFILL2(2312,SNGL(P1),SNGL(EAL),1.) - CALL CHFILL2(2313,SNGL(P1),SNGL(EXM),1.) - CALL CHFILL2(2314,SNGL(P1),SNGL(EYM),1.) - - CALL CHFILL2(2315,SNGL(SQRT(P2)),SNGL(EPH),1.) - CALL CHFILL2(2316,SNGL(SQRT(P2)),SNGL(EAL),1.) - CALL CHFILL2(2317,SNGL(SQRT(P2)),SNGL(EXM),1.) - CALL CHFILL2(2318,SNGL(SQRT(P2)),SNGL(EYM),1.) - - CALL CHFILL2(2302,SNGL(SQRT(P2)),SNGL((EPH/SIGCUT)**2),1.) - CALL CHFILL2(2303,SNGL(SQRT(P2)),SNGL((EAL/SIGCUT)**2),1.) - CALL CHFILL2(2304,SNGL(SQRT(P2)),SNGL((EXM/SIGCUT)**2),1.) - CALL CHFILL2(2305,SNGL(SQRT(P2)),SNGL((EYM/SIGCUT)**2),1.) - - CALL CHFILL2(2307,SNGL(P1),SNGL((EPH/SIGCUT)**2),1.) - CALL CHFILL2(2308,SNGL(P1),SNGL((EAL/SIGCUT)**2),1.) - CALL CHFILL2(2309,SNGL(P1),SNGL((EXM/SIGCUT)**2),1.) - CALL CHFILL2(2310,SNGL(P1),SNGL((EYM/SIGCUT)**2),1.) -** end 29.07 - ** DO IEX = 4,5 ** EEXM(IEX) = EEXM(3) ** EEYM(IEX) = EEYM(3) @@ -1607,11 +1604,11 @@ Y2 = YPL(3,2) PHI1 = PHPL(3) ALAM1 = ALPL(3) - - CALL DISTMIN4(X1,Y1,PHI1,ALAM1,3,EXM,EYM,EPH,EAL,IPA3) + + CALL DISTMIN4(X1,Y1,PHI1,ALAM1,3,EXM,EYM,EPH,EAL,IPA3,IFIND2) P1 = PTOT(IP(5,JJ5)) - + CALL CHECK_HISTO4(61,3,IPA3,5,JJ5,X1,Y1,PHI1,ALAM1,P1, & EXM,EYM,EPH,EAL) @@ -1626,7 +1623,7 @@ MANG(3) = 1 GO TO 124 ELSE - CALL DISTMIN2(X1,Y1,X2,Y2,3,EXM,EYM,0.D0,0.D0,IP3) + CALL DISTMIN2(X1,Y1,X2,Y2,3,EXM,EYM,0.D0,0.D0,IP3,IFIND2) CALL CHECK_HISTO2(0,3,IP3,5,JJ5,X1,Y1,X2,Y2,P1,EXM,EYM, & 0.D0,0.D0) ENDIF @@ -1653,12 +1650,13 @@ IT = ITRACK(IP(5,JJ5)) IF (ITCHECK(IT).EQ.1) THEN IF ((ID5.EQ.ID3).AND.(ID5.EQ.ID4)) THEN - NMU345 = NMU345 + 1 + IF (ITYP(IP(5,JJ5)).EQ.5) NMU345(1) = 1 + IF (ITYP(IP(5,JJ5)).EQ.6) NMU345(2) = 1 ENDIF ENDIF ENDIF - IVERTEX = 0 + IVERTEX = 1 ! CCC PEST(1) = PXZINV45 PEST(2) = TPHI45 @@ -1670,49 +1668,30 @@ PSTEP(3) = 0.001 PSTEP(4) = 1. PSTEP(5) = 1. - + CALL TRACKF_FIT(IVERTEX,PEST,PSTEP,PXZINV345,TPHI345, & TALAM345,XVERT,YVERT) * -- Recherche dans la st. 2 P2 = (1.0D0 + TALAM345**2)/(PXZINV345**2) ! P**2 -** EPH=SIGCUT*SQRT(3.63D-6+4.8D-3/P2) -** EAL=SIGCUT*SQRT(6.49D-4) -** EXM=SIGCUT*SQRT(1.64D-2+821./P2) -** EYM=SIGCUT*SQRT(4.83D-2+866./P2) - EPH=SIGCUT*SQRT(5.78D-7+5.97D-3/P2) - EAL=SIGCUT*SQRT(1.D-4) - EXM=SIGCUT*SQRT(0.+1453./P2) - EYM=SIGCUT*SQRT(2.78D-2+504./P2) + + if (idstation.eq.8) then ! DZ_CH = 8 CM + EPH=SIGCUT*SQRT(3.63D-6+4.8D-3/P2) + EAL=SIGCUT*SQRT(6.49D-4) + EXM=SIGCUT*SQRT(1.64D-2+821./P2) + EYM=SIGCUT*SQRT(4.83D-2+866./P2) + else if (idstation.eq.20) then ! DZ_CH = 20 CM + EPH=SIGCUT*SQRT(5.78D-7+5.97D-3/P2) + EAL=SIGCUT*SQRT(1.D-4) + EXM=SIGCUT*SQRT(0.+1453./P2) + EYM=SIGCUT*SQRT(2.78D-2+504./P2) + end if + EEXM(2) = EXM/SIGCUT EEYM(2) = EYM/SIGCUT EEPH(2) = EPH/SIGCUT EEAL(2) = EAL/SIGCUT -** 29.07 - CALL CHF1(2201,SNGL(SQRT(P2)),1.) - P1 = PTOT(IP(5,JJ5)) - CALL CHFILL2(2211,SNGL(P1),SNGL(EPH),1.) - CALL CHFILL2(2212,SNGL(P1),SNGL(EAL),1.) - CALL CHFILL2(2213,SNGL(P1),SNGL(EXM),1.) - CALL CHFILL2(2214,SNGL(P1),SNGL(EYM),1.) - - CALL CHFILL2(2215,SNGL(SQRT(P2)),SNGL(EPH),1.) - CALL CHFILL2(2216,SNGL(SQRT(P2)),SNGL(EAL),1.) - CALL CHFILL2(2217,SNGL(SQRT(P2)),SNGL(EXM),1.) - CALL CHFILL2(2218,SNGL(SQRT(P2)),SNGL(EYM),1.) - - CALL CHFILL2(2202,SNGL(SQRT(P2)),SNGL((EPH/SIGCUT)**2),1.) - CALL CHFILL2(2203,SNGL(SQRT(P2)),SNGL((EAL/SIGCUT)**2),1.) - CALL CHFILL2(2204,SNGL(SQRT(P2)),SNGL((EXM/SIGCUT)**2),1.) - CALL CHFILL2(2205,SNGL(SQRT(P2)),SNGL((EYM/SIGCUT)**2),1.) - - CALL CHFILL2(2207,SNGL(P1),SNGL((EPH/SIGCUT)**2),1.) - CALL CHFILL2(2208,SNGL(P1),SNGL((EAL/SIGCUT)**2),1.) - CALL CHFILL2(2209,SNGL(P1),SNGL((EXM/SIGCUT)**2),1.) - CALL CHFILL2(2210,SNGL(P1),SNGL((EYM/SIGCUT)**2),1.) -** end 29.07 - ** DO IEX = 3,5 ** EEXM(IEX) = EEXM(2) ** EEYM(IEX) = EEYM(2) @@ -1724,46 +1703,28 @@ Y1 = YPL(2,1) PHI1 = PHPL(2) ALAM1 = ALPL(2) - CALL DISTMIN4(X1,Y1,PHI1,ALAM1,2,EXM,EYM,EPH,EAL,IPA2) + CALL DISTMIN4(X1,Y1,PHI1,ALAM1,2,EXM,EYM,EPH,EAL,IPA2,IFIND2) P1 = PTOT(IP(5,JJ5)) CALL CHECK_HISTO4(21,2,IPA2,5,JJ5,X1,Y1,PHI1,ALAM1,P1, & EXM,EYM,EPH,EAL) * -- Recherche dans la st. 1 -** EPH=SIGCUT*SQRT(3.54D-6+4.49D-3/P2) -** EAL=SIGCUT*SQRT(6.14D-4) -** EXM=SIGCUT*SQRT(6.43D-2+986./P2) -** EYM=SIGCUT*SQRT(4.66D-2+1444./P2) - EPH=SIGCUT*SQRT(4.96D-7+5.87D-3/P2) - EAL=SIGCUT*SQRT(1.D-4) - EXM=SIGCUT*SQRT(6.98D-4+1467./P2) - EYM=SIGCUT*SQRT(5.22D-2+1013./P2) + + if (idstation.eq.8) then ! DZ_CH = 8 CM + EPH=SIGCUT*SQRT(3.54D-6+4.49D-3/P2) + EAL=SIGCUT*SQRT(6.14D-4) + EXM=SIGCUT*SQRT(6.43D-2+986./P2) + EYM=SIGCUT*SQRT(4.66D-2+1444./P2) + else if (idstation.eq.20) then ! DZ_CH = 20 CM + EPH=SIGCUT*SQRT(4.96D-7+5.87D-3/P2) + EAL=SIGCUT*SQRT(1.D-4) + EXM=SIGCUT*SQRT(6.98D-4+1467./P2) + EYM=SIGCUT*SQRT(5.22D-2+1013./P2) + end if + EEXM(1) = EXM/SIGCUT EEYM(1) = EYM/SIGCUT EEPH(1) = EPH/SIGCUT EEAL(1) = EAL/SIGCUT -** 29.07 - CALL CHFILL2(2111,SNGL(P1),SNGL(EPH),1.) - CALL CHFILL2(2112,SNGL(P1),SNGL(EAL),1.) - CALL CHFILL2(2113,SNGL(P1),SNGL(EXM),1.) - CALL CHFILL2(2114,SNGL(P1),SNGL(EYM),1.) - - CALL CHFILL2(2115,SNGL(SQRT(P2)),SNGL(EPH),1.) - CALL CHFILL2(2116,SNGL(SQRT(P2)),SNGL(EAL),1.) - CALL CHFILL2(2117,SNGL(SQRT(P2)),SNGL(EXM),1.) - CALL CHFILL2(2118,SNGL(SQRT(P2)),SNGL(EYM),1.) - - CALL CHFILL2(2102,SNGL(SQRT(P2)),SNGL((EPH/SIGCUT)**2),1.) - CALL CHFILL2(2103,SNGL(SQRT(P2)),SNGL((EAL/SIGCUT)**2),1.) - CALL CHFILL2(2104,SNGL(SQRT(P2)),SNGL((EXM/SIGCUT)**2),1.) - CALL CHFILL2(2105,SNGL(SQRT(P2)),SNGL((EYM/SIGCUT)**2),1.) - - CALL CHFILL2(2107,SNGL(P1),SNGL((EPH/SIGCUT)**2),1.) - CALL CHFILL2(2108,SNGL(P1),SNGL((EAL/SIGCUT)**2),1.) - CALL CHFILL2(2109,SNGL(P1),SNGL((EXM/SIGCUT)**2),1.) - CALL CHFILL2(2110,SNGL(P1),SNGL((EYM/SIGCUT)**2),1.) -** end 29.07 - - ** DO IEX = 2,5 ** EEXM(IEX) = EEXM(1) ** EEYM(IEX) = EEYM(1) @@ -1775,7 +1736,7 @@ Y1 = YPL(1,1) PHI1 = PHPL(1) ALAM1 = ALPL(1) - CALL DISTMIN4(X1,Y1,PHI1,ALAM1,1,EXM,EYM,EPH,EAL,IPA1) + CALL DISTMIN4(X1,Y1,PHI1,ALAM1,1,EXM,EYM,EPH,EAL,IPA1,IFIND2) CALL CHECK_HISTO4(31,1,IPA1,5,JJ5,X1,Y1,PHI1,ALAM1,P1, & EXM,EYM,EPH,EAL) * -- A partir de P+A dans la st. 2 @@ -1807,43 +1768,23 @@ * !!! ATTENTION aux erreurs P2 = (1.0D0 + TALAM**2)/(PXZINV**2) -** EPH=SIGCUT*SQRT(3.15D-6+9.21D-3/P2) -** EAL=SIGCUT*SQRT(5.94D-4) -** EXM=SIGCUT*SQRT(4.16D-2+182./P2) -** EYM=SIGCUT*SQRT(2.13) - EPH=SIGCUT*SQRT(9.58D-7+8.93D-3/P2) - EAL=SIGCUT*SQRT(1.D-4) - EXM=SIGCUT*SQRT(1.92D-2+103.3/P2) - EYM=SIGCUT*SQRT(6.3D-2+81.1/P2) + + if (idstation.eq.8) then ! DZ_CH = 8 CM + EPH=SIGCUT*SQRT(3.15D-6+9.21D-3/P2) + EAL=SIGCUT*SQRT(5.94D-4) + EXM=SIGCUT*SQRT(4.16D-2+182./P2) + EYM=SIGCUT*SQRT(2.13) + else if (idstation.eq.20) then ! DZ_CH = 20 CM + EPH=SIGCUT*SQRT(9.58D-7+8.93D-3/P2) + EAL=SIGCUT*SQRT(1.D-4) + EXM=SIGCUT*SQRT(1.92D-2+103.3/P2) + EYM=SIGCUT*SQRT(6.3D-2+81.1/P2) + end if + EEXM(1) = EXM/SIGCUT EEYM(1) = EYM/SIGCUT EEPH(1) = EPH/SIGCUT EEAL(1) = EAL/SIGCUT -** 29.07 - CALL CHF1(2701,SNGL(SQRT(P2)),1.) - CALL CHFILL2(2711,SNGL(P1),SNGL(EPH),1.) - CALL CHFILL2(2712,SNGL(P1),SNGL(EAL),1.) - CALL CHFILL2(2713,SNGL(P1),SNGL(EXM),1.) - CALL CHFILL2(2714,SNGL(P1),SNGL(EYM),1.) - - CALL CHFILL2(2715,SNGL(SQRT(P2)),SNGL(EPH),1.) - CALL CHFILL2(2716,SNGL(SQRT(P2)),SNGL(EAL),1.) - CALL CHFILL2(2717,SNGL(SQRT(P2)),SNGL(EXM),1.) - CALL CHFILL2(2718,SNGL(SQRT(P2)),SNGL(EYM),1.) - - CALL CHFILL2(2702,SNGL(SQRT(P2)),SNGL((EPH/SIGCUT)**2),1.) - CALL CHFILL2(2703,SNGL(SQRT(P2)),SNGL((EAL/SIGCUT)**2),1.) - CALL CHFILL2(2704,SNGL(SQRT(P2)),SNGL((EXM/SIGCUT)**2),1.) - CALL CHFILL2(2705,SNGL(SQRT(P2)),SNGL((EYM/SIGCUT)**2),1.) - - - CALL CHFILL2(2707,SNGL(P1),SNGL((EPH/SIGCUT)**2),1.) - CALL CHFILL2(2708,SNGL(P1),SNGL((EAL/SIGCUT)**2),1.) - CALL CHFILL2(2709,SNGL(P1),SNGL((EXM/SIGCUT)**2),1.) - CALL CHFILL2(2710,SNGL(P1),SNGL((EYM/SIGCUT)**2),1.) -** end 29.07 - - ** DO IEX = 2,5 ** EEXM(IEX) = EEXM(1) ** EEYM(IEX) = EEYM(1) @@ -1858,12 +1799,14 @@ PHI1 = PHPL(1) ALAM1 = ALPL(1) CALL DISTMIN4(X1,Y1,PHI1,ALAM1,1,EXM,EYM,EPH,EAL, - & IPA2PA1) + & IPA2PA1,IFIND2) CALL CHECK_HISTO4(41,1,IPA2PA1,5,JJ5,X1,Y1,PHI1,ALAM1, & P1,EXM,EYM,EPH,EAL) IF (IPA2PA1.GT.0) THEN JJ2 = IPA2 JJ1 = IPA2PA1 + + XMES(1) = XM(1,JJ1) YMES(1) = YM(1,JJ1) IZMES(1) = IZM(1,JJ1) @@ -1873,7 +1816,8 @@ MANG(1) = 1 GOTO 123 ELSE - CALL DISTMIN2(X1,Y1,X2,Y2,1,EXM,EYM,0.D0,0.D0,IPA2P1) + CALL DISTMIN2(X1,Y1,X2,Y2,1,EXM,EYM,0.D0,0.D0,IPA2P1, + & IFIND2) CALL CHECK_HISTO2(0,1,IPA2P1,5,JJ5,X1,Y1,X2,Y2,P1, & EXM,EYM,0.D0,0.D0) ENDIF @@ -1909,47 +1853,23 @@ * !!! ATTENTION aux erreurs P2 = (1.0D0 + TALAM**2)/(PXZINV**2) -** EPH=SIGCUT*SQRT(3.15D-6+9.21D-3/P2) -** EAL=SIGCUT*SQRT(5.94D-4) -** EXM=SIGCUT*SQRT(4.16D-2+182./P2) -** EYM=SIGCUT*SQRT(2.13) - EPH=SIGCUT*SQRT(9.58D-7+8.93D-3/P2) - EAL=SIGCUT*SQRT(1.D-4) - EXM=SIGCUT*SQRT(4.0D-2+11.4/P2) - EYM=SIGCUT*SQRT(5.5D-2+44.35/P2) - + + if (idstation.eq.8) then ! DZ_CH = 8 CM + EPH=SIGCUT*SQRT(3.15D-6+9.21D-3/P2) + EAL=SIGCUT*SQRT(5.94D-4) + EXM=SIGCUT*SQRT(4.16D-2+182./P2) + EYM=SIGCUT*SQRT(2.13) + else if (idstation.eq.20) then ! DZ_CH = 20 CM + EPH=SIGCUT*SQRT(9.58D-7+8.93D-3/P2) + EAL=SIGCUT*SQRT(1.D-4) + EXM=SIGCUT*SQRT(4.0D-2+11.4/P2) + EYM=SIGCUT*SQRT(5.5D-2+44.35/P2) + end if + EEXM(2) = EXM/SIGCUT EEYM(2) = EYM/SIGCUT EEPH(2) = EPH/SIGCUT EEAL(2) = EAL/SIGCUT -** 29.07 - CALL CHF1(2801,SNGL(SQRT(P2)),1.) - CALL CHFILL2(2811,SNGL(P1),SNGL(EPH),1.) - CALL CHFILL2(2812,SNGL(P1),SNGL(EAL),1.) - CALL CHFILL2(2813,SNGL(P1),SNGL(EXM),1.) - CALL CHFILL2(2814,SNGL(P1),SNGL(EYM),1.) - - CALL CHFILL2(2815,SNGL(SQRT(P2)),SNGL(EPH),1.) - CALL CHFILL2(2816,SNGL(SQRT(P2)),SNGL(EAL),1.) - CALL CHFILL2(2817,SNGL(SQRT(P2)),SNGL(EXM),1.) - CALL CHFILL2(2818,SNGL(SQRT(P2)),SNGL(EYM),1.) - - CALL CHFILL2(2802,SNGL(SQRT(P2)),SNGL((EPH/SIGCUT)**2),1.) - CALL CHFILL2(2803,SNGL(SQRT(P2)),SNGL((EAL/SIGCUT)**2),1.) - CALL CHFILL2(2804,SNGL(SQRT(P2)),SNGL((EXM/SIGCUT)**2),1.) - CALL CHFILL2(2805,SNGL(SQRT(P2)),SNGL((EYM/SIGCUT)**2),1.) - - - CALL CHFILL2(2807,SNGL(P1),SNGL((EPH/SIGCUT)**2),1.) - CALL CHFILL2(2808,SNGL(P1),SNGL((EAL/SIGCUT)**2),1.) - CALL CHFILL2(2809,SNGL(P1),SNGL((EXM/SIGCUT)**2),1.) - CALL CHFILL2(2810,SNGL(P1),SNGL((EYM/SIGCUT)**2),1.) - -** end 29.07 - - - - ** DO IEX = 1,5 ** EEXM(IEX) = EEXM(2) ** EEYM(IEX) = EEYM(2) @@ -1965,7 +1885,7 @@ ALAM1 = ALPL(2) CALL DISTMIN4(X1,Y1,PHI1,ALAM1,2,EXM,EYM,EPH,EAL, - & IPA1PA2) + & IPA1PA2,IFIND2) CALL CHECK_HISTO4(51,2,IPA1PA2,5,JJ5,X1,Y1,PHI1,ALAM1, & P1,EXM,EYM,EPH,EAL) @@ -1981,7 +1901,8 @@ MANG(2) = 1 GOTO 123 ELSE - CALL DISTMIN2(X1,Y1,X2,Y2,2,EXM,EYM,0.D0,0.D0,IPA1P2) + CALL DISTMIN2(X1,Y1,X2,Y2,2,EXM,EYM,0.D0,0.D0,IPA1P2, + & IFIND2) CALL CHECK_HISTO2(0,2,IPA1P2,5,JJ5,X1,Y1,X2,Y2,P1, & EXM,EYM,0.D0,0.D0) ENDIF @@ -2014,14 +1935,14 @@ 123 CONTINUE *** NTRACKFOLD = NTRACKF - NMUONFOLD = NMUONF + NMUONFOLD = NMUONF(1)+NMUONF(2) NGHOSTOLD = NGHOST CALL CHECK_MUON(JJ1,JJ2,JJ3,JJ4,JJ5,NTRACKF,NMUONF, & NGHOST,NERR,PXZINV,TPHI,TALAM,XVERT,YVERT) IF (NTRACKF.GT.NTRACKFOLD) THEN ISTAT(NTRACKF) = 0 - IF (NMUONF.GT.NMUONFOLD) ISTAT(NTRACKF) = 1 ! Good muon + IF ((NMUONF(1)+NMUONF(2)).GT.NMUONFOLD) ISTAT(NTRACKF) = 1 ! Good muon IF (NGHOST.GT.NGHOSTOLD) ISTAT(NTRACKF) = 2 ! ghost track PXZOUT(NTRACKF) = 1./PXZINV TPHIOUT(NTRACKF) = TPHI @@ -2036,25 +1957,25 @@ *** ENDDO ! end loop on candidats NCAN - IF (NMU345.GE.2) NRES(2) = NRES(2) + 1 + 125 IF (NMU345(1).EQ.1.AND.NMU345(2).EQ.1) NRES(2) = NRES(2) + 1 IF (IDEBUG.GE.2) THEN PRINT *,'RECO_TRACKF nb of good muons 3 4 5 :' - & ,NMU345 + & ,(NMU345(1)+NMU345(2)) ENDIF IF (IDEBUG.GE.2) THEN - PRINT *,'RECO_TRACKF nb of track /evt :',NTRACKF - PRINT *,'RECO_TRACKF nb of good muon /evt :',NMUONF - PRINT *,'RECO_TRACKF nb of ghost /evt :',NGHOST + PRINT *,'RECO_TRACKF nb of track/evt :',NTRACKF + PRINT *,'RECO_TRACKF nb of good muon/evt :',NMUONF(1)+NMUONF(2) + PRINT *,'RECO_TRACKF nb of ghost/evt :',NGHOST DO I = 1,4 PRINT *,'RECO_TRACKF nb of error in st',I,'/evt:',NERR(I) ENDDO ENDIF IF (NTRMU.GE.2) NRES(5) = NRES(5)+1 - IF (NMUONF.GE.2) NRESF = NRESF+1 - NMUONALL = NMUONALL+NMUONF + IF ((NMUONF(1)+NMUONF(2)).EQ.2) NRESF = NRESF+1 + NMUONALL = NMUONALL+NMUONF(1)+NMUONF(2) NGHOSTALL = NGHOSTALL+NGHOST NTRACKFALL = NTRACKFALL+NTRACKF DO I = 1,4 @@ -2152,7 +2073,7 @@ REAL*4 R1,R2 DATA R1,R2/0.,1./ - DIMENSION NERR(NBSTATION),JJK(NBSTATION) + DIMENSION NERR(NBSTATION),JJK(NBSTATION),NMUONF(2) * print*,' *** appel de la subroutine check_muon ***' @@ -2200,8 +2121,9 @@ & ID(IP(2,JJ2)).EQ.IDFIND .AND. & ID(IP(3,JJ3)).EQ.IDFIND .AND. & ID(IP(4,JJ4)).EQ.IDFIND) THEN - - NMUONF = NMUONF+1 ! Bon muon + + IF (ITYP(IP(5,JJ5)).EQ.5) NMUONF(1) = 1 ! Bon muon + IF (ITYP(IP(5,JJ5)).EQ.6) NMUONF(2) = 1 ! Bon muon PT = SQRT(PVERT1(IP(5,JJ5))**2+PVERT2(IP(5,JJ5))**2) PZ = PVERT3(IP(5,JJ5)) @@ -2229,8 +2151,12 @@ IF (ITCHECK(ITRACK(IP(5,JJ5))).EQ.1) THEN IF (JJ3.EQ.0) NERR(3) = NERR(3)+1 IF (JJ3.NE.0) THEN + IF (JJ1.EQ.0) NERR(1) = NERR(1)+1 IF (JJ2.EQ.0) NERR(2) = NERR(2)+1 + IF (JJ1.EQ.0) print*,'hit not found stations 1', NERR(1) + IF (JJ2.EQ.0) print*,'hit not found stations 2', NERR(2) + ENDIF PT = SQRT(PVERT1(IP(5,JJ5))**2+PVERT2(IP(5,JJ5))**2) PZ = PVERT3(IP(5,JJ5)) @@ -2290,37 +2216,49 @@ & CHI2R(NTRMAX),PXV(NTRMAX),PYV(NTRMAX),PZV(NTRMAX) * COMMON/DEBEVT/IDEBUG +* + DIMENSION ISEL(NTRMAX) + * + CALL RECO_SELECT(ISEL) +* NMUF = 0 NGHF = 0 + DO ITR = 1,NTREVT - NTRACKFALL1 = NTRACKFALL1 + 1 - IF (ISTAT(ITR).EQ.1) THEN - NMUF = NMUF + 1 - NMUONALL1 = NMUONALL1 + 1 - ELSEIF (ISTAT(ITR).EQ.2) THEN - NGHF = NGHF + 1 - NGHOSTALL1 = NGHOSTALL1 + 1 - ENDIF + IF (ISEL(ITR).EQ.1) THEN + NTRACKFALL1 = NTRACKFALL1 + 1 + IF (ISTAT(ITR).EQ.1) THEN + NMUF = NMUF + 1 + NMUONALL1 = NMUONALL1 + 1 + ELSEIF (ISTAT(ITR).EQ.2) THEN + NGHF = NGHF + 1 + NGHOSTALL1 = NGHOSTALL1 + 1 + ENDIF + ENDIF ENDDO - IF (NMUF.EQ.2) NRESF1 = NRESF1 + 1 + + IF (NMUF.GE.2) NRESF1 = NRESF1 + 1 * - NTRACKR = NTREVT + NTRACKR = 0 DO ITR = 1,NTREVT - ISTATR(ITR) = ISTAT(ITR) - ISIGNR(ITR) = 1 - IF (PXZOUT(ITR).LT.0.) ISIGNR(ITR) = -1 - PXZ = ABS(PXZOUT(ITR)) - PHI = ATAN(TPHIOUT(ITR)) - ALAM = ATAN(TALAMOUT(ITR)) - PYR(ITR) = PXZ*SIN(PHI) - PXR(ITR) = PXZ*TAN(ALAM) - PZR(ITR) = PXZ*COS(PHI) - ZVR(ITR) = 0. - CHI2R(ITR) = CHI2OUT(ITR) - PXV(ITR) = PXVOUT(ITR) - PYV(ITR) = PYVOUT(ITR) - PZV(ITR) = PZVOUT(ITR) + IF (ISEL(ITR).EQ.1) THEN + NTRACKR = NTRACKR + 1 + ISTATR(NTRACKR) = ISTAT(ITR) + ISIGNR(NTRACKR) = 1 + IF (PXZOUT(ITR).LT.0.) ISIGNR(NTRACKR) = -1 + PXZ = ABS(PXZOUT(ITR)) + PHI = ATAN(TPHIOUT(ITR)) + ALAM = ATAN(TALAMOUT(ITR)) + PYR(NTRACKR) = PXZ*SIN(PHI) + PXR(NTRACKR) = PXZ*TAN(ALAM) + PZR(NTRACKR) = PXZ*COS(PHI) + ZVR(NTRACKR) = 0. + CHI2R(NTRACKR) = CHI2OUT(ITR) + PXV(NTRACKR) = PXVOUT(ITR) + PYV(NTRACKR) = PYVOUT(ITR) + PZV(NTRACKR) = PZVOUT(ITR) + ENDIF ENDDO CALL CHFNT(IEVR,NTRACKR,ISTATR,ISIGNR, @@ -2328,14 +2266,13 @@ IF (IDEBUG.GE.2) THEN PRINT *,'RECO_SUM evt number :',IEVOUT - PRINT *,'RECO_SUM nb of track /evt :',NTREVT + PRINT *,'RECO_SUM nb of track /evt :',NTRACKR PRINT *,'RECO_SUM nb of good muon /evt :',NMUF PRINT *,'RECO_SUM nb of ghost /evt :',NGHF - IF (NTREVT.GT.0) THEN - DO ITR = 1,NTREVT + IF (NTRACKR.GT.0) THEN + DO ITR = 1,NTRACKR PRINT *,'RECO_SUM track number :',ITR - PRINT *,'RECO_SUM PXZOUT :',PXZOUT(ITR) - PRINT *,'RECO_SUM CHI2OUT :',CHI2OUT(ITR) + PRINT *,'RECO_SUM CHI2OUT :',CHI2R(ITR) PRINT *,' PX GEANT= ', PXV(ITR),' PX RECONS= ',PYR(ITR) PRINT *,' PY GEANT= ', PYV(ITR),' PY RECONS= ',PXR(ITR) PRINT *,' PZ GEANT= ', PZV(ITR),' PZ RECONS= ',PZR(ITR) @@ -2343,12 +2280,12 @@ PXZR = SQRT( PXR(ITR)**2+PZR(ITR)**2) PRINT *,' PXZ GEANT= ', PXZV,' PXZ RECONS= ',PXZR FIV=ATAN2(PYV(ITR),PZV(ITR)) - ALAMV=ATAN2(DBLE(PXV(ITR)),PXZV) + ALAMV=ATAN2(PXV(ITR),PXZV) FIR=ATAN2(PXR(ITR),PZR(ITR)) - ALAMR=ATAN2(DBLE(PYR(ITR)),PXZR) + ALAMR=ATAN2(PYR(ITR),PXZR) ** PRINT *,' PHI GEANT= ',FIV,' PXZ RECONS= ',FIR ** PRINT *,' ALAM GEANT= ',ALAMV,' ALAM RECONS= ',ALAMR - ENDDO + ENDDO ENDIF ENDIF @@ -2372,7 +2309,7 @@ * COMMON/DEBEVT/IDEBUG * -* CHARACTER*50 FILEBKG,FILERES,FILEOUT,FILEMIN + CHARACTER*50 FILEBKG,FILERES,FILEOUT,FILEMIN * IF (IDEBUG.GE.1) THEN PRINT *,' ' @@ -2529,7 +2466,6 @@ ** & ZPLANEP(IPL3),ZPLANEP(IPL4) ** PRINT *,' CONST= ',CONST - PRINT *,' RECO_PRECISION CHI2OUT avant fit ',CHI2OUT(ICAN) IF (CHI2OUT(ICAN).GT.CHI2CUT) GO TO 2 @@ -2564,7 +2500,6 @@ YVERTOUT(NTRACK) = YEA CHI2OUT(NTRACK) = CHI2/FLOAT(2*NPLU-5) - PRINT *,' RECO_PRECISION CHI2OUT apres fit',CHI2OUT(NTRACK) ** print *,' reco_precision pxz tphi talam xvert yvert chi2', ** & PXZEA,PHIEA,ALAMEA, @@ -2657,7 +2592,8 @@ RETURN END *********************************************************************************** - SUBROUTINE DISTMIN4(X1,Y1,PHI1,ALAM1,ICH,EX,EY,EPHI,ELAM,IFIND) + SUBROUTINE DISTMIN4(X1,Y1,PHI1,ALAM1,ICH,EX,EY,EPHI,ELAM,IFIND, + & IFIND2) *********************************************************************************** * Find the nearest hit in station ICH in the (X,Y,lambda,phi) phase space * @@ -2672,11 +2608,17 @@ & IZM(NBSTATION,MAXHITCH), & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) - + DIMENSION IFIND2(10) + IFIND = 0 + DO I = 1,10 + IFIND2(I) = 0 + ENDDO + DISTMIN=4. + NF = 0 DO I=1,JHIT(ICH) - IF (PHM(ICH,I).LE.6.3) THEN ! angles measured + IF (PHM(ICH,I).LE.6.3) THEN ! vector measurement IF (ABS(PHI1-PHM(ICH,I)) .LT. EPHI .AND. & ABS(ALAM1-ALM(ICH,I)) .LT. ELAM .AND. & ABS(X1-XM(ICH,I)) .LT. EX .AND. @@ -2685,6 +2627,8 @@ & ((ALAM1-ALM(ICH,I))/ELAM)**2 + & ((X1-XM(ICH,I))/EX)**2 + & ((Y1-YM(ICH,I))/EY)**2 + NF = NF+1 + IF (NF.LE.10) IFIND2(NF) = I IF (DIST .LT. DISTMIN) THEN DISTMIN = DIST IFIND = I @@ -2696,7 +2640,7 @@ RETURN END *********************************************************************************** - SUBROUTINE DISTMIN2(X1,Y1,X2,Y2,ICH,EX1,EY1,EX2,EY2,IFIND) + SUBROUTINE DISTMIN2(X1,Y1,X2,Y2,ICH,EX1,EY1,EX2,EY2,IFIND,IFIND2) *********************************************************************************** * Find the nearest hit in station ICH in the (X,Y) space * @@ -2710,14 +2654,20 @@ & IZM(NBSTATION,MAXHITCH), & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) + DIMENSION IFIND2(10) IFIND = 0 + DO I = 1,10 + IFIND2(I) = 0 + ENDDO + DISTMIN=2. + NF = 0 DO I=1,JHIT(ICH) - IF (IZM(ICH,I).EQ.1) THEN + IF (IZM(ICH,I).EQ.1) THEN ! 1st chamber X = X1 Y = Y1 - ELSE + ELSE ! 2nd chamber X = X2 Y = Y2 ENDIF @@ -2736,6 +2686,8 @@ & ABS(Y-YM(ICH,I)) .LT. EY) THEN DIST = ((X-XM(ICH,I))/EX)**2 + & ((Y-YM(ICH,I))/EY)**2 + NF = NF+1 + IF (NF.LE.10) IFIND2(NF) = I IF (DIST .LT. DISTMIN) THEN DISTMIN = DIST IFIND = I @@ -2823,7 +2775,7 @@ END ******************************************************************************** - SUBROUTINE FOLLOW(ZSTR,PEST,IFLAG,XPL,YPL,PHPL,ALPL) + SUBROUTINE OLDFOLLOW(ZSTR,PEST,IFLAG,XPL,YPL,PHPL,ALPL) ******************************************************************************** * Calculate the particle trajectory in the spectrometer and * (XPL,YPL,PHPL,ALPL) @@ -2949,7 +2901,7 @@ RETURN END ******************************************************************************** - SUBROUTINE NEWFOLLOW(ZSTR,PEST,IFLAG,XPL,YPL,PHPL,ALPL) + SUBROUTINE FOLLOW(ZSTR,PEST,IFLAG,XPL,YPL,PHPL,ALPL) ******************************************************************************** * Calculate the particle trajectory in the spectrometer * (XPL,YPL,PHPL,ALPL) @@ -3014,7 +2966,8 @@ & .AND.NSTEP.LE.NSTEPMAX) NSTEP = NSTEP+1 ** WRITE(6,*) NSTEP,(VECT(I),I=1,7) - CALL RECO_GRKUTA (ASIGN,STEP,VECT,VOUT) +** CALL RECO_GRKUTA (ASIGN,STEP,VECT,VOUT) ! CCC + CALL RECO_GHELIX (ASIGN,STEP,VECT,VOUT) DO I = 1,7 VECT(I) = VOUT(I) ENDDO @@ -3070,6 +3023,10 @@ COMMON/VERTEX/ERRV,IVERTEX + DIMENSION XC(NBSTATION),YC(NBSTATION) + + EXTERNAL RECOCHI2 + PEEST(1)=PEST(1) PEEST(2)=PEST(2) PEEST(3)=PEST(3) @@ -3081,6 +3038,11 @@ PEEST(5)=0.0D0 ENDIF + ALAM = DATAN(PEST(3)) + PXZ = DABS(1./PEST(1)) + PTOT = PXZ/DCOS(ALAM) + + CALL FOLLOW (0.0D0,PEEST,IFLAG,XPL,YPL,PHPL,ALPL) ! calcul des IF(IFLAG.EQ.1) THEN ! points d impacts dans les PRINT *,'FCN ',XPL(4,1),XMES(4) ! plans @@ -3089,35 +3051,42 @@ PRINT *,'FCN ',YPL(5,1),YMES(5) ENDIF -* IF (IVERTEX.EQ.1) THEN -* FVAL = (PEST(4)/ERRV)**2 + (PEST(5)/ERRV)**2 -* ELSE - FVAL = 0.0D0 -* ENDIF - NPLPL = 0 - DO J = 1,NBSTATION - IF (MPOS(J).EQ.1) THEN - NPLPL = NPLPL+1 - XPLC = XPL(J,IZMES(J)) - YPLC = YPL(J,IZMES(J)) - FF = (XMES(J) - XPLC)/EEXM(J) - FVAL =FVAL + FF**2 - FF = (YMES(J) - YPLC)/EEYM(J) - FVAL =FVAL + FF**2 - ENDIF - IF (MANG(J).EQ.1) THEN - NPLPL = NPLPL+1 - FF = (PHMES(J) - PHPL(J))/EEPH(J) - FVAL =FVAL + FF**2 - FF = (ALMES(J) - ALPL(J))/EEAL(J) - FVAL =FVAL + FF**2 - ENDIF + DO I = 1,NBSTATION + XC(I) = XPL(I,1) + YC(I) = YPL(I,1) ENDDO -** PRINT *,'ST 1',XPL(1,1),XMES(1),YPL(1,1),YMES(1) -** PRINT *,'ST 2',XPL(2,1),XMES(2),YPL(2,1),YMES(2) -** PRINT *,'ST 3',XPL(3,1),XMES(3),YPL(3,1),YMES(3) -** PRINT *,'ST 4',XPL(4,1),XMES(4),YPL(4,1),YMES(4) -** PRINT *,'ST 5',XPL(5,1),XMES(5),YPL(5,1),YMES(5) + + IF (IVERTEX.EQ.1) THEN + + FVAL = RECOCHI2(MPOS,MANG,XMES,YMES,ALMES,PHMES, + & XC,YC,ALPL,PHPL,PTOT,IZMES,NPLPL) + + ELSE + + FVAL = 0.0D0 + + NPLPL = 0 + DO J = 1,NBSTATION + IF (MPOS(J).EQ.1) THEN + NPLPL = NPLPL+1 + XPLC = XPL(J,IZMES(J)) + YPLC = YPL(J,IZMES(J)) + FF = (XMES(J) - XPLC)/EEXM(J) + FVAL = FVAL + FF**2 + FF = (YMES(J) - YPLC)/EEYM(J) + FVAL = FVAL + FF**2 + ENDIF + IF (MANG(J).EQ.1) THEN + NPLPL = NPLPL+1 + FF = (PHMES(J) - PHPL(J))/EEPH(J) + FVAL = FVAL + FF**2 + FF = (ALMES(J) - ALPL(J))/EEAL(J) + FVAL = FVAL + FF**2 + ENDIF + ENDDO + + ENDIF + NPARAM = 3 IF (IVERTEX.EQ.1) NPARAM = 5 CHI2PL = FVAL/FLOAT(2*NPLPL-NPARAM) @@ -3125,8 +3094,8 @@ RETURN END ******************************************************************************** - SUBROUTINE STOCK_CANDIDAT(ICH1,JHITCH1,ICH2,IFIND,EXM,EYM,EPH,EAL, - & NCAN,ICODE) + SUBROUTINE STOCK_CANDIDAT(ICH1,JHITCH1,ICH2,IFIND,IFIND2,EXM,EYM, + & EPH,EAL,NCAN,ICODE) ******************************************************************************** * Fill common CANDIDAT with track candidates from the search in stations 4&5 * @@ -3150,95 +3119,174 @@ COMMON/CANDIDAT/JCAN(NBSTATION,MAXCAN),JCANTYP(MAXCAN), & EEX(MAXCAN),EEY(MAXCAN),EEP(MAXCAN),EEA(MAXCAN) + DIMENSION IFIND2(10) ** PRINT *,'STOCK st. init.=',ICH1,'id. init.=',ID(IP(ICH1,JHITCH1)) ** PRINT *,'STOCK st. finale=',ICH2,'id. final=',ID(IP(ICH2,IFIND)) ** PRINT *,'STOCK ifind=',IFIND ** PRINT *,'STOCK icode=',ICODE - NCAN = NCAN+1 - JCAN(ICH1,NCAN) = JHITCH1 - JCAN(ICH2,NCAN) = IFIND - JCANTYP(NCAN) = ICODE - EEX(NCAN) = EXM - EEY(NCAN) = EYM - EEP(NCAN) = EPH - EEA(NCAN) = EAL + DO I = 1,10 + IF (IFIND2(I).GT.0) THEN + NCAN = NCAN+1 + JCAN(ICH1,NCAN) = JHITCH1 + JCAN(ICH2,NCAN) = IFIND2(I) + JCANTYP(NCAN) = ICODE + EEX(NCAN) = EXM + EEY(NCAN) = EYM + EEP(NCAN) = EPH + EEA(NCAN) = EAL + ENDIF + ENDDO + RETURN END -***************************************************************************** - SUBROUTINE CHECK_HISTO4(IDHIST,ICH2,IHIT2,ICH1,IHIT1, - & X1,Y1,PHI1,ALAM1,P1,EXM,EYM,EPH,EAL) -***************************************************************************** -* Check hit IHIT2 with GEANT informations from hit HIT1 +******************************************************************************* + SUBROUTINE FCNOLD(NPAR,GRAD,FVAL,PEST,IFLAG,FUTIL) +******************************************************************************* +* Calculate FVAL=CHI2 the function minimized by minuit for a given track * -* INPUT : ICH2 : No st. de recherche -* IDCH1,X1,Y1,PHI1,ALAM1,P1 : Trace de reference -* OUTPUT : JOK : No hit dans ICH2 appartenant a la meme trace. -* -***************************************************************************** - IMPLICIT DOUBLE PRECISION(A-H,O-Z) - - PARAMETER (MAXHITCH=10000,MAXHITTOT=20000,NBSTATION=5, - & MAXTRK=50000) - - COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), - & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), - & IZM(NBSTATION,MAXHITCH), - & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), - & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) - - COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), - & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), - & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), - & ZVERT(MAXHITTOT),NHITTOT +******************************************************************************* + IMPLICIT DOUBLE PRECISION(A-H,O-Z) - COMMON/VERIFGEANT/ITTROUGH(MAXTRK,NBSTATION), - & IT_LIST(MAXTRK),IT_NP(MAXTRK),ITCHECK(MAXTRK), - & ITRACK(MAXHITTOT) -* - COMMON/DEBEVT/IDEBUG + PARAMETER(NBSTATION=5) - REAL*4 R2 - DATA R2/1./ +* DIMENSION PEST(*),GRAD(*) + DIMENSION PEST(5),GRAD(5) + DIMENSION PEEST(NBSTATION) - JOK = 0 + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) - DO I=1,JHIT(ICH2) - IF (PHM(ICH2,I).LE.6.3) THEN - IF (ID(IP(ICH1,IHIT1)).EQ.ID(IP(ICH2,I))) THEN - JOK = I - IF (IDHIST.GT.0) THEN - CALL CHFILL2(IDHIST,SNGL(P1), - & SNGL((X1-XM(ICH2,I))**2),1.) - CALL CHFILL2(IDHIST+1,SNGL(P1), - & SNGL((Y1-YM(ICH2,I))**2),1.) - CALL CHFILL2(IDHIST+2,SNGL(P1), - & SNGL((PHI1-PHM(ICH2,I))**2),1.) - CALL CHFILL2(IDHIST+3,SNGL(P1), - & SNGL((ALAM1-ALM(ICH2,I))**2),1.) - CALL CHF1(400+IDHIST, - & SNGL(X1-XM(ICH2,I)),1.) - CALL CHF1(400+IDHIST+1, - & SNGL(Y1-YM(ICH2,I)),1.) - CALL CHF1(400+IDHIST+2, - & SNGL(PHI1-PHM(ICH2,I)),1.) - CALL CHF1(400+IDHIST+3, - & SNGL(ALAM1-ALM(ICH2,I)),1.) - CALL CHF1(IDHIST+4,SNGL(P1),R2) - ENDIF - ENDIF - ENDIF - ENDDO - - IF (JOK.GT.0) THEN - IF (ITCHECK(ITRACK(IP(ICH1,IHIT1))).EQ.1) THEN - IF (IDEBUG.GE.2) THEN - IF (IHIT2.EQ.0) THEN - PRINT *,'CHECK4 histo nb:',IDHIST - PRINT *,'CHECK4 p de st.',ICH1,'=',P1 - PRINT *,'CHECK4 track not found in st.',ICH2 - PRINT *,'CHECK4 error X :',(XM(ICH2,JOK)-X1), EXM + + COMMON/PRECIS/EEXM(NBSTATION),EEYM(NBSTATION),EEPH(NBSTATION), + & EEAL(NBSTATION) + + COMMON /MEASUR/XMES(NBSTATION),YMES(NBSTATION),IZMES(NBSTATION), + & PHMES(NBSTATION),ALMES(NBSTATION), MPOS(NBSTATION), + & MANG(NBSTATION) + + COMMON /PLANE/XPL(NBSTATION,2),YPL(NBSTATION,2),PHPL(NBSTATION), + & ALPL(NBSTATION),CHI2PL + + COMMON/VERTEX/ERRV,IVERTEX + + PEEST(1)=PEST(1) + PEEST(2)=PEST(2) + PEEST(3)=PEST(3) + IF(IVERTEX.EQ.1) THEN + PEEST(4)=PEST(4) ! position du vertex + PEEST(5)=PEST(5) + ELSE + PEEST(4)=0.0D0 + PEEST(5)=0.0D0 + ENDIF + + CALL FOLLOW (0.0D0,PEEST,IFLAG,XPL,YPL,PHPL,ALPL) ! calcul des + IF(IFLAG.EQ.1) THEN ! points d impacts dans les + PRINT *,'FCN ',XPL(4,1),XMES(4) ! plans + PRINT *,'FCN ',YPL(4,1),YMES(4) + PRINT *,'FCN ',XPL(5,1),XMES(5) + PRINT *,'FCN ',YPL(5,1),YMES(5) + ENDIF + +* IF (IVERTEX.EQ.1) THEN +* FVAL = (PEST(4)/ERRV)**2 + (PEST(5)/ERRV)**2 +* ELSE + FVAL = 0.0D0 +* ENDIF + NPLPL = 0 + DO J = 1,NBSTATION + IF (MPOS(J).EQ.1) THEN + NPLPL = NPLPL+1 + XPLC = XPL(J,IZMES(J)) + YPLC = YPL(J,IZMES(J)) + FF = (XMES(J) - XPLC)/EEXM(J) + FVAL =FVAL + FF**2 + FF = (YMES(J) - YPLC)/EEYM(J) + FVAL =FVAL + FF**2 + ENDIF + IF (MANG(J).EQ.1) THEN + NPLPL = NPLPL+1 + FF = (PHMES(J) - PHPL(J))/EEPH(J) + FVAL =FVAL + FF**2 + FF = (ALMES(J) - ALPL(J))/EEAL(J) + FVAL =FVAL + FF**2 + ENDIF + ENDDO +** PRINT *,'ST 1',XPL(1,1),XMES(1),YPL(1,1),YMES(1) +** PRINT *,'ST 2',XPL(2,1),XMES(2),YPL(2,1),YMES(2) +** PRINT *,'ST 3',XPL(3,1),XMES(3),YPL(3,1),YMES(3) +** PRINT *,'ST 4',XPL(4,1),XMES(4),YPL(4,1),YMES(4) +** PRINT *,'ST 5',XPL(5,1),XMES(5),YPL(5,1),YMES(5) + NPARAM = 3 + IF (IVERTEX.EQ.1) NPARAM = 5 + CHI2PL = FVAL/FLOAT(2*NPLPL-NPARAM) + + RETURN + END +**************************************************************************** + SUBROUTINE CHECK_HISTO4(IDHIST,ICH2,IHIT2,ICH1,IHIT1, + & X1,Y1,PHI1,ALAM1,P1,EXM,EYM,EPH,EAL) +***************************************************************************** +* Check hit IHIT2 with GEANT informations from hit HIT1 +* +* INPUT : ICH2 : No st. de recherche +* IDCH1,X1,Y1,PHI1,ALAM1,P1 : Trace de reference +* OUTPUT : JOK : No hit dans ICH2 appartenant a la meme trace. +* +***************************************************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER (MAXHITCH=10000,MAXHITTOT=20000,NBSTATION=5, + & MAXTRK=50000) + + COMMON/CHHIT/XM(NBSTATION,MAXHITCH),YM(NBSTATION,MAXHITCH), + & PHM(NBSTATION,MAXHITCH),ALM(NBSTATION,MAXHITCH), + & IZM(NBSTATION,MAXHITCH), + & IP(NBSTATION,MAXHITCH),JHIT(NBSTATION), + & XMR(NBSTATION,MAXHITCH,2),YMR(NBSTATION,MAXHITCH,2) + + COMMON/RHIT/ITYP(MAXHITTOT),XTR(MAXHITTOT),YTR(MAXHITTOT), + & PTOT(MAXHITTOT),ID(MAXHITTOT),IZST(MAXHITTOT), + & PVERT1(MAXHITTOT),PVERT2(MAXHITTOT),PVERT3(MAXHITTOT), + & ZVERT(MAXHITTOT),NHITTOT + + COMMON/VERIFGEANT/ITTROUGH(MAXTRK,NBSTATION), + & IT_LIST(MAXTRK),IT_NP(MAXTRK),ITCHECK(MAXTRK), + & ITRACK(MAXHITTOT) +* + COMMON/DEBEVT/IDEBUG + + REAL*4 R2 + DATA R2/1./ + + JOK = 0 + + DO I=1,JHIT(ICH2) + IF (PHM(ICH2,I).LE.6.3) THEN ! vector measurement + IF (ID(IP(ICH1,IHIT1)).EQ.ID(IP(ICH2,I))) THEN + JOK = I + IF (IDHIST.GT.0) THEN +* CALL CHF1(IDHIST,SNGL(P1),SNGL((X1-XM(ICH2,I))**2)) +* CALL CHF1(IDHIST+1,SNGL(P1),SNGL((Y1-YM(ICH2,I))**2)) +* CALL CHF1(IDHIST+2,SNGL(P1), +* & SNGL((PHI1-PHM(ICH2,I))**2)) +* CALL CHF1(IDHIST+3,SNGL(P1), +* & SNGL((ALAM1-ALM(ICH2,I))**2)) +* CALL CHF1(IDHIST+4,SNGL(P1),R2) + ENDIF + ENDIF + ENDIF + ENDDO + + IF (JOK.GT.0) THEN + IF (ITCHECK(ITRACK(IP(ICH1,IHIT1))).EQ.1) THEN + IF (IDEBUG.GE.2) THEN + IF (IHIT2.EQ.0) THEN + PRINT *,'CHECK4 histo nb:',IDHIST + PRINT *,'CHECK4 p de st.',ICH1,'=',P1 + PRINT *,'CHECK4 track not found in st.',ICH2 + PRINT *,'CHECK4 error X :',(XM(ICH2,JOK)-X1), EXM PRINT *,'CHECK4 error Y :',(YM(ICH2,JOK)-Y1), EYM PRINT *,'CHECK4 error PHI :',(PHM(ICH2,JOK)-PHI1),EPH PRINT *,'CHECK4 error ALAM :',(ALM(ICH2,JOK)-ALAM1), @@ -3251,6 +3299,7 @@ & ID(IP(ICH1,IHIT1)) PRINT *,'CHECK4 id ghost trouve :', & ID(IP(ICH2,IHIT2)) + PRINT *,'CHECK4 JOK=',JOK,' IHIT2=',IHIT2 ENDIF ENDIF ENDIF @@ -3301,22 +3350,16 @@ IF (ID(IP(ICH1,IHIT1)).EQ.ID(IP(ICH2,I))) THEN JOK = I IF (IDHIST.GT.0) THEN - IF (IZM(ICH2,I).EQ.1) THEN + IF (IZM(ICH2,I).EQ.1) THEN ! 1st chamber X = X1 Y = Y1 - ELSE + ELSE ! 2nd chamber X = X2 Y = Y2 - ENDIF - CALL CHFILL2(200+IDHIST,SNGL(P1), - & SNGL((X-XM(ICH2,I))**2),1.) - CALL CHFILL2(200+IDHIST+1,SNGL(P1), - & SNGL((Y-YM(ICH2,I))**2),1.) - CALL CHF1(200+IDHIST+2, - & SNGL(X-XM(ICH2,I)),1.) - CALL CHF1(200+IDHIST+3, - & SNGL(Y-YM(ICH2,I)),1.) - CALL CHF1(200+IDHIST+4,SNGL(P1),R2) + ENDIF + CALL CHF1(IDHIST,SNGL(P1),SNGL((X-XM(ICH2,I))**2)) + CALL CHF1(IDHIST+1,SNGL(P1),SNGL((Y-YM(ICH2,I))**2)) + CALL CHF1(IDHIST+4,SNGL(P1),R2) ENDIF ENDIF ENDDO @@ -3355,6 +3398,7 @@ & ID(IP(ICH1,IHIT1)) PRINT *,'CHECK2 id ghost trouve :', & ID(IP(ICH2,IHIT2)) + PRINT *,'CHECK2 JOK=',JOK,' IHIT2=',IHIT2 ENDIF ENDIF ENDIF @@ -3363,10 +3407,71 @@ RETURN END - + DOUBLE PRECISION FUNCTION DEDX(P,THET,XEA,YEA) + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + REA = DSQRT(XEA**2+YEA**2) + IF (REA.lT.26.3611) THEN + if (p .lt. 15.) then + DP=2.737+0.0494*p-0.001123*p*p + else + DP=3.0643+0.01346*p + endif + ELSE + if (p .lt. 15.) then + DP = 2.1380+0.0351*p-0.000853*p*p + else + DP = 2.407+0.00702*p + endif + ENDIF + P=P+DP/DCOS(THET) + DEDX=P + RETURN + END ************************************************************************ - DOUBLE PRECISION FUNCTION DEDX (P,THET,XEA,YEA) + DOUBLE PRECISION FUNCTION DEDX_oldold(P,THET,XEA,YEA) +************************************************************************ +* DEDX est la nouvelle impulsion au vertex, corrigee de la perte +* d'energie dans l'absorbeur +* +************************************************************************ + + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + DIMENSION PPB(6), PW(6) +* FIT RESULT FOR PB REGION (5TH ORDER POLY) +* 1 p0 2.24358e+03 2.55765e+00 1.06982e-03 6.30474e-07 +* 2 p1 1.16393e+01 4.45081e-02 6.58627e-06 -1.15822e-04 +* 3 p2 -1.82314e-01 3.28429e-04 8.69340e-08 -1.27281e-02 +* 4 p3 1.60930e-03 2.23812e-06 7.67374e-10 -4.15573e-01 +* 5 p4 -6.96885e-06 1.35405e-08 3.32301e-12 1.22136e+02 +* 6 p5 1.16339e-08 5.91665e-11 1.06532e-14 3.33965e+04 + + DATA PPB /2.24358d+03, 1.16393d+01, -1.82314d-01, 1.60930d-03 + + ,-6.96885d-06, 1.16339d-08/ +* FIT RESULT FOR W REGION (5TH ORDER POLY) +* 1 p0 2.90155e+03 3.49066e+00 1.38357e-03 -2.79916e-05 +* 2 p1 1.57716e+01 6.09946e-02 9.03687e-06 -6.63098e-03 +* 3 p2 -2.48349e-01 4.50365e-04 1.18422e-07 -8.27199e-01 +* 4 p3 2.19908e-03 3.07148e-06 1.04860e-09 -1.03290e+02 +* 5 p4 -9.54046e-06 1.85908e-08 4.54924e-12 -1.51284e+04 +* 6 p5 1.59463e-08 8.11346e-11 1.46446e-14 -2.69491e+06 + DATA PW /2.90155d+03, 1.57716d+01, -2.48349d-01, 2.19908d-03 + + , -9.54046d-06, 1.59463d-08/ +* + REA = DSQRT(XEA**2+YEA**2) + IF (REA.GT.26.3611) THEN + DP=PPB(1)+PPB(2)*P+PPB(3)*P**2 + & +PPB(4)*P**3+PPB(5)*P**4+PPB(6)*P**5 + ELSE + DP=PW(1)+PW(2)*P+PW(3)*P**2 + & +PW(4)*P**3+PW(5)*P**4+PW(6)*P**5 + ENDIF + P=P+DP/1000.D0/DCOS(THET) + DEDX=P + RETURN + END +************************************************************************ + DOUBLE PRECISION FUNCTION DEDX_OLD(P,THET,XEA,YEA) ************************************************************************ * DEDX est la nouvelle impulsion au vertex, corrigee de la perte * d'energie dans l'absorbeur @@ -3418,6 +3523,8 @@ RETURN END +*/ + ************************************************************************ SUBROUTINE BRANSON(PXZ,PHI,ALAM,XEA,YEA) ************************************************************************ @@ -3449,7 +3556,7 @@ ELSE ! Abso. W pour theta < 3 deg ZBP = ZBP2 ENDIF - +* ZBP = ZEA ! Andreas XBP = XEA-PX/PZ*(ZEA-ZBP) YBP = YEA-PY/PZ*(ZEA-ZBP) PZ = PTOT*ZBP/DSQRT(XBP**2+YBP**2+ZBP**2) @@ -3597,14 +3704,12 @@ * $Id$ * * $Log$ -* Revision 1.3 1999/10/05 17:15:45 fca -* Minor syntax for the Alpha OSF -* -* Revision 1.2 1999/08/06 14:12:30 fca -* Remove several warnings +* Revision 1.4.4.2 2000/04/26 15:48:37 morsch +* Some routines from obsolete algo.F are needed by reco_muon.F and have been +* copied there. * -* Revision 1.1 1999/07/30 10:53:20 fca -* New version of MUON from M.Bondila & A.Morsch +* Revision 1.4.4.1 2000/01/12 16:00:55 morsch +* New version of MUON code * * Revision 1.1.1.1 1996/02/15 17:48:35 mclareni * Kernlib @@ -3726,6 +3831,7 @@ COMMON/FCNOUT/PXZEA,ALAMEA,PHIEA,XEA,YEA,NPLU,CHI2 + DIMENSION GRAD(*),XVAL(*),AMS(500),DISTAZ(500) DIMENSION XP(NPLANE),YP(NPLANE), @@ -3784,7 +3890,8 @@ ** & .AND. (THETA*PITODEG).LT.9.) NSTEP = NSTEP+1 ** WRITE(6,*) NSTEP,(VECT(I),I=1,7) - CALL RECO_GRKUTA(ASIGN,STEP,VECT,VOUT) +** CALL RECO_GRKUTA(ASIGN,STEP,VECT,VOUT) ! CCC + CALL RECO_GHELIX(ASIGN,STEP,VECT,VOUT) DO I = 1,7 VECT(I) = VOUT(I) ENDDO @@ -3818,11 +3925,11 @@ ENDIF * IF (I .EQ. 10 .AND. J .EQ. 10) PRINT *,'10 10 ',COV(J,I) - DO L = 1,NTMAX - COV(J,I) = COV(J,I) - & + (ZPLANEP(II) + DISTAZ(L))*(ZPLANEP(JJ) + - & DISTAZ(L))*AMS(L)**2 - ENDDO +** DO L = 1,NTMAX +** COV(J,I) = COV(J,I) +** & + (ZPLANEP(II) + DISTAZ(L))*(ZPLANEP(JJ) + +** & DISTAZ(L))*AMS(L)**2 +** ENDDO DO K = 1, II-1 COV(J,I) = COV(J,I) & + (ZPLANEP(II)-ZPLANEP(K))* @@ -4679,6 +4786,7 @@ C 999 END + ******************************************************************* SUBROUTINE RECO_GUFLD(X,B) C @@ -4756,13 +4864,13 @@ C B(1)=0. B(2)=0. B(3)=0. - ENDIF + ENDIF ELSE IF(ISXFMAP.LE.3) THEN IF (-700.LT.X(3).AND.X(3).LT.ZMBEG + .AND. X(1)**2+(X(2)+30.)**2 .LT. 560.**2 ) THEN B(1)=0. B(2)=0. - B(3)=2. + B(3)=0. ELSE IF ((X(3) .GE. ZMBEG .AND. X(3) .LT. ZMEND) .AND. + (XMBEG.LE.ABS(X(1)).AND.ABS(X(1)).LT.XMEND) .AND. + (YMBEG.LE.ABS(X(2)).AND.ABS(X(2)).LT.YMEND)) THEN @@ -4956,8 +5064,6 @@ C --- Common containing magnetic field map data $,XMBEG,YMBEG,ZMBEG,XMEND,YMEND,ZMEND $,BV(MAXFLD) - CHARACTER*255 CHDIR - ISXFMAP = 3 IF(ISXFMAP.EQ.1) THEN @@ -4968,10 +5074,7 @@ C --- Common containing magnetic field map data 10000 FORMAT(' *SXFMAP* Magnetic field map flag: ',I5 $ ,'; Reading magnetic field map data ') * - CHDIR=' ' - CALL GETENVF('ALICE_ROOT',CHDIR) - LEND=LNBLNK(CHDIR) - OPEN(77,FILE=CHDIR(1:LEND)//'/data/field01.dat', + OPEN(77,FILE='/home/morsch/AliRoot/V3.02/data/field01.dat', $ FORM='FORMATTED',STATUS='OLD') READ(77,*) NX,NY,NZ,DX,DY,DZ,XMBEG,YMBEG,ZMBEG PRINT*,'NX,NY,NZ,DX,DY,DZ,XMBEG,YMBEG,ZMBEG', @@ -5271,4 +5374,748 @@ C RETURN END +* +* $Id$ +* +* $Log$ +* Revision 1.4.4.2 2000/04/26 15:48:37 morsch +* Some routines from obsolete algo.F are needed by reco_muon.F and have been +* copied there. +* +* Revision 1.4.4.1 2000/01/12 16:00:55 morsch +* New version of MUON code +* +* Revision 1.1.1.1 1995/10/24 10:21:41 cernlib +* Geant +* +* +*CMZ : 3.21/02 29/03/94 15.41.23 by S.Giani +*-- Author : + SUBROUTINE RECO_GHELIX (CHARGE, STEP, VECT, VOUT) +C. +C. ****************************************************************** +C. * * +C. * Performs the tracking of one step in a magnetic field * +C. * The trajectory is assumed to be a helix in a constant field * +C. * taken at the mid point of the step. * +C. * Parameters: * +C. * input * +C. * STEP =arc length of the step asked * +C. * VECT =input vector (position,direction cos and momentum) * +C. * CHARGE= electric charge of the particle * +C. * output * +C. * VOUT = same as VECT after completion of the step * +C. * * +C. * ==>Called by : , GUSWIM * +C. * Author M.Hansroul ********* * +C. * Modified S.Egli, S.V.Levonian * +C. * Modified V.Perevoztchikov +C. * * +C. ****************************************************************** +C. + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + + DIMENSION VECT(7),VOUT(7) + DIMENSION XYZ(3),H(4),HXP(3) + PARAMETER (IX=1,IY=2,IZ=3,IPX=4,IPY=5,IPZ=6,IPP=7) + PARAMETER (SIXTH = 1./6.) + PARAMETER (EC=2.9979251E-4) +C. +C. ------------------------------------------------------------------ +C. +C units are kgauss,centimeters,gev/c +C + VOUT(IPP) = VECT(IPP) + IF (CHARGE.EQ.0.) GO TO 10 + XYZ(1) = VECT(IX) + 0.5 * STEP * VECT(IPX) + XYZ(2) = VECT(IY) + 0.5 * STEP * VECT(IPY) + XYZ(3) = VECT(IZ) + 0.5 * STEP * VECT(IPZ) +C + CALL RECO_GUFLD (XYZ, H) + + H2XY = H(1)**2 + H(2)**2 + H(4) = H(3)**2 + H2XY + IF (H(4).LE.1.E-12) GO TO 10 + IF (H2XY.LE.1.E-12*H(4)) THEN + CALL RECO_GHELX3 (CHARGE*H(3), STEP, VECT, VOUT) + GO TO 999 + ENDIF + H(4) = SQRT(H(4)) + H(1) = H(1)/H(4) + H(2) = H(2)/H(4) + H(3) = H(3)/H(4) + H(4) = H(4)*EC +* + HXP(1) = H(2)*VECT(IPZ) - H(3)*VECT(IPY) + HXP(2) = H(3)*VECT(IPX) - H(1)*VECT(IPZ) + HXP(3) = H(1)*VECT(IPY) - H(2)*VECT(IPX) + + HP = H(1)*VECT(IPX) + H(2)*VECT(IPY) + H(3)*VECT(IPZ) +* + RHO = -CHARGE*H(4)/VECT(IPP) + TET = RHO * STEP + IF (ABS(TET).GT.0.15) THEN + SINT = SIN(TET) + SINTT = (SINT/TET) + TSINT = (TET-SINT)/TET + COS1T = 2.*(SIN(0.5*TET))**2/TET + ELSE + TSINT = SIXTH*TET**2 + SINTT = (1. - TSINT) + SINT = TET*SINTT + COS1T = 0.5*TET + ENDIF +* + F1 = STEP * SINTT + F2 = STEP * COS1T + F3 = STEP * TSINT * HP + F4 = -TET*COS1T + F5 = SINT + F6 = TET * COS1T * HP + + VOUT(IX) = VECT(IX) + (F1*VECT(IPX) + F2*HXP(1) + F3*H(1)) + VOUT(IY) = VECT(IY) + (F1*VECT(IPY) + F2*HXP(2) + F3*H(2)) + VOUT(IZ) = VECT(IZ) + (F1*VECT(IPZ) + F2*HXP(3) + F3*H(3)) + + VOUT(IPX) = VECT(IPX) + (F4*VECT(IPX) + F5*HXP(1) + F6*H(1)) + VOUT(IPY) = VECT(IPY) + (F4*VECT(IPY) + F5*HXP(2) + F6*H(2)) + VOUT(IPZ) = VECT(IPZ) + (F4*VECT(IPZ) + F5*HXP(3) + F6*H(3)) + + GO TO 999 + + 10 CONTINUE + DO 20 I = 1,3 + VOUT(I) = VECT(I) + STEP * VECT(I+3) + VOUT(I+3) = VECT(I+3) + 20 CONTINUE +C + 999 END + +* +* $Id$ +* +* $Log$ +* Revision 1.4.4.2 2000/04/26 15:48:37 morsch +* Some routines from obsolete algo.F are needed by reco_muon.F and have been +* copied there. +* +* Revision 1.4.4.1 2000/01/12 16:00:55 morsch +* New version of MUON code +* +* Revision 1.1.1.1 1995/10/24 10:21:41 cernlib +* Geant +* +* + +*CMZ : 3.21/02 29/03/94 15.41.23 by S.Giani +*-- Author : + SUBROUTINE RECO_GHELX3 (FIELD, STEP, VECT, VOUT) +C. +C. ****************************************************************** +C. * * +C. * Tracking routine in a constant field oriented * +C. * along axis 3 * +C. * Tracking is performed with a conventional * +C. * helix step method * +C. * * +C. * ==>Called by : , GUSWIM * +C. * Authors R.Brun, M.Hansroul ********* * +C * Rewritten V.Perevoztchikov +C. * * +C. ****************************************************************** +C. + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + + DIMENSION VECT(7),VOUT(7),HXP(3) + PARAMETER (IX=1,IY=2,IZ=3,IPX=4,IPY=5,IPZ=6,IPP=7) + PARAMETER (SIXTH = 1./6.) + PARAMETER (EC=2.9979251E-4) +C. +C. ------------------------------------------------------------------ +C. +C units are kgauss,centimeters,gev/c +C + VOUT(IPP) = VECT(IPP) + H4 = FIELD * EC +* + HXP(1) = - VECT(IPY) + HXP(2) = + VECT(IPX) + + HP = VECT(IPZ) +* + RHO = -H4/VECT(IPP) + TET = RHO * STEP + IF (ABS(TET).GT.0.15) THEN + SINT = SIN(TET) + SINTT = (SINT/TET) + TSINT = (TET-SINT)/TET + COS1T = 2.*(SIN(0.5*TET))**2/TET + ELSE + TSINT = SIXTH*TET**2 + SINTT = (1. - TSINT) + SINT = TET*SINTT + COS1T = 0.5*TET + ENDIF +* + F1 = STEP * SINTT + F2 = STEP * COS1T + F3 = STEP * TSINT * HP + F4 = -TET*COS1T + F5 = SINT + F6 = TET * COS1T * HP + + VOUT(IX) = VECT(IX) + (F1*VECT(IPX) + F2*HXP(1)) + VOUT(IY) = VECT(IY) + (F1*VECT(IPY) + F2*HXP(2)) + VOUT(IZ) = VECT(IZ) + (F1*VECT(IPZ) + F3) + + VOUT(IPX) = VECT(IPX) + (F4*VECT(IPX) + F5*HXP(1)) + VOUT(IPY) = VECT(IPY) + (F4*VECT(IPY) + F5*HXP(2)) + VOUT(IPZ) = VECT(IPZ) + (F4*VECT(IPZ) + F6) + +C + 999 END + +************************************************************************ + DOUBLE PRECISION FUNCTION RECOCHI2 (MPOS,MANG,XM,YM,ALAMM,APHIM, + & XC,YC,ALAMC,APHIC,PTOT,IZMES,NPLPL) +C. +C. ****************************************************************** +C. * Calculate chi2 taking into account MSC * +C. * * +C. ****************************************************************** +C. + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + PARAMETER(NBSTATION=5,NPLANE=10) + + COMMON/ZDEFIN/ZPLANE(NBSTATION),ZCOIL,ZMAGEND,DZ_PL(NBSTATION) + + COMMON/PARAM/ZPLANEP(NPLANE),THICK,XPREC,YPREC,B0,BL3,ZMAGS, + & ZMAGE,ZABS,XMAG,ZBP1,ZBP2,CONST +C + DIMENSION MPOS(NBSTATION),MANG(NBSTATION), + & XM(NBSTATION),YM(NBSTATION),ALAMM(NBSTATION),APHIM(NBSTATION), + & XC(NBSTATION),YC(NBSTATION),ALAMC(NBSTATION),APHIC(NBSTATION), + & ALAMP(NBSTATION),APHIP(NBSTATION) + + DIMENSION AP(NPLANE),IZMES(NBSTATION),IPLANE(NPLANE) + DIMENSION COVX(NPLANE,NPLANE),COVY(NPLANE,NPLANE) + DIMENSION XM1(NPLANE),YM1(NPLANE),XC1(NPLANE),YC1(NPLANE) + + + ICH = 0 + NPLPL = 0 + DO IZ = 1,NBSTATION + ICH = ICH + 1 + IPLANE(ICH) = 0 + AL = THICK/(COS(ALAMC(IZ))*COS(APHIC(IZ))) + AP(ICH) = (0.0136D0/PTOT)*DSQRT(AL)*(1.+0.038D0*DLOG(AL)) + IF (MPOS(IZ).EQ.1.AND.IZMES(IZ).EQ.1) THEN + IPLANE(ICH) = 1 + XM1(ICH) = XM(IZ) + YM1(ICH) = YM(IZ) + ENDIF + XC1(ICH) = XC(IZ) + YC1(ICH) = YC(IZ) + + ICH = ICH + 1 + IPLANE(ICH) = 0 + AP(ICH) = (0.0136D0/PTOT)*DSQRT(AL)*(1.+0.038D0*DLOG(AL)) + IF (MPOS(IZ).EQ.1.AND.IZMES(IZ).EQ.2) THEN + IPLANE(ICH) = 1 + XM1(ICH) = XM(IZ) + YM1(ICH) = YM(IZ) + ENDIF + IF (MANG(IZ).EQ.1) THEN + IPLANE(ICH) = 1 + XM1(ICH) = XM(IZ) - DZ_PL(IZ) * TAN(APHIM(IZ)) + YM1(ICH) = YM(IZ) + DZ_PL(IZ)/COS(APHIM(IZ))*TAN(ALAMM(IZ)) + ENDIF + XC1(ICH) = XC(IZ) - DZ_PL(IZ) * TAN(APHIC(IZ)) + YC1(ICH) = YC(IZ) + DZ_PL(IZ)/COS(APHIC(IZ))*TAN(ALAMC(IZ)) + IF (IPLANE(ICH).EQ.1) NPLPL = NPLPL+1 + ENDDO + + + +** Matrice de covariance X et Y + I = 0 + DO II = 1,NPLANE + + IF (IPLANE(II).EQ.1) THEN + I = I + 1 + + J = I - 1 + DO JJ = II, NPLANE + IF (IPLANE(JJ).EQ.1) THEN + J = J + 1 + + COVX (I,J) = 0. + COVX (J,I) = 0. + IF (I .EQ. J) THEN + COVX(J,I) =COVX(J,I) + XPREC**2 + ENDIF + + DO K = 1, II-1 + COVX(J,I) = COVX(J,I) + & + (-ZPLANEP(II)+ZPLANEP(K))* + & (-ZPLANEP(JJ)+ZPLANEP(K))*AP(K)**2 + + ENDDO + COVY(I,J) = 0. + COVY(J,I) = COVX(J,I) + IF (I .EQ. J) THEN + COVY(J,I) = COVY(J,I) - XPREC**2 + YPREC**2 + ENDIF + ENDIF + ENDDO + ENDIF + ENDDO + + NPLUP = I + + +* Inversion des matrices de covariance + IFAIL = 0 + CALL DSINV(NPLUP, COVX, NPLANE, IFAIL) +** IF (JFAIL.NE.0 .AND. IFAIL .NE. 0) STOP 'ERROR' + IF (IFAIL .NE. 0) STOP 'RECOCHI2 ERROR COVX' + + IFAIL = 0 + CALL DSINV(NPLUP, COVY, NPLANE, IFAIL) +** IF (JFAIL.NE.0 .AND. IFAIL .NE. 0) STOP 'ERROR' + IF (IFAIL .NE. 0) STOP 'RECOCHI2 ERROR COVY' + +** Calcul de FVAL ou CHI2 + FVAL = 0. + + I = 0 + DO II = 1,NPLANE + IF (IPLANE(II).EQ.1) THEN + I = I+1 + J = 0 +** print *,' II=',ii,' XM1,YM1 =',xm1(ii),ym1(ii), +** & ' XC,YC =',xc1(ii),yc1(ii) + DO JJ = 1,NPLANE + IF (IPLANE(JJ).EQ.1) THEN + J = J+1 + FVAL = FVAL + COVX(J,I)*(XM1(II)-XC1(II)) + & *(XM1(JJ)-XC1(JJ)) + FVAL = FVAL + COVY(J,I)*(YM1(II)-YC1(II)) + & *(YM1(JJ)-YC1(JJ)) + ENDIF + ENDDO + ENDIF + ENDDO + + RECOCHI2 = FVAL +** print *,' recochi2 =',recochi2 + +C + RETURN + END + +************************************************************************ + SUBROUTINE RECO_SELECT(ISEL) +************************************************************************ * ISEL(I) = 1 if track number I is OK, ISEL(I) = 0 otherwise +************************************************************************ + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + + PARAMETER (NPLANE=10,NBCHAMBER=10,NTRMAX=500) + COMMON/DEBEVT/IDEBUG + + COMMON/PARAM/ZPLANEP(NPLANE),THICK,XPREC,YPREC,B0,BL3,ZMAGS, + & ZMAGE,ZABS,XMAG,ZBP1,ZBP2,CONST + + COMMON/TRACKFOUT/IEVOUT,NTREVT,JJOUT(NBCHAMBER,NTRMAX), + & ISTAT(NTRMAX),PXZOUT(NTRMAX),TPHIOUT(NTRMAX), + & TALAMOUT(NTRMAX),XVERTOUT(NTRMAX),YVERTOUT(NTRMAX), + & CHI2OUT(NTRMAX), + & XMESOUT(NBCHAMBER,NTRMAX),YMESOUT(NBCHAMBER,NTRMAX) + & ,PXVOUT(NTRMAX),PYVOUT(NTRMAX),PZVOUT(NTRMAX) + + DIMENSION ISEL(NTRMAX) + + DO I = 1,NTREVT + ISEL(I) = 1 + ENDDO + + DO I = 1,NTREVT + + ICH1 = 9 + JJ1 = JJOUT(ICH1,I) + IF (JJ1.EQ.0) ICH1 = 10 + X1 = XMESOUT(ICH1,I) + Y1 = YMESOUT(ICH1,I) + + DO J = I+1,NTREVT + ICH2 = 9 + JJ2 = JJOUT(ICH2,J) + IF (JJ2.EQ.0) ICH2 = 10 + X2 = XMESOUT(ICH2,J) + Y2 = YMESOUT(ICH2,J) + DIST = SQRT(((X2-X1)/(10.*XPREC))**2 + & +((Y2-Y1)/(10.*YPREC))**2) + IF (DIST.LT.2.) THEN + CHI21 = CHI2OUT(I) + CHI22 = CHI2OUT(J) + IF (CHI22.LT.CHI21) THEN + ISEL(I) = 0 + IF (IDEBUG.EQ.2) THEN + PRINT *,' RECO_SELECT I,ISEL= ',I,ISEL(I) + ENDIF + ELSE + ISEL(J) = 0 + IF (IDEBUG.EQ.2) THEN + PRINT *,' RECO_SELECT J,ISEL= ',J,ISEL(J) + ENDIF + ENDIF + ENDIF + ENDDO + + ENDDO + + + RETURN + END + +*************************************************** + SUBROUTINE reconstmuon2(IFIT,IDEBUGC,NEV) +*************************************************** + IMPLICIT DOUBLE PRECISION(A-H,O-Z) + + PARAMETER(NPLANE=10,MAXIDG=28,NTRMAX=500) + + REAL*4 PXR,PYR,PZR,ZVR,CHI2R,PXV,PYV,PZV + + COMMON/TRACKFI/EFF,EFF1,EFF2,XPREC,YPREC,PHIPREC,ALAMPREC, + & HCUT,LBKG,SIGCUT,ALPHATOP,HTOP + + COMMON/PAWCR4/IEVR,NTRACKR,ISTATR(NTRMAX),ISIGNR(NTRMAX), + & PXR(NTRMAX),PYR(NTRMAX),PZR(NTRMAX),ZVR(NTRMAX), + & CHI2R(NTRMAX),PXV(NTRMAX),PYV(NTRMAX),PZV(NTRMAX) + + COMMON/MEAS/LPLANE(NPLANE),XMP(NPLANE),YMP(NPLANE) + + COMMON/FIT/NHITTOT1,izch(maxidg),xgeant(maxidg), + & ygeant(nplane) + + COMMON/PRECCUT/PCUT,PTCUT,CHI2CUT + + REAL*4 RN1,RN2 + +** Read events + CALL trackf_read_fit(IEVR,NEV,NHITTOT1,IZCH,XGEANT,YGEANT) + print*,'nhittot1 ',nhittot1 + +* do i=1,NHITTOT1 +* print*,'x=',xgeant(i),' y=',ygeant(i),' ch=',izch(i) +* enddo + + if (nhittot1.ne.20) goto 55 + nhit1=1 + nhit2=10 + do ntr=1,2 ! loop over tracks + do nhit=nhit1,nhit2 ! loop over hits + ich=izch(nhit) + lplane(ich)=1 + + CALL RANNOR(RN1,RN2) ! CCC +* xmp(ich)=xgeant(nhit) +* ymp(ich)=ygeant(nhit) + xmp(ich)=xgeant(nhit) + RN1 * XPREC + ymp(ich)=ygeant(nhit) + RN2 * YPREC + end do + call fit_trace(ntr) + nhit1=11 + nhit2=20 + end do + + CALL CHFNT(IEVR,NTRACK,ISTATR,ISIGNR, + & PXR,PYR,PZR,ZVR,CHI2R,PXV,PYV,PZV) + + 55 continue + + END + +********************************* + subroutine fit_trace(ntr) +********************************* +* + IMPLICIT DOUBLE PRECISION (A-H,O-Z) + + PARAMETER(NPLANE=10,NTRACK=2,NTRMAX=500) + + COMMON/FCNOUT/PXZEA,ALAMEA,PHIEA,XEA,YEA,NPLU,CHI2 + + REAL*4 PXR,PYR,PZR,ZVR,CHI2R,PXV,PYV,PZV + COMMON/PAWCR4/IEVR,NTRACKR,ISTATR(NTRMAX),ISIGNR(NTRMAX), + & PXR(NTRMAX),PYR(NTRMAX),PZR(NTRMAX),ZVR(NTRMAX), + & CHI2R(NTRMAX),PXV(NTRMAX),PYV(NTRMAX),PZV(NTRMAX) + + COMMON/MEAS/LPLANE(NPLANE),XMP(NPLANE),YMP(NPLANE) + + COMMON/PARAM/ZPLANEP(NPLANE),THICK,XPREC,YPREC,B0,BL3,ZMAGS, + & ZMAGE,ZABS,XMAG,ZBP1,ZBP2,CONST + + COMMON/PRECCUT/PCUT,PTCUT,CHI2CUT + + dimension PXZOUT(NTRMAX),TPHIOUT(NTRMAX),TALAMOUT(NTRMAX), + & CHI2OUT(NTRMAX) + + x1=xmp(1) + y1=ymp(1) + ipl1=1 + x2=xmp(3) + y2=ymp(3) + ipl2=3 + x3=xmp(7) + ipl3=7 + x4=xmp(9) + ipl4=9 + + PHIAV = DATAN2((X2-X1),(ZPLANEP(IPL2)-ZPLANEP(IPL1))) + PHIAP = DATAN2((X4-X3),(ZPLANEP(IPL4)-ZPLANEP(IPL3))) + + DPHI = (PHIAP-PHIAV) + ASIGN = 1. + IF (DPHI.LT.0.) ASIGN = -1. ! CCC + PXZ = CONST/DABS(DPHI) + +* * Cuts PXZ + IF (PXZ.LT.PCUT) GO TO 66 + + PXZINVI = ASIGN/PXZ ! CCC + PHII = PHIAV + ALAMI = DATAN2((Y2-Y1),DSQRT((X2-X1)**2 + & +(ZPLANEP(IPL2)-ZPLANEP(IPL1))**2)) + XVR = X1 + YVR = Y1 + +* print *,' avant prec_fit pxzi phii alami x y',1./ PXZINVI, +* & PHII, ALAMI ,XVR,YVR +* PRINT *,' X1 X2 X3 X4',X1,X2,X3,X4 +* PRINT *,' Z1 Z2 Z3 Z4',ZPLANEP(IPL1),ZPLANEP(IPL2), +* & ZPLANEP(IPL3),ZPLANEP(IPL4) +* PRINT *,' CONST= ',CONST + +* * Fit des traces apres l'absorbeur + CALL PREC_FIT (PXZINVI,PHII,ALAMI,XVR,YVR, + & PXZINVF,PHIF,ALAMF,XVERTF,YVERTF,EPXZINV,EPHI,EALAM, + & EXVERT,EYVERT) + +* * Correction de Branson + CALL BRANSON(PXZEA,PHIEA,ALAMEA,XEA,YEA) + + PXZ1 = DABS(PXZEA) + PX1 = PXZ1*DSIN(PHIEA) + PY1 = PXZ1*DTAN(ALAMEA) + PT1 = DSQRT(PX1**2+PY1**2) + +* print*,'pt1=',pt1 +* print*,'ptcut=',ptcut +* print*,'chi2=',CHI2/FLOAT(2*NPLU-5) +* print*,'chi2cut=',CHI2CUT + +* * Cuts PT + IF (PT1.LT.PTCUT) GO TO 66 +* * Cuts CHI2 + IF ((CHI2/FLOAT(2*NPLU-5)).GT.CHI2CUT) GO TO 66 + + PXZOUT(NTR) = PXZEA + TPHIOUT(NTR) = DTAN(PHIEA) + TALAMOUT(NTR) = DTAN(ALAMEA) + CHI2OUT(NTR) = CHI2/FLOAT(2*NPLU-5) + + ISIGNR(NTR) = 1 + IF (PXZOUT(NTR).LT.0.) ISIGNR(NTR) = -1 + PXZ = ABS(PXZOUT(NTR)) + PHI = ATAN(TPHIOUT(NTR)) + ALAM = ATAN(TALAMOUT(NTR)) + PYR(NTR) = PXZ*SIN(PHI) + PXR(NTR) = PXZ*TAN(ALAM) + PZR(NTR) = PXZ*COS(PHI) + + 66 CONTINUE + + return + end + + SUBROUTINE SORTZV (A,INDEX,N1,MODE,NWAY,NSORT) +C +C CERN PROGLIB# M101 SORTZV .VERSION KERNFOR 3.15 820113 +C ORIG. 02/10/75 +C + DIMENSION A(N1),INDEX(N1) +C +C + N = N1 + IF (N.LE.0) RETURN + IF (NSORT.NE.0) GO TO 2 + DO 1 I=1,N + 1 INDEX(I)=I +C + 2 IF (N.EQ.1) RETURN + IF (MODE) 10,20,30 + 10 CALL SORTTI (A,INDEX,N) + GO TO 40 +C + 20 CALL SORTTC(A,INDEX,N) + GO TO 40 +C + 30 CALL SORTTF (A,INDEX,N) +C + 40 IF (NWAY.EQ.0) GO TO 50 + N2 = N/2 + DO 41 I=1,N2 + ISWAP = INDEX(I) + K = N+1-I + INDEX(I) = INDEX(K) + 41 INDEX(K) = ISWAP + 50 RETURN + END + + SUBROUTINE SORTTI (A,INDEX,N1) +C + INTEGER A,AI + DIMENSION A(N1),INDEX(N1) +C + N = N1 + DO 3 I1=2,N + I3 = I1 + I33 = INDEX(I3) + AI = A(I33) + 1 I2 = I3/2 + IF (I2) 3,3,2 + 2 I22 = INDEX(I2) + IF (AI.LE.A (I22)) GO TO 3 + INDEX (I3) = I22 + I3 = I2 + GO TO 1 + 3 INDEX (I3) = I33 + 4 I3 = INDEX (N) + INDEX (N) = INDEX (1) + AI = A(I3) + N = N-1 + IF (N-1) 12,12,5 + 5 I1 = 1 + 6 I2 = I1 + I1 + IF (I2.LE.N) I22= INDEX(I2) + IF (I2-N) 7,9,11 + 7 I222 = INDEX (I2+1) + IF (A(I22)-A(I222)) 8,9,9 + 8 I2 = I2+1 + I22 = I222 + 9 IF (AI-A(I22)) 10,11,11 + 10 INDEX(I1) = I22 + I1 = I2 + GO TO 6 + 11 INDEX (I1) = I3 + GO TO 4 + 12 INDEX (1) = I3 + RETURN + END + +* ======================================== + SUBROUTINE SORTTC (A,INDEX,N1) +C + INTEGER A,AI + DIMENSION A(N1),INDEX(N1) +C + N = N1 + DO 3 I1=2,N + I3 = I1 + I33 = INDEX(I3) + AI = A(I33) + 1 I2 = I3/2 + IF (I2) 3,3,2 + 2 I22 = INDEX(I2) + IF(ICMPCH(AI,A(I22)))3,3,21 + 21 INDEX (I3) = I22 + I3 = I2 + GO TO 1 + 3 INDEX (I3) = I33 + 4 I3 = INDEX (N) + INDEX (N) = INDEX (1) + AI = A(I3) + N = N-1 + IF (N-1) 12,12,5 + 5 I1 = 1 + 6 I2 = I1 + I1 + IF (I2.LE.N) I22= INDEX(I2) + IF (I2-N) 7,9,11 + 7 I222 = INDEX (I2+1) + IF (ICMPCH(A(I22),A(I222))) 8,9,9 + 8 I2 = I2+1 + I22 = I222 + 9 IF (ICMPCH(AI,A(I22))) 10,11,11 + 10 INDEX(I1) = I22 + I1 = I2 + GO TO 6 + 11 INDEX (I1) = I3 + GO TO 4 + 12 INDEX (1) = I3 + RETURN + END +* ======================================== + FUNCTION ICMPCH(IC1,IC2) +C FUNCTION TO COMPARE TWO 4 CHARACTER EBCDIC STRINGS - IC1,IC2 +C ICMPCH=-1 IF HEX VALUE OF IC1 IS LESS THAN IC2 +C ICMPCH=0 IF HEX VALUES OF IC1 AND IC2 ARE THE SAME +C ICMPCH=+1 IF HEX VALUES OF IC1 IS GREATER THAN IC2 + I1=IC1 + I2=IC2 + IF(I1.GE.0.AND.I2.GE.0)GOTO 40 + IF(I1.GE.0)GOTO 60 + IF(I2.GE.0)GOTO 80 + I1=-I1 + I2=-I2 + IF(I1-I2)80,70,60 + 40 IF(I1-I2)60,70,80 + 60 ICMPCH=-1 + RETURN + 70 ICMPCH=0 + RETURN + 80 ICMPCH=1 + RETURN + END + + SUBROUTINE SORTTF (A,INDEX,N1) +C + DIMENSION A(N1),INDEX(N1) +C + N = N1 + DO 3 I1=2,N + I3 = I1 + I33 = INDEX(I3) + AI = A(I33) + 1 I2 = I3/2 + IF (I2) 3,3,2 + 2 I22 = INDEX(I2) + IF (AI.LE.A (I22)) GO TO 3 + INDEX (I3) = I22 + I3 = I2 + GO TO 1 + 3 INDEX (I3) = I33 + 4 I3 = INDEX (N) + INDEX (N) = INDEX (1) + AI = A(I3) + N = N-1 + IF (N-1) 12,12,5 + 5 I1 = 1 + 6 I2 = I1 + I1 + IF (I2.LE.N) I22= INDEX(I2) + IF (I2-N) 7,9,11 + 7 I222 = INDEX (I2+1) + IF (A(I22)-A(I222)) 8,9,9 + 8 I2 = I2+1 + I22 = I222 + 9 IF (AI-A(I22)) 10,11,11 + 10 INDEX(I1) = I22 + I1 = I2 + GO TO 6 + 11 INDEX (I1) = I3 + GO TO 4 + 12 INDEX (1) = I3 + RETURN + END -- 2.43.0