/* $Id$ */
-////////////////////////////////////
-//
-// MUON cluster reconstructor for MUON
-//
-// Should implement a virtual class ClusterFinder to chose between VS and AZ method
-////////////////////////////////////
+//-----------------------------------------------------------------------------
+/// \class AliMUONClusterReconstructor
+///
+/// This class is just a steering class to loop over detection elements of tracking chambers,
+/// extract the relevant digits, and pass them to the actual clusterizer class,
+/// which operate on a single detection element at a time.
+///
+/// \author C. Finck and L. Aphecetche, Subatech
+///
+//-----------------------------------------------------------------------------
#include "AliMUONClusterReconstructor.h"
-#include "AliRun.h" // for gAlice
-#include "AliRunLoader.h"
-#include "AliLoader.h"
-#include "AliMUON.h"
-#include "AliMUONDigit.h"
-#include "AliMUONConstants.h"
-#include "AliMUONData.h"
-#include "AliMUONClusterFinderVS.h"
-#include "AliMUONClusterInput.h"
-#include "AliMUONRawCluster.h"
-#include "AliRawReader.h" // for raw data
#include "AliLog.h"
-
-
-const Int_t AliMUONClusterReconstructor::fgkDefaultPrintLevel = 0;
-
+#include "AliMUONCluster.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONRawCluster.h"
+#include "AliMUONVClusterFinder.h"
+#include "AliMUONVClusterStore.h"
+#include "AliMUONVDigit.h"
+#include "AliMUONVDigitStore.h"
+#include "AliMpDEIterator.h"
+#include "AliMpDEManager.h"
+#include "AliMpSegmentation.h"
+#include <Riostream.h>
+
+/// \cond CLASSIMP
ClassImp(AliMUONClusterReconstructor) // Class implementation in ROOT context
-
-//__________________________________________________________________________
-AliMUONClusterReconstructor::AliMUONClusterReconstructor(AliLoader* loader)
- : TObject(),
- fMUONData(0),
- fPrintLevel(fgkDefaultPrintLevel),
- fDebug(0)
-{
- // Standard Constructor
-
- // initialize loader's
- fLoader = loader;
-
- // initialize container
- fMUONData = new AliMUONData(fLoader,"MUON","MUON");
-
- // reconstruction model
- fRecModel = new AliMUONClusterFinderVS();
- //fRecModel = new AliMUONClusterFinderAZ();
-
-}
-
+/// \endcond
+
//__________________________________________________________________________
-AliMUONClusterReconstructor::AliMUONClusterReconstructor()
- : TObject(),
- fMUONData(0),
- fPrintLevel(fgkDefaultPrintLevel),
- fDebug(0),
- fLoader(0)
-{
- // Default Constructor
-}
-
-//_______________________________________________________________________
-AliMUONClusterReconstructor::AliMUONClusterReconstructor (const AliMUONClusterReconstructor& rhs)
- : TObject(rhs)
-{
-// Protected copy constructor
-
- AliFatal("Not implemented.");
-}
-
-//_______________________________________________________________________
-AliMUONClusterReconstructor &
-AliMUONClusterReconstructor::operator=(const AliMUONClusterReconstructor& rhs)
+AliMUONClusterReconstructor::AliMUONClusterReconstructor(AliMUONVClusterFinder* clusterFinder,
+ const AliMUONGeometryTransformer* transformer)
+: TObject(),
+ fClusterFinder(clusterFinder),
+ fTransformer(transformer),
+ fClusterStore(0x0)
{
-// Protected assignement operator
-
- if (this == &rhs) return *this;
-
- AliFatal("Not implemented.");
-
- return *this;
+ /// Standard Constructor
+ /// Note that we adopt clusterFinder
+
+ if (!transformer && clusterFinder)
+ {
+ AliFatal("I require a geometry transformer, otherwise I cannot compute "
+ "global coordinates of the clusters !");
+ }
+
+// fRecModel->SetGhostChi2Cut(10);
}
//__________________________________________________________________________
AliMUONClusterReconstructor::~AliMUONClusterReconstructor(void)
{
-
- if (fMUONData)
- delete fMUONData;
-
- return;
-}
-//____________________________________________________________________
-void AliMUONClusterReconstructor::Digits2Clusters()
-{
-//
-// Perform cluster finding
-//
-
- AliMUON* pMUON = (AliMUON*) gAlice->GetModule("MUON");
- if (pMUON->WhichSegmentation() == 1)
- Digits2ClustersOld();
- else
- Digits2ClustersNew();
-
+ /// Destructor
+ delete fClusterFinder;
}
-//____________________________________________________________________
-void AliMUONClusterReconstructor::Digits2ClustersOld()
-{
-//
-// Perform cluster finding
-//
- TClonesArray *dig1, *dig2;
- Int_t ndig, k;
- dig1 = new TClonesArray("AliMUONDigit",1000);
- dig2 = new TClonesArray("AliMUONDigit",1000);
- AliMUONDigit *digit;
-
-// Loop on chambers and on cathode planes
- TClonesArray * muonDigits;
-
- for (Int_t ich = 0; ich < 10; ich++) {
-
- fMUONData->ResetDigits();
- fMUONData->GetCathode(0);
- //TClonesArray *
- muonDigits = fMUONData->Digits(ich);
- ndig=muonDigits->GetEntriesFast();
- AliDebug(1,Form("1 Found %d digits in %p chamber %d", ndig, (void*)muonDigits,ich));
- TClonesArray &lhits1 = *dig1;
- Int_t n = 0;
- for (k = 0; k < ndig; k++) {
- digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
- new(lhits1[n++]) AliMUONDigit(*digit);
- }
- fMUONData->ResetDigits();
- fMUONData->GetCathode(1);
- muonDigits = fMUONData->Digits(ich);
- ndig=muonDigits->GetEntriesFast();
- AliDebug(1,Form("2 Found %d digits in %p %d", ndig, (void*)muonDigits, ich));
- TClonesArray &lhits2 = *dig2;
- n=0;
-
- for (k=0; k<ndig; k++) {
- digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
- new(lhits2[n++]) AliMUONDigit(*digit);
- }
-
- if (fRecModel) {
- AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
- fRecModel->FindRawClusters();
- }
- // copy into the container
- TClonesArray* tmp = fRecModel->GetRawClusters();
- for (Int_t id = 0; id < tmp->GetEntriesFast(); id++) {
- AliMUONRawCluster* pClus = (AliMUONRawCluster*) tmp->At(id);
- fMUONData->AddRawCluster(ich, *pClus);
- }
- dig1->Delete();
- dig2->Delete();
- } // for ich
- delete dig1;
- delete dig2;
-}
-//____________________________________________________________________
-void AliMUONClusterReconstructor::Digits2ClustersNew()
+//______________________________________________________________________________
+void
+AliMUONClusterReconstructor::ClusterizeOneDE(Int_t detElemId,
+ const AliMUONVDigitStore& digitStore)
{
-
- TClonesArray *dig1, *dig2, *digAll;
- Int_t ndig, k, idDE, idDE_prev;
- dig1 = new TClonesArray("AliMUONDigit",1000);
- dig2 = new TClonesArray("AliMUONDigit",1000);
- digAll = new TClonesArray("AliMUONDigit",2000);
-
- AliMUONDigit* digit;
-
- TArrayI id(200); // contains the different IdDE
-
+ /// Clusterize one detection element, which digits are in digitStore
-// Loop on chambers and on cathode planes
- TClonesArray* muonDigits;
- Int_t n2;
- Int_t n1;
- Int_t flag = 0;
-
- for (Int_t ich = 0; ich < AliMUONConstants::NTrackingCh(); ich++) {
-
- id.Reset();
- n1 = 0;
- n2 = 0;
- //cathode 0
- fMUONData->ResetDigits();
- fMUONData->GetCathode(0);
- muonDigits = fMUONData->Digits(ich);
- ndig = muonDigits->GetEntriesFast();
- TClonesArray &lDigit = *digAll;
-
- idDE_prev = 0;
-
- for (k = 0; k < ndig; k++) {
-
- digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
- new(lDigit[n1++]) AliMUONDigit(*digit);
- idDE = digit->DetElemId();
- if (idDE != idDE_prev) {
- id.AddAt(idDE,n2++);
- }
- idDE_prev = idDE;
- }
-
- //cathode 1
- fMUONData->ResetDigits();
- fMUONData->GetCathode(1);
- muonDigits = fMUONData->Digits(ich);
- ndig = muonDigits->GetEntriesFast();
-
- Int_t idSize = n2;
+// AliDebug(1,Form("detElemId=%d, %d digits",detElemId,digitStore.GetSize()));
+
+ if ( digitStore.IsEmpty() ) return;
+
+ const AliMpVSegmentation* seg[2] =
+ { AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0),
+ AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath1)
+ };
- for (k = 0; k < ndig; k++) {
-
- digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
- new(lDigit[n1++]) AliMUONDigit(*digit);
- idDE = digit->DetElemId();
- flag = 0;
-
- // looking for new idDE in cathode 1 (method to be checked CF)
- for (Int_t n = 0; n < idSize; n++) {
- if (idDE == id[n]) {
- flag = 1;
- break;
- }
- }
- if (flag) continue;
- id.AddAt(idDE,n2++);
+ Bool_t ok = fClusterFinder->Prepare(seg,digitStore);
+ if ( !ok )
+ {
+ AliWarning(Form("No hit pad for DE %d ?",detElemId));
+ }
+
+ AliMUONCluster* cluster;
+
+ while ( ( cluster = fClusterFinder->NextCluster() ) )
+ {
+ // Converts cluster objects into ones suitable for output
+ //
+ AliMUONRawCluster rawCluster;
+
+ rawCluster.SetDetElemId(detElemId);
+
+ for ( Int_t cathode = 0; cathode < 2; ++cathode )
+ {
+ rawCluster.SetMultiplicity(cathode,cluster->Multiplicity(cathode));
+ rawCluster.SetCharge(cathode,cluster->Charge()); // both cathode get the total cluster charge
+ Double_t xg, yg, zg;
+
+ fTransformer->Local2Global(detElemId,
+ cluster->Position().X(), cluster->Position().Y(),
+ 0, xg, yg, zg);
+
+ if ( cathode == 0 )
+ {
+ AliDebug(1,Form("Adding RawCluster detElemId %4d mult %2d charge %e (xl,yl,zl)=(%e,%e,%e) (xg,yg,zg)=(%e,%e,%e)",
+ detElemId,cluster->Multiplicity(),cluster->Charge(),
+ cluster->Position().X(),cluster->Position().Y(),0.0,
+ xg,yg,zg));
}
-
- idSize = n2;
-
- // loop over id DE
- for (idDE = 0; idDE < idSize; idDE++) {
- TClonesArray &lhits1 = *dig1;
- TClonesArray &lhits2 = *dig2;
- n1 = n2 = 0;
- // printf("idDE %d\n", id[idDE]);
-
- for (k = 0; k < digAll->GetEntriesFast(); k++) {
- digit = (AliMUONDigit*) digAll->UncheckedAt(k);
- // printf("digit idDE %d\n", digit->DetElemId());
- if (id[idDE] == digit->DetElemId()) {
- if (digit->Cathode() == 1)
- new(lhits1[n1++]) AliMUONDigit(*digit);
- else
- new(lhits2[n2++]) AliMUONDigit(*digit);
- }
- }
-
- // cluster finder
- if (fRecModel) {
- AliMUONClusterInput::Instance()->SetDigits(ich, id[idDE], dig1, dig2);
- fRecModel->FindRawClusters();
- }
- // copy into the container
- TClonesArray* tmp = fRecModel->GetRawClusters();
- for (Int_t id = 0; id < tmp->GetEntriesFast(); id++) {
- AliMUONRawCluster* pClus = (AliMUONRawCluster*) tmp->At(id);
- fMUONData->AddRawCluster(ich, *pClus);
- }
- dig1->Delete();
- dig2->Delete();
-
- } // idDE
- digAll->Delete();
- } // for ich
- delete dig1;
- delete dig2;
- delete digAll;
+ rawCluster.SetX(cathode,xg);
+ rawCluster.SetY(cathode,yg);
+ rawCluster.SetZ(cathode,zg);
+ }
+ fClusterStore->Add(rawCluster);
+ }
}
//____________________________________________________________________
-void AliMUONClusterReconstructor::Digits2Clusters(AliRawReader* /*rawReader*/)
-{
-
-// Perform cluster finding form raw data
-
- AliFatal("clusterization not implemented for raw data input");
-}
-//_______________________________________________________________________
-void AliMUONClusterReconstructor::Trigger2Trigger()
-{
-// copy trigger from TreeD to TreeR
-
- fMUONData->SetTreeAddress("GLT");
- fMUONData->GetTriggerD();
-}
-//_______________________________________________________________________
-void AliMUONClusterReconstructor::Trigger2Trigger(AliRawReader* /*rawReader*/)
+void AliMUONClusterReconstructor::Digits2Clusters(const AliMUONVDigitStore& digitStore,
+ AliMUONVClusterStore& clusterStore)
{
-// call the Trigger Algorithm from raw data and fill TreeR
-
- AliFatal("Trigger not implemented for raw data input");
-
+ /// Clusterize the digitStore to produce a clusterStore
+
+ fClusterStore = &clusterStore;
+ fClusterStore->Clear();
+
+ AliMpDEIterator deIt;
+
+ deIt.First();
+
+ while (!deIt.IsDone())
+ {
+ AliMUONVDigitStore* deDigits = digitStore.Create();
+
+ Int_t currentDE = deIt.CurrentDEId();
+ AliMp::StationType stationType = AliMpDEManager::GetStationType(currentDE);
+ if (stationType!=AliMp::kStationTrigger)
+ {
+ TIter next(digitStore.CreateIterator(currentDE,currentDE));
+ AliMUONVDigit* digit;
+
+ while ( ( digit = static_cast<AliMUONVDigit*>(next()) ) )
+ {
+ if ( ! digit->Charge() > 0 ) continue; // skip void digits.
+
+ deDigits->Add(*digit,AliMUONVDigitStore::kIgnore);
+ }
+ ClusterizeOneDE(currentDE,*deDigits);
+ }
+ delete deDigits;
+ deIt.Next();
+ }
}