- Implementing the possibility to histogram the raw adc values when reading
authorivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 8 Feb 2008 13:31:18 +0000 (13:31 +0000)
committerivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 8 Feb 2008 13:31:18 +0000 (13:31 +0000)
  raw data.
- General speed improvement
- Corrected a bug (using a 2DMap where a 1DMap was needed) that lead to very
  poor data reading performance.
- Added new class AliMUONSparseHisto to hold adc values in the most compact
  way possible (used later on by AliMUONTrackerData to generate TH1 histograms)
- Moved generation of calibrated data to its own class
  AliMUONTrackerCalibratedDataMaker, in order not to slow
  down the plain raw data reading (made in AliMUONTrackerRawDataMaker)
(Laurent)

17 files changed:
MUON/AliMUONMchViewApplication.h
MUON/AliMUONPainterDataSourceFrame.cxx
MUON/AliMUONPainterDataSourceFrame.h
MUON/AliMUONPainterMasterFrame.cxx
MUON/AliMUONSparseHisto.cxx [new file with mode: 0644]
MUON/AliMUONSparseHisto.h [new file with mode: 0644]
MUON/AliMUONTrackerCalibratedDataMaker.cxx [new file with mode: 0644]
MUON/AliMUONTrackerCalibratedDataMaker.h [new file with mode: 0644]
MUON/AliMUONTrackerData.cxx
MUON/AliMUONTrackerData.h
MUON/AliMUONTrackerRawDataMaker.cxx
MUON/AliMUONTrackerRawDataMaker.h
MUON/AliMUONVTrackerData.cxx
MUON/AliMUONVTrackerData.h
MUON/MUONgraphicsLinkDef.h
MUON/READMEmchview.txt
MUON/libMUONgraphics.pkg

index 9fc4f55..24ceac1 100644 (file)
@@ -33,7 +33,7 @@ public:
   void HandleMenu(Int_t i);
 
   /// Return the version number of the mchview application
-  static const char* Version() { return "0.8"; }
+  static const char* Version() { return "0.9"; }
   
 private:
   /// Not implemented
index f00e379..2cc0428 100644 (file)
 
 #include "AliMUONPainterDataSourceFrame.h"
 
+
+#include "AliLog.h"
 #include "AliMUONPainterDataSourceItem.h"
 #include "AliMUONPainterEnv.h"
 #include "AliMUONPainterHelper.h"
 #include "AliMUONPainterRegistry.h"
+#include "AliMUONTrackerCalibratedDataMaker.h"
 #include "AliMUONTrackerOCDBDataMaker.h"
 #include "AliMUONTrackerRawDataMaker.h"
-#include "AliMUONVTrackerDataMaker.h"
-#include "AliLog.h"
 #include "AliRawReaderDate.h"
 #include "AliRawReaderRoot.h"
 #include <TGButton.h>
