]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PHOS/AliPHOS.cxx
New AliTRDcluster constructor
[u/mrichter/AliRoot.git] / PHOS / AliPHOS.cxx
index 34b1634e9fd81099855c0c06ec70f84db3b2cc39..a5ee04d407c2c9103c9a0cede3749728593bfd51 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 /* $Id$ */
+/* History of cvs commits:
+ *
+ * $Log$
+ * Revision 1.111  2007/02/18 15:21:47  kharlov
+ * Corrections for memory leak in Digits2Raw due to AliAltroMapping
+ *
+ * Revision 1.110  2007/02/13 10:52:08  policheh
+ * Raw2SDigits() implemented
+ *
+ * Revision 1.109  2007/02/05 10:43:25  hristov
+ * Changes for correct initialization of Geant4 (Mihaela)
+ *
+ * Revision 1.108  2007/02/01 10:34:47  hristov
+ * Removing warnings on Solaris x86
+ *
+ * Revision 1.107  2007/01/29 16:29:37  kharlov
+ * Digits2Raw(): special workaround for digits with time out of range
+ *
+ * Revision 1.106  2007/01/17 17:28:56  kharlov
+ * Extract ALTRO sample generation to a separate class AliPHOSPulseGenerator
+ *
+ * Revision 1.105  2007/01/12 21:44:29  kharlov
+ * Simulate and reconstruct two gains simulaneouslsy
+ *
+ * Revision 1.104  2006/11/23 13:40:44  hristov
+ * Common class for raw data reading and ALTRO mappiing for PHOS and EMCAL (Gustavo, Cvetan)
+ *
+ * Revision 1.103  2006/11/14 17:11:15  hristov
+ * Removing inheritances from TAttLine, TAttMarker and AliRndm in AliModule. The copy constructor and assignment operators are moved to the private part of the class and not implemented. The corresponding changes are propagated to the detectors
+ *
+ * Revision 1.102  2006/10/27 17:14:27  kharlov
+ * Introduce AliDebug and AliLog (B.Polichtchouk)
+ *
+ * Revision 1.101  2006/10/13 06:47:29  kharlov
+ * Simulation of RAW data applies real mapping (B.Polichtchouk)
+ *
+ * Revision 1.100  2006/08/11 12:36:26  cvetan
+ * Update of the PHOS code needed in order to read and reconstruct the beam test raw data (i.e. without an existing galice.root)
+ *
+ * Revision 1.99  2006/06/28 11:36:09  cvetan
+ * New detector numbering scheme (common for DAQ/HLT/Offline). All the subdetectors shall use the AliDAQ class for the sim and rec of the raw data. The AliDAQ and raw reader classes now provide all the necessary interfaces to write and select the detector specific raw-data payload. Look into the AliDAQ.h and AliRawReader.h for more details.
+ *
+ * Revision 1.98  2006/05/11 11:30:48  cvetan
+ * Major changes in AliAltroBuffer. Now it can be used only for writing of raw data. All the corresponding read method are removed. It is based now on AliFstream in order to avoid endianess problems. The altro raw data is written always with little endian
+ *
+ * Revision 1.97  2006/04/22 10:30:17  hristov
+ * Add fEnergy to AliPHOSDigit and operate with EMC amplitude in energy units (Yu.Kharlov)
+ *
+ * Revision 1.96  2006/04/07 08:41:59  hristov
+ * Follow AliAlignObj framework and remove AliPHOSAlignData (Yu.Kharlov)
+ *
+ * Revision 1.95  2006/03/14 19:40:41  kharlov
+ * Remove De-digitizing of raw data and digitizing the raw data fit
+ *
+ * Revision 1.94  2006/03/07 18:56:25  kharlov
+ * CDB is passed via environment variable
+ *
+ * Revision 1.93  2005/11/22 08:45:11  kharlov
+ * Calibration is read from CDB if any (Boris Polichtchouk)
+ *
+ * Revision 1.92  2005/11/03 13:09:19  hristov
+ * Removing meaningless const declarations (linuxicc)
+ *
+ * Revision 1.91  2005/07/27 15:08:53  kharlov
+ * Mixture ArCO2 is corrected
+ *
+ * Revision 1.90  2005/06/17 07:39:07  hristov
+ * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
+ *
+ * Revision 1.89  2005/05/28 12:10:07  schutz
+ * Copy constructor is corrected (by T.P.)
+ *
+ */
 
 //_________________________________________________________________________
 // Base Class for PHOS description:
