1 /**************************************************************************
\r
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
\r
4 * Author: The ALICE Off-line Project. *
\r
5 * Contributors are mentioned in the code where appropriate. *
\r
7 * Permission to use, copy, modify and distribute this software and its *
\r
8 * documentation strictly for non-commercial purposes is hereby granted *
\r
9 * without fee, provided that the above copyright notice appears in all *
\r
10 * copies and that both the copyright notice and this permission notice *
\r
11 * appear in the supporting documentation. The authors make no claims *
\r
12 * about the suitability of this software for any purpose. It is *
\r
13 * provided "as is" without express or implied warranty. *
\r
15 **************************************************************************/
\r
17 /********************************************************************************
\r
19 * AliLHCData: summary of the LHC related information from LHC DIP. *
\r
20 * Created from the TMap provided by the AliLHCReader with optional beginning *
\r
22 * The data are (wrapped in the AliLHCDipValT): *
\r
23 * made of TimeStamp (double) and array of values *
\r
25 * Multiple entries for each type of data are possible. To obtaine number of *
\r
26 * records (with distinct timestamp) for give type od records use: *
\r
27 * int GetNBunchConfigMeasured(int beam) (with beam=0,1) etc. *
\r
29 * To get i-th entry, use brec= AliLHCDipValI* GetBunchConfigMeasured(bm,i); *
\r
30 * Note: exact type of templated AliLHCDipValT pointer depends on the record *
\r
31 * type, concult getters to know it. *
\r
33 * Then, once the pointer is obtained, details can be accessed: *
\r
34 * int nBunches = brec->GetSize(); *
\r
35 * for (int i=0;i<nBunches;i++) printf("Bunch#%d: %d\n",i,(*brec)[i]); *
\r
38 * Author: ruben.shahoyan@cern.ch *
\r
40 ********************************************************************************/
\r
42 #include "AliLHCData.h"
\r
44 #include "AliDCSArray.h"
\r
45 #include "AliLHCReader.h"
\r
46 #include "AliTriggerBCMask.h"
\r
47 #include <TString.h>
\r
48 #include <TObjArray.h>
\r
50 ClassImp(AliLHCData)
\r
52 const Char_t* AliLHCData::fgkDCSNames[] = {
\r
53 "LHC_IntensityBeam%1d_totalIntensity",
\r
54 "LHC_BeamIntensityPerBunchBeam%1d_averageBeamIntensity",
\r
55 "LHC_BeamIntensityPerBunchBeam%1d_Average_BunchIntensities",
\r
57 "LHC_LumAverageBRANB_4%c2_acqMode",
\r
58 "LHC_LumAverageBRANB_4%c2_meanLuminosity",
\r
59 "LHC_LumAverageBRANB_4%c2_meanLuminosityError",
\r
60 "LHC_BeamLuminosityPerBunchBRANB_4%c2_Average_BunchLuminosity",
\r
61 "LHC_BeamLuminosityPerBunchBRANB_4%c2_BunchLuminosityError",
\r
62 "LHC_LumAverageBRANB_4%c2_meanCrossingAngle",
\r
63 "LHC_LumAverageBRANB_4%c2_meanCrossingAngleError",
\r
64 "LHC_CirculatingBunchConfig_Beam%d",
\r
67 "LHC_BunchLengthBeam%1d_nBunches",
\r
68 "LHC_BunchLengthBeam%1d_bunchesLenghts",
\r
69 "LHC_BunchLengthBeam%1d_filledBuckets",
\r
71 "LHC_RunControl_ActiveInjectionScheme",
\r
72 "LHC_RunControl_BetaStar",
\r
73 "LHC_RunControl_IP2_Xing_Murad",
\r
74 "LHC_RunControl_IP2_ALICE_Murad",
\r
76 "LHC_BeamSizeBeam%1d_acqMode",
\r
77 "LHC_BeamSizeBeam%1d_sigmaH",
\r
78 "LHC_BeamSizeBeam%1d_sigmaV",
\r
79 "LHC_BeamSizeBeam%1d_emittanceH",
\r
80 "LHC_BeamSizeBeam%1d_emittanceV",
\r
81 "LHC_BeamSizeBeam%1d_errorSigmaH",
\r
82 "LHC_BeamSizeBeam%1d_errorSigmaV",
\r
84 "LHC_CollimatorPos_%s_lvdt_%s"
\r
87 const Char_t* AliLHCData::fgkDCSColNames[] = {
\r
93 const Char_t* AliLHCData::fgkDCSColJaws[] = {
\r
94 "gap_downstream","gap_upstream","left_downstream",
\r
95 "left_upstream","right_downstream","right_upstream"};
\r
97 //___________________________________________________________________
\r
98 AliLHCData::AliLHCData(const TMap* dcsMap, double tmin, double tmax)
\r
99 : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fkFile2Process(0),fkMap2Process(0)
\r
101 FillData(dcsMap,tmin,tmax);
\r
104 //___________________________________________________________________
\r
105 AliLHCData::AliLHCData(const Char_t* dcsFile, double tmin, double tmax)
\r
106 : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fkFile2Process(dcsFile),fkMap2Process(0)
\r
108 FillData(dcsFile,tmin,tmax);
\r
111 //___________________________________________________________________
\r
112 Bool_t AliLHCData::FillData(const TMap* dcsMap,double tmin, double tmax)
\r
114 // process DCS map and fill all fields.
\r
116 fkMap2Process = dcsMap;
\r
117 FillData(tmin,tmax);
\r
121 //___________________________________________________________________
\r
122 Bool_t AliLHCData::FillData(const Char_t* dcsFile,double tmin, double tmax)
\r
124 // process DCS file and fill all fields.
\r
126 fkFile2Process = dcsFile;
\r
127 FillData(tmin,tmax);
\r
131 //___________________________________________________________________
\r
132 Bool_t AliLHCData::FillData(double tmin, double tmax)
\r
134 // process DCS map and fill all fields.
\r
135 // Accept only entries with timestamp between tmin and tmax
\r
137 char buff[100],buff1[100];
\r
142 // -------------------------- extract Fill Number
\r
143 int iFirst=0,iLast=0;
\r
144 TObjArray* arr = GetDCSEntry(fgkDCSNames[kFillNum],iFirst,iLast,fTMin,fTMax);
\r
145 if (arr) SetFillNumber( ExtractInt( (AliDCSArray*)arr->At(iFirst), 0) );
\r
146 if (fkFile2Process) delete arr; // array was created on demand
\r
148 for (int ibm=0;ibm<2;ibm++) {
\r
150 snprintf(buff,99,fgkDCSNames[kBunchConf],ibm+1); // ----- declared bunch configuration
\r
151 FillBunchConfig(fBunchConfDecl[ibm], buff);
\r
153 snprintf(buff,99,fgkDCSNames[kBunchLgtFillB],ibm+1); // ----- measured bunch configuration
\r
154 FillBunchConfig(fBunchConfMeas[ibm], buff);
\r
156 snprintf(buff,99,fgkDCSNames[kBunchLgt],ibm+1); // ----- measured bunch lenghts
\r
157 FillBunchInfo(fBunchLengths[ibm],buff,ibm,kFALSE);
\r
159 snprintf(buff,99,fgkDCSNames[kIntBunchAv],ibm+1); // ----- B-by-B intensities
\r
160 FillBunchInfo(fIntensPerBunch[ibm],buff,ibm,kTRUE);
\r
163 snprintf(buff,99,fgkDCSNames[kIntTot],ibm+1); // ----- total intensities for beam 1 and 2
\r
164 FillScalarRecord(fIntensTotal[ibm], buff);
\r
166 snprintf(buff,99,fgkDCSNames[kIntTotAv],ibm+1); // ----- total intensities for beam 1 and 2 from B-by-B average
\r
167 FillScalarRecord(fIntensTotalAv[ibm], buff);
\r
169 snprintf(buff,99,fgkDCSNames[kBeamSzEmittH],ibm+1); // ----- H emittance for beam 1 and 2
\r
170 FillScalarRecord(fEmittanceH[ibm], buff);
\r
172 snprintf(buff,99,fgkDCSNames[kBeamSzEmittV],ibm+1); // ----- V emittance for beam 1 and 2
\r
173 FillScalarRecord(fEmittanceV[ibm], buff);
\r
175 snprintf(buff,99 ,fgkDCSNames[kBeamSzSigH], ibm+1); // ----- H sigmas and errors for beam 1 and 2
\r
176 snprintf(buff1,99,fgkDCSNames[kBeamSzSigHErr],ibm+1);
\r
177 FillScalarRecord(fBeamSigmaH[ibm], buff, buff1);
\r
179 snprintf(buff,99 ,fgkDCSNames[kBeamSzSigV], ibm+1); // ----- V sigmas and errors for beam 1 and 2
\r
180 snprintf(buff1,99,fgkDCSNames[kBeamSzSigVErr],ibm+1);
\r
181 FillScalarRecord(fBeamSigmaV[ibm], buff, buff1);
\r
185 FlagInteractingBunches(fBunchConfMeas[0],fBunchConfMeas[1]);
\r
186 FlagInteractingBunches(fBunchConfDecl[0],fBunchConfDecl[1]);
\r
188 for (int ilr=0;ilr<2;ilr++) {
\r
190 snprintf(buff,99 ,fgkDCSNames[kLumBunch], ilr ? 'R':'L'); // ---- BC-by-BC luminosity at IP2 and its error
\r
191 snprintf(buff1,99,fgkDCSNames[kLumBunchErr], ilr ? 'R':'L');
\r
192 FillBCLuminosities(fLuminPerBC[ilr], buff, buff1, 0); // BRAN L uses beam2 as a reference, BRAN R - beam1
\r
194 snprintf(buff,99 ,fgkDCSNames[kLumTot] , ilr ? 'R':'L'); // ---- total luminosity at IP2 and its error
\r
195 snprintf(buff1,99,fgkDCSNames[kLumTotErr], ilr ? 'R':'L');
\r
196 FillScalarRecord(fLuminTotal[ilr], buff, buff1);
\r
198 snprintf(buff,99 ,fgkDCSNames[kLumAcqMode], ilr ? 'R':'L'); // ---- luminosity acquisition mode
\r
199 FillAcqMode(fLuminAcqMode[ilr], buff);
\r
201 snprintf(buff,99, fgkDCSNames[kLumCrossAng] , ilr ? 'R':'L'); //----- crossing angle at IP2 and its error
\r
202 snprintf(buff1,99,fgkDCSNames[kLumCrossAngErr], ilr ? 'R':'L');
\r
203 FillScalarRecord(fCrossAngle[ilr], buff, buff1);
\r
207 for (int icl=0;icl<kNCollimators;icl++) { // ----- collimators positions
\r
208 for (int jaw=0;jaw<kNJaws;jaw++) {
\r
209 snprintf(buff,99,fgkDCSNames[kCollPos], fgkDCSColNames[icl],fgkDCSColJaws[jaw]);
\r
210 FillScalarRecord(fCollimators[icl][jaw], buff);
\r
216 FillStringRecord(fRCInjScheme, fgkDCSNames[kRCInjSch]); // ---- active injection scheme
\r
217 FillScalarRecord(fRCBeta, fgkDCSNames[kRCBeta]); // ---- target beta
\r
218 FillScalarRecord(fRCAngH, fgkDCSNames[kRCCrossAng]); // ---- horisontal angle
\r
219 FillScalarRecord(fRCAngV,fgkDCSNames[kRCVang] ); // ---- vertical angle
\r
224 //___________________________________________________________________
\r
225 TObjArray* AliLHCData::GetDCSEntry(const char* key,int &entry,int &last,double tmin,double tmax) const
\r
227 // extract array from the DCS map or file and find the first entry within the time limits
\r
231 if (fkMap2Process) arr = (TObjArray*)fkMap2Process->GetValue(key);
\r
232 else if (fkFile2Process) {
\r
234 arr = rd.ReadSingleLHCDP(fkFile2Process,key);
\r
237 AliError("Neither DCS map nor DCS filename are set");
\r
241 if (!arr || !arr->GetEntriesFast()) {
\r
242 AliWarning(Form("No data for %s",key));
\r
243 if (fkMap2Process) delete arr; // created on demand
\r
246 int ntot = arr->GetEntriesFast();
\r
248 // search 1st entry before or at tmin
\r
249 AliDCSArray* ent = 0;
\r
250 Bool_t found = kFALSE;
\r
251 for (entry=0;entry<ntot;entry++) {
\r
252 ent = (AliDCSArray*)arr->At(entry);
\r
253 if (ent->GetTimeStamp()>=tmin-kMarginSOR && ent->GetTimeStamp()<=tmax+kMarginEOR) {
\r
255 if (ent->GetTimeStamp()>tmin) break;
\r
261 str += AliLHCDipValD::TimeAsString(tmin);
\r
263 str += AliLHCDipValD::TimeAsString(tmax);
\r
264 AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));
\r
265 if (fkMap2Process) delete arr; // created on demand
\r
268 if (entry>0) entry--;
\r
270 // search last entry at or after tmin
\r
272 for (last=entry;last<ntot;last++) {
\r
273 ent = (AliDCSArray*)arr->At(last);
\r
274 if (ent->GetTimeStamp()>tmax) break;
\r
276 if (last == ntot) last--;
\r
277 else if (ent->GetTimeStamp()>tmax+kMarginEOR) last--;
\r
282 //___________________________________________________________________
\r
283 Int_t AliLHCData::TimeDifference(double v1,double v2,double tol) const
\r
285 // return 0 if the times are the same within the tolerance
\r
289 if (v1>tol) return 1;
\r
290 if (v1<-tol) return -1;
\r
294 //___________________________________________________________________
\r
295 Bool_t AliLHCData::GoodPairID(int beam) const
\r
297 // check for correct beam identifier
\r
298 if (beam>kBeam2||beam<0) {AliError(Form("BeamID can be 0 or 1, %d requested",beam)); return kFALSE;}
\r
302 //___________________________________________________________________
\r
303 AliLHCDipValI* AliLHCData::GetBunchConfigMeasured(int beam,double tstamp) const
\r
305 // find measured bunch configuration valid for given tstamp
\r
306 if (!GoodPairID(beam)) return 0;
\r
307 return (AliLHCDipValI*)FindRecValidFor(fBunchConfMeas[beam][kStart],fBunchConfMeas[beam][kNStor],tstamp);
\r
310 //___________________________________________________________________
\r
311 AliLHCDipValI* AliLHCData::GetBunchConfigDeclared(int beam,double tstamp) const
\r
313 // find declared bunch configuration valid for given tstamp
\r
314 if (!GoodPairID(beam)) return 0;
\r
315 return (AliLHCDipValI*)FindRecValidFor(fBunchConfDecl[beam][kStart],fBunchConfDecl[beam][kNStor],tstamp);
\r
318 //___________________________________________________________________
\r
319 TObject* AliLHCData::FindRecValidFor(int start,int nrec, double tstamp) const
\r
321 // find record within this limits valid for given tstamp (i.e. the last one before or equal to tstamp)
\r
322 AliLHCDipValI *prevObj = 0;
\r
323 for (int i=0;i<nrec;i++) {
\r
324 AliLHCDipValI* curObj = (AliLHCDipValI*)fData[start+i];
\r
325 if (TimeDifference(tstamp,curObj->GetTimeStamp())<0) break;
\r
328 if (!prevObj && nrec>0) prevObj = (AliLHCDipValI*)fData[start]; // if no exact match, return the 1st one
\r
332 //___________________________________________________________________
\r
333 Int_t AliLHCData::FillScalarRecord(int refs[2], const char* rec, const char* recErr)
\r
335 // fill record for scalar value, optionally accompanied by measurement error
\r
337 AliInfo(Form("Acquiring record: %s",rec));
\r
339 TObjArray *arr=0,*arrE=0;
\r
340 Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;
\r
342 refs[kStart] = fData.GetEntriesFast();
\r
345 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
\r
349 arrE = GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);
\r
353 // Bool_t last = kFALSE;
\r
354 while (iFirst<=iLast) {
\r
355 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
\r
356 double tstamp = dcsVal->GetTimeStamp();
\r
358 AliLHCDipValF* curValF = new AliLHCDipValF(dim,tstamp); // start new period
\r
359 (*curValF)[0] = ExtractDouble(dcsVal,0); // value
\r
362 double errVal = -1;
\r
363 while (iFirstE<=iLastE) { // try to find corresponding error
\r
364 AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);
\r
365 double tstampE = dcsValE->GetTimeStamp();
\r
366 int tdif = TimeDifference(tstamp,tstampE);
\r
367 if (!tdif) { // error matches to value
\r
368 errVal = ExtractDouble(dcsValE,0);
\r
372 else if (tdif>0) iFirstE++; // error time lags behind, read the next one
\r
373 else break; // error time is ahead of value, no error associated
\r
375 (*curValF)[dim-1] = errVal; // error
\r
376 curValF->SetLastSpecial(); // lable the last entry as an error
\r
379 fData.Add(curValF);
\r
381 // if (last) break;
\r
384 if (fkFile2Process) {
\r
388 return refs[kNStor];
\r
391 //___________________________________________________________________
\r
392 Int_t AliLHCData::FillBunchConfig(int refs[2],const char* rec)
\r
394 // fill record for bunch configuration
\r
396 AliInfo(Form("Acquiring record: %s",rec));
\r
398 Int_t iLast,iFirst;
\r
400 refs[kStart] = fData.GetEntriesFast();
\r
403 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
\r
405 AliLHCDipValI* prevRecI=0;
\r
407 while (iFirst<=iLast) {
\r
408 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
\r
409 double tstamp = dcsVal->GetTimeStamp();
\r
411 int bucket=0, nbunch=0, ndiff=0;
\r
412 int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)
\r
413 int* dcsArr = dcsVal->GetInt();
\r
414 while(nbunch<nSlots && (bucket=dcsArr[nbunch])) {
\r
415 if (prevRecI && prevRecI->GetSize()>nbunch && bucket!=prevRecI->GetValue(nbunch)) ndiff++;
\r
418 if (!nbunch) AliWarning(Form("%s record is present but empty: no beam?",rec));
\r
419 if (prevRecI && !ndiff && nbunch==prevRecI->GetSize()) continue; // record similar to previous one
\r
420 AliLHCDipValI* curValI = new AliLHCDipValI(nbunch,tstamp);
\r
421 for (int i=nbunch;i--;) (*curValI)[i] = dcsArr[i];
\r
422 fData.Add(curValI);
\r
424 prevRecI = curValI;
\r
427 if (fkFile2Process) delete arr;
\r
428 return refs[kNStor];
\r
431 //___________________________________________________________________
\r
432 Int_t AliLHCData::FillAcqMode(int refs[2],const char* rec)
\r
434 // fill acquisition mode
\r
436 AliInfo(Form("Acquiring record: %s",rec));
\r
438 Int_t iLast,iFirst;
\r
440 refs[kStart] = fData.GetEntriesFast();
\r
443 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
\r
445 AliLHCDipValI* prevRecI=0;
\r
446 while (iFirst<=iLast) {
\r
447 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
\r
448 double tstamp = dcsVal->GetTimeStamp();
\r
450 int nSlots = dcsVal->GetNEntries();
\r
451 if (nSlots<1) continue;
\r
452 int acqMode = dcsVal->GetInt()[0];
\r
453 if (prevRecI && (*prevRecI)[0] == acqMode) continue; // record similar to previous one
\r
454 AliLHCDipValI* curValI = new AliLHCDipValI(1,tstamp);
\r
455 (*curValI)[0] = acqMode;
\r
456 fData.Add(curValI);
\r
458 prevRecI = curValI;
\r
461 if (fkFile2Process) delete arr;
\r
462 return refs[kNStor];
\r
465 //___________________________________________________________________
\r
466 Int_t AliLHCData::FillStringRecord(int refs[2],const char* rec)
\r
468 // fill record with string value
\r
470 AliInfo(Form("Acquiring record: %s",rec));
\r
473 Int_t iLast,iFirst;
\r
475 refs[kStart] = fData.GetEntriesFast();
\r
478 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
\r
480 while (iFirst<=iLast) {
\r
481 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
\r
482 double tstamp = dcsVal->GetTimeStamp();
\r
484 TString &str = ExtractString(dcsVal);
\r
485 if (!prevRec.IsNull()) {if (str == prevRec) continue;} // skip similar record
\r
486 else prevRec = str;
\r
488 AliLHCDipValC* curValS = new AliLHCDipValC(1,tstamp);
\r
489 curValS->SetValues(str.Data(),str.Length()+1);
\r
491 fData.Add(curValS);
\r
494 if (fkFile2Process) delete arr;
\r
495 return refs[kNStor];
\r
498 //___________________________________________________________________
\r
499 Int_t AliLHCData::FillBunchInfo(int refs[2],const char* rec, int ibm, Bool_t inRealSlots)
\r
501 // fill bunch properties for beam ibm
\r
502 // if inRealSlots = true, then the value is taken from bunchRFbucket/10, otherwise, the value
\r
503 // for the i-th bunch is taken from the i-th element
\r
505 AliInfo(Form("Acquiring record: %s",rec));
\r
507 Int_t iLast,iFirst;
\r
509 refs[kStart] = fData.GetEntriesFast();
\r
512 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
\r
514 while (iFirst<=iLast) {
\r
515 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
\r
516 double tstamp = dcsVal->GetTimeStamp();
\r
518 AliLHCDipValI *bconf = GetBunchConfigMeasured(ibm,tstamp);
\r
520 AliWarning(Form("Mearured bunch configuration for beam %d at t=%.1f is not available, trying declared one",ibm+1,tstamp));
\r
521 bconf = GetBunchConfigDeclared(ibm,tstamp);
\r
524 AliWarning(Form("Declared bunch configuration for beam %d at t=%.1f is not available, skip this record",ibm+1,tstamp));
\r
527 int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)
\r
528 int nbunch = bconf->GetSize();
\r
529 if (nbunch>nSlots) {
\r
530 AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));
\r
533 double* dcsArr = dcsVal->GetDouble();
\r
534 AliLHCDipValF* curValF = new AliLHCDipValF(nbunch,tstamp);
\r
535 for (int i=nbunch;i--;) {
\r
536 int ind = inRealSlots ? (*bconf)[i]/10 : i;
\r
538 AliError(Form("Bunch %d refers to wrong slot %d, set to -1",i,(*bconf)[i]));
\r
539 (*curValF)[i] = -1;
\r
541 else (*curValF)[i] = dcsArr[ind];
\r
543 fData.Add(curValF);
\r
546 if (fkFile2Process) delete arr;
\r
547 return refs[kNStor];
\r
551 //___________________________________________________________________
\r
552 Int_t AliLHCData::FillBCLuminosities(int refs[2],const char* rec, const char* recErr, int useBeam)
\r
554 // fill luminosities per bunch crossing
\r
556 AliInfo(Form("Acquiring record: %s",rec));
\r
557 TObjArray *arr,*arrE=0;
\r
558 Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;
\r
560 refs[kStart] = fData.GetEntriesFast();
\r
563 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
\r
565 while (iFirst<=iLast) {
\r
566 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
\r
567 double tstamp = dcsVal->GetTimeStamp();
\r
569 AliLHCDipValI *bconf;
\r
570 bconf = GetBunchConfigMeasured(useBeam,tstamp); // luminosities are stored according to beam bunches
\r
572 AliWarning(Form("Mearured bunch configuration for beam%d at t=%.1f is not available, trying declared one",useBeam,tstamp));
\r
573 bconf = GetBunchConfigDeclared(useBeam,tstamp);
\r
576 AliWarning(Form("Declared bunch configuration for beam%i at t=%.1f is not available, skip this record",useBeam,tstamp));
\r
579 int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)
\r
580 int nbunch = bconf->GetSize();
\r
581 double* dcsArr = dcsVal->GetDouble();
\r
583 if (nbunch>nSlots) {
\r
584 AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));
\r
588 if (!bconf->IsProcessed1()) {
\r
589 AliWarning(Form("Bunch conf. for beam%d has no marked interacting bunches, store all luminosity for all filled bunches",useBeam));
\r
592 else { // count number of interacting bunches
\r
593 for (int i=nbunch;i--;) if ((*bconf)[i]<0) dim++;
\r
597 arrE=GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);
\r
600 AliLHCDipValF* curValF = new AliLHCDipValF(dim,tstamp);
\r
602 for (int i=0;i<nbunch;i++) {
\r
603 int slot = (*bconf)[i];
\r
604 if (bconf->IsProcessed1() && slot>0) continue;
\r
606 int ind = TMath::Abs(slot)/10;
\r
608 AliError(Form("Bunch %d refers to wrong slot %d, set to -1",cnt,slot));
\r
609 (*curValF)[cnt] = -1;
\r
611 else (*curValF)[cnt] = dcsArr[ind];
\r
616 double errVal = -1;
\r
617 while (iFirstE<=iLastE) { // try to find corresponding error
\r
618 AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);
\r
619 double tstamp1 = dcsValE->GetTimeStamp();
\r
620 int tdif = TimeDifference(tstamp,tstamp1);
\r
621 if (!tdif) { // error matches to value
\r
622 errVal = dcsValE->GetDouble()[0];
\r
626 else if (tdif>0) iFirstE++; // error time lags behind, read the next one
\r
627 else break; // error time is ahead of value, no error associated
\r
629 (*curValF)[dim-1] = errVal; // error
\r
630 curValF->SetLastSpecial(); // lable the last entry as an error
\r
633 fData.Add(curValF);
\r
636 if (fkFile2Process) {
\r
640 return refs[kNStor];
\r
644 //___________________________________________________________________
\r
645 Int_t AliLHCData::ExtractInt(AliDCSArray* dcsArray,Int_t el) const
\r
647 // extract integer from the dcsArray
\r
650 int sz = dcsArray->GetNEntries();
\r
651 if (sz<=el) return val;
\r
653 if (dcsArray->GetType()==AliDCSArray::kInt) val = dcsArray->GetInt(el);
\r
654 else if (dcsArray->GetType()==AliDCSArray::kString) {
\r
655 TObjString *stro = dcsArray->GetStringArray(el);
\r
656 if (stro) val = stro->GetString().Atoi();
\r
657 else AliError(Form("DCSArray TObjString for element %d is missing",el));
\r
659 else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);
\r
660 else AliError(Form("Integer requested from DCSArray of type %d",dcsArray->GetType()));
\r
664 //___________________________________________________________________
\r
665 Double_t AliLHCData::ExtractDouble(AliDCSArray* dcsArray,Int_t el) const
\r
667 // extract double from the dcsArray
\r
670 int sz = dcsArray->GetNEntries();
\r
671 if (sz<=el) return val;
\r
673 if (dcsArray->GetType()==AliDCSArray::kDouble) val = dcsArray->GetDouble(el);
\r
674 else if (dcsArray->GetType()==AliDCSArray::kFloat) val = dcsArray->GetFloat(el);
\r
675 else if (dcsArray->GetType()==AliDCSArray::kString) {
\r
676 TObjString *stro = dcsArray->GetStringArray(el);
\r
677 if (stro) val = stro->GetString().Atof();
\r
678 else AliError(Form("DCSArray has TObjString for element %d is missing",el));
\r
680 else if (dcsArray->GetType()==AliDCSArray::kChar) val = dcsArray->GetChar(el);
\r
681 else if (dcsArray->GetType()==AliDCSArray::kInt) val = dcsArray->GetInt(el);
\r
682 else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);
\r
683 else AliError(Form("Double requested from DCSArray of type %d",dcsArray->GetType()));
\r
687 //___________________________________________________________________
\r
688 TString& AliLHCData::ExtractString(AliDCSArray* dcsArray) const
\r
690 // extract string from the dcsArray
\r
691 static TString str;
\r
694 int sz = dcsArray->GetNEntries();
\r
695 if (dcsArray->GetType()!=AliDCSArray::kString) {
\r
696 AliError(Form("String requested from DCSArray of type %d",dcsArray->GetType()));
\r
700 for (int i=0;i<sz;i++) {
\r
701 str += dcsArray->GetStringArray(i)->GetString();
\r
702 if (i<sz-1) str += " ";
\r
707 //___________________________________________________________________
\r
708 void AliLHCData::Print(const Option_t* opt) const
\r
711 TString opts = opt;
\r
713 Bool_t utcTime = opts.Contains("loc") ? kFALSE:kTRUE;
\r
714 Bool_t full = kTRUE;
\r
715 if (!opts.Contains("f")) {
\r
716 printf("Use Print(\"f\") to print full info\n");
\r
717 printf("Printing short info:\n<RecordType>(number of records): <TimeStamp, value> for 1st record only\n");
\r
720 TString sdtmn = AliLHCDipValI::TimeAsString(fTMin,utcTime);
\r
721 TString sdtmx = AliLHCDipValI::TimeAsString(fTMax,utcTime);
\r
722 printf("Fill#%6d Validity: %s - %s (%s)\n",fFillNumber,sdtmn.Data(),sdtmx.Data(),utcTime ? "UTC":"LOC");
\r
724 printf("********** SETTINGS FROM RUN CONTROL **********\n");
\r
726 printf("* %-38s","Injection Scheme");
\r
727 PrintAux(full,fRCInjScheme,opts);
\r
729 printf("* %-38s","Beta Star");
\r
730 PrintAux(full,fRCBeta,opts);
\r
732 printf("* %-38s","Horisontal Crossing Angle");
\r
733 PrintAux(full,fRCAngH,opts);
\r
735 printf("* %-38s","Vertical Crossing Angle");
\r
736 PrintAux(full,fRCAngV,opts);
\r
738 for (int ib=0;ib<2;ib++) {
\r
739 printf("* Beam%d filling [- interacts at IR2!] ",ib+1);
\r
740 PrintAux(full,fBunchConfDecl[ib],opts);
\r
743 printf("\n********** MEASURED DATA **********\n");
\r
745 for (int ib=0;ib<2;ib++) {
\r
746 printf("* Beam%d filling [- interacts at IR2!] ",ib+1);
\r
747 PrintAux(full,fBunchConfMeas[ib],opts);
\r
750 for (int ib=0;ib<2;ib++) {
\r
751 printf("* Beam%d total intensity ",ib+1);
\r
752 PrintAux(full,fIntensTotal[ib],opts);
\r
755 for (int ib=0;ib<2;ib++) {
\r
756 printf("* Beam%d total intensity (bunch average) ",ib+1);
\r
757 PrintAux(full,fIntensTotalAv[ib],opts);
\r
760 for (int ib=0;ib<2;ib++) {
\r
761 printf("* Beam%d intensity per bunch ",ib+1);
\r
762 PrintAux(full,fIntensPerBunch[ib],opts);
\r
765 for (int ib=0;ib<2;ib++) {
\r
766 printf("* Beam%d bunch lengths ",ib+1);
\r
767 PrintAux(full,fBunchLengths[ib],opts);
\r
770 for (int ib=0;ib<2;ib++) {
\r
771 printf("* Beam%d Horisontal emittance ",ib+1);
\r
772 PrintAux(full,fEmittanceH[ib],opts);
\r
775 for (int ib=0;ib<2;ib++) {
\r
776 printf("* Beam%d Vertical emittance ",ib+1);
\r
777 PrintAux(full,fEmittanceV[ib],opts);
\r
780 for (int ib=0;ib<2;ib++) {
\r
781 printf("* Beam%d Horisontal sigma ",ib+1);
\r
782 PrintAux(full,fBeamSigmaH[ib],opts);
\r
785 for (int ib=0;ib<2;ib++) {
\r
786 printf("* Beam%d Vertical sigma ",ib+1);
\r
787 PrintAux(full,fBeamSigmaV[ib],opts);
\r
790 for (int lr=0;lr<2;lr++) {
\r
791 printf("* Total luminosity from BRANB_4%c2 ",lr ? 'R':'L');
\r
792 PrintAux(full,fLuminTotal[lr],opts);
\r
795 for (int lr=0;lr<2;lr++) {
\r
796 printf("* Luminosity acq.mode, BRANB_4%c2 ",lr ? 'R':'L');
\r
797 PrintAux(full,fLuminAcqMode[lr],opts+"bit");
\r
800 for (int lr=0;lr<2;lr++) {
\r
801 printf("* Luminosity per BC from BRANB_4%c2 ",lr ? 'R':'L');
\r
802 PrintAux(full,fLuminPerBC[lr],opts);
\r
805 for (int lr=0;lr<2;lr++) {
\r
806 printf("* Crossing angle, side %c ",lr ? 'R':'L');
\r
807 PrintAux(full,fCrossAngle[lr],opts);
\r
810 for (int coll=0;coll<kNCollimators;coll++)
\r
811 for (int jaw=0;jaw<kNJaws;jaw++) {
\r
812 printf("* Collimator %10s:%16s",fgkDCSColNames[coll],fgkDCSColJaws[jaw]);
\r
813 PrintAux(full,fCollimators[coll][jaw],opts);
\r
818 //___________________________________________________________________
\r
819 void AliLHCData::PrintAux(Bool_t full, const Int_t refs[2], const Option_t *opt) const
\r
821 // aux method to print the reocrds of the same type
\r
822 int nrec = refs[kNStor];
\r
824 printf(": N/A\n");
\r
827 printf(": (%3d):\t",nrec); // number of records
\r
828 if (!full) nrec = 1;
\r
829 int sz = ((AliLHCDipValI*)fData[refs[kStart]])->GetSizeTotal(); // dimension of the record
\r
830 Bool_t isStr = ((AliLHCDipValI*)fData[refs[kStart]])->IsTypeC();
\r
831 if ((!isStr && sz>2) || nrec>1) printf("\n"); // long record, open new line
\r
832 for (int i=0;i<nrec;i++) fData[refs[kStart]+i]->Print(opt);
\r
836 //___________________________________________________________________
\r
837 void AliLHCData::Clear(const Option_t *)
\r
844 fkFile2Process = 0;
\r
847 for (int i=2;i--;) {
\r
848 fRCInjScheme[i] = 0;
\r
853 for (int icl=kNCollimators;icl--;) for (int jaw=kNJaws;jaw--;) fCollimators[icl][jaw][i]=0;
\r
855 for (int j=2;j--;) {
\r
856 fBunchConfDecl[j][i] = 0;
\r
857 fBunchConfMeas[j][i] = 0;
\r
858 fBunchLengths[j][i] = 0;
\r
859 fIntensTotal[j][i] = 0;
\r
860 fIntensTotalAv[j][i] = 0;
\r
861 fIntensPerBunch[j][i] = 0;
\r
862 fCrossAngle[j][i] = 0;
\r
863 fEmittanceH[j][i] = 0;
\r
864 fEmittanceV[j][i] = 0;
\r
865 fBeamSigmaH[j][i] = 0;
\r
866 fBeamSigmaV[j][i] = 0;
\r
867 fLuminTotal[j][i] = 0;
\r
868 fLuminPerBC[j][i] = 0;
\r
869 fLuminAcqMode[j][i] = 0;
\r
874 //___________________________________________________________________
\r
875 Int_t AliLHCData::GetNInteractingBunchesMeasured(int i) const
\r
877 // get number of interacting bunches at IR2
\r
878 AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);
\r
879 if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}
\r
880 if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1;}
\r
882 for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;
\r
886 //___________________________________________________________________
\r
887 Int_t AliLHCData::GetNInteractingBunchesDeclared(int i) const
\r
889 // get number of interacting bunches at IR2
\r
890 AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);
\r
891 if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}
\r
892 if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1; }
\r
894 for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;
\r
898 //___________________________________________________________________
\r
899 Int_t AliLHCData::IsPilotPresent(int i) const
\r
901 // check in the filling scheme is the pilot bunch is present
\r
902 AliLHCDipValC* rec = GetInjectionScheme();
\r
903 if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}
\r
904 TString scheme = rec->GetValues();
\r
905 return scheme.Contains("wp",TString::kIgnoreCase);
\r
908 //___________________________________________________________________
\r
909 void AliLHCData::FlagInteractingBunches(const Int_t beam1[2],const Int_t beam2[2])
\r
911 // assign - sign to interacting bunches
\r
913 for (int ib1=0;ib1<beam1[kNStor];ib1++) {
\r
914 AliLHCDipValI *bm1 = (AliLHCDipValI*)fData[ beam1[kStart] + ib1];
\r
915 if (!bm1) continue;
\r
916 AliLHCDipValI *bm2 = (AliLHCDipValI*)FindRecValidFor(beam2[kStart],beam2[kNStor], bm1->GetTimeStamp());
\r
917 if (!bm2) continue;
\r
919 int nb1 = bm1->GetSize();
\r
920 int nb2 = bm2->GetSize();
\r
922 for (i1=0;i1<nb1;i1++) {
\r
923 int bunch2=-1, bunch1 = TMath::Abs((*bm1)[i1]);
\r
924 int slot2 =-1, slot1 = GetBCId(bunch1,0);
\r
925 for (i2=0;i2<nb2;i2++) {
\r
926 bunch2 = TMath::Abs((*bm2)[i2]);
\r
927 slot2 = GetBCId(bunch2,1);
\r
928 if (slot1==slot2) break;
\r
930 if (slot1!=slot2) continue;
\r
931 (*bm1)[i1] = -bunch1;
\r
932 (*bm2)[i2] = -bunch2;
\r
933 bm1->SetProcessed1();
\r
934 bm2->SetProcessed1();
\r
939 //___________________________________________________________________
\r
940 Int_t AliLHCData::GetMeanIntensity(int beamID, Double_t &colliding, Double_t &noncolliding, const TObjArray* bcmasks) const
\r
942 // get average intensity for all, colliding and non-colliding bunches
\r
943 // on success returns number of intensity records used (1 per ~10 min)
\r
944 // If triggered BC masks are provided, calculation is done for Triggered BC only
\r
945 colliding = noncolliding = -1.;
\r
946 if (beamID<0||beamID>1) {
\r
947 AliError(Form("BeamID must be either 0 or 1, %d requested",beamID));
\r
951 AliTriggerBCMask *bcMaskBoth=0,*bcMaskSingle=0;
\r
953 if (bcmasks && (nbcm=bcmasks->GetEntries())) {
\r
954 if (nbcm>1) bcMaskBoth = (AliTriggerBCMask*)bcmasks->At(1);
\r
955 if (nbcm>0 && beamID==kBeam1) bcMaskSingle = (AliTriggerBCMask*)bcmasks->At(0);
\r
956 else if (nbcm>2 && beamID==kBeam2) bcMaskSingle = (AliTriggerBCMask*)bcmasks->At(2);
\r
958 if (!bcMaskSingle) AliError(Form("Only triggered BSs are requested but %c mask is not provided",beamID ? 'C':'A'));
\r
959 if (!bcMaskBoth) AliError("Only triggered BSs are requested but B mask is not provided");
\r
962 AliWarning("No BC masks are provided");
\r
965 int nrec = GetNIntensityPerBunch(beamID);
\r
966 if (nrec<1) return -1;
\r
967 AliLHCDipValI *conf = GetBunchConfigMeasured(beamID);
\r
968 if (!conf) conf = GetBunchConfigDeclared(beamID);
\r
969 if (!conf) return -2;
\r
970 int nb = conf->GetSize();
\r
972 for (int irec=0;irec<nrec;irec++) {
\r
974 AliLHCDipValF* rInt = GetIntensityPerBunch(beamID,irec);
\r
975 for (int ib=0;ib<nb;ib++) {
\r
976 double val = rInt->GetValue(ib);
\r
977 if (val<0) continue;
\r
978 int bID = conf->GetValue(ib);
\r
979 // check if this is a triggered bunch
\r
980 int bcID = GetBCId(bID, beamID);
\r
981 if (bID<0) { // interacting
\r
982 if (bcMaskBoth && bcMaskBoth->GetMask(bcID)) continue; // masked
\r
986 if (bcMaskSingle && bcMaskSingle->GetMask(bcID)) continue; // masked
\r
987 noncolliding += val;
\r
992 noncolliding /= nrec;
\r