@@ -59,10 +60,16 @@ AliMUONPainterDataSourceFrame::AliMUONPainterDataSourceFrame(const TGWindow* p,
 : TGCompositeFrame(p,w,h,kVerticalFrame),
   fRecentSourceSelector(new TGGroupFrame(p,"Recent sources",kHorizontalFrame)),
   fRawSelector(new TGGroupFrame(p,"Raw file URI",kHorizontalFrame)),
+  fRawSelector2(new TGCompositeFrame(fRawSelector,w,h,kVerticalFrame)),
+  fRawSelector21(new TGCompositeFrame(fRawSelector2,w,h,kHorizontalFrame)),
+  fRawSelector22(new TGCompositeFrame(fRawSelector2,w,h,kHorizontalFrame)),
+  fRawSelector23(new TGCompositeFrame(fRawSelector2,w,h,kHorizontalFrame)),
+  fCalibrateButton(new TGCheckButton(fRawSelector22,"Calibrate")),
+  fHistogramButton(new TGCheckButton(fRawSelector23,"Histogram")),
+  fRawOCDBPath(new TGTextEntry(fRawSelector22,"")),
   fOCDBSelector(new TGGroupFrame(p,"OCDB Path",kHorizontalFrame)),
   fDataReaders(new TGGroupFrame(p,"Data sources")),
-  fFilePath(new TGTextEntry(fRawSelector,"")),
-  fRawOCDBPath(new TGTextEntry(fRawSelector,"")),
+  fFilePath(new TGTextEntry(fRawSelector21,"")),
   fOCDBPath(new TGTextEntry(fOCDBSelector,"")),
   fRunSelector(new TGNumberEntry(fOCDBSelector,0)),
   fOCDBTypes(new TGComboBox(fOCDBSelector)),
@@ -109,17 +116,33 @@ AliMUONPainterDataSourceFrame::AliMUONPainterDataSourceFrame(const TGWindow* p,
                                     
     /// Raw file selection
     
-    TGButton* openButton = new TGPictureButton(fRawSelector,
+    TGButton* openButton = new TGPictureButton(fRawSelector21,
                                            gClient->GetPicture("fileopen.xpm"));
     openButton->SetToolTipText("Click to open file dialog");
                                         
-    TGButton* createRawButton = new TGTextButton(fRawSelector,"Create data source");
+    fRawSelector2->AddFrame(fRawSelector21, new TGLayoutHints(kLHintsExpandX,5,5,5,5));
+    fRawSelector2->AddFrame(fRawSelector22, new TGLayoutHints(kLHintsExpandX,5,5,5,5));
+    fRawSelector2->AddFrame(fRawSelector23, new TGLayoutHints(kLHintsExpandX,5,5,5,5));
+
+    fRawSelector21->AddFrame(openButton,new TGLayoutHints(kLHintsTop,5,5,5,5));
+    fRawSelector21->AddFrame(fFilePath, new TGLayoutHints(kLHintsExpandX | kLHintsTop,5,5,5,5));
+
+    fRawSelector22->AddFrame(fCalibrateButton, new TGLayoutHints(kLHintsTop,5,5,5,5));
+    fRawSelector22->AddFrame(fRawOCDBPath, new TGLayoutHints(kLHintsExpandX | kLHintsTop,5,5,5,5));
+    fRawOCDBPath->SetEnabled(kFALSE);
     
-    fRawSelector->AddFrame(fFilePath, new TGLayoutHints(kLHintsExpandX | kLHintsTop,5,5,5,5));
-    fRawSelector->AddFrame(fRawOCDBPath, new TGLayoutHints(kLHintsTop,5,5,5,5));
-    fRawSelector->AddFrame(openButton,new TGLayoutHints(kLHintsTop,5,5,5,5));
-    fRawSelector->AddFrame(createRawButton,new TGLayoutHints(kLHintsTop,5,5,5,5));
+    fRawSelector23->AddFrame(fHistogramButton,new TGLayoutHints(kLHintsTop,5,5,5,5));
+
+    TGButton* createRawButton = new TGTextButton(fRawSelector,"Create data source");
     
+    fRawSelector->AddFrame(fRawSelector2, new TGLayoutHints(kLHintsExpandX | kLHintsTop,5,5,5,5));
+    fRawSelector->AddFrame(createRawButton, new TGLayoutHints(kLHintsCenterY,5,5,5,5));
+        
+    fCalibrateButton->Connect("Clicked()",
+                              "AliMUONPainterDataSourceFrame",
+                              this,
+                              "CalibrateButtonClicked()");
+
     openButton->Connect("Clicked()",
                         "AliMUONPainterDataSourceFrame",
                         this,
@@ -191,6 +214,25 @@ AliMUONPainterDataSourceFrame::AddRecentSource(const char* name)
   fRecentSources->Layout();
 }
 
+//_____________________________________________________________________________
+void
+AliMUONPainterDataSourceFrame::CalibrateButtonClicked()
+{
+  /// Calibrate button was clicked.
+  
+  if ( fCalibrateButton->IsOn() ) 
+  {
+    fRawOCDBPath->SetEnabled(kTRUE);
+    fRawOCDBPath->SetFocus();
+    fHistogramButton->SetEnabled(kFALSE);
+  }
+  else
+  {
+    fRawOCDBPath->SetEnabled(kFALSE);
+    fHistogramButton->SetEnabled(kTRUE);
+  }
+}
+
 //_____________________________________________________________________________
 void
 AliMUONPainterDataSourceFrame::CreateOCDBDataSource()
@@ -271,7 +313,7 @@ AliMUONPainterDataSourceFrame::CreateRawDataSource()
     return;
   }
 
-  uri = Form("RAW;%s;%s",uri.Data(),fRawOCDBPath->GetText());
+  uri = Form("%sRAW;%s;%s",( fHistogramButton->IsOn() ? "H":""),uri.Data(),fRawOCDBPath->GetText());
   
   if ( CreateRawDataSource(uri) )
   {
@@ -325,7 +367,18 @@ AliMUONPainterDataSourceFrame::CreateRawDataSource(const TString& uri)
     return kFALSE;
   }
   
-  AliMUONTrackerRawDataMaker* reader = new AliMUONTrackerRawDataMaker(rawReader,ocdbPath.Data());
+  AliMUONVTrackerDataMaker* reader(0x0);
+  Bool_t histogram(kFALSE);
+  
+  if ( ocdbPath.Length() > 0 ) 
+  {
+    reader = new AliMUONTrackerCalibratedDataMaker(rawReader,ocdbPath.Data());
+  }
+  else
+  {
+    if ( uri.Contains(TRegexp("^H")) ) histogram = kTRUE;
+    reader = new AliMUONTrackerRawDataMaker(rawReader,histogram);
+  }
   
   reader->SetSource(filename.Data());
   
@@ -337,7 +390,7 @@ AliMUONPainterDataSourceFrame::CreateRawDataSource(const TString& uri)
   
   env->Set(fgkNumberOfDataSourcesKey,n+1);
   
-  TString ds(Form("RAW;%s;%s",filename.Data(),ocdbPath.Data()));
+  TString ds(Form("%sRAW;%s;%s",(histogram ? "H":""),filename.Data(),ocdbPath.Data()));
   
   env->Set(Form(fgkDataSourceURIKey,n),ds.Data());
   
@@ -354,8 +407,6 @@ AliMUONPainterDataSourceFrame::DataReaderWasRegistered(AliMUONVTrackerDataMaker*
 {
   /// Update ourselves as a new data reader was created
   
-  AliInfo(Form("%s",reader->GetName()));
-  
   AliMUONPainterDataSourceItem* item = new AliMUONPainterDataSourceItem(fDataReaders,100,20,reader);
       
   fDataReaders->AddFrame(item);
@@ -372,7 +423,7 @@ AliMUONPainterDataSourceFrame::DataReaderWasUnregistered(AliMUONVTrackerDataMake
 {
   /// Update ourselves as a new data reader was deleted
   
-  AliInfo(Form("%s",reader->GetName()));
+//  AliInfo(Form("%s",reader->GetName()));
           
 }
 
@@ -402,7 +453,7 @@ AliMUONPainterDataSourceFrame::OpenRecentSource()
 
   TString uri(t->GetText()->GetString());
   
-  if ( uri.Contains(TRegexp("^RAW")) )
+  if ( uri.Contains(TRegexp("^RAW")) || uri.Contains(TRegexp("^HRAW")) )
   {
     CreateRawDataSource(uri);
   }
index 565f742..e51b20c 100644 (file)
 #  include <TGFrame.h>
 #endif
 
-class TObjArray;
-class TGGroupFrame;
 class AliMUONVTrackerDataMaker;
-class TGTextEntry;
-class TGNumberEntry;
+class TGCheckButton;
 class TGComboBox;
+class TGGroupFrame;
+class TGNumberEntry;
+class TGTextEntry;
+class TObjArray;
 
 class AliMUONPainterDataSourceFrame : public TGCompositeFrame
 {
@@ -29,6 +30,8 @@ public:
   AliMUONPainterDataSourceFrame(const TGWindow* p, UInt_t w, UInt_t h);
   virtual ~AliMUONPainterDataSourceFrame();
   
+  void CalibrateButtonClicked(); 
+  
   void CreateOCDBDataSource();
 
   void CreateRawDataSource();
@@ -58,11 +61,19 @@ private:
 private:
     
   TGGroupFrame* fRecentSourceSelector; ///< to select recently used sources   
+  
   TGGroupFrame* fRawSelector; ///< to select a new raw data source
+  TGCompositeFrame* fRawSelector2; ///< idem
+  TGCompositeFrame* fRawSelector21; ///< idem
+  TGCompositeFrame* fRawSelector22; ///< idem
+  TGCompositeFrame* fRawSelector23; ///< idem
+  TGCheckButton* fCalibrateButton; ///< to trig calibration of raw data
+  TGCheckButton* fHistogramButton; ///< to trig histogramming of raw data
+  TGTextEntry* fRawOCDBPath; ///< OCDB path for raw data calibration
+  
   TGGroupFrame* fOCDBSelector; ///< to select a new OCDB data source
   TGGroupFrame* fDataReaders; ///< to display currently active data sources  
   TGTextEntry* fFilePath; ///< raw data file path text entry widget
-  TGTextEntry* fRawOCDBPath; ///< OCDB path for raw data calibration
   TGTextEntry* fOCDBPath; ///< OCDB path text entry widget
   TGNumberEntry* fRunSelector; ///< OCDB run number entry widget
   TGComboBox* fOCDBTypes; ///< OCDB type combo box entry widget  
@@ -72,7 +83,7 @@ private:
   static const char* fgkNumberOfDataSourcesKey; ///< key used to store the # of data sources in the resource file
   static const char* fgkDataSourceURIKey; ///< key usde to store the data source URIs in the resource file
 
-  ClassDef(AliMUONPainterDataSourceFrame,1) // Data source selection frame
+  ClassDef(AliMUONPainterDataSourceFrame,2) // Data source selection frame
 };
 
 #endif
index 7627879..76ffe77 100644 (file)
@@ -365,11 +365,6 @@ AliMUONPainterMasterFrame::ShiftClicked(AliMUONVPainter* painter, Double_t*)
       return;
     }
     
-    AliInfo(Form("Starting from %s will generate %s and %s",
-                 a.GetName(),
-                 a1.GetName(),
-                 a2.GetName()));
-    
     p1->UpdateGroupsFrom(*(painter->Master()));
     p2->UpdateGroupsFrom(*(painter->Master()));
     
diff --git a/MUON/AliMUONSparseHisto.cxx b/MUON/AliMUONSparseHisto.cxx
new file mode 100644 (file)
index 0000000..68afbfb
--- /dev/null
@@ -0,0 +1,222 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUONSparseHisto.h"
+#include <TString.h>
+#include <Riostream.h>
+#include <TH1.h>
+
+/// \class AliMUONSparseHisto
+///
+/// Tiny histogram-like class to hold adc distributions of tracker data.
+/// Only intent of this class is to minimize memory consumption, in
+/// order to fit a maximum number of channel histograms into memory.
+/// The rest is not supported ;-)
+///
+/// \author Laurent Aphecetche, Subatech
+
+/// \cond CLASSIMP
+ClassImp(AliMUONSparseHisto)
+/// \endcond
+
+//______________________________________________________________________________
+AliMUONSparseHisto::AliMUONSparseHisto()
+: TObject(),
+fNbins(0),
+fArray(0x0)
+{
+  /// ctor
+}
+
+//______________________________________________________________________________
+AliMUONSparseHisto::AliMUONSparseHisto(const AliMUONSparseHisto& rhs)
+: TObject(rhs),
+fNbins(0),
+fArray(0x0)
+{
+  /// copy ctor
+  rhs.Copy(*this);
+}
+
+//______________________________________________________________________________
+AliMUONSparseHisto&
+AliMUONSparseHisto::operator=(const AliMUONSparseHisto& rhs)
+{
+  /// assignment operator
+  if ( this != &rhs )
+  {
+    rhs.Copy(*this);
+  }
+  return *this;
+}
+
+//______________________________________________________________________________
+AliMUONSparseHisto::~AliMUONSparseHisto()
+{
+  /// dtor
+  delete[] fArray;
+}
+
+//______________________________________________________________________________
+void 
+AliMUONSparseHisto::Clear(Option_t*)
+{
+  /// Reset the content
+  delete[] fArray;
+  fArray = 0x0;
+  fNbins = 0;
+}  
+
+//______________________________________________________________________________
+void 
+AliMUONSparseHisto::Copy(TObject& object) const
+{
+  /// Copy this to *object
+  TObject::Copy(object);
+  AliMUONSparseHisto& h = static_cast<AliMUONSparseHisto&>(object);
+  delete[] h.fArray;
+  h.fArray = 0x0;
+  h.fNbins = GetNbins();
+  if ( GetNbins() > 0 )
+  {
+    h.fArray = new Int_t[GetNbins()];
+    for ( Int_t i = 0; i < GetNbins(); ++i ) 
+    {
+      h.fArray[i] = GetBinContent(i);
+    }
+  }
+}
+
+//______________________________________________________________________________
+void 
+AliMUONSparseHisto::Decode(Int_t value, Int_t& adc, Int_t& count) const
+{
+  /// Convert value into (adc,count) pair
+  
+  adc   = ( value & 0xFFF00000 ) >> 20;
+  count = ( value & 0x000FFFFF );
+}
+
+//______________________________________________________________________________
+Int_t 
+AliMUONSparseHisto::Encode(Int_t adc, Int_t count) const
+{
+  /// Convert (adc,count) into a single value
+  return ( ( adc & 0xFFF ) ) << 20 | ( count & 0xFFFFF );
+}
+
+//______________________________________________________________________________
+void 
+AliMUONSparseHisto::Expand()
+{
+  /// Make fArray of size n
+  if (!fArray || !fNbins) 
+  {
+    delete[] fArray;
+    fArray = new Int_t[1];
+    fNbins = 1;
+  }
+  else
+  {
+    Int_t* tmp = new Int_t[fNbins+1];
+    for ( Int_t i = 0; i < fNbins; ++i ) 
+    {
+      tmp[i] = fArray[i];
+    }
+    delete[] fArray;
+    fArray = tmp;
+    ++fNbins;
+  }
+}
+
+//______________________________________________________________________________
+Int_t 
+AliMUONSparseHisto::Fill(Int_t adc)
+{
+  /// Fill
+  
+  if ( adc < 0 || adc > 4095 ) return -1;
+  
+  Int_t i = Find(adc);
+  
+  if ( i < 0 ) 
+  {
+    Int_t n = fNbins;
+    Expand();
+    fArray[n] = Encode(adc,1);
+    i = n;
+  }
+  else
+  {
+    Int_t iadc,icontent;
+    Decode(fArray[i],iadc,icontent);
+    fArray[i] = Encode(adc,icontent+1);
+  }
+    
+  return i;
+}
+
+//______________________________________________________________________________
+Int_t 
+AliMUONSparseHisto::Find(Int_t adc) const
+{
+  /// Return the index in fArray of adc, or -1 if not found
+  for ( Int_t i = 0; i < GetNbins(); ++i ) 
+  {
+    Int_t content = GetBinContent(i);
+    Int_t iadc,value;
+    Decode(content,iadc,value);
+    if ( iadc == adc ) return i;
+  }
+  return -1;
+}
+
+//______________________________________________________________________________
+Int_t 
+AliMUONSparseHisto::GetBinContent(Int_t bin) const
+{
+  /// Get bin content. Note that the content is compacted, so you must
+  /// use Decode() method to get (adc,count) values.
+  if ( bin >= 0 && bin < GetNbins() ) return fArray[bin];
+  return 0;
+}
+
+//______________________________________________________________________________
+void 
+AliMUONSparseHisto::Print(Option_t* opt) const
+{
+  /// Printout
+  Int_t id1 = ( GetUniqueID() & 0xFFFF0000 ) >> 16;
+  Int_t id2 = GetUniqueID() & 0xFFFF;
+  
+  cout << "(" << id1 << "," << id2 << ") n bins = " << GetNbins() << endl;
+  
+  TString sopt(opt);
+  sopt.ToUpper();
+  
+  if ( sopt.Contains("FULL") )
+  {
+    for ( Int_t i = 0; i < GetNbins(); ++i ) 
+    {
+      Int_t content = GetBinContent(i);
+      Int_t adc,value;
+      Decode(content,adc,value);
+      cout << Form("i %4d content %10x adc %4d value %6d",i,content,adc,value)
+        << endl;
+    }
+  }
+}
diff --git a/MUON/AliMUONSparseHisto.h b/MUON/AliMUONSparseHisto.h
new file mode 100644 (file)
index 0000000..af70755
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef ALIMUONSPARSEHISTO_H
+#define ALIMUONSPARSEHISTO_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice                               */
+
+// $Id$
+
+/// \ingroup graphics
+/// \class AliMUONSparseHisto
+/// \brief A very memory compact histogram to hold tracker ADC distributions
+/// 
+// Author Laurent Aphecetche, Subatech
+
+#ifndef ROOT_TObject
+#  include "TObject.h"
+#endif
+
+class AliMUONSparseHisto : public TObject
+{
+public:
+  AliMUONSparseHisto();
+  AliMUONSparseHisto(const AliMUONSparseHisto& rhs);
+  AliMUONSparseHisto& operator=(const AliMUONSparseHisto& rhs);
+  
+  virtual ~AliMUONSparseHisto();
+  
+  Int_t Fill(Int_t adc);
+  
+  /// Return number of bins we hold
+  Int_t GetNbins() const { return fNbins; }
+  
+  Int_t GetBinContent(Int_t bin) const;
+  
+  virtual void Print(Option_t* opt="") const;
+  
+  virtual void Clear(Option_t* opt="");
+  
+  void Decode(Int_t value, Int_t& adc, Int_t& count) const;
+  
+  Int_t Encode(Int_t adc, Int_t count) const;
+  
+  Int_t Find(Int_t adc) const;
+  
+  virtual void Copy(TObject& object) const;
+
+private:
+      
+    void Expand();
+  
+private:
+
+  Int_t fNbins;  ///< number of bins we hold
+
+  /// compacted content = (bin,value)
+  Int_t* fArray; //[fNbins] compacted content = (bin,value)
+  
+  ClassDef(AliMUONSparseHisto,1) // Sparse histogram-like class for ADC distributions
+};
+
+#endif
diff --git a/MUON/AliMUONTrackerCalibratedDataMaker.cxx b/MUON/AliMUONTrackerCalibratedDataMaker.cxx
new file mode 100644 (file)
index 0000000..b72ca8e
--- /dev/null
@@ -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.                  *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUONTrackerCalibratedDataMaker.h"
+
+#include "AliMUON2DMap.h"
+#include "AliMUONCalibParamND.h"
+#include "AliMUONCalibrationData.h"
+#include "AliMUONDigitCalibrator.h"
+#include "AliMUONDigitMaker.h"
+#include "AliMUONDigitStoreV2R.h"
+#include "AliMUONTrackerData.h"
+#include "AliMUONVDigit.h"
+#include "AliMUONVDigitStore.h"
+#include "AliMpDDLStore.h"
+#include "AliCodeTimer.h"
+#include "AliCDBManager.h"
+#include "AliCDBStorage.h"
+#include "AliRawEventHeaderBase.h"
+#include "AliRawReader.h"
+#include "AliLog.h"
+#include <Riostream.h>
+
+///\class AliMUONTrackerCalibratedDataMaker
+///
+/// Creator of AliMUONVTrackerData from AliRawReader
+/// 
+///\author Laurent Aphecetche, Subatech
+
+///\cond CLASSIMP
+ClassImp(AliMUONTrackerCalibratedDataMaker)
+///\endcond
+
+Int_t AliMUONTrackerCalibratedDataMaker::fgkCounter(0);
+
+//_____________________________________________________________________________
+AliMUONTrackerCalibratedDataMaker::AliMUONTrackerCalibratedDataMaker(AliRawReader* reader,
+                                                       const char* cdbpath)
+: AliMUONVTrackerDataMaker(),
+  fRawReader(reader),
+  fAccumulatedData(0x0),
+  fOneEventData(new AliMUON2DMap(true)),
+  fIsOwner(kTRUE),
+  fSource("unspecified"),
+  fIsRunning(kFALSE),
+  fDigitMaker(0x0),
+  fDigitCalibrator(0x0),
+  fCalibrationData(0x0),
+  fDigitStore(0x0), 
+  fCDBPath(cdbpath),
+  fNumberOfEvents(0)
+{
+  /// Ctor
+  reader->NextEvent(); // to be sure to get run number available
+  
+  Int_t runNumber = reader->GetRunNumber();
+  
+  ++fgkCounter;
+  
+  Bool_t calibrate = ( fCDBPath.Length() > 0 );
+  
+  TString name;
+  
+  if (!runNumber)
+  {
+    name = Form("%s(%d)",(calibrate ? "CAL" : "RAW"),fgkCounter);
+  }
+  else
+  {
+    name = Form("%s%d",(calibrate ? "CAL" : "RAW"),runNumber);
+  }
+  
+  fAccumulatedData = new AliMUONTrackerData(name.Data(),"charge values",1);
+  fAccumulatedData->SetDimensionName(0,(calibrate ? "Calibrated charge" : "Raw charge"));
+  
+  reader->RewindEvents();
+
+  fDigitMaker = new AliMUONDigitMaker;
+  fDigitMaker->SetMakeTriggerDigits(kFALSE);
+  fDigitStore = new AliMUONDigitStoreV2R;
+
+  if ( calibrate ) 
+  {
+    fCalibrationData = new AliMUONCalibrationData(runNumber);
+    
+    // force the reading of calibration NOW
+    // FIXME: not really elegant and error prone (as we have the list of calib data twice, 
+    // once here and once in the digitcalibrator class, hence the change of them getting
+    // out of sync)
+    // But with the current CDBManager implementation, I don't know how to solve
+    // this better (e.g. to avoid clearing cache messages and so on).
+    
+    AliCDBStorage* storage = AliCDBManager::Instance()->GetDefaultStorage();
+    
+    if ( storage->GetURI() != fCDBPath.Data() ) 
+    {
+      AliCDBManager::Instance()->SetDefaultStorage(fCDBPath.Data());
+    }
+    
+    fCalibrationData->Pedestals();
+    fCalibrationData->Gains();
+    fCalibrationData->Neighbours();
+    fCalibrationData->HV();
+    fCalibrationData->Capacitances();
+    
+    if ( storage->GetURI() != fCDBPath.Data() ) 
+    {
+      AliCDBManager::Instance()->SetDefaultStorage(storage);
+    }
+    
+    fDigitCalibrator = new AliMUONDigitCalibrator(*fCalibrationData);
+  }
+}
+
+//_____________________________________________________________________________
+AliMUONTrackerCalibratedDataMaker::~AliMUONTrackerCalibratedDataMaker()
+{
+  /// dtor
+  delete fOneEventData;
+  if ( fIsOwner ) delete fAccumulatedData;
+  delete fRawReader;
+  delete fDigitStore;
+  delete fCalibrationData;
+  delete fDigitMaker;
+  delete fDigitCalibrator;
+}
+
+//_____________________________________________________________________________
+Bool_t 
+AliMUONTrackerCalibratedDataMaker::NextEvent()
+{
+  /// Read next event
+  AliCodeTimerAuto("");
+  
+  static Int_t nphysics(0);
+  static Int_t ngood(0);
+
+  if ( !IsRunning() ) return kTRUE;
+  
+  Bool_t ok = fRawReader->NextEvent();
+
+  if (!ok) 
+  {
+    fDigitMaker->Print();
+    return kFALSE;
+  }
+  
+  Int_t eventType = fRawReader->GetType();
+
+  ++fNumberOfEvents;
+  
+  if (eventType != AliRawEventHeaderBase::kPhysicsEvent ) 
+  {
+    return kTRUE; // for the moment
+  }
+
+  ++nphysics;
+
+  Int_t rv = fDigitMaker->Raw2Digits(fRawReader,fDigitStore);
+  
+  if ( ( rv & AliMUONDigitMaker::kTrackerBAD ) != 0 ) return kTRUE;
+
+  if ( fDigitCalibrator ) 
+  {
+    fDigitCalibrator->Calibrate(*fDigitStore);
+  }
+  
+  Bool_t dok = ConvertDigits();
+  
+  if ( dok )
+    {
+      ++ngood;
+      fAccumulatedData->Add(*fOneEventData);
+    }
+
+  AliDebug(1,Form("n %10d nphysics %10d ngood %10d",fNumberOfEvents,nphysics,ngood));
+
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+Bool_t 
+AliMUONTrackerCalibratedDataMaker::ConvertDigits()
+{
+  /// Convert digitstore into fOneEventData
+  
+  AliCodeTimerAuto("");
+  
+  TIter next(fDigitStore->CreateIterator());
+  AliMUONVDigit* digit;
+
+  fOneEventData->Clear();
+  
+  while ( ( digit = static_cast<AliMUONVDigit*>(next())) )
+  {
+    Double_t value = ( digit->IsCalibrated() ? digit->Charge() : digit->ADC() );
+
+    if ( value > 0 ) 
+    {
+      Int_t detElemId = digit->DetElemId();
+      Int_t manuId = digit->ManuId();
+    
+      AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fOneEventData->FindObject(detElemId,manuId));
+      if (!param)
+      {
+        param = new AliMUONCalibParamND(1,64,detElemId,manuId,
+                                      AliMUONVCalibParam::InvalidFloatValue());
+        fOneEventData->Add(param);
+      }
+    
+      param->SetValueAsDouble(digit->ManuChannel(),0,value);
+    }
+  }
+
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONTrackerCalibratedDataMaker::Print(Option_t*) const
+{
+  /// Printout
+  
+  cout << "Source=" << Source() << " Running=" << ( IsRunning() ? "YES" : "NO")
+  << endl;
+  
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONTrackerCalibratedDataMaker::Rewind()
+{
+  /// Rewind events
+  fRawReader->RewindEvents();
+  fNumberOfEvents=0;
+}
diff --git a/MUON/AliMUONTrackerCalibratedDataMaker.h b/MUON/AliMUONTrackerCalibratedDataMaker.h
new file mode 100644 (file)
index 0000000..ab054bc
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef ALIMUONTRACKERCALIBRATEDDATAMAKER_H
+#define ALIMUONTRACKERCALIBRATEDDATAMAKER_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice                               */
+
+// $Id$
+
+/// \ingroup graphics
+/// \class AliMUONTrackerCalibratedDataMaker
+/// \brief Creator of calibrated AliMUONVTrackerData from AliRawReader
+/// 
+// Author Laurent Aphecetche, Subatech
+
+#ifndef ALIMUONVTRACKERDATAMAKER_H
+#  include "AliMUONVTrackerDataMaker.h"
+#endif
+#ifndef ROOT_TString
+#  include "TString.h"
+#endif
+
+class AliRawReader;
+class AliMUONCalibrationData;
+class AliMUONDigitCalibrator;
+class AliMUONDigitMaker;
+class AliMUONVTrackerData;
+class AliMUONVStore;
+class AliMUONVDigitStore;
+
+class AliMUONTrackerCalibratedDataMaker : public AliMUONVTrackerDataMaker
+{
+public:
+  AliMUONTrackerCalibratedDataMaker(AliRawReader* reader = 0x0, const char* cdbpath=0x0);
+  virtual ~AliMUONTrackerCalibratedDataMaker();
+  
+  /// Whether we have a valid raw reader
+  Bool_t IsValid() const { return fRawReader != 0x0; }
+  
+  /// Our data
+  AliMUONVTrackerData* Data() const { return fAccumulatedData; }
+  
+  /// We can be run
+  virtual Bool_t IsRunnable() const { return kTRUE; }
+  
+  /// Whether we are running or not
+  virtual Bool_t IsRunning() const { return fIsRunning; }
+  
+  /// Set the running status
+  virtual void SetRunning(Bool_t flag) { fIsRunning = flag; }
+  
+  Bool_t NextEvent();
+  
+  void Print(Option_t* opt="") const;
+  
+  void Rewind();
+  
+  /// Tell if we are owner of our data or not
+  void SetOwner(Bool_t flag) { fIsOwner = flag; }
+  
+  /// Get our source URI
+  virtual TString Source() const { return fSource.Data(); }
+  
+  /// Set our source URI
+  void SetSource(const char* source) { fSource = source; }
+  
+  /// Get our digit store
+  AliMUONVDigitStore* DigitStore() const { return fDigitStore; }
+  
+  /// Number of events seen
+    Int_t NumberOfEvents() const { return fNumberOfEvents; }
+
+private:
+  /// Not implemented
+  AliMUONTrackerCalibratedDataMaker(const AliMUONTrackerCalibratedDataMaker& rhs);
+  /// Not implemented
+  AliMUONTrackerCalibratedDataMaker& operator=(const AliMUONTrackerCalibratedDataMaker& rhs);
+  
+  Bool_t ConvertDigits();
+  
+private:
+  AliRawReader* fRawReader; ///< reader of the data (owner)
+  AliMUONVTrackerData* fAccumulatedData; ///< data (owner if fIsOwner==kTRUE)
+  AliMUONVStore* fOneEventData; ///< data for one event (owner)
+  Bool_t fIsOwner; ///< whether we are owner of our data or not
+  TString fSource; ///< where the data comes from
+  Bool_t fIsRunning; ///< whether we are running or are paused
+  AliMUONDigitMaker* fDigitMaker; ///< digit maker
+  AliMUONDigitCalibrator* fDigitCalibrator; ///< digit calibrator (if calibrating data)
+  AliMUONCalibrationData* fCalibrationData; ///< calibration data (if calibrating data)  
+  AliMUONVDigitStore* fDigitStore; ///< digit store (if calibrating data)
+  TString fCDBPath; ///< OCDB path (if calibrating data)
+  Int_t fNumberOfEvents; ///< number of events seen
+  static Int_t fgkCounter; ///< to count the number of instances
+  
+  ClassDef(AliMUONTrackerCalibratedDataMaker,1) // Producer of calibrated AliMUONVTrackerData from raw data
+};
+
+#endif
index 898ae37..dbf9785 100644 (file)
 
 #include "AliMUONTrackerData.h"
 
+#include "AliCodeTimer.h"
+#include "AliLog.h"
+#include "AliMUON1DArray.h"
+#include "AliMUON1DMap.h"
+#include "AliMUON2DMap.h"
 #include "AliMUONCalibParamND.h"
+#include "AliMUONSparseHisto.h"
 #include "AliMUONVStore.h"
 #include "AliMpBusPatch.h"
+#include "AliMpConstants.h"
 #include "AliMpDDLStore.h"
-#include "AliMpDEManager.h"
 #include "AliMpDEIterator.h"
+#include "AliMpDEManager.h"
 #include "AliMpDetElement.h"
 #include "AliMpHVNamer.h"
-#include "AliCodeTimer.h"
-#include "AliLog.h"
+#include "AliMpManuIterator.h"
 #include <Riostream.h>
+#include <TH1.h>
 #include <TMath.h>
 #include <TObjArray.h>
 #include <TObjString.h>
@@ -62,10 +69,15 @@ fPCBValues(0x0),
 fDimension(dimension*2+fgkExtraDimension),
 fNevents(0x0),
 fDimensionNames(new TObjArray(fDimension+fgkVirtualExtraDimension)),
+fExternalDimensionNames(new TObjArray(dimension)),
 fExternalDimension(dimension),
-fIsRunnable(runnable)
+fIsRunnable(runnable),
+fHistogramming(new Int_t[fExternalDimension]),
+fChannelHistos(0x0)
 {  
   /// ctor
+  memset(fHistogramming,0,sizeof(Int_t)); // histogramming is off by default. Use SetHistogramDimension to turn it on.
+  fExternalDimensionNames->SetOwner(kTRUE);
   fDimensionNames->SetOwner(kTRUE);  
   fDimensionNames->AddAt(new TObjString("occ"),IndexOfOccupancyDimension());
   fDimensionNames->AddAt(new TObjString("N"),IndexOfNumberDimension());
@@ -84,78 +96,128 @@ AliMUONTrackerData::~AliMUONTrackerData()
   delete fChamberValues;
   delete fPCBValues;
   delete fDimensionNames;
+  delete fExternalDimensionNames;
+  delete[] fHistogramming;
+  delete fChannelHistos;
 }
 
 //_____________________________________________________________________________
 Bool_t
 AliMUONTrackerData::Add(const AliMUONVStore& store)
 {
-  /// We first convert the external store to a temporary internal store
-  /// with more dimension (2*store's dimension)
+  /// Add the given external store to our internal store
   
-  AliCodeTimerAuto(GetName())
-  
-  Int_t ndim(NumberOfDimensions()-fgkExtraDimension-fgkVirtualExtraDimension); 
+  AliCodeTimerAuto(GetName());
+    
+  ++fNevents;
+  NumberOfEventsChanged();
   
-  AliMUONVStore* istore = store.Create();
+  if (!fChannelValues)
+  {
+    fChannelValues = store.Create();
+    fManuValues = store.Create();
+    fPCBValues = store.Create();
+    fBusPatchValues = new AliMUON1DMap;
+    fDEValues = new AliMUON1DMap;
+    fChamberValues = new AliMUON1DArray;
+  }
   
   TIter next(store.CreateIterator());
   AliMUONVCalibParam* external;
   
-  AliCodeTimerStart("from external to internal store");
-  
   while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
   {
-    Int_t detElemId = external->ID0();
-    Int_t manuId = external->ID1();
+    if ( external->Dimension() != ExternalDimension() )
+    {
+      AliError(Form("Incompatible dimensions %d vs %d",
+                    external->Dimension(),ExternalDimension()));
+      return kFALSE;
+    }
     
-    AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
+
+    AliMUONVCalibParam* chamber, *de, *busPatch, *pcb, *manu, *channel;
+    AliMpDetElement* mpde;
     
-    AliMUONVCalibParam* internal = static_cast<AliMUONVCalibParam*>
-      (istore->FindObject(detElemId,manuId));
+    Int_t manuId = GetParts(external,chamber,de,busPatch,pcb,manu,channel,mpde);
     
-    if (!internal)
-    {
-      internal = new AliMUONCalibParamND(ndim,external->Size(),
-                                         detElemId, manuId, 
-                                         0.0);
-      istore->Add(internal);
-    }
+    Int_t detElemId = mpde->GetId();
+    
+    Double_t value[] = { 0.0, 0.0 };
+    
+    Int_t nch = mpde->NofChannelsInManu(manuId);
     
     for ( Int_t i = 0; i < external->Size(); ++i ) 
     {
-      Bool_t connectPad = de->IsConnectedChannel(manuId,i);
-      
-      if (!connectPad) continue;
+      Bool_t existingChannel =  ( nch == AliMpConstants::ManuNofChannels() ? kTRUE
+                                                                           : mpde->IsConnectedChannel(manuId,i));
+      // note we only use IsConnectedChannel method when really needed, as
+      // it costs (some) CPU time...
       
-      for ( Int_t j = 0; j < external->Dimension(); ++j )
+      if ( existingChannel ) 
       {
-        Int_t ix = External2Internal(j);
-        
-        Double_t vext = external->IsDoublePrecision() ? 
-          external->ValueAsDouble(i,j) :
-          external->ValueAsFloat(i,j);
+        Bool_t validChannel(kFALSE);
         
-        Double_t sumw = internal->ValueAsDouble(i,ix) + vext;
-        Double_t sumw2 = internal->ValueAsDouble(i,ix+1) + vext*vext;
+        for ( Int_t j = 0; j < external->Dimension(); ++j )
+        {
+          Double_t vext = external->IsDoublePrecision() ? 
+            external->ValueAsDoubleFast(i,j) :
+            external->ValueAsFloatFast(i,j);
+          
+          if ( vext >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
+          
+          validChannel = kTRUE;
+                    
+          Int_t ix = External2Internal(j);
+          
+          value[0] = vext;
+          value[1] = vext*vext;
+          
+          if ( IsHistogrammed(j) )
+          {
+            FillChannel(detElemId,manuId,i,j,vext);
+          }
+          
+          for ( Int_t k = 0; k < 2; ++k ) 
+          {
+            channel->SetValueAsDoubleFast(i,ix+k,channel->ValueAsDoubleFast(i,ix+k)+value[k]);
+
+            manu->SetValueAsDoubleFast(0,ix+k,manu->ValueAsDoubleFast(0,ix+k)+value[k]);            
+            
+            busPatch->SetValueAsDoubleFast(0,ix+k,busPatch->ValueAsDoubleFast(0,ix+k)+value[k]);
+          
+            de->SetValueAsDoubleFast(0,ix+k,de->ValueAsDoubleFast(0,ix+k)+value[k]);
+          
+            chamber->SetValueAsDoubleFast(0,ix+k,chamber->ValueAsDoubleFast(0,ix+k)+value[k]);
+          
+            if ( pcb ) 
+            {
+              pcb->SetValueAsDoubleFast(0,ix+k,pcb->ValueAsDoubleFast(0,ix+k)+value[k]);
+            }
+          }
+        }
         
-        internal->SetValueAsFloat(i,ix,sumw);
-        internal->SetValueAsFloat(i,ix+1,sumw2);
+        if ( validChannel )
+        {
+          channel->SetValueAsDoubleFast(i,IndexOfOccupancyDimension(),
+                                        channel->ValueAsDoubleFast(i,IndexOfOccupancyDimension())+1.0);
+          manu->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
+                                                 manu->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
+          busPatch->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
+                                                         busPatch->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
+          de->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
+                                             de->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
+          chamber->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
+                                                       chamber->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0); 
+          if ( pcb ) 
+          {
+            pcb->SetValueAsDoubleFast(0,IndexOfOccupancyDimension(),
+                                      pcb->ValueAsDoubleFast(0,IndexOfOccupancyDimension())+1.0);        
+          }
+        }
       }
     }
   }
   
-  AliCodeTimerStop("from external to internal store");
-  
-  /// and we add this internal store to what we already have
-  
-  InternalAdd(*istore);
-  
-  /// delete the temporary internal store.
-  AliCodeTimerStart("delete");
-  delete istore;
-  AliCodeTimerStop("delete");
-  
   return kTRUE;
 }
 
@@ -171,11 +233,57 @@ AliMUONTrackerData::BusPatch(Int_t busPatchId, Int_t dim) const
 
 //_____________________________________________________________________________
 AliMUONVCalibParam* 
-AliMUONTrackerData::BusPatchParam(Int_t busPatchId) const
+AliMUONTrackerData::BusPatchParam(Int_t busPatchId, Bool_t create) const
 {
   /// Return (if it exist), the VCalibParam for a given busPatch
-  return fBusPatchValues ? static_cast<AliMUONVCalibParam*>
-  (fBusPatchValues->FindObject(busPatchId)) : 0x0;
+  
+  AliMUONVCalibParam* busPatch = fBusPatchValues ? static_cast<AliMUONVCalibParam*>
+    (fBusPatchValues->FindObject(busPatchId)) : 0x0;
+  
+  if (!busPatch && create && fBusPatchValues)
+  {
+    busPatch = CreateBusPatchParam(busPatchId);
+    fBusPatchValues->Add(busPatch);
+  }
+  
+  return busPatch;
+}
+
+//_____________________________________________________________________________
+AliMUONVCalibParam* 
+AliMUONTrackerData::CreateBusPatchParam(Int_t busPatchId) const
+{
+  /// Create storage for one bus patch
+  
+  AliCodeTimerAuto("");
+  
+  AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
+  
+  if (!bp)
+  {
+    AliError(Form("Got an invalid buspatchId = %d",busPatchId));
+    return 0x0;
+  }
+  
+  AliMUONVCalibParam* busPatch = new AliMUONCalibParamND(Dimension(),1,busPatchId,0,0.0);
+  
+  // set the number of channels in that buspatch
+  
+  Int_t nchannels(0);
+  
+  Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(busPatchId);
+  
+  AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
+  
+  for ( Int_t i = 0; i < bp->GetNofManus(); ++i ) 
+  {
+    Int_t manuId = bp->GetManuId(i);
+    nchannels += de->NofChannelsInManu(manuId);
+  }
+  
+  busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
+  
+  return busPatch;
 }
 
 //_____________________________________________________________________________
@@ -190,11 +298,61 @@ AliMUONTrackerData::Chamber(Int_t chamberId, Int_t dim) const
 
 //_____________________________________________________________________________
 AliMUONVCalibParam* 
-AliMUONTrackerData::ChamberParam(Int_t chamberId) const
+AliMUONTrackerData::ChamberParam(Int_t chamberId, Bool_t create) const
 {
   /// Return (if it exist) the VCalibParam for a given chamber
-  return fChamberValues ? static_cast<AliMUONVCalibParam*>
+  
+  AliMUONVCalibParam* chamber =  fChamberValues ? static_cast<AliMUONVCalibParam*>
   (fChamberValues->FindObject(chamberId)) : 0x0;
+  
+  if (!chamber && create && fChamberValues)
+  {
+    chamber = CreateChamberParam(chamberId);
+    fChamberValues->Add(chamber);
+  }
+    
+  return chamber;
+}
+
+//_____________________________________________________________________________
+AliMUONVCalibParam* 
+AliMUONTrackerData::CreateChamberParam(Int_t chamberId) const
+{
+  /// Create storage for one chamber
+  
+  AliCodeTimerAuto("");
+  
+  AliMUONVCalibParam* chamber = new AliMUONCalibParamND(Dimension(),1,chamberId,0,0.0);
+  
+  // set the number of channels in that chamber
+  
+  Int_t nchannels(0);
+  
+  AliMpDEIterator it;
+  
+  it.First(chamberId);
+  
+  while ( !it.IsDone() )
+  {        
+    AliMpDetElement* det = it.CurrentDE();
+    
+    for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
+    {
+      Int_t busPatchId = det->GetBusPatchId(i);
+      AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
+      for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
+      {
+        Int_t manuId = bp->GetManuId(j);
+        nchannels += det->NofChannelsInManu(manuId);
+      }        
+    }
+    
+    it.Next();
+  }
+  
+  chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
+  
+  return chamber;
 }
 
 //_____________________________________________________________________________
@@ -211,14 +369,23 @@ AliMUONTrackerData::Channel(Int_t detElemId, Int_t manuId,
 
 //_____________________________________________________________________________
 AliMUONVCalibParam* 
-AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId) const
+AliMUONTrackerData::ChannelParam(Int_t detElemId, Int_t manuId,
+                                 AliMUONVCalibParam* external) const
 {
   /// Return (if it exist) the VCalibParam for a given manu
-  return fChannelValues ? static_cast<AliMUONVCalibParam*>
-  (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
+  
+  AliMUONVCalibParam* param = fChannelValues ? static_cast<AliMUONVCalibParam*>
+    (fChannelValues->FindObject(detElemId,manuId)) : 0x0 ;
+  
+  if (!param && external && fChannelValues)
+  {
+    param = CreateDouble(*external);
+    fChannelValues->Add(param);
+  }
+  
+  return param;
 }
 
-
 //_____________________________________________________________________________
 void 
 AliMUONTrackerData::Clear(Option_t*)
@@ -229,7 +396,8 @@ AliMUONTrackerData::Clear(Option_t*)
   if ( fBusPatchValues) fBusPatchValues->Clear();
   if ( fPCBValues ) fPCBValues->Clear();
   if ( fDEValues) fDEValues->Clear();
-  if ( fChamberValues) fChamberValues->Clear();
+  if ( fChamberValues ) fChamberValues->Clear();
+  if ( fChannelHistos ) fChannelHistos->Clear();
   fNevents = 0;
   NumberOfEventsChanged();
 }
@@ -240,12 +408,8 @@ AliMUONTrackerData::Count(Int_t detElemId, Int_t manuId,
                           Int_t manuChannel) const
 {
   /// Return the number of times a given channel had data
-  AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>
-  (fChannelValues->FindObject(detElemId,manuId));
-  
-  if ( !param ) return 0.0;
   
-  return param->ValueAsDouble(manuChannel,IndexOfOccupancyDimension());
+  return Channel(detElemId,manuId,manuChannel,IndexOfNumberDimension());
 }
 
 //_____________________________________________________________________________
@@ -253,11 +417,14 @@ AliMUONVCalibParam*
 AliMUONTrackerData::CreateDouble(const AliMUONVCalibParam& param) const
 {
   /// Create a double version of VCalibParam, for internal use
-  AliMUONVCalibParam* c = new AliMUONCalibParamND(param.Dimension()+fgkExtraDimension,
-                                 param.Size(),
-                                 param.ID0(),
-                                 param.ID1(),
-                                 0.0);
+  
+  AliCodeTimerAuto("");
+  
+  AliMUONVCalibParam* c = new AliMUONCalibParamND(Dimension(),
+                                                  param.Size(),
+                                                  param.ID0(),
+                                                  param.ID1(),
+                                                  0.0);
   
   for ( Int_t i = 0; i < c->Size(); ++i ) 
   {
@@ -279,11 +446,50 @@ AliMUONTrackerData::DetectionElement(Int_t detElemId, Int_t dim) const
 
 //_____________________________________________________________________________
 AliMUONVCalibParam* 
-AliMUONTrackerData::DetectionElementParam(Int_t detElemId) const
+AliMUONTrackerData::DetectionElementParam(Int_t detElemId, Bool_t create) const
 {
   /// Return (if it exist) the VCalibParam for a given detection element
-  return fDEValues ? static_cast<AliMUONVCalibParam*>
-  (fDEValues->FindObject(detElemId)) : 0x0 ;
+  
+  AliMUONVCalibParam* de = fDEValues ? static_cast<AliMUONVCalibParam*>
+    (fDEValues->FindObject(detElemId)) : 0x0 ;
+  
+  if (!de && create && fDEValues)
+  {
+    de = CreateDetectionElementParam(detElemId);
+    fDEValues->Add(de);
+  }
+  
+  return de;
+  
+}
+
+//_____________________________________________________________________________
+AliMUONVCalibParam* 
+AliMUONTrackerData::CreateDetectionElementParam(Int_t detElemId) const
+{
+  /// Create storage for one detection element
+  
+  AliCodeTimerAuto("");
+  
+  AliMUONVCalibParam*  de = new AliMUONCalibParamND(Dimension(),1,detElemId,0,0.0);
+  
+  AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
+  Int_t nchannels(0);
+  
+  for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
+  {
+    Int_t busPatchId = det->GetBusPatchId(i);
+    AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
+    for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
+    {
+      Int_t manuId = bp->GetManuId(j);
+      nchannels += det->NofChannelsInManu(manuId);
+    }        
+  }
+  
+  de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
+  
+  return de;
 }
 
 //_____________________________________________________________________________
@@ -303,304 +509,405 @@ AliMUONTrackerData::DimensionName(Int_t dim) const
 }
 
 //_____________________________________________________________________________
-Bool_t 
-AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
+TString 
+AliMUONTrackerData::ExternalDimensionName(Int_t dim) const
 {
-  /// Whether we have data for a given buspatch
-  return ( BusPatchParam(busPatchId) != 0 );
+  /// Get the name of a given external dimension
+  
+  TObjString* value = static_cast<TObjString*>(fExternalDimensionNames->At(dim));
+  if ( value ) 
+  {
+    return value->String();
+  }
+  else
+  {
+    return TString("Invalid");
+  }  
 }
 
 //_____________________________________________________________________________
-Bool_t 
-AliMUONTrackerData::HasChamber(Int_t chamberId) const
+void
+AliMUONTrackerData::FillChannel(Int_t detElemId, Int_t manuId, Int_t manuChannel,
+                                Int_t dim, Double_t value)
 {
-  /// Whether we have data for a given chamber
-  return ( ChamberParam(chamberId) != 0 );
+  /// Fill histogram of a given channel
+  
+  AliMUONSparseHisto* h = GetChannelHisto(detElemId, manuId, manuChannel,dim);
+  h->Fill(static_cast<Int_t>(TMath::Nint(value)));
 }
 
 //_____________________________________________________________________________
-Bool_t 
-AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
+TH1*
+AliMUONTrackerData::CreateChannelHisto(Int_t detElemId, Int_t manuId, 
+                                       Int_t manuChannel, Int_t dim)
 {
-  /// Whether we have data for a given detection element
-  return ( DetectionElementParam(detElemId) != 0 );
+  /// Create histogram of a given channel. Note that in order
+  /// to keep memory footprint as low as possible, you should delete
+  /// the returned pointer as soon as possible...
+
+  if ( HasChannel(detElemId, manuId, manuChannel) && IsHistogrammed(dim) )
+  {
+    AliMUONSparseHisto* sh = GetChannelHisto(detElemId,manuId,manuChannel,dim);
+  
+    if ( sh ) 
+    {
+      TH1* h = new TH1I(Form("DE%04dMANU%04dCH%02d_%d",detElemId,manuId,manuChannel,dim),
+                        Form("Data=%s Dim=%s",GetName(),ExternalDimensionName(dim).Data()),
+                        4096,-0.5,4095.5);
+      
+      Add(*h,*sh);
+      return h;
+    }
+  }
+  return 0x0;
 }
 
 //_____________________________________________________________________________
-Bool_t
-AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
+void
+AliMUONTrackerData::Add(TH1& h, const AliMUONSparseHisto& sh)
 {
-  /// Whether we have data for a given manu
-  return ( ManuParam(detElemId,manuId) != 0 ); 
+  /// Add sparse histo content to histogram.
+  
+  Double_t entries(h.GetEntries());
+  
+  for ( Int_t i = 0; i < sh.GetNbins(); ++i ) 
+  {
+    Int_t x = sh.GetBinContent(i);
+    Int_t adc, count;
+    sh.Decode(x,adc,count);
+    h.Fill(adc,count);
+    entries += count;
+  }
+  
+  h.SetEntries(entries);
 }
 
 //_____________________________________________________________________________
-Bool_t
-AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
+TH1*
+AliMUONTrackerData::CreateHisto(const char* name, Int_t dim) const
 {
-  /// Whether we have data for a given pcb
-  return ( PCBParam(detElemId,pcbIndex) != 0 ); 
+  /// Create a single histogram
+  return new TH1I(name,Form("Data=%s Dim=%s",GetName(),ExternalDimensionName(dim).Data()),
+                  4096,-0.5,4095.5);
 }
 
 //_____________________________________________________________________________
-Bool_t 
-AliMUONTrackerData::InternalAdd(const AliMUONVStore& store)
+TH1*
+AliMUONTrackerData::CreateBusPatchHisto(Int_t busPatchId, Int_t dim)
 {
-  /// Add the given store to our internal store
-  /// Store must be of dimension = fDimension-1
+  /// Create histogram of a given bus patch. Note that in order
+  /// to keep memory footprint as low as possible, you should delete
+  /// the returned pointer as soon as possible...
   
-  AliCodeTimerAuto(GetName());
+  TH1* h(0x0);
   
-  AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
-  
-  ++fNevents;
-  NumberOfEventsChanged();
-  
-  if (!fChannelValues)
+  if ( HasBusPatch(busPatchId) && IsHistogrammed(dim)) 
   {
-    fChannelValues = store.Create();
-    fManuValues = store.Create();
-    fBusPatchValues = store.Create();
-    fDEValues = store.Create();
-    fChamberValues = store.Create();
-    fPCBValues = store.Create();
+    h = CreateHisto(Form("BP%04d_%d",busPatchId,dim),dim);
+    AddBusPatchHisto(*h,busPatchId,dim);
   }
   
-  TIter next(store.CreateIterator());
-  AliMUONVCalibParam* external;
-  
-  AliMpHVNamer namer;
-  
-  while ( ( external = static_cast<AliMUONVCalibParam*>(next()) ) )
+  return h;
+}  
+//_____________________________________________________________________________
+void
+AliMUONTrackerData::AddBusPatchHisto(TH1& h, Int_t busPatchId, Int_t dim)
+{
+  /// Add data from one bus patch to the histogram
+      
+  if ( HasBusPatch(busPatchId ) )
   {
-    if ( external->Dimension() != fDimension-fgkExtraDimension ) 
+    AliMpBusPatch* busPatch = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
+    for ( Int_t i = 0; i < busPatch->GetNofManus(); ++i ) 
     {
-      AliError(Form("Incompatible dimensions %d vs %d",
-                    external->Dimension(),fDimension-fgkExtraDimension));
-      return kFALSE;
+      Int_t manuId = busPatch->GetManuId(i);
+      AddManuHisto(h,busPatch->GetDEId(),manuId,dim);
     }
-    
-    Int_t detElemId = external->ID0();
-    
-    AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId);
-    
-    Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
-    
-    Int_t manuId = external->ID1();
-    
-    AliMpDetElement* mpde = ddlStore->GetDetElement(detElemId);
+  }
+}
 
-    Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
-    
-    Int_t pcbIndex = -1;
-    
-    if ( stationType == AliMp::kStation345 ) 
-    {
-      pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
-    }
 
-    AliMUONVCalibParam* channel = ChannelParam(detElemId,manuId);
-    if (!channel)
-    {
-      channel = CreateDouble(*external);
-      fChannelValues->Add(channel);
-    }
+//_____________________________________________________________________________
+TH1*
+AliMUONTrackerData::CreateDEHisto(Int_t detElemId, Int_t dim)
+{
+  /// Create histogram of a given detection element. Note that in order
+  /// to keep memory footprint as low as possible, you should delete
+  /// the returned pointer as soon as possible...
+  
+  TH1* h(0x0);
+  
+  if ( HasDetectionElement(detElemId) && IsHistogrammed(dim) ) 
+  {
+    h = CreateHisto(Form("DE%04d-%d",detElemId,dim),dim);
+    AddDEHisto(*h,detElemId,dim);
+  }
+  
+  return h;
+}
 
-    AliMUONVCalibParam* manu = ManuParam(detElemId,manuId);
-    if (!manu)
+//_____________________________________________________________________________
+void
+AliMUONTrackerData::AddDEHisto(TH1& h, Int_t detElemId, Int_t dim)
+{
+  /// Add data from one detection element to the histogram
+  
+  if ( HasDetectionElement(detElemId) )
+  {
+    AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
+    for ( Int_t i = 0; i < de->GetNofBusPatches(); ++ i ) 
     {
-      manu = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
-                                     1,
-                                     detElemId,
-                                     manuId,
-                                     0.0);
-      
-      // set the number of channels in that manu
-      
-      AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
-      
-      manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
-      
-      fManuValues->Add(manu);
+      Int_t busPatchId = de->GetBusPatchId(i);
+      AddBusPatchHisto(h,busPatchId,dim);
     }
-    
-    AliMUONVCalibParam* busPatch = BusPatchParam(busPatchId);
-    if (!busPatch)
-    {
-      AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
-
-      if (!bp)
-      {
-        AliError(Form("Got an invalid buspatchId = %d",busPatchId));
-        continue;
-      }
-      
-      busPatch = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
-                                         1,
-                                         busPatchId,
-                                         0,
-                                         0.0);
-      
-      // set the number of channels in that buspatch
-
-      Int_t nchannels(0);
-      
-      AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
-
-      for ( Int_t i = 0; i < bp->GetNofManus(); ++i ) 
-      {
-        Int_t manuId = bp->GetManuId(i);
-        nchannels += de->NofChannelsInManu(manuId);
-      }
+  }
+}
 
-      busPatch->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
-      
-      fBusPatchValues->Add(busPatch);
-    }
+//_____________________________________________________________________________
+TH1*
+AliMUONTrackerData::CreateManuHisto(Int_t detElemId, Int_t manuId, Int_t dim)
+{
+  /// Create histogram of a given manu. Note that in order
+  /// to keep memory footprint as low as possible, you should delete
+  /// the returned pointer as soon as possible...
+  
+  TH1* h(0x0);
+  
+  if ( HasManu(detElemId, manuId) && IsHistogrammed(dim) ) 
+  {
+    h = CreateHisto(Form("DE%04dMANU%04d_%d",detElemId,manuId,dim),dim);
+    AddManuHisto(*h,detElemId,manuId,dim);
+  }
+  
+  return h;
+}
 
-    AliMUONVCalibParam* de = DetectionElementParam(detElemId);
-    if (!de)
+//_____________________________________________________________________________
+void
+AliMUONTrackerData::AddManuHisto(TH1& h, Int_t detElemId, Int_t manuId, Int_t dim)
+{
+  /// Add data from a given manu to histogram
+  
+  if ( HasManu(detElemId,manuId) )
+  {
+    for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i ) 
     {
-      de = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
-                                         1,
-                                         detElemId,
-                                         0,
-                                         0.0);
-      
-      AliMpDetElement* det = AliMpDDLStore::Instance()->GetDetElement(detElemId);
-      Int_t nchannels(0);
-      
-      for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
+      if ( HasChannel(detElemId,manuId,i) )
       {
-        Int_t busPatchId = det->GetBusPatchId(i);
-        AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
-        for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
-        {
-          Int_t manuId = bp->GetManuId(j);
-          nchannels += det->NofChannelsInManu(manuId);
-        }        
-      }
-      
-      de->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
-      
-      fDEValues->Add(de);
-    }
-
-    AliMUONVCalibParam* chamber = ChamberParam(chamberId);
-    if (!chamber)
-    {
-      chamber = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
-                                   1,
-                                   chamberId,
-                                   0,
-                                   0.0);
-
-      // set the number of channels in that chamber
-      
-      Int_t nchannels(0);
-      
-      AliMpDEIterator it;
-      
-      it.First(chamberId);
-      
-      while ( !it.IsDone() )
-      {        
-        AliMpDetElement* det = it.CurrentDE();
+        AliMUONSparseHisto* sh = GetChannelHisto(detElemId,manuId,i,dim);
       
-        for ( Int_t i = 0; i < det->GetNofBusPatches(); ++i ) 
-        {
-          Int_t busPatchId = det->GetBusPatchId(i);
-          AliMpBusPatch* bp = AliMpDDLStore::Instance()->GetBusPatch(busPatchId);
-          for ( Int_t j = 0; j < bp->GetNofManus(); ++j ) 
-          {
-            Int_t manuId = bp->GetManuId(j);
-            nchannels += det->NofChannelsInManu(manuId);
-          }        
+        if ( sh ) 
+        {      
+          Add(h,*sh);
         }
-        
-        it.Next();
       }
-      
-      chamber->SetValueAsDouble(0,IndexOfNumberDimension(),nchannels);
-      
-      fChamberValues->Add(chamber);
     }
+  }
+}
 
-    AliMUONVCalibParam* pcb = 0x0;
-    
-    if ( pcbIndex >= 0 ) 
+//_____________________________________________________________________________
+TH1*
+AliMUONTrackerData::CreatePCBHisto(Int_t /*detElemId*/, Int_t /*pcbIndex*/, Int_t /*dim*/)
+{
+  /// Create histogram of a given PCB. Note that in order
+  /// to keep memory footprint as low as possible, you should delete
+  /// the returned pointer as soon as possible...
+  
+ // TH1* h(0x0);
+//  
+//  if ( HasPCB(detElemId, pcbIndex) && IsHistogrammed(dim)) 
+//  {
+//    h = CreateHisto(Form("DE%04dPCB1d_%d",detElemId,pcbIndex,dim),dim);
+//  }
+//  
+//  return h;
+
+  AliWarning("Not implemented (is it needed ?)");
+  return 0x0;
+}
+
+//_____________________________________________________________________________
+TH1*
+AliMUONTrackerData::CreateChamberHisto(Int_t chamberId, Int_t dim)
+{
+  /// Create histogram of a given chamber. Note that in order
+  /// to keep memory footprint as low as possible, you should delete
+  /// the returned pointer as soon as possible...
+  
+  TH1* h(0x0);
+  
+  if ( HasChamber(chamberId) && IsHistogrammed(dim))
+  {
+    h = CreateHisto(Form("CHAMBER%02d_%d",chamberId,dim),dim);
+    AliMpDEIterator it;
+    it.First(chamberId);
+    while ( !it.IsDone() )
     {
-      pcb = PCBParam(detElemId,pcbIndex);
-      if (!pcb)
-      {
-        pcb = new AliMUONCalibParamND(external->Dimension()+fgkExtraDimension,
-                                        namer.NumberOfPCBs(detElemId),
-                                        detElemId,
-                                        pcbIndex,
-                                        0.0);
-        fPCBValues->Add(pcb);
-      }
+      Int_t detElemId = it.CurrentDEId();
+      AddDEHisto(*h,detElemId,dim);
+      it.Next();
     }
-    
-    for ( Int_t i = 0; i < external->Size(); ++i ) 
-    {
-      Bool_t existingChannel = mpde->IsConnectedChannel(manuId,i);
-      
-      if ( existingChannel ) 
-      {
-        Bool_t validChannel(kFALSE);
-        
-        for ( Int_t j = 0; j < external->Dimension(); ++j )
-        {
-          if ( external->ValueAsFloat(i,j) >= AliMUONVCalibParam::InvalidFloatValue() ) continue;
-          
-          validChannel = kTRUE;
-          
-          Double_t vext = external->IsDoublePrecision() ? 
-            external->ValueAsDouble(i,j) :
-            external->ValueAsFloat(i,j);
-          
-          Double_t value = channel->ValueAsDouble(i,j) + vext;
-          
-          channel->SetValueAsDouble(i,j,value);
-          
-          manu->SetValueAsDouble(0,j,manu->ValueAsDouble(0,j)+vext);  
-          
-          busPatch->SetValueAsDouble(0,j,busPatch->ValueAsDouble(0,j)+vext);
+  }
+  
+  return h;
+}
 
-          de->SetValueAsDouble(0,j,de->ValueAsDouble(0,j)+vext);
+//_____________________________________________________________________________
+AliMUONSparseHisto*
+AliMUONTrackerData::GetChannelHisto(Int_t detElemId, Int_t manuId, 
+                                    Int_t manuChannel, Int_t dim)
+{
+  /// Get histogram of a given channel
+  
+  if (!fChannelHistos) fChannelHistos = new AliMUON2DMap(kTRUE);
+  
+  TObjArray* dimArray = static_cast<TObjArray*>(fChannelHistos->FindObject(detElemId,manuId));
+  if (!dimArray)
+  {
+    dimArray = new TObjArray(fExternalDimension);
+    dimArray->SetUniqueID( ( manuId << 16 ) | detElemId );
+    fChannelHistos->Add(dimArray);
+  }
+  
+  TObjArray* channels = static_cast<TObjArray*>(dimArray->UncheckedAt(dim));
+  if (!channels)
+  {
+    channels = new TObjArray(AliMpConstants::ManuNofChannels());
+    dimArray->AddAt(channels,dim);
+  }
+  
+  AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(channels->UncheckedAt(manuChannel));
+  if (!h)
+  {
+    h = new AliMUONSparseHisto;
+    h->SetUniqueID(( manuChannel << 16 ) | dim);
+    channels->AddAt(h,manuChannel);
+  }
+  
+  return h;
+// below is an alternate implementation, using a 1DMap, which *seems* to be
+// slightly SLOWER.
+//
+//  AliMUON1DMap* m = static_cast<AliMUON1DMap*>(fChannelHistos->FindObject(detElemId,manuId));
+//  if (!m)
+//  {
+//    m = new AliMUON1DMap(kFALSE);
+//    m->SetUniqueID( ( manuId << 16 ) | detElemId );
+//    fChannelHistos->Add(m);
+//  }
+//  
+//  UInt_t uid = ( manuChannel << 16 ) | dim;
+//  
+//  AliMUONSparseHisto* h = static_cast<AliMUONSparseHisto*>(m->FindObject(uid));
+//  if (!h)
+//  {
+//    h = new AliMUONSparseHisto;
+//    
+//    h->SetUniqueID(uid);
+//    
+//    m->Add(h);
+//  }
 
-          chamber->SetValueAsDouble(0,j,chamber->ValueAsDouble(0,j)+vext);
+  return h;
+}
 
-          if ( pcb ) 
-          {
-            pcb->SetValueAsDouble(pcbIndex,j,pcb->ValueAsDouble(pcbIndex,j)+vext);
-          }
-        }
-        
-        if ( validChannel )
-        {
-          channel->SetValueAsDouble(i,IndexOfOccupancyDimension(),
-                                  channel->ValueAsDouble(i,IndexOfOccupancyDimension())+1.0);
-          manu->SetValueAsDouble(0,IndexOfOccupancyDimension(),
-                               manu->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0);        
-          busPatch->SetValueAsDouble(0,IndexOfOccupancyDimension(),
-                                 busPatch->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0);        
-          de->SetValueAsDouble(0,IndexOfOccupancyDimension(),
-                                     de->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0);        
-          chamber->SetValueAsDouble(0,IndexOfOccupancyDimension(),
-                               chamber->ValueAsDouble(0,IndexOfOccupancyDimension())+1.0); 
-          if ( pcb ) 
-          {
-            pcb->SetValueAsDouble(pcbIndex,IndexOfOccupancyDimension(),
-                                    pcb->ValueAsDouble(pcbIndex,IndexOfOccupancyDimension())+1.0);        
-          }
-        }
-      }
-    }
+//_____________________________________________________________________________
+Int_t
+AliMUONTrackerData::GetParts(AliMUONVCalibParam* external,
+                             AliMUONVCalibParam*& chamber,
+                             AliMUONVCalibParam*& de,
+                             AliMUONVCalibParam*& busPatch,
+                             AliMUONVCalibParam*& pcb,
+                             AliMUONVCalibParam*& manu,
+                             AliMUONVCalibParam*& channel,
+                             AliMpDetElement*& mpde)
+{
+  /// Get containers at all levels
+  AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
+  
+  Int_t detElemId = external->ID0();
+  
+  Int_t chamberId = AliMpDEManager::GetChamberId(detElemId);
+  
+  Int_t manuId = external->ID1();
+  
+  mpde = ddlStore->GetDetElement(detElemId);
+  
+  Int_t busPatchId = ddlStore->GetBusPatchId(detElemId,manuId);
+  
+  Int_t pcbIndex = -1;
+  
+  AliMp::StationType stationType = mpde->GetStationType();
+  
+  if ( stationType == AliMp::kStation345 ) 
+  {
+    AliMpHVNamer namer;
+    pcbIndex = namer.ManuId2PCBIndex(detElemId,manuId);
+  }
+  
+  channel = ChannelParam(detElemId,manuId,external);
+  
+  manu = ManuParam(detElemId,manuId,kTRUE);
+  
+  busPatch = BusPatchParam(busPatchId,kTRUE);
+  
+  de = DetectionElementParam(detElemId,kTRUE);
+  
+  chamber = ChamberParam(chamberId,kTRUE);
+  
+  pcb = 0x0;
+  
+  if ( pcbIndex >= 0 ) 
+  {
+    pcb = PCBParam(detElemId,pcbIndex,kTRUE);
   }
+  
+  return manuId;
+}
 
-  return kTRUE;
+//_____________________________________________________________________________
+Bool_t 
+AliMUONTrackerData::HasBusPatch(Int_t busPatchId) const
+{
+  /// Whether we have data for a given buspatch
+  return ( BusPatchParam(busPatchId) != 0 );
+}
+
+//_____________________________________________________________________________
+Bool_t 
+AliMUONTrackerData::HasChamber(Int_t chamberId) const
+{
+  /// Whether we have data for a given chamber
+  return ( ChamberParam(chamberId) != 0 );
+}
+
+//_____________________________________________________________________________
+Bool_t 
+AliMUONTrackerData::HasDetectionElement(Int_t detElemId) const
+{
+  /// Whether we have data for a given detection element
+  return ( DetectionElementParam(detElemId) != 0 );
+}
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONTrackerData::HasManu(Int_t detElemId, Int_t manuId) const
+{
+  /// Whether we have data for a given manu
+  return ( ManuParam(detElemId,manuId) != 0 ); 
+}
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONTrackerData::HasPCB(Int_t detElemId, Int_t pcbIndex) const
+{
+  /// Whether we have data for a given pcb
+  return ( PCBParam(detElemId,pcbIndex) != 0 ); 
 }
 
 //_____________________________________________________________________________
@@ -615,11 +922,39 @@ AliMUONTrackerData::Manu(Int_t detElemId, Int_t manuId, Int_t dim) const
 
 //_____________________________________________________________________________
 AliMUONVCalibParam* 
-AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId) const
+AliMUONTrackerData::ManuParam(Int_t detElemId, Int_t manuId, Bool_t create) const
 {
   /// Get the VCalibParam for a given manu
-  return fManuValues ? static_cast<AliMUONVCalibParam*>
-  (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
+  
+  AliMUONVCalibParam* manu = fManuValues ? static_cast<AliMUONVCalibParam*>
+    (fManuValues->FindObject(detElemId,manuId)) : 0x0 ;
+  
+  if (!manu && create && fManuValues)
+  {
+    manu = CreateManuParam(detElemId,manuId);
+    fManuValues->Add(manu);
+  }
+  
+  return manu;
+}
+
+//_____________________________________________________________________________
+AliMUONVCalibParam* 
+AliMUONTrackerData::CreateManuParam(Int_t detElemId, Int_t manuId) const
+{
+  /// Create storage for one manu
+  
+  AliCodeTimerAuto("");
+  
+  AliMUONVCalibParam* manu = new AliMUONCalibParamND(Dimension(),1,detElemId,manuId,0.0);
+  
+  // set the number of channels in that manu
+  
+  AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
+  
+  manu->SetValueAsDouble(0,IndexOfNumberDimension(),de->NofChannelsInManu(manuId));
+  
+  return manu;
 }
 
 //_____________________________________________________________________________
@@ -644,11 +979,38 @@ AliMUONTrackerData::PCB(Int_t detElemId, Int_t pcbIndex, Int_t dim) const
 
 //_____________________________________________________________________________
 AliMUONVCalibParam* 
-AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex) const
+AliMUONTrackerData::PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create) const
 {
   /// Return (if it exist) the VCalibParam for a given pcb
-  return fPCBValues ? static_cast<AliMUONVCalibParam*>
-  (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
+
+  AliMUONVCalibParam* pcb =  fPCBValues ? static_cast<AliMUONVCalibParam*>
+    (fPCBValues->FindObject(detElemId,pcbIndex)) : 0x0 ;
+  
+  if (create && fPCBValues && !pcb)
+  {
+    pcb = CreatePCBParam(detElemId,pcbIndex);
+    fPCBValues->Add(pcb);
+  }
+  
+  return pcb;
+}
+
+//_____________________________________________________________________________
+AliMUONVCalibParam* 
+AliMUONTrackerData::CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const
+{
+  /// Create storage for one PCB (station345 only)
+  
+  AliCodeTimerAuto("");
+  
+  AliMpHVNamer namer;
+  
+  AliMUONVCalibParam* pcb = new AliMUONCalibParamND(Dimension(),
+                                                    namer.NumberOfPCBs(detElemId),
+                                                    detElemId,
+                                                    pcbIndex,
+                                                    0.0);
+  return pcb;
 }
 
 //_____________________________________________________________________________
@@ -663,16 +1025,22 @@ AliMUONTrackerData::Print(Option_t* wildcard, Option_t* opt) const
   {
     cout << " Nevents=" << fNevents << endl;
   }
+
+  for ( Int_t i = 0; i <= fExternalDimensionNames->GetLast(); ++i ) 
+  {
+    TObjString* name = static_cast<TObjString*>(fExternalDimensionNames->At(i));
+    cout << Form("External Dimension %2d Name %s %s",i,
+                 ( name ? name->String().Data() : "null"),
+                 ( IsHistogrammed(i) ? "(histogrammed)" : "")) << endl;
+  }
   
   for ( Int_t i = 0; i <= fDimensionNames->GetLast(); ++i ) 
   {
     TObjString* name = static_cast<TObjString*>(fDimensionNames->At(i));
-    cout << Form("Dimension %2d Name %s",i,
+    cout << Form("Internal Dimension %2d Name %s",i,
                  ( name ? name->String().Data() : "null")) << endl;
   }
-  
-  cout << Form("External Dimensions = %d",fExternalDimension) << endl;  
-
+    
   TString sopt(opt);
   sopt.ToUpper();
   
@@ -725,6 +1093,22 @@ AliMUONTrackerData::SetDimensionName(Int_t index, const char* name)
     
     SetInternalDimensionName(j,Form("%s of %s",prefix[i],name));
   }
+  
+  SetExternalDimensionName(index,name);
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONTrackerData::SetHistogramDimension(Int_t index, Bool_t value)
+{
+  /// decide to make histos for a given dimension
+  if ( index >= ExternalDimension() ) 
+  {
+    AliError(Form("Index out of bounds : %d / %d",index,ExternalDimension()));
+    return;
+  }
+  
+  fHistogramming[index] = value;
 }
 
 //_____________________________________________________________________________
@@ -748,6 +1132,27 @@ AliMUONTrackerData::SetInternalDimensionName(Int_t index, const char* value)
   fDimensionNames->AddAt(new TObjString(value),index);
 }
 
