Updated SSD handler (S. Borysov)
authormasera <masera@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 4 Jun 2008 15:21:26 +0000 (15:21 +0000)
committermasera <masera@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 4 Jun 2008 15:21:26 +0000 (15:21 +0000)
ITS/AliITSHandleDaSSD.cxx
ITS/AliITSHandleDaSSD.h
ITS/ITSSSDPEDda.cxx

index b4d2970..f4ff41e 100644 (file)
@@ -23,6 +23,8 @@
 //  Date: 19/05/2008
 ///////////////////////////////////////////////////////////////////////////////
 
+#include <string>
+#include <fstream>
 #include <Riostream.h> 
 #include "AliITSHandleDaSSD.h"
 #include <math.h>
@@ -49,10 +51,16 @@ using namespace std;
 const Int_t    AliITSHandleDaSSD::fgkNumberOfSSDModules = 1698;       // Number of SSD modules in ITS
 const Int_t    AliITSHandleDaSSD::fgkNumberOfSSDModulesPerDdl = 108;  // Number of SSD modules in DDL
 const Int_t    AliITSHandleDaSSD::fgkNumberOfSSDModulesPerSlot = 12;  // Number of SSD modules in Slot
+const Int_t    AliITSHandleDaSSD::fgkNumberOfSSDSlotsPerDDL = 9;      // Number of SSD slots per DDL
 const Int_t    AliITSHandleDaSSD::fgkNumberOfSSDDDLs = 16;            // Number of SSD modules in Slot
 const Float_t  AliITSHandleDaSSD::fgkPedestalThresholdFactor = 3.0;   // Defalt value for fPedestalThresholdFactor 
 const Float_t  AliITSHandleDaSSD::fgkCmThresholdFactor = 3.0;         // Defalt value for fCmThresholdFactor
 
+const UInt_t   AliITSHandleDaSSD::fgkZsBitMask      = 0x0000003F;     // Bit mask for FEROM ZS
+const UInt_t   AliITSHandleDaSSD::fgkOffSetBitMask  = 0x000003FF;     // Bit mask for FEROM Offset correction
+const UInt_t   AliITSHandleDaSSD::fgkBadChannelMask = 0x00000001;     // Mask to suppress the channel from the bad channel list
+const Int_t    AliITSHandleDaSSD::fgkAdcPerDBlock   = 6;              // FEROM configuration file constant
+
 //______________________________________________________________________________
 AliITSHandleDaSSD::AliITSHandleDaSSD() :
   fRawDataFileName(NULL),
@@ -67,7 +75,10 @@ AliITSHandleDaSSD::AliITSHandleDaSSD() :
   fLdcId(0),
   fRunId(0),
   fPedestalThresholdFactor(fgkPedestalThresholdFactor),
-  fCmThresholdFactor(fgkCmThresholdFactor) 
+  fCmThresholdFactor(fgkCmThresholdFactor),
+  fZsDefault(-1),
+  fOffsetDefault(INT_MAX),
+  fZsFactor(3.0)
 {
 // Default constructor
 }
@@ -87,7 +98,10 @@ AliITSHandleDaSSD::AliITSHandleDaSSD(Char_t *rdfname) :
   fLdcId(0),
   fRunId(0),
   fPedestalThresholdFactor(fgkPedestalThresholdFactor) ,
-  fCmThresholdFactor(fgkCmThresholdFactor) 
+  fCmThresholdFactor(fgkCmThresholdFactor),
+  fZsDefault(-1),
+  fOffsetDefault(INT_MAX),
+  fZsFactor(3.0)
 {
   if (!Init(rdfname)) AliError("AliITSHandleDaSSD::AliITSHandleDaSSD() initialization error!");
 }
@@ -108,7 +122,10 @@ AliITSHandleDaSSD::AliITSHandleDaSSD(const AliITSHandleDaSSD& ssdadldc) :
   fLdcId(ssdadldc.fLdcId),
   fRunId(ssdadldc.fRunId),
   fPedestalThresholdFactor(ssdadldc.fPedestalThresholdFactor),
