]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
The class for LHC DIP data was completely changed
authorshahoian <shahoian@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 29 Mar 2010 12:56:35 +0000 (12:56 +0000)
committershahoian <shahoian@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 29 Mar 2010 12:56:35 +0000 (12:56 +0000)
STEER/AliLHCData.cxx
STEER/AliLHCData.h
STEER/AliLHCDipValT.h

index bf1967c352149f7495657649636efcf03f16014f..ba9d3d455bed2feac25d8864cebd45f98bbbd705 100755 (executable)
-/**************************************************************************
- * 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.                  *
- *                                                                        *
- **************************************************************************/
-
-
-#include "AliLHCData.h"
-#include "TMap.h"
-
-
-ClassImp(AliLHCData)
-
-const Char_t* AliLHCData::fgkDCSNames[] = {
-  "lhcMon_LHCIntensityBeam%d.totalIntensity",
-  "lhcInst_BeamIntensityPerBunchBeam%d.averageBeamIntensity",
-  "lhcInst_BeamIntensityPerBunchBeam%d_Avgerage.averageBunchIntensities",
-  "lhcMon_LHCLumAverageBRANB_4%c2.meanLuminosity",
-  "lhcInst_BeamLuminosityPerBunchBRANB_4%c2_Average.bunchByBunchLuminosity",
-  "lhcMon_LHCLumAverageBRANB_4%c2.meanCrossingAngle",
-  "lhcMon_LHCCirculatingBunchConfig_Beam%d.value",
-  "lhcMon_LHCFillNumber.payload",
-  //
-  "lhcMon_LHCBeamSizeBeam%d.planeSet%d",
-  "lhcMon_LHCBeamSizeBeam%d.amplitudeSet%d",
-  "lhcMon_LHCBeamSizeBeam%d.positionSet%d",
-  "lhcMon_LHCBeamSizeBeam%d.sigmaSet%d"
-};
-
-const Char_t* AliLHCData::fgkDCSColNames[] = {
-  "lhcMon_LHCCollimatorPos_TCTVB_4L2.%s",
-  "lhcMon_LHCCollimatorPos_TCTVB_4R2.%s",  
-  "lhcMon_LHCCollimatorPos_TCLIA_4R2.%s"
-};
-
-const Char_t* AliLHCData::fgkDCSColJaws[] = {
-  "lvdt_gap_downstream","lvdt_gap_upstream","lvdt_left_downstream",
-  "lvdt_left_upstream","lvdt_right_downstream","lvdt_right_upstream"};
-
-//___________________________________________________________________
-AliLHCData::AliLHCData(const TMap* dcsMap, double tmin, double tmax, int avPeriod)
-  : fPeriod(avPeriod),fTMin(tmin),fTMax(tmax)  
-{
-  FillData(dcsMap,tmin,tmax);
-}
-
-//___________________________________________________________________
-Bool_t AliLHCData::FillData(const TMap* dcsMap, double tmin, double tmax)
-{
-  // process DCS map and fill all fields. 
-  // Accept only entries with timestamp between tmin and tmax
-  const double ktReal = 1200000000.;
-  const double kCollTolerance = 100e-4; // tolerance on collimator move (cm)
-  char buff[100];
-  TObjArray* arr;
-  AliDCSArray* dcsVal;
-  Double_t tPeriodEnd=0;
-  Int_t dcsSize,nEntries,iEntry;
-  //
-  SetTMin(tmin);
-  SetTMax(tmax);
-  //
-  // -------------------------- extract Fill Number
-  arr = GetDCSEntry(dcsMap,fgkDCSNames[kRecFillNum],iEntry,tmin,tmax);
-  if (arr && iEntry>=0) SetFillNumber( ((AliDCSArray*)arr->At(iEntry))->GetInt(0) );
-  //
-  // -------------------------- extract total intensities for beam 1 and 2 (DC BCT: slow average)
-  for (int ibm=0;ibm<2;ibm++) {
-    //
-    sprintf(buff,fgkDCSNames[kRecTotInt],ibm+1);  
-    if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
-    AliLHCDipValD* curVal = 0;
-    tPeriodEnd = 0;
-    //
-    nEntries = arr->GetEntriesFast();
-    while (iEntry<nEntries) {
-      dcsVal = (AliDCSArray*) arr->At(iEntry++);
-      double tstamp = dcsVal->GetTimeStamp();
-      if (tstamp>tmax) break;
-      if (tstamp>tPeriodEnd) {
-       curVal = new AliLHCDipValD(1,0.,0);  // start new period
-       fIntTot[ibm].Add(curVal);
-       // if tmin is provided, count periods from it, otherwise from the 1st timestamp
-       if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
-       tPeriodEnd += fPeriod;
-      }
-      *curVal += *dcsVal;
-    }
-    for (int i=fIntTot[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntTot[ibm])[i])->Average();
-  }
-  //
-  // -------------------------- extract total intensities for beam 1 and 2 (BCTFR: fast average)
-  for (int ibm=0;ibm<2;ibm++) {
-    //
-    sprintf(buff,fgkDCSNames[kRecTotIntBunch],ibm+1);  
-    if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
-    AliLHCDipValD* curVal = 0;
-    tPeriodEnd = 0;
-    //
-    nEntries = arr->GetEntriesFast();
-    while (iEntry<nEntries) {
-      dcsVal = (AliDCSArray*) arr->At(iEntry++);
-      double tstamp = dcsVal->GetTimeStamp();
-      if (tstamp>tmax) break;
-      if (tstamp>tPeriodEnd) {
-       curVal = new AliLHCDipValD(1,0.,0);  // start new period
-       fIntTotBunch[ibm].Add(curVal);
-       // if tmin is provided, count periods from it, otherwise from the 1st timestamp
-       if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
-       tPeriodEnd += fPeriod;
-      }
-      *curVal += *dcsVal;
-    }
-    for (int i=fIntTotBunch[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntTotBunch[ibm])[i])->Average();
-  }
-  //  
-  // -------------------------- extract total luminosities according L and R detectors
-  for (int ilr=0;ilr<2;ilr++) {
-    //
-    sprintf(buff,fgkDCSNames[kRecTotLum],ilr ? 'L':'R');  
-    if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
-    AliLHCDipValD* curVal = 0;
-    tPeriodEnd = 0;
-    //
-    nEntries = arr->GetEntriesFast();
-    while (iEntry<nEntries) {
-      dcsVal = (AliDCSArray*) arr->At(iEntry++);
-      double tstamp = dcsVal->GetTimeStamp();
-      if (tstamp>tmax) break;
-      if (tstamp>tPeriodEnd) {
-       curVal = new AliLHCDipValD(1,0.,0);  // start new period
-       fLuminTot[ilr].Add(curVal);
-       // if tmin is provided, count periods from it, otherwise from the 1st timestamp
-       if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
-       tPeriodEnd += fPeriod;
-      }
-      *curVal += *dcsVal;
-    }
-    for (int i=fLuminTot[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fLuminTot[ilr])[i])->Average();
-  }
-  //
-  // -------------------------- extract mean crossing angles according to L and R detectors
-  for (int ilr=0;ilr<2;ilr++) {
-    //
-    sprintf(buff,fgkDCSNames[kRecCrossAngle],ilr ? 'L':'R');  
-    if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
-    AliLHCDipValD* curVal = 0;
-    tPeriodEnd = 0;
-    //
-    nEntries = arr->GetEntriesFast();
-    while (iEntry<nEntries) {
-      dcsVal = (AliDCSArray*) arr->At(iEntry++);
-      double tstamp = dcsVal->GetTimeStamp();
-      if (tstamp>tmax) break;
-      if (tstamp>tPeriodEnd) {
-       curVal = new AliLHCDipValD(1,0.,0);  // start new period
-       fCrossAngle[ilr].Add(curVal);
-       // if tmin is provided, count periods from it, otherwise from the 1st timestamp
-       if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
-       tPeriodEnd += fPeriod;
-      }
-      *curVal += *dcsVal;
-    }
-    for (int i=fCrossAngle[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fCrossAngle[ilr])[i])->Average();
-  }
-  //
-  //
-  // ------------------------- extract bunch configuration for beam 1 and 2
-  int nbunch[2];
-  for (int ibm=0;ibm<2;ibm++) {
-    //
-    nbunch[ibm] = -1;
-    sprintf(buff,fgkDCSNames[kRecBunchConf],ibm+1);  
-    if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
-    dcsVal = (AliDCSArray*) arr->At(iEntry);
-    nEntries = dcsVal->GetNEntries();     // count number of actual bunches
-    nbunch[ibm] = 0;
-    while(nbunch[ibm]<nEntries && dcsVal->GetInt(nbunch[ibm])) nbunch[ibm]++;
-    if (!nbunch[ibm]) {
-      AliWarning(Form("Beam%d bunches configuration record is present but empty",ibm+1));
-      continue;
-    }
-    fBunchConfig[ibm].SetSize(nbunch[ibm]);
-    fBunchConfig[ibm] += *dcsVal;
-  }
-  // -------------------------- extract intensities per bunch for beam 1 and 2
-  for (int ibm=0;ibm<2;ibm++) {
-    //
-    sprintf(buff,fgkDCSNames[kRecBunchInt],ibm+1);  
-    if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
-    AliLHCDipValD* curVal = 0;
-    tPeriodEnd = 0;
-    //
-    dcsVal = (AliDCSArray*)arr->At(iEntry);
-    nEntries = dcsVal->GetNEntries();     // count number of actual bunches
-    dcsSize = 0;
-    while(dcsSize<nEntries && dcsVal->GetDouble(dcsSize)>0) dcsSize++;
-    if (!dcsSize) {
-      AliWarning(Form("Beam%d bunch intensities record is present but empty",ibm+1));
-      continue;
-    }
-    if (nbunch[ibm]>0) { // bunch pattern was provided
-      if (dcsSize>nbunch[ibm]) {
-       AliWarning(Form("Beam%d declares %d bunches but %d bunch intensities are non-0. Take first %d",
-                       ibm+1,nbunch[ibm],dcsSize,nbunch[ibm]));
-       dcsSize = nbunch[ibm];
-      }
-      else if (dcsSize<nbunch[ibm]) {
-       AliWarning(Form("Beam%d declares %d bunches but %d bunch intensities are non-0. Skip",
-                       ibm+1,nbunch[ibm],dcsSize));
-       continue;
-      }
-    }
-    //
-    nEntries = arr->GetEntriesFast();
-    while (iEntry<nEntries) {
-      dcsVal = (AliDCSArray*) arr->At(iEntry++);
-      double tstamp = dcsVal->GetTimeStamp();
-      if (tstamp>tmax) break;
-      if (tstamp>tPeriodEnd) {
-       curVal = new AliLHCDipValD(dcsSize,0.,0);  // start new period
-       fIntBunch[ibm].Add(curVal);
-       // if tmin is provided, count periods from it, otherwise from the 1st timestamp
-       if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
-       tPeriodEnd += fPeriod;
-      }
-      *curVal += *dcsVal;
-    }
-    for (int i=fIntBunch[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntBunch[ibm])[i])->Average();
-  }
-  //
-  // -------------------------- extract per bunch luminosities according L and R detectors
-  for (int ilr=0;ilr<2;ilr++) {
-    //
-    sprintf(buff,fgkDCSNames[kRecBunchLum],ilr ? 'L':'R');  
-    if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
-    AliLHCDipValD* curVal = 0;
-    tPeriodEnd = 0;
-    //
-    dcsVal = (AliDCSArray*) arr->At(iEntry);
-    nEntries = dcsVal->GetNEntries();     // count number of actual bunches
-    dcsSize = 0;
-    while(dcsSize<nEntries && dcsVal->GetDouble(dcsSize)>0) dcsSize++;
-    if (!dcsSize) {
-      AliWarning(Form("Probe%c bunch luminosities record is present but empty",ilr ? 'R':'L'));
-      continue;
-    }
-    //
-    if (nbunch[ilr]>0) { // bunch pattern was provided
-      if (dcsSize>nbunch[ilr]) {
-       AliWarning(Form("Beam%d declares %d bunches but %d bunch luminosities are non-0. Take first %d",
-                       ilr+1,nbunch[ilr],dcsSize,nbunch[ilr]));
-       dcsSize = nbunch[ilr];
-      }
-      else if (dcsSize<nbunch[ilr]) {
-       AliWarning(Form("Beam%d declares %d bunches but %d bunch luminosities are non-0. Skip",
-                       ilr+1,nbunch[ilr],dcsSize));
-       continue;
-      }
-    }
-    //
-    nEntries = arr->GetEntriesFast();
-    while (iEntry<nEntries) {
-      dcsVal = (AliDCSArray*) arr->At(iEntry++);
-      double tstamp = dcsVal->GetTimeStamp();
-      if (tstamp>tmax) break;
-      if (tstamp>tPeriodEnd) {
-       curVal = new AliLHCDipValD(dcsSize,0.,0);  // start new period
-       fLuminBunch[ilr].Add(curVal);
-       // if tmin is provided, count periods from it, otherwise from the 1st timestamp
-       if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
-       tPeriodEnd += fPeriod;
-      }
-      *curVal += *dcsVal;
-    }
-    for (int i=fLuminBunch[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fLuminBunch[ilr])[i])->Average();
-  }
-  //
-  // ------------------------- extract gaussian fit params for beam 1 and 2 profiles
-  for (int ibm=0;ibm<2;ibm++) {
-    for (int ixy=0;ixy<2;ixy++) {
-      // determine which projection corresponds actually to given ixy
-      sprintf(buff,fgkDCSNames[kRecPrfPrID],ibm+1,ixy+1); 
-      if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,0/*tmin*/,tmax)) || iEntry<0 ) continue;
-      dcsVal = (AliDCSArray*) arr->At(iEntry);
-      int proj = dcsVal->GetInt(0)-1;          // beam projection
-      //
-      if (proj!=kX && proj!=kY) {
-       AliError(Form("Unknown beam projection %d for %s",proj,buff));
-       continue;
-      }
-      // Amp,Pos,Sig - each one have separate entry and time stamp (though come from the single fit)
-      int entPar[3];
-      TObjArray *arrPar[3];
-      AliDCSArray *dcsPar[3];
-      AliLHCDipValD* curVal = 0;
-      double tstamp = 0;
-      int npars = 0;
-      for (int ipar=0;ipar<3;ipar++) {
-       sprintf(buff,fgkDCSNames[ipar+kRecPrfAmp],ibm+1,ixy+1);
-       if ( !(arrPar[ipar]=GetDCSEntry(dcsMap,buff,entPar[ipar],tmin,tmax)) || entPar[ipar]<0 ) break;
-       dcsPar[ipar] = (AliDCSArray*) arrPar[ipar]->At(entPar[ipar]);   
-       if (dcsPar[ipar]->GetTimeStamp()>tstamp) tstamp = dcsPar[ipar]->GetTimeStamp(); // max time among 1st entries
-       npars++;
-      }
-      if (npars<3) continue; // ignore incomplete data
-      //
-      tPeriodEnd = 0;
-      // start recording from max timeStamp: 
-      // the entries for different params must correspond to same timestamp
-      while(1) { 
-       //
-       // read next timestamp for which all 3 params are present
-       npars = 0; // align the first entries to read to same timestamp
-       for (int ipar=0;ipar<3;ipar++) {
-         while(entPar[ipar]<arrPar[ipar]->GetEntriesFast()) {
-           dcsPar[ipar] = (AliDCSArray*) arrPar[ipar]->At(entPar[ipar]);
-           double df = dcsPar[ipar]->GetTimeStamp() - tstamp;
-           if (TMath::Abs(df)<0.5) { // same time stamp, ok
-             npars++; 
-             break;
-           }
-           if (df<0) entPar[ipar]++;  // check next entry
-           else {
-             tstamp = dcsPar[ipar]->GetTimeStamp();
-             ipar = -1; // reference tstamp was changed, check all arrays again
-             npars = 0;
-             break;
-           }
-         }
-       } // 
-       if (npars<3) break; // no more data
-       for (int ipar=0;ipar<3;ipar++) entPar[ipar]++;
-       //
-       if (tstamp>tmax) break;
-       if (tstamp>tPeriodEnd) {
-         curVal = new AliLHCDipValD(3,0.,0);  // start new period
-         fBeamPos[ibm][proj].Add(curVal);
-         // if tmin is provided, count periods from it, otherwise from the 1st timestamp
-         if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
-         tPeriodEnd += fPeriod;
-       }
-       int nsamp = curVal->GetNSamplesUsed()+1;
-       curVal->SetTimeStamp( (tstamp + curVal->GetNSamplesUsed()*curVal->GetTimeStamp())/nsamp);
-       curVal->SetNSamplesUsed(nsamp);
-       for (int ipar=3;ipar--;) (*curVal)[ipar] += dcsPar[ipar]->GetDouble(0);
-       //
-      }
-      //
-      for (int i=fBeamPos[ibm][proj].GetEntriesFast();i--;) ((AliLHCDipValD*)(fBeamPos[ibm][proj])[i])->Average();
-      //
-    } // projection
-  } // beam
-  //
-  // ------------------------- extract collimators data
-  for (int icl=0;icl<kNCollimators;icl++) {
-    for (int jaw=0;jaw<kNJaws;jaw++) {
-      sprintf(buff,fgkDCSColNames[icl],fgkDCSColJaws[jaw]);        
-      if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
-      dcsVal = (AliDCSArray*) arr->At(iEntry);       
-      AliLHCDipValD* curVal = new AliLHCDipValD(1,dcsVal->GetTimeStamp(),1);
-      (*curVal)[0] = dcsVal->GetDouble(0)/10;  // gap in cm
-      fCollimators[icl][jaw].Add(curVal);
-      //
-      // now track the changes above the threshold (100 um?)
-      nEntries = arr->GetEntriesFast();
-      while(++iEntry<nEntries) {
-       dcsVal = (AliDCSArray*) arr->At(iEntry);
-       if (dcsVal->GetTimeStamp() > tmax) break;  // out of time
-       double val = dcsVal->GetDouble(0)/10;
-       if ( TMath::Abs(val-curVal->GetValue(0))<kCollTolerance ) continue;  // no significant change
-       // need to create a new entry
-       curVal = new AliLHCDipValD(1,dcsVal->GetTimeStamp(),1);
-       (*curVal)[0] = val;  // gap in cm
-       fCollimators[icl][jaw].Add(curVal);     
-      }
-    } // jaws
-  } // collimators
-  //
-  return kTRUE;
-}
-
-//___________________________________________________________________
-TObjArray* AliLHCData::GetDCSEntry(const TMap* dcsMap,const char* key,int &entry,double tmin,double tmax) const
-{
-  // extract array from the DCS map and find the first entry within the time limits
-  TObjArray* arr = (TObjArray*)dcsMap->GetValue(key);
-  if (!arr || !arr->GetEntriesFast()) { 
-    AliWarning(Form("No data for %s",key)); 
-    return 0;
-  }
-  int ntot = arr->GetEntriesFast();
-  for (entry=0;entry<ntot;entry++) {
-    AliDCSArray* ent = (AliDCSArray*)arr->At(entry);
-    if (ent->GetTimeStamp()>=tmin && ent->GetTimeStamp()<=tmax) break;
-  }
-  if (entry==ntot) {
-    entry = -1;
-    TString str;
-    str += AliLHCDipValD::TimeAsString(tmin);
-    str += " : ";
-    str += AliLHCDipValD::TimeAsString(tmax);
-    AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));
-  }
-  return arr;
-}
-
-//___________________________________________________________________
-void AliLHCData::Print(const Option_t* opt) const
-{
-  // print everything
-  printf("LHC DIP Data | Fill Number#%d (Averaging time: %d sec.)\n",GetFillNumber(),fPeriod);
-  printf("Validity period: %s : %s\n\n",
-        fTMin<1.23e9 ? "N/A": AliLHCDipValD::TimeAsString(fTMin),
-        fTMax>7.00e9 ? "N/A": AliLHCDipValD::TimeAsString(fTMax) );
-  //
-  int n=0;
-  for (int ibm=0;ibm<2;ibm++) {
-    printf("*** Bunch Configuration for Beam%d: %s\n",ibm,(n=fBunchConfig[ibm].GetSize()) ? "":"N/A");
-    if (n) fBunchConfig[ibm].Print(opt);
-  }
-  printf("\n");
-  //
-  for (int ibm=0;ibm<2;ibm++) {
-    printf("*** Average total intensity for Beam%d (DCBCT): %s\n",ibm,(n=fIntTot[ibm].GetEntriesFast()) ? "":"N/A");
-    for (int i=0;i<n;i++) (fIntTot[ibm])[i]->Print(opt);
-  }
-  printf("\n");
-  //
-  for (int ibm=0;ibm<2;ibm++) {
-    printf("*** Total intensity for Beam%d (BCTFR): %s\n",ibm,(n=fIntTotBunch[ibm].GetEntriesFast()) ? "":"N/A");
-    for (int i=0;i<n;i++) (fIntTotBunch[ibm])[i]->Print(opt);
-  }
-  printf("\n");  //
-  for (int ibm=0;ibm<2;ibm++) {
-    printf("*** Bunch intensities for Beam%d: %s\n",ibm,(n=fIntBunch[ibm].GetEntriesFast()) ? "":"N/A");
-    for (int i=0;i<n;i++) (fIntBunch[ibm])[i]->Print(opt);
-  }
-  printf("\n");
-  //
-  for (int ibm=0;ibm<2;ibm++) {
-    printf("*** Total luminosity for probe%c: %s\n",ibm ? 'R':'L',(n=fLuminTot[ibm].GetEntriesFast()) ? "":"N/A");
-    for (int i=0;i<n;i++) (fLuminTot[ibm])[i]->Print(opt);
-  }
-  printf("\n");
-  //
-  for (int ibm=0;ibm<2;ibm++) {
-    printf("*** Bunch luminosities for probe%c: %s\n",ibm ? 'R':'L',(n=fLuminBunch[ibm].GetEntriesFast()) ? "":"N/A");
-    for (int i=0;i<n;i++) (fLuminBunch[ibm])[i]->Print(opt);
-  }
-  printf("\n");
-  //
-  for (int ibm=0;ibm<2;ibm++) {
-    printf("*** Crossing angle for probe%c: %s\n",ibm ? 'L':'R',(n=fCrossAngle[ibm].GetEntriesFast()) ? "":"N/A");
-    for (int i=0;i<n;i++) (fCrossAngle[ibm])[i]->Print(opt);
-  }
-  printf("\n");
-  //
-  for (int ibm=0;ibm<2;ibm++) {
-    for (int ixy=0;ixy<2;ixy++) {
-      printf("*** Gaussian fit for Beam%d %c profile: %s\n",ibm,ixy ? 'Y':'X',(n=fBeamPos[ibm][ixy].GetEntriesFast()) ? "":"N/A");
-      for (int i=0;i<n;i++) (fBeamPos[ibm][ixy])[i]->Print(opt);
-    }
-  }
-  //
-  for (int icl=0;icl<kNCollimators;icl++) {
-    printf("\n");
-    for (int ij=0;ij<kNJaws;ij++) {
-      printf(fgkDCSColNames[icl],fgkDCSColJaws[ij]);
-      printf(": %s\n",(n=fCollimators[icl][ij].GetEntriesFast()) ? "":"N/A");
-      for (int i=0;i<n;i++) (fCollimators[icl][ij])[i]->Print(opt);
-    }
-  }
-  //
-}
+/**************************************************************************\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 <TString.h>\r
+#include <TObjArray.h>\r
+\r
+ClassImp(AliLHCData)\r
+\r
+const Char_t* AliLHCData::fgkDCSNames[] = {\r
+  "LHC_IntensityBeam%d_totalIntensity",\r
+  "LHC_BeamIntensityPerBunchBeam%d_averageBeamIntensity",\r
+  "LHC_BeamIntensityPerBunchBeam%d_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%d_nBunches",\r
+  "LHC_BunchLengthBeam%d_bunchesLenghts",\r
+  "LHC_BunchLengthBeam%d_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%d_acqMode",\r
+  "LHC_BeamSizeBeam%d_sigmaH",\r
+  "LHC_BeamSizeBeam%d_sigmaV",\r
+  "LHC_BeamSizeBeam%d_emittanceH",\r
+  "LHC_BeamSizeBeam%d_emittanceV",\r
+  "LHC_BeamSizeBeam%d_errorSigmaH",\r
+  "LHC_BeamSizeBeam%d_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(tmin),fTMax(tmax),fFillNumber(0),fData(0)\r
+{\r
+  Clear();\r
+  SetTMin(tmin);\r
+  SetTMin(tmax);\r
+  FillData(dcsMap);\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
+  // 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 iEntry;\r
+  TObjArray* arr = GetDCSEntry(dcsMap, fgkDCSNames[kFillNum],iEntry,fTMin,fTMax);\r
+  if (arr && iEntry>=0) SetFillNumber( ExtractInt( (AliDCSArray*)arr->At(iEntry), 0) );\r
+  //\r
+  for (int ibm=0;ibm<2;ibm++) {\r
+    //\r
+    sprintf(buff,fgkDCSNames[kBunchConf],ibm+1);         // ----- declared bunch configuration\r
+    FillBunchConfig(dcsMap, fBunchConfDecl[ibm], buff);\r
+    //\r
+    sprintf(buff,fgkDCSNames[kBunchLgtFillB],ibm+1);     // ----- measured bunch configuration\r
+    FillBunchConfig(dcsMap, fBunchConfMeas[ibm], buff);\r
+    //\r
+    sprintf(buff,fgkDCSNames[kBunchLgt],ibm+1);          // ----- maesured bunch lenghts\r
+    FillBunchInfo(dcsMap, fBunchLengths[ibm],buff,ibm,kFALSE);  \r
+    //\r
+    sprintf(buff,fgkDCSNames[kIntBunchAv],ibm+1);        // ----- B-by-B intensities\r
+    FillBunchInfo(dcsMap, fIntensPerBunch[ibm],buff,ibm,kTRUE);\r
+    //\r
+    //\r
+    sprintf(buff,fgkDCSNames[kIntTot],ibm+1);            // ----- total intensities for beam 1 and 2\r
+    FillScalarRecord(dcsMap, fIntensTotal[ibm], buff);\r
+    //\r
+    sprintf(buff,fgkDCSNames[kIntTotAv],ibm+1);          // ----- total intensities for beam 1 and 2 from B-by-B average\r
+    FillScalarRecord(dcsMap, fIntensTotalAv[ibm], buff);\r
+    //\r
+    sprintf(buff,fgkDCSNames[kBeamSzEmittH],ibm+1);      // ----- H emittance for beam 1 and 2 \r
+    FillScalarRecord(dcsMap, fEmittanceH[ibm], buff);\r
+    //\r
+    sprintf(buff,fgkDCSNames[kBeamSzEmittV],ibm+1);      // ----- V emittance for beam 1 and 2 \r
+    FillScalarRecord(dcsMap, fEmittanceV[ibm], buff);\r
+    //\r
+    sprintf(buff ,fgkDCSNames[kBeamSzSigH],   ibm+1);    // ----- H sigmas and errors for beam 1 and 2 \r
+    sprintf(buff1,fgkDCSNames[kBeamSzSigHErr],ibm+1);\r
+    FillScalarRecord(dcsMap, fBeamSigmaH[ibm], buff, buff1);\r
+    //\r
+    sprintf(buff ,fgkDCSNames[kBeamSzSigV],   ibm+1);    // ----- V sigmas and errors for beam 1 and 2 \r
+    sprintf(buff1,fgkDCSNames[kBeamSzSigVErr],ibm+1);\r
+    FillScalarRecord(dcsMap, fBeamSigmaV[ibm], buff, buff1);\r
+    //\r
+  }\r
+  //\r
+  for (int ilr=0;ilr<2;ilr++) {\r
+    //\r
+    sprintf(buff ,fgkDCSNames[kLumBunch], ilr ? 'R':'L');       // ---- BC-by-BC luminosity at IP2 and its error\r
+    sprintf(buff1,fgkDCSNames[kLumBunchErr], ilr ? 'R':'L');\r
+    FillBCLuminosities(dcsMap, fLuminPerBC[ilr], buff, buff1, kTRUE);\r
+    //\r
+    sprintf(buff ,fgkDCSNames[kLumTot]   , ilr ? 'R':'L');       // ---- total luminosity at IP2 and its error\r
+    sprintf(buff1,fgkDCSNames[kLumTotErr], ilr ? 'R':'L');\r
+    FillScalarRecord(dcsMap, fLuminTotal[ilr], buff, buff1);\r
+    //\r
+    sprintf(buff ,fgkDCSNames[kLumAcqMode], ilr ? 'R':'L');      // ---- luminosity acquisition mode\r
+    FillAcqMode(dcsMap, fLuminAcqMode[ilr], buff);\r
+    //\r
+    sprintf(buff, fgkDCSNames[kLumCrossAng]   , ilr ? 'R':'L');  //----- crossing angle at IP2 and its error\r
+    sprintf(buff1,fgkDCSNames[kLumCrossAngErr], ilr ? 'R':'L');\r
+    FillScalarRecord(dcsMap, 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
+      sprintf(buff,fgkDCSNames[kCollPos], fgkDCSColNames[icl],fgkDCSColJaws[jaw]);        \r
+      FillScalarRecord(dcsMap, fCollimators[icl][jaw], buff);\r
+    } // jaws\r
+  } // collimators\r
+  //\r
+  //\r
+  // RunControl info\r
+  FillStringRecord(dcsMap, fRCInjScheme, fgkDCSNames[kRCInjSch]);   // ---- active injection scheme\r
+  FillScalarRecord(dcsMap, fRCBeta, fgkDCSNames[kRCBeta]);          // ---- target beta \r
+  FillScalarRecord(dcsMap, fRCAngH, fgkDCSNames[kRCCrossAng]);      // ---- horisontal angle\r
+  FillScalarRecord(dcsMap, fRCAngV,fgkDCSNames[kRCVang] );          // ---- vertical angle\r
+  //\r
+  return kTRUE;\r
+}\r
+\r
+//___________________________________________________________________\r
+TObjArray* AliLHCData::GetDCSEntry(const TMap* dcsMap,const char* key,int &entry,double tmin,double tmax) const\r
+{\r
+  // extract array from the DCS map and find the first entry within the time limits\r
+  entry = -1;\r
+  TObjArray* arr = (TObjArray*)dcsMap->GetValue(key);\r
+  if (!arr || !arr->GetEntriesFast()) { \r
+    AliWarning(Form("No data for %s",key)); \r
+    return 0;\r
+  }\r
+  int ntot = arr->GetEntriesFast();\r
+  for (entry=0;entry<ntot;entry++) {\r
+    AliDCSArray* ent = (AliDCSArray*)arr->At(entry);\r
+    if (ent->GetTimeStamp()>=tmin && ent->GetTimeStamp()<=tmax) break;\r
+  }\r
+  if (entry==ntot) {\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
+  }\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(const TMap* dcsMap, 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,*arrE;\r
+  Int_t nEntries,nEntriesE,iEntry,iEntryE;\r
+  //\r
+  refs[kStart] = fData.GetEntriesFast();\r
+  refs[kNStor] = 0;\r
+  //\r
+  if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
+  nEntries = arr->GetEntriesFast();\r
+  //\r
+  int dim = 1;\r
+  if (recErr) {\r
+    if ( !(arrE=GetDCSEntry(dcsMap,recErr,iEntryE,fTMin,fTMax)) || iEntryE<0 ) nEntriesE = -999;\r
+    else nEntriesE = arrE->GetEntriesFast();\r
+    dim += 1;\r
+  }\r
+  //\r
+  while (iEntry<nEntries) {\r
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
+    double tstamp = dcsVal->GetTimeStamp();\r
+    if (tstamp>fTMax) break;\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 (iEntryE<nEntriesE) {       // try to find corresponding error\r
+       AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iEntryE);\r
+        double tstampE = dcsValE->GetTimeStamp();\r
+        if (tstampE>fTMax) break;\r
+        int tdif = TimeDifference(tstamp,tstampE);\r
+        if (!tdif) { // error matches to value\r
+          errVal = ExtractDouble(dcsValE,0);\r
+         iEntryE++; \r
+         break;\r
+       }\r
+        else if (tdif>0) iEntryE++; // 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
+  //\r
+  return refs[kNStor];\r
+}\r
+\r
+//___________________________________________________________________\r
+Int_t AliLHCData::FillBunchConfig(const TMap* dcsMap, 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 nEntries,iEntry;\r
+  //\r
+  refs[kStart] = fData.GetEntriesFast();\r
+  refs[kNStor] = 0;\r
+  //\r
+  if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
+  nEntries = arr->GetEntriesFast();\r
+  //\r
+  AliLHCDipValI* prevRecI=0;\r
+  while (iEntry<nEntries) {\r
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
+    double tstamp = dcsVal->GetTimeStamp();\r
+    if (tstamp>fTMax) break;\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
+  return refs[kNStor];\r
+}\r
\r
+//___________________________________________________________________\r
+Int_t AliLHCData::FillAcqMode(const TMap* dcsMap, 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 nEntries,iEntry;\r
+  //\r
+  refs[kStart] = fData.GetEntriesFast();\r
+  refs[kNStor] = 0;\r
+  //\r
+  if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
+  nEntries = arr->GetEntriesFast();\r
+  //\r
+  AliLHCDipValI* prevRecI=0;\r
+  while (iEntry<nEntries) {\r
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
+    double tstamp = dcsVal->GetTimeStamp();\r
+    if (tstamp>fTMax) break;\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
+  return refs[kNStor];\r
+}\r
\r
+//___________________________________________________________________\r
+Int_t AliLHCData::FillStringRecord(const TMap* dcsMap, 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 nEntries,iEntry;\r
+  //\r
+  refs[kStart] = fData.GetEntriesFast();\r
+  refs[kNStor] = 0;\r
+  //\r
+  if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
+  nEntries = arr->GetEntriesFast();\r
+  //\r
+  while (iEntry<nEntries) {\r
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
+    double tstamp = dcsVal->GetTimeStamp();\r
+    if (tstamp>fTMax) break;\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
+  return refs[kNStor];\r
+}\r
+\r
+//___________________________________________________________________\r
+Int_t AliLHCData::FillBunchInfo(const TMap* dcsMap, 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 nEntries,iEntry;\r
+  //\r
+  refs[kStart] = fData.GetEntriesFast();\r
+  refs[kNStor] = 0;\r
+  //\r
+  if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
+  nEntries = arr->GetEntriesFast();\r
+  //\r
+  while (iEntry<nEntries) {\r
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
+    double tstamp = dcsVal->GetTimeStamp();\r
+    if (tstamp>fTMax) break;\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
+  return refs[kNStor];\r
+  //\r
+}\r
\r
+//___________________________________________________________________\r
+Int_t AliLHCData::FillBCLuminosities(const TMap* dcsMap, int refs[2],const char* rec, const char* recErr, Bool_t opt)\r
+{\r
+  // fill luminosities per bunch crossing\r
+  //\r
+  AliInfo(Form("Acquiring record: %s",rec));\r
+  TObjArray *arr,*arrE;\r
+  Int_t nEntries,nEntriesE,iEntry,iEntryE;\r
+  //\r
+  refs[kStart] = fData.GetEntriesFast();\r
+  refs[kNStor] = 0;\r
+  //\r
+  if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
+  nEntries = arr->GetEntriesFast();\r
+  //\r
+  while (iEntry<nEntries) {\r
+    AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
+    double tstamp = dcsVal->GetTimeStamp();\r
+    if (tstamp>fTMax) break;\r
+    //\r
+    AliLHCDipValI *bconf = GetBunchConfigMeasured(0,tstamp);  // luminosities are stored according to 1st beam bunches\r
+    if (!bconf) {\r
+      AliWarning(Form("Mearured bunch configuration for beam 1 at t=%.1f is not available, trying declared one",tstamp));\r
+      bconf = GetBunchConfigDeclared(0,tstamp);\r
+    }\r
+    if (!bconf) {\r
+      AliWarning(Form("Declared bunch configuration for beam 1 at t=%.1f is not available, skip this record",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
+    // ATTENTION: FOR THE MOMENT STORE ALL SLOTS CORRESPONDING TO FILLED BUNCHES (until the scheme is clarified)\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 = nbunch;\r
+    if (recErr) {\r
+      if ( !(arrE=GetDCSEntry(dcsMap,recErr,iEntryE,fTMin,fTMax)) || iEntryE<0 ) nEntriesE = -999;\r
+      else nEntriesE = arrE->GetEntriesFast();\r
+      dim += 1;\r
+    }\r
+    AliLHCDipValF* curValF = new AliLHCDipValF(dim,tstamp);\r
+    for (int i=nbunch;i--;) {\r
+      int ind = opt ? (*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
+    //\r
+    if (recErr) {\r
+      double errVal = -1;\r
+      while (iEntryE<nEntriesE) {       // try to find corresponding error\r
+       AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iEntryE);\r
+       double tstamp1 = dcsValE->GetTimeStamp();\r
+       if (tstamp1>fTMax) break;\r
+       int tdif = TimeDifference(tstamp,tstamp1);\r
+       if (!tdif) { // error matches to value\r
+         errVal = dcsValE->GetDouble()[0];\r
+         iEntryE++; \r
+         break;\r
+       }\r
+       else if (tdif>0) iEntryE++; // 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
+  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 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
+  printf("Fill#%6d Validity: %s - %s\n",fFillNumber,\r
+        AliLHCDipValI::TimeAsString(fTMin),AliLHCDipValI::TimeAsString(fTMax));\r
+  //\r
+  printf("********** SETTINGS FROM RUN CONTROL **********\n");\r
+  //\r
+  printf("** Injection Scheme");\r
+  PrintAux(full,fRCInjScheme);\r
+  //\r
+  printf("** Beta Star");\r
+  PrintAux(full,fRCBeta);\r
+  //\r
+  printf("** Horisontal Crossing Angle");\r
+  PrintAux(full,fRCAngH);\r
+  //\r
+  printf("** Vertical   Crossing Angle");\r
+  PrintAux(full,fRCAngV);\r
+  //\r
+  for (int ib=0;ib<2;ib++) {\r
+    printf("** Beam%d bunch filling scheme [negative: bunch interacting at IR2!]",ib+1);\r
+    PrintAux(full,fBunchConfDecl[ib]);\r
+  }\r
+  //\r
+  printf("\n**********       MEASURED DATA       **********\n");\r
+  //\r
+  for (int ib=0;ib<2;ib++) {\r
+    printf("** Beam%d bunch filling scheme [negative: bunch interacts at IR2!]",ib+1);\r
+    PrintAux(full,fBunchConfMeas[ib]);\r
+  } \r
+  //\r
+  for (int ib=0;ib<2;ib++) {\r
+    printf("** Beam%d total intensity",ib+1);\r
+    PrintAux(full,fIntensTotal[ib]);\r
+  } \r
+  //\r
+  for (int ib=0;ib<2;ib++) {\r
+    printf("** Beam%d total intensity from bunch average",ib+1);\r
+    PrintAux(full,fIntensTotalAv[ib]);\r
+  } \r
+  //\r
+  for (int ib=0;ib<2;ib++) {\r
+    printf("** Beam%d intensity per bunch",ib+1);\r
+    PrintAux(full,fIntensPerBunch[ib]);\r
+  }\r
+  //\r
+  for (int ib=0;ib<2;ib++) {\r
+    printf("** Beam%d bunch lengths",ib+1);\r
+    PrintAux(full,fBunchLengths[ib]);\r
+  } \r
+  //\r
+  for (int ib=0;ib<2;ib++) {\r
+    printf("** Beam%d H. emittance",ib+1);\r
+    PrintAux(full,fEmittanceH[ib]);\r
+  }\r
+  //\r
+  for (int ib=0;ib<2;ib++) {\r
+    printf("** Beam%d V. emittance",ib+1);\r
+    PrintAux(full,fEmittanceV[ib]);\r
+  }\r
+  //\r
+  for (int ib=0;ib<2;ib++) {\r
+    printf("** Beam%d H. sigma",ib+1);\r
+    PrintAux(full,fBeamSigmaH[ib]);\r
+  }\r
+  //\r
+  for (int ib=0;ib<2;ib++) {\r
+    printf("** Beam%d V. sigma",ib+1);\r
+    PrintAux(full,fBeamSigmaV[ib]);\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]);\r
+  } \r
+  //\r
+  for (int lr=0;lr<2;lr++) {\r
+    printf("** Luminosity acquisition mode, BRANB_4%c2",lr ? 'R':'L');\r
+    PrintAux(full,fLuminPerBC[lr]);\r
+  } \r
+  //\r
+  for (int lr=0;lr<2;lr++) {\r
+    printf("** Luminosity per Bunch Crossing from BRANB_4%c2",lr ? 'R':'L');\r
+    PrintAux(full,fLuminPerBC[lr]);\r
+  }\r
+  //\r
+  for (int lr=0;lr<2;lr++) {\r
+    printf("** Crossing angle, side %c",lr ? 'R':'L');\r
+    PrintAux(full,fCrossAngle[lr]);\r
+  }\r
+  //\r
+  for (int coll=0;coll<kNCollimators;coll++)\r
+    for (int jaw=0;jaw<kNJaws;jaw++) {\r
+      printf("** Collimator %s:%s",fgkDCSColNames[coll],fgkDCSColJaws[jaw]);\r
+      PrintAux(full,fCollimators[coll][jaw]);\r
+    }\r
+  //\r
+}\r
+\r
+//___________________________________________________________________\r
+void AliLHCData::PrintAux(Bool_t full, const Int_t refs[2]) 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(": (%d):\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();\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
+  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 i=rec->GetSize();i--;) if ( (*rec)[i]<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 i=rec->GetSize();i--;) if ( (*rec)[i]<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
index 1269b10d3d2a1ecc662a79630d7fe4e301c1f405..40a02cac51cf8fdaa4a8df429fc3c9fcefec1bdd 100755 (executable)
-#ifndef ALILHCDATA_H
-#define ALILHCDATA_H
-
-/////////////////////////////////////////////////////////////////////////////////
-//                                                                             //
-//  AliLHCData: summary of the lumnosity related information from LHC DIP.     //
-//  The time dependent values are averaged over the fPeriod (default: 10 min)  //
-//  Created from the TMap provided by the AliLHCReader with optional beginning //
-//  and end time stamps to account.                                            //
-//                                                                             //
-//  The data are (wrapped in the AliLHCDipValT):                               //
-//  Total beam intensities   ( eg GetIntensityTotal(beam) for beam=0,1         //
-//  Total beam luminosities  ( eg GetLuminTotal(side) for side=0,1 (left/right)//
-//  Bunched intensities and luminosities and crossing angle:                   //
-//  GetIntensityBunch(beam),GetLuminBunch(side),GetCrossAngle(side)            //
-//  Bunches configuration:   GetBunchConfig(beam)                              //
-//                                                                             //
-//  Collimators information (initial position + changes > 100 microns)         //
-//  GetCollimator(collID,jawID) with collID={kTCTVB4L2, kTCTVB4R2, kTCLIA4R2}  //
-//  and jawID={kGapDn,kGapUp,kLeftDn,kLeftUp,kRightDn,kRightUp}                //
-//                                                                             //
-//  Author: ruben.shahoyan@cern.ch                                             //
-//                                                                             //
-/////////////////////////////////////////////////////////////////////////////////
-#include "TObject.h"
-#include "AliLHCDipValT.h"
-
-class TMap;
-
-class AliLHCData : public TObject
-{
- public:
-  enum BeamID_t {kBeam1,kBeam2};
-  enum Proj_t   {kX,kY};
-  enum Side_t   {kLeft,kRight};
-  enum Collim_t {kTCTVB4L2, kTCTVB4R2, kTCLIA4R2, kNCollimators};
-  enum ColJaw_t {kGapDn,kGapUp,kLeftDn,kLeftUp,kRightDn,kRightUp,kNJaws};
-  enum {kRecTotInt,kRecTotIntBunch,kRecBunchInt,kRecTotLum,kRecBunchLum,kRecCrossAngle,kRecBunchConf,kRecFillNum,
-       kRecPrfPrID,kRecPrfAmp,kRecPrfPos,kRecPrfSig};
-  //
- public:
-  //
- AliLHCData() : fPeriod(600),fTMin(0),fTMax(1e20) {}
-  AliLHCData(const TMap* dcsMap, double tmin=0, double tmax=1.e20,int avPeriod=600);
-  virtual ~AliLHCData() {}
-  //
-  Bool_t                FillData(const TMap* dcsMap, double tmin=0, double tmax=1.e20);
-  //
-  const TObjArray&      GetIntensityTotal(BeamID_t b)                const {return fIntTot[b];}
-  const TObjArray&      GetIntensityTotalBunch(BeamID_t b)           const {return fIntTotBunch[b];}
-  const TObjArray&      GetIntensityBunch(BeamID_t b)                const {return fIntBunch[b];}
-  const TObjArray&      GetBeamPos(BeamID_t b,Proj_t p)              const {return fBeamPos[b][p];}
-  const TObjArray&      GetLuminTotal(Side_t s)                      const {return fLuminTot[s];}
-  const TObjArray&      GetLuminBunch(Side_t s)                      const {return fLuminBunch[s];}
-  const TObjArray&      GetCrossAngle(Side_t s)                      const {return fCrossAngle[s];}
-  const AliLHCDipValI&  GetBunchConfig(BeamID_t b)                   const {return fBunchConfig[b];}
-  const TObjArray&      GetCollimator(Collim_t c,ColJaw_t jaw)       const {return fCollimators[c][jaw];}
-  //
-  Double_t              GetTMin()                                    const {return fTMin;}
-  Double_t              GetTMax()                                    const {return fTMax;}
-  Int_t                 GetPeriod()                                  const {return fPeriod;}
-  Int_t                 GetNBunches(BeamID_t b)                      const {return GetBunchConfig(b).GetSize();}
-  Int_t                 GetBunchRFBeam1(BeamID_t b,Int_t bunch)      const {return GetBunchConfig(b).GetValue(bunch);}
-  Int_t                 GetFillNumber()                              const {return GetUniqueID();}
-  void                  SetFillNumber(Int_t fill)                          {SetUniqueID(fill);}
-  void                  SetPeriod(Int_t nsec=600)                          {fPeriod = nsec;}
-  void                  SetTMin(Double_t t)                                {fTMin = t;}
-  void                  SetTMax(Double_t t)                                {fTMax = t;}
-  virtual void          Print(const Option_t *opt="")                const;
-  //
- protected:
-  TObjArray*            GetDCSEntry(const TMap* dcsMap,const char* key,int &entry,double tmin,double tmax) const;
-
- AliLHCData(const AliLHCData& src) : TObject(src),fPeriod(src.fPeriod),fTMin(src.fTMin),fTMax(src.fTMax) { /*dummy*/ }
-  AliLHCData& operator=(const AliLHCData& ) { /*dummy*/ return *this;}
-  
- protected:
-  //
-  Int_t           fPeriod;                            // averaging period in seconds
-  Double_t        fTMin;                              // selection timeMin
-  Double_t        fTMax;                              // selection timeMax
-  AliLHCDipValI   fBunchConfig[2];                    // bunches configuration for beam1 and beam2 
-  //
-  TObjArray       fIntTot[2];                         // total intensity (DC BCT) for beam1 and beam2 (AliLHCDipValD)
-  TObjArray       fIntTotBunch[2];                    // total intensity (BCTFR) for beam1 and beam2 (AliLHCDipValD)
-  TObjArray       fIntBunch[2];                       // bunch by bunch intensity for beam1 and beam2 (AliLHCDipValD)
-  //
-  TObjArray       fBeamPos[2][2];                     // horizontal and vertical projection gaussian fit params for beam1 and beam2 (AliLHCDipValD: amp,pos,sigma)
-  //
-  TObjArray       fLuminTot[2];                       // total luminosity from BRANB_4L2 and BRANB_4R2 (AliLHCDipValD)
-  TObjArray       fLuminBunch[2];                     // bunch by bunch luminosity from BRANB_4L2 and BRANB_4R2 (AliLHCDipValD)
-  TObjArray       fCrossAngle[2];                     // beams crossing angle from BRANB_4L2 and BRANB_4R2 (AliLHCDipValD)
-  // 
-  TObjArray       fCollimators[kNCollimators][kNJaws];// collimators data (AliLHCDipValD: kGapDn,kGapUp,kLeftDn,kLeftUp,kRightDn,kRightUp)
-  //
-  static const Char_t *fgkDCSNames[];                 // beam related DCS names to extract
-  static const Char_t *fgkDCSColNames[];              // collimators to extract
-  static const Char_t *fgkDCSColJaws[];               // names of collimator pieces
-
-  ClassDef(AliLHCData,2)
-};
-
-#endif
+#ifndef ALILHCDATA_H\r
+#define ALILHCDATA_H\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
+*   ATTENTION: Bunch RFBucked is NEGATIVE for bunches interacting at IR2        *\r
+*                                                                               *\r
+*                                                                               *\r
+*                                                                               *\r
+*   Author: ruben.shahoyan@cern.ch                                              *\r
+*                                                                               *\r
+********************************************************************************/\r
+\r
+#include "AliLHCDipValT.h"\r
+#include "TObject.h"\r
+class TObjArray;\r
+//class AliLHCDipValT;\r
+\r
+class AliDCSArray;\r
+class TString;\r
+class TMap;\r
+\r
+\r
+class AliLHCData : public TObject\r
+{\r
+ public:\r
+  enum          {kStart,kNStor};\r
+  enum BeamID_t {kBeam1,kBeam2};\r
+  enum Proj_t   {kX,kY};\r
+  enum Side_t   {kLeft,kRight};\r
+  enum Collim_t {kTCTVB4L2, kTCTVB4R2, kTCLIA4R2, kNCollimators};\r
+  enum ColJaw_t {kGapDn,kGapUp,kLeftDn,kLeftUp,kRightDn,kRightUp,kNJaws};\r
+  enum          {kMaxBSlots = 3564};\r
+  //\r
+  enum {kIntTot,kIntTotAv,kIntBunchAv,\r
+       kLumAcqMode,kLumTot,kLumTotErr,kLumBunch,kLumBunchErr,kLumCrossAng,kLumCrossAngErr,\r
+       kBunchConf,kFillNum,kBunchLgtNB,kBunchLgt,kBunchLgtFillB,\r
+       kRCInjSch,kRCBeta,kRCCrossAng,kRCVang,\r
+       kBeamSzAcqMode,kBeamSzSigH,kBeamSzSigV,kBeamSzEmittH,kBeamSzEmittV,kBeamSzSigHErr,kBeamSzSigVErr,\r
+       kCollPos};\r
+  //\r
+  //le\r
+ public:\r
+  //\r
+ AliLHCData() : fTMin(0),fTMax(1e10),fFillNumber(0),fData(0) {Clear();}\r
+  AliLHCData(const TMap* dcsMap, double tmin=0, double tmax=1.e10);\r
+  virtual ~AliLHCData() {}\r
+  //\r
+  Bool_t                FillData(const TMap* dcsMap, double tmin=0, double tmax=1.e20);\r
+  Double_t              GetTMin()                                    const {return fTMin;}\r
+  Double_t              GetTMax()                                    const {return fTMax;}\r
+  Int_t                 GetFillNumber()                              const {return fFillNumber;}\r
+  void                  SetFillNumber(Int_t fill)                          {fFillNumber = fill;}\r
+  void                  SetTMin(Double_t t)                                {fTMin = t<0?0:(t>1e10?1e10:t);}\r
+  void                  SetTMax(Double_t t)                                {fTMax = t<0?0:(t>1e10?1e10:t);}\r
+  virtual void          Print(const Option_t *opt="")                const;\r
+  virtual void          Clear(const Option_t *opt="");\r
+  //\r
+  Int_t GetNBunchConfigMeasured(int bm)           const {return GoodPairID(bm)?fBunchConfMeas[bm][kNStor]:-1;}\r
+  Int_t GetNBunchConfigDeclared(int bm)           const {return GoodPairID(bm)?fBunchConfDecl[bm][kNStor]:-1;}\r
+  Int_t GetNBunchLengths(int bm)                  const {return GoodPairID(bm)?fBunchLengths[bm][kNStor]:-1;}\r
+  Int_t GetNTotalIntensity(int bm)                const {return GoodPairID(bm)?fIntensTotal[bm][kNStor]:-1;}\r
+  Int_t GetNTotalIntensityAv(int bm)              const {return GoodPairID(bm)?fIntensTotalAv[bm][kNStor]:-1;}\r
+  Int_t GetNIntensityPerBunch(int bm)             const {return GoodPairID(bm)?fIntensPerBunch[bm][kNStor]:-1;}\r
+  Int_t GetNEmittanceH(int bm)                    const {return GoodPairID(bm)?fEmittanceH[bm][kNStor]:-1;}\r
+  Int_t GetNEmittanceV(int bm)                    const {return GoodPairID(bm)?fEmittanceV[bm][kNStor]:-1;}\r
+  Int_t GetNBeamSigmaH(int bm)                    const {return GoodPairID(bm)?fBeamSigmaH[bm][kNStor]:-1;}\r
+  Int_t GetNBeamSigmaV(int bm)                    const {return GoodPairID(bm)?fBeamSigmaV[bm][kNStor]:-1;}\r
+  //\r
+  Int_t GetNLuminosityTotal(int lr)               const {return GoodPairID(lr)?fLuminTotal[lr][kNStor]:-1;}\r
+  Int_t GetNLuminosityPerBunch(int lr)            const {return GoodPairID(lr)?fLuminPerBC[lr][kNStor]:-1;}\r
+  Int_t GetNLuminosityAcqMode(int lr)             const {return GoodPairID(lr)?fLuminAcqMode[lr][kNStor]:-1;}\r
+  Int_t GetNCrossingAngle(int lr)                 const {return GoodPairID(lr)?fCrossAngle[lr][kNStor]:-1;}\r
+  //\r
+  Int_t GetNInjectionScheme()                     const {return fRCInjScheme[kNStor];}\r
+  Int_t GetNRCBetaStar()                          const {return fRCBeta[kNStor];}\r
+  Int_t GetNRCAngleH()                            const {return fRCAngH[kNStor];}\r
+  Int_t GetNRCAngleV()                            const {return fRCAngV[kNStor];}\r
+  //\r
+  Int_t GetNCollimatorJawPos(int coll,int jaw)    const;\r
+  //\r
+  AliLHCDipValI* GetBunchConfigMeasured(int bm, int i=0)  const;\r
+  AliLHCDipValF* GetBunchLengths(int bm, int i=0)         const;\r
+  AliLHCDipValI* GetBunchConfigDeclared(int bm, int i=0)  const;\r
+  AliLHCDipValF* GetTotalIntensity(int bm, int i=0)       const;\r
+  AliLHCDipValF* GetTotalIntensityAv(int bm, int i=0)     const;\r
+  AliLHCDipValF* GetIntensityPerBunch(int bm, int i=0)    const;\r
+  AliLHCDipValF* GetEmittanceH(int bm, int i=0)           const;\r
+  AliLHCDipValF* GetEmittanceV(int bm, int i=0)           const;\r
+  AliLHCDipValF* GetBeamSigmaH(int bm, int i=0)           const;\r
+  AliLHCDipValF* GetBeamSigmaV(int bm, int i=0)           const;\r
+  AliLHCDipValF* GetLuminosityTotal(int lr, int i=0)      const;\r
+  AliLHCDipValF* GetLuminosityPerBunch(int lr, int i=0)   const;\r
+  AliLHCDipValI* GetLuminosityAcqMode(int lr, int i=0)    const;\r
+  AliLHCDipValF* GetCrossAngle(int lr, int i=0)           const;\r
+  AliLHCDipValC* GetInjectionScheme(int i=0)              const;\r
+  AliLHCDipValF* GetRCBetaStar(int i=0)                   const;\r
+  AliLHCDipValF* GetRCAngleH(int i=0)                     const; \r
+  AliLHCDipValF* GetRCAngleV(int i=0)                     const; \r
+  AliLHCDipValF* GetCollimJawPos(int coll, int jaw, int i=0) const;\r
+  //\r
+  TObject*       FindRecValidFor(int start,int nrec, double tstamp) const;\r
+  AliLHCDipValI* GetBunchConfigMeasured(int beam,double tstamp)  const;\r
+  AliLHCDipValI* GetBunchConfigDeclared(int beam,double tstamp)  const;\r
+  Int_t          GetNInteractingBunchesMeasured(int i=0)         const;\r
+  Int_t          GetNInteractingBunchesDeclared(int i=0)         const;\r
+  Int_t          IsPilotPresent(int i=0)                         const;\r
+  //\r
+  // return array with beginning [0] and number of records for corresponding info (in the fData)\r
+  const Int_t* GetOffsBunchConfigMeasured(int bm)         const {return GoodPairID(bm)?fBunchConfMeas[bm]:0;}\r
+  const Int_t* GetOffsBunchConfigDeclared(int bm)         const {return GoodPairID(bm)?fBunchConfDecl[bm]:0;}\r
+  const Int_t* GetOffsBunchLengths(int bm)                const {return GoodPairID(bm)?fBunchLengths[bm]:0;}\r
+  const Int_t* GetOffsTotalIntensity(int bm)              const {return GoodPairID(bm)?fIntensTotal[bm]:0;}\r
+  const Int_t* GetOffsTotalIntensityAv(int bm)            const {return GoodPairID(bm)?fIntensTotalAv[bm]:0;}\r
+  const Int_t* GetOffsIntensityPerBunch(int bm)           const {return GoodPairID(bm)?fIntensPerBunch[bm]:0;}\r
+  const Int_t* GetOffsEmittanceH(int bm)                  const {return GoodPairID(bm)?fEmittanceH[bm]:0;}\r
+  const Int_t* GetOffsEmittanceV(int bm)                  const {return GoodPairID(bm)?fEmittanceV[bm]:0;}\r
+  const Int_t* GetOffsBeamSigmaH(int bm)                  const {return GoodPairID(bm)?fBeamSigmaH[bm]:0;}\r
+  const Int_t* GetOffsBeamSigmaV(int bm)                  const {return GoodPairID(bm)?fBeamSigmaV[bm]:0;}\r
+  //\r
+  const Int_t* GetOffsLuminosityTotal(int lr)             const {return GoodPairID(lr)?fLuminTotal[lr]:0;}\r
+  const Int_t* GetOffsLuminosityPerBunch(int lr)          const {return GoodPairID(lr)?fLuminPerBC[lr]:0;}\r
+  const Int_t* GetOffsLuminosityAcqMode(int lr)           const {return GoodPairID(lr)?fLuminAcqMode[lr]:0;}\r
+  const Int_t* GetOffsCrossingAngle(int lr)               const {return GoodPairID(lr)?fCrossAngle[lr]:0;}\r
+  //\r
+  const Int_t* GetOffsInjectionScheme()                   const {return fRCInjScheme;}\r
+  const Int_t* GetOffsRCBetaStar()                        const {return fRCBeta;}\r
+  const Int_t* GetOffsRCAngleH()                          const {return fRCAngH;}\r
+  const Int_t* GetOffsRCAngleV()                          const {return fRCAngV;}\r
+  //\r
+  const Int_t* GetOffsCollimatorJawPos(int coll,int jaw)  const;\r
+  //\r
+  const TObjArray&  GetData()                             const {return fData;}\r
+  //\r
+ protected:\r
+  //\r
+  void                  PrintAux(Bool_t full,const Int_t refs[2]) const;\r
+  TObjArray*            GetDCSEntry(const TMap* dcsMap,const char* key,int &entry,double tmin,double tmax) const;\r
+  Int_t                 FillScalarRecord(  const TMap* dcsMap, int refs[2], const char* rec, const char* recErr=0);\r
+  Int_t                 FillBunchConfig(   const TMap* dcsMap, int refs[2], const char* rec);\r
+  Int_t                 FillStringRecord(  const TMap* dcsMap, int refs[2], const char* rec);\r
+  Int_t                 FillAcqMode(       const TMap* dcsMap, int refs[2], const char* rec);\r
+  Int_t                 FillBunchInfo(     const TMap* dcsMap, int refs[2], const char* rec,int ibm, Bool_t inRealSlots);\r
+  Int_t                 FillBCLuminosities(const TMap* dcsMap, int refs[2], const char* rec, const char* recErr, Bool_t opt);\r
+  //\r
+  Int_t                 ExtractInt(AliDCSArray* dcsArray,Int_t el)    const;\r
+  Double_t              ExtractDouble(AliDCSArray* dcsArray,Int_t el) const;\r
+  TString&              ExtractString(AliDCSArray* dcsArray)          const;\r
+ AliLHCData(const AliLHCData& src) : TObject(src),fTMin(0),fTMax(0),fFillNumber(0),fData(0) { /*dummy*/ }\r
+  AliLHCData& operator=(const AliLHCData& ) { /*dummy*/ return *this;}\r
+  Int_t                 TimeDifference(double v1,double v2,double tol=0.9) const;\r
+  Bool_t                IzZero(double val, double tol=1e-16)         const {return TMath::Abs(val)<tol;}\r
+  Bool_t                GoodPairID(int beam)                         const;\r
+  //\r
+ protected:\r
+  //\r
+  Double_t        fTMin;                              // selection timeMin\r
+  Double_t        fTMax;                              // selection timeMax\r
+  Int_t           fFillNumber;                        // fill number           : kFillNum\r
+  //\r
+  //---------------- Last index gives: 0 - beginning of the records in fData, 1 - number of records\r
+  //\r
+  //              infrormation from RunControl\r
+  Int_t           fRCInjScheme[2];                    // active injection scheme                       : String |kRCInjScheme\r
+  Int_t           fRCBeta[2];                         // target beta                                   : Float  |kRCBeta\r
+  Int_t           fRCAngH[2];                         // horisontal angle                              : Float  |kRCCrossAng\r
+  Int_t           fRCAngV[2];                         // vertical angle                                : Float  |kRCVang\r
+  Int_t           fBunchConfDecl[2][2];               // declared beam configuration                   : Float  |kBunchConf                \r
+  //\r
+  //              measured information\r
+  Int_t           fBunchConfMeas[2][2];               // measured beam configuration                   : Int    |kBunchLgtFillB\r
+  Int_t           fBunchLengths[2][2];                // measured beam lenghts                         : Float  |kBunchLgt\r
+  Int_t           fIntensTotal[2][2];                 // total beam intensities                        : Float  |kIntTot\r
+  Int_t           fIntensTotalAv[2][2];               // total beam intensities from bunch averages    : Float  |kIntTotAv\r
+  Int_t           fIntensPerBunch[2][2];              // bunch-by-bunch intensities                    : Float  |kIntBunchAv\r
+  //\r
+  Int_t           fCrossAngle[2][2];                  // crossing angle   at IP2 and its error         : Float  |kLimCrossAng, kLumCrossAngErr\r
+  Int_t           fEmittanceH[2][2];                  // beam H emittances                             : Float  |kBeamSzEmittH\r
+  Int_t           fEmittanceV[2][2];                  // beam V emittances                             : Float  |kBeamSzEmittV\r
+  Int_t           fBeamSigmaH[2][2];                  // beam H sigma and error                        : Float  |kBeamSzSigH,kBeamSzSigHErr\r
+  Int_t           fBeamSigmaV[2][2];                  // beam V sigma and error                        : Float  |kBeamSzSigV,kBeamSzSigVErr\r
+  //\r
+  Int_t           fLuminTotal[2][2];                  // total luminosity at IP2 and its error         : Float  |kLumTot, kLumTotErr\r
+  Int_t           fLuminPerBC[2][2];                  // luminosity at IP2 for each BC and its error   : Float  |kLumBunch,kLumBunchErr\r
+  Int_t           fLuminAcqMode[2][2];                // luminosity acquisition mode                   : Int    | kLumAcqMode\r
+  //\r
+  Int_t           fCollimators[kNCollimators][kNJaws][2];// collimator jaws positions                  : Float  |kCollPos\r
+  //\r
+  TObjArray       fData;                              // single storage for various records\r
+  //\r
+  static const Char_t *fgkDCSNames[];                 // beam related DCS names to extract\r
+  static const Char_t *fgkDCSColNames[];              // collimators to extract\r
+  static const Char_t *fgkDCSColJaws[];               // names of collimator pieces\r
+\r
+  ClassDef(AliLHCData,1)\r
+};\r
+\r
+\r
+//_____________________________________________________________________________\r
+inline Int_t AliLHCData::GetNCollimatorJawPos(int coll,int jaw) const {// get n records\r
+  return (coll>=0&&coll<kNCollimators&&jaw>=0&&jaw<kNJaws)? fCollimators[coll][jaw][kNStor]:0;\r
+}\r
+\r
+inline const Int_t* AliLHCData::GetOffsCollimatorJawPos(int coll,int jaw)  const { // offset array\r
+  return (coll>=0&&coll<kNCollimators&&jaw>=0&&jaw<kNJaws)? fCollimators[coll][jaw]:0;\r
+}\r
+\r
+inline AliLHCDipValI* AliLHCData::GetBunchConfigMeasured(int bm, int i) const { // get record\r
+  return (GoodPairID(bm) && i>=0 && i<fBunchConfMeas[bm][kNStor]) ? (AliLHCDipValI*)fData[fBunchConfMeas[bm][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetBunchLengths(int bm, int i) const { // get record\r
+  return (GoodPairID(bm) && i>=0 && i<fBunchLengths[bm][kNStor]) ? (AliLHCDipValF*)fData[fBunchLengths[bm][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValI* AliLHCData::GetBunchConfigDeclared(int bm, int i) const { // get record\r
+  return (GoodPairID(bm) && i>=0 && i<fBunchConfDecl[bm][kNStor]) ? (AliLHCDipValI*)fData[fBunchConfDecl[bm][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetTotalIntensity(int bm, int i) const { // get record\r
+  return (GoodPairID(bm) && i>=0 && i<fIntensTotal[bm][kNStor]) ? (AliLHCDipValF*)fData[fIntensTotal[bm][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetTotalIntensityAv(int bm, int i) const { // get record\r
+  return (GoodPairID(bm) && i>=0 && i<fIntensTotalAv[bm][kNStor]) ? (AliLHCDipValF*)fData[fIntensTotalAv[bm][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetIntensityPerBunch(int bm, int i) const { // get record\r
+  return (GoodPairID(bm) && i>=0 && i<fIntensPerBunch[bm][kNStor]) ? (AliLHCDipValF*)fData[fIntensPerBunch[bm][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetEmittanceH(int bm, int i) const { // get record\r
+  return (GoodPairID(bm) && i>=0 && i<fEmittanceH[bm][kNStor]) ? (AliLHCDipValF*)fData[fEmittanceH[bm][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetEmittanceV(int bm, int i) const { // get record\r
+  return (GoodPairID(bm) && i>=0 && i<fEmittanceV[bm][kNStor]) ? (AliLHCDipValF*)fData[fEmittanceV[bm][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetBeamSigmaH(int bm, int i) const { // get record\r
+  return (GoodPairID(bm) && i>=0 && i<fBeamSigmaH[bm][kNStor]) ? (AliLHCDipValF*)fData[fBeamSigmaH[bm][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetBeamSigmaV(int bm, int i) const { // get record\r
+  return (GoodPairID(bm) && i>=0 && i<fBeamSigmaV[bm][kNStor]) ? (AliLHCDipValF*)fData[fBeamSigmaV[bm][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetLuminosityTotal(int lr, int i) const { // get record\r
+  return (GoodPairID(lr) && i>=0 && i<fLuminTotal[lr][kNStor]) ? (AliLHCDipValF*)fData[fLuminTotal[lr][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetLuminosityPerBunch(int lr, int i) const { // get record\r
+  return (GoodPairID(lr) && i>=0 && i<fLuminPerBC[lr][kNStor]) ? (AliLHCDipValF*)fData[fLuminPerBC[lr][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValI* AliLHCData::GetLuminosityAcqMode(int lr, int i) const { // get record\r
+  return (GoodPairID(lr) && i>=0 && i<fLuminAcqMode[lr][kNStor]) ? (AliLHCDipValI*)fData[fLuminAcqMode[lr][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetCrossAngle(int lr, int i) const { // get record\r
+  return (GoodPairID(lr) && i>=0 && i<fCrossAngle[lr][kNStor]) ? (AliLHCDipValF*)fData[fCrossAngle[lr][kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValC* AliLHCData::GetInjectionScheme(int i) const { // get record\r
+  return (i>=0 && i<fRCInjScheme[kNStor]) ? (AliLHCDipValC*)fData[fRCInjScheme[kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetRCBetaStar(int i) const { // get record\r
+  return (i>=0 && i<fRCBeta[kNStor]) ? (AliLHCDipValF*)fData[fRCBeta[kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetRCAngleH(int i) const { // get record\r
+  return (i>=0 && i<fRCAngH[kNStor]) ? (AliLHCDipValF*)fData[fRCAngH[kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetRCAngleV(int i) const { // get record\r
+  return (i>=0 && i<fRCAngV[kNStor]) ? (AliLHCDipValF*)fData[fRCAngV[kStart+i]]:0;\r
+}\r
+\r
+inline AliLHCDipValF* AliLHCData::GetCollimJawPos(int coll, int jaw, int i) const { // get record\r
+  return (coll>=0 && coll<kNCollimators && jaw>=0 && jaw<kNJaws && \r
+         i>=0 && i<fCollimators[coll][jaw][kNStor]) ? (AliLHCDipValF*)fData[fCollimators[coll][jaw][kStart+i]]:0;\r
+}\r
+\r
+\r
+#endif\r
index 12ab5da3225dd9cd0f020fe3627e49b7519c9114..5df929e497c30f999624898886ac0aaffddbf92c 100755 (executable)
@@ -5,7 +5,6 @@
 #include <TString.h>
 #include <TObjString.h>
 #include <TObject.h>
-#include "AliDCSArray.h"
 #include "AliLog.h"
 
 
@@ -24,12 +23,17 @@ template<class Element> class AliLHCDipValT : public TObject
 {
  public:
   //
-  AliLHCDipValT(Int_t size=0, Double_t t=0,Int_t nv=1);
-  AliLHCDipValT(AliLHCDipValT<Element> &src);
+  enum {
+    kLastSpecial=BIT(14),         // last element of array is special (e.g. assigned error etc) 
+    kProcessed1 =BIT(15),         // last element of array is special (e.g. assigned error etc) 
+    kChar=BIT(22),
+    kFloat=BIT(23)
+  };
+  //
+  AliLHCDipValT(Int_t size=0, Double_t t=0);
+  AliLHCDipValT(const AliLHCDipValT<Element> &src);
   virtual ~AliLHCDipValT() {delete[] fArray;}
   AliLHCDipValT& operator=(const AliLHCDipValT<Element> &src);
-  AliLHCDipValT& operator+=(const AliLHCDipValT<Element> &src);
-  AliLHCDipValT& operator+=(const AliDCSArray &src);
   Element&       operator[](Int_t i);
   Element        operator[](Int_t i)                          const;
   //
@@ -37,16 +41,22 @@ template<class Element> class AliLHCDipValT : public TObject
   void                SetValue(Int_t i,Element v);
   void                SetValues(const Element *v, Int_t n);
   void                SetTimeStamp(Double_t v)                      {fTimeStamp = v;}
-  void                SetNSamplesUsed(Int_t n)                      {SetUniqueID((UInt_t)n);}
   // 
-  Int_t               GetSize()                               const {return fSize;}
+  Int_t               GetSizeTotal()                          const {return GetUniqueID();}
   Element             GetValue(Int_t i=0)                     const;
   Element*            GetValues()                             const {return (Element*)fArray;}
   Double_t            GetTimeStamp()                          const {return fTimeStamp;}
-  Int_t               GetNSamplesUsed()                       const {return GetUniqueID();}
   Char_t*             GetTimeAsString()                       const {return TimeAsString(fTimeStamp);}
   //
-  virtual void Average(const Option_t *opt="");
+  void                SetProcessed1(Bool_t v=kTRUE)                 {SetBit(kProcessed1,v);}
+  void                SetLastSpecial(Bool_t v=kTRUE)                {SetBit(kLastSpecial,v);}
+  Bool_t              IsProcessed1()                          const {return TestBit(kProcessed1);}
+  Bool_t              IsLastSpecial()                         const {return TestBit(kLastSpecial);}
+  Int_t               GetSize()                               const {return IsLastSpecial() ? GetSizeTotal()-1:GetSizeTotal();}
+  Bool_t              IsTypeC()                               const {return TestBit(kChar);}
+  Bool_t              IsTypeF()                               const {return TestBit(kFloat);}
+  Bool_t              IsTypeI()                               const {return !TestBit(kFloat|kChar);}
+  //
   virtual void Clear(const Option_t *opt="");
   virtual void Print(const Option_t *opt="")                  const;
   //
@@ -55,8 +65,7 @@ template<class Element> class AliLHCDipValT : public TObject
  protected:
   //
   Double_t            fTimeStamp;        // timestamp of the entry
-  Int_t               fSize;
-  Element*            fArray;            //[fSize] array of entries
+  Element*            fArray;            //[fUniqueID] array of entries
   //
   ClassDef(AliLHCDipValT,1)
 };
@@ -64,22 +73,26 @@ template<class Element> class AliLHCDipValT : public TObject
 
 //__________________________________________________________________________
 template<class Element>
-AliLHCDipValT<Element>::AliLHCDipValT(Int_t size,Double_t t,Int_t nv
-: fTimeStamp(t),fSize(0),fArray(0)
+AliLHCDipValT<Element>::AliLHCDipValT(Int_t size,Double_t t) 
+: fTimeStamp(t),fArray(0)
 {
   //def. constructor
-  SetNSamplesUsed(nv);
   SetSize(size);
+  if      (!strcmp(typeid(fArray).name(),typeid(Char_t*).name())) SetBit(kChar);
+  else if (!strcmp(typeid(fArray).name(),typeid(Double_t*).name()) ||
+          !strcmp(typeid(fArray).name(),typeid(Float_t*).name() )) SetBit(kFloat);
+  //
 }
 
 //__________________________________________________________________________
 template<class Element>
-AliLHCDipValT<Element>::AliLHCDipValT(AliLHCDipValT<Element> &src)
-: TObject(src),fTimeStamp(src.fTimeStamp),fSize(0),fArray(0)
+AliLHCDipValT<Element>::AliLHCDipValT(const AliLHCDipValT<Element> &src)
+: TObject(src),fTimeStamp(src.fTimeStamp),fArray(0)
 {
   //copy constructor
-  SetSize(src.fSize);
-  memcpy(fArray,src.fArray,fSize*sizeof(Element));
+  SetUniqueID(0);
+  SetSize(src.GetSizeTotal());
+  memcpy(fArray,src.fArray,GetSizeTotal()*sizeof(Element));
 }
 
 //__________________________________________________________________________
@@ -89,83 +102,14 @@ AliLHCDipValT<Element>& AliLHCDipValT<Element>::operator=(const AliLHCDipValT<El
   //assingment
   if (this != &src) {
     ((TObject*)this)->operator=(src);
+    SetUniqueID(0);
+    if (GetSizeTotal()!=src.GetSizeTotal()) SetSize(src.GetSizeTotal());
     SetTimeStamp(src.GetTimeStamp());
-    if (fSize!=src.fSize) SetSize(src.fSize);
-    memcpy(fArray,src.fArray,fSize*sizeof(Element));    
+    memcpy(fArray,src.fArray,GetSizeTotal()*sizeof(Element));    
   }
   return *this;
 }
 
-//__________________________________________________________________________
-template<class Element>
-AliLHCDipValT<Element>& AliLHCDipValT<Element>::operator+=(const AliLHCDipValT<Element> &src)
-{
-  //addition
-  TString tp = typeid(fArray).name();
-  if (tp == typeid(Char_t*).name()) {
-    if (fSize<1 && src.fSize>0) *this=src; // for strings reassign only if this is empty
-  }
-  else if (fSize!=src.fSize) {
-    AliError(Form("Sizes of arrays to add must be the same (%d vs %d)",fSize,src.fSize));
-    return *this;    
-  }
-  else {
-    double wtime0 = fTimeStamp*GetNSamplesUsed();
-    double wtime1 = src.fTimeStamp*src.GetNSamplesUsed();
-    int wtot = GetNSamplesUsed() + src.GetNSamplesUsed();
-    SetNSamplesUsed(wtot);
-    if (wtot>0) SetTimeStamp( (wtime0 + wtime1)/wtot );
-    for (int i=fSize;i--;) fArray[i] += src.fArray[i];
-  }
-  return *this;
-}
-
-//__________________________________________________________________________
-template<class Element>
-AliLHCDipValT<Element>& AliLHCDipValT<Element>::operator+=(const AliDCSArray &src)
-{
-  //addition
-  TString tp = typeid(fArray).name();
-  int isstr = (tp==typeid(Char_t*).name()) + (src.GetType()==AliDCSArray::kString);
-  if ( isstr == 1) {
-    AliError("Only one of the sides is of the string type");
-    return *this;
-  }
-  else if (isstr == 2) { // both are string type
-    if (fSize<1 && src.GetNEntries()>0) {
-      TString str;
-      for (int i=0;i<src.GetNEntries();i++) {
-       str += ((TObjString*)src.GetStringArray(i))->GetName();
-       str += " ";
-      }
-      SetSize(str.Length()+1);
-      memcpy(fArray,str.Data(),fSize*sizeof(char));
-    }
-  } else {
-    if (fSize>src.GetNEntries()) {
-      AliError(Form("Size of RHS (%d) is smaller than size of LHS (%d)",src.GetNEntries(),fSize));
-      return *this;
-    }
-    for (int i=fSize;i--;) {
-      Element &val = fArray[i];
-      if      (src.GetType() == AliDCSArray::kDouble) val += src.GetDouble()[i];
-      else if (src.GetType() == AliDCSArray::kFloat)  val += src.GetFloat()[i];
-      else if (src.GetType() == AliDCSArray::kInt)    val += src.GetInt()[i];
-      else if (src.GetType() == AliDCSArray::kUInt)   val += src.GetUInt()[i];
-      else if (src.GetType() == AliDCSArray::kChar)   val += src.GetChar()[i];
-      else if (src.GetType() == AliDCSArray::kBool)   val += src.GetBool()[i];
-    }
-  }
-  //
-  double wtime0 = fTimeStamp*GetNSamplesUsed();
-  double wtime1 = src.GetTimeStamp();
-  int wtot = GetNSamplesUsed() + 1;
-  SetNSamplesUsed(wtot);
-  if (wtot>0) SetTimeStamp( (wtime0 + wtime1)/wtot ); 
-  //
-  return *this;
-}
-
 //__________________________________________________________________________
 template<class Element>
 Char_t* AliLHCDipValT<Element>::TimeAsString(double t)
@@ -181,8 +125,8 @@ template<class Element>
 void AliLHCDipValT<Element>::SetValue(Int_t i,Element v)
 {
   //assign value
-  if (i>=fSize || i<0) {
-    AliError(Form("Index %d is out of range 0:%d",i,fSize-1));
+  if (i>=GetSizeTotal() || i<0) {
+    AliError(Form("Index %d is out of range 0:%d",i,GetSizeTotal()-1));
     return;
   }
   fArray[i] = v;
@@ -193,7 +137,7 @@ template<class Element>
 void AliLHCDipValT<Element>::SetValues(const Element* v, Int_t n)
 {
   //assign value
-  if (n!=fSize) SetSize(n);
+  if (n!=GetSizeTotal()) SetSize(n);
   memcpy(fArray,v,n*sizeof(Element));
 }
 
@@ -202,8 +146,8 @@ template<class Element>
 Element& AliLHCDipValT<Element>::operator[](Int_t i)
 {
   //obtain value refeterence
-  if (i>=fSize || i<0) {
-    AliError(Form("Index %d is out of range 0:%d",i,fSize-1));
+  if (i>=GetSizeTotal() || i<0) {
+    AliError(Form("Index %d is out of range 0:%d",i,GetSizeTotal()-1));
     return fArray[0];
   }
   return fArray[i];
@@ -214,8 +158,8 @@ template<class Element>
 Element AliLHCDipValT<Element>::operator[](Int_t i) const
 {
   //obtain value
-  if (i>=fSize || i<0) {
-    AliError(Form("Index %d is out of range 0:%d",i,fSize-1));
+  if (i>=GetSizeTotal() || i<0) {
+    AliError(Form("Index %d is out of range 0:%d",i,GetSizeTotal()-1));
     return 0;
   }
   return fArray[i];
@@ -226,8 +170,8 @@ template<class Element>
 Element AliLHCDipValT<Element>::GetValue(Int_t i) const
 {
   //obtain value
-  if (i>=fSize || i<0) {
-    AliError(Form("Index %d is out of range 0:%d",i,fSize-1));
+  if (i>=GetSizeTotal() || i<0) {
+    AliError(Form("Index %d is out of range 0:%d",i,GetSizeTotal()-1));
     return 0;
   }
   return fArray[i];
@@ -241,16 +185,16 @@ void AliLHCDipValT<Element>::SetSize(Int_t sz)
   Element* arr = 0;
   if (sz>0) {
     arr = new Element[sz];
-    int nc = fSize > sz ? sz:fSize; // n elems to copy
+    int nc = GetSizeTotal() > sz ? sz:GetSizeTotal(); // n elems to copy
     if (nc) memcpy(arr, fArray, nc*sizeof(Element));
     if (nc<sz) memset(arr+nc, 0, (sz-nc)*sizeof(Element));
-    if (fSize) delete[] fArray;
+    if (GetSizeTotal()) delete[] fArray;
     fArray = arr;
-    fSize = sz;
+    SetUniqueID(sz);
   }
   else {
     delete[] fArray;
-    fSize = 0;
+    SetUniqueID(0);
   }
 }
 
@@ -261,22 +205,30 @@ void AliLHCDipValT<Element>::Print(const Option_t *opt) const
   // print time and value
   TString str = opt; 
   str.ToLower();
-  printf("Timestamp: ");
-  if (str.Contains("raw")) printf("%f",GetTimeStamp());
-  else printf("%s",GetTimeAsString());
-  printf(" | samples %6d | Value: ",GetNSamplesUsed());
+  if (str.Contains("raw")) printf("%.1f ",GetTimeStamp());
+  else printf("[%s] ",GetTimeAsString());
   //
   TString tp = typeid(fArray).name();
-  if ( tp==typeid(Char_t*).name() ) printf(" => %s\n",(Char_t*)fArray);
+  if ( tp==typeid(Char_t*).name() ) printf(": %s\n",(Char_t*)fArray);
   else {
-    if (fSize>1) printf("\n");
-    for (int i=0;i<fSize;i++) {
-      if      (tp == typeid(Int_t*).name()    || tp == typeid(UInt_t*).name() ) printf("#%4d %+11d |",i,(Int_t)fArray[i]);
-      else if (tp == typeid(Double_t*).name() || tp == typeid(Float_t*).name()) printf("#%4d %+e |",  i,(Double_t)fArray[i]);
+    int sz = GetSize();
+    if (sz>1) printf("\n");
+    Bool_t eolOK = kFALSE;
+    for (int i=0;i<sz;i++) {
+      if      (tp == typeid(Int_t*).name()    || tp == typeid(UInt_t*).name() ) printf(" %+5d |" ,(Int_t)fArray[i]);
+      else if (tp == typeid(Double_t*).name() || tp == typeid(Float_t*).name()) printf(" %+.3e |",(Float_t)fArray[i]);
       else printf(" ");
-      if ( (i+1)%5 == 0) printf("\n");
+      eolOK = kFALSE;
+      if ( (i+1)%5 == 0) {printf("\n"); eolOK = kTRUE;}
+    }
+    if (IsLastSpecial()) {
+      if (sz>1 && !eolOK) {printf("\n"); eolOK = kTRUE;}
+      if (tp == typeid(Double_t*).name() || tp == typeid(Float_t*).name()) {
+       printf(" Error: %+e\n",(Float_t)fArray[sz]);
+       eolOK = kTRUE;
+      }
     }
-    if (fSize%5) printf("\n");
+    if (!eolOK) printf("\n");
   }
   //
 }
@@ -286,19 +238,8 @@ template<class Element>
 void AliLHCDipValT<Element>::Clear(const Option_t *)
 {
   // reset to 0 everything
-  SetNSamplesUsed(0);
   SetTimeStamp(0);
-  memset(fArray,0,fSize*sizeof(Element));
-}
-
-//__________________________________________________________________________
-template<class Element>
-void AliLHCDipValT<Element>::Average(const Option_t *)
-{
-  // average of samples
-  int n = GetNSamplesUsed();
-  if (n>0) for (int i=fSize;i--;) fArray[i] /= n;
-  //
+  memset(fArray,0,GetSizeTotal()*sizeof(Element));
 }