@@ -30,53 +103,52 @@ class TFile;
 #include <TFolder.h> 
 #include <TTree.h>
 #include <TVirtualMC.h> 
+#include <TH1F.h> 
+#include <TF1.h> 
+#include <TRandom.h> 
 
 // --- Standard library ---
 
 // --- AliRoot header files ---
 #include "AliMagF.h"
-#include "AliESDtrack.h" 
-#include "AliESD.h"
 #include "AliPHOS.h"
 #include "AliPHOSGetter.h"
-#include "AliPHOSQAChecker.h"
 #include "AliRun.h"
 #include "AliPHOSDigitizer.h"
 #include "AliPHOSSDigitizer.h"
-#include "AliPHOSReconstructor.h"
+#include "AliPHOSDigit.h"
+#include "AliAltroBuffer.h"
+#include "AliAltroMapping.h"
+#include "AliCaloAltroMapping.h"
+#include "AliLog.h"
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
+#include "AliCDBStorage.h"
+#include "AliPHOSCalibData.h"
+#include "AliPHOSPulseGenerator.h"
+#include "AliDAQ.h"
+#include "AliPHOSRawDecoder.h"
+#include "AliPHOSRawDigiProducer.h"
+
 ClassImp(AliPHOS)
+
 //____________________________________________________________________________
-AliPHOS:: AliPHOS() : AliDetector()
+  AliPHOS:: AliPHOS() : AliDetector()
 {
   // Default ctor
-  fName="PHOS";
-  fQATask = 0;
-  fTreeQA = 0;
-  fDebug = kFALSE ; 
+  fName   = "PHOS" ;
+
 }
 
 //____________________________________________________________________________
-AliPHOS::AliPHOS(const char* name, const char* title): AliDetector(name, title) 
+AliPHOS::AliPHOS(const char* name, const char* title): AliDetector(name, title)
 {
   //   ctor : title is used to identify the layout
-  
-  fQATask = 0;
-  fTreeQA = 0;
-  fDebug = kFALSE ; 
 }
 
 //____________________________________________________________________________
 AliPHOS::~AliPHOS() 
 {  
-  
-}
-
-//____________________________________________________________________________
-void AliPHOS::Copy(AliPHOS & phos)
-{
-  TObject::Copy(phos) ; 
-  //  fQATask = AliPHOSQAChecker::Copy(*(phos.fQATask)) ; 
-  phos.fTreeQA = fTreeQA->CloneTree() ; 
 }
 
 //____________________________________________________________________________
@@ -149,7 +221,7 @@ void AliPHOS::CreateMaterials()
 
   AliMixture(7, "Thermo Insul.$", aTI, zTI, dTI, -2, wTI) ;
 
-  // --- Textolitn ---
+  // --- Textolith ---
   Float_t aTX[4] = {16.0, 28.09, 12.011, 1.00794} ;
   Float_t zTX[4] = {8.0, 14.0, 6.0, 1.0} ;
   Float_t wTX[4] = {292.0, 68.0, 462.0, 736.0} ;
@@ -158,12 +230,12 @@ void AliPHOS::CreateMaterials()
   AliMixture(8, "Textolit$", aTX, zTX, dTX, -4, wTX) ;
 
   //--- FR4  ---
