]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/STEER/AliLHCData.cxx
MFT clean-up (Antonio)
[u/mrichter/AliRoot.git] / STEER / STEER / AliLHCData.cxx
CommitLineData
a65a7e70 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 * *
15 **************************************************************************/
16
17/********************************************************************************
18* *
19* AliLHCData: summary of the LHC related information from LHC DIP. *
20* Created from the TMap provided by the AliLHCReader with optional beginning *
21* *
22* The data are (wrapped in the AliLHCDipValT): *
23* made of TimeStamp (double) and array of values *
24* *
25* Multiple entries for each type of data are possible. To obtaine number of *
26* records (with distinct timestamp) for give type od records use: *
27* int GetNBunchConfigMeasured(int beam) (with beam=0,1) etc. *
28* *
29* To get i-th entry, use brec= AliLHCDipValI* GetBunchConfigMeasured(bm,i); *
30* Note: exact type of templated AliLHCDipValT pointer depends on the record *
31* type, concult getters to know it. *
32* *
33* Then, once the pointer is obtained, details can be accessed: *
34* int nBunches = brec->GetSize(); *
35* for (int i=0;i<nBunches;i++) printf("Bunch#%d: %d\n",i,(*brec)[i]); *
36* *
37* *
38* Author: ruben.shahoyan@cern.ch *
39* *
40********************************************************************************/
41
42#include "AliLHCData.h"
43#include "TMap.h"
44#include "AliDCSArray.h"
45#include "AliLHCReader.h"
46#include "AliTriggerBCMask.h"
47#include <TString.h>
48#include <TObjArray.h>
49#include <TGraph.h>
50
51ClassImp(AliLHCData)
52
53const Char_t* AliLHCData::fgkDCSNames[] = {
54 "LHC_IntensityBeam%1d_totalIntensity",
55 "LHC_BeamIntensityPerBunchBeam%1d_averageBeamIntensity",
56 "LHC_BeamIntensityPerBunchBeam%1d_Average_BunchIntensities",
57 //
58 "LHC_LumAverageBRANB_4%c2_acqMode",
59 "LHC_LumAverageBRANB_4%c2_meanLuminosity",
60 "LHC_LumAverageBRANB_4%c2_meanLuminosityError",
61 "LHC_BeamLuminosityPerBunchBRANB_4%c2_Average_BunchLuminosity",
62 "LHC_BeamLuminosityPerBunchBRANB_4%c2_BunchLuminosityError",
63 "LHC_LumAverageBRANB_4%c2_meanCrossingAngle",
64 "LHC_LumAverageBRANB_4%c2_meanCrossingAngleError",
65 "LHC_CirculatingBunchConfig_Beam%d",
66 "LHC_FillNumber",
67 //
68 "LHC_BunchLengthBeam%1d_nBunches",
69 "LHC_BunchLengthBeam%1d_bunchesLenghts",
70 "LHC_BunchLengthBeam%1d_filledBuckets",
71 //
72 "LHC_RunControl_ActiveInjectionScheme",
73 "LHC_RunControl_BetaStar",
74 "LHC_RunControl_IP2_Xing_Murad",
75 "LHC_RunControl_IP2_ALICE_Murad",
76
77 "LHC_BeamSizeBeam%1d_acqMode",
78 "LHC_BeamSizeBeam%1d_sigmaH",
79 "LHC_BeamSizeBeam%1d_sigmaV",
80 "LHC_BeamSizeBeam%1d_emittanceH",
81 "LHC_BeamSizeBeam%1d_emittanceV",
82 "LHC_BeamSizeBeam%1d_errorSigmaH",
83 "LHC_BeamSizeBeam%1d_errorSigmaV",
84 //
85 "LHC_CollimatorPos_%s_lvdt_%s",
86 "ALICE_LumiIntFill",
87 "ALICE_BckgIntFill"
88};
89
90const Char_t* AliLHCData::fgkDCSColNames[] = {
91 "TCTVB_4L2",
92 "TCTVB_4R2",
93 "TCLIA_4R2"
94};
95
96const Char_t* AliLHCData::fgkDCSColJaws[] = {
97 "gap_downstream","gap_upstream","left_downstream",
98 "left_upstream","right_downstream","right_upstream"};
99
100//___________________________________________________________________
101AliLHCData::AliLHCData(const TMap* dcsMap, double tmin, double tmax)
102 : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fkFile2Process(0),fkMap2Process(0)
103{
104 FillData(dcsMap,tmin,tmax);
105}
106
107//___________________________________________________________________
108AliLHCData::AliLHCData(const Char_t* dcsFile, double tmin, double tmax)
109 : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fkFile2Process(dcsFile),fkMap2Process(0)
110{
111 FillData(dcsFile,tmin,tmax);
112}
113
114//___________________________________________________________________
115Bool_t AliLHCData::FillData(const TMap* dcsMap,double tmin, double tmax)
116{
117 // process DCS map and fill all fields.
118 Clear();
119 fkMap2Process = dcsMap;
120 FillData(tmin,tmax);
121 return kTRUE;
122}
123
124//___________________________________________________________________
125Bool_t AliLHCData::FillData(const Char_t* dcsFile,double tmin, double tmax)
126{
127 // process DCS file and fill all fields.
128 Clear();
129 fkFile2Process = dcsFile;
130 FillData(tmin,tmax);
131 return kTRUE;
132}
133
134//___________________________________________________________________
135Bool_t AliLHCData::FillData(double tmin, double tmax)
136{
137 // process DCS map and fill all fields.
138 // Accept only entries with timestamp between tmin and tmax
139 //
140 char buff[100],buff1[100];
141 //
142 SetTMin(tmin);
143 SetTMax(tmax);
144 //
145 // -------------------------- extract Fill Number
146 int iFirst=0,iLast=0;
147 TObjArray* arr = GetDCSEntry(fgkDCSNames[kFillNum],iFirst,iLast,fTMin,fTMax);
148 if (arr) SetFillNumber( ExtractInt( (AliDCSArray*)arr->At(iFirst), 0) );
149 if (fkFile2Process) delete arr; // array was created on demand
150 //
151 for (int ibm=0;ibm<2;ibm++) {
152 //
153 snprintf(buff,99,fgkDCSNames[kBunchConf],ibm+1); // ----- declared bunch configuration
154 FillBunchConfig(fBunchConfDecl[ibm], buff);
155 //
156 snprintf(buff,99,fgkDCSNames[kBunchLgtFillB],ibm+1); // ----- measured bunch configuration
157 FillBunchConfig(fBunchConfMeas[ibm], buff);
158 //
159 snprintf(buff,99,fgkDCSNames[kBunchLgt],ibm+1); // ----- measured bunch lenghts
160 FillBunchInfo(fBunchLengths[ibm],buff,ibm,kFALSE);
161 //
162 snprintf(buff,99,fgkDCSNames[kIntBunchAv],ibm+1); // ----- B-by-B intensities
163 FillBunchInfo(fIntensPerBunch[ibm],buff,ibm,kTRUE);
164 //
165 //
166 snprintf(buff,99,fgkDCSNames[kIntTot],ibm+1); // ----- total intensities for beam 1 and 2
167 FillScalarRecord(fIntensTotal[ibm], buff);
168 //
169 snprintf(buff,99,fgkDCSNames[kIntTotAv],ibm+1); // ----- total intensities for beam 1 and 2 from B-by-B average
170 FillScalarRecord(fIntensTotalAv[ibm], buff);
171 //
172 snprintf(buff,99,fgkDCSNames[kBeamSzEmittH],ibm+1); // ----- H emittance for beam 1 and 2
173 FillScalarRecord(fEmittanceH[ibm], buff);
174 //
175 snprintf(buff,99,fgkDCSNames[kBeamSzEmittV],ibm+1); // ----- V emittance for beam 1 and 2
176 FillScalarRecord(fEmittanceV[ibm], buff);
177 //
178 snprintf(buff,99 ,fgkDCSNames[kBeamSzSigH], ibm+1); // ----- H sigmas and errors for beam 1 and 2
179 snprintf(buff1,99,fgkDCSNames[kBeamSzSigHErr],ibm+1);
180 FillScalarRecord(fBeamSigmaH[ibm], buff, buff1);
181 //
182 snprintf(buff,99 ,fgkDCSNames[kBeamSzSigV], ibm+1); // ----- V sigmas and errors for beam 1 and 2
183 snprintf(buff1,99,fgkDCSNames[kBeamSzSigVErr],ibm+1);
184 FillScalarRecord(fBeamSigmaV[ibm], buff, buff1);
185 //
186 }
187 //
188 FlagInteractingBunches(fBunchConfMeas[0],fBunchConfMeas[1]);
189 FlagInteractingBunches(fBunchConfDecl[0],fBunchConfDecl[1]);
190 //
191 for (int ilr=0;ilr<2;ilr++) {
192 //
193 snprintf(buff,99 ,fgkDCSNames[kLumBunch], ilr ? 'R':'L'); // ---- BC-by-BC luminosity at IP2 and its error
194 snprintf(buff1,99,fgkDCSNames[kLumBunchErr], ilr ? 'R':'L');
195 FillBCLuminosities(fLuminPerBC[ilr], buff, buff1, 0); // BRAN L uses beam2 as a reference, BRAN R - beam1
196 //
197 snprintf(buff,99 ,fgkDCSNames[kLumTot] , ilr ? 'R':'L'); // ---- total luminosity at IP2 and its error
198 snprintf(buff1,99,fgkDCSNames[kLumTotErr], ilr ? 'R':'L');
199 FillScalarRecord(fLuminTotal[ilr], buff, buff1);
200 //
201 snprintf(buff,99 ,fgkDCSNames[kLumAcqMode], ilr ? 'R':'L'); // ---- luminosity acquisition mode
202 FillAcqMode(fLuminAcqMode[ilr], buff);
203 //
204 snprintf(buff,99, fgkDCSNames[kLumCrossAng] , ilr ? 'R':'L'); //----- crossing angle at IP2 and its error
205 snprintf(buff1,99,fgkDCSNames[kLumCrossAngErr], ilr ? 'R':'L');
206 FillScalarRecord(fCrossAngle[ilr], buff, buff1);
207 //
208 }
209 //
210 for (int icl=0;icl<kNCollimators;icl++) { // ----- collimators positions
211 for (int jaw=0;jaw<kNJaws;jaw++) {
212 snprintf(buff,99,fgkDCSNames[kCollPos], fgkDCSColNames[icl],fgkDCSColJaws[jaw]);
213 FillScalarRecord(fCollimators[icl][jaw], buff);
214 } // jaws
215 } // collimators
216 //
217 //
218 // RunControl info
219 FillStringRecord(fRCInjScheme, fgkDCSNames[kRCInjSch]); // ---- active injection scheme
220 FillScalarRecord(fRCBeta, fgkDCSNames[kRCBeta]); // ---- target beta
221 FillScalarRecord(fRCAngH, fgkDCSNames[kRCCrossAng]); // ---- horisontal angle
222 FillScalarRecord(fRCAngV,fgkDCSNames[kRCVang] ); // ---- vertical angle
223 //
224 return kTRUE;
225}
226
227//___________________________________________________________________
228TObjArray* AliLHCData::GetDCSEntry(const char* key,int &entry,int &last,double tmin,double tmax) const
229{
230 // extract array from the DCS map or file and find the first entry within the time limits
231 entry = -1;
232 last = -2;
233 TObjArray* arr;
234 if (fkMap2Process) arr = (TObjArray*)fkMap2Process->GetValue(key);
235 else if (fkFile2Process) {
236 AliLHCReader rd;
237 arr = rd.ReadSingleLHCDP(fkFile2Process,key);
238 }
239 else {
240 AliError("Neither DCS map nor DCS filename are set");
241 return 0;
242 }
243 //
244 if (!arr || !arr->GetEntriesFast()) {
245 AliWarning(Form("No data for %s",key));
246 if (fkMap2Process) delete arr; // created on demand
247 return 0;
248 }
249 int ntot = arr->GetEntriesFast();
250 //
251 // search 1st entry before or at tmin
252 AliDCSArray* ent = 0;
253 Bool_t found = kFALSE;
254 for (entry=0;entry<ntot;entry++) {
255 ent = (AliDCSArray*)arr->At(entry);
256 if (ent->GetTimeStamp()>=tmin-kMarginSOR && ent->GetTimeStamp()<=tmax+kMarginEOR) {
257 found = kTRUE;
258 if (ent->GetTimeStamp()>tmin) break;
259 }
260 }
261 if (!found) {
262 entry = -1;
263 TString str;
264 str += AliLHCDipValF::TimeAsString(tmin);
265 str += " : ";
266 str += AliLHCDipValF::TimeAsString(tmax);
267 AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));
268 if (fkMap2Process) delete arr; // created on demand
269 return 0;
270 }
271 if (entry>0) entry--;
272 //
273 // search last entry at or after tmin
274 ent = 0;
275 for (last=entry;last<ntot;last++) {
276 ent = (AliDCSArray*)arr->At(last);
277 if (ent->GetTimeStamp()>tmax) break;
278 }
279 if (last == ntot) last--;
280 else if (ent->GetTimeStamp()>tmax+kMarginEOR) last--;
281 //
282 return arr;
283}
284
285//___________________________________________________________________
286Int_t AliLHCData::TimeDifference(double v1,double v2,double tol) const
287{
288 // return 0 if the times are the same within the tolerance
289 // 1 if v1>v2
290 // -1 if v1<v2
291 v1-=v2;
292 if (v1>tol) return 1;
293 if (v1<-tol) return -1;
294 return 0;
295}
296
297//___________________________________________________________________
298Bool_t AliLHCData::GoodPairID(int beam) const
299{
300 // check for correct beam identifier
301 if (beam>kBeam2||beam<0) {AliError(Form("BeamID can be 0 or 1, %d requested",beam)); return kFALSE;}
302 return kTRUE;
303}
304
305//___________________________________________________________________
306AliLHCDipValI* AliLHCData::GetBunchConfigMeasured(int beam,double tstamp) const
307{
308 // find measured bunch configuration valid for given tstamp
309 if (!GoodPairID(beam)) return 0;
310 return (AliLHCDipValI*)FindRecValidFor(fBunchConfMeas[beam][kStart],fBunchConfMeas[beam][kNStor],tstamp);
311}
312
313//___________________________________________________________________
314AliLHCDipValI* AliLHCData::GetBunchConfigDeclared(int beam,double tstamp) const
315{
316 // find declared bunch configuration valid for given tstamp
317 if (!GoodPairID(beam)) return 0;
318 return (AliLHCDipValI*)FindRecValidFor(fBunchConfDecl[beam][kStart],fBunchConfDecl[beam][kNStor],tstamp);
319}
320
321//___________________________________________________________________
322TObject* AliLHCData::FindRecValidFor(int start,int nrec, double tstamp) const
323{
324 // find record within this limits valid for given tstamp (i.e. the last one before or equal to tstamp)
325 AliLHCDipValI *prevObj = 0;
326 for (int i=0;i<nrec;i++) {
327 AliLHCDipValI* curObj = (AliLHCDipValI*)fData[start+i];
328 if (TimeDifference(tstamp,curObj->GetTimeStamp())<=0) break;
329 prevObj = curObj;
330 }
331 if (!prevObj && nrec>0) prevObj = (AliLHCDipValI*)fData[start]; // if no exact match, return the 1st one
332 return prevObj;
333}
334
335//___________________________________________________________________
336Int_t AliLHCData::FillScalarRecord(int refs[2], const char* rec, const char* recErr, Double_t maxAbsVal)
337{
338 // fill record for scalar value, optionally accompanied by measurement error
339 //
340 AliInfo(Form("Acquiring record: %s",rec));
341 //
342 TObjArray *arr=0,*arrE=0;
343 Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;
344 //
345 refs[kStart] = fData.GetEntriesFast();
346 refs[kNStor] = 0;
347 //
348 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
349 //
350 int dim = 1;
351 if (recErr) {
352 arrE = GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);
353 dim += 1;
354 }
355 //
356 // Bool_t last = kFALSE;
357 while (iFirst<=iLast) {
358 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
359 double tstamp = dcsVal->GetTimeStamp();
360 //
361 AliLHCDipValF* curValD = new AliLHCDipValF(dim,tstamp); // start new period
362 double vcheck = ExtractDouble(dcsVal,0); // value
363 if (TMath::Abs(vcheck) > maxAbsVal) {
364 AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",vcheck, 0, rec, maxAbsVal));
365 vcheck = 0.;
366 }
367 (*curValD)[0] = vcheck;
368 //
369 if (recErr) {
370 double errVal = -1;
371 while (iFirstE<=iLastE) { // try to find corresponding error
372 AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);
373 double tstampE = dcsValE->GetTimeStamp();
374 int tdif = TimeDifference(tstamp,tstampE);
375 if (!tdif) { // error matches to value
376 errVal = ExtractDouble(dcsVal,0); // value
377 if (TMath::Abs(errVal) > maxAbsVal) {
378 AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",errVal, 0, recErr, maxAbsVal));
379 errVal = 0.;
380 }
381 iFirstE++;
382 break;
383 }
384 else if (tdif>0) iFirstE++; // error time lags behind, read the next one
385 else break; // error time is ahead of value, no error associated
386 }
387 (*curValD)[dim-1] = errVal; // error
388 curValD->SetLastSpecial(); // lable the last entry as an error
389 }
390 //
391 fData.Add(curValD);
392 refs[kNStor]++;
393 // if (last) break;
394 }
395 //
396 if (fkFile2Process) {
397 delete arr;
398 delete arrE;
399 }
400 return refs[kNStor];
401}
402
403//___________________________________________________________________
404Int_t AliLHCData::FillBunchConfig(int refs[2],const char* rec)
405{
406 // fill record for bunch configuration
407 //
408 AliInfo(Form("Acquiring record: %s",rec));
409 TObjArray *arr;
410 Int_t iLast,iFirst;
411 //
412 refs[kStart] = fData.GetEntriesFast();
413 refs[kNStor] = 0;
414 //
415 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
416 //
417 AliLHCDipValI* prevRecI=0;
418 //
419 while (iFirst<=iLast) {
420 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
421 double tstamp = dcsVal->GetTimeStamp();
422 //
423 int bucket=0, nbunch=0, ndiff=0;
424 int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)
425 int* dcsArr = dcsVal->GetInt();
426 while(nbunch<nSlots && (bucket=dcsArr[nbunch])) {
427 if (prevRecI && prevRecI->GetSize()>nbunch && bucket!=prevRecI->GetValue(nbunch)) ndiff++;
428 nbunch++;
429 }
430 if (!nbunch) AliWarning(Form("%s record is present but empty: no beam?",rec));
431 if (prevRecI && !ndiff && nbunch==prevRecI->GetSize()) continue; // record similar to previous one
432 AliLHCDipValI* curValI = new AliLHCDipValI(nbunch,tstamp);
433 for (int i=nbunch;i--;) (*curValI)[i] = dcsArr[i];
434 fData.Add(curValI);
435 refs[kNStor]++;
436 prevRecI = curValI;
437 }
438 //
439 if (fkFile2Process) delete arr;
440 return refs[kNStor];
441}
442
443//___________________________________________________________________
444Int_t AliLHCData::FillAcqMode(int refs[2],const char* rec)
445{
446 // fill acquisition mode
447 //
448 AliInfo(Form("Acquiring record: %s",rec));
449 TObjArray *arr;
450 Int_t iLast,iFirst;
451 //
452 refs[kStart] = fData.GetEntriesFast();
453 refs[kNStor] = 0;
454 //
455 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
456 //
457 AliLHCDipValI* prevRecI=0;
458 while (iFirst<=iLast) {
459 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
460 double tstamp = dcsVal->GetTimeStamp();
461 //
462 int nSlots = dcsVal->GetNEntries();
463 if (nSlots<1) continue;
464 int acqMode = dcsVal->GetInt()[0];
465 if (prevRecI && (*prevRecI)[0] == acqMode) continue; // record similar to previous one
466 AliLHCDipValI* curValI = new AliLHCDipValI(1,tstamp);
467 (*curValI)[0] = acqMode;
468 fData.Add(curValI);
469 refs[kNStor]++;
470 prevRecI = curValI;
471 }
472 //
473 if (fkFile2Process) delete arr;
474 return refs[kNStor];
475}
476
477//___________________________________________________________________
478Int_t AliLHCData::FillStringRecord(int refs[2],const char* rec)
479{
480 // fill record with string value
481 //
482 AliInfo(Form("Acquiring record: %s",rec));
483 TString prevRec;
484 TObjArray *arr;
485 Int_t iLast,iFirst;
486 //
487 refs[kStart] = fData.GetEntriesFast();
488 refs[kNStor] = 0;
489 //
490 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
491 //
492 while (iFirst<=iLast) {
493 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
494 double tstamp = dcsVal->GetTimeStamp();
495 //
496 TString &str = ExtractString(dcsVal);
497 if (!prevRec.IsNull()) {if (str == prevRec) continue;} // skip similar record
498 else prevRec = str;
499 //
500 AliLHCDipValC* curValS = new AliLHCDipValC(1,tstamp);
501 curValS->SetValues(str.Data(),str.Length()+1);
502 //
503 fData.Add(curValS);
504 refs[kNStor]++;
505 }
506 if (fkFile2Process) delete arr;
507 return refs[kNStor];
508}
509
510//___________________________________________________________________
511Int_t AliLHCData::FillBunchInfo(int refs[2],const char* rec, int ibm, Bool_t inRealSlots, Double_t maxAbsVal)
512{
513 // fill bunch properties for beam ibm
514 // if inRealSlots = true, then the value is taken from bunchRFbucket/10, otherwise, the value
515 // for the i-th bunch is taken from the i-th element
516 //
517 AliInfo(Form("Acquiring record: %s",rec));
518 TObjArray *arr;
519 Int_t iLast,iFirst;
520 //
521 refs[kStart] = fData.GetEntriesFast();
522 refs[kNStor] = 0;
523 //
524 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
525 //
526 while (iFirst<=iLast) {
527 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
528 double tstamp = dcsVal->GetTimeStamp();
529 //
530 AliLHCDipValI *bconf = GetBunchConfigMeasured(ibm,tstamp);
531 if (!bconf) {
532 AliWarning(Form("Mearured bunch configuration for beam %d at t=%.1f is not available, trying declared one",ibm+1,tstamp));
533 bconf = GetBunchConfigDeclared(ibm,tstamp);
534 }
535 if (!bconf) {
536 AliWarning(Form("Declared bunch configuration for beam %d at t=%.1f is not available, skip this record",ibm+1,tstamp));
537 return -1;
538 }
539 int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)
540 int nbunch = bconf->GetSize();
541 if (nbunch>nSlots) {
542 AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));
543 continue;
544 }
545 double* dcsArr = dcsVal->GetDouble();
546 AliLHCDipValF* curValD = new AliLHCDipValF(nbunch,tstamp);
547 for (int i=nbunch;i--;) {
548 int ind = inRealSlots ? (*bconf)[i]/10 : i;
549 if (ind>nSlots) {
550 AliError(Form("Bunch %d refers to wrong slot %d, set to -1",i,(*bconf)[i]));
551 (*curValD)[i] = -1;
552 }
553 else {
554 double vcheck = dcsArr[ind];
555 if (TMath::Abs(vcheck) > maxAbsVal) {
556 AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",vcheck, ind, rec, maxAbsVal));
557 vcheck = 0.;
558 }
559 (*curValD)[i] = vcheck;
560 }
561 }
562 fData.Add(curValD);
563 refs[kNStor]++;
564 }
565 if (fkFile2Process) delete arr;
566 return refs[kNStor];
567 //
568}
569
570//___________________________________________________________________
571Int_t AliLHCData::FillBCLuminosities(int refs[2],const char* rec, const char* recErr, int useBeam, Double_t maxAbsVal)
572{
573 // fill luminosities per bunch crossing
574 //
575 AliInfo(Form("Acquiring record: %s",rec));
576 TObjArray *arr,*arrE=0;
577 Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;
578 //
579 refs[kStart] = fData.GetEntriesFast();
580 refs[kNStor] = 0;
581 //
582 if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;
583 //
584 while (iFirst<=iLast) {
585 AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);
586 double tstamp = dcsVal->GetTimeStamp();
587 //
588 AliLHCDipValI *bconf;
589 bconf = GetBunchConfigMeasured(useBeam,tstamp); // luminosities are stored according to beam bunches
590 if (!bconf) {
591 AliWarning(Form("Mearured bunch configuration for beam%d at t=%.1f is not available, trying declared one",useBeam,tstamp));
592 bconf = GetBunchConfigDeclared(useBeam,tstamp);
593 }
594 if (!bconf) {
595 AliWarning(Form("Declared bunch configuration for beam%i at t=%.1f is not available, skip this record",useBeam,tstamp));
596 return -1;
597 }
598 int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)
599 int nbunch = bconf->GetSize();
600 double* dcsArr = dcsVal->GetDouble();
601 //
602 if (nbunch>nSlots) {
603 AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));
604 continue;
605 }
606 int dim = 0;
607 if (!bconf->IsProcessed1()) {
608 AliWarning(Form("Bunch conf. for beam%d has no marked interacting bunches, store all luminosity for all filled bunches",useBeam));
609 dim = nbunch;
610 }
611 else { // count number of interacting bunches
612 for (int i=nbunch;i--;) if ((*bconf)[i]<0) dim++;
613 }
614 //
615 if (recErr) {
616 arrE=GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);
617 dim += 1;
618 }
619 AliLHCDipValF* curValD = new AliLHCDipValF(dim,tstamp);
620 int cnt = 0;
621 for (int i=0;i<nbunch;i++) {
622 int slot = (*bconf)[i];
623 if (bconf->IsProcessed1() && slot>0) continue;
624 //
625 int ind = TMath::Abs(slot)/10;
626 if (ind>nSlots) {
627 AliError(Form("Bunch %d refers to wrong slot %d, set to -1",cnt,slot));
628 (*curValD)[cnt] = -1;
629 }
630 else {
631 double vcheck = dcsArr[ind];
632 if (TMath::Abs(vcheck) > maxAbsVal) {
633 AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",vcheck, ind, rec, maxAbsVal));
634 vcheck = 0.;
635 }
636 (*curValD)[i] = vcheck;
637 }
638 cnt++;
639 }
640 //
641 if (recErr) {
642 double errVal = -1;
643 while (iFirstE<=iLastE) { // try to find corresponding error
644 AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);
645 double tstamp1 = dcsValE->GetTimeStamp();
646 int tdif = TimeDifference(tstamp,tstamp1);
647 if (!tdif) { // error matches to value
648 errVal = dcsValE->GetDouble()[0];
649 if (TMath::Abs(errVal) > maxAbsVal) {
650 AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",errVal,0, rec, maxAbsVal));
651 errVal = 0.;
652 }
653 iFirstE++;
654 break;
655 }
656 else if (tdif>0) iFirstE++; // error time lags behind, read the next one
657 else break; // error time is ahead of value, no error associated
658 }
659 (*curValD)[dim-1] = errVal; // error
660 curValD->SetLastSpecial(); // lable the last entry as an error
661 }
662 //
663 fData.Add(curValD);
664 refs[kNStor]++;
665 }
666 if (fkFile2Process) {
667 delete arr;
668 delete arrE;
669 }
670 return refs[kNStor];
671 //
672}
673
674//___________________________________________________________________
675Int_t AliLHCData::ExtractInt(AliDCSArray* dcsArray,Int_t el) const
676{
677 // extract integer from the dcsArray
678 int val = -1;
679 //
680 int sz = dcsArray->GetNEntries();
681 if (sz<=el) return val;
682 //
683 if (dcsArray->GetType()==AliDCSArray::kInt) val = dcsArray->GetInt(el);
684 else if (dcsArray->GetType()==AliDCSArray::kString) {
685 TObjString *stro = dcsArray->GetStringArray(el);
686 if (stro) val = stro->GetString().Atoi();
687 else AliError(Form("DCSArray TObjString for element %d is missing",el));
688 }
689 else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);
690 else AliError(Form("Integer requested from DCSArray of type %d",dcsArray->GetType()));
691 return val;
692}
693
694//___________________________________________________________________
695Double_t AliLHCData::ExtractDouble(AliDCSArray* dcsArray,Int_t el) const
696{
697 // extract double from the dcsArray
698 double val = 0;
699 //
700 int sz = dcsArray->GetNEntries();
701 if (sz<=el) return val;
702 //
703 if (dcsArray->GetType()==AliDCSArray::kDouble) val = dcsArray->GetDouble(el);
704 else if (dcsArray->GetType()==AliDCSArray::kFloat) val = dcsArray->GetFloat(el);
705 else if (dcsArray->GetType()==AliDCSArray::kString) {
706 TObjString *stro = dcsArray->GetStringArray(el);
707 if (stro) val = stro->GetString().Atof();
708 else AliError(Form("DCSArray has TObjString for element %d is missing",el));
709 }
710 else if (dcsArray->GetType()==AliDCSArray::kChar) val = dcsArray->GetChar(el);
711 else if (dcsArray->GetType()==AliDCSArray::kInt) val = dcsArray->GetInt(el);
712 else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);
713 else AliError(Form("Double requested from DCSArray of type %d",dcsArray->GetType()));
714 return val;
715}
716
717//___________________________________________________________________
718TString& AliLHCData::ExtractString(AliDCSArray* dcsArray) const
719{
720 // extract string from the dcsArray
721 static TString str;
722 str = "";
723 //
724 int sz = dcsArray->GetNEntries();
725 if (dcsArray->GetType()!=AliDCSArray::kString) {
726 AliError(Form("String requested from DCSArray of type %d",dcsArray->GetType()));
727 return str;
728 }
729 //
730 for (int i=0;i<sz;i++) {
731 str += dcsArray->GetStringArray(i)->GetString();
732 if (i<sz-1) str += " ";
733 }
734 return str;
735}
736
737//___________________________________________________________________
738void AliLHCData::Print(const Option_t* opt) const
739{
740 // print full info
741 TString opts = opt;
742 opts.ToLower();
743 Bool_t utcTime = opts.Contains("loc") ? kFALSE:kTRUE;
744 Bool_t full = kTRUE;
745 if (!opts.Contains("f")) {
746 printf("Use Print(\"f\") to print full info\n");
747 printf("Printing short info:\n<RecordType>(number of records): <TimeStamp, value> for 1st record only\n");
748 full = kFALSE;
749 }
750 TString sdtmn = AliLHCDipValI::TimeAsString(fTMin,utcTime);
751 TString sdtmx = AliLHCDipValI::TimeAsString(fTMax,utcTime);
752 printf("Fill#%6d Validity: %s - %s (%s)\n",fFillNumber,sdtmn.Data(),sdtmx.Data(),utcTime ? "UTC":"LOC");
753 //
754 printf("********** SETTINGS FROM RUN CONTROL **********\n");
755 //
756 printf("* %-38s","Injection Scheme");
757 PrintAux(full,fRCInjScheme,opts);
758 //
759 printf("* %-38s","Beta Star");
760 PrintAux(full,fRCBeta,opts);
761 //
762 printf("* %-38s","Horisontal Crossing Angle");
763 PrintAux(full,fRCAngH,opts);
764 //
765 printf("* %-38s","Vertical Crossing Angle");
766 PrintAux(full,fRCAngV,opts);
767 //
768 for (int ib=0;ib<2;ib++) {
769 printf("* Beam%d filling [- interacts at IR2!] ",ib+1);
770 PrintAux(full,fBunchConfDecl[ib],opts);
771 }
772 //
773 printf("\n********** MEASURED DATA **********\n");
774 //
775 for (int ib=0;ib<2;ib++) {
776 printf("* Beam%d filling [- interacts at IR2!] ",ib+1);
777 PrintAux(full,fBunchConfMeas[ib],opts);
778 }
779 //
780 for (int ib=0;ib<2;ib++) {
781 printf("* Beam%d total intensity ",ib+1);
782 PrintAux(full,fIntensTotal[ib],opts);
783 }
784 //
785 for (int ib=0;ib<2;ib++) {
786 printf("* Beam%d total intensity (bunch average) ",ib+1);
787 PrintAux(full,fIntensTotalAv[ib],opts);
788 }
789 //
790 for (int ib=0;ib<2;ib++) {
791 printf("* Beam%d intensity per bunch ",ib+1);
792 PrintAux(full,fIntensPerBunch[ib],opts);
793 }
794 //
795 for (int ib=0;ib<2;ib++) {
796 printf("* Beam%d bunch lengths ",ib+1);
797 PrintAux(full,fBunchLengths[ib],opts);
798 }
799 //
800 for (int ib=0;ib<2;ib++) {
801 printf("* Beam%d Horisontal emittance ",ib+1);
802 PrintAux(full,fEmittanceH[ib],opts);
803 }
804 //
805 for (int ib=0;ib<2;ib++) {
806 printf("* Beam%d Vertical emittance ",ib+1);
807 PrintAux(full,fEmittanceV[ib],opts);
808 }
809 //
810 for (int ib=0;ib<2;ib++) {
811 printf("* Beam%d Horisontal sigma ",ib+1);
812 PrintAux(full,fBeamSigmaH[ib],opts);
813 }
814 //
815 for (int ib=0;ib<2;ib++) {
816 printf("* Beam%d Vertical sigma ",ib+1);
817 PrintAux(full,fBeamSigmaV[ib],opts);
818 }
819 //
820 for (int lr=0;lr<2;lr++) {
821 printf("* Total luminosity from BRANB_4%c2 ",lr ? 'R':'L');
822 PrintAux(full,fLuminTotal[lr],opts);
823 }
824 //
825 for (int lr=0;lr<2;lr++) {
826 printf("* Luminosity acq.mode, BRANB_4%c2 ",lr ? 'R':'L');
827 PrintAux(full,fLuminAcqMode[lr],opts+"bit");
828 }
829 //
830 for (int lr=0;lr<2;lr++) {
831 printf("* Luminosity per BC from BRANB_4%c2 ",lr ? 'R':'L');
832 PrintAux(full,fLuminPerBC[lr],opts);
833 }
834 //
835 for (int lr=0;lr<2;lr++) {
836 printf("* Crossing angle, side %c ",lr ? 'R':'L');
837 PrintAux(full,fCrossAngle[lr],opts);
838 }
839 //
840 for (int coll=0;coll<kNCollimators;coll++)
841 for (int jaw=0;jaw<kNJaws;jaw++) {
842 printf("* Collimator %10s:%16s",fgkDCSColNames[coll],fgkDCSColJaws[jaw]);
843 PrintAux(full,fCollimators[coll][jaw],opts);
844 }
845 //
846 printf("* Alice fill integrated luminosity data: ");
847 PrintAux(full,fLumiAlice,opts);
848 //
849 printf("* Alice fill integrated background data ");
850 PrintAux(full,fBckgAlice,opts);
851 //
852
853}
854
855//___________________________________________________________________
856void AliLHCData::PrintAux(Bool_t full, const Int_t refs[2], const Option_t *opt) const
857{
858 // aux method to print the reocrds of the same type
859 int nrec = refs[kNStor];
860 if (nrec<1) {
861 printf(": N/A\n");
862 return;
863 }
864 printf(": (%3d):\t",nrec); // number of records
865 if (!full) nrec = 1;
866 int sz = ((AliLHCDipValI*)fData[refs[kStart]])->GetSizeTotal(); // dimension of the record
867 Bool_t isStr = ((AliLHCDipValI*)fData[refs[kStart]])->IsTypeC();
868 if ((!isStr && sz>2) || nrec>1) printf("\n"); // long record, open new line
869 for (int i=0;i<nrec;i++) fData[refs[kStart]+i]->Print(opt);
870 //
871}
872
873//___________________________________________________________________
874void AliLHCData::Clear(const Option_t *)
875{
876 // clear all info
877 fData.Delete();
878 fFillNumber = 0;
879 fTMin = 0;
880 fTMax = 1e10;
881 fkFile2Process = 0;
882 fkMap2Process = 0;
883 //
884 for (int i=2;i--;) {
885 fRCInjScheme[i] = 0;
886 fRCBeta[i] = 0;
887 fRCAngH[i] = 0;
888 fRCAngV[i] = 0;
889 fLumiAlice[i] = 0;
890 fBckgAlice[i] = 0;
891 //
892 for (int icl=kNCollimators;icl--;) for (int jaw=kNJaws;jaw--;) fCollimators[icl][jaw][i]=0;
893 //
894 for (int j=2;j--;) {
895 fBunchConfDecl[j][i] = 0;
896 fBunchConfMeas[j][i] = 0;
897 fBunchLengths[j][i] = 0;
898 fIntensTotal[j][i] = 0;
899 fIntensTotalAv[j][i] = 0;
900 fIntensPerBunch[j][i] = 0;
901 fCrossAngle[j][i] = 0;
902 fEmittanceH[j][i] = 0;
903 fEmittanceV[j][i] = 0;
904 fBeamSigmaH[j][i] = 0;
905 fBeamSigmaV[j][i] = 0;
906 fLuminTotal[j][i] = 0;
907 fLuminPerBC[j][i] = 0;
908 fLuminAcqMode[j][i] = 0;
909 }
910 }
911}
912
913//___________________________________________________________________
914Int_t AliLHCData::GetNInteractingBunchesMeasured(int i) const
915{
916 // get number of interacting bunches at IR2
917 AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);
918 if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}
919 if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1;}
920 int n = 0;
921 for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;
922 return n;
923}
924
925//___________________________________________________________________
926Int_t AliLHCData::GetNInteractingBunchesDeclared(int i) const
927{
928 // get number of interacting bunches at IR2
929 AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);
930 if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}
931 if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1; }
932 int n = 0;
933 for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;
934 return n;
935}
936
937//___________________________________________________________________
938Int_t AliLHCData::IsPilotPresent(int i) const
939{
940 // check in the filling scheme is the pilot bunch is present
941 AliLHCDipValC* rec = GetInjectionScheme();
942 if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}
943 TString scheme = rec->GetValues();
944 return scheme.Contains("wp",TString::kIgnoreCase);
945}
946
947//___________________________________________________________________
948void AliLHCData::FlagInteractingBunches(const Int_t beam1[2],const Int_t beam2[2])
949{
950 // assign - sign to interacting bunches
951 //
952 for (int ib1=0;ib1<beam1[kNStor];ib1++) {
953 AliLHCDipValI *bm1 = (AliLHCDipValI*)fData[ beam1[kStart] + ib1];
954 if (!bm1) continue;
955 AliLHCDipValI *bm2 = (AliLHCDipValI*)FindRecValidFor(beam2[kStart],beam2[kNStor], bm1->GetTimeStamp());
956 if (!bm2) continue;
957 //
958 int nb1 = bm1->GetSize();
959 int nb2 = bm2->GetSize();
960 int i1,i2;
961 for (i1=0;i1<nb1;i1++) {
962 int bunch2=-1, bunch1 = TMath::Abs((*bm1)[i1]);
963 int slot2 =-1, slot1 = GetBCId(bunch1,0);
964 for (i2=0;i2<nb2;i2++) {
965 bunch2 = TMath::Abs((*bm2)[i2]);
966 slot2 = GetBCId(bunch2,1);
967 if (slot1==slot2) break;
968 }
969 if (slot1!=slot2) continue;
970 (*bm1)[i1] = -bunch1;
971 (*bm2)[i2] = -bunch2;
972 bm1->SetProcessed1();
973 bm2->SetProcessed1();
974 }
975 }
976}
977
978//___________________________________________________________________
979Int_t AliLHCData::GetMeanIntensity(int beamID, Double_t &colliding, Double_t &noncolliding, const TObjArray* bcmasks) const
980{
981 // get average intensity for all, colliding and non-colliding bunches
982 // on success returns number of intensity records used (1 per ~10 min)
983 // If triggered BC masks are provided, calculation is done for Triggered BC only
984 colliding = noncolliding = -1.;
985 if (beamID<0||beamID>1) {
986 AliError(Form("BeamID must be either 0 or 1, %d requested",beamID));
987 return -10;
988 }
989 //
990 AliTriggerBCMask *bcMaskBoth=0,*bcMaskSingle=0;
991 int nbcm = 0;
992 if (bcmasks && (nbcm=bcmasks->GetEntries())) {
993 if (nbcm>1) bcMaskBoth = (AliTriggerBCMask*)bcmasks->At(1);
994 if (nbcm>0 && beamID==kBeam1) bcMaskSingle = (AliTriggerBCMask*)bcmasks->At(0);
995 else if (nbcm>2 && beamID==kBeam2) bcMaskSingle = (AliTriggerBCMask*)bcmasks->At(2);
996 //
997 if (!bcMaskSingle) AliError(Form("Only triggered BSs are requested but %c mask is not provided",beamID ? 'C':'A'));
998 if (!bcMaskBoth) AliError("Only triggered BSs are requested but B mask is not provided");
999 }
1000 else {
1001 AliWarning("No BC masks are provided");
1002 }
1003 //
1004 int nrec = GetNIntensityPerBunch(beamID);
1005 if (nrec<1) return -1;
1006 AliLHCDipValI *conf = GetBunchConfigMeasured(beamID);
1007 if (!conf) conf = GetBunchConfigDeclared(beamID);
1008 if (!conf) return -2;
1009 int nb = conf->GetSize();
1010 //
1011 for (int irec=0;irec<nrec;irec++) {
1012 //
1013 AliLHCDipValD* rIntD = 0;
1014 AliLHCDipValF* rIntF = GetIntensityPerBunch(beamID,irec);
1015 // for BWD compatibility of some periods
1016 if (rIntF->IsA() == AliLHCDipValD::Class()) {rIntD=(AliLHCDipValD*)rIntF; rIntF=0;}
1017 if (!rIntF && !rIntD) {
1018 AliError(Form("Failed to get GetIntensityPerBunch(%d,%d)",beamID,irec));
1019 continue;
1020 }
1021 for (int ib=0;ib<nb;ib++) {
1022 double val = 0;
1023 if (rIntF) val = rIntF->GetValue(ib);
1024 else if (rIntD) val = rIntD->GetValue(ib);
1025 if (val<0) continue;
1026 int bID = conf->GetValue(ib);
1027 // check if this is a triggered bunch
1028 int bcID = GetBCId(bID, beamID);
1029 if (bID<0) { // interacting
1030 if (bcMaskBoth && bcMaskBoth->GetMask(bcID)) continue; // masked
1031 colliding += val;
1032 }
1033 else {
1034 if (bcMaskSingle && bcMaskSingle->GetMask(bcID)) continue; // masked
1035 noncolliding += val;
1036 }
1037 }
1038 }
1039 colliding /= nrec;
1040 noncolliding /= nrec;
1041 return nrec;
1042}
1043
1044//___________________________________________________________________
1045void AliLHCData::FillLumiAlice(Int_t nrec, Int_t* timeArr, Double_t* valArr)
1046{
1047 // Create a record for lumi integrated from the beginning of fill
1048 // We need dedicated method since this info comes from Alice (not LHCDip) as instantaneous values
1049 // and is retrofitted for past runs
1050 fLumiAlice[kStart] = fData.GetEntriesFast();
1051 fLumiAlice[kNStor] = 0;
1052 if (nrec<2 || !timeArr || !valArr) return;
1053 double tprv,period,currTime;
1054 if ((currTime=double(UInt_t(timeArr[0])))>fTMin) {
1055 AliError(Form("TimeStamp of 1st record: %s > TimeStamp of SOR: %s, STOP",
1056 AliLHCDipValI::TimeAsString(currTime),AliLHCDipValI::TimeAsString(fTMin)));
1057 return;
1058 }
1059 //
1060 if ((tprv=double(UInt_t(timeArr[nrec-1])))<fTMax) {
1061 AliWarning(Form("TimeStamp of last (%d) record: %s < TimeStamp of EOR: %s, Data will be truncated",nrec-1,
1062 AliLHCDipValI::TimeAsString(tprv),AliLHCDipValI::TimeAsString(fTMax)));
1063 }
1064 //
1065 // init the average time step
1066 period = (tprv - currTime)/(nrec-1);
1067 double lumiInt = 0;
1068 //
1069 for (int i=0;i<nrec;i++) {
1070 tprv = currTime;
1071 currTime = double(UInt_t(timeArr[i]));
1072 if (i>0) period = currTime - tprv;
1073 if (currTime-period>fTMax) continue;
1074 lumiInt += valArr[i]*period;
1075 // printf("%d %.2f V:%f Int:%f\n",i,period,valArr[i],lumiInt);
1076 if (currTime+period<fTMin) continue;
1077 AliLHCDipValF* curValF = new AliLHCDipValF(1,currTime);
1078 (*curValF)[0] = lumiInt;
1079 fData.Add(curValF);
1080 fLumiAlice[kNStor]++;
1081 }
1082 //
1083 printf("Stored %d Alice Integrated luminosity records out of %d provided\n",fLumiAlice[kNStor],nrec);
1084}
1085
1086//___________________________________________________________________
1087void AliLHCData::FillBckgAlice(Int_t nrec, Int_t* timeArr, Double_t* valArr)
1088{
1089 // Create a record for lumi integrated from the beginning of fill
1090 // We need dedicated method since this info comes from Alice (not LHCDip) as instantaneous values
1091 // and is retrofitted for past runs
1092 fBckgAlice[kStart] = fData.GetEntriesFast();
1093 fBckgAlice[kNStor] = 0;
1094 if (nrec<2 || !timeArr || !valArr) return;
1095 double tprv,period,currTime;
1096 if ((currTime=double(UInt_t(timeArr[0])))>fTMin) {
1097 AliError(Form("TimeStamp of 1st record: %s > TimeStamp of SOR: %s, STOP",
1098 AliLHCDipValI::TimeAsString(currTime),AliLHCDipValI::TimeAsString(fTMin)));
1099 return;
1100 }
1101 //
1102 if ((tprv=double(UInt_t(timeArr[nrec-1])))<fTMax) {
1103 AliWarning(Form("TimeStamp of last (%d) record: %s < TimeStamp of EOR: %s, Data will be truncated",nrec-1,
1104 AliLHCDipValI::TimeAsString(tprv),AliLHCDipValI::TimeAsString(fTMax)));
1105 }
1106 //
1107 // init the average time step
1108 period = (tprv - currTime)/(nrec-1);
1109 double bckgInt = 0;
1110 //
1111 for (int i=0;i<nrec;i++) {
1112 tprv = currTime;
1113 currTime = double(UInt_t(timeArr[i]));
1114 if (i>0) period = currTime - tprv;
1115 if (currTime-period>fTMax) continue;
1116 bckgInt += valArr[i]*period;
1117 if (currTime+period<fTMin) continue;
1118 AliLHCDipValF* curValF = new AliLHCDipValF(1,currTime);
1119 (*curValF)[0] = bckgInt;
1120 fData.Add(curValF);
1121 fBckgAlice[kNStor]++;
1122 }
1123 //
1124 printf("Stored %d Alice Integrated Background records out of %d provided\n",fBckgAlice[kNStor],nrec);
1125}
1126
1127//_____________________________________________________________________________
1128Float_t AliLHCData::GetLumiInstAlice(Double_t tStamp) const
1129{
1130 // get closest in time value on inst luminosity
1131 int idx = FindEntryValidFor(fLumiAlice[kStart],fLumiAlice[kNStor],tStamp);
1132 if (idx<0) return -1;
1133 AliLHCDipValF *rec=GetLumiAliceRecord(idx),*rec1=GetLumiAliceRecord(idx>0 ? idx-1:idx+1);
1134 if (!rec || !rec1) return -1;
1135 double dt = rec->GetTimeStamp() - rec1->GetTimeStamp();
1136 return TMath::Abs(dt)>1e-6 ? (rec->GetValue()-rec1->GetValue())/dt : -1;
1137}
1138
1139//_____________________________________________________________________________
1140Float_t AliLHCData::GetBckgInstAlice(Double_t tStamp) const
1141{
1142 // get closest in time value on inst luminosity
1143 int idx = FindEntryValidFor(fBckgAlice[kStart],fBckgAlice[kNStor],tStamp);
1144 if (idx<0) return -1;
1145 AliLHCDipValF *rec=GetBckgAliceRecord(idx),*rec1=GetBckgAliceRecord(idx>0 ? idx-1:idx+1);
1146 if (!rec || !rec1) return -1;
1147 double dt = rec->GetTimeStamp() - rec1->GetTimeStamp();
1148 return TMath::Abs(dt)>1e-6 ? (rec->GetValue()-rec1->GetValue())/dt : -1;
1149}
1150
1151//_____________________________________________________________________________
1152TGraph* AliLHCData::ExportGraph(Int_t *coord, Int_t elID) const
1153{
1154 // export time/values to graph:
1155 // coord: int[2] array with 1st entry and number of entries stored, obtained via GetOffs... method
1156 // elID - element of the AliLHCDipValT array to extract
1157 if (!coord || coord[1]<1) return 0;
1158 TGraph* gr = new TGraph(coord[1]);
1159 for (int i=0;i<coord[1];i++) {
1160 TObject* obj = fData.At(coord[0]+i);
1161 if (!obj) {
1162 AliError(Form("Entry %d does not exist",i));
1163 continue;
1164 }
1165 if (obj->IsA()==AliLHCDipValD::Class()) {
1166 AliLHCDipValD* objD = (AliLHCDipValD*)obj;
1167 gr->SetPoint(i,objD->GetTimeStamp(),objD->GetValue(elID));
1168 }
1169 else if (obj->IsA()==AliLHCDipValF::Class()) {
1170 AliLHCDipValF* objF = (AliLHCDipValF*)obj;
1171 gr->SetPoint(i,objF->GetTimeStamp(),objF->GetValue(elID));
1172 }
1173 else if (obj->IsA()==AliLHCDipValI::Class()) {
1174 AliLHCDipValI* objI = (AliLHCDipValI*)obj;
1175 gr->SetPoint(i,objI->GetTimeStamp(),objI->GetValue(elID));
1176 }
1177 else if (obj->IsA()==AliLHCDipValC::Class()) {
1178 AliLHCDipValC* objC = (AliLHCDipValC*)obj;
1179 gr->SetPoint(i,objC->GetTimeStamp(),objC->GetValue(elID));
1180 }
1181 else {
1182 AliError(Form("Graph cannot be exported for records of type %s",obj->IsA()->GetName()));
1183 }
1184 }
1185 return gr;
1186}