+//_____________________________________________________________________________
+void 
+AliMUONTrackerData::SetExternalDimensionName(Int_t index, const char* value)
+{
+  /// Set the name of a given external dimension
+  if ( index >= fExternalDimension ) 
+  {
+    AliError(Form("Index out of bounds : %d / %d",index,fExternalDimension));
+    return;
+  }
+  
+  TObjString* ovalue = static_cast<TObjString*>(fExternalDimensionNames->At(index));
+  
+  if ( ovalue ) 
+  {
+    fExternalDimensionNames->Remove(ovalue);
+    delete ovalue;
+  }
+  fExternalDimensionNames->AddAt(new TObjString(value),index);
+}
+
 //_____________________________________________________________________________
 Double_t 
 AliMUONTrackerData::Value(const AliMUONVCalibParam& param, Int_t i, Int_t dim) const
index fa632f0..d34f41c 100644 (file)
 #  include "AliMUONVTrackerData.h"
 #endif
 
+class AliMUONSparseHisto;
 class AliMUONVCalibParam;
 class AliMUONVStore;
+class AliMpDetElement;
+class TH1;
 
 class AliMUONTrackerData : public AliMUONVTrackerData
 {
@@ -43,6 +46,8 @@ public:
   virtual Double_t DetectionElement(Int_t detElemId, Int_t dim=0) const;
 
   virtual TString DimensionName(Int_t dim) const;
+  
+  virtual TString ExternalDimensionName(Int_t dim) const;
 
   virtual Bool_t HasChamber(Int_t chamberId) const;
   
@@ -74,19 +79,53 @@ public:
   
   virtual void SetDimensionName(Int_t index, const char* value);  
 
-//protected: FIXME: uncomment when debug done
+  Bool_t CanHistogram() const { return kTRUE; }
+  
+  void SetHistogramDimension(Int_t index, Bool_t value);
+  
+  TH1* CreateChannelHisto(Int_t detElemId, Int_t manuId, 
+                          Int_t manuChannel, Int_t dim=0);
+
+  TH1* CreateBusPatchHisto(Int_t busPatchId, Int_t dim=0);
+  
+  TH1* CreateDEHisto(Int_t detElemId, Int_t dim=0);
+
+  TH1* CreateManuHisto(Int_t detElemId, Int_t manuId, Int_t dim=0);
+
+  TH1* CreatePCBHisto(Int_t detElemId, Int_t pcbIndex, Int_t dim=0);
+  
+  TH1* CreateChamberHisto(Int_t chamberId, Int_t dim=0);
+  
+private:
+    
+  void FillChannel(Int_t detElemId, Int_t manuId, Int_t manuChannel,
+                   Int_t dim, Double_t value);
+
+  AliMUONSparseHisto* GetChannelHisto(Int_t detElemId, Int_t manuId, 
+                                      Int_t manuChannel, Int_t dim=0);
+  
+  AliMUONVCalibParam* BusPatchParam(Int_t busPatch, Bool_t create=kFALSE) const;
+
+  AliMUONVCalibParam* CreateBusPatchParam(Int_t busPatch) const;
+  
+  AliMUONVCalibParam* ChamberParam(Int_t chamberId, Bool_t create=kFALSE) const;
+
+  AliMUONVCalibParam* CreateChamberParam(Int_t chamberId) const;
+  
+  AliMUONVCalibParam* ChannelParam(Int_t detElemId, Int_t manuId,
+                                   AliMUONVCalibParam* external=0x0) const;
 
-  virtual AliMUONVCalibParam* BusPatchParam(Int_t busPatch) const;
+  AliMUONVCalibParam* DetectionElementParam(Int_t detElemId, Bool_t create=kFALSE) const;
 
-  virtual AliMUONVCalibParam* ChamberParam(Int_t chamberId) const;
+  AliMUONVCalibParam* CreateDetectionElementParam(Int_t detElemId) const;
   
-  virtual AliMUONVCalibParam* ChannelParam(Int_t detElemId, Int_t manuId) const;
+  AliMUONVCalibParam* ManuParam(Int_t detElemId, Int_t manuId, Bool_t create=kFALSE) const;
 
-  virtual AliMUONVCalibParam* DetectionElementParam(Int_t detElemId) const;
+  AliMUONVCalibParam* CreateManuParam(Int_t detElemInd, Int_t manuId) const;
   
-  virtual AliMUONVCalibParam* ManuParam(Int_t detElemId, Int_t manuId) const;
+  AliMUONVCalibParam* PCBParam(Int_t detElemId, Int_t pcbIndex, Bool_t create=kFALSE) const;
 
-  virtual AliMUONVCalibParam* PCBParam(Int_t detElemId, Int_t pcbIndex) const;
+  AliMUONVCalibParam* CreatePCBParam(Int_t detElemId, Int_t pcbIndex) const;
   
   /// Index of the dimension containing the number of time an item was hit
   virtual Int_t IndexOfNumberDimension() const { return fDimension - 1; }
@@ -100,17 +139,45 @@ private:
   /// Not implemented
   AliMUONTrackerData& operator=(const AliMUONTrackerData& rhs);
   
+  void Add(TH1& h, const AliMUONSparseHisto& sh);
+  
+  void AddManuHisto(TH1& h, Int_t detElemId, Int_t manuId, Int_t dim);
+
+  void AddBusPatchHisto(TH1& h, Int_t busPatchId, Int_t dim);
+
+  void AddDEHisto(TH1& h, Int_t detElemId, Int_t dim);
+  
+  TH1* CreateHisto(const char* name, Int_t dim) const;
+
   AliMUONVCalibParam* CreateDouble(const AliMUONVCalibParam& param) const;
 
+  Int_t GetParts(AliMUONVCalibParam* external,
+                 AliMUONVCalibParam*& chamber,
+                 AliMUONVCalibParam*& de,
+                 AliMUONVCalibParam*& busPatch,
+                 AliMUONVCalibParam*& pcb,
+                 AliMUONVCalibParam*& manu,
+                 AliMUONVCalibParam*& channel,
+                 AliMpDetElement*& mpde);
+
   /// Convert from external to internal index
   Int_t External2Internal(Int_t index) const { return index*2; }
 
-  Bool_t InternalAdd(const AliMUONVStore& channelValues);
-
   void SetInternalDimensionName(Int_t index, const char* value);  
 
+  void SetExternalDimensionName(Int_t index, const char* value);  
+
   Double_t Value(const AliMUONVCalibParam& param, Int_t i, Int_t dim) const;
-    
+  
+  /// The number of values we actually *store* for each item
+  Int_t Dimension() const { return fDimension; }
+
+  /// The number of values we are inputting
+  Int_t ExternalDimension() const { return fExternalDimension; }
+  
+  /// Whether we have histograms for a given dimension, or not
+  Bool_t IsHistogrammed(Int_t dim) const { return ( fHistogramming[dim] > 0 ); }
+  
 private:
     
   AliMUONVStore* fChannelValues; ///< the channel store
@@ -121,14 +188,18 @@ private:
   AliMUONVStore* fPCBValues; ///< the pcb store
   Int_t fDimension; ///< the dimension of the data
   Int_t fNevents; ///< the number of events treated
-  TObjArray* fDimensionNames; ///< the names of the dimensions
+  TObjArray* fDimensionNames; ///< the names of the (internal) dimensions
+  TObjArray* fExternalDimensionNames; ///< the names of the external (i.e. original) dimensions
   Int_t fExternalDimension; ///< number of interface values per item 
   Bool_t fIsRunnable; ///< whether we can deal with more than one event
+  /// whether we should histogram the dimension(s)
+  Int_t* fHistogramming; //[fExternalDimension] whether we should histogram the dimension(s)
+  AliMUONVStore* fChannelHistos; ///< the channel histograms
   
   static const Int_t fgkExtraDimension; ///< to hold extra information
   static const Int_t fgkVirtualExtraDimension; ///< to give access to information not stored, but computed on the fly
   
-  ClassDef(AliMUONTrackerData,1) // Implementation of AliMUONVTrackerData
+  ClassDef(AliMUONTrackerData,2) // Implementation of AliMUONVTrackerData
 };
 
 #endif