-  Float_t aFR[3] = {28.0855, 15.9994, 17.749} ; 
-  Float_t zFR[3] = {14., 8., 8.875} ; 
-  Float_t wFR[3] = {.28, .32, .4} ;
+  Float_t aFR[4] = {16.0, 28.09, 12.011, 1.00794} ;
+  Float_t zFR[4] = {8.0, 14.0, 6.0, 1.0} ;
+  Float_t wFR[4] = {292.0, 68.0, 462.0, 736.0} ;
   Float_t dFR = 1.8 ; 
 
-  AliMixture(9, "FR4$", aFR, zFR, dFR, -3, wFR) ;
+  AliMixture(9, "FR4$", aFR, zFR, dFR, -4, wFR) ;
 
   // --- The Composite Material for  micromegas (so far polyetylene) ---                                       
   Float_t aCM[2] = {12.01, 1.} ; 
@@ -200,30 +272,16 @@ void AliPHOS::CreateMaterials()
   Float_t dAr = 0.001782 ; 
   AliMaterial(15, "Ar$", 39.948, 18.0, dAr, 14.0, 0., 0, 0) ;   
  
- // ArCo2
-  Char_t namate[21]="";
-  Float_t aGM[2] ; 
-  Float_t zGM[2] ; 
-  Float_t wGM[2] ; 
-  Float_t dGM ; 
-
-  Float_t absL, radL, density ;
-  Float_t buf[1] ;
-  Int_t nbuf ;
-
-  gMC->Gfmate((*fIdmate)[15], namate, aGM[0], zGM[0], density, radL, absL, buf, nbuf) ; // Get properties of Ar 
-  gMC->Gfmate((*fIdmate)[14], namate, aGM[1], zGM[1], density, radL, absL, buf, nbuf) ; // Get properties of CO2 
-
-
-  // Create gas mixture 
-
-  Float_t arContent    = 0.80 ;  // Ar-content of the Ar/CO2-mixture (80% / 20%) 
-  wGM[0] = arContent;
-  wGM[1] = 1. - arContent ;
-  dGM    = wGM[0] * dAr + wGM[1] * dCO;
-
-  AliMixture(16, "ArCO2$", aGM, zGM, dGM,  2, wGM) ;
+  // Ar+CO2 Mixture (80% / 20%)
+  Float_t arContent = 0.80 ;  // Ar-content of the ArCO2-mixture
+  Float_t aArCO[3]  = {39.948, 12.0, 16.0} ;
+  Float_t zArCO[3]  = {18.0  ,  6.0,  8.0} ;
+  Float_t wArCO[3];
+  wArCO[0] = arContent;
+  wArCO[1] = (1-arContent)*1;
+  wArCO[2] = (1-arContent)*2;
+  Float_t dArCO = arContent*dAr + (1-arContent)*dCO ;
+  AliMixture(16, "ArCO2$", aArCO, zArCO, dArCO,  -3, wArCO) ;
 
   // --- Stainless steel (let it be pure iron) ---
   AliMaterial(17, "Steel$", 55.845, 26, 7.87, 1.76, 0., 0, 0) ;
@@ -248,16 +306,17 @@ void AliPHOS::CreateMaterials()
   AliMixture(19, "Cables  $", aCA, zCA, dCA, -4, wCA) ;
 
 
-
   // --- Air ---
-  AliMaterial(99, "Air$", 14.61, 7.3, 0.001205, 30420., 67500., 0, 0) ;
-  
+  Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
+  Float_t zAir[4]={6.,7.,8.,18.};
+  Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
+  Float_t dAir = 1.20479E-3;
  
+  AliMixture(99, "Air$", aAir, zAir, dAir, 4, wAir) ;
+
   // DEFINITION OF THE TRACKING MEDIA
 
   // for PHOS: idtmed[699->798] equivalent to fIdtmed[0->100]
-  Int_t * idtmed = fIdtmed->GetArray() - 699 ; 
   Int_t   isxfld = gAlice->Field()->Integ() ;
   Float_t sxmgmx = gAlice->Field()->Max() ;
 
