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