-  fCmThresholdFactor(ssdadldc.fCmThresholdFactor) 
+  fCmThresholdFactor(ssdadldc.fCmThresholdFactor),
+  fZsDefault(ssdadldc.fZsDefault),
+  fOffsetDefault(ssdadldc.fOffsetDefault),
+  fZsFactor(ssdadldc.fZsFactor)
 {
   // copy constructor
   if ((ssdadldc.fNumberOfModules > 0) && (ssdadldc.fModules)) {
@@ -219,7 +236,7 @@ void AliITSHandleDaSSD::Reset()
 
 
 //______________________________________________________________________________
-Bool_t AliITSHandleDaSSD::Init(Char_t *rdfname, const Char_t *configfname)
+Bool_t AliITSHandleDaSSD::Init(Char_t *rdfname)
 {
 // Read raw data file and set initial and configuration parameters
   Long_t physeventind = 0, strn = 0, nofstripsev, nofstrips = 0;
@@ -228,7 +245,6 @@ Bool_t AliITSHandleDaSSD::Init(Char_t *rdfname, const Char_t *configfname)
   UChar_t *data = NULL;
   Long_t datasize = 0, eqbelsize = 1;
 
-  if (configfname) ReadConfigurationFile(configfname);
   rawreaderdate = new AliRawReaderDate(rdfname, 0);
   if (!(rawreaderdate->GetAttributes() || rawreaderdate->GetEventId())) {
     AliError(Form("AliITSHandleDaSSD: Error reading raw data file %s by RawReaderDate", rdfname));
@@ -256,7 +272,7 @@ Bool_t AliITSHandleDaSSD::Init(Char_t *rdfname, const Char_t *configfname)
         AliError(Form("AliITSHandleDaSSD: Error Init(%s): event data size %i is not an integer of equipment data size %i", 
                                    rdfname, datasize, eqbelsize));
         MakeZombie();
-       return kFALSE;
+           return kFALSE;
       }
       nofstripsev += (Int_t) (datasize / eqbelsize);
     }
@@ -291,14 +307,6 @@ Bool_t AliITSHandleDaSSD::Init(Char_t *rdfname, const Char_t *configfname)
 }
 
 
-//______________________________________________________________________________
-Bool_t AliITSHandleDaSSD::ReadConfigurationFile(const Char_t * /* configfname */) 
-const {
-// Dowload configuration parameters from configuration file or database
-  return kFALSE;
-}
-
-
 
 //______________________________________________________________________________
 AliITSModuleDaSSD* AliITSHandleDaSSD::GetModule (const UChar_t ddlID, const UChar_t ad, const UChar_t adc) const
@@ -457,6 +465,7 @@ Bool_t AliITSHandleDaSSD::ReadDDLModuleMap(const Char_t *filename)
   Int_t ind = 0;
   while((!ddlmfile.eof()) && (ind < (fgkNumberOfSSDDDLs * fgkNumberOfSSDModulesPerDdl))) {
     ddlmfile >> fDDLModuleMap[ind++];
+    if (ddlmfile.fail()) AliError(Form("Error extracting number from the DDL map file %s, ind: ", filename, ind));
   }
   if (ind != (fgkNumberOfSSDDDLs * fgkNumberOfSSDModulesPerDdl))
     AliWarning(Form("Only %i (< %i) entries were read from DDL Map!", ind, (fgkNumberOfSSDDDLs * fgkNumberOfSSDModulesPerDdl)));
@@ -526,8 +535,7 @@ Int_t AliITSHandleDaSSD::ReadModuleRawData (const Int_t modulesnumber)
         if (fDDLModuleMap) mddli = RetrieveModuleId(ddlID, ad, adc);
         else  mddli = 0;
        if (!module->SetModuleIdData (ddlID, ad, adc, mddli)) return 0;
-//     if (!module->SetModuleIdData (ddlID, ad, adc, RetrieveModuleId(ddlID, ad, adc))) return 0;
-        module->SetModuleRorcId (equipid, equiptype);
+    module->SetModuleRorcId (equipid, equiptype);
        module->SetCMFeromEventsNumber(fNumberOfEvents);
        modpos = fModIndRead + modind;
        modind += 1;
@@ -1042,3 +1050,192 @@ Bool_t AliITSHandleDaSSD::AllocateSimulatedModules(const Int_t copymodind)
   for (UShort_t modind = 0; modind < fNumberOfModules; modind++) fModules[modind]->SetModuleId(modind + 1080);  
   return kTRUE;
 }