@@ -340,8 +399,16 @@ void AliPHOS::CreateMaterials()
   // Air                                                                            -> idtmed[798] 
   AliMedium(99, "Air          $", 99, 0,
             isxfld, sxmgmx, 10.0, 1.0, 0.1, 0.1, 10.0, 0, 0) ;
+}
 
+//_____________________________________________________________________________
+void AliPHOS::Init()
+{
+  //
+  // Initialises cuts for PHOS
+  //
   // --- Set decent energy thresholds for gamma and electron tracking
+  Int_t * idtmed = fIdtmed->GetArray() - 699 ; 
 
   // Tracking threshold for photons and electrons in the scintillator crystal 
   gMC->Gstpar(idtmed[699], "CUTGAM",0.5E-4) ; 
@@ -373,68 +440,171 @@ void AliPHOS::CreateMaterials()
   gMC->Gstpar(idtmed[715], "LOSS",2.) ;
   gMC->Gstpar(idtmed[715], "DRAY",0.) ;
   gMC->Gstpar(idtmed[715], "STRA",2.) ;
-
 }
 
 //____________________________________________________________________________
-void AliPHOS::FillESD(AliESD* esd) const 
+void AliPHOS::Digits2Raw()
 {
-  // Called by AliReconstruct after Reconstruct() and global tracking and vertxing
-
-  //Creates the tracksegments and Recparticles
-  AliPHOSReconstructor * rec = new AliPHOSReconstructor((fLoader->GetRunLoader()->GetFileName()).Data()) ; 
-  TList * taskslist = rec->GetListOfTasks() ; 
-  Int_t index ;
-  TTask * task ; 
-  TString name ; 
- // set clusterizer task inactive 
-  for (index = 0; index < taskslist->GetSize(); index++) {
-    task = dynamic_cast<TTask *>(taskslist->At(index)) ; 
-    name = task->GetName() ; 
-    if ( name.Contains(AliConfig::Instance()->GetReconstructionerTaskName()))
-      task->SetActive(kFALSE) ; 
-    if ( name.Contains(AliConfig::Instance()->GetTrackerTaskName()))
-      (dynamic_cast<AliPHOSTrackSegmentMaker *> (task))->SetESD(esd) ; 
+// convert digits of the current event to raw data
+  
+  AliPHOSLoader * loader = dynamic_cast<AliPHOSLoader*>(fLoader) ; 
+
+  // get the digits
+  loader->LoadDigits();
+  TClonesArray* digits = loader->Digits() ;
+
+  if (!digits) {
+    AliError(Form("No digits found !"));
+    return;
   }
 
-  AliPHOSGetter *gime = AliPHOSGetter::Instance( (fLoader->GetRunLoader()->GetFileName()).Data() ) ;
-  Int_t eventNumber = gime->EventNumber();
-  rec->SetEventRange(eventNumber, eventNumber) ; // do current event; the loop over events is done by AliReconstruction::Run()
-  if ( Debug() ) 
-    rec->ExecuteTask("deb all") ;
-  else 
-    rec->ExecuteTask("") ;
-
-  // Creates AliESDtrack from AliPHOSRecParticles 
-  gime->Event(eventNumber, "P") ; 
-  TClonesArray *recParticles = gime->RecParticles();
-  Int_t nOfRecParticles = recParticles->GetEntries();
-  for (Int_t recpart = 0 ; recpart < nOfRecParticles ; recpart++) {
-    AliPHOSRecParticle * rp = dynamic_cast<AliPHOSRecParticle*>(recParticles->At(recpart));
-    if (Debug()) 
-      rp->Print();
-    AliESDtrack * et = new AliESDtrack() ; 
-    // fills the ESDtrack
-    Double_t xyz[3];
-    for (Int_t ixyz=0; ixyz<3; ixyz++) xyz[ixyz] = rp->GetPos()[ixyz];
-    et->SetPHOSposition(xyz) ; 
-    et->SetPHOSsignal  (rp->Energy()) ; 
-    et->SetPHOSpid     (rp->GetPID()) ;
-    // add the track to the esd object
-    esd->AddTrack(et);
-    delete et;
+  // get the geometry
+  AliPHOSGeometry* geom = GetGeometry();
+  if (!geom) {
+    AliError(Form("No geometry found !"));
+    return;
   }
-}       
+
+  // some digitization constants
+  const Float_t    kThreshold = 0.001; // skip digits below 1 MeV
+  const Int_t      kAdcThreshold = 1;  // Lower ADC threshold to write to raw data
+
+  Int_t prevDDL = -1;
+
+  // Create a shaper pulse object
+  AliPHOSPulseGenerator *pulse = new AliPHOSPulseGenerator();
+  
+  Int_t *adcValuesLow = new Int_t[pulse->GetRawFormatTimeBins()];
+  Int_t *adcValuesHigh= new Int_t[pulse->GetRawFormatTimeBins()];
+  
+  const Int_t maxDDL = 20;
+  AliAltroBuffer  *buffer[maxDDL];
+  AliAltroMapping *mapping[maxDDL];
+
+  for(Int_t jDDL=0; jDDL<maxDDL; jDDL++) {
+    buffer[jDDL]=0;
+    mapping[jDDL]=0;
+  }
+
+  //!!!!for debug!!!
+  Int_t modMax=-111;
+  Int_t colMax=-111;
+  Int_t rowMax=-111;
+  Float_t eMax=-333;
+  //!!!for debug!!!
+
+  // loop over digits (assume ordered digits)
+  for (Int_t iDigit = 0; iDigit < digits->GetEntries(); iDigit++) {
+    AliPHOSDigit* digit = dynamic_cast<AliPHOSDigit *>(digits->At(iDigit)) ;
+    if (digit->GetEnergy() < kThreshold) 
+      continue;
+    Int_t relId[4];
+    geom->AbsToRelNumbering(digit->GetId(), relId);
+    Int_t module = relId[0];
+    // Begin FIXME 
+    if (relId[1] != 0) 
+      continue;    // ignore digits from CPV
+    // End FIXME 
+
+    Int_t row = relId[2]-1;
+    Int_t col = relId[3]-1;
+
+    Int_t iRCU = -111;
+
+    //RCU0
+    if(0<=row&&row<32 && 0<=col&&col<28) iRCU=0;
+
+    //RCU1
+    if(0<=row&&row<32 && 28<=col&&col<56) iRCU=1;
+
+    //RCU2
+    if(32<=row&&row<64 && 0<=col&&col<28) iRCU=2;
+
+    //RCU3
+    if(32<=row&&row<64 && 28<=col&&col<56) iRCU=3;
+
+
+    // PHOS EMCA has 4 DDL per module. Splitting is based on the (row,column) numbers.
+    // PHOS internal convention: 1<module<5.
+    Int_t iDDL = 4 * (module - 1) + iRCU;
+
+    // new DDL
+    if (iDDL != prevDDL) {
+      if (buffer[iDDL] == 0) {
+       // open new file and write dummy header
+       TString fileName = AliDAQ::DdlFileName("PHOS",iDDL);
+
+       TString path = gSystem->Getenv("ALICE_ROOT");
+       path += "/PHOS/mapping/RCU";
+       path += iRCU;
+       path += ".data";
+
+       mapping[iDDL] = new AliCaloAltroMapping(path.Data());
+       buffer[iDDL]  = new AliAltroBuffer(fileName.Data(),mapping[iDDL]);
+       buffer[iDDL]->WriteDataHeader(kTRUE, kFALSE);  //Dummy;
+      }
+      prevDDL = iDDL;
+    }
+
+    AliDebug(2,Form("digit E=%.4f GeV, t=%g s, (mod,col,row)=(%d,%d,%d)\n",
+                   digit->GetEnergy(),digit->GetTimeR(),
+                   relId[0]-1,relId[3]-1,relId[2]-1));
+    // if a signal is out of time range, write only trailer
+    if (digit->GetTimeR() > pulse->GetRawFormatTimeMax()*0.5 ) {
+      AliInfo("Signal is out of time range.\n");
+      buffer[iDDL]->FillBuffer(0);
+      buffer[iDDL]->FillBuffer(pulse->GetRawFormatTimeBins() );  // time bin
+      buffer[iDDL]->FillBuffer(3);                               // bunch length
+      buffer[iDDL]->WriteTrailer(3, relId[3]-1, relId[2]-1, 0);  // trailer
+      
+    // calculate the time response function
+    } else {
+      Double_t energy = 0 ;
+      module = relId[0];
+      if (digit->GetId() <= geom->GetNModules() * geom->GetNCristalsInModule()) {
+       energy=digit->GetEnergy();
+       if(energy>eMax) {eMax=energy; modMax=module; colMax=col; rowMax=row;}
+      }
+      else {
+       energy = 0; // CPV raw data format is now know yet
+      }
+      pulse->SetAmplitude(energy);
+      pulse->SetTZero(digit->GetTimeR());
+      pulse->MakeSamples();
+      pulse->GetSamples(adcValuesHigh, adcValuesLow) ; 
+      buffer[iDDL]->WriteChannel(relId[3]-1, relId[2]-1, 0, 
+                          pulse->GetRawFormatTimeBins(), adcValuesLow , kAdcThreshold);
+      buffer[iDDL]->WriteChannel(relId[3]-1, relId[2]-1, 1, 
+                          pulse->GetRawFormatTimeBins(), adcValuesHigh, kAdcThreshold);
+    }
+  }
+  
+  // write real header and close last file
+  for (Int_t iDDL=0; iDDL<maxDDL; iDDL++) {
+    if (buffer[iDDL]) {
+      buffer[iDDL]->Flush();
+      buffer[iDDL]->WriteDataHeader(kFALSE, kFALSE);
+      delete buffer[iDDL];
+      if (mapping[iDDL]) delete mapping[iDDL];
+    }
+  }
+  
+  AliDebug(1,Form("Digit with max. energy:  modMax %d colMax %d rowMax %d  eMax %f\n",
+        modMax,colMax,rowMax,eMax));
+
+  delete pulse;
+  loader->UnloadDigits();
+}
 
 //____________________________________________________________________________
 void AliPHOS::Hits2SDigits()  
 { 
 // create summable digits
 
-  AliPHOSSDigitizer* phosDigitizer = 
-    new AliPHOSSDigitizer(fLoader->GetRunLoader()->GetFileName().Data()) ;
-  phosDigitizer->SetEventRange(0, -1) ; // do all the events
-  phosDigitizer->ExecuteTask("all") ;
+  AliPHOSSDigitizer phosDigitizer(fLoader->GetRunLoader()->GetFileName().Data()) ;
+  phosDigitizer.SetEventRange(0, -1) ; // do all the events
+  phosDigitizer.ExecuteTask("all") ; 
 }
 
 //____________________________________________________________________________
@@ -453,76 +623,48 @@ void AliPHOS::SetTreeAddress()
   TBranch *branch;
   char branchname[20];
   sprintf(branchname,"%s",GetName());
-  
   // Branch address for hit tree
-  TTree *treeH = TreeH();
+    TTree *treeH = TreeH();
   if (treeH) {
     branch = treeH->GetBranch(branchname);
     if (branch) 
      { 
        if (fHits == 0x0) fHits= new TClonesArray("AliPHOSHit",1000);
-       //Info("SetTreeAddress","<%s> Setting Hits Address",GetName());
+       //AliInfo(Form("<%s> Setting Hits Address",GetName()));
        branch->SetAddress(&fHits);
      }
   }
 }
 
 //____________________________________________________________________________