index 4517055..348e8b3 100644 (file)
@@ -17,6 +17,8 @@
 
 #include "AliMUONTrackerRawDataMaker.h"
 
+#include "AliCodeTimer.h"
+#include "AliLog.h"
 #include "AliMUON2DMap.h"
 #include "AliMUONCalibParamND.h"
 #include "AliMUONCalibrationData.h"
 #include "AliRawReader.h"
 #include "AliLog.h"
 #include <Riostream.h>
+#include "AliMUONRawStreamTracker.h"
 
 ///\class AliMUONTrackerRawDataMaker
 ///
-/// Creator of AliMUONVTrackerData from AliRawReader
+/// Creator of raw AliMUONVTrackerData from AliRawReader
 /// 
 ///\author Laurent Aphecetche, Subatech
 
@@ -47,8 +50,7 @@ ClassImp(AliMUONTrackerRawDataMaker)
 Int_t AliMUONTrackerRawDataMaker::fgkCounter(0);
 
 //_____________________________________________________________________________
-AliMUONTrackerRawDataMaker::AliMUONTrackerRawDataMaker(AliRawReader* reader,
-                                                       const char* cdbpath)
+AliMUONTrackerRawDataMaker::AliMUONTrackerRawDataMaker(AliRawReader* reader, Bool_t histogram)
 : AliMUONVTrackerDataMaker(),
   fRawReader(reader),
   fAccumulatedData(0x0),