+
+
+    
+//___________________________________________________________________________________________
+Bool_t AliITSHandleDaSSD::AdDataPresent(const Int_t ddl, const Int_t ad) const
+{
+// Check if there are calibration data for given ddl and slot
+  for (Int_t modind = 0; modind < fNumberOfModules; modind++)
+    if ((GetModule(modind)->GetAD() == ad) && (GetModule(modind)->GetDdlId() == ddl)) return kTRUE;
+  return kFALSE;
+}
+
+   
+
+//___________________________________________________________________________________________
+Bool_t AliITSHandleDaSSD::SaveEqSlotCalibrationData(const Int_t ddl, const Int_t ad, const Char_t *fname) const
+// Saves calibration files for selected equipment (DDL)
+{
+  fstream    feefile;
+  Int_t      zsml, offsetml;
+  ULong_t    zsth, offset, zsoffset;
+  if (!fname) {
+    AliError("File name must be specified!");
+    return kFALSE;   
+  }
+  if (!AdDataPresent(ddl, ad)) {
+    AliError(Form("Error SaveEqSlotCalibrationData(ddl = %i, ad = %i) no data present", ddl, ad)); 
+    return kFALSE;
+  }
+  feefile.open(fname, ios::out);
+  if (!feefile.is_open()) {
+       AliError(Form("Can not open the file %s for output!", fname)); 
+    return kFALSE;
+  }
+  for (zsml = 0; fgkZsBitMask >> zsml; zsml++);
+  for (offsetml = 0; fgkOffSetBitMask >> offsetml; offsetml++);
+  for (Int_t strind = 0; strind < AliITSModuleDaSSD::GetStripsPerModuleConst(); strind++) {
+    for (Int_t adcb = 0; adcb < fgkAdcPerDBlock; adcb++) {
+      zsoffset = 0x0;
+      for (Int_t j = 0; j < 2; j++) {
+        Int_t adc = adcb + j * 8;
+        zsth = ZsThreshold(ddl, ad, adc, strind);
+        offset = OffsetValue(ddl, ad, adc, strind);
+        zsoffset = zsoffset | (((zsth << offsetml) | offset) << ((j == 0) ? (offsetml + zsml) : 0));
+      }
+      feefile << "0x" << ConvBase(static_cast<unsigned long>(zsoffset), 16) << endl;
+    }
+  }
+  feefile.close();
+  return kTRUE;
+}
+
+
+//______________________________________________________________________________
+Int_t AliITSHandleDaSSD::ChannelIsBad(const UChar_t ddl, const UChar_t ad, const UChar_t adc, const Int_t strn) const
+{
+// Check if the channel is bad
+  AliITSBadChannelsSSD  *badch = NULL;
+  TArrayI                bcharray;
+  Int_t                  strsiden, modn = -1;
+  if (fStaticBadChannelsMap && fDDLModuleMap) {
+    modn = RetrieveModuleId(ddl, ad, adc);
+    if (modn < 0) return -1;
+    Int_t modind = 0;
+    while ((modind < fStaticBadChannelsMap->GetEntriesFast() && (!badch))) {
+      AliITSBadChannelsSSD  *bc = static_cast<AliITSBadChannelsSSD*>(fStaticBadChannelsMap->At(modind++));
+      if ((bc->GetMod()) == modn) badch = bc; 
+    }
+    if (badch) {
+      if (strn < AliITSModuleDaSSD::GetPNStripsPerModule()) { 
+        bcharray = badch->GetBadPChannelsList();
+        strsiden = strn;
+      } else {
+        bcharray = badch->GetBadNChannelsList();
+        strsiden = AliITSChannelDaSSD::GetMaxStripIdConst() - strn;
+      }
+      if (bcharray.GetSize() <  AliITSModuleDaSSD::GetPNStripsPerModule()) {
+           AliWarning(Form("No entry found in bad channels list TArrayI for ddl/ad/adc/str: %i/%i/%i/%i", ddl, ad, adc, strn));
+           return 0;
+      } 
+      return (bcharray[strsiden] & fgkBadChannelMask);
+    } else {
+      AliWarning(Form("No entry found in bad channels list for ddl = %i,  ad = %i,  adc = %i", ddl, ad, adc));
+      return 0;
+    }  
+  } else {
+    AliError("Error ether bad channels list or DDLMap is not initialized or both, return 0!");
+       return 0;
+  }
+}
+        
+        
+//______________________________________________________________________________
+ULong_t AliITSHandleDaSSD::OffsetValue(const AliITSChannelDaSSD *strip, 
+                                       const UChar_t ddl, const UChar_t ad, const UChar_t adc, const Int_t strn) const
+{
+// Calculate the offset value to be upload to FEROM    
+  Int_t  pedint;
+  if (fOffsetDefault < INT_MAX) pedint = fOffsetDefault;
+  else pedint = TMath::Nint(strip->GetPedestal());
+  if (pedint > static_cast<Int_t>((fgkOffSetBitMask >> 1))) {
+    if (!ChannelIsBad(ddl, ad, adc, strn)) 
+      AliError(Form("Offset %i, channel(ddl/ad/adc/strip) %i/%i/%i/%i  can not be represented with mask %i, Offset = %i",
+                   pedint, ddl, ad, adc, strn, ConvBase(fgkOffSetBitMask, 16).c_str(), fgkOffSetBitMask));
+    return fgkOffSetBitMask;
+  }  
+  if ((-pedint) > static_cast<Int_t>(((fgkOffSetBitMask + 1) >> 1))) {
+    if (!ChannelIsBad(ddl, ad, adc, strn)) 
+      AliError(Form("Offset %i, channel(ddl/ad/adc/strip) %i/%i/%i/%i  can not be represented with mask %i, Offset = %i", 
+                   pedint, ddl, ad, adc, strn, ConvBase(fgkOffSetBitMask, 16).c_str(), (fgkOffSetBitMask & (~fgkOffSetBitMask >> 1))));
+    return fgkOffSetBitMask & (~fgkOffSetBitMask >> 1);
+  }
+  return fgkOffSetBitMask & (pedint >= 0 ? pedint : pedint + fgkOffSetBitMask + 1);
+}
+
+
+
+//______________________________________________________________________________
+ULong_t AliITSHandleDaSSD::OffsetValue(const UChar_t ddl, const UChar_t ad, const UChar_t adc, const Int_t strn) const
+{
+// Calculate the offset value to be upload to FEROM    
+  AliITSChannelDaSSD    *strip = NULL;
+  AliITSModuleDaSSD     *module = NULL;
+  if (module = GetModule(ddl, ad, adc)) {
+    if (strip = module->GetStrip(strn)) return OffsetValue(strip, ddl, ad, adc, strn);
+    else {
+      AliWarning(Form("There is no calibration data for ddl = %i,  ad = %i,  adc = %i,  strip = %i, 0 is used!", ddl, ad, adc, strn));
+      return 0ul;
+    }
+  } else {
+    AliWarning(Form("There is no calibration data for ddl = %i,  ad = %i,  adc = %i, 0 is used!", ddl, ad, adc));
+    return 0ul;
+  }  
+}
+
+
+
+//______________________________________________________________________________
+ULong_t AliITSHandleDaSSD::ZsThreshold(AliITSChannelDaSSD *strip) const
+{ 
+// Calculate the value of zero suppression threshold to be upload to FEROM
+  ULong_t zs;
+  if (fZsDefault < 0) zs = TMath::Nint(fZsFactor * strip->GetNoiseCM());
+  else zs = fZsDefault;
+  return (zs < fgkZsBitMask) ? (zs & fgkZsBitMask) : fgkZsBitMask;
+}
+
+
+//______________________________________________________________________________
+ULong_t AliITSHandleDaSSD::ZsThreshold(const UChar_t ddl, const UChar_t ad, const UChar_t adc, const Int_t strn) const
+{
+// Calculate the value of zero suppression threshold to be upload to FEROM, account bad channels list
+  AliITSChannelDaSSD    *strip = NULL;
+  AliITSModuleDaSSD     *module = NULL;
+  if (ChannelIsBad(ddl, ad, adc, strn)) return fgkZsBitMask;
+  if (module = GetModule(ddl, ad, adc)) {
+    if (strip = module->GetStrip(strn))  return ZsThreshold(strip);
+    else {
+      AliWarning(Form("There is no calibration data for ddl = %i,  ad = %i,  adc = %i,  strip = %i, 0 is used!", ddl, ad, adc, strn));
+      return 0ul;
+    }
+  } else {
+    AliWarning(Form("There is no calibration data for ddl = %i,  ad = %i,  adc = %i, 0 is used!", ddl, ad, adc));
+    return 0ul;
+  }
+}
+
+            
+//______________________________________________________________________________
+string AliITSHandleDaSSD::ConvBase(const unsigned long value, const long base) const
+{
+// Converts the unsigned long number into that in another base 
+  string digits = "0123456789ABCDEF";
+  string result;
+  unsigned long v = value;
+  if((base < 2) || (base > 16)) {
+    result = "Error: base out of range.";
+  }
+  else {
+    int i = 0;
+    do {
+      result = digits[v % base] + result;
+      v /= base;
+      i++;
+    }
+    while((v) || (i<8));
+  }
+  return result;
+}
index 038b9d3..37dfcef 100644 (file)
@@ -6,6 +6,7 @@
 /*                                                                        */
 /* $Id$ */
 
