-/**************************************************************************
- * 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[] = {
- "dip/acc/LHC/Beam/Intensity/Beam%d.totalIntensity",
- "dip/acc/LHC/Beam/IntensityPerBunchBeam%d.averageBunchIntensity",
- "dip/acc/LHC/Beam/LuminosityAverage/BRANB.4%c2.meanLuminosity",
- "dip/acc/LHC/Beam/LuminosityPerBunch/BRANB_4%c2.bunchByBunchLuminosity",
- "dip/acc/LHC/Beam/LuminosityAverage/BRANB.4%c2.meanCrossingAngle",
- "dip/acc/LHC/RunControl/CirculatingBunchConfig/Beam%d.value",
- "dip/acc/LHC/RunControl/FillNumber.payload",
- //
- "dip/acc/LHC/Beam/Size/Beam%d.planeSet%d",
- "dip/acc/LHC/Beam/Size/Beam%d.amplitudeSet%d",
- "dip/acc/LHC/Beam/Size/Beam%d.positionSet%d",
- "dip/acc/LHC/Beam/Size/Beam%d.sigmaSet%d"};
-
-const Char_t* AliLHCData::fgkDCSColNames[] = {
- "dip/acc/LHC/Machine/CollimatorPositions/TCTVB.4L2.%s",
- "dip/acc/LHC/Machine/CollimatorPositions/TCTVB.4R2.%s",
- "dip/acc/LHC/Machine/CollimatorPositions/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
- 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;
- 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 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 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("Beam1 bunch intensities record is present but empty",ibm));
- 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;
- }
- //
- 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 bunch configuration for beam 1 and 2
- for (int ibm=0;ibm<2;ibm++) {
- //
- 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
- dcsSize = 0;
- while(dcsSize<nEntries && dcsVal->GetInt(dcsSize)) dcsSize++;
- if (!dcsSize) {
- AliWarning("Bunches configuration record is present but empty");
- continue;
- }
- fBunchConfig[ibm].SetSize(dcsSize);
- fBunchConfig[ibm] += *dcsVal;
- }
- //
- // ------------------------- 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.)",GetFillNumber(),fPeriod);
- printf("Validity period: %s : %s",
- 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("*** Total intensity for Beam%d: %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("*** 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 "AliLHCReader.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(0),fTMax(0),fFillNumber(0),fData(0),fFile2Process(0),fMap2Process(0)\r
+{\r
+ FillData(dcsMap,tmin,tmax);\r
+}\r
+\r
+//___________________________________________________________________\r
+AliLHCData::AliLHCData(const Char_t* dcsFile, double tmin, double tmax)\r
+ : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fFile2Process(dcsFile),fMap2Process(0)\r
+{\r
+ FillData(dcsFile,tmin,tmax);\r
+}\r
+\r
+//___________________________________________________________________\r
+Bool_t AliLHCData::FillData(const TMap* dcsMap,double tmin, double tmax)\r
+{\r
+ // process DCS map and fill all fields. \r
+ Clear();\r
+ fMap2Process = dcsMap;\r
+ FillData(tmin,tmax);\r
+ return kTRUE;\r
+}\r
+\r
+//___________________________________________________________________\r
+Bool_t AliLHCData::FillData(const Char_t* dcsFile,double tmin, double tmax)\r
+{\r
+ // process DCS file and fill all fields. \r
+ Clear();\r
+ fFile2Process = dcsFile;\r
+ FillData(tmin,tmax);\r
+ return kTRUE;\r
+}\r
+\r
+//___________________________________________________________________\r
+Bool_t AliLHCData::FillData(double tmin, double tmax)\r
+{\r
+ // process DCS map and fill all fields. \r
+ // Accept only entries with timestamp between tmin and tmax\r
+ //\r
+ char buff[100],buff1[100];\r
+ //\r
+ SetTMin(tmin);\r
+ SetTMax(tmax);\r
+ //\r
+ // -------------------------- extract Fill Number\r
+ int iFirst=0,iLast=0;\r
+ TObjArray* arr = GetDCSEntry(fgkDCSNames[kFillNum],iFirst,iLast,fTMin,fTMax);\r
+ if (arr) SetFillNumber( ExtractInt( (AliDCSArray*)arr->At(iFirst), 0) );\r
+ if (fFile2Process) delete arr; // array was created on demand\r
+ //\r
+ for (int ibm=0;ibm<2;ibm++) {\r
+ //\r
+ sprintf(buff,fgkDCSNames[kBunchConf],ibm+1); // ----- declared bunch configuration\r
+ FillBunchConfig(fBunchConfDecl[ibm], buff);\r
+ //\r
+ sprintf(buff,fgkDCSNames[kBunchLgtFillB],ibm+1); // ----- measured bunch configuration\r
+ FillBunchConfig(fBunchConfMeas[ibm], buff);\r
+ //\r
+ sprintf(buff,fgkDCSNames[kBunchLgt],ibm+1); // ----- measured bunch lenghts\r
+ FillBunchInfo(fBunchLengths[ibm],buff,ibm,kFALSE); \r
+ //\r
+ sprintf(buff,fgkDCSNames[kIntBunchAv],ibm+1); // ----- B-by-B intensities\r
+ FillBunchInfo(fIntensPerBunch[ibm],buff,ibm,kTRUE);\r
+ //\r
+ //\r
+ sprintf(buff,fgkDCSNames[kIntTot],ibm+1); // ----- total intensities for beam 1 and 2\r
+ FillScalarRecord(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(fIntensTotalAv[ibm], buff);\r
+ //\r
+ sprintf(buff,fgkDCSNames[kBeamSzEmittH],ibm+1); // ----- H emittance for beam 1 and 2 \r
+ FillScalarRecord(fEmittanceH[ibm], buff);\r
+ //\r
+ sprintf(buff,fgkDCSNames[kBeamSzEmittV],ibm+1); // ----- V emittance for beam 1 and 2 \r
+ FillScalarRecord(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(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(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
+ 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(fLuminPerBC[ilr], buff, buff1, 0); // BRAN L uses beam2 as a reference, BRAN R - beam1\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(fLuminTotal[ilr], buff, buff1);\r
+ //\r
+ sprintf(buff ,fgkDCSNames[kLumAcqMode], ilr ? 'R':'L'); // ---- luminosity acquisition mode\r
+ FillAcqMode(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(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(fCollimators[icl][jaw], buff);\r
+ } // jaws\r
+ } // collimators\r
+ //\r
+ //\r
+ // RunControl info\r
+ FillStringRecord(fRCInjScheme, fgkDCSNames[kRCInjSch]); // ---- active injection scheme\r
+ FillScalarRecord(fRCBeta, fgkDCSNames[kRCBeta]); // ---- target beta \r
+ FillScalarRecord(fRCAngH, fgkDCSNames[kRCCrossAng]); // ---- horisontal angle\r
+ FillScalarRecord(fRCAngV,fgkDCSNames[kRCVang] ); // ---- vertical angle\r
+ //\r
+ return kTRUE;\r
+}\r
+\r
+//___________________________________________________________________\r
+TObjArray* AliLHCData::GetDCSEntry(const char* key,int &entry,int &last,double tmin,double tmax) const\r
+{\r
+ // extract array from the DCS map or file and find the first entry within the time limits\r
+ entry = -1;\r
+ last = -2;\r
+ TObjArray* arr;\r
+ if (fMap2Process) arr = (TObjArray*)fMap2Process->GetValue(key);\r
+ else if (fFile2Process) {\r
+ AliLHCReader rd;\r
+ arr = rd.ReadSingleLHCDP(fFile2Process,key);\r
+ }\r
+ else {\r
+ AliError("Neither DCS map nor DCS filename are set");\r
+ return 0; \r
+ }\r
+ //\r
+ if (!arr || !arr->GetEntriesFast()) { \r
+ AliWarning(Form("No data for %s",key)); \r
+ if (fMap2Process) delete arr; // created on demand\r
+ return 0;\r
+ }\r
+ int ntot = arr->GetEntriesFast();\r
+ //\r
+ // search 1st entry before or at tmin\r
+ AliDCSArray* ent = 0;\r
+ Bool_t found = kFALSE;\r
+ for (entry=0;entry<ntot;entry++) {\r
+ ent = (AliDCSArray*)arr->At(entry);\r
+ if (ent->GetTimeStamp()>=tmin-kMarginSOR && ent->GetTimeStamp()<=tmax+kMarginEOR) {\r
+ found = kTRUE;\r
+ if (ent->GetTimeStamp()>tmin) break;\r
+ }\r
+ }\r
+ if (!found) {\r
+ entry = -1;\r
+ TString str;\r
+ str += AliLHCDipValD::TimeAsString(tmin);\r
+ str += " : ";\r
+ str += AliLHCDipValD::TimeAsString(tmax);\r
+ AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));\r
+ if (fMap2Process) delete arr; // created on demand\r
+ return 0;\r
+ }\r
+ if (entry>0) entry--;\r
+ //\r
+ // search last entry at or after tmin\r
+ ent = 0;\r
+ for (last=entry;last<ntot;last++) {\r
+ ent = (AliDCSArray*)arr->At(last);\r
+ if (ent->GetTimeStamp()>tmax) break;\r
+ }\r
+ if (last == ntot) last--;\r
+ else if (ent->GetTimeStamp()>tmax+kMarginEOR) last--;\r
+ //\r
+ return arr;\r
+}\r
+\r
+//___________________________________________________________________\r
+Int_t AliLHCData::TimeDifference(double v1,double v2,double tol) const\r
+{\r
+ // return 0 if the times are the same within the tolerance\r
+ // 1 if v1>v2\r
+ // -1 if v1<v2\r
+ v1-=v2;\r
+ if (v1>tol) return 1;\r
+ if (v1<-tol) return -1;\r
+ return 0;\r
+}\r
+\r
+//___________________________________________________________________\r
+Bool_t AliLHCData::GoodPairID(int beam) const\r
+{\r
+ // check for correct beam identifier \r
+ if (beam>kBeam2||beam<0) {AliError(Form("BeamID can be 0 or 1, %d requested",beam)); return kFALSE;}\r
+ return kTRUE;\r
+}\r
+\r
+//___________________________________________________________________\r
+AliLHCDipValI* AliLHCData::GetBunchConfigMeasured(int beam,double tstamp) const\r
+{\r
+ // find measured bunch configuration valid for given tstamp\r
+ if (!GoodPairID(beam)) return 0;\r
+ return (AliLHCDipValI*)FindRecValidFor(fBunchConfMeas[beam][kStart],fBunchConfMeas[beam][kNStor],tstamp);\r
+}\r
+\r
+//___________________________________________________________________\r
+AliLHCDipValI* AliLHCData::GetBunchConfigDeclared(int beam,double tstamp) const\r
+{\r
+ // find declared bunch configuration valid for given tstamp\r
+ if (!GoodPairID(beam)) return 0;\r
+ return (AliLHCDipValI*)FindRecValidFor(fBunchConfDecl[beam][kStart],fBunchConfDecl[beam][kNStor],tstamp);\r
+}\r
+\r
+//___________________________________________________________________\r
+TObject* AliLHCData::FindRecValidFor(int start,int nrec, double tstamp) const\r
+{\r
+ // find record within this limits valid for given tstamp (i.e. the last one before or equal to tstamp)\r
+ AliLHCDipValI *prevObj = 0;\r
+ for (int i=0;i<nrec;i++) {\r
+ AliLHCDipValI* curObj = (AliLHCDipValI*)fData[start+i];\r
+ if (TimeDifference(tstamp,curObj->GetTimeStamp())<0) break;\r
+ prevObj = curObj;\r
+ }\r
+ if (!prevObj && nrec>0) prevObj = (AliLHCDipValI*)fData[start]; // if no exact match, return the 1st one\r
+ return prevObj;\r
+}\r
+\r
+//___________________________________________________________________\r
+Int_t AliLHCData::FillScalarRecord(int refs[2], const char* rec, const char* recErr)\r
+{\r
+ // fill record for scalar value, optionally accompanied by measurement error \r
+ //\r
+ AliInfo(Form("Acquiring record: %s",rec));\r
+ //\r
+ TObjArray *arr=0,*arrE=0;\r
+ Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;\r
+ //\r
+ refs[kStart] = fData.GetEntriesFast();\r
+ refs[kNStor] = 0;\r
+ //\r
+ if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
+ //\r
+ int dim = 1;\r
+ if (recErr) {\r
+ arrE = GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);\r
+ dim += 1;\r
+ }\r
+ //\r
+ Bool_t last = kFALSE;\r
+ while (iFirst<=iLast) {\r
+ AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
+ double tstamp = dcsVal->GetTimeStamp();\r
+ //\r
+ AliLHCDipValF* curValF = new AliLHCDipValF(dim,tstamp); // start new period\r
+ (*curValF)[0] = ExtractDouble(dcsVal,0); // value\r
+ //\r
+ if (recErr) {\r
+ double errVal = -1;\r
+ while (iFirstE<=iLastE) { // try to find corresponding error\r
+ AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);\r
+ double tstampE = dcsValE->GetTimeStamp();\r
+ int tdif = TimeDifference(tstamp,tstampE);\r
+ if (!tdif) { // error matches to value\r
+ errVal = ExtractDouble(dcsValE,0);\r
+ iFirstE++; \r
+ break;\r
+ }\r
+ else if (tdif>0) iFirstE++; // error time lags behind, read the next one\r
+ else break; // error time is ahead of value, no error associated\r
+ }\r
+ (*curValF)[dim-1] = errVal; // error\r
+ curValF->SetLastSpecial(); // lable the last entry as an error\r
+ }\r
+ //\r
+ fData.Add(curValF);\r
+ refs[kNStor]++;\r
+ if (last) break;\r
+ }\r
+ //\r
+ if (fFile2Process) {\r
+ delete arr;\r
+ delete arrE;\r
+ }\r
+ return refs[kNStor];\r
+}\r
+\r
+//___________________________________________________________________\r
+Int_t AliLHCData::FillBunchConfig(int refs[2],const char* rec)\r
+{\r
+ // fill record for bunch configuration\r
+ //\r
+ AliInfo(Form("Acquiring record: %s",rec));\r
+ TObjArray *arr;\r
+ Int_t iLast,iFirst;\r
+ //\r
+ refs[kStart] = fData.GetEntriesFast();\r
+ refs[kNStor] = 0;\r
+ //\r
+ if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
+ //\r
+ AliLHCDipValI* prevRecI=0;\r
+ // \r
+ while (iFirst<=iLast) {\r
+ AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
+ double tstamp = dcsVal->GetTimeStamp();\r
+ //\r
+ int bucket=0, nbunch=0, ndiff=0;\r
+ int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)\r
+ int* dcsArr = dcsVal->GetInt();\r
+ while(nbunch<nSlots && (bucket=dcsArr[nbunch])) {\r
+ if (prevRecI && prevRecI->GetSize()>nbunch && bucket!=prevRecI->GetValue(nbunch)) ndiff++;\r
+ nbunch++;\r
+ }\r
+ if (!nbunch) AliWarning(Form("%s record is present but empty: no beam?",rec));\r
+ if (prevRecI && !ndiff && nbunch==prevRecI->GetSize()) continue; // record similar to previous one\r
+ AliLHCDipValI* curValI = new AliLHCDipValI(nbunch,tstamp); \r
+ for (int i=nbunch;i--;) (*curValI)[i] = dcsArr[i];\r
+ fData.Add(curValI);\r
+ refs[kNStor]++;\r
+ prevRecI = curValI;\r
+ }\r
+ //\r
+ if (fFile2Process) delete arr;\r
+ return refs[kNStor];\r
+}\r
+ \r
+//___________________________________________________________________\r
+Int_t AliLHCData::FillAcqMode(int refs[2],const char* rec)\r
+{\r
+ // fill acquisition mode\r
+ //\r
+ AliInfo(Form("Acquiring record: %s",rec));\r
+ TObjArray *arr;\r
+ Int_t iLast,iFirst;\r
+ //\r
+ refs[kStart] = fData.GetEntriesFast();\r
+ refs[kNStor] = 0;\r
+ //\r
+ if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
+ //\r
+ AliLHCDipValI* prevRecI=0;\r
+ while (iFirst<=iLast) {\r
+ AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
+ double tstamp = dcsVal->GetTimeStamp();\r
+ //\r
+ int nSlots = dcsVal->GetNEntries();\r
+ if (nSlots<1) continue;\r
+ int acqMode = dcsVal->GetInt()[0];\r
+ if (prevRecI && (*prevRecI)[0] == acqMode) continue; // record similar to previous one\r
+ AliLHCDipValI* curValI = new AliLHCDipValI(1,tstamp); \r
+ (*curValI)[0] = acqMode;\r
+ fData.Add(curValI);\r
+ refs[kNStor]++;\r
+ prevRecI = curValI;\r
+ }\r
+ //\r
+ if (fFile2Process) delete arr;\r
+ return refs[kNStor];\r
+}\r
+ \r
+//___________________________________________________________________\r
+Int_t AliLHCData::FillStringRecord(int refs[2],const char* rec)\r
+{\r
+ // fill record with string value\r
+ //\r
+ AliInfo(Form("Acquiring record: %s",rec));\r
+ TString prevRec;\r
+ TObjArray *arr;\r
+ Int_t iLast,iFirst;\r
+ //\r
+ refs[kStart] = fData.GetEntriesFast();\r
+ refs[kNStor] = 0;\r
+ //\r
+ if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
+ //\r
+ while (iFirst<=iLast) {\r
+ AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
+ double tstamp = dcsVal->GetTimeStamp();\r
+ //\r
+ TString &str = ExtractString(dcsVal);\r
+ if (!prevRec.IsNull()) {if (str == prevRec) continue;} // skip similar record\r
+ else prevRec = str;\r
+ //\r
+ AliLHCDipValC* curValS = new AliLHCDipValC(1,tstamp); \r
+ curValS->SetValues(str.Data(),str.Length()+1);\r
+ //\r
+ fData.Add(curValS);\r
+ refs[kNStor]++;\r
+ }\r
+ if (fFile2Process) delete arr;\r
+ return refs[kNStor];\r
+}\r
+\r
+//___________________________________________________________________\r
+Int_t AliLHCData::FillBunchInfo(int refs[2],const char* rec, int ibm, Bool_t inRealSlots)\r
+{\r
+ // fill bunch properties for beam ibm\r
+ // if inRealSlots = true, then the value is taken from bunchRFbucket/10, otherwise, the value \r
+ // for the i-th bunch is taken from the i-th element\r
+ //\r
+ AliInfo(Form("Acquiring record: %s",rec));\r
+ TObjArray *arr;\r
+ Int_t iLast,iFirst;\r
+ //\r
+ refs[kStart] = fData.GetEntriesFast();\r
+ refs[kNStor] = 0;\r
+ //\r
+ if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
+ //\r
+ while (iFirst<=iLast) {\r
+ AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
+ double tstamp = dcsVal->GetTimeStamp();\r
+ //\r
+ AliLHCDipValI *bconf = GetBunchConfigMeasured(ibm,tstamp);\r
+ if (!bconf) {\r
+ AliWarning(Form("Mearured bunch configuration for beam %d at t=%.1f is not available, trying declared one",ibm+1,tstamp));\r
+ bconf = GetBunchConfigDeclared(ibm,tstamp);\r
+ }\r
+ if (!bconf) {\r
+ AliWarning(Form("Declared bunch configuration for beam %d at t=%.1f is not available, skip this record",ibm+1,tstamp));\r
+ return -1;\r
+ }\r
+ int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)\r
+ int nbunch = bconf->GetSize();\r
+ if (nbunch>nSlots) {\r
+ AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));\r
+ continue;\r
+ }\r
+ double* dcsArr = dcsVal->GetDouble();\r
+ AliLHCDipValF* curValF = new AliLHCDipValF(nbunch,tstamp);\r
+ for (int i=nbunch;i--;) {\r
+ int ind = inRealSlots ? (*bconf)[i]/10 : i;\r
+ if (ind>nSlots) {\r
+ AliError(Form("Bunch %d refers to wrong slot %d, set to -1",i,(*bconf)[i]));\r
+ (*curValF)[i] = -1;\r
+ }\r
+ else (*curValF)[i] = dcsArr[ind];\r
+ }\r
+ fData.Add(curValF);\r
+ refs[kNStor]++;\r
+ }\r
+ if (fFile2Process) delete arr;\r
+ return refs[kNStor];\r
+ //\r
+}\r
+ \r
+//___________________________________________________________________\r
+Int_t AliLHCData::FillBCLuminosities(int refs[2],const char* rec, const char* recErr, int useBeam)\r
+{\r
+ // fill luminosities per bunch crossing\r
+ //\r
+ AliInfo(Form("Acquiring record: %s",rec));\r
+ TObjArray *arr,*arrE=0;\r
+ Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;\r
+ //\r
+ refs[kStart] = fData.GetEntriesFast();\r
+ refs[kNStor] = 0;\r
+ //\r
+ if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
+ //\r
+ while (iFirst<=iLast) {\r
+ AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
+ double tstamp = dcsVal->GetTimeStamp();\r
+ //\r
+ AliLHCDipValI *bconf;\r
+ bconf = GetBunchConfigMeasured(useBeam,tstamp); // luminosities are stored according to beam bunches\r
+ if (!bconf) {\r
+ AliWarning(Form("Mearured bunch configuration for beam%d at t=%.1f is not available, trying declared one",useBeam,tstamp));\r
+ bconf = GetBunchConfigDeclared(useBeam,tstamp);\r
+ }\r
+ if (!bconf) {\r
+ AliWarning(Form("Declared bunch configuration for beam%i at t=%.1f is not available, skip this record",useBeam,tstamp));\r
+ return -1;\r
+ }\r
+ int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)\r
+ int nbunch = bconf->GetSize();\r
+ double* dcsArr = dcsVal->GetDouble();\r
+ //\r
+ if (nbunch>nSlots) {\r
+ AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));\r
+ continue;\r
+ }\r
+ int dim = 0;\r
+ if (!bconf->IsProcessed1()) {\r
+ AliWarning(Form("Bunch conf. for beam%d has no marked interacting bunches, store all luminosity for all filled bunches",useBeam));\r
+ dim = nbunch;\r
+ }\r
+ else { // count number of interacting bunches\r
+ for (int i=nbunch;i--;) if ((*bconf)[i]<0) dim++;\r
+ }\r
+ //\r
+ if (recErr) {\r
+ arrE=GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);\r
+ dim += 1;\r
+ }\r
+ AliLHCDipValF* curValF = new AliLHCDipValF(dim,tstamp);\r
+ int cnt = 0;\r
+ for (int i=0;i<nbunch;i++) {\r
+ int slot = (*bconf)[i];\r
+ if (bconf->IsProcessed1() && slot>0) continue;\r
+ //\r
+ int ind = TMath::Abs(slot)/10;\r
+ if (ind>nSlots) {\r
+ AliError(Form("Bunch %d refers to wrong slot %d, set to -1",cnt,slot));\r
+ (*curValF)[cnt] = -1;\r
+ }\r
+ else (*curValF)[cnt] = dcsArr[ind];\r
+ cnt++;\r
+ }\r
+ //\r
+ if (recErr) {\r
+ double errVal = -1;\r
+ while (iFirstE<=iLastE) { // try to find corresponding error\r
+ AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);\r
+ double tstamp1 = dcsValE->GetTimeStamp();\r
+ int tdif = TimeDifference(tstamp,tstamp1);\r
+ if (!tdif) { // error matches to value\r
+ errVal = dcsValE->GetDouble()[0];\r
+ iFirstE++; \r
+ break;\r
+ }\r
+ else if (tdif>0) iFirstE++; // error time lags behind, read the next one\r
+ else break; // error time is ahead of value, no error associated\r
+ }\r
+ (*curValF)[dim-1] = errVal; // error\r
+ curValF->SetLastSpecial(); // lable the last entry as an error\r
+ }\r
+ //\r
+ fData.Add(curValF);\r
+ refs[kNStor]++;\r
+ }\r
+ if (fFile2Process) {\r
+ delete arr;\r
+ delete arrE;\r
+ }\r
+ return refs[kNStor];\r
+ //\r
+}\r
+\r
+//___________________________________________________________________\r
+Int_t AliLHCData::ExtractInt(AliDCSArray* dcsArray,Int_t el) const\r
+{\r
+ // extract integer from the dcsArray\r
+ int val = -1;\r
+ //\r
+ int sz = dcsArray->GetNEntries();\r
+ if (sz<=el) return val;\r
+ //\r
+ if (dcsArray->GetType()==AliDCSArray::kInt) val = dcsArray->GetInt(el);\r
+ else if (dcsArray->GetType()==AliDCSArray::kString) {\r
+ TObjString *stro = dcsArray->GetStringArray(el);\r
+ if (stro) val = stro->GetString().Atoi();\r
+ else AliError(Form("DCSArray TObjString for element %d is missing",el));\r
+ }\r
+ else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);\r
+ else AliError(Form("Integer requested from DCSArray of type %d",dcsArray->GetType()));\r
+ return val;\r
+}\r
+\r
+//___________________________________________________________________\r
+Double_t AliLHCData::ExtractDouble(AliDCSArray* dcsArray,Int_t el) const\r
+{\r
+ // extract double from the dcsArray\r
+ double val = 0;\r
+ //\r
+ int sz = dcsArray->GetNEntries();\r
+ if (sz<=el) return val;\r
+ //\r
+ if (dcsArray->GetType()==AliDCSArray::kDouble) val = dcsArray->GetDouble(el);\r
+ else if (dcsArray->GetType()==AliDCSArray::kFloat) val = dcsArray->GetFloat(el);\r
+ else if (dcsArray->GetType()==AliDCSArray::kString) {\r
+ TObjString *stro = dcsArray->GetStringArray(el);\r
+ if (stro) val = stro->GetString().Atof();\r
+ else AliError(Form("DCSArray has TObjString for element %d is missing",el));\r
+ }\r
+ else if (dcsArray->GetType()==AliDCSArray::kChar) val = dcsArray->GetChar(el);\r
+ else if (dcsArray->GetType()==AliDCSArray::kInt) val = dcsArray->GetInt(el);\r
+ else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);\r
+ else AliError(Form("Double requested from DCSArray of type %d",dcsArray->GetType()));\r
+ return val;\r
+}\r
+\r
+//___________________________________________________________________\r
+TString& AliLHCData::ExtractString(AliDCSArray* dcsArray) const\r
+{\r
+ // extract string from the dcsArray\r
+ static TString str;\r
+ str = "";\r
+ //\r
+ int sz = dcsArray->GetNEntries();\r
+ if (dcsArray->GetType()!=AliDCSArray::kString) {\r
+ AliError(Form("String requested from DCSArray of type %d",dcsArray->GetType()));\r
+ return str;\r
+ }\r
+ //\r
+ for (int i=0;i<sz;i++) {\r
+ str += dcsArray->GetStringArray(i)->GetString();\r
+ if (i<sz-1) str += " ";\r
+ }\r
+ return str;\r
+}\r
+\r
+//___________________________________________________________________\r
+void AliLHCData::Print(const Option_t* opt) const\r
+{\r
+ // print full info\r
+ TString opts = opt;\r
+ opts.ToLower();\r
+ Bool_t utcTime = opts.Contains("loc") ? kFALSE:kTRUE;\r
+ Bool_t full = kTRUE;\r
+ if (!opts.Contains("f")) {\r
+ printf("Use Print(\"f\") to print full info\n");\r
+ printf("Printing short info:\n<RecordType>(number of records): <TimeStamp, value> for 1st record only\n");\r
+ full = kFALSE;\r
+ }\r
+ TString sdtmn = AliLHCDipValI::TimeAsString(fTMin,utcTime);\r
+ TString sdtmx = AliLHCDipValI::TimeAsString(fTMax,utcTime);\r
+ printf("Fill#%6d Validity: %s - %s (%s)\n",fFillNumber,sdtmn.Data(),sdtmx.Data(),utcTime ? "UTC":"LOC");\r
+ //\r
+ printf("********** SETTINGS FROM RUN CONTROL **********\n");\r
+ //\r
+ printf("* %-38s","Injection Scheme");\r
+ PrintAux(full,fRCInjScheme,opts);\r
+ //\r
+ printf("* %-38s","Beta Star");\r
+ PrintAux(full,fRCBeta,opts);\r
+ //\r
+ printf("* %-38s","Horisontal Crossing Angle");\r
+ PrintAux(full,fRCAngH,opts);\r
+ //\r
+ printf("* %-38s","Vertical Crossing Angle");\r
+ PrintAux(full,fRCAngV,opts);\r
+ //\r
+ for (int ib=0;ib<2;ib++) {\r
+ printf("* Beam%d filling [- interacts at IR2!] ",ib+1);\r
+ PrintAux(full,fBunchConfDecl[ib],opts);\r
+ }\r
+ //\r
+ printf("\n********** MEASURED DATA **********\n");\r
+ //\r
+ for (int ib=0;ib<2;ib++) {\r
+ printf("* Beam%d filling [- interacts at IR2!] ",ib+1);\r
+ PrintAux(full,fBunchConfMeas[ib],opts);\r
+ } \r
+ //\r
+ for (int ib=0;ib<2;ib++) {\r
+ printf("* Beam%d total intensity ",ib+1);\r
+ PrintAux(full,fIntensTotal[ib],opts);\r
+ } \r
+ //\r
+ for (int ib=0;ib<2;ib++) {\r
+ printf("* Beam%d total intensity (bunch average) ",ib+1);\r
+ PrintAux(full,fIntensTotalAv[ib],opts);\r
+ } \r
+ //\r
+ for (int ib=0;ib<2;ib++) {\r
+ printf("* Beam%d intensity per bunch ",ib+1);\r
+ PrintAux(full,fIntensPerBunch[ib],opts);\r
+ }\r
+ //\r
+ for (int ib=0;ib<2;ib++) {\r
+ printf("* Beam%d bunch lengths ",ib+1);\r
+ PrintAux(full,fBunchLengths[ib],opts);\r
+ } \r
+ //\r
+ for (int ib=0;ib<2;ib++) {\r
+ printf("* Beam%d Horisontal emittance ",ib+1);\r
+ PrintAux(full,fEmittanceH[ib],opts);\r
+ }\r
+ //\r
+ for (int ib=0;ib<2;ib++) {\r
+ printf("* Beam%d Vertical emittance ",ib+1);\r
+ PrintAux(full,fEmittanceV[ib],opts);\r
+ }\r
+ //\r
+ for (int ib=0;ib<2;ib++) {\r
+ printf("* Beam%d Horisontal sigma ",ib+1);\r
+ PrintAux(full,fBeamSigmaH[ib],opts);\r
+ }\r
+ //\r
+ for (int ib=0;ib<2;ib++) {\r
+ printf("* Beam%d Vertical sigma ",ib+1);\r
+ PrintAux(full,fBeamSigmaV[ib],opts);\r
+ }\r
+ //\r
+ for (int lr=0;lr<2;lr++) {\r
+ printf("* Total luminosity from BRANB_4%c2 ",lr ? 'R':'L');\r
+ PrintAux(full,fLuminTotal[lr],opts);\r
+ } \r
+ //\r
+ for (int lr=0;lr<2;lr++) {\r
+ printf("* Luminosity acq.mode, BRANB_4%c2 ",lr ? 'R':'L');\r
+ PrintAux(full,fLuminAcqMode[lr],opts+"bit");\r
+ } \r
+ //\r
+ for (int lr=0;lr<2;lr++) {\r
+ printf("* Luminosity per BC from BRANB_4%c2 ",lr ? 'R':'L');\r
+ PrintAux(full,fLuminPerBC[lr],opts);\r
+ }\r
+ //\r
+ for (int lr=0;lr<2;lr++) {\r
+ printf("* Crossing angle, side %c ",lr ? 'R':'L');\r
+ PrintAux(full,fCrossAngle[lr],opts);\r
+ }\r
+ //\r
+ for (int coll=0;coll<kNCollimators;coll++)\r
+ for (int jaw=0;jaw<kNJaws;jaw++) {\r
+ printf("* Collimator %10s:%16s",fgkDCSColNames[coll],fgkDCSColJaws[jaw]);\r
+ PrintAux(full,fCollimators[coll][jaw],opts);\r
+ }\r
+ //\r
+}\r
+\r
+//___________________________________________________________________\r
+void AliLHCData::PrintAux(Bool_t full, const Int_t refs[2], const Option_t *opt) const\r
+{\r
+ // aux method to print the reocrds of the same type\r
+ int nrec = refs[kNStor];\r
+ if (nrec<1) {\r
+ printf(": N/A\n"); \r
+ return;\r
+ }\r
+ printf(": (%3d):\t",nrec); // number of records\r
+ if (!full) nrec = 1;\r
+ int sz = ((AliLHCDipValI*)fData[refs[kStart]])->GetSizeTotal(); // dimension of the record\r
+ Bool_t isStr = ((AliLHCDipValI*)fData[refs[kStart]])->IsTypeC();\r
+ if ((!isStr && sz>2) || nrec>1) printf("\n"); // long record, open new line\r
+ for (int i=0;i<nrec;i++) fData[refs[kStart]+i]->Print(opt);\r
+ //\r
+}\r
+\r
+//___________________________________________________________________\r
+void AliLHCData::Clear(const Option_t *)\r
+{\r
+ // clear all info\r
+ fData.Delete();\r
+ fFillNumber = 0;\r
+ fTMin = 0;\r
+ fTMax = 1e10;\r
+ fFile2Process = 0;\r
+ fMap2Process = 0;\r
+ //\r
+ for (int i=2;i--;) {\r
+ fRCInjScheme[i] = 0;\r
+ fRCBeta[i] = 0;\r
+ fRCAngH[i] = 0;\r
+ fRCAngV[i] = 0;\r
+ //\r
+ for (int icl=kNCollimators;icl--;) for (int jaw=kNJaws;jaw--;) fCollimators[icl][jaw][i]=0;\r
+ //\r
+ for (int j=2;j--;) {\r
+ fBunchConfDecl[j][i] = 0;\r
+ fBunchConfMeas[j][i] = 0;\r
+ fBunchLengths[j][i] = 0;\r
+ fIntensTotal[j][i] = 0;\r
+ fIntensTotalAv[j][i] = 0;\r
+ fIntensPerBunch[j][i] = 0; \r
+ fCrossAngle[j][i] = 0;\r
+ fEmittanceH[j][i] = 0;\r
+ fEmittanceV[j][i] = 0;\r
+ fBeamSigmaH[j][i] = 0;\r
+ fBeamSigmaV[j][i] = 0;\r
+ fLuminTotal[j][i] = 0;\r
+ fLuminPerBC[j][i] = 0;\r
+ fLuminAcqMode[j][i] = 0;\r
+ }\r
+ }\r
+}\r
+\r
+//___________________________________________________________________\r
+Int_t AliLHCData::GetNInteractingBunchesMeasured(int i) const\r
+{\r
+ // get number of interacting bunches at IR2\r
+ AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r
+ if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
+ if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1;}\r
+ int n = 0;\r
+ for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;\r
+ return n;\r
+}\r
+\r
+//___________________________________________________________________\r
+Int_t AliLHCData::GetNInteractingBunchesDeclared(int i) const\r
+{\r
+ // get number of interacting bunches at IR2\r
+ AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r
+ if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
+ if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1; }\r
+ int n = 0;\r
+ for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;\r
+ return n;\r
+}\r
+\r
+//___________________________________________________________________\r
+Int_t AliLHCData::IsPilotPresent(int i) const\r
+{\r
+ // check in the filling scheme is the pilot bunch is present\r
+ AliLHCDipValC* rec = GetInjectionScheme();\r
+ if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
+ TString scheme = rec->GetValues();\r
+ return scheme.Contains("wp",TString::kIgnoreCase);\r
+}\r
+\r
+//___________________________________________________________________\r
+void AliLHCData::FlagInteractingBunches(const Int_t beam1[2],const Int_t beam2[2])\r
+{\r
+ // assign - sign to interacting bunches\r
+ const int kMaxSlots = 3564;\r
+ const int kOffsBeam1 = 346;\r
+ const int kOffsBeam2 = 3019;\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 = (bunch1/10 + kOffsBeam1)%kMaxSlots;\r
+ for (i2=0;i2<nb2;i2++) {\r
+ bunch2 = TMath::Abs((*bm2)[i2]);\r
+ slot2 = (bunch2/10 + kOffsBeam2)%kMaxSlots;\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\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
+ 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
+ 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
+ AliLHCDipValF* rInt = GetIntensityPerBunch(beamID,irec);\r
+ for (int ib=0;ib<nb;ib++) {\r
+ double val = rInt->GetValue(ib);\r
+ if (val<0) continue;\r
+ int bID = conf->GetValue(ib);\r
+ if (bID<0) colliding += val;\r
+ else noncolliding += val;\r
+ }\r
+ }\r
+ colliding /= nrec;\r
+ noncolliding /= nrec;\r
+ return nrec;\r
+}\r