@@ -56,11 +58,6 @@ AliMUONTrackerRawDataMaker::AliMUONTrackerRawDataMaker(AliRawReader* reader,
   fIsOwner(kTRUE),
   fSource("unspecified"),
   fIsRunning(kFALSE),
-  fDigitMaker(0x0),
-  fDigitCalibrator(0x0),
-  fCalibrationData(0x0),
-  fDigitStore(0x0), 
-  fCDBPath(cdbpath),
   fNumberOfEvents(0)
 {
   /// Ctor
@@ -68,60 +65,26 @@ AliMUONTrackerRawDataMaker::AliMUONTrackerRawDataMaker(AliRawReader* reader,
   
   Int_t runNumber = reader->GetRunNumber();
   
-  ++fgkCounter;
-  
-  Bool_t calibrate = ( fCDBPath.Length() > 0 );
-  
   TString name;
   
   if (!runNumber)
   {
-    name = Form("%s(%d)",(calibrate ? "CAL" : "RAW"),fgkCounter);
+    ++fgkCounter;    
+    name = Form("%sRAW(%d)",(histogram?"H":""),fgkCounter);
   }
   else
   {
-    name = Form("%s%d",(calibrate ? "CAL" : "RAW"),runNumber);
+    name = Form("%sRAW%d",(histogram?"H":""),runNumber);
   }
   
   fAccumulatedData = new AliMUONTrackerData(name.Data(),"charge values",1);
-  fAccumulatedData->SetDimensionName(0,(calibrate ? "Calibrated charge" : "Raw charge"));
-  
-  reader->RewindEvents();
-
-  fDigitMaker = new AliMUONDigitMaker;
-  fDigitMaker->SetMakeTriggerDigits(kFALSE);
-  fDigitStore = new AliMUONDigitStoreV2R;
-
-  if ( calibrate ) 
+  fAccumulatedData->SetDimensionName(0,"Raw charge");
+  if ( histogram ) 
   {
-    fCalibrationData = new AliMUONCalibrationData(runNumber);
-    
-    // force the reading of calibration NOW
-    // FIXME: not really elegant and error prone (as we have the list of calib data twice, 
-    // once here and once in the digitcalibrator class, hence the change of them getting
-    // out of sync)
-    // But with the current CDBManager implementation, I don't know how to solve
-    // this better (e.g. to avoid clearing cache messages and so on).
-    
-    AliCDBStorage* storage = AliCDBManager::Instance()->GetDefaultStorage();
-    
-    if ( storage->GetURI() != fCDBPath.Data() ) 
-    {
-      AliCDBManager::Instance()->SetDefaultStorage(fCDBPath.Data());
-    }
-    
-    fCalibrationData->Pedestals();
-    fCalibrationData->Gains();
-    fCalibrationData->Neighbours();
-    fCalibrationData->HV();
-    
-    if ( storage->GetURI() != fCDBPath.Data() ) 
-    {
-      AliCDBManager::Instance()->SetDefaultStorage(storage);
-    }
-    
-    fDigitCalibrator = new AliMUONDigitCalibrator(*fCalibrationData);
+    fAccumulatedData->SetHistogramDimension(0,kTRUE);
   }
+  
+  reader->RewindEvents();
 }
 
 //_____________________________________________________________________________
@@ -130,11 +93,6 @@ AliMUONTrackerRawDataMaker::~AliMUONTrackerRawDataMaker()
   /// dtor
   delete fOneEventData;
   if ( fIsOwner ) delete fAccumulatedData;
-  delete fRawReader;
-  delete fDigitStore;
-  delete fCalibrationData;
-  delete fDigitMaker;
-  delete fDigitCalibrator;
 }
 
 //_____________________________________________________________________________
@@ -143,16 +101,19 @@ AliMUONTrackerRawDataMaker::NextEvent()
 {
   /// Read next event
  
+  AliCodeTimerAuto("");
+  
   static Int_t nphysics(0);
   static Int_t ngood(0);
 
+  fOneEventData->Clear();
+  
   if ( !IsRunning() ) return kTRUE;
   
   Bool_t ok = fRawReader->NextEvent();
 
   if (!ok) 
   {
-    fDigitMaker->Print();
     return kFALSE;
   }
   
@@ -167,60 +128,40 @@ AliMUONTrackerRawDataMaker::NextEvent()
 
   ++nphysics;
 
-  Int_t rv = fDigitMaker->Raw2Digits(fRawReader,fDigitStore);
+  AliMUONVRawStreamTracker* stream = new AliMUONRawStreamTracker(fRawReader);
+    
+  stream->First();
+    
+  Int_t buspatchId;
+  UShort_t manuId;
+  UChar_t manuChannel;
+       UShort_t adc;
+  
+  while ( stream->Next(buspatchId,manuId,manuChannel,adc) )
+  {    
+    Int_t detElemId = AliMpDDLStore::Instance()->GetDEfromBus(buspatchId);
+    
+    AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fOneEventData->FindObject(detElemId,manuId));
+    if (!param)
+    {
+      param = new AliMUONCalibParamND(1,64,detElemId,manuId,
+                                      AliMUONVCalibParam::InvalidFloatValue());
+      fOneEventData->Add(param);
+    }
+    
+    param->SetValueAsDouble(manuChannel,0,adc);    
+  }    
   
-  if ( ( rv & AliMUONDigitMaker::kTrackerBAD ) != 0 ) return kTRUE;
-
-  if ( fDigitCalibrator ) 
+  if ( !stream->IsErrorMessage() )
   {
-    fDigitCalibrator->Calibrate(*fDigitStore);
+    ++ngood;
+    fAccumulatedData->Add(*fOneEventData);
   }
-  
-  Bool_t dok = ConvertDigits();
-  
-  if ( dok )
-    {
-      ++ngood;
-      fAccumulatedData->Add(*fOneEventData);
-    }
 
   AliDebug(1,Form("n %10d nphysics %10d ngood %10d",fNumberOfEvents,nphysics,ngood));
 
-  return kTRUE;
-}
-
-//_____________________________________________________________________________
-Bool_t 
-AliMUONTrackerRawDataMaker::ConvertDigits()
-{
-  /// Convert digitstore into fOneEventData
-  
-  TIter next(fDigitStore->CreateIterator());
-  AliMUONVDigit* digit;
-
-  fOneEventData->Clear();
+  delete stream;
   
-  while ( ( digit = static_cast<AliMUONVDigit*>(next())) )
-  {
-    Double_t value = ( digit->IsCalibrated() ? digit->Charge() : digit->ADC() );
-
-    if ( value > 0 ) 
-    {
-      Int_t detElemId = digit->DetElemId();
-      Int_t manuId = digit->ManuId();
-    
-      AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fOneEventData->FindObject(detElemId,manuId));
-      if (!param)
-      {
-        param = new AliMUONCalibParamND(1,64,detElemId,manuId,
-                                      AliMUONVCalibParam::InvalidFloatValue());
-        fOneEventData->Add(param);
-      }
-    
-      param->SetValueAsDouble(digit->ManuChannel(),0,value);
-    }
-  }
-
   return kTRUE;
 }
 