-void AliPHOS::Reconstruct() const 
-{ 
-  // method called by AliReconstruction; it should not be called otherwise but the AliPHOSReconstructionner 
-  // should be called for stand alone reconstruction.
-  // Only the clusterization is performed,; the rest of the reconstruction is done in FillESD because the track
-  // segment maker needs access to the AliESD object to retrieve the tracks reconstructed by 
-  // the global tracking.
-  AliPHOSReconstructor * rec = new AliPHOSReconstructor((fLoader->GetRunLoader()->GetFileName()).Data()) ; 
-  TList * taskslist = rec->GetListOfTasks() ; 
-  Int_t index ;
-  TTask * task ; 
-  TString name ; 
-  // set all tasks inactive except clusterizer
-  for (index = 0; index < taskslist->GetSize(); index++) {
-    task = dynamic_cast<TTask *>(taskslist->At(index)) ; 
-    name = task->GetName() ; 
-    if ( !name.Contains(AliConfig::Instance()->GetReconstructionerTaskName()))
-      task->SetActive(kFALSE) ; 
+Bool_t AliPHOS::Raw2SDigits(AliRawReader* rawReader)
+{
+
+  AliPHOSLoader * loader = dynamic_cast<AliPHOSLoader*>(fLoader) ;
+
+  TTree * tree = 0 ;
+  tree = loader->TreeS() ;
+  if ( !tree ) {
+    loader->MakeTree("S");
+    tree = loader->TreeS() ;
   }
-  rec->SetEventRange(0, -1) ; // do all the events
-  if ( Debug() ) 
-    rec->ExecuteTask("deb all") ; 
-  else 
-    rec->ExecuteTask("") ; 
-  
-}
 
-//____________________________________________________________________________
-void AliPHOS::WriteQA()
-{
+  TClonesArray * sdigits = loader->SDigits() ;
+  if(!sdigits) { 
+    loader->MakeSDigitsArray();
+    sdigits = loader->SDigits();
+  }
+  sdigits->Clear();
 
-  // Make TreeQA in the output file. 
+  AliPHOSRawDecoder dc(rawReader);
+  AliPHOSRawDigiProducer pr;
+  pr.MakeDigits(sdigits,&dc);
 
-  if(fTreeQA == 0)
-    fTreeQA = new TTree("TreeQA", "QA Alarms") ;    
-  // Create Alarms branches
-  Int_t bufferSize = 32000 ;    
-  Int_t splitlevel = 0 ; 
+  Int_t bufferSize = 32000 ;
+  TBranch * sdigitsBranch = tree->Branch("PHOS",&sdigits,bufferSize);
+  tree->Fill();
 
-  TFolder* topfold = GetLoader()->GetTopFolder(); //get top aliroot folder; skowron
-  TString phosqafn(AliConfig::Instance()->GetQAFolderName()+"/"); //get name of QAaut folder relative to top event; skowron
-  phosqafn+=GetName(); //hard wired string!!! add the detector name to the pathname; skowron 
-  TFolder * alarmsF = (TFolder*)topfold->FindObjectAny(phosqafn); //get the folder
-  if (alarmsF == 0x0)
-   {
-     Error("WriteQA","Can not find folder with qa alarms");
-     return;
-   }
-  TString branchName(alarmsF->GetName());
-  TBranch * alarmsBranch = fTreeQA->Branch(branchName,"TFolder", &alarmsF, bufferSize, splitlevel);
-  TString branchTitle = branchName + " QA alarms" ; 
-  alarmsBranch->SetTitle(branchTitle);
-  alarmsBranch->Fill() ; 
-
-  //fTreeQA->Fill() ; 
+  fLoader->WriteSDigits("OVERWRITE");
+  return kTRUE;
+    
 }