+#include <string>
 #include "TObject.h"
 #include "AliITSModuleDaSSD.h"
 
@@ -17,6 +18,8 @@
 //  Date: 19/05/2008
 ///////////////////////////////////////////////////////////////////////////////
 
+using namespace std;
+
 class TObjArray;
 
 class AliITSHandleDaSSD : public TObject {
@@ -27,10 +30,21 @@ class AliITSHandleDaSSD : public TObject {
     AliITSHandleDaSSD& operator = (const AliITSHandleDaSSD& ssdadldc);
     virtual ~AliITSHandleDaSSD();
 
-    virtual Bool_t Init(Char_t *rdfname, const Char_t *configfname = NULL);
-    virtual Bool_t ReadConfigurationFile(const Char_t *configfname = NULL) const;
+    virtual Bool_t Init(Char_t *rdfname);
     Bool_t  SetRawFileName (Char_t *rdfname) {return Init(rdfname); }
 
+    void    SetZsDefaul(Int_t zs)        { fZsDefault = zs;       }
+    void    SetOffsetDefault(Int_t offs) { fOffsetDefault = offs; }
+    void    SetZsFactor(Float_t zsf)     { fZsFactor = zsf;       }
+    void    SetPedestalThresholdFactor(Float_t pthf) { fPedestalThresholdFactor = pthf; }
+    void    SetCmThresholdFactor(Float_t cmthf)      { fCmThresholdFactor = cmthf;      }
+
+    Int_t   GetZsDefault() const     { return fZsDefault;     }
+    Int_t   GetOffsetDefault() const { return fOffsetDefault; }
+    Float_t GetZsFactor() const      { return fZsFactor;      }
+    Float_t GetPedestalThresholdFactor() const { return fPedestalThresholdFactor; }
+    Float_t GetCmThresholdFactor() const       { return fCmThresholdFactor;       }
+    
     Int_t              GetNumberOfModules() const { return fNumberOfModules; }
     UInt_t             GetLdcId() const { return fLdcId; }
     UInt_t             GetRunId() const { return fRunId; }
@@ -59,7 +73,17 @@ class AliITSHandleDaSSD : public TObject {
     virtual Bool_t  ProcessRawData(const Int_t nmread = fgkNumberOfSSDModulesPerDdl);
     virtual Bool_t  RelocateModules();
     virtual Bool_t  AllocateSimulatedModules(const Int_t copymodind = 0);
-     
+
+    Bool_t  AdDataPresent(const Int_t ddl, const Int_t ad) const;
+    Int_t   DdlToEquipmentId (Int_t ddl) const { return (512 + ddl); }
+    Int_t   ChannelIsBad(const UChar_t ddl, const UChar_t ad, const UChar_t adc, const Int_t strn) const;
+    Bool_t  SaveEqSlotCalibrationData(const Int_t ddl, const Int_t ad, const Char_t *fname) const;
+    ULong_t OffsetValue(const AliITSChannelDaSSD *strip, const UChar_t ddl = 0, const UChar_t ad = 0, 
+                                 const UChar_t adc = 0, const Int_t strn = -1) const;
+    ULong_t OffsetValue(const UChar_t ddl, const UChar_t ad, const UChar_t adc, const Int_t strn) const;
+    ULong_t ZsThreshold(AliITSChannelDaSSD *strip) const;
+    ULong_t ZsThreshold(const UChar_t ddl, const UChar_t ad, const UChar_t adc, const Int_t strn) const;
+    
     virtual void    Reset();
     virtual Short_t RetrieveModuleId(const UChar_t ddlID, const UChar_t ad, const UChar_t adc) const;
     Bool_t  DumpModInfo(const Float_t meannosethreshold) const;
@@ -74,14 +98,20 @@ class AliITSHandleDaSSD : public TObject {
     static Int_t GetNumberOfSSDModulesConst() { return fgkNumberOfSSDModules; }
 
   protected :
-  
+
     static const Int_t    fgkNumberOfSSDModules ;        // Number of SSD modules in ITS
     static const Int_t    fgkNumberOfSSDModulesPerDdl;   // Number of SSD modules in DDL
     static const Int_t    fgkNumberOfSSDModulesPerSlot;  // Number of SSD modules in Slot
     static const Int_t    fgkNumberOfSSDDDLs;            // Number of DDLs in SSD
+    static const Int_t    fgkNumberOfSSDSlotsPerDDL;     // Number of SSD slots per DDL
     static const Float_t  fgkPedestalThresholdFactor;    // Defalt value for fPedestalThresholdFactor 
     static const Float_t  fgkCmThresholdFactor;          // Defalt value for fCmThresholdFactor 
-    
+   
+    static const UInt_t   fgkZsBitMask ;           // Bit mask for FEROM ZS
+    static const UInt_t   fgkOffSetBitMask;        // Bit mask for FEROM Offset correction
+    static const UInt_t   fgkBadChannelMask;       // Mask to suppress the channel from the bad channel list
+    static const Int_t    fgkAdcPerDBlock;         // FEROM configuration file constant
+     
     Char_t              *fRawDataFileName;       // Name of the file with raw data
     Int_t                fNumberOfModules;       // number of AliITSModuleDaSSD to allocate
     AliITSModuleDaSSD  **fModules;               //[fNumberOfModules] array of pointer on AliITSModuleDaSSD objects (1698 SSD  Modules)
@@ -96,14 +126,19 @@ class AliITSHandleDaSSD : public TObject {
     UInt_t               fLdcId;                 //  LDC number, read from header
     UInt_t               fRunId;                 //  Run number, read from header
 
-    Float_t     fPedestalThresholdFactor;        // configuration parameter: ThresholdFactor for pedestal calculation 
-    Float_t     fCmThresholdFactor;              // configuration parameter: ThresholdFactor for CM calculation 
+    Float_t         fPedestalThresholdFactor;        // configuration parameter: ThresholdFactor for pedestal calculation 
+    Float_t         fCmThresholdFactor;              // configuration parameter: ThresholdFactor for CM calculation 
+    Int_t           fZsDefault;                      // default value for ZS threshold
+    Int_t           fOffsetDefault;                  // default value for offset correction
+    Float_t         fZsFactor;                       // zs factor 3.0
 
-  private :
+  protected :
     Bool_t   SignalOutOfRange (const Short_t signal) const { return (signal >= AliITSChannelDaSSD::GetOverflowConst()); }
+    string   ConvBase(const unsigned long value, const long base) const;
 
     ClassDef(AliITSHandleDaSSD, 5)
 
 };
 
 #endif
+
index c92bcd4..a303ce5 100644 (file)
@@ -3,15 +3,18 @@
 - Link: /afs/infn.it/ts/user/efragiac/public/testCosm3125.001
 - Run Type: 
 - DA Type: LDC
-- Number of events needed: >=500
-- Input Files: raw_data_file_on_LDC, ssdddlmap.txt, badchannels.root
-- Output Files: ./ssddaldc_<LDCID>.root, FXS_name=ITSSSDda_<LDCID>.root 
+- Number of events needed: ~500
+- Input Files: raw_data_file_on_LDC, ssddaconfig txt, ssdddlmap.txt, badchannels.root
+- Output Files: ./<EqId_Slot> ./ssddaldc_<LDCID>.root, FXS_name=ITSSSDda_<LDCID>.root 
                 local files are persistent over runs: data source
 - Trigger types used:
  **************************************************************************/
 
 
 #include <iostream>
+#include <fstream>
+#include <sstream>
+#include <string>
 #include "TString.h"
 #include "TFile.h"
 #include "daqDA.h"
 using namespace std;
 
 
+struct ConfigStruct {
+  Int_t    fNModuleProcess;
+  string   fSsdDdlMap;
+  string   fBadChannels;
+  ConfigStruct() : fNModuleProcess(108), fSsdDdlMap(""), fBadChannels("") {}
+};
+
+
+Int_t SaveEquipmentCalibrationData(const AliITSHandleDaSSD  *ssddaldc, const Char_t  *fprefix = NULL);
+Bool_t ReadDAConfigurationFile(const Char_t *configfname, AliITSHandleDaSSD *const ssddaldc, ConfigStruct& cfg);
+
+
 int main( int argc, char** argv )
 {
+  const Char_t       *configfname = "ssddaconfig.txt";
+  const Char_t       *bcfname = "badchannels.root"; 
+  const Char_t       *ddlmfname = "ssdddlmap.txt";
   AliITSHandleDaSSD  *ssddaldc;
   TString             feefname, fcdbsave, lfname;
   Int_t               status;
   Char_t             *dafname = NULL;
-  const Char_t       *bcfname = "badchannels.root";
-  const Char_t       *ddlmfname = "ssdddlmap.txt";
-
+  ConfigStruct        cfg; 
 
-   gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
+  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
                                         "*",
                                         "TStreamerInfo",
                                         "RIO",
                                         "TStreamerInfo()");
 
 
-
   /* check that we got some arguments = list of files */
   if (argc<2) {
     fprintf(stderr, "Wrong number of arguments\n");
@@ -48,25 +63,39 @@ int main( int argc, char** argv )
 
   char *datafilename = argv[1];
   ssddaldc = new AliITSHandleDaSSD(datafilename);
-  if (ssddaldc->IsZombie()) return -1;
+  if (ssddaldc->IsZombie()) { 
+   cerr << "Failed to process raw data file " << datafilename << "! Exit DA!\n";
+   return -1;
+  }
 
+  lfname.Form("./%s", configfname);
+  if (!(status = daqDA_DB_getFile(configfname, lfname.Data()))) {
+    if (!ReadDAConfigurationFile(lfname.Data(), ssddaldc, cfg)) cerr << "Error reading configuration file "  << lfname.Data() << " !\n";
+  } else fprintf(stderr, "Failed to import DA configuration file %s from the detector db: %d, %s \n", configfname, status, lfname.Data());
+    
+  if (cfg.fBadChannels.size() > 0) bcfname = cfg.fBadChannels.c_str();
   lfname.Form("./%s", bcfname);
-  status = daqDA_DB_getFile(bcfname, lfname.Data());
-  if (!status) {
-    if (!ssddaldc->ReadStaticBadChannelsMap(lfname.Data())) cerr << "Error reading static bad channels map " << lfname.Data() << " !\n"; 
-  } else fprintf(stderr, "Failed to import file %s from the detector db: %d, %s \n", bcfname, status, lfname.Data());
-
+  if (status = daqDA_DB_getFile(bcfname, lfname.Data())) {
+    fprintf(stderr, "Failed to import the file %s from the detector db: %d, %s! Exit DA!\n", bcfname, status, lfname.Data());
+    delete ssddaldc;
+    return -3;
+  }  
+  if (!ssddaldc->ReadStaticBadChannelsMap(lfname.Data())) {
+    cerr << "Error reading static bad channels map " << lfname.Data() << "! Exit DA!\n";
+    delete ssddaldc;
+    return -4;
+  }      
+  
+  if (cfg.fSsdDdlMap.size() > 0) ddlmfname = cfg.fSsdDdlMap.c_str();
   lfname.Form("./%s", ddlmfname);
-  status = daqDA_DB_getFile(ddlmfname, lfname.Data());
-  if (!status) {
+  if (!(status = daqDA_DB_getFile(ddlmfname, lfname.Data()))) {
     if (!ssddaldc->ReadDDLModuleMap(lfname.Data())) cerr << "Error reading DDL map from file " << lfname.Data() << " !\n"; 
   } else {
-    fprintf(stderr, "Failed to import file %s from the detector db: %d, %s \n", bcfname, status, lfname.Data());
+    fprintf(stderr, "Failed to import file %s from the detector db: %d, %s \n", ddlmfname, status, lfname.Data());
     if (!ssddaldc->ReadDDLModuleMap()) cerr << "Failed to load the DDL map from AliITSRawStreamSSD!\n"; 
   }    
-
-  if (!ssddaldc->ProcessRawData())
-  {
+  
+  if (!ssddaldc->ProcessRawData(cfg.fNModuleProcess))  {
      cerr << "Error !ssddaldc->ProcessRawData()" << endl;
      delete ssddaldc;
      return -1;
@@ -78,7 +107,7 @@ int main( int argc, char** argv )
     cout << "SSDDA data are saved in " << dafname << endl;
     status = daqDA_FES_storeFile(dafname, "CALIBRATION");
     if (status) fprintf(stderr, "Failed to export file : %d\n", status);
-  } else cerr << "Error saving DA data to the file! Probably $DA_TEST_DIR defined incorrectly!" << endl;
+  } else cerr << "Error saving DA data to the file!\n";
 
   feefname.Form("%s/ssddaldc_%i.root", ".", ssddaldc->GetLdcId());
   cout << "Saving feessdda data in " << feefname << endl;
@@ -87,7 +116,7 @@ int main( int argc, char** argv )
     cerr << "Error open file " << feefname << endl;
     delete ssddaldc;
     delete fileRun;
-    return 2;
+    return -2;
   }  
   ssddaldc->Write();
   fileRun->Close();
@@ -96,8 +125,127 @@ int main( int argc, char** argv )
   fcdbsave.Form("ssddaldc_%i.root", ssddaldc->GetLdcId());
   status = daqDA_DB_storeFile(feefname.Data(), fcdbsave.Data());
   if (status) fprintf(stderr, "Failed to export file %s to the detector db: %d, %s \n", feefname.Data(), status, fcdbsave.Data());
-
+  cout << SaveEquipmentCalibrationData(ssddaldc) << " files were uploaded to DetDB!\n";
   delete ssddaldc;
   daqDA_progressReport(100);
   return 0;
 }
+
+
+
+//__________________________________________________________________________________________
+Int_t SaveEquipmentCalibrationData(const AliITSHandleDaSSD  *ssddaldc, const Char_t  *fprefix)
+{
+  TString feefilename;
+  Int_t count = 0, status;
+  for (Int_t ddli = 0; ddli < 16; ddli++) {
+    for(Int_t adi = 1; adi <= 9; adi++) {
+         if (!ssddaldc->AdDataPresent(ddli, adi)) continue;  
+         if (fprefix) feefilename.Form("%s%i_%i", fprefix, ssddaldc->DdlToEquipmentId(ddli), adi);
+         else feefilename.Form("%i_%i", ssddaldc->DdlToEquipmentId(ddli), adi);
+      if (ssddaldc->SaveEqSlotCalibrationData(ddli, adi, feefilename)) {
+        status = daqDA_DB_storeFile(feefilename, feefilename);
+        if (status) fprintf(stderr, "Error %i, failed to export file %s\n", status, feefilename.Data());
+        else count++;
+      }
+    }
+  }
+  return count;
+}
+
+
+//__________________________________________________________________________________________
+Bool_t ReadDAConfigurationFile(const Char_t *configfname, AliITSHandleDaSSD *const ssddaldc, ConfigStruct& cfg) 
+{
+// Dowload configuration parameters from configuration file or database
+  const int nkwords = 8;
+  char *keywords[nkwords] = {"ZsDefault", "OffsetDefault", "ZsFactor", "PedestalThresholdFactor", "CmThresholdFactor",
+                             "NModulesToProcess", "DDLMapFile", "BadChannelsFile"};
+  Int_t tmpint;
+  Float_t tmpflt;
+  fstream dfile;
+  if (!configfname) {
+    cerr << "No DA configuration file name is specified, defaul value are used!\n";
+    return kFALSE;
+  }
+  dfile.open(configfname, ios::in);
+  if (!dfile.is_open()) {
+    cerr << "Error open DA configuration file " << configfname << " defaul value are used!\n";
+    return kFALSE;
+  }
+  while (!dfile.eof()) {
+    string str, keystr, tmpstr;
+    getline(dfile, str);
+    stringstream strline(str);
+    strline >> keystr;
+    if (keystr.size() == 0) continue;
+    if ((keystr.at(0) == '#') ) continue;
+    int ind = 0;
+    while (keystr.compare(keywords[ind])) if (++ind == nkwords) break;
+    switch (ind) {
+         case 0: 
+              strline >> tmpint;
+              if (strline.fail()) cerr << "Failed to read " << keystr << " value from DA configuration file!\n";
+              else {
+                   ssddaldc->SetZsDefaul(tmpint);   
+                   cout << "Default value for ZS thereshold " << keystr << ": " << ssddaldc->GetZsDefault() << endl;
+              } break;   
+         case 1: 
+                 strline >> tmpint;
+              if (strline.fail()) cerr << "Failed to read " << keystr << " value from DA configuration file!\n";
+              else {
+                   ssddaldc->SetOffsetDefault(tmpint);   
+                   cout << "Default value for offset correction " << keystr << ": " << ssddaldc->GetOffsetDefault() << endl;
+              } break;   
+         case 2: 
+                 strline >> tmpflt;
+              if (strline.fail()) cerr << "Failed to read " << keystr << " value from DA configuration file!\n";
+              else {
+                   ssddaldc->SetZsFactor(tmpflt);   
+                cout << keystr << ": " << ssddaldc->GetZsFactor() << endl;
+              } break;
+         case 3: 
+                 strline >> tmpflt;
+              if (strline.fail()) cerr << "Failed to read " << keystr << " value from DA configuration file!\n";
+              else {
+                   ssddaldc->SetPedestalThresholdFactor(tmpflt);
+                cout << keystr << ": " << ssddaldc->GetPedestalThresholdFactor() << endl;
+              } break;
+         case 4: 
+                 strline >> tmpflt;
+              if (strline.fail()) cerr << "Failed to read " << keystr << " value from DA configuration file!\n";
+              else {
+                   ssddaldc->SetCmThresholdFactor(tmpflt);
+                cout << keystr << ": " << ssddaldc->GetCmThresholdFactor() << endl;
+              } break;
+         case 5: 
+                 strline >> tmpint;
+              if (strline.fail()) cerr << "Failed to read " << keystr << " value from DA configuration file!\n";
+              else {
+                   cfg.fNModuleProcess = tmpint;
+                cout << keystr << ": " << cfg.fNModuleProcess << endl;
+              } break;
+         case 6: 
+                 strline >> tmpstr;
+              if (strline.fail()) cerr << "Failed to read " << keystr << " value from DA configuration file!\n";
+              else {
+                if (tmpstr.size() == 0) continue;
+                if (tmpstr.at(0) == '#') continue;
+                   cfg.fSsdDdlMap = tmpstr;
+                cout << keystr << ": " << cfg.fSsdDdlMap.c_str() << endl;
+              } break;
+         case 7: 
+                 strline >> tmpstr;
+              if (strline.fail()) cerr << "Failed to read " << keystr << " value from DA configuration file!\n";
+              else {
+                if (tmpstr.size() == 0) continue;
+                if (tmpstr.at(0) == '#') continue;
+                   cfg.fBadChannels = tmpstr;
+                cout << keystr << ": " << cfg.fBadChannels.c_str() << endl;
+              } break;
+         default: 
+                 cerr << keystr << " is not a key word, no assignment were made!\n"; 
+    }
+  }  
+  return kTRUE;
+}