1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 // -----------------------------------
19 // Class AliMUONClusterReconstructor
20 // ----------------------------------
21 // MUON cluster reconstructor for MUON
22 // Should implement a virtual class ClusterFinder to choose between VS and AZ method
24 #include <Riostream.h>
25 #include "AliMUONClusterReconstructor.h"
26 #include "AliRunLoader.h"
27 #include "AliLoader.h"
29 #include "AliMUONDigit.h"
30 #include "AliMUONConstants.h"
31 #include "AliMUONData.h"
32 #include "AliMUONClusterFinderVS.h"
33 #include "AliMUONClusterInput.h"
34 #include "AliMUONRawCluster.h"
35 #include "AliMUONVClusterFinder.h"
36 #include "AliMUONCluster.h"
37 #include "AliMpDEManager.h"
38 #include "AliMpSegmentation.h"
39 #include "AliMpCathodType.h"
40 #include "AliMUONGeometryTransformer.h"
44 ClassImp(AliMUONClusterReconstructor) // Class implementation in ROOT context
47 //__________________________________________________________________________
48 AliMUONClusterReconstructor::AliMUONClusterReconstructor(AliMUONData* data,
49 AliMUONVClusterFinder* clusterFinder,
50 const AliMUONGeometryTransformer* transformer)
52 fClusterFinder(clusterFinder),
54 fRecModel(new AliMUONClusterFinderVS()),
55 fDigitsCath0(new TClonesArray("AliMUONDigit",1000)),
56 fDigitsCath1(new TClonesArray("AliMUONDigit",1000)),
57 fTransformer(transformer)
59 /// Standard Constructor
61 fDigitsCath0->SetOwner(kTRUE);
62 fDigitsCath1->SetOwner(kTRUE);
63 if (!transformer && clusterFinder)
65 AliFatal("I require a geometry transformer, otherwise I cannot compute "
66 "global coordinates of the clusters !");
70 //__________________________________________________________________________
71 AliMUONClusterReconstructor::~AliMUONClusterReconstructor(void)
80 //______________________________________________________________________________
82 AliMUONClusterReconstructor::ClusterizeOneDEV2(Int_t detElemId)
84 /// Clusterize one detection element, and let fMUONData know about
87 AliDebug(1,Form("DE %d",detElemId));
88 const AliMpVSegmentation* seg[2] =
89 { AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0),
90 AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath1)
94 TClonesArray* digits[2] = { fDigitsCath0, fDigitsCath1 };
96 Bool_t ok = fClusterFinder->Prepare(seg,digits);
99 AliWarning(Form("No hit pad for DE %d ?",detElemId));
102 AliMUONCluster* cluster;
104 Int_t chamber = detElemId/100 - 1;
106 while ( ( cluster = fClusterFinder->NextCluster() ) )
108 // StdoutToAliDebug(1,cout << "From AliMUONClusterReconstructor::ClusterizeOneDEV2 : cluster->Print():" << endl;
109 // cluster->Print(););
111 // Converts cluster objects into ones suitable for output
113 AliMUONRawCluster rawCluster;
115 rawCluster.SetDetElemId(detElemId);
117 for ( Int_t cathode = 0; cathode < 2; ++cathode )
119 rawCluster.SetMultiplicity(cathode,cluster->Multiplicity(cathode));
120 rawCluster.SetCharge(cathode,cluster->Charge()); // both cathode get the total cluster charge
123 fTransformer->Local2Global(detElemId,
124 cluster->Position().X(), cluster->Position().Y(),
129 AliDebug(1,Form("Adding RawCluster detElemId %4d mult %2d charge %e (xl,yl,zl)=(%e,%e,%e) (xg,yg,zg)=(%e,%e,%e)",
130 detElemId,cluster->Multiplicity(),cluster->Charge(),
131 cluster->Position().X(),cluster->Position().Y(),0.0,
134 rawCluster.SetX(cathode,xg);
135 rawCluster.SetY(cathode,yg);
136 rawCluster.SetZ(cathode,zg);
138 fMUONData->AddRawCluster(chamber,rawCluster);
142 //______________________________________________________________________________
144 AliMUONClusterReconstructor::ClusterizeOneDE(Int_t detElemId)
146 /// Clusterize one detection element, and let fMUONData know about
149 if ( fDigitsCath0->GetEntriesFast() || fDigitsCath1->GetEntriesFast() )
151 if ( fClusterFinder )
153 ClusterizeOneDEV2(detElemId);
157 Int_t iChamber = AliMpDEManager::GetChamberId(detElemId);
158 AliMUONClusterInput::Instance()->SetDigits(iChamber, detElemId,
159 fDigitsCath0,fDigitsCath1);
160 AliDebug(3,Form("ClusterizeOneDE iChamber=%d DE=%d",iChamber,detElemId));
161 // StdoutToAliDebug(3,cout << "DigitsCath0=" << endl;
162 // fDigitsCath0->Print();
163 // cout << "DigitsCath1=" << endl;
164 // fDigitsCath1->Print(););
165 fRecModel->FindRawClusters();
167 // copy results into the output container
168 TClonesArray* tmp = fRecModel->GetRawClusters();
169 for (Int_t id = 0; id < tmp->GetEntriesFast(); ++id)
171 AliMUONRawCluster* pClus = (AliMUONRawCluster*) tmp->At(id);
172 fMUONData->AddRawCluster(iChamber, *pClus);
176 fDigitsCath0->Clear("C");
177 fDigitsCath1->Clear("C");
181 //____________________________________________________________________
182 void AliMUONClusterReconstructor::Digits2Clusters(Int_t chBeg)
184 /// Clusterize all the tracking chamber digits.
186 /// For each chamber, we loop *once* on that chamber digits, and store them
187 /// in 2 temporary arrays (one pair of arrays per detection element,
188 /// one array per cathode). Once a pair of arrays is full (i.e. all the digits
189 /// of that detection element have been stored), we clusterize this DE, and
190 /// move to the next one.
192 if (!fRecModel && !fClusterFinder)
194 AliWarning("No reco model defined. Nothing to do...");
202 for ( iChamber = chBeg; iChamber < AliMUONConstants::NTrackingCh(); ++iChamber )
204 TClonesArray* muonDigits = fMUONData->Digits(iChamber);
206 Int_t ndig = muonDigits->GetEntriesFast();
209 muonDigits->Sort(); // the sort *must* be per DE (at least), otherwise
210 // the following logic with currentDE will fail.
212 currentDE = -1; // initialize the DE counter (that is used to track
213 // when we change of DE in the following loop over
214 // all digits) to an invalid value.
216 for ( Int_t k = 0; k < ndig; ++k )
218 AliMUONDigit* digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
219 if ( ! digit->Signal() > 0 ) continue; // skip void digits.
221 if ( digit->DetElemId() != currentDE )
223 AliDebug(3,Form("Switching DE from %d to %d",currentDE,digit->DetElemId()));
224 // we get to a new DE, so clusterize the previous one before
226 ClusterizeOneDE(currentDE);
227 currentDE = digit->DetElemId();
230 // Add the digit to the array with the right cathode number.
231 if (digit->Cathode() == 0)
233 new((*fDigitsCath0)[fDigitsCath0->GetLast()+1]) AliMUONDigit(*digit);
237 new((*fDigitsCath1)[fDigitsCath1->GetLast()+1]) AliMUONDigit(*digit);
239 } // end of loop on chamber digits
241 // As the above logic is based on detecting a change in DE number,
242 // the last DE of each chamber has not been clusterized, so we do
244 ClusterizeOneDE(currentDE);
245 } // end of loop over chambers
248 //_______________________________________________________________________
250 AliMUONClusterReconstructor::SetRecoModel(AliMUONClusterFinderVS* rec)
252 /// Set reconstruction model
258 //_______________________________________________________________________
259 void AliMUONClusterReconstructor::Trigger2Trigger()
261 /// Copy trigger from TreeD to TreeR
263 fMUONData->SetTreeAddress("GLT");
264 fMUONData->GetTriggerD();