prevent running if CDB snapshot setting failed
[u/mrichter/AliRoot.git] / STEER / STEER / AliLHCData.cxx
index db304c9..ad39a2d 100755 (executable)
-/**************************************************************************\r
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *\r
- *                                                                        *\r
- * Author: The ALICE Off-line Project.                                    *\r
- * Contributors are mentioned in the code where appropriate.              *\r
- *                                                                        *\r
- * Permission to use, copy, modify and distribute this software and its   *\r
- * documentation strictly for non-commercial purposes is hereby granted   *\r
- * without fee, provided that the above copyright notice appears in all   *\r
- * copies and that both the copyright notice and this permission notice   *\r
- * appear in the supporting documentation. The authors make no claims     *\r
- * about the suitability of this software for any purpose. It is          *\r
- * provided "as is" without express or implied warranty.                  *\r
- *                                                                        *\r
- **************************************************************************/\r
-\r
-/********************************************************************************\r
-*                                                                               *\r
-*   AliLHCData: summary of the LHC related information from LHC DIP.            *\r
-*   Created from the TMap provided by the AliLHCReader with optional beginning  *\r
-*                                                                               *\r
-*   The data are (wrapped in the AliLHCDipValT):                                *\r
-*   made of TimeStamp (double) and array of values                              *\r
-*                                                                               *\r
-*   Multiple entries for each type of data are possible. To obtaine number of   *\r
-*   records (with distinct timestamp) for give type od records use:             *\r
-*   int GetNBunchConfigMeasured(int beam) (with beam=0,1) etc.                  *\r
-*                                                                               *\r
-*   To get i-th entry, use brec= AliLHCDipValI* GetBunchConfigMeasured(bm,i);   *\r
-*   Note: exact type of templated AliLHCDipValT pointer depends on the record   *\r
-*   type, concult getters to know it.                                           *\r
-*                                                                               *\r
-*   Then, once the pointer is obtained, details can be accessed:                *\r
-*   int nBunches = brec->GetSize();                                             *\r
-*   for (int i=0;i<nBunches;i++) printf("Bunch#%d: %d\n",i,(*brec)[i]);         *\r
-*                                                                               *\r
-*                                                                               *\r
-*   Author: ruben.shahoyan@cern.ch                                              *\r
-*                                                                               *\r
-********************************************************************************/\r
-\r
-#include "AliLHCData.h"\r
-#include "TMap.h"\r
-#include "AliDCSArray.h"\r
-#include "AliLHCReader.h"\r
-#include "AliTriggerBCMask.h"\r
-#include <TString.h>\r
-#include <TObjArray.h>\r
-\r
-ClassImp(AliLHCData)\r
-\r
-const Char_t* AliLHCData::fgkDCSNames[] = {\r
-  "LHC_IntensityBeam%1d_totalIntensity",\r
-  "LHC_BeamIntensityPerBunchBeam%1d_averageBeamIntensity",\r
-  "LHC_BeamIntensityPerBunchBeam%1d_Average_BunchIntensities",\r
-  //\r
-  "LHC_LumAverageBRANB_4%c2_acqMode",\r
-  "LHC_LumAverageBRANB_4%c2_meanLuminosity",\r
-  "LHC_LumAverageBRANB_4%c2_meanLuminosityError",\r
-  "LHC_BeamLuminosityPerBunchBRANB_4%c2_Average_BunchLuminosity",\r
-  "LHC_BeamLuminosityPerBunchBRANB_4%c2_BunchLuminosityError",\r
-  "LHC_LumAverageBRANB_4%c2_meanCrossingAngle",\r
-  "LHC_LumAverageBRANB_4%c2_meanCrossingAngleError",\r
-  "LHC_CirculatingBunchConfig_Beam%d",\r
-  "LHC_FillNumber",\r
-  //\r
-  "LHC_BunchLengthBeam%1d_nBunches",\r
-  "LHC_BunchLengthBeam%1d_bunchesLenghts",\r
-  "LHC_BunchLengthBeam%1d_filledBuckets",\r
-  //\r
-  "LHC_RunControl_ActiveInjectionScheme",\r
-  "LHC_RunControl_BetaStar",\r
-  "LHC_RunControl_IP2_Xing_Murad",\r
-  "LHC_RunControl_IP2_ALICE_Murad",\r
-\r
-  "LHC_BeamSizeBeam%1d_acqMode",\r
-  "LHC_BeamSizeBeam%1d_sigmaH",\r
-  "LHC_BeamSizeBeam%1d_sigmaV",\r
-  "LHC_BeamSizeBeam%1d_emittanceH",\r
-  "LHC_BeamSizeBeam%1d_emittanceV",\r
-  "LHC_BeamSizeBeam%1d_errorSigmaH",\r
-  "LHC_BeamSizeBeam%1d_errorSigmaV",\r
-  //\r
-  "LHC_CollimatorPos_%s_lvdt_%s"\r
-};\r
-\r
-const Char_t* AliLHCData::fgkDCSColNames[] = {\r
-  "TCTVB_4L2",\r
-  "TCTVB_4R2",\r
-  "TCLIA_4R2"\r
-};\r
-\r
-const Char_t* AliLHCData::fgkDCSColJaws[] = {\r
-  "gap_downstream","gap_upstream","left_downstream",\r
-  "left_upstream","right_downstream","right_upstream"};\r
-\r
-//___________________________________________________________________\r
-AliLHCData::AliLHCData(const TMap* dcsMap, double tmin, double tmax)\r
-  : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fFile2Process(0),fMap2Process(0)\r
-{\r
-  FillData(dcsMap,tmin,tmax);\r
-}\r
-\r
-//___________________________________________________________________\r
-AliLHCData::AliLHCData(const Char_t* dcsFile, double tmin, double tmax)\r
-  : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fFile2Process(dcsFile),fMap2Process(0)\r
-{\r
-  FillData(dcsFile,tmin,tmax);\r
-}\r
-\r
-//___________________________________________________________________\r
-Bool_t AliLHCData::FillData(const TMap*   dcsMap,double tmin, double tmax)\r
-{\r
-  // process DCS map and fill all fields. \r
-  Clear();\r
-  fMap2Process = dcsMap;\r
-  FillData(tmin,tmax);\r
-  return kTRUE;\r
-}\r
-\r
-//___________________________________________________________________\r
-Bool_t AliLHCData::FillData(const Char_t* dcsFile,double tmin, double tmax)\r
-{\r
-  // process DCS file and fill all fields. \r
-  Clear();\r
-  fFile2Process = dcsFile;\r
-  FillData(tmin,tmax);\r
-  return kTRUE;\r
-}\r
-\r
-//___________________________________________________________________\r
-Bool_t AliLHCData::FillData(double tmin, double tmax)\r
-{\r
-  // process DCS map and fill all fields. \r
-  // Accept only entries with timestamp between tmin and tmax\r
-  //\r
-  char buff[100],buff1[100];\r
-  //\r
-  SetTMin(tmin);\r
-  SetTMax(tmax);\r
-  //\r
-  // -------------------------- extract Fill Number\r
-  int iFirst=0,iLast=0;\r
-  TObjArray* arr = GetDCSEntry(fgkDCSNames[kFillNum],iFirst,iLast,fTMin,fTMax);\r
-  if (arr) SetFillNumber( ExtractInt( (AliDCSArray*)arr->At(iFirst), 0) );\r
-  if (fFile2Process) delete arr; // array was created on demand\r
-  //\r
-  for (int ibm=0;ibm<2;ibm++) {\r
-    //\r
-    snprintf(buff,99,fgkDCSNames[kBunchConf],ibm+1);         // ----- declared bunch configuration\r
-    FillBunchConfig(fBunchConfDecl[ibm], buff);\r
-    //\r
-    snprintf(buff,99,fgkDCSNames[kBunchLgtFillB],ibm+1);     // ----- measured bunch configuration\r
-    FillBunchConfig(fBunchConfMeas[ibm], buff);\r
-    //\r
-    snprintf(buff,99,fgkDCSNames[kBunchLgt],ibm+1);          // ----- measured bunch lenghts\r
-    FillBunchInfo(fBunchLengths[ibm],buff,ibm,kFALSE);  \r
-    //\r
-    snprintf(buff,99,fgkDCSNames[kIntBunchAv],ibm+1);        // ----- B-by-B intensities\r
-    FillBunchInfo(fIntensPerBunch[ibm],buff,ibm,kTRUE);\r
-    //\r
-    //\r
-    snprintf(buff,99,fgkDCSNames[kIntTot],ibm+1);            // ----- total intensities for beam 1 and 2\r
-    FillScalarRecord(fIntensTotal[ibm], buff);\r
-    //\r
-    snprintf(buff,99,fgkDCSNames[kIntTotAv],ibm+1);          // ----- total intensities for beam 1 and 2 from B-by-B average\r
-    FillScalarRecord(fIntensTotalAv[ibm], buff);\r
-    //\r
-    snprintf(buff,99,fgkDCSNames[kBeamSzEmittH],ibm+1);      // ----- H emittance for beam 1 and 2 \r
-    FillScalarRecord(fEmittanceH[ibm], buff);\r
-    //\r
-    snprintf(buff,99,fgkDCSNames[kBeamSzEmittV],ibm+1);      // ----- V emittance for beam 1 and 2 \r
-    FillScalarRecord(fEmittanceV[ibm], buff);\r
-    //\r
-    snprintf(buff,99 ,fgkDCSNames[kBeamSzSigH],   ibm+1);    // ----- H sigmas and errors for beam 1 and 2 \r
-    snprintf(buff1,99,fgkDCSNames[kBeamSzSigHErr],ibm+1);\r
-    FillScalarRecord(fBeamSigmaH[ibm], buff, buff1);\r
-    //\r
-    snprintf(buff,99 ,fgkDCSNames[kBeamSzSigV],   ibm+1);    // ----- V sigmas and errors for beam 1 and 2 \r
-    snprintf(buff1,99,fgkDCSNames[kBeamSzSigVErr],ibm+1);\r
-    FillScalarRecord(fBeamSigmaV[ibm], buff, buff1);\r
-    //\r
-  }\r
-  //\r
-  FlagInteractingBunches(fBunchConfMeas[0],fBunchConfMeas[1]);\r
-  FlagInteractingBunches(fBunchConfDecl[0],fBunchConfDecl[1]);\r
-  //\r
-  for (int ilr=0;ilr<2;ilr++) {\r
-    //\r
-    snprintf(buff,99 ,fgkDCSNames[kLumBunch], ilr ? 'R':'L');       // ---- BC-by-BC luminosity at IP2 and its error\r
-    snprintf(buff1,99,fgkDCSNames[kLumBunchErr], ilr ? 'R':'L');\r
-    FillBCLuminosities(fLuminPerBC[ilr], buff, buff1, 0); // BRAN L uses beam2 as a reference, BRAN R - beam1\r
-    //\r
-    snprintf(buff,99 ,fgkDCSNames[kLumTot]   , ilr ? 'R':'L');       // ---- total luminosity at IP2 and its error\r
-    snprintf(buff1,99,fgkDCSNames[kLumTotErr], ilr ? 'R':'L');\r
-    FillScalarRecord(fLuminTotal[ilr], buff, buff1);\r
-    //\r
-    snprintf(buff,99 ,fgkDCSNames[kLumAcqMode], ilr ? 'R':'L');      // ---- luminosity acquisition mode\r
-    FillAcqMode(fLuminAcqMode[ilr], buff);\r
-    //\r
-    snprintf(buff,99, fgkDCSNames[kLumCrossAng]   , ilr ? 'R':'L');  //----- crossing angle at IP2 and its error\r
-    snprintf(buff1,99,fgkDCSNames[kLumCrossAngErr], ilr ? 'R':'L');\r
-    FillScalarRecord(fCrossAngle[ilr], buff, buff1);\r
-    //    \r
-  }\r
-  //\r
-  for (int icl=0;icl<kNCollimators;icl++) {             // ----- collimators positions\r
-    for (int jaw=0;jaw<kNJaws;jaw++) {\r
-      snprintf(buff,99,fgkDCSNames[kCollPos], fgkDCSColNames[icl],fgkDCSColJaws[jaw]);        \r
-      FillScalarRecord(fCollimators[icl][jaw], buff);\r
-    } // jaws\r
-  } // collimators\r
-  //\r
-  //\r
-  // RunControl info\r
-  FillStringRecord(fRCInjScheme, fgkDCSNames[kRCInjSch]);   // ---- active injection scheme\r
-  FillScalarRecord(fRCBeta, fgkDCSNames[kRCBeta]);          // ---- target beta \r
-  FillScalarRecord(fRCAngH, fgkDCSNames[kRCCrossAng]);      // ---- horisontal angle\r
-  FillScalarRecord(fRCAngV,fgkDCSNames[kRCVang] );          // ---- vertical angle\r
-  //\r
-  return kTRUE;\r
-}\r
-\r
-//___________________________________________________________________\r
-TObjArray* AliLHCData::GetDCSEntry(const char* key,int &entry,int &last,double tmin,double tmax) const\r
-{\r
-  // extract array from the DCS map or file and find the first entry within the time limits\r
-  entry = -1;\r
-  last = -2;\r
-  TObjArray* arr;\r
-  if (fMap2Process) arr = (TObjArray*)fMap2Process->GetValue(key);\r
-  else if (fFile2Process) {\r
-    AliLHCReader rd;\r
-    arr = rd.ReadSingleLHCDP(fFile2Process,key);\r
-  }\r
-  else {\r
-    AliError("Neither DCS map nor DCS filename are set");\r
-    return 0;  \r
-  }\r
-  //\r
-  if (!arr || !arr->GetEntriesFast()) { \r
-    AliWarning(Form("No data for %s",key)); \r
-    if (fMap2Process) delete arr; // created on demand\r
-    return 0;\r
-  }\r
-  int ntot = arr->GetEntriesFast();\r
-  //\r
-  // search 1st entry before or at tmin\r
-  AliDCSArray* ent = 0;\r
-  Bool_t found = kFALSE;\r
-  for (entry=0;entry<ntot;entry++) {\r
-    ent = (AliDCSArray*)arr->At(entry);\r
-    if (ent->GetTimeStamp()>=tmin-kMarginSOR && ent->GetTimeStamp()<=tmax+kMarginEOR) {\r
-      found = kTRUE;\r
-      if (ent->GetTimeStamp()>tmin) break;\r
-    }\r
-  }\r
-  if (!found) {\r
-    entry = -1;\r
-    TString str;\r
-    str += AliLHCDipValD::TimeAsString(tmin);\r
-    str += " : ";\r
-    str += AliLHCDipValD::TimeAsString(tmax);\r
-    AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));\r
-    if (fMap2Process) delete arr; // created on demand\r
-    return 0;\r
-  }\r
-  if (entry>0) entry--;\r
-  //\r
-  // search last entry at or after tmin\r
-  ent = 0;\r
-  for (last=entry;last<ntot;last++) {\r
-    ent = (AliDCSArray*)arr->At(last);\r
-    if (ent->GetTimeStamp()>tmax) break;\r
-  }\r
-  if (last == ntot) last--;\r
-  else if (ent->GetTimeStamp()>tmax+kMarginEOR) last--;\r
-  //\r
-  return arr;\r
-}\r
-\r
-//___________________________________________________________________\r
-Int_t AliLHCData::TimeDifference(double v1,double v2,double tol) const\r
-{\r
-  // return 0 if the times are the same within the tolerance\r
-  //        1 if v1>v2\r
-  //       -1 if v1<v2\r
-  v1-=v2;\r
-  if (v1>tol)  return  1;\r
-  if (v1<-tol) return -1;\r
-  return 0;\r
-}\r
-\r
-//___________________________________________________________________\r
-Bool_t AliLHCData::GoodPairID(int beam) const\r
-{\r
-  // check for correct beam identifier \r
-  if (beam>kBeam2||beam<0) {AliError(Form("BeamID can be 0 or 1, %d requested",beam)); return kFALSE;}\r
-  return kTRUE;\r
-}\r
-\r
-//___________________________________________________________________\r
-AliLHCDipValI* AliLHCData::GetBunchConfigMeasured(int beam,double tstamp) const\r
-{\r
-  // find measured bunch configuration valid for given tstamp\r
-  if (!GoodPairID(beam)) return 0;\r
-  return (AliLHCDipValI*)FindRecValidFor(fBunchConfMeas[beam][kStart],fBunchConfMeas[beam][kNStor],tstamp);\r
-}\r
-\r
-//___________________________________________________________________\r
-AliLHCDipValI* AliLHCData::GetBunchConfigDeclared(int beam,double tstamp) const\r
-{\r
-  // find declared bunch configuration valid for given tstamp\r
-  if (!GoodPairID(beam)) return 0;\r
-  return (AliLHCDipValI*)FindRecValidFor(fBunchConfDecl[beam][kStart],fBunchConfDecl[beam][kNStor],tstamp);\r
-}\r
-\r
-//___________________________________________________________________\r
-TObject* AliLHCData::FindRecValidFor(int start,int nrec, double tstamp) const\r
-{\r
-  // find record within this limits valid for given tstamp (i.e. the last one before or equal to tstamp)\r
-  AliLHCDipValI *prevObj = 0;\r
-  for (int i=0;i<nrec;i++) {\r
-    AliLHCDipValI* curObj = (AliLHCDipValI*)fData[start+i];\r
-    if (TimeDifference(tstamp,curObj->GetTimeStamp())<0) break;\r
-    prevObj = curObj;\r
-  }\r
-  if (!prevObj && nrec>0) prevObj = (AliLHCDipValI*)fData[start]; // if no exact match, return the 1st one\r
-  return prevObj;\r
-}\r
-\r
-//___________________________________________________________________\r
-Int_t AliLHCData::FillScalarRecord(int refs[2], const char* rec, const char* recErr)\r
-{\r
-  // fill record for scalar value, optionally accompanied by measurement error \r
-  //\r
-  AliInfo(Form("Acquiring record: %s",rec));\r
-  //\r
-  TObjArray *arr=0,*arrE=0;\r
-  Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;\r
-  //\r
-  refs[kStart] = fData.GetEntriesFast();\r
-  refs[kNStor] = 0;\r
-  //\r
-  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
-  //\r
-  int dim = 1;\r
-  if (recErr) {\r
-    arrE = GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);\r
-    dim += 1;\r
-  }\r
-  //\r
-  // Bool_t last = kFALSE;\r
-  while (iFirst<=iLast) {\r
-    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
-    double tstamp = dcsVal->GetTimeStamp();\r
-    //\r
-    AliLHCDipValF* curValF = new AliLHCDipValF(dim,tstamp);  // start new period\r
-    (*curValF)[0] = ExtractDouble(dcsVal,0);     // value\r
-    //\r
-    if (recErr) {\r
-      double errVal = -1;\r
-      while (iFirstE<=iLastE) {       // try to find corresponding error\r
-       AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);\r
-        double tstampE = dcsValE->GetTimeStamp();\r
-        int tdif = TimeDifference(tstamp,tstampE);\r
-        if (!tdif) { // error matches to value\r
-          errVal = ExtractDouble(dcsValE,0);\r
-         iFirstE++; \r
-         break;\r
-       }\r
-        else if (tdif>0) iFirstE++; // error time lags behind, read the next one\r
-        else break;                 // error time is ahead of value, no error associated\r
-      }\r
-      (*curValF)[dim-1] = errVal;   // error\r
-      curValF->SetLastSpecial();    // lable the last entry as an error\r
-    }\r
-    //\r
-    fData.Add(curValF);\r
-    refs[kNStor]++;\r
-    // if (last) break;\r
-  }\r
-  //\r
-  if (fFile2Process) {\r
-    delete arr;\r
-    delete arrE;\r
-  }\r
-  return refs[kNStor];\r
-}\r
-\r
-//___________________________________________________________________\r
-Int_t AliLHCData::FillBunchConfig(int refs[2],const char* rec)\r
-{\r
-  // fill record for bunch configuration\r
-  //\r
-  AliInfo(Form("Acquiring record: %s",rec));\r
-  TObjArray *arr;\r
-  Int_t iLast,iFirst;\r
-  //\r
-  refs[kStart] = fData.GetEntriesFast();\r
-  refs[kNStor] = 0;\r
-  //\r
-  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
-  //\r
-  AliLHCDipValI* prevRecI=0;\r
-  //  \r
-  while (iFirst<=iLast) {\r
-    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
-    double tstamp = dcsVal->GetTimeStamp();\r
-    //\r
-    int bucket=0, nbunch=0, ndiff=0;\r
-    int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)\r
-    int* dcsArr = dcsVal->GetInt();\r
-    while(nbunch<nSlots && (bucket=dcsArr[nbunch])) {\r
-      if (prevRecI && prevRecI->GetSize()>nbunch && bucket!=prevRecI->GetValue(nbunch)) ndiff++;\r
-      nbunch++;\r
-    }\r
-    if (!nbunch) AliWarning(Form("%s record is present but empty: no beam?",rec));\r
-    if (prevRecI && !ndiff && nbunch==prevRecI->GetSize()) continue; // record similar to previous one\r
-    AliLHCDipValI* curValI = new AliLHCDipValI(nbunch,tstamp);      \r
-    for (int i=nbunch;i--;) (*curValI)[i] = dcsArr[i];\r
-    fData.Add(curValI);\r
-    refs[kNStor]++;\r
-    prevRecI = curValI;\r
-  }\r
-  //\r
-  if (fFile2Process) delete arr;\r
-  return refs[kNStor];\r
-}\r
\r
-//___________________________________________________________________\r
-Int_t AliLHCData::FillAcqMode(int refs[2],const char* rec)\r
-{\r
-  // fill acquisition mode\r
-  //\r
-  AliInfo(Form("Acquiring record: %s",rec));\r
-  TObjArray *arr;\r
-  Int_t iLast,iFirst;\r
-  //\r
-  refs[kStart] = fData.GetEntriesFast();\r
-  refs[kNStor] = 0;\r
-  //\r
-  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
-  //\r
-  AliLHCDipValI* prevRecI=0;\r
-  while (iFirst<=iLast) {\r
-    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
-    double tstamp = dcsVal->GetTimeStamp();\r
-    //\r
-    int nSlots = dcsVal->GetNEntries();\r
-    if (nSlots<1) continue;\r
-    int acqMode = dcsVal->GetInt()[0];\r
-    if (prevRecI && (*prevRecI)[0] == acqMode) continue; // record similar to previous one\r
-    AliLHCDipValI* curValI = new AliLHCDipValI(1,tstamp);      \r
-    (*curValI)[0] = acqMode;\r
-    fData.Add(curValI);\r
-    refs[kNStor]++;\r
-    prevRecI = curValI;\r
-  }\r
-  //\r
-  if (fFile2Process) delete arr;\r
-  return refs[kNStor];\r
-}\r
\r
-//___________________________________________________________________\r
-Int_t AliLHCData::FillStringRecord(int refs[2],const char* rec)\r
-{\r
-  // fill record with string value\r
-  //\r
-  AliInfo(Form("Acquiring record: %s",rec));\r
-  TString prevRec;\r
-  TObjArray *arr;\r
-  Int_t iLast,iFirst;\r
-  //\r
-  refs[kStart] = fData.GetEntriesFast();\r
-  refs[kNStor] = 0;\r
-  //\r
-  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
-  //\r
-  while (iFirst<=iLast) {\r
-    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
-    double tstamp = dcsVal->GetTimeStamp();\r
-    //\r
-    TString &str = ExtractString(dcsVal);\r
-    if (!prevRec.IsNull()) {if (str == prevRec) continue;} // skip similar record\r
-    else prevRec = str;\r
-    //\r
-    AliLHCDipValC* curValS = new AliLHCDipValC(1,tstamp);      \r
-    curValS->SetValues(str.Data(),str.Length()+1);\r
-    //\r
-    fData.Add(curValS);\r
-    refs[kNStor]++;\r
-  }\r
-  if (fFile2Process) delete arr;\r
-  return refs[kNStor];\r
-}\r
-\r
-//___________________________________________________________________\r
-Int_t AliLHCData::FillBunchInfo(int refs[2],const char* rec, int ibm, Bool_t inRealSlots)\r
-{\r
-  // fill bunch properties for beam ibm\r
-  // if inRealSlots = true, then the value is taken from bunchRFbucket/10, otherwise, the value \r
-  // for the i-th bunch is taken from the i-th element\r
-  //\r
-  AliInfo(Form("Acquiring record: %s",rec));\r
-  TObjArray *arr;\r
-  Int_t iLast,iFirst;\r
-  //\r
-  refs[kStart] = fData.GetEntriesFast();\r
-  refs[kNStor] = 0;\r
-  //\r
-  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
-  //\r
-  while (iFirst<=iLast) {\r
-    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
-    double tstamp = dcsVal->GetTimeStamp();\r
-    //\r
-    AliLHCDipValI *bconf = GetBunchConfigMeasured(ibm,tstamp);\r
-    if (!bconf) {\r
-      AliWarning(Form("Mearured bunch configuration for beam %d at t=%.1f is not available, trying declared one",ibm+1,tstamp));\r
-      bconf = GetBunchConfigDeclared(ibm,tstamp);\r
-    }\r
-    if (!bconf) {\r
-      AliWarning(Form("Declared bunch configuration for beam %d at t=%.1f is not available, skip this record",ibm+1,tstamp));\r
-      return -1;\r
-    }\r
-    int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)\r
-    int nbunch = bconf->GetSize();\r
-    if (nbunch>nSlots) {\r
-      AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));\r
-      continue;\r
-    }\r
-    double* dcsArr = dcsVal->GetDouble();\r
-    AliLHCDipValF* curValF = new AliLHCDipValF(nbunch,tstamp);\r
-    for (int i=nbunch;i--;) {\r
-      int ind = inRealSlots ? (*bconf)[i]/10 : i;\r
-      if (ind>nSlots) {\r
-       AliError(Form("Bunch %d refers to wrong slot %d, set to -1",i,(*bconf)[i]));\r
-       (*curValF)[i] = -1;\r
-      }\r
-      else (*curValF)[i] = dcsArr[ind];\r
-    }\r
-    fData.Add(curValF);\r
-    refs[kNStor]++;\r
-  }\r
-  if (fFile2Process) delete arr;\r
-  return refs[kNStor];\r
-  //\r
-}\r
\r
-//___________________________________________________________________\r
-Int_t AliLHCData::FillBCLuminosities(int refs[2],const char* rec, const char* recErr, int useBeam)\r
-{\r
-  // fill luminosities per bunch crossing\r
-  //\r
-  AliInfo(Form("Acquiring record: %s",rec));\r
-  TObjArray *arr,*arrE=0;\r
-  Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;\r
-  //\r
-  refs[kStart] = fData.GetEntriesFast();\r
-  refs[kNStor] = 0;\r
-  //\r
-  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
-  //\r
-  while (iFirst<=iLast) {\r
-    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
-    double tstamp = dcsVal->GetTimeStamp();\r
-    //\r
-    AliLHCDipValI *bconf;\r
-    bconf = GetBunchConfigMeasured(useBeam,tstamp);  // luminosities are stored according to beam bunches\r
-    if (!bconf) {\r
-      AliWarning(Form("Mearured bunch configuration for beam%d at t=%.1f is not available, trying declared one",useBeam,tstamp));\r
-      bconf = GetBunchConfigDeclared(useBeam,tstamp);\r
-    }\r
-    if (!bconf) {\r
-      AliWarning(Form("Declared bunch configuration for beam%i at t=%.1f is not available, skip this record",useBeam,tstamp));\r
-      return -1;\r
-    }\r
-    int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)\r
-    int nbunch = bconf->GetSize();\r
-    double* dcsArr = dcsVal->GetDouble();\r
-    //\r
-    if (nbunch>nSlots) {\r
-      AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));\r
-      continue;\r
-    }\r
-    int dim = 0;\r
-    if (!bconf->IsProcessed1()) {\r
-      AliWarning(Form("Bunch conf. for beam%d has no marked interacting bunches, store all luminosity for all filled bunches",useBeam));\r
-      dim = nbunch;\r
-    }\r
-    else { // count number of interacting bunches\r
-      for (int i=nbunch;i--;) if ((*bconf)[i]<0) dim++;\r
-    }\r
-    //\r
-    if (recErr) {\r
-      arrE=GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);\r
-      dim += 1;\r
-    }\r
-    AliLHCDipValF* curValF = new AliLHCDipValF(dim,tstamp);\r
-    int cnt = 0;\r
-    for (int i=0;i<nbunch;i++) {\r
-      int slot = (*bconf)[i];\r
-      if (bconf->IsProcessed1() && slot>0) continue;\r
-      //\r
-      int ind = TMath::Abs(slot)/10;\r
-      if (ind>nSlots) {\r
-       AliError(Form("Bunch %d refers to wrong slot %d, set to -1",cnt,slot));\r
-       (*curValF)[cnt] = -1;\r
-      }\r
-      else (*curValF)[cnt] = dcsArr[ind];\r
-      cnt++;\r
-    }\r
-    //\r
-    if (recErr) {\r
-      double errVal = -1;\r
-      while (iFirstE<=iLastE) {       // try to find corresponding error\r
-       AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);\r
-       double tstamp1 = dcsValE->GetTimeStamp();\r
-       int tdif = TimeDifference(tstamp,tstamp1);\r
-       if (!tdif) { // error matches to value\r
-         errVal = dcsValE->GetDouble()[0];\r
-         iFirstE++; \r
-         break;\r
-       }\r
-       else if (tdif>0) iFirstE++; // error time lags behind, read the next one\r
-       else break;                 // error time is ahead of value, no error associated\r
-      }\r
-      (*curValF)[dim-1] = errVal;   // error\r
-      curValF->SetLastSpecial();    // lable the last entry as an error\r
-    }\r
-    //\r
-    fData.Add(curValF);\r
-    refs[kNStor]++;\r
-  }\r
-  if (fFile2Process) {\r
-    delete arr;\r
-    delete arrE;\r
-  }\r
-  return refs[kNStor];\r
-  //\r
-}\r
-\r
-//___________________________________________________________________\r
-Int_t AliLHCData::ExtractInt(AliDCSArray* dcsArray,Int_t el) const\r
-{\r
-  // extract integer from the dcsArray\r
-  int val = -1;\r
-  //\r
-  int sz = dcsArray->GetNEntries();\r
-  if (sz<=el) return val;\r
-  //\r
-  if (dcsArray->GetType()==AliDCSArray::kInt)  val = dcsArray->GetInt(el);\r
-  else if (dcsArray->GetType()==AliDCSArray::kString) {\r
-    TObjString *stro = dcsArray->GetStringArray(el);\r
-    if (stro) val = stro->GetString().Atoi();\r
-    else AliError(Form("DCSArray TObjString for element %d is missing",el));\r
-  }\r
-  else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);\r
-  else AliError(Form("Integer requested from DCSArray of type %d",dcsArray->GetType()));\r
-  return val;\r
-}\r
-\r
-//___________________________________________________________________\r
-Double_t AliLHCData::ExtractDouble(AliDCSArray* dcsArray,Int_t el) const\r
-{\r
-  // extract double from the dcsArray\r
-  double val = 0;\r
-  //\r
-  int sz = dcsArray->GetNEntries();\r
-  if (sz<=el) return val;\r
-  //\r
-  if      (dcsArray->GetType()==AliDCSArray::kDouble) val = dcsArray->GetDouble(el);\r
-  else if (dcsArray->GetType()==AliDCSArray::kFloat)  val = dcsArray->GetFloat(el);\r
-  else if (dcsArray->GetType()==AliDCSArray::kString) {\r
-    TObjString *stro = dcsArray->GetStringArray(el);\r
-    if (stro) val = stro->GetString().Atof();\r
-    else AliError(Form("DCSArray has TObjString for element %d is missing",el));\r
-  }\r
-  else if (dcsArray->GetType()==AliDCSArray::kChar)   val = dcsArray->GetChar(el);\r
-  else if (dcsArray->GetType()==AliDCSArray::kInt)    val = dcsArray->GetInt(el);\r
-  else if (dcsArray->GetType()==AliDCSArray::kUInt)   val = dcsArray->GetUInt(el);\r
-  else     AliError(Form("Double requested from DCSArray of type %d",dcsArray->GetType()));\r
-  return val;\r
-}\r
-\r
-//___________________________________________________________________\r
-TString& AliLHCData::ExtractString(AliDCSArray* dcsArray) const\r
-{\r
-  // extract string from the dcsArray\r
-  static TString str;\r
-  str = "";\r
-  //\r
-  int sz = dcsArray->GetNEntries();\r
-  if (dcsArray->GetType()!=AliDCSArray::kString)  {\r
-    AliError(Form("String requested from DCSArray of type %d",dcsArray->GetType()));\r
-    return str;\r
-  }\r
-  //\r
-  for (int i=0;i<sz;i++) {\r
-    str += dcsArray->GetStringArray(i)->GetString();\r
-    if (i<sz-1) str += " ";\r
-  }\r
-  return str;\r
-}\r
-\r
-//___________________________________________________________________\r
-void AliLHCData::Print(const Option_t* opt) const\r
-{\r
-  // print full info\r
-  TString opts = opt;\r
-  opts.ToLower();\r
-  Bool_t utcTime = opts.Contains("loc") ? kFALSE:kTRUE;\r
-  Bool_t full = kTRUE;\r
-  if (!opts.Contains("f")) {\r
-    printf("Use Print(\"f\") to print full info\n");\r
-    printf("Printing short info:\n<RecordType>(number of records): <TimeStamp, value> for 1st record only\n");\r
-    full = kFALSE;\r
-  }\r
-  TString sdtmn = AliLHCDipValI::TimeAsString(fTMin,utcTime);\r
-  TString sdtmx = AliLHCDipValI::TimeAsString(fTMax,utcTime);\r
-  printf("Fill#%6d Validity: %s - %s (%s)\n",fFillNumber,sdtmn.Data(),sdtmx.Data(),utcTime ? "UTC":"LOC");\r
-  //\r
-  printf("********** SETTINGS FROM RUN CONTROL **********\n");\r
-  //\r
-  printf("* %-38s","Injection Scheme");\r
-  PrintAux(full,fRCInjScheme,opts);\r
-  //\r
-  printf("* %-38s","Beta Star");\r
-  PrintAux(full,fRCBeta,opts);\r
-  //\r
-  printf("* %-38s","Horisontal Crossing Angle");\r
-  PrintAux(full,fRCAngH,opts);\r
-  //\r
-  printf("* %-38s","Vertical   Crossing Angle");\r
-  PrintAux(full,fRCAngV,opts);\r
-  //\r
-  for (int ib=0;ib<2;ib++) {\r
-    printf("* Beam%d filling  [- interacts at IR2!]  ",ib+1);\r
-    PrintAux(full,fBunchConfDecl[ib],opts);\r
-  }\r
-  //\r
-  printf("\n**********       MEASURED DATA       **********\n");\r
-  //\r
-  for (int ib=0;ib<2;ib++) {\r
-    printf("* Beam%d filling  [- interacts at IR2!]  ",ib+1);\r
-    PrintAux(full,fBunchConfMeas[ib],opts);\r
-  } \r
-  //\r
-  for (int ib=0;ib<2;ib++) {\r
-    printf("* Beam%d total intensity                 ",ib+1);\r
-    PrintAux(full,fIntensTotal[ib],opts);\r
-  } \r
-  //\r
-  for (int ib=0;ib<2;ib++) {\r
-    printf("* Beam%d total intensity (bunch average) ",ib+1);\r
-    PrintAux(full,fIntensTotalAv[ib],opts);\r
-  } \r
-  //\r
-  for (int ib=0;ib<2;ib++) {\r
-    printf("* Beam%d intensity per bunch             ",ib+1);\r
-    PrintAux(full,fIntensPerBunch[ib],opts);\r
-  }\r
-  //\r
-  for (int ib=0;ib<2;ib++) {\r
-    printf("* Beam%d bunch lengths                   ",ib+1);\r
-    PrintAux(full,fBunchLengths[ib],opts);\r
-  } \r
-  //\r
-  for (int ib=0;ib<2;ib++) {\r
-    printf("* Beam%d Horisontal emittance            ",ib+1);\r
-    PrintAux(full,fEmittanceH[ib],opts);\r
-  }\r
-  //\r
-  for (int ib=0;ib<2;ib++) {\r
-    printf("* Beam%d Vertical emittance              ",ib+1);\r
-    PrintAux(full,fEmittanceV[ib],opts);\r
-  }\r
-  //\r
-  for (int ib=0;ib<2;ib++) {\r
-    printf("* Beam%d Horisontal sigma                ",ib+1);\r
-    PrintAux(full,fBeamSigmaH[ib],opts);\r
-  }\r
-  //\r
-  for (int ib=0;ib<2;ib++) {\r
-    printf("* Beam%d Vertical sigma                  ",ib+1);\r
-    PrintAux(full,fBeamSigmaV[ib],opts);\r
-  }\r
-  //\r
-  for (int lr=0;lr<2;lr++) {\r
-    printf("* Total luminosity from BRANB_4%c2       ",lr ? 'R':'L');\r
-    PrintAux(full,fLuminTotal[lr],opts);\r
-  } \r
-  //\r
-  for (int lr=0;lr<2;lr++) {\r
-    printf("* Luminosity acq.mode, BRANB_4%c2        ",lr ? 'R':'L');\r
-    PrintAux(full,fLuminAcqMode[lr],opts+"bit");\r
-  } \r
-  //\r
-  for (int lr=0;lr<2;lr++) {\r
-    printf("* Luminosity per BC from BRANB_4%c2      ",lr ? 'R':'L');\r
-    PrintAux(full,fLuminPerBC[lr],opts);\r
-  }\r
-  //\r
-  for (int lr=0;lr<2;lr++) {\r
-    printf("* Crossing angle, side %c                ",lr ? 'R':'L');\r
-    PrintAux(full,fCrossAngle[lr],opts);\r
-  }\r
-  //\r
-  for (int coll=0;coll<kNCollimators;coll++)\r
-    for (int jaw=0;jaw<kNJaws;jaw++) {\r
-      printf("* Collimator %10s:%16s",fgkDCSColNames[coll],fgkDCSColJaws[jaw]);\r
-      PrintAux(full,fCollimators[coll][jaw],opts);\r
-    }\r
-  //\r
-}\r
-\r
-//___________________________________________________________________\r
-void AliLHCData::PrintAux(Bool_t full, const Int_t refs[2], const Option_t *opt) const\r
-{\r
-  // aux method to print the reocrds of the same type\r
-  int nrec = refs[kNStor];\r
-  if (nrec<1) {\r
-    printf(": N/A\n"); \r
-    return;\r
-  }\r
-  printf(": (%3d):\t",nrec); // number of records\r
-  if (!full) nrec = 1;\r
-  int sz = ((AliLHCDipValI*)fData[refs[kStart]])->GetSizeTotal(); // dimension of the record\r
-  Bool_t isStr = ((AliLHCDipValI*)fData[refs[kStart]])->IsTypeC();\r
-  if ((!isStr && sz>2) || nrec>1) printf("\n"); // long record, open new line\r
-  for (int i=0;i<nrec;i++) fData[refs[kStart]+i]->Print(opt);\r
-  //\r
-}\r
-\r
-//___________________________________________________________________\r
-void AliLHCData::Clear(const Option_t *)\r
-{\r
-  // clear all info\r
-  fData.Delete();\r
-  fFillNumber = 0;\r
-  fTMin = 0;\r
-  fTMax = 1e10;\r
-  fFile2Process = 0;\r
-  fMap2Process  = 0;\r
-  //\r
-  for (int i=2;i--;) {\r
-    fRCInjScheme[i] = 0;\r
-    fRCBeta[i] = 0;\r
-    fRCAngH[i] = 0;\r
-    fRCAngV[i] = 0;\r
-    //\r
-    for (int icl=kNCollimators;icl--;) for (int jaw=kNJaws;jaw--;) fCollimators[icl][jaw][i]=0;\r
-    //\r
-    for (int j=2;j--;) {\r
-      fBunchConfDecl[j][i] = 0;\r
-      fBunchConfMeas[j][i] = 0;\r
-      fBunchLengths[j][i] = 0;\r
-      fIntensTotal[j][i] = 0;\r
-      fIntensTotalAv[j][i] = 0;\r
-      fIntensPerBunch[j][i] = 0;      \r
-      fCrossAngle[j][i] = 0;\r
-      fEmittanceH[j][i] = 0;\r
-      fEmittanceV[j][i] = 0;\r
-      fBeamSigmaH[j][i] = 0;\r
-      fBeamSigmaV[j][i] = 0;\r
-      fLuminTotal[j][i] = 0;\r
-      fLuminPerBC[j][i] = 0;\r
-      fLuminAcqMode[j][i] = 0;\r
-    }\r
-  }\r
-}\r
-\r
-//___________________________________________________________________\r
-Int_t AliLHCData::GetNInteractingBunchesMeasured(int i) const\r
-{\r
-  // get number of interacting bunches at IR2\r
-  AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r
-  if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
-  if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1;}\r
-  int n = 0;\r
-  for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;\r
-  return n;\r
-}\r
-\r
-//___________________________________________________________________\r
-Int_t AliLHCData::GetNInteractingBunchesDeclared(int i) const\r
-{\r
-  // get number of interacting bunches at IR2\r
-  AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r
-  if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
-  if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1; }\r
-  int n = 0;\r
-  for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;\r
-  return n;\r
-}\r
-\r
-//___________________________________________________________________\r
-Int_t AliLHCData::IsPilotPresent(int i) const\r
-{\r
-  // check in the filling scheme is the pilot bunch is present\r
-  AliLHCDipValC* rec = GetInjectionScheme();\r
-  if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
-  TString scheme = rec->GetValues();\r
-  return scheme.Contains("wp",TString::kIgnoreCase);\r
-}\r
-\r
-//___________________________________________________________________\r
-void AliLHCData::FlagInteractingBunches(const Int_t beam1[2],const Int_t beam2[2])\r
-{\r
-  // assign - sign to interacting bunches\r
-  //\r
-  for (int ib1=0;ib1<beam1[kNStor];ib1++) {\r
-    AliLHCDipValI *bm1 = (AliLHCDipValI*)fData[ beam1[kStart] + ib1];\r
-    if (!bm1) continue;\r
-    AliLHCDipValI *bm2 = (AliLHCDipValI*)FindRecValidFor(beam2[kStart],beam2[kNStor], bm1->GetTimeStamp());\r
-    if (!bm2) continue;\r
-    //\r
-    int nb1 = bm1->GetSize();\r
-    int nb2 = bm2->GetSize();\r
-    int i1,i2;\r
-    for (i1=0;i1<nb1;i1++) {\r
-      int bunch2=-1, bunch1 = TMath::Abs((*bm1)[i1]);\r
-      int slot2 =-1, slot1  = GetBCId(bunch1,0);\r
-      for (i2=0;i2<nb2;i2++) {\r
-       bunch2 = TMath::Abs((*bm2)[i2]);\r
-       slot2 = GetBCId(bunch2,1);\r
-       if (slot1==slot2) break;\r
-      }\r
-      if (slot1!=slot2) continue;\r
-      (*bm1)[i1] = -bunch1;\r
-      (*bm2)[i2] = -bunch2;\r
-      bm1->SetProcessed1();\r
-      bm2->SetProcessed1();\r
-    }\r
-  }\r
-}\r
-\r
-//___________________________________________________________________\r
-Int_t AliLHCData::GetMeanIntensity(int beamID, Double_t &colliding, Double_t &noncolliding, const TObjArray* bcmasks) const\r
-{\r
-  // get average intensity for all, colliding and non-colliding bunches\r
-  // on success returns number of intensity records used (1 per ~10 min)\r
-  // If triggered BC masks are provided, calculation is done for Triggered BC only\r
-  colliding = noncolliding = -1.;\r
-  if (beamID<0||beamID>1) {\r
-    AliError(Form("BeamID must be either 0 or 1, %d requested",beamID));\r
-    return -10;\r
-  }\r
-  //\r
-  AliTriggerBCMask *bcMaskBoth=0,*bcMaskSingle=0;\r
-  int nbcm = 0;\r
-  if (bcmasks && (nbcm=bcmasks->GetEntries())) {\r
-    if (nbcm>1) bcMaskBoth = (AliTriggerBCMask*)bcmasks->At(1);\r
-    if      (nbcm>0 && beamID==kBeam1) bcMaskSingle = (AliTriggerBCMask*)bcmasks->At(0);\r
-    else if (nbcm>2 && beamID==kBeam2) bcMaskSingle = (AliTriggerBCMask*)bcmasks->At(2);\r
-    //\r
-    if (!bcMaskSingle) AliError(Form("Only triggered BSs are requested but %c mask is not provided",beamID ? 'C':'A'));\r
-    if (!bcMaskBoth)   AliError("Only triggered BSs are requested but B mask is not provided");\r
-  }\r
-  else {\r
-    AliWarning("No BC masks are provided");\r
-  }\r
-  //\r
-  int nrec = GetNIntensityPerBunch(beamID);\r
-  if (nrec<1) return -1;\r
-  AliLHCDipValI *conf = GetBunchConfigMeasured(beamID);\r
-  if (!conf) conf = GetBunchConfigDeclared(beamID);\r
-  if (!conf) return -2;\r
-  int nb = conf->GetSize();\r
-  //\r
-  for (int irec=0;irec<nrec;irec++) {\r
-    //\r
-    AliLHCDipValF* rInt = GetIntensityPerBunch(beamID,irec);\r
-    for (int ib=0;ib<nb;ib++) {\r
-      double val = rInt->GetValue(ib);\r
-      if (val<0) continue;\r
-      int bID = conf->GetValue(ib);\r
-      // check if this is a triggered bunch\r
-      int bcID = GetBCId(bID, beamID);\r
-      if (bID<0) { // interacting\r
-       if (bcMaskBoth && bcMaskBoth->GetMask(bcID)) continue; // masked\r
-       colliding += val;\r
-      }\r
-      else {\r
-       if (bcMaskSingle && bcMaskSingle->GetMask(bcID)) continue; // masked    \r
-       noncolliding += val;\r
-      }\r
-    }\r
-  }\r
-  colliding /= nrec;\r
-  noncolliding /= nrec;\r
-  return nrec;\r
-}\r
+/**************************************************************************
+ * 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.                  *
+ *                                                                        *
+ **************************************************************************/
+
+/********************************************************************************
+*                                                                               *
+*   AliLHCData: summary of the LHC related information from LHC DIP.            *
+*   Created from the TMap provided by the AliLHCReader with optional beginning  *
+*                                                                               *
+*   The data are (wrapped in the AliLHCDipValT):                                *
+*   made of TimeStamp (double) and array of values                              *
+*                                                                               *
+*   Multiple entries for each type of data are possible. To obtaine number of   *
+*   records (with distinct timestamp) for give type od records use:             *
+*   int GetNBunchConfigMeasured(int beam) (with beam=0,1) etc.                  *
+*                                                                               *
+*   To get i-th entry, use brec= AliLHCDipValI* GetBunchConfigMeasured(bm,i);   *
+*   Note: exact type of templated AliLHCDipValT pointer depends on the record   *
+*   type, concult getters to know it.                                           *
+*                                                                               *
+*   Then, once the pointer is obtained, details can be accessed:                *
+*   int nBunches = brec->GetSize();                                             *
+*   for (int i=0;i<nBunches;i++) printf("Bunch#%d: %d\n",i,(*brec)[i]);         *
+*                                                                               *
+*                                                                               *
+*   Author: ruben.shahoyan@cern.ch                                              *
+*                                                                               *
+********************************************************************************/
+
+#include "AliLHCData.h"
+#include "TMap.h"
+#include "AliDCSArray.h"
+#include "AliLHCReader.h"
+#include "AliTriggerBCMask.h"
+#include <TString.h>
+#include <TObjArray.h>
+#include <TGraph.h>
+
+ClassImp(AliLHCData)
+
+const Char_t* AliLHCData::fgkDCSNames[] = {
+  "LHC_IntensityBeam%1d_totalIntensity"
+  ,"LHC_BeamIntensityPerBunchBeam%1d_averageBeamIntensity"
+  ,"LHC_BeamIntensityPerBunchBeam%1d_Average_BunchIntensities"
+  //
+  ,"LHC_LumAverageBRANB_4%c2_acqMode"
+  ,"LHC_LumAverageBRANB_4%c2_meanLuminosity"
+  ,"LHC_LumAverageBRANB_4%c2_meanLuminosityError"
+  ,"LHC_BeamLuminosityPerBunchBRANB_4%c2_Average_BunchLuminosity"
+  ,"LHC_BeamLuminosityPerBunchBRANB_4%c2_BunchLuminosityError"
+  ,"LHC_LumAverageBRANB_4%c2_meanCrossingAngle"
+  ,"LHC_LumAverageBRANB_4%c2_meanCrossingAngleError"
+  ,"LHC_CirculatingBunchConfig_Beam%d"
+  ,"LHC_FillNumber"
+  //
+  ,"LHC_BunchLengthBeam%1d_nBunches"
+  ,"LHC_BunchLengthBeam%1d_bunchesLenghts"
+  ,"LHC_BunchLengthBeam%1d_filledBuckets"
+  //
+  ,"LHC_RunControl_ActiveInjectionScheme"
+  ,"LHC_RunControl_BetaStar"
+  ,"LHC_RunControl_IP2_Xing_Murad"
+  ,"LHC_RunControl_IP2_ALICE_Murad"
+
+  ,"LHC_BeamSizeBeam%1d_acqMode"
+  ,"LHC_BeamSizeBeam%1d_sigmaH"
+  ,"LHC_BeamSizeBeam%1d_sigmaV"
+  ,"LHC_BeamSizeBeam%1d_emittanceH"
+  ,"LHC_BeamSizeBeam%1d_emittanceV"
+  ,"LHC_BeamSizeBeam%1d_errorSigmaH"
+  ,"LHC_BeamSizeBeam%1d_errorSigmaV"
+  //
+  ,"LHC_CollimatorPos_%s_lvdt_%s"
+  //
+  ,"BPTX_deltaT_B1_B2"
+  ,"BPTX_deltaTRMS_B1_B2"
+  ,"BPTX_Phase_B%1d"
+  ,"BPTX_PhaseRMS_B%1d"
+  ,"BPTX_Phase_Shift_B%1d"
+  //
+  ,"ALI_Lumi_Total_Inst"
+  ,"ALI_Lumi_Total_Delivered_StabBeam"
+  ,"ALI_Lumi_Bunch_Inst"
+  ,"ALI_Background%1d"
+};
+
+const Char_t* AliLHCData::fgkDCSColNames[] = {
+  "TCTVB_4L2",
+  "TCTVB_4R2",
+  "TCLIA_4R2"
+};
+
+const Char_t* AliLHCData::fgkDCSColJaws[] = {
+  "gap_downstream","gap_upstream","left_downstream",
+  "left_upstream","right_downstream","right_upstream"};
+
+//___________________________________________________________________
+AliLHCData::AliLHCData(const TMap* dcsMap, double tmin, double tmax)
+  : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fkFile2Process(0),fkMap2Process(0)
+{
+  FillData(dcsMap,tmin,tmax);
+}
+
+//___________________________________________________________________
+AliLHCData::AliLHCData(const Char_t* dcsFile, double tmin, double tmax)
+  : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fkFile2Process(dcsFile),fkMap2Process(0)
+{
+  FillData(dcsFile,tmin,tmax);
+}
+
+//___________________________________________________________________
+Bool_t AliLHCData::FillData(const TMap*   dcsMap,double tmin, double tmax)
+{
+  // process DCS map and fill all fields. 
+  Clear();
+  fkMap2Process = dcsMap;
+  FillData(tmin,tmax);
+  return kTRUE;
+}
+
+//___________________________________________________________________
+Bool_t AliLHCData::FillData(const Char_t* dcsFile,double tmin, double tmax)
+{
+  // process DCS file and fill all fields. 
+  Clear();
+  fkFile2Process = dcsFile;
+  FillData(tmin,tmax);
+  return kTRUE;
+}
+
+//___________________________________________________________________
+Bool_t AliLHCData::FillData(double tmin, double tmax)
+{
+  // process DCS map and fill all fields. 
+  // Accept only entries with timestamp between tmin and tmax
+  //
+  char buff[100],buff1[100];
+  //
+  SetTMin(tmin);
+  SetTMax(tmax);
+  //
+  // -------------------------- extract Fill Number
+  int iFirst=0,iLast=0;
+  TObjArray* arr = GetDCSEntry(fgkDCSNames[kFillNum],iFirst,iLast,fTMin,fTMax);
+  if (arr) SetFillNumber( ExtractInt( (AliDCSArray*)arr->At(iFirst), 0) );
+  if (fkFile2Process) delete arr; // array was created on demand
+  //
+  for (int ibm=0;ibm<2;ibm++) {
+    //
+    snprintf(buff,99,fgkDCSNames[kBunchConf],ibm+1);         // ----- declared bunch configuration
+    FillBunchConfig(fBunchConfDecl[ibm], buff);
+    //
+    snprintf(buff,99,fgkDCSNames[kBunchLgtFillB],ibm+1);     // ----- measured bunch configuration
+    FillBunchConfig(fBunchConfMeas[ibm], buff);
+    //
+    snprintf(buff,99,fgkDCSNames[kBunchLgt],ibm+1);          // ----- measured bunch lenghts
+    FillBunchInfo(fBunchLengths[ibm],buff,ibm,kFALSE);  
+    //
+    snprintf(buff,99,fgkDCSNames[kIntBunchAv],ibm+1);        // ----- B-by-B intensities
+    FillBunchInfo(fIntensPerBunch[ibm],buff,ibm,kTRUE);
+    //
+    //
+    snprintf(buff,99,fgkDCSNames[kIntTot],ibm+1);            // ----- total intensities for beam 1 and 2
+    FillScalarRecord(fIntensTotal[ibm], buff);
+    //
+    snprintf(buff,99,fgkDCSNames[kIntTotAv],ibm+1);          // ----- total intensities for beam 1 and 2 from B-by-B average
+    FillScalarRecord(fIntensTotalAv[ibm], buff);
+    //
+    snprintf(buff,99,fgkDCSNames[kBeamSzEmittH],ibm+1);      // ----- H emittance for beam 1 and 2 
+    FillScalarRecord(fEmittanceH[ibm], buff);
+    //
+    snprintf(buff,99,fgkDCSNames[kBeamSzEmittV],ibm+1);      // ----- V emittance for beam 1 and 2 
+    FillScalarRecord(fEmittanceV[ibm], buff);
+    //
+    snprintf(buff,99 ,fgkDCSNames[kBeamSzSigH],   ibm+1);    // ----- H sigmas and errors for beam 1 and 2 
+    snprintf(buff1,99,fgkDCSNames[kBeamSzSigHErr],ibm+1);
+    FillScalarRecord(fBeamSigmaH[ibm], buff, buff1);
+    //
+    snprintf(buff,99 ,fgkDCSNames[kBeamSzSigV],   ibm+1);    // ----- V sigmas and errors for beam 1 and 2 
+    snprintf(buff1,99,fgkDCSNames[kBeamSzSigVErr],ibm+1);
+    FillScalarRecord(fBeamSigmaV[ibm], buff, buff1);
+    //
+    //
+    snprintf(buff,99,fgkDCSNames[kBPTXPhase],ibm+1);         // ----- BPTXPhase beam 1 and 2
+    FillScalarRecord(fBPTXPhase[ibm], buff);
+    //
+    snprintf(buff,99,fgkDCSNames[kBPTXPhaseRMS],ibm+1);      // ----- BPTXPhaseRMS beam 1 and 2
+    FillScalarRecord(fBPTXPhaseRMS[ibm], buff);
+    //
+    snprintf(buff,99,fgkDCSNames[kBPTXPhaseShift],ibm+1);    // ----- BPTXPhaseShift beam 1 and 2
+    FillScalarRecord(fBPTXPhaseShift[ibm], buff);
+    //
+  }
+  //
+  for (int ibg=0;ibg<kNBGs;ibg++) {
+    snprintf(buff,99,fgkDCSNames[kALIBackground],ibg+1);    // ----- Alice backgrounds 1,2,3
+    FillScalarRecord(fBckgAlice[ibg], buff);
+  }
+  //
+  FlagInteractingBunches(fBunchConfMeas[0],fBunchConfMeas[1]);
+  FlagInteractingBunches(fBunchConfDecl[0],fBunchConfDecl[1]);
+  //
+  for (int ilr=0;ilr<2;ilr++) {
+    //
+    snprintf(buff,99 ,fgkDCSNames[kLumBunch], ilr ? 'R':'L');       // ---- BC-by-BC luminosity at IP2 and its error
+    snprintf(buff1,99,fgkDCSNames[kLumBunchErr], ilr ? 'R':'L');
+    FillBCLuminosities(fLuminPerBC[ilr], buff, buff1, 0); // BRAN L uses beam2 as a reference, BRAN R - beam1
+    //
+    snprintf(buff,99 ,fgkDCSNames[kLumTot]   , ilr ? 'R':'L');       // ---- total luminosity at IP2 and its error
+    snprintf(buff1,99,fgkDCSNames[kLumTotErr], ilr ? 'R':'L');
+    FillScalarRecord(fLuminTotal[ilr], buff, buff1);
+    //
+    snprintf(buff,99 ,fgkDCSNames[kLumAcqMode], ilr ? 'R':'L');      // ---- luminosity acquisition mode
+    FillAcqMode(fLuminAcqMode[ilr], buff);
+    //
+    snprintf(buff,99, fgkDCSNames[kLumCrossAng]   , ilr ? 'R':'L');  //----- crossing angle at IP2 and its error
+    snprintf(buff1,99,fgkDCSNames[kLumCrossAngErr], ilr ? 'R':'L');
+    FillScalarRecord(fCrossAngle[ilr], buff, buff1);
+    //    
+  }
+  //
+  for (int icl=0;icl<kNCollimators;icl++) {             // ----- collimators positions
+    for (int jaw=0;jaw<kNJaws;jaw++) {
+      snprintf(buff,99,fgkDCSNames[kCollPos], fgkDCSColNames[icl],fgkDCSColJaws[jaw]);        
+      FillScalarRecord(fCollimators[icl][jaw], buff);
+    } // jaws
+  } // collimators
+  //
+  //
+  // RunControl info
+  FillStringRecord(fRCInjScheme, fgkDCSNames[kRCInjSch]);   // ---- active injection scheme
+  FillScalarRecord(fRCBeta, fgkDCSNames[kRCBeta]);          // ---- target beta 
+  FillScalarRecord(fRCAngH, fgkDCSNames[kRCCrossAng]);      // ---- horisontal angle
+  FillScalarRecord(fRCAngV,fgkDCSNames[kRCVang] );          // ---- vertical angle
+  //
+  FillScalarRecord(fBPTXdTB1B2,    fgkDCSNames[kBPTXdeltaTB1B2]);
+  FillScalarRecord(fBPTXdTRMSB1B2, fgkDCSNames[kBPTXdeltaTRMSB1B2]);
+  FillScalarRecord(fLumiAlice,     fgkDCSNames[kALILumiTotalInst]);
+  FillScalarRecord(fLumiAliceStB,  fgkDCSNames[kALILumiTotalDeliveredStabBeam]);  
+  FillBCLuminosities(fLumiAliceBbB,fgkDCSNames[kALILumiBunchInst],0,0);  
+  //
+  return kTRUE;
+}
+
+//___________________________________________________________________
+TObjArray* AliLHCData::GetDCSEntry(const char* key,int &entry,int &last,double tmin,double tmax) const
+{
+  // extract array from the DCS map or file and find the first entry within the time limits
+  entry = -1;
+  last = -2;
+  TObjArray* arr;
+  if (fkMap2Process) arr = (TObjArray*)fkMap2Process->GetValue(key);
+  else if (fkFile2Process) {
+    AliLHCReader rd;
+    arr = rd.ReadSingleLHCDP(fkFile2Process,key);
+  }
+  else {
+    AliError("Neither DCS map nor DCS filename are set");
+    return 0;  
+  }
+  //
+  if (!arr || !arr->GetEntriesFast()) { 
+    AliWarning(Form("No data for %s",key)); 
+    if (fkMap2Process) delete arr; // created on demand
+    return 0;
+  }
+  int ntot = arr->GetEntriesFast();
+  //
+  // search 1st entry before or at tmin
+  AliDCSArray* ent = 0;
+  Bool_t found = kFALSE;
+  for (entry=0;entry<ntot;entry++) {
+    ent = (AliDCSArray*)arr->At(entry);
+    if (ent->GetTimeStamp()>=tmin-kMarginSOR && ent->GetTimeStamp()<=tmax+kMarginEOR) {
+      found = kTRUE;
+      if (ent->GetTimeStamp()>tmin) break;
+    }
+  }
+  if (!found) {
+    entry = -1;
+    TString str;
+    str += AliLHCDipValF::TimeAsString(tmin);
+    str += " : ";
+    str += AliLHCDipValF::TimeAsString(tmax);
+    AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));
+    if (fkMap2Process) delete arr; // created on demand
+    return 0;
+  }
+  if (entry>0) entry--;
+  //
+  // search last entry at or after tmin
+  ent = 0;
+  for (last=entry;last<ntot;last++) {
+    ent = (AliDCSArray*)arr->At(last);
+    if (ent->GetTimeStamp()>tmax) break;
+  }
+  if (last == ntot) last--;
+  else if (ent->GetTimeStamp()>tmax+kMarginEOR) last--;
+  //
+  return arr;
+}
+
+//___________________________________________________________________
+Int_t AliLHCData::TimeDifference(double v1,double v2,double tol) const
+{
+  // return 0 if the times are the same within the tolerance
+  //        1 if v1>v2
+  //       -1 if v1<v2
+  v1-=v2;
+  if (v1>tol)  return  1;
+  if (v1<-tol) return -1;
+  return 0;
+}
+
+//___________________________________________________________________
+Bool_t AliLHCData::GoodPairID(int beam) const
+{
+  // check for correct beam identifier 
+  if (beam>kBeam2||beam<0) {AliError(Form("BeamID can be 0 or 1, %d requested",beam)); return kFALSE;}
+  return kTRUE;
+}
+
+//___________________________________________________________________
+AliLHCDipValI* AliLHCData::GetBunchConfigMeasured(int beam,double tstamp) const
+{
+  // find measured bunch configuration valid for given tstamp
+  if (!GoodPairID(beam)) return 0;
+  return (AliLHCDipValI*)FindRecValidFor(fBunchConfMeas[beam][kStart],fBunchConfMeas[beam][kNStor],tstamp);
+}
+
+//___________________________________________________________________
+AliLHCDipValI* AliLHCData::GetBunchConfigDeclared(int beam,double tstamp) const
+{
+  // find declared bunch configuration valid for given tstamp
+  if (!GoodPairID(beam)) return 0;
+  return (AliLHCDipValI*)FindRecValidFor(fBunchConfDecl[beam][kStart],fBunchConfDecl[beam][kNStor],tstamp);
+}
+
+//___________________________________________________________________
+TObject* AliLHCData::FindRecValidFor(int start,int nrec, double tstamp) const
+{
+  // find record within this limits valid for given tstamp (i.e. the last one before or equal to tstamp)
+  AliLHCDipValI *prevObj = 0;
+  for (int i=0;i<nrec;i++) {
+    AliLHCDipValI* curObj = (AliLHCDipValI*)fData[start+i];
+    if (TimeDifference(tstamp,curObj->GetTimeStamp())<=0) break;
+    prevObj = curObj;
+  }
+  if (!prevObj && nrec>0) prevObj = (AliLHCDipValI*)fData[start]; // if no exact match, return the 1st one
+  return prevObj;
+}
+
+//___________________________________________________________________
+Int_t AliLHCData::FillScalarRecord(int refs[2], const char* rec, const char* recErr, Double_t maxAbsVal)
+{
+  // fill record for scalar value, optionally accompanied by measurement error 
+  //
+  AliInfo(Form("Acquiring record: %s",rec));
+  //
+  TObjArray *arr=0,*arrE=0;
+  Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;
+  //
+  refs[kStart] = fData.GetEntriesFast();
+  refs[kNStor] = 0;
+  //
+  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
+  //
+  int dim = 1;
+  if (recErr) {
+    arrE = GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);
+    dim += 1;
+  }
+  //
+  // Bool_t last = kFALSE;
+  while (iFirst<=iLast) {
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
+    double tstamp = dcsVal->GetTimeStamp();
+    //
+    AliLHCDipValF* curValD = new AliLHCDipValF(dim,tstamp);  // start new period
+    double vcheck = ExtractDouble(dcsVal,0);     // value
+    if (TMath::Abs(vcheck) > maxAbsVal) {
+      AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",vcheck, 0, rec, maxAbsVal));
+      vcheck = 0.;
+    }    
+    (*curValD)[0] = vcheck;
+    //
+    if (recErr) {
+      double errVal = -1;
+      while (iFirstE<=iLastE) {       // try to find corresponding error
+       AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);
+        double tstampE = dcsValE->GetTimeStamp();
+        int tdif = TimeDifference(tstamp,tstampE);
+        if (!tdif) { // error matches to value
+         errVal = ExtractDouble(dcsVal,0);     // value
+         if (TMath::Abs(errVal) > maxAbsVal) {
+           AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",errVal, 0, recErr, maxAbsVal));
+           errVal = 0.;
+         }
+         iFirstE++; 
+         break;
+       }
+        else if (tdif>0) iFirstE++; // error time lags behind, read the next one
+        else break;                 // error time is ahead of value, no error associated
+      }
+      (*curValD)[dim-1] = errVal;   // error
+      curValD->SetLastSpecial();    // lable the last entry as an error
+    }
+    //
+    fData.Add(curValD);
+    refs[kNStor]++;
+    // if (last) break;
+  }
+  //
+  if (fkFile2Process) {
+    delete arr;
+    delete arrE;
+  }
+  return refs[kNStor];
+}
+
+//___________________________________________________________________
+Int_t AliLHCData::FillBunchConfig(int refs[2],const char* rec)
+{
+  // fill record for bunch configuration
+  //
+  AliInfo(Form("Acquiring record: %s",rec));
+  TObjArray *arr;
+  Int_t iLast,iFirst;
+  //
+  refs[kStart] = fData.GetEntriesFast();
+  refs[kNStor] = 0;
+  //
+  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
+  //
+  AliLHCDipValI* prevRecI=0;
+  //  
+  while (iFirst<=iLast) {
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
+    double tstamp = dcsVal->GetTimeStamp();
+    //
+    int bucket=0, nbunch=0, ndiff=0;
+    int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)
+    int* dcsArr = dcsVal->GetInt();
+    while(nbunch<nSlots && (bucket=dcsArr[nbunch])) {
+      if (prevRecI && prevRecI->GetSize()>nbunch && bucket!=prevRecI->GetValue(nbunch)) ndiff++;
+      nbunch++;
+    }
+    if (!nbunch) AliWarning(Form("%s record is present but empty: no beam?",rec));
+    if (prevRecI && !ndiff && nbunch==prevRecI->GetSize()) continue; // record similar to previous one
+    AliLHCDipValI* curValI = new AliLHCDipValI(nbunch,tstamp);      
+    for (int i=nbunch;i--;) (*curValI)[i] = dcsArr[i];
+    fData.Add(curValI);
+    refs[kNStor]++;
+    prevRecI = curValI;
+  }
+  //
+  if (fkFile2Process) delete arr;
+  return refs[kNStor];
+}
+//___________________________________________________________________
+Int_t AliLHCData::FillAcqMode(int refs[2],const char* rec)
+{
+  // fill acquisition mode
+  //
+  AliInfo(Form("Acquiring record: %s",rec));
+  TObjArray *arr;
+  Int_t iLast,iFirst;
+  //
+  refs[kStart] = fData.GetEntriesFast();
+  refs[kNStor] = 0;
+  //
+  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
+  //
+  AliLHCDipValI* prevRecI=0;
+  while (iFirst<=iLast) {
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
+    double tstamp = dcsVal->GetTimeStamp();
+    //
+    int nSlots = dcsVal->GetNEntries();
+    if (nSlots<1) continue;
+    int acqMode = dcsVal->GetInt()[0];
+    if (prevRecI && (*prevRecI)[0] == acqMode) continue; // record similar to previous one
+    AliLHCDipValI* curValI = new AliLHCDipValI(1,tstamp);      
+    (*curValI)[0] = acqMode;
+    fData.Add(curValI);
+    refs[kNStor]++;
+    prevRecI = curValI;
+  }
+  //
+  if (fkFile2Process) delete arr;
+  return refs[kNStor];
+}
+//___________________________________________________________________
+Int_t AliLHCData::FillStringRecord(int refs[2],const char* rec)
+{
+  // fill record with string value
+  //
+  AliInfo(Form("Acquiring record: %s",rec));
+  TString prevRec;
+  TObjArray *arr;
+  Int_t iLast,iFirst;
+  //
+  refs[kStart] = fData.GetEntriesFast();
+  refs[kNStor] = 0;
+  //
+  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
+  //
+  while (iFirst<=iLast) {
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
+    double tstamp = dcsVal->GetTimeStamp();
+    //
+    TString &str = ExtractString(dcsVal);
+    if (!prevRec.IsNull()) {if (str == prevRec) continue;} // skip similar record
+    else prevRec = str;
+    //
+    AliLHCDipValC* curValS = new AliLHCDipValC(1,tstamp);      
+    curValS->SetValues(str.Data(),str.Length()+1);
+    //
+    fData.Add(curValS);
+    refs[kNStor]++;
+  }
+  if (fkFile2Process) delete arr;
+  return refs[kNStor];
+}
+
+//___________________________________________________________________
+Int_t AliLHCData::FillBunchInfo(int refs[2],const char* rec, int ibm, Bool_t inRealSlots, Double_t maxAbsVal)
+{
+  // fill bunch properties for beam ibm
+  // if inRealSlots = true, then the value is taken from bunchRFbucket/10, otherwise, the value 
+  // for the i-th bunch is taken from the i-th element
+  //
+  AliInfo(Form("Acquiring record: %s",rec));
+  TObjArray *arr;
+  Int_t iLast,iFirst;
+  //
+  refs[kStart] = fData.GetEntriesFast();
+  refs[kNStor] = 0;
+  //
+  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
+  //
+  while (iFirst<=iLast) {
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
+    double tstamp = dcsVal->GetTimeStamp();
+    //
+    AliLHCDipValI *bconf = GetBunchConfigMeasured(ibm,tstamp);
+    if (!bconf) {
+      AliWarning(Form("Mearured bunch configuration for beam %d at t=%.1f is not available, trying declared one",ibm+1,tstamp));
+      bconf = GetBunchConfigDeclared(ibm,tstamp);
+    }
+    if (!bconf) {
+      AliWarning(Form("Declared bunch configuration for beam %d at t=%.1f is not available, skip this record",ibm+1,tstamp));
+      return -1;
+    }
+    int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)
+    int nbunch = bconf->GetSize();
+    if (nbunch>nSlots) {
+      AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));
+      continue;
+    }
+    double* dcsArr = dcsVal->GetDouble();
+    AliLHCDipValF* curValD = new AliLHCDipValF(nbunch,tstamp);
+    for (int i=nbunch;i--;) {
+      int ind = inRealSlots ? (*bconf)[i]/10 : i;
+      if (ind>nSlots) {
+       AliError(Form("Bunch %d refers to wrong slot %d, set to -1",i,(*bconf)[i]));
+       (*curValD)[i] = -1;
+      }
+      else {
+       double vcheck = dcsArr[ind];
+       if (TMath::Abs(vcheck) > maxAbsVal) {
+         AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",vcheck, ind, rec, maxAbsVal));
+         vcheck = 0.;
+       }
+       (*curValD)[i] = vcheck;
+      }
+    }
+    fData.Add(curValD);
+    refs[kNStor]++;
+  }
+  if (fkFile2Process) delete arr;
+  return refs[kNStor];
+  //
+}
+//___________________________________________________________________
+Int_t AliLHCData::FillBCLuminosities(int refs[2],const char* rec, const char* recErr, int useBeam, Double_t maxAbsVal)
+{
+  // fill luminosities per bunch crossing
+  //
+  AliInfo(Form("Acquiring record: %s",rec));
+  TObjArray *arr,*arrE=0;
+  Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;
+  //
+  refs[kStart] = fData.GetEntriesFast();
+  refs[kNStor] = 0;
+  //
+  if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
+  //
+  while (iFirst<=iLast) {
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
+    double tstamp = dcsVal->GetTimeStamp();
+    //
+    AliLHCDipValI *bconf;
+    bconf = GetBunchConfigMeasured(useBeam,tstamp);  // luminosities are stored according to beam bunches
+    if (!bconf) {
+      AliWarning(Form("Mearured bunch configuration for beam%d at t=%.1f is not available, trying declared one",useBeam,tstamp));
+      bconf = GetBunchConfigDeclared(useBeam,tstamp);
+    }
+    if (!bconf) {
+      AliWarning(Form("Declared bunch configuration for beam%i at t=%.1f is not available, skip this record",useBeam,tstamp));
+      return -1;
+    }
+    int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)
+    int nbunch = bconf->GetSize();
+    double* dcsArr = dcsVal->GetDouble();
+    //
+    if (nbunch>nSlots) {
+      AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));
+      continue;
+    }
+    int dim = 0;
+    if (!bconf->IsProcessed1()) {
+      AliWarning(Form("Bunch conf. for beam%d has no marked interacting bunches, store all luminosity for all filled bunches",useBeam));
+      dim = nbunch;
+    }
+    else { // count number of interacting bunches
+      for (int i=nbunch;i--;) if ((*bconf)[i]<0) dim++;
+    }
+    //
+    if (recErr) {
+      arrE=GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);
+      dim += 1;
+    }
+    AliLHCDipValF* curValD = new AliLHCDipValF(dim,tstamp);
+    int cnt = 0;
+    for (int i=0;i<nbunch;i++) {
+      int slot = (*bconf)[i];
+      if (bconf->IsProcessed1() && slot>0) continue;
+      //
+      int ind = TMath::Abs(slot)/10;
+      if (ind>nSlots) {
+       AliError(Form("Bunch %d refers to wrong slot %d, set to -1",cnt,slot));
+       (*curValD)[cnt] = -1;
+      }
+      else {
+       double vcheck = dcsArr[ind];
+       if (TMath::Abs(vcheck) > maxAbsVal) {
+         AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",vcheck, ind, rec, maxAbsVal));
+         vcheck = 0.;
+       }
+       (*curValD)[i] = vcheck;
+      }
+      cnt++;
+    }
+    //
+    if (recErr) {
+      double errVal = -1;
+      while (iFirstE<=iLastE) {       // try to find corresponding error
+       AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);
+       double tstamp1 = dcsValE->GetTimeStamp();
+       int tdif = TimeDifference(tstamp,tstamp1);
+       if (!tdif) { // error matches to value
+         errVal = dcsValE->GetDouble()[0];
+         if (TMath::Abs(errVal) > maxAbsVal) {
+           AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",errVal,0, rec, maxAbsVal));
+           errVal = 0.;
+         }       
+         iFirstE++; 
+         break;
+       }
+       else if (tdif>0) iFirstE++; // error time lags behind, read the next one
+       else break;                 // error time is ahead of value, no error associated
+      }
+      (*curValD)[dim-1] = errVal;   // error
+      curValD->SetLastSpecial();    // lable the last entry as an error
+    }
+    //
+    fData.Add(curValD);
+    refs[kNStor]++;
+  }
+  if (fkFile2Process) {
+    delete arr;
+    delete arrE;
+  }
+  return refs[kNStor];
+  //
+}
+
+//___________________________________________________________________
+Int_t AliLHCData::ExtractInt(AliDCSArray* dcsArray,Int_t el) const
+{
+  // extract integer from the dcsArray
+  int val = -1;
+  //
+  int sz = dcsArray->GetNEntries();
+  if (sz<=el) return val;
+  //
+  if (dcsArray->GetType()==AliDCSArray::kInt)  val = dcsArray->GetInt(el);
+  else if (dcsArray->GetType()==AliDCSArray::kString) {
+    TObjString *stro = dcsArray->GetStringArray(el);
+    if (stro) val = stro->GetString().Atoi();
+    else AliError(Form("DCSArray TObjString for element %d is missing",el));
+  }
+  else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);
+  else AliError(Form("Integer requested from DCSArray of type %d",dcsArray->GetType()));
+  return val;
+}
+
+//___________________________________________________________________
+Double_t AliLHCData::ExtractDouble(AliDCSArray* dcsArray,Int_t el) const
+{
+  // extract double from the dcsArray
+  double val = 0;
+  //
+  int sz = dcsArray->GetNEntries();
+  if (sz<=el) return val;
+  //
+  if      (dcsArray->GetType()==AliDCSArray::kDouble) val = dcsArray->GetDouble(el);
+  else if (dcsArray->GetType()==AliDCSArray::kFloat)  val = dcsArray->GetFloat(el);
+  else if (dcsArray->GetType()==AliDCSArray::kString) {
+    TObjString *stro = dcsArray->GetStringArray(el);
+    if (stro) val = stro->GetString().Atof();
+    else AliError(Form("DCSArray has TObjString for element %d is missing",el));
+  }
+  else if (dcsArray->GetType()==AliDCSArray::kChar)   val = dcsArray->GetChar(el);
+  else if (dcsArray->GetType()==AliDCSArray::kInt)    val = dcsArray->GetInt(el);
+  else if (dcsArray->GetType()==AliDCSArray::kUInt)   val = dcsArray->GetUInt(el);
+  else     AliError(Form("Double requested from DCSArray of type %d",dcsArray->GetType()));
+  return val;
+}
+
+//___________________________________________________________________
+TString& AliLHCData::ExtractString(AliDCSArray* dcsArray) const
+{
+  // extract string from the dcsArray
+  static TString str;
+  str = "";
+  //
+  int sz = dcsArray->GetNEntries();
+  if (dcsArray->GetType()!=AliDCSArray::kString)  {
+    AliError(Form("String requested from DCSArray of type %d",dcsArray->GetType()));
+    return str;
+  }
+  //
+  for (int i=0;i<sz;i++) {
+    str += dcsArray->GetStringArray(i)->GetString();
+    if (i<sz-1) str += " ";
+  }
+  return str;
+}
+
+//___________________________________________________________________
+void AliLHCData::Print(const Option_t* opt) const
+{
+  // print full info
+  TString opts = opt;
+  opts.ToLower();
+  Bool_t utcTime = opts.Contains("loc") ? kFALSE:kTRUE;
+  //
+  Bool_t includeMissing = opts.Contains("m");
+  if (!includeMissing) printf("Missing records are skept, use Print(\"m\") to print missing record names\n");
+  else                 printf("Missing records are printed, remove \"m\" from Print options to skip them\n");
+  Bool_t full = kTRUE;
+  if (!opts.Contains("f")) {
+    printf("Use Print(\"f\") to print full info\n");
+    printf("Printing short info:\n<RecordType>(number of records): <TimeStamp, value> for 1st record only\n");
+    full = kFALSE;
+  }
+  TString sdtmn = AliLHCDipValI::TimeAsString(fTMin,utcTime);
+  TString sdtmx = AliLHCDipValI::TimeAsString(fTMax,utcTime);
+  printf("Fill#%6d Validity: %s - %s (%s)\n",fFillNumber,sdtmn.Data(),sdtmx.Data(),utcTime ? "UTC":"LOC");
+  //
+  printf("********** SETTINGS FROM RUN CONTROL **********\n");
+  //
+  if (fRCInjScheme[kNStor] || includeMissing) {
+    printf("* %-38s","Injection Scheme");
+    PrintAux(full,fRCInjScheme,opts);
+  }
+  //
+  if (fRCBeta[kNStor] || includeMissing) {
+    printf("* %-38s","Beta Star");
+    PrintAux(full,fRCBeta,opts);
+  }
+  //
+  if (fRCAngH[kNStor] || includeMissing) {
+    printf("* %-38s","Horisontal Crossing Angle");
+    PrintAux(full,fRCAngH,opts);
+  }
+  //
+  if (fRCAngV[kNStor] || includeMissing) {
+    printf("* %-38s","Vertical   Crossing Angle");
+    PrintAux(full,fRCAngV,opts);
+  }
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fBunchConfDecl[ib][kNStor] || includeMissing) {
+      printf("* Beam%d filling  [- interacts at IR2!]  ",ib+1);
+      PrintAux(full,fBunchConfDecl[ib],opts);
+    }
+  }
+  //
+  printf("\n**********       MEASURED DATA       **********\n");
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fBunchConfMeas[ib][kNStor] || includeMissing) {
+      printf("* Beam%d filling  [- interacts at IR2!]  ",ib+1);
+      PrintAux(full,fBunchConfMeas[ib],opts);
+    }
+  } 
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fIntensTotal[ib][kNStor] || includeMissing) {
+      printf("* Beam%d total intensity                 ",ib+1);
+      PrintAux(full,fIntensTotal[ib],opts);
+    }
+  } 
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fIntensTotalAv[ib][kNStor] || includeMissing) {
+      printf("* Beam%d total intensity (bunch average) ",ib+1);
+      PrintAux(full,fIntensTotalAv[ib],opts);
+    }
+  } 
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fIntensPerBunch[ib][kNStor] || includeMissing) {
+      printf("* Beam%d intensity per bunch             ",ib+1);
+      PrintAux(full,fIntensPerBunch[ib],opts);
+    }
+  }
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fBunchLengths[ib][kNStor] || includeMissing) {
+      printf("* Beam%d bunch lengths                   ",ib+1);
+      PrintAux(full,fBunchLengths[ib],opts);
+    }
+  } 
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fEmittanceH[ib][kNStor] || includeMissing) {
+      printf("* Beam%d Horisontal emittance            ",ib+1);
+      PrintAux(full,fEmittanceH[ib],opts);
+    }
+  }
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fEmittanceV[ib][kNStor] || includeMissing) {
+      printf("* Beam%d Vertical emittance              ",ib+1);
+      PrintAux(full,fEmittanceV[ib],opts);
+    }
+  }
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fBeamSigmaH[ib][kNStor] || includeMissing) {
+      printf("* Beam%d Horisontal sigma                ",ib+1);
+      PrintAux(full,fBeamSigmaH[ib],opts);
+    }
+  }
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fBeamSigmaV[ib][kNStor] || includeMissing) {
+      printf("* Beam%d Vertical sigma                  ",ib+1);
+      PrintAux(full,fBeamSigmaV[ib],opts);
+    }
+  }
+  //
+  for (int lr=0;lr<2;lr++) {
+    if (fLuminTotal[lr][kNStor] || includeMissing) {
+      printf("* Total luminosity from BRANB_4%c2       ",lr ? 'R':'L');
+      PrintAux(full,fLuminTotal[lr],opts);
+    }
+  } 
+  //
+  for (int lr=0;lr<2;lr++) {
+    if (fLuminAcqMode[lr][kNStor] || includeMissing) {
+      printf("* Luminosity acq.mode, BRANB_4%c2        ",lr ? 'R':'L');
+      PrintAux(full,fLuminAcqMode[lr],opts+"bit");
+    }
+  } 
+  //
+  for (int lr=0;lr<2;lr++) {
+    if (fLuminPerBC[lr][kNStor] || includeMissing) {
+      printf("* Luminosity per BC from BRANB_4%c2      ",lr ? 'R':'L');
+      PrintAux(full,fLuminPerBC[lr],opts);
+    }
+  }
+  //
+  for (int lr=0;lr<2;lr++) {
+    if (fCrossAngle[lr][kNStor] || includeMissing) {
+      printf("* Crossing angle, side %c                ",lr ? 'R':'L');
+      PrintAux(full,fCrossAngle[lr],opts);
+    }
+  }
+  //
+  for (int coll=0;coll<kNCollimators;coll++)
+    for (int jaw=0;jaw<kNJaws;jaw++) {
+      if (fCollimators[coll][jaw][kNStor] || includeMissing) {
+       printf("* Collimator %10s:%16s",fgkDCSColNames[coll],fgkDCSColJaws[jaw]);
+       PrintAux(full,fCollimators[coll][jaw],opts);
+      }
+    }
+  //
+  printf("\n**********    ALICE MEASURED DATA    **********\n");
+  //
+  if (fLumiAlice[kNStor] || includeMissing) {
+    printf("* %-38s","Alice luminosity total");
+    PrintAux(full,fLumiAlice,opts);
+  }
+  //
+  if (fLumiAliceStB[kNStor] || includeMissing) {
+    printf("* %-38s","Alice luminosity delivered stable beam");
+    PrintAux(full,fLumiAliceStB,opts);
+  }
+  //
+  if (fLumiAliceBbB[kNStor] || includeMissing) {
+    printf("* %-38s","Alice luminosity B-by-B, stable beam");
+    PrintAux(full,fLumiAliceBbB,opts);
+  }
+  //
+  for (int ib=0;ib<3;ib++) {
+    if (fBckgAlice[ib][kNStor] || includeMissing) {
+      printf("* Alice background%d                     ",ib+1);
+      PrintAux(full,fBckgAlice[ib],opts);
+    }
+  }
+  //
+  if (fBPTXdTB1B2[kNStor] || includeMissing) {
+    printf("* %-38s","BPTX DeltaT Beam1 Beam2");
+    PrintAux(full,fBPTXdTB1B2,opts);
+  }
+  //
+  if (fBPTXdTRMSB1B2[kNStor] || includeMissing) {
+    printf("* %-38s","BPTX DeltaT RMS Beam1 Beam2");
+    PrintAux(full,fBPTXdTRMSB1B2,opts);
+  }
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fBPTXPhase[ib][kNStor] || includeMissing) {
+      printf("* BPTX Phase Beam%d                      ",ib+1);
+      PrintAux(full,fBPTXPhase[ib],opts);
+    }
+  }
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fBPTXPhaseRMS[ib][kNStor] || includeMissing) {
+      printf("* BPTX Phase RMS Beam%d                  ",ib+1);
+      PrintAux(full,fBPTXPhaseRMS[ib],opts);
+    }
+  }
+  //
+  for (int ib=0;ib<2;ib++) {
+    if (fBPTXPhaseShift[ib][kNStor] || includeMissing) {
+      printf("* BPTX Phase Shift Beam%d                ",ib+1);
+      PrintAux(full,fBPTXPhaseShift[ib],opts);
+    }
+  }
+  //
+}
+
+//___________________________________________________________________
+void AliLHCData::PrintAux(Bool_t full, const Int_t refs[2], const Option_t *opt) const
+{
+  // aux method to print the reocrds of the same type
+  int nrec = refs[kNStor];
+  if (nrec<1) {
+    printf(": N/A\n"); 
+    return;
+  }
+  printf(": (%3d):\t",nrec); // number of records
+  if (!full) nrec = 1;
+  int sz = ((AliLHCDipValI*)fData[refs[kStart]])->GetSizeTotal(); // dimension of the record
+  Bool_t isStr = ((AliLHCDipValI*)fData[refs[kStart]])->IsTypeC();
+  if ((!isStr && sz>2) || nrec>1) printf("\n"); // long record, open new line
+  for (int i=0;i<nrec;i++) fData[refs[kStart]+i]->Print(opt);
+  //
+}
+
+//___________________________________________________________________
+void AliLHCData::Clear(const Option_t *)
+{
+  // clear all info
+  fData.Delete();
+  fFillNumber = 0;
+  fTMin = 0;
+  fTMax = 1e10;
+  fkFile2Process = 0;
+  fkMap2Process  = 0;
+  //
+  for (int i=2;i--;) {
+    fRCInjScheme[i] = 0;
+    fRCBeta[i] = 0;
+    fRCAngH[i] = 0;
+    fRCAngV[i] = 0;
+    fLumiAlice[i] = 0;
+    fLumiAliceStB[i] = 0;
+    fLumiAliceBbB[i] = 0;
+    for (int ibg=kNBGs;ibg--;) fBckgAlice[ibg][i] = 0;
+    fBPTXdTB1B2[i] = 0;
+    fBPTXdTRMSB1B2[i] = 0;
+    //
+    for (int icl=kNCollimators;icl--;) for (int jaw=kNJaws;jaw--;) fCollimators[icl][jaw][i]=0;
+    //
+    for (int j=2;j--;) {
+      fBPTXPhase[j][i] = 0;
+      fBPTXPhaseRMS[j][i] = 0;
+      fBPTXPhaseShift[j][i] = 0;
+      //
+      fBunchConfDecl[j][i] = 0;
+      fBunchConfMeas[j][i] = 0;
+      fBunchLengths[j][i] = 0;
+      fIntensTotal[j][i] = 0;
+      fIntensTotalAv[j][i] = 0;
+      fIntensPerBunch[j][i] = 0;      
+      fCrossAngle[j][i] = 0;
+      fEmittanceH[j][i] = 0;
+      fEmittanceV[j][i] = 0;
+      fBeamSigmaH[j][i] = 0;
+      fBeamSigmaV[j][i] = 0;
+      fLuminTotal[j][i] = 0;
+      fLuminPerBC[j][i] = 0;
+      fLuminAcqMode[j][i] = 0;
+    }
+  }
+}
+
+//___________________________________________________________________
+Int_t AliLHCData::GetNInteractingBunchesMeasured(int i) const
+{
+  // get number of interacting bunches at IR2
+  AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);
+  if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}
+  if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1;}
+  int n = 0;
+  for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;
+  return n;
+}
+
+//___________________________________________________________________
+Int_t AliLHCData::GetNInteractingBunchesDeclared(int i) const
+{
+  // get number of interacting bunches at IR2
+  AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);
+  if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}
+  if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1; }
+  int n = 0;
+  for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;
+  return n;
+}
+
+//___________________________________________________________________
+Int_t AliLHCData::IsPilotPresent(int i) const
+{
+  // check in the filling scheme is the pilot bunch is present
+  AliLHCDipValC* rec = GetInjectionScheme();
+  if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}
+  TString scheme = rec->GetValues();
+  return scheme.Contains("wp",TString::kIgnoreCase);
+}
+
+//___________________________________________________________________
+void AliLHCData::FlagInteractingBunches(const Int_t beam1[2],const Int_t beam2[2])
+{
+  // assign - sign to interacting bunches
+  //
+  for (int ib1=0;ib1<beam1[kNStor];ib1++) {
+    AliLHCDipValI *bm1 = (AliLHCDipValI*)fData[ beam1[kStart] + ib1];
+    if (!bm1) continue;
+    AliLHCDipValI *bm2 = (AliLHCDipValI*)FindRecValidFor(beam2[kStart],beam2[kNStor], bm1->GetTimeStamp());
+    if (!bm2) continue;
+    //
+    int nb1 = bm1->GetSize();
+    int nb2 = bm2->GetSize();
+    int i1,i2;
+    for (i1=0;i1<nb1;i1++) {
+      int bunch2=-1, bunch1 = TMath::Abs((*bm1)[i1]);
+      int slot2 =-1, slot1  = GetBCId(bunch1,0);
+      for (i2=0;i2<nb2;i2++) {
+       bunch2 = TMath::Abs((*bm2)[i2]);
+       slot2 = GetBCId(bunch2,1);
+       if (slot1==slot2) break;
+      }
+      if (slot1!=slot2) continue;
+      (*bm1)[i1] = -bunch1;
+      (*bm2)[i2] = -bunch2;
+      bm1->SetProcessed1();
+      bm2->SetProcessed1();
+    }
+  }
+}
+
+//___________________________________________________________________
+Int_t AliLHCData::GetMeanIntensity(int beamID, Double_t &colliding, Double_t &noncolliding, const TObjArray* bcmasks) const
+{
+  // get average intensity for all, colliding and non-colliding bunches
+  // on success returns number of intensity records used (1 per ~10 min)
+  // If triggered BC masks are provided, calculation is done for Triggered BC only
+  colliding = noncolliding = -1.;
+  if (beamID<0||beamID>1) {
+    AliError(Form("BeamID must be either 0 or 1, %d requested",beamID));
+    return -10;
+  }
+  //
+  AliTriggerBCMask *bcMaskBoth=0,*bcMaskSingle=0;
+  int nbcm = 0;
+  if (bcmasks && (nbcm=bcmasks->GetEntries())) {
+    if (nbcm>1) bcMaskBoth = (AliTriggerBCMask*)bcmasks->At(1);
+    if      (nbcm>0 && beamID==kBeam1) bcMaskSingle = (AliTriggerBCMask*)bcmasks->At(0);
+    else if (nbcm>2 && beamID==kBeam2) bcMaskSingle = (AliTriggerBCMask*)bcmasks->At(2);
+    //
+    if (!bcMaskSingle) AliError(Form("Only triggered BSs are requested but %c mask is not provided",beamID ? 'C':'A'));
+    if (!bcMaskBoth)   AliError("Only triggered BSs are requested but B mask is not provided");
+  }
+  else {
+    AliWarning("No BC masks are provided");
+  }
+  //
+  int nrec = GetNIntensityPerBunch(beamID);
+  if (nrec<1) return -1;
+  AliLHCDipValI *conf = GetBunchConfigMeasured(beamID);
+  if (!conf) conf = GetBunchConfigDeclared(beamID);
+  if (!conf) return -2;
+  int nb = conf->GetSize();
+  //
+  for (int irec=0;irec<nrec;irec++) {
+    //
+    AliLHCDipValD* rIntD = 0;
+    AliLHCDipValF* rIntF = GetIntensityPerBunch(beamID,irec);
+    // for BWD compatibility of some periods
+    if (rIntF->IsA() == AliLHCDipValD::Class()) {rIntD=(AliLHCDipValD*)rIntF; rIntF=0;}
+    if (!rIntF && !rIntD) {
+      AliError(Form("Failed to get GetIntensityPerBunch(%d,%d)",beamID,irec));
+      continue;
+    }
+    for (int ib=0;ib<nb;ib++) {
+      double val = 0;
+      if (rIntF) val = rIntF->GetValue(ib);
+      else if (rIntD) val = rIntD->GetValue(ib);
+      if (val<0) continue;
+      int bID = conf->GetValue(ib);
+      // check if this is a triggered bunch
+      int bcID = GetBCId(bID, beamID);
+      if (bID<0) { // interacting
+       if (bcMaskBoth && bcMaskBoth->GetMask(bcID)) continue; // masked
+       colliding += val;
+      }
+      else {
+       if (bcMaskSingle && bcMaskSingle->GetMask(bcID)) continue; // masked    
+       noncolliding += val;
+      }
+    }
+  }
+  colliding /= nrec;
+  noncolliding /= nrec;
+  return nrec;
+}
+
+/***************************************************************************************
+// this is for the obsolete retrofitting
+
+//___________________________________________________________________
+void AliLHCData::FillLumiAliceOFL(Int_t nrec, Int_t* timeArr, Double_t* valArr)
+{
+  // Create a record for lumi integrated from the beginning of fill
+  // We need dedicated method since this info comes from Alice (not LHCDip) as instantaneous values
+  // and is retrofitted for past runs
+  fLumiAlice[kStart] = fData.GetEntriesFast();
+  fLumiAlice[kNStor] = 0;
+  if (nrec<2 || !timeArr || !valArr) return;
+  double tprv,period,currTime;
+  if ((currTime=double(UInt_t(timeArr[0])))>fTMin) {
+    AliError(Form("TimeStamp of 1st record: %s > TimeStamp of SOR: %s, STOP",
+                 AliLHCDipValI::TimeAsString(currTime),AliLHCDipValI::TimeAsString(fTMin)));
+    return;
+  }
+  //
+  if ((tprv=double(UInt_t(timeArr[nrec-1])))<fTMax) {
+    AliWarning(Form("TimeStamp of last (%d) record: %s < TimeStamp of EOR: %s, Data will be truncated",nrec-1,
+                   AliLHCDipValI::TimeAsString(tprv),AliLHCDipValI::TimeAsString(fTMax)));
+  }
+  //
+  // init the average time step
+  period = (tprv - currTime)/(nrec-1);
+  double lumiInt  = 0;
+  //
+  for (int i=0;i<nrec;i++) {
+    tprv = currTime;
+    currTime = double(UInt_t(timeArr[i]));
+    if (i>0) period = currTime - tprv;
+    if (currTime-period>fTMax) continue;    
+    lumiInt += valArr[i]*period;    
+    //    printf("%d %.2f V:%f Int:%f\n",i,period,valArr[i],lumiInt);
+    if (currTime+period<fTMin) continue;
+    AliLHCDipValF* curValF = new AliLHCDipValF(1,currTime);
+    (*curValF)[0] = lumiInt;
+    fData.Add(curValF);
+    fLumiAlice[kNStor]++;
+  }
+  //
+  printf("Stored %d Alice Integrated luminosity records out of %d provided\n",fLumiAlice[kNStor],nrec);
+}
+
+//___________________________________________________________________
+void AliLHCData::FillBckgAliceOFL(Int_t nrec, Int_t* timeArr, Double_t* valArr)
+{
+  // Create a record for lumi integrated from the beginning of fill
+  // We need dedicated method since this info comes from Alice (not LHCDip) as instantaneous values
+  // and is retrofitted for past runs
+  fBckgAlice[kStart] = fData.GetEntriesFast();
+  fBckgAlice[kNStor] = 0;
+  if (nrec<2 || !timeArr || !valArr) return;
+  double tprv,period,currTime;
+  if ((currTime=double(UInt_t(timeArr[0])))>fTMin) {
+    AliError(Form("TimeStamp of 1st record: %s > TimeStamp of SOR: %s, STOP",
+                 AliLHCDipValI::TimeAsString(currTime),AliLHCDipValI::TimeAsString(fTMin)));
+    return;
+  }
+  //
+  if ((tprv=double(UInt_t(timeArr[nrec-1])))<fTMax) {
+    AliWarning(Form("TimeStamp of last (%d) record: %s < TimeStamp of EOR: %s, Data will be truncated",nrec-1,
+                   AliLHCDipValI::TimeAsString(tprv),AliLHCDipValI::TimeAsString(fTMax)));
+  }
+  //
+  // init the average time step
+  period = (tprv - currTime)/(nrec-1);
+  double bckgInt  = 0;
+  //
+  for (int i=0;i<nrec;i++) {
+    tprv = currTime;
+    currTime = double(UInt_t(timeArr[i]));
+    if (i>0) period = currTime - tprv;
+    if (currTime-period>fTMax) continue;    
+    bckgInt += valArr[i]*period;    
+    if (currTime+period<fTMin) continue;
+    AliLHCDipValF* curValF = new AliLHCDipValF(1,currTime);
+    (*curValF)[0] = bckgInt;
+    fData.Add(curValF);
+    fBckgAlice[kNStor]++;
+  }
+  //
+  printf("Stored %d Alice Integrated Background records out of %d provided\n",fBckgAlice[kNStor],nrec);
+}
+
+***************************************************************************************/
+
+/*
+//_____________________________________________________________________________
+Float_t AliLHCData::GetLumiInstAlice(Double_t tStamp) const 
+{
+  // get closest in time value on inst luminosity
+  int idx = FindEntryValidFor(fLumiAlice[kStart],fLumiAlice[kNStor],tStamp);
+  if (idx<0) return -1;
+  AliLHCDipValF *rec=GetLumiAlice(idx),*rec1=GetLumiAlice(idx>0 ? idx-1:idx+1);
+  if (!rec || !rec1) return -1;
+  double dt = rec->GetTimeStamp() - rec1->GetTimeStamp();
+  return TMath::Abs(dt)>1e-6 ? (rec->GetValue()-rec1->GetValue())/dt : -1;
+}
+
+//_____________________________________________________________________________
+Float_t AliLHCData::GetBckgInstAlice(Double_t tStamp) const 
+{
+  // get closest in time value on inst luminosity
+  int idx = FindEntryValidFor(fBckgAlice[kStart],fBckgAlice[kNStor],tStamp);
+  if (idx<0) return -1;
+  AliLHCDipValF *rec=GetBckgAliceRecord(idx),*rec1=GetBckgAliceRecord(idx>0 ? idx-1:idx+1);
+  if (!rec || !rec1) return -1;
+  double dt = rec->GetTimeStamp() - rec1->GetTimeStamp();
+  return TMath::Abs(dt)>1e-6 ? (rec->GetValue()-rec1->GetValue())/dt : -1;
+}
+*/
+
+//_____________________________________________________________________________
+TGraph* AliLHCData::ExportGraph(Int_t *coord, Int_t elID) const
+{
+  // export time/values to graph:
+  // coord: int[2] array with 1st entry and number of entries stored, obtained via GetOffs... method 
+  // elID - element of the AliLHCDipValT array to extract
+  if (!coord || coord[1]<1) return 0;
+  TGraph* gr = new TGraph(coord[1]);
+  for (int i=0;i<coord[1];i++) {
+    TObject* obj = fData.At(coord[0]+i);
+    if (!obj) {
+      AliError(Form("Entry %d does not exist",i));
+      continue;
+    }
+    if (obj->IsA()==AliLHCDipValD::Class()) {
+      AliLHCDipValD* objD =  (AliLHCDipValD*)obj;
+      gr->SetPoint(i,objD->GetTimeStamp(),objD->GetValue(elID));
+    }
+    else if (obj->IsA()==AliLHCDipValF::Class()) {
+      AliLHCDipValF* objF =  (AliLHCDipValF*)obj;
+      gr->SetPoint(i,objF->GetTimeStamp(),objF->GetValue(elID));
+    }
+    else if (obj->IsA()==AliLHCDipValI::Class()) {
+      AliLHCDipValI* objI =  (AliLHCDipValI*)obj;
+      gr->SetPoint(i,objI->GetTimeStamp(),objI->GetValue(elID));
+    }
+    else if (obj->IsA()==AliLHCDipValC::Class()) {
+      AliLHCDipValC* objC =  (AliLHCDipValC*)obj;
+      gr->SetPoint(i,objC->GetTimeStamp(),objC->GetValue(elID));
+    }
+    else {
+      AliError(Form("Graph cannot be exported for records of type %s",obj->IsA()->GetName()));
+    }
+  }
+  return gr;
+}