index 55bd1a1..e7aaf19 100644 (file)
@@ -8,7 +8,7 @@
 
 /// \ingroup graphics
 /// \class AliMUONTrackerRawDataMaker
-/// \brief Creator of AliMUONVTrackerData from AliRawReader
+/// \brief Creator of raw AliMUONVTrackerData from AliRawReader
 /// 
 // Author Laurent Aphecetche, Subatech
 
 #endif
 
 class AliRawReader;
-class AliMUONCalibrationData;
-class AliMUONDigitCalibrator;
-class AliMUONDigitMaker;
-class AliMUONVTrackerData;
 class AliMUONVStore;
-class AliMUONVDigitStore;
+class AliMUONVTrackerData;
 
 class AliMUONTrackerRawDataMaker : public AliMUONVTrackerDataMaker
 {
 public:
-  AliMUONTrackerRawDataMaker(AliRawReader* reader = 0x0, const char* cdbpath=0x0);
+  AliMUONTrackerRawDataMaker(AliRawReader* reader = 0x0, Bool_t histogram=kFALSE);
   virtual ~AliMUONTrackerRawDataMaker();
   
   /// Whether we have a valid raw reader
@@ -63,11 +59,8 @@ public:
   /// Set our source URI
   void SetSource(const char* source) { fSource = source; }
   
-  /// Get our digit store
-  AliMUONVDigitStore* DigitStore() const { return fDigitStore; }
-  
   /// Number of events seen
-    Int_t NumberOfEvents() const { return fNumberOfEvents; }
+  Int_t NumberOfEvents() const { return fNumberOfEvents; }
 
 private:
   /// Not implemented
@@ -75,8 +68,6 @@ private:
   /// Not implemented
   AliMUONTrackerRawDataMaker& operator=(const AliMUONTrackerRawDataMaker& rhs);
   
-  Bool_t ConvertDigits();
-  
 private:
   AliRawReader* fRawReader; ///< reader of the data (owner)
   AliMUONVTrackerData* fAccumulatedData; ///< data (owner if fIsOwner==kTRUE)
@@ -84,15 +75,10 @@ private:
   Bool_t fIsOwner; ///< whether we are owner of our data or not
   TString fSource; ///< where the data comes from
   Bool_t fIsRunning; ///< whether we are running or are paused
-  AliMUONDigitMaker* fDigitMaker; ///< digit maker
-  AliMUONDigitCalibrator* fDigitCalibrator; ///< digit calibrator (if calibrating data)
-  AliMUONCalibrationData* fCalibrationData; ///< calibration data (if calibrating data)  
-  AliMUONVDigitStore* fDigitStore; ///< digit store (if calibrating data)
-  TString fCDBPath; ///< OCDB path (if calibrating data)
   Int_t fNumberOfEvents; ///< number of events seen
   static Int_t fgkCounter; ///< to count the number of instances
   
-  ClassDef(AliMUONTrackerRawDataMaker,1) // Producer of AliMUONVTrackerData from raw data
+  ClassDef(AliMUONTrackerRawDataMaker,2) // Producer of AliMUONVTrackerData from raw data
 };
 
 #endif
index 3c62a74..ac4eb97 100644 (file)
@@ -49,6 +49,15 @@ AliMUONVTrackerData::~AliMUONVTrackerData()
   /// dtor
 }
 
+//_____________________________________________________________________________
+Bool_t 
+AliMUONVTrackerData::HasChannel(Int_t detElemId, Int_t manuId, Int_t manuChannel) const
+{
+  /// Whether we have data for a given channel
+  
+  return (Count(detElemId,manuId,manuChannel) > 0.0);
+}
+
 //_____________________________________________________________________________
 void 
 AliMUONVTrackerData::NumberOfEventsChanged()
index 0a79df9..131dddb 100644 (file)
@@ -24,6 +24,7 @@
 #endif
 
 class AliMUONVStore;
+class TH1;
 
 class AliMUONVTrackerData : public TNamed
 {
@@ -62,6 +63,9 @@ public:
   /// Whether we have data for a given buspath
   virtual Bool_t HasBusPatch(Int_t busPatchId) const = 0;
 
+  /// Whether we have a given channel or not
+  virtual Bool_t HasChannel(Int_t detElemId, Int_t manuId, Int_t manuChannel) const;
+  
   /// Whether we have data for a given chamber
   virtual Bool_t HasChamber(Int_t chamberId) const = 0;
   
@@ -103,6 +107,31 @@ public:
 
   /// Set the name of a given dimension
   virtual void SetDimensionName(Int_t index, const char* value) = 0;
+
+  /// Whether or not we can make histograms.
+  virtual Bool_t CanHistogram() const { return kFALSE; }
+  
+  /// Select a dimension to be histogrammed (if CanHistogram==kTRUE) only
+  virtual void SetHistogramDimension(Int_t /* index */, Bool_t /* value */) { }
+
+  /// Create (if CanHistogram) an histo for a given channel
+  virtual TH1* CreateChannelHisto(Int_t /*detElemId*/, Int_t /*manuId*/, 
+                                  Int_t /*manuChannel*/, Int_t /*dim*/=0) { return 0x0; }
+  
+  /// Create (if CanHistogram) an histo for a given bus patch
+  virtual TH1* CreateBusPatchHisto(Int_t /*busPatchId*/, Int_t /*dim*/=0)  { return 0x0; }
+  
+  /// Create (if CanHistogram) an histo for a given detection element
+  virtual TH1* CreateDEHisto(Int_t /*detElemId*/, Int_t /*dim*/=0)  { return 0x0; }
+  
+  /// Create (if CanHistogram) an histo for a given manu
+  virtual TH1* CreateManuHisto(Int_t /*detElemId*/, Int_t /*manuId*/, Int_t /*dim*/=0)  { return 0x0; }
+  
+  /// Create (if CanHistogram) an histo for a given pcb
+  virtual TH1* CreatePCBHisto(Int_t /*detElemId*/, Int_t /*pcbIndex*/, Int_t /*dim*/=0)  { return 0x0; }
+  
+  /// Create (if CanHistogram) an histo for a given chamber
+  virtual TH1* CreateChamberHisto(Int_t /*chamberId*/, Int_t /*dim*/=0)  { return 0x0; }
   
 private:
   /// not implemented
index 25b322e..ec171de 100644 (file)
@@ -39,6 +39,8 @@
 #pragma link C++ class AliMUONVTrackerDataMaker+;
 #pragma link C++ class AliMUONTrackerData+;
 #pragma link C++ class AliMUONTrackerRawDataMaker+;
+#pragma link C++ class AliMUONTrackerCalibratedDataMaker+;
 #pragma link C++ class AliMUONMchViewApplication+;
+#pragma link C++ class AliMUONSparseHisto+;
 
 #endif
index a5b0a21..f3ed221 100644 (file)
@@ -61,8 +61,11 @@ From top to bottom, you'll see group of frames used to :
 
 - select from a list of recently used source
 
-- select a raw data source (either by typing in its full pathname, or opening a file dialog). The second text field in this group is to specify the
-location of the OCDB to be used (if any). If that field is not empty (and the corresponding entry is correct, of course), the raw data will be calibrated.
+- select a raw data source (either by typing in its full pathname, or opening a file dialog). 
+The second line in this group is to specify that you want to calibrate the data. Check the calibrate button, and specify the
+location of the OCDB to be used. If that field is not empty (and the corresponding entry is correct, of course), 
+the raw data will be calibrated.
+The last line in that group is a single check button, to instruct the program to produce histograms of the data (see \ref mchview_histogramming)
 
 - select an OCDB data source (pedestals, gains, capacitances)
 
@@ -70,6 +73,12 @@ In all the frames, once you've selected or entered the needed information, you'l
 and a new data source line will appear in the bottom of that tab (and in also in the first tab, that data source will now 
 be selectable for plotting). Each data source line indicates the short name of the data source, the full path, and a list of buttons to run, stop, rewind and
 remove. Run/Stop/Rewind is only selectable for data sources where the notion of event means something (e.g. for pedestals it won't).
+The short name of the data source is as follow :
+
+- RAW# : raw data for run #
+- RAW(#) : raw data for simulated run (where run number is always 0, so # here is the number of such data sources opened at the same time)
+- HRAW# (or HRAW(#)) : as above, but with histogramming turned on
+- CAL# (or CAL(#)): as above, but for calibrated data.
 
 Note that all the file paths can be local ones or alien ones, if you have a correctly installed alien, and you use a short wrapped to call the \em mchview program.
 For instance :
@@ -98,6 +107,31 @@ export alien_API_USER=youralienuserid # only needed if different from your local
 mchview $*
 </pre>
 
+\section mchview_histogramming Histogramming
+
+Starting at version 0.9 of the \em mchview program, you can now produce histograms of the raw adc values, while running over the
+data. For this you have to check the "histogram" button when creating the data source. Please note that turning on the histogram will slow down
+a bit the data reading. 
+Histograms produced by the program are as compact as possible in order to fit in memory (so they are *not* plain TH1 objects).
+Plain TH1 objects are produced later on (on request only), and should be deleted as soon as possible (you have to realize that
+1 million TH1 of 4096 channels has no chance to fit in memory...)
+For the moment, access to the histograms cannot be done through the GUI. So you have to use the root prompt (of the \em mchview program itself).
+First get the data object, and then ask the data object to create the histogram(s) you want. Remember to delete those histograms as soon
+as you no longer need them :
+
+<pre>
+AliMUONPainterRegistry* reg = AliMUONPainterRegistry::Instance();
+reg->Print();
+AliMUONVTrackerData* data = reg->FindDataSource("HRAW(1)");
+TH1* h = data->CreateChannelHisto(707,1025,63);
+h->Draw();
+delete h;
+h = data->CreateManuHisto(707,1025);
+etc...
+</pre>
+
+You can get histograms for all levels (except PCB) : channel, manu, bus patch, detection element, chamber. See AliMUONVTrackerData doc. for the methods.
+
 ---------
 
 IMPORTANT WARNINGS
index 4fc021d..51ec8c1 100644 (file)
@@ -30,7 +30,9 @@ SRCS:=  AliMUONVPainter.cxx \
   AliMUONVTrackerDataMaker.cxx \
   AliMUONTrackerData.cxx \
   AliMUONTrackerRawDataMaker.cxx \
-  AliMUONMchViewApplication.cxx
+  AliMUONTrackerCalibratedDataMaker.cxx \
+  AliMUONMchViewApplication.cxx \
+  AliMUONSparseHisto.cxx
     
 HDRS:= $(SRCS:.cxx=.h)