]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliLHCData.cxx
Fixes for Coverity warnings
[u/mrichter/AliRoot.git] / STEER / AliLHCData.cxx
1 /**************************************************************************\r
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *\r
3  *                                                                        *\r
4  * Author: The ALICE Off-line Project.                                    *\r
5  * Contributors are mentioned in the code where appropriate.              *\r
6  *                                                                        *\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
14  *                                                                        *\r
15  **************************************************************************/\r
16 \r
17 /********************************************************************************\r
18 *                                                                               *\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
21 *                                                                               *\r
22 *   The data are (wrapped in the AliLHCDipValT):                                *\r
23 *   made of TimeStamp (double) and array of values                              *\r
24 *                                                                               *\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
28 *                                                                               *\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
32 *                                                                               *\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
36 *                                                                               *\r
37 *                                                                               *\r
38 *   Author: ruben.shahoyan@cern.ch                                              *\r
39 *                                                                               *\r
40 ********************************************************************************/\r
41 \r
42 #include "AliLHCData.h"\r
43 #include "TMap.h"\r
44 #include "AliDCSArray.h"\r
45 #include "AliLHCReader.h"\r
46 #include <TString.h>\r
47 #include <TObjArray.h>\r
48 \r
49 ClassImp(AliLHCData)\r
50 \r
51 const Char_t* AliLHCData::fgkDCSNames[] = {\r
52   "LHC_IntensityBeam%1d_totalIntensity",\r
53   "LHC_BeamIntensityPerBunchBeam%1d_averageBeamIntensity",\r
54   "LHC_BeamIntensityPerBunchBeam%1d_Average_BunchIntensities",\r
55   //\r
56   "LHC_LumAverageBRANB_4%c2_acqMode",\r
57   "LHC_LumAverageBRANB_4%c2_meanLuminosity",\r
58   "LHC_LumAverageBRANB_4%c2_meanLuminosityError",\r
59   "LHC_BeamLuminosityPerBunchBRANB_4%c2_Average_BunchLuminosity",\r
60   "LHC_BeamLuminosityPerBunchBRANB_4%c2_BunchLuminosityError",\r
61   "LHC_LumAverageBRANB_4%c2_meanCrossingAngle",\r
62   "LHC_LumAverageBRANB_4%c2_meanCrossingAngleError",\r
63   "LHC_CirculatingBunchConfig_Beam%d",\r
64   "LHC_FillNumber",\r
65   //\r
66   "LHC_BunchLengthBeam%1d_nBunches",\r
67   "LHC_BunchLengthBeam%1d_bunchesLenghts",\r
68   "LHC_BunchLengthBeam%1d_filledBuckets",\r
69   //\r
70   "LHC_RunControl_ActiveInjectionScheme",\r
71   "LHC_RunControl_BetaStar",\r
72   "LHC_RunControl_IP2_Xing_Murad",\r
73   "LHC_RunControl_IP2_ALICE_Murad",\r
74 \r
75   "LHC_BeamSizeBeam%1d_acqMode",\r
76   "LHC_BeamSizeBeam%1d_sigmaH",\r
77   "LHC_BeamSizeBeam%1d_sigmaV",\r
78   "LHC_BeamSizeBeam%1d_emittanceH",\r
79   "LHC_BeamSizeBeam%1d_emittanceV",\r
80   "LHC_BeamSizeBeam%1d_errorSigmaH",\r
81   "LHC_BeamSizeBeam%1d_errorSigmaV",\r
82   //\r
83   "LHC_CollimatorPos_%s_lvdt_%s"\r
84 };\r
85 \r
86 const Char_t* AliLHCData::fgkDCSColNames[] = {\r
87   "TCTVB_4L2",\r
88   "TCTVB_4R2",\r
89   "TCLIA_4R2"\r
90 };\r
91 \r
92 const Char_t* AliLHCData::fgkDCSColJaws[] = {\r
93   "gap_downstream","gap_upstream","left_downstream",\r
94   "left_upstream","right_downstream","right_upstream"};\r
95 \r
96 //___________________________________________________________________\r
97 AliLHCData::AliLHCData(const TMap* dcsMap, double tmin, double tmax)\r
98   : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fFile2Process(0),fMap2Process(0)\r
99 {\r
100   FillData(dcsMap,tmin,tmax);\r
101 }\r
102 \r
103 //___________________________________________________________________\r
104 AliLHCData::AliLHCData(const Char_t* dcsFile, double tmin, double tmax)\r
105   : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fFile2Process(dcsFile),fMap2Process(0)\r
106 {\r
107   FillData(dcsFile,tmin,tmax);\r
108 }\r
109 \r
110 //___________________________________________________________________\r
111 Bool_t AliLHCData::FillData(const TMap*   dcsMap,double tmin, double tmax)\r
112 {\r
113   // process DCS map and fill all fields. \r
114   Clear();\r
115   fMap2Process = dcsMap;\r
116   FillData(tmin,tmax);\r
117   return kTRUE;\r
118 }\r
119 \r
120 //___________________________________________________________________\r
121 Bool_t AliLHCData::FillData(const Char_t* dcsFile,double tmin, double tmax)\r
122 {\r
123   // process DCS file and fill all fields. \r
124   Clear();\r
125   fFile2Process = dcsFile;\r
126   FillData(tmin,tmax);\r
127   return kTRUE;\r
128 }\r
129 \r
130 //___________________________________________________________________\r
131 Bool_t AliLHCData::FillData(double tmin, double tmax)\r
132 {\r
133   // process DCS map and fill all fields. \r
134   // Accept only entries with timestamp between tmin and tmax\r
135   //\r
136   char buff[100],buff1[100];\r
137   //\r
138   SetTMin(tmin);\r
139   SetTMax(tmax);\r
140   //\r
141   // -------------------------- extract Fill Number\r
142   int iFirst=0,iLast=0;\r
143   TObjArray* arr = GetDCSEntry(fgkDCSNames[kFillNum],iFirst,iLast,fTMin,fTMax);\r
144   if (arr) SetFillNumber( ExtractInt( (AliDCSArray*)arr->At(iFirst), 0) );\r
145   if (fFile2Process) delete arr; // array was created on demand\r
146   //\r
147   for (int ibm=0;ibm<2;ibm++) {\r
148     //\r
149     snprintf(buff,99,fgkDCSNames[kBunchConf],ibm+1);         // ----- declared bunch configuration\r
150     FillBunchConfig(fBunchConfDecl[ibm], buff);\r
151     //\r
152     snprintf(buff,99,fgkDCSNames[kBunchLgtFillB],ibm+1);     // ----- measured bunch configuration\r
153     FillBunchConfig(fBunchConfMeas[ibm], buff);\r
154     //\r
155     snprintf(buff,99,fgkDCSNames[kBunchLgt],ibm+1);          // ----- measured bunch lenghts\r
156     FillBunchInfo(fBunchLengths[ibm],buff,ibm,kFALSE);  \r
157     //\r
158     snprintf(buff,99,fgkDCSNames[kIntBunchAv],ibm+1);        // ----- B-by-B intensities\r
159     FillBunchInfo(fIntensPerBunch[ibm],buff,ibm,kTRUE);\r
160     //\r
161     //\r
162     snprintf(buff,99,fgkDCSNames[kIntTot],ibm+1);            // ----- total intensities for beam 1 and 2\r
163     FillScalarRecord(fIntensTotal[ibm], buff);\r
164     //\r
165     snprintf(buff,99,fgkDCSNames[kIntTotAv],ibm+1);          // ----- total intensities for beam 1 and 2 from B-by-B average\r
166     FillScalarRecord(fIntensTotalAv[ibm], buff);\r
167     //\r
168     snprintf(buff,99,fgkDCSNames[kBeamSzEmittH],ibm+1);      // ----- H emittance for beam 1 and 2 \r
169     FillScalarRecord(fEmittanceH[ibm], buff);\r
170     //\r
171     snprintf(buff,99,fgkDCSNames[kBeamSzEmittV],ibm+1);      // ----- V emittance for beam 1 and 2 \r
172     FillScalarRecord(fEmittanceV[ibm], buff);\r
173     //\r
174     snprintf(buff,99 ,fgkDCSNames[kBeamSzSigH],   ibm+1);    // ----- H sigmas and errors for beam 1 and 2 \r
175     snprintf(buff1,99,fgkDCSNames[kBeamSzSigHErr],ibm+1);\r
176     FillScalarRecord(fBeamSigmaH[ibm], buff, buff1);\r
177     //\r
178     snprintf(buff,99 ,fgkDCSNames[kBeamSzSigV],   ibm+1);    // ----- V sigmas and errors for beam 1 and 2 \r
179     snprintf(buff1,99,fgkDCSNames[kBeamSzSigVErr],ibm+1);\r
180     FillScalarRecord(fBeamSigmaV[ibm], buff, buff1);\r
181     //\r
182   }\r
183   //\r
184   FlagInteractingBunches(fBunchConfMeas[0],fBunchConfMeas[1]);\r
185   FlagInteractingBunches(fBunchConfDecl[0],fBunchConfDecl[1]);\r
186   //\r
187   for (int ilr=0;ilr<2;ilr++) {\r
188     //\r
189     snprintf(buff,99 ,fgkDCSNames[kLumBunch], ilr ? 'R':'L');       // ---- BC-by-BC luminosity at IP2 and its error\r
190     snprintf(buff1,99,fgkDCSNames[kLumBunchErr], ilr ? 'R':'L');\r
191     FillBCLuminosities(fLuminPerBC[ilr], buff, buff1, 0); // BRAN L uses beam2 as a reference, BRAN R - beam1\r
192     //\r
193     snprintf(buff,99 ,fgkDCSNames[kLumTot]   , ilr ? 'R':'L');       // ---- total luminosity at IP2 and its error\r
194     snprintf(buff1,99,fgkDCSNames[kLumTotErr], ilr ? 'R':'L');\r
195     FillScalarRecord(fLuminTotal[ilr], buff, buff1);\r
196     //\r
197     snprintf(buff,99 ,fgkDCSNames[kLumAcqMode], ilr ? 'R':'L');      // ---- luminosity acquisition mode\r
198     FillAcqMode(fLuminAcqMode[ilr], buff);\r
199     //\r
200     snprintf(buff,99, fgkDCSNames[kLumCrossAng]   , ilr ? 'R':'L');  //----- crossing angle at IP2 and its error\r
201     snprintf(buff1,99,fgkDCSNames[kLumCrossAngErr], ilr ? 'R':'L');\r
202     FillScalarRecord(fCrossAngle[ilr], buff, buff1);\r
203     //    \r
204   }\r
205   //\r
206   for (int icl=0;icl<kNCollimators;icl++) {             // ----- collimators positions\r
207     for (int jaw=0;jaw<kNJaws;jaw++) {\r
208       snprintf(buff,99,fgkDCSNames[kCollPos], fgkDCSColNames[icl],fgkDCSColJaws[jaw]);        \r
209       FillScalarRecord(fCollimators[icl][jaw], buff);\r
210     } // jaws\r
211   } // collimators\r
212   //\r
213   //\r
214   // RunControl info\r
215   FillStringRecord(fRCInjScheme, fgkDCSNames[kRCInjSch]);   // ---- active injection scheme\r
216   FillScalarRecord(fRCBeta, fgkDCSNames[kRCBeta]);          // ---- target beta \r
217   FillScalarRecord(fRCAngH, fgkDCSNames[kRCCrossAng]);      // ---- horisontal angle\r
218   FillScalarRecord(fRCAngV,fgkDCSNames[kRCVang] );          // ---- vertical angle\r
219   //\r
220   return kTRUE;\r
221 }\r
222 \r
223 //___________________________________________________________________\r
224 TObjArray* AliLHCData::GetDCSEntry(const char* key,int &entry,int &last,double tmin,double tmax) const\r
225 {\r
226   // extract array from the DCS map or file and find the first entry within the time limits\r
227   entry = -1;\r
228   last = -2;\r
229   TObjArray* arr;\r
230   if (fMap2Process) arr = (TObjArray*)fMap2Process->GetValue(key);\r
231   else if (fFile2Process) {\r
232     AliLHCReader rd;\r
233     arr = rd.ReadSingleLHCDP(fFile2Process,key);\r
234   }\r
235   else {\r
236     AliError("Neither DCS map nor DCS filename are set");\r
237     return 0;  \r
238   }\r
239   //\r
240   if (!arr || !arr->GetEntriesFast()) { \r
241     AliWarning(Form("No data for %s",key)); \r
242     if (fMap2Process) delete arr; // created on demand\r
243     return 0;\r
244   }\r
245   int ntot = arr->GetEntriesFast();\r
246   //\r
247   // search 1st entry before or at tmin\r
248   AliDCSArray* ent = 0;\r
249   Bool_t found = kFALSE;\r
250   for (entry=0;entry<ntot;entry++) {\r
251     ent = (AliDCSArray*)arr->At(entry);\r
252     if (ent->GetTimeStamp()>=tmin-kMarginSOR && ent->GetTimeStamp()<=tmax+kMarginEOR) {\r
253       found = kTRUE;\r
254       if (ent->GetTimeStamp()>tmin) break;\r
255     }\r
256   }\r
257   if (!found) {\r
258     entry = -1;\r
259     TString str;\r
260     str += AliLHCDipValD::TimeAsString(tmin);\r
261     str += " : ";\r
262     str += AliLHCDipValD::TimeAsString(tmax);\r
263     AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));\r
264     if (fMap2Process) delete arr; // created on demand\r
265     return 0;\r
266   }\r
267   if (entry>0) entry--;\r
268   //\r
269   // search last entry at or after tmin\r
270   ent = 0;\r
271   for (last=entry;last<ntot;last++) {\r
272     ent = (AliDCSArray*)arr->At(last);\r
273     if (ent->GetTimeStamp()>tmax) break;\r
274   }\r
275   if (last == ntot) last--;\r
276   else if (ent->GetTimeStamp()>tmax+kMarginEOR) last--;\r
277   //\r
278   return arr;\r
279 }\r
280 \r
281 //___________________________________________________________________\r
282 Int_t AliLHCData::TimeDifference(double v1,double v2,double tol) const\r
283 {\r
284   // return 0 if the times are the same within the tolerance\r
285   //        1 if v1>v2\r
286   //       -1 if v1<v2\r
287   v1-=v2;\r
288   if (v1>tol)  return  1;\r
289   if (v1<-tol) return -1;\r
290   return 0;\r
291 }\r
292 \r
293 //___________________________________________________________________\r
294 Bool_t AliLHCData::GoodPairID(int beam) const\r
295 {\r
296   // check for correct beam identifier \r
297   if (beam>kBeam2||beam<0) {AliError(Form("BeamID can be 0 or 1, %d requested",beam)); return kFALSE;}\r
298   return kTRUE;\r
299 }\r
300 \r
301 //___________________________________________________________________\r
302 AliLHCDipValI* AliLHCData::GetBunchConfigMeasured(int beam,double tstamp) const\r
303 {\r
304   // find measured bunch configuration valid for given tstamp\r
305   if (!GoodPairID(beam)) return 0;\r
306   return (AliLHCDipValI*)FindRecValidFor(fBunchConfMeas[beam][kStart],fBunchConfMeas[beam][kNStor],tstamp);\r
307 }\r
308 \r
309 //___________________________________________________________________\r
310 AliLHCDipValI* AliLHCData::GetBunchConfigDeclared(int beam,double tstamp) const\r
311 {\r
312   // find declared bunch configuration valid for given tstamp\r
313   if (!GoodPairID(beam)) return 0;\r
314   return (AliLHCDipValI*)FindRecValidFor(fBunchConfDecl[beam][kStart],fBunchConfDecl[beam][kNStor],tstamp);\r
315 }\r
316 \r
317 //___________________________________________________________________\r
318 TObject* AliLHCData::FindRecValidFor(int start,int nrec, double tstamp) const\r
319 {\r
320   // find record within this limits valid for given tstamp (i.e. the last one before or equal to tstamp)\r
321   AliLHCDipValI *prevObj = 0;\r
322   for (int i=0;i<nrec;i++) {\r
323     AliLHCDipValI* curObj = (AliLHCDipValI*)fData[start+i];\r
324     if (TimeDifference(tstamp,curObj->GetTimeStamp())<0) break;\r
325     prevObj = curObj;\r
326   }\r
327   if (!prevObj && nrec>0) prevObj = (AliLHCDipValI*)fData[start]; // if no exact match, return the 1st one\r
328   return prevObj;\r
329 }\r
330 \r
331 //___________________________________________________________________\r
332 Int_t AliLHCData::FillScalarRecord(int refs[2], const char* rec, const char* recErr)\r
333 {\r
334   // fill record for scalar value, optionally accompanied by measurement error \r
335   //\r
336   AliInfo(Form("Acquiring record: %s",rec));\r
337   //\r
338   TObjArray *arr=0,*arrE=0;\r
339   Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;\r
340   //\r
341   refs[kStart] = fData.GetEntriesFast();\r
342   refs[kNStor] = 0;\r
343   //\r
344   if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
345   //\r
346   int dim = 1;\r
347   if (recErr) {\r
348     arrE = GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);\r
349     dim += 1;\r
350   }\r
351   //\r
352   Bool_t last = kFALSE;\r
353   while (iFirst<=iLast) {\r
354     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
355     double tstamp = dcsVal->GetTimeStamp();\r
356     //\r
357     AliLHCDipValF* curValF = new AliLHCDipValF(dim,tstamp);  // start new period\r
358     (*curValF)[0] = ExtractDouble(dcsVal,0);     // value\r
359     //\r
360     if (recErr) {\r
361       double errVal = -1;\r
362       while (iFirstE<=iLastE) {       // try to find corresponding error\r
363         AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);\r
364         double tstampE = dcsValE->GetTimeStamp();\r
365         int tdif = TimeDifference(tstamp,tstampE);\r
366         if (!tdif) { // error matches to value\r
367           errVal = ExtractDouble(dcsValE,0);\r
368           iFirstE++; \r
369           break;\r
370         }\r
371         else if (tdif>0) iFirstE++; // error time lags behind, read the next one\r
372         else break;                 // error time is ahead of value, no error associated\r
373       }\r
374       (*curValF)[dim-1] = errVal;   // error\r
375       curValF->SetLastSpecial();    // lable the last entry as an error\r
376     }\r
377     //\r
378     fData.Add(curValF);\r
379     refs[kNStor]++;\r
380     if (last) break;\r
381   }\r
382   //\r
383   if (fFile2Process) {\r
384     delete arr;\r
385     delete arrE;\r
386   }\r
387   return refs[kNStor];\r
388 }\r
389 \r
390 //___________________________________________________________________\r
391 Int_t AliLHCData::FillBunchConfig(int refs[2],const char* rec)\r
392 {\r
393   // fill record for bunch configuration\r
394   //\r
395   AliInfo(Form("Acquiring record: %s",rec));\r
396   TObjArray *arr;\r
397   Int_t iLast,iFirst;\r
398   //\r
399   refs[kStart] = fData.GetEntriesFast();\r
400   refs[kNStor] = 0;\r
401   //\r
402   if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
403   //\r
404   AliLHCDipValI* prevRecI=0;\r
405   //  \r
406   while (iFirst<=iLast) {\r
407     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
408     double tstamp = dcsVal->GetTimeStamp();\r
409     //\r
410     int bucket=0, nbunch=0, ndiff=0;\r
411     int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)\r
412     int* dcsArr = dcsVal->GetInt();\r
413     while(nbunch<nSlots && (bucket=dcsArr[nbunch])) {\r
414       if (prevRecI && prevRecI->GetSize()>nbunch && bucket!=prevRecI->GetValue(nbunch)) ndiff++;\r
415       nbunch++;\r
416     }\r
417     if (!nbunch) AliWarning(Form("%s record is present but empty: no beam?",rec));\r
418     if (prevRecI && !ndiff && nbunch==prevRecI->GetSize()) continue; // record similar to previous one\r
419     AliLHCDipValI* curValI = new AliLHCDipValI(nbunch,tstamp);      \r
420     for (int i=nbunch;i--;) (*curValI)[i] = dcsArr[i];\r
421     fData.Add(curValI);\r
422     refs[kNStor]++;\r
423     prevRecI = curValI;\r
424   }\r
425   //\r
426   if (fFile2Process) delete arr;\r
427   return refs[kNStor];\r
428 }\r
429  \r
430 //___________________________________________________________________\r
431 Int_t AliLHCData::FillAcqMode(int refs[2],const char* rec)\r
432 {\r
433   // fill acquisition mode\r
434   //\r
435   AliInfo(Form("Acquiring record: %s",rec));\r
436   TObjArray *arr;\r
437   Int_t iLast,iFirst;\r
438   //\r
439   refs[kStart] = fData.GetEntriesFast();\r
440   refs[kNStor] = 0;\r
441   //\r
442   if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
443   //\r
444   AliLHCDipValI* prevRecI=0;\r
445   while (iFirst<=iLast) {\r
446     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
447     double tstamp = dcsVal->GetTimeStamp();\r
448     //\r
449     int nSlots = dcsVal->GetNEntries();\r
450     if (nSlots<1) continue;\r
451     int acqMode = dcsVal->GetInt()[0];\r
452     if (prevRecI && (*prevRecI)[0] == acqMode) continue; // record similar to previous one\r
453     AliLHCDipValI* curValI = new AliLHCDipValI(1,tstamp);      \r
454     (*curValI)[0] = acqMode;\r
455     fData.Add(curValI);\r
456     refs[kNStor]++;\r
457     prevRecI = curValI;\r
458   }\r
459   //\r
460   if (fFile2Process) delete arr;\r
461   return refs[kNStor];\r
462 }\r
463  \r
464 //___________________________________________________________________\r
465 Int_t AliLHCData::FillStringRecord(int refs[2],const char* rec)\r
466 {\r
467   // fill record with string value\r
468   //\r
469   AliInfo(Form("Acquiring record: %s",rec));\r
470   TString prevRec;\r
471   TObjArray *arr;\r
472   Int_t iLast,iFirst;\r
473   //\r
474   refs[kStart] = fData.GetEntriesFast();\r
475   refs[kNStor] = 0;\r
476   //\r
477   if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
478   //\r
479   while (iFirst<=iLast) {\r
480     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
481     double tstamp = dcsVal->GetTimeStamp();\r
482     //\r
483     TString &str = ExtractString(dcsVal);\r
484     if (!prevRec.IsNull()) {if (str == prevRec) continue;} // skip similar record\r
485     else prevRec = str;\r
486     //\r
487     AliLHCDipValC* curValS = new AliLHCDipValC(1,tstamp);      \r
488     curValS->SetValues(str.Data(),str.Length()+1);\r
489     //\r
490     fData.Add(curValS);\r
491     refs[kNStor]++;\r
492   }\r
493   if (fFile2Process) delete arr;\r
494   return refs[kNStor];\r
495 }\r
496 \r
497 //___________________________________________________________________\r
498 Int_t AliLHCData::FillBunchInfo(int refs[2],const char* rec, int ibm, Bool_t inRealSlots)\r
499 {\r
500   // fill bunch properties for beam ibm\r
501   // if inRealSlots = true, then the value is taken from bunchRFbucket/10, otherwise, the value \r
502   // for the i-th bunch is taken from the i-th element\r
503   //\r
504   AliInfo(Form("Acquiring record: %s",rec));\r
505   TObjArray *arr;\r
506   Int_t iLast,iFirst;\r
507   //\r
508   refs[kStart] = fData.GetEntriesFast();\r
509   refs[kNStor] = 0;\r
510   //\r
511   if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
512   //\r
513   while (iFirst<=iLast) {\r
514     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
515     double tstamp = dcsVal->GetTimeStamp();\r
516     //\r
517     AliLHCDipValI *bconf = GetBunchConfigMeasured(ibm,tstamp);\r
518     if (!bconf) {\r
519       AliWarning(Form("Mearured bunch configuration for beam %d at t=%.1f is not available, trying declared one",ibm+1,tstamp));\r
520       bconf = GetBunchConfigDeclared(ibm,tstamp);\r
521     }\r
522     if (!bconf) {\r
523       AliWarning(Form("Declared bunch configuration for beam %d at t=%.1f is not available, skip this record",ibm+1,tstamp));\r
524       return -1;\r
525     }\r
526     int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)\r
527     int nbunch = bconf->GetSize();\r
528     if (nbunch>nSlots) {\r
529       AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));\r
530       continue;\r
531     }\r
532     double* dcsArr = dcsVal->GetDouble();\r
533     AliLHCDipValF* curValF = new AliLHCDipValF(nbunch,tstamp);\r
534     for (int i=nbunch;i--;) {\r
535       int ind = inRealSlots ? (*bconf)[i]/10 : i;\r
536       if (ind>nSlots) {\r
537         AliError(Form("Bunch %d refers to wrong slot %d, set to -1",i,(*bconf)[i]));\r
538         (*curValF)[i] = -1;\r
539       }\r
540       else (*curValF)[i] = dcsArr[ind];\r
541     }\r
542     fData.Add(curValF);\r
543     refs[kNStor]++;\r
544   }\r
545   if (fFile2Process) delete arr;\r
546   return refs[kNStor];\r
547   //\r
548 }\r
549  \r
550 //___________________________________________________________________\r
551 Int_t AliLHCData::FillBCLuminosities(int refs[2],const char* rec, const char* recErr, int useBeam)\r
552 {\r
553   // fill luminosities per bunch crossing\r
554   //\r
555   AliInfo(Form("Acquiring record: %s",rec));\r
556   TObjArray *arr,*arrE=0;\r
557   Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;\r
558   //\r
559   refs[kStart] = fData.GetEntriesFast();\r
560   refs[kNStor] = 0;\r
561   //\r
562   if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r
563   //\r
564   while (iFirst<=iLast) {\r
565     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r
566     double tstamp = dcsVal->GetTimeStamp();\r
567     //\r
568     AliLHCDipValI *bconf;\r
569     bconf = GetBunchConfigMeasured(useBeam,tstamp);  // luminosities are stored according to beam bunches\r
570     if (!bconf) {\r
571       AliWarning(Form("Mearured bunch configuration for beam%d at t=%.1f is not available, trying declared one",useBeam,tstamp));\r
572       bconf = GetBunchConfigDeclared(useBeam,tstamp);\r
573     }\r
574     if (!bconf) {\r
575       AliWarning(Form("Declared bunch configuration for beam%i at t=%.1f is not available, skip this record",useBeam,tstamp));\r
576       return -1;\r
577     }\r
578     int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)\r
579     int nbunch = bconf->GetSize();\r
580     double* dcsArr = dcsVal->GetDouble();\r
581     //\r
582     if (nbunch>nSlots) {\r
583       AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));\r
584       continue;\r
585     }\r
586     int dim = 0;\r
587     if (!bconf->IsProcessed1()) {\r
588       AliWarning(Form("Bunch conf. for beam%d has no marked interacting bunches, store all luminosity for all filled bunches",useBeam));\r
589       dim = nbunch;\r
590     }\r
591     else { // count number of interacting bunches\r
592       for (int i=nbunch;i--;) if ((*bconf)[i]<0) dim++;\r
593     }\r
594     //\r
595     if (recErr) {\r
596       arrE=GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);\r
597       dim += 1;\r
598     }\r
599     AliLHCDipValF* curValF = new AliLHCDipValF(dim,tstamp);\r
600     int cnt = 0;\r
601     for (int i=0;i<nbunch;i++) {\r
602       int slot = (*bconf)[i];\r
603       if (bconf->IsProcessed1() && slot>0) continue;\r
604       //\r
605       int ind = TMath::Abs(slot)/10;\r
606       if (ind>nSlots) {\r
607         AliError(Form("Bunch %d refers to wrong slot %d, set to -1",cnt,slot));\r
608         (*curValF)[cnt] = -1;\r
609       }\r
610       else (*curValF)[cnt] = dcsArr[ind];\r
611       cnt++;\r
612     }\r
613     //\r
614     if (recErr) {\r
615       double errVal = -1;\r
616       while (iFirstE<=iLastE) {       // try to find corresponding error\r
617         AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);\r
618         double tstamp1 = dcsValE->GetTimeStamp();\r
619         int tdif = TimeDifference(tstamp,tstamp1);\r
620         if (!tdif) { // error matches to value\r
621           errVal = dcsValE->GetDouble()[0];\r
622           iFirstE++; \r
623           break;\r
624         }\r
625         else if (tdif>0) iFirstE++; // error time lags behind, read the next one\r
626         else break;                 // error time is ahead of value, no error associated\r
627       }\r
628       (*curValF)[dim-1] = errVal;   // error\r
629       curValF->SetLastSpecial();    // lable the last entry as an error\r
630     }\r
631     //\r
632     fData.Add(curValF);\r
633     refs[kNStor]++;\r
634   }\r
635   if (fFile2Process) {\r
636     delete arr;\r
637     delete arrE;\r
638   }\r
639   return refs[kNStor];\r
640   //\r
641 }\r
642 \r
643 //___________________________________________________________________\r
644 Int_t AliLHCData::ExtractInt(AliDCSArray* dcsArray,Int_t el) const\r
645 {\r
646   // extract integer from the dcsArray\r
647   int val = -1;\r
648   //\r
649   int sz = dcsArray->GetNEntries();\r
650   if (sz<=el) return val;\r
651   //\r
652   if (dcsArray->GetType()==AliDCSArray::kInt)  val = dcsArray->GetInt(el);\r
653   else if (dcsArray->GetType()==AliDCSArray::kString) {\r
654     TObjString *stro = dcsArray->GetStringArray(el);\r
655     if (stro) val = stro->GetString().Atoi();\r
656     else AliError(Form("DCSArray TObjString for element %d is missing",el));\r
657   }\r
658   else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);\r
659   else AliError(Form("Integer requested from DCSArray of type %d",dcsArray->GetType()));\r
660   return val;\r
661 }\r
662 \r
663 //___________________________________________________________________\r
664 Double_t AliLHCData::ExtractDouble(AliDCSArray* dcsArray,Int_t el) const\r
665 {\r
666   // extract double from the dcsArray\r
667   double val = 0;\r
668   //\r
669   int sz = dcsArray->GetNEntries();\r
670   if (sz<=el) return val;\r
671   //\r
672   if      (dcsArray->GetType()==AliDCSArray::kDouble) val = dcsArray->GetDouble(el);\r
673   else if (dcsArray->GetType()==AliDCSArray::kFloat)  val = dcsArray->GetFloat(el);\r
674   else if (dcsArray->GetType()==AliDCSArray::kString) {\r
675     TObjString *stro = dcsArray->GetStringArray(el);\r
676     if (stro) val = stro->GetString().Atof();\r
677     else AliError(Form("DCSArray has TObjString for element %d is missing",el));\r
678   }\r
679   else if (dcsArray->GetType()==AliDCSArray::kChar)   val = dcsArray->GetChar(el);\r
680   else if (dcsArray->GetType()==AliDCSArray::kInt)    val = dcsArray->GetInt(el);\r
681   else if (dcsArray->GetType()==AliDCSArray::kUInt)   val = dcsArray->GetUInt(el);\r
682   else     AliError(Form("Double requested from DCSArray of type %d",dcsArray->GetType()));\r
683   return val;\r
684 }\r
685 \r
686 //___________________________________________________________________\r
687 TString& AliLHCData::ExtractString(AliDCSArray* dcsArray) const\r
688 {\r
689   // extract string from the dcsArray\r
690   static TString str;\r
691   str = "";\r
692   //\r
693   int sz = dcsArray->GetNEntries();\r
694   if (dcsArray->GetType()!=AliDCSArray::kString)  {\r
695     AliError(Form("String requested from DCSArray of type %d",dcsArray->GetType()));\r
696     return str;\r
697   }\r
698   //\r
699   for (int i=0;i<sz;i++) {\r
700     str += dcsArray->GetStringArray(i)->GetString();\r
701     if (i<sz-1) str += " ";\r
702   }\r
703   return str;\r
704 }\r
705 \r
706 //___________________________________________________________________\r
707 void AliLHCData::Print(const Option_t* opt) const\r
708 {\r
709   // print full info\r
710   TString opts = opt;\r
711   opts.ToLower();\r
712   Bool_t utcTime = opts.Contains("loc") ? kFALSE:kTRUE;\r
713   Bool_t full = kTRUE;\r
714   if (!opts.Contains("f")) {\r
715     printf("Use Print(\"f\") to print full info\n");\r
716     printf("Printing short info:\n<RecordType>(number of records): <TimeStamp, value> for 1st record only\n");\r
717     full = kFALSE;\r
718   }\r
719   TString sdtmn = AliLHCDipValI::TimeAsString(fTMin,utcTime);\r
720   TString sdtmx = AliLHCDipValI::TimeAsString(fTMax,utcTime);\r
721   printf("Fill#%6d Validity: %s - %s (%s)\n",fFillNumber,sdtmn.Data(),sdtmx.Data(),utcTime ? "UTC":"LOC");\r
722   //\r
723   printf("********** SETTINGS FROM RUN CONTROL **********\n");\r
724   //\r
725   printf("* %-38s","Injection Scheme");\r
726   PrintAux(full,fRCInjScheme,opts);\r
727   //\r
728   printf("* %-38s","Beta Star");\r
729   PrintAux(full,fRCBeta,opts);\r
730   //\r
731   printf("* %-38s","Horisontal Crossing Angle");\r
732   PrintAux(full,fRCAngH,opts);\r
733   //\r
734   printf("* %-38s","Vertical   Crossing Angle");\r
735   PrintAux(full,fRCAngV,opts);\r
736   //\r
737   for (int ib=0;ib<2;ib++) {\r
738     printf("* Beam%d filling  [- interacts at IR2!]  ",ib+1);\r
739     PrintAux(full,fBunchConfDecl[ib],opts);\r
740   }\r
741   //\r
742   printf("\n**********       MEASURED DATA       **********\n");\r
743   //\r
744   for (int ib=0;ib<2;ib++) {\r
745     printf("* Beam%d filling  [- interacts at IR2!]  ",ib+1);\r
746     PrintAux(full,fBunchConfMeas[ib],opts);\r
747   } \r
748   //\r
749   for (int ib=0;ib<2;ib++) {\r
750     printf("* Beam%d total intensity                 ",ib+1);\r
751     PrintAux(full,fIntensTotal[ib],opts);\r
752   } \r
753   //\r
754   for (int ib=0;ib<2;ib++) {\r
755     printf("* Beam%d total intensity (bunch average) ",ib+1);\r
756     PrintAux(full,fIntensTotalAv[ib],opts);\r
757   } \r
758   //\r
759   for (int ib=0;ib<2;ib++) {\r
760     printf("* Beam%d intensity per bunch             ",ib+1);\r
761     PrintAux(full,fIntensPerBunch[ib],opts);\r
762   }\r
763   //\r
764   for (int ib=0;ib<2;ib++) {\r
765     printf("* Beam%d bunch lengths                   ",ib+1);\r
766     PrintAux(full,fBunchLengths[ib],opts);\r
767   } \r
768   //\r
769   for (int ib=0;ib<2;ib++) {\r
770     printf("* Beam%d Horisontal emittance            ",ib+1);\r
771     PrintAux(full,fEmittanceH[ib],opts);\r
772   }\r
773   //\r
774   for (int ib=0;ib<2;ib++) {\r
775     printf("* Beam%d Vertical emittance              ",ib+1);\r
776     PrintAux(full,fEmittanceV[ib],opts);\r
777   }\r
778   //\r
779   for (int ib=0;ib<2;ib++) {\r
780     printf("* Beam%d Horisontal sigma                ",ib+1);\r
781     PrintAux(full,fBeamSigmaH[ib],opts);\r
782   }\r
783   //\r
784   for (int ib=0;ib<2;ib++) {\r
785     printf("* Beam%d Vertical sigma                  ",ib+1);\r
786     PrintAux(full,fBeamSigmaV[ib],opts);\r
787   }\r
788   //\r
789   for (int lr=0;lr<2;lr++) {\r
790     printf("* Total luminosity from BRANB_4%c2       ",lr ? 'R':'L');\r
791     PrintAux(full,fLuminTotal[lr],opts);\r
792   } \r
793   //\r
794   for (int lr=0;lr<2;lr++) {\r
795     printf("* Luminosity acq.mode, BRANB_4%c2        ",lr ? 'R':'L');\r
796     PrintAux(full,fLuminAcqMode[lr],opts+"bit");\r
797   } \r
798   //\r
799   for (int lr=0;lr<2;lr++) {\r
800     printf("* Luminosity per BC from BRANB_4%c2      ",lr ? 'R':'L');\r
801     PrintAux(full,fLuminPerBC[lr],opts);\r
802   }\r
803   //\r
804   for (int lr=0;lr<2;lr++) {\r
805     printf("* Crossing angle, side %c                ",lr ? 'R':'L');\r
806     PrintAux(full,fCrossAngle[lr],opts);\r
807   }\r
808   //\r
809   for (int coll=0;coll<kNCollimators;coll++)\r
810     for (int jaw=0;jaw<kNJaws;jaw++) {\r
811       printf("* Collimator %10s:%16s",fgkDCSColNames[coll],fgkDCSColJaws[jaw]);\r
812       PrintAux(full,fCollimators[coll][jaw],opts);\r
813     }\r
814   //\r
815 }\r
816 \r
817 //___________________________________________________________________\r
818 void AliLHCData::PrintAux(Bool_t full, const Int_t refs[2], const Option_t *opt) const\r
819 {\r
820   // aux method to print the reocrds of the same type\r
821   int nrec = refs[kNStor];\r
822   if (nrec<1) {\r
823     printf(": N/A\n"); \r
824     return;\r
825   }\r
826   printf(": (%3d):\t",nrec); // number of records\r
827   if (!full) nrec = 1;\r
828   int sz = ((AliLHCDipValI*)fData[refs[kStart]])->GetSizeTotal(); // dimension of the record\r
829   Bool_t isStr = ((AliLHCDipValI*)fData[refs[kStart]])->IsTypeC();\r
830   if ((!isStr && sz>2) || nrec>1) printf("\n"); // long record, open new line\r
831   for (int i=0;i<nrec;i++) fData[refs[kStart]+i]->Print(opt);\r
832   //\r
833 }\r
834 \r
835 //___________________________________________________________________\r
836 void AliLHCData::Clear(const Option_t *)\r
837 {\r
838   // clear all info\r
839   fData.Delete();\r
840   fFillNumber = 0;\r
841   fTMin = 0;\r
842   fTMax = 1e10;\r
843   fFile2Process = 0;\r
844   fMap2Process  = 0;\r
845   //\r
846   for (int i=2;i--;) {\r
847     fRCInjScheme[i] = 0;\r
848     fRCBeta[i] = 0;\r
849     fRCAngH[i] = 0;\r
850     fRCAngV[i] = 0;\r
851     //\r
852     for (int icl=kNCollimators;icl--;) for (int jaw=kNJaws;jaw--;) fCollimators[icl][jaw][i]=0;\r
853     //\r
854     for (int j=2;j--;) {\r
855       fBunchConfDecl[j][i] = 0;\r
856       fBunchConfMeas[j][i] = 0;\r
857       fBunchLengths[j][i] = 0;\r
858       fIntensTotal[j][i] = 0;\r
859       fIntensTotalAv[j][i] = 0;\r
860       fIntensPerBunch[j][i] = 0;      \r
861       fCrossAngle[j][i] = 0;\r
862       fEmittanceH[j][i] = 0;\r
863       fEmittanceV[j][i] = 0;\r
864       fBeamSigmaH[j][i] = 0;\r
865       fBeamSigmaV[j][i] = 0;\r
866       fLuminTotal[j][i] = 0;\r
867       fLuminPerBC[j][i] = 0;\r
868       fLuminAcqMode[j][i] = 0;\r
869     }\r
870   }\r
871 }\r
872 \r
873 //___________________________________________________________________\r
874 Int_t AliLHCData::GetNInteractingBunchesMeasured(int i) const\r
875 {\r
876   // get number of interacting bunches at IR2\r
877   AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r
878   if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
879   if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1;}\r
880   int n = 0;\r
881   for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;\r
882   return n;\r
883 }\r
884 \r
885 //___________________________________________________________________\r
886 Int_t AliLHCData::GetNInteractingBunchesDeclared(int i) const\r
887 {\r
888   // get number of interacting bunches at IR2\r
889   AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r
890   if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
891   if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1; }\r
892   int n = 0;\r
893   for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;\r
894   return n;\r
895 }\r
896 \r
897 //___________________________________________________________________\r
898 Int_t AliLHCData::IsPilotPresent(int i) const\r
899 {\r
900   // check in the filling scheme is the pilot bunch is present\r
901   AliLHCDipValC* rec = GetInjectionScheme();\r
902   if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
903   TString scheme = rec->GetValues();\r
904   return scheme.Contains("wp",TString::kIgnoreCase);\r
905 }\r
906 \r
907 //___________________________________________________________________\r
908 void AliLHCData::FlagInteractingBunches(const Int_t beam1[2],const Int_t beam2[2])\r
909 {\r
910   // assign - sign to interacting bunches\r
911   const int kMaxSlots  = 3564;\r
912   const int kOffsBeam1 = 346;\r
913   const int kOffsBeam2 = 3019;\r
914   //\r
915   for (int ib1=0;ib1<beam1[kNStor];ib1++) {\r
916     AliLHCDipValI *bm1 = (AliLHCDipValI*)fData[ beam1[kStart] + ib1];\r
917     if (!bm1) continue;\r
918     AliLHCDipValI *bm2 = (AliLHCDipValI*)FindRecValidFor(beam2[kStart],beam2[kNStor], bm1->GetTimeStamp());\r
919     if (!bm2) continue;\r
920     //\r
921     int nb1 = bm1->GetSize();\r
922     int nb2 = bm2->GetSize();\r
923     int i1,i2;\r
924     for (i1=0;i1<nb1;i1++) {\r
925       int bunch2=-1, bunch1 = TMath::Abs((*bm1)[i1]);\r
926       int slot2 =-1, slot1  = (bunch1/10 + kOffsBeam1)%kMaxSlots;\r
927       for (i2=0;i2<nb2;i2++) {\r
928         bunch2 = TMath::Abs((*bm2)[i2]);\r
929         slot2 = (bunch2/10 + kOffsBeam2)%kMaxSlots;\r
930         if (slot1==slot2) break;\r
931       }\r
932       if (slot1!=slot2) continue;\r
933       (*bm1)[i1] = -bunch1;\r
934       (*bm2)[i2] = -bunch2;\r
935       bm1->SetProcessed1();\r
936       bm2->SetProcessed1();\r
937     }\r
938   }\r
939 }\r
940 \r
941 //___________________________________________________________________\r
942 Int_t AliLHCData::GetMeanIntensity(int beamID, Double_t &colliding, Double_t &noncolliding) const\r
943 {\r
944   // get average intensity for all, colliding and non-colliding bunches\r
945   // on success returns number of intensity records used (1 per ~10 min)\r
946   colliding = noncolliding = -1.;\r
947   if (beamID<0||beamID>1) {\r
948     AliError(Form("BeamID must be either 0 or 1, %d requested",beamID));\r
949     return -10;\r
950   }\r
951   //\r
952   int nrec = GetNIntensityPerBunch(beamID);\r
953   if (nrec<1) return -1;\r
954   AliLHCDipValI *conf = GetBunchConfigMeasured(beamID);\r
955   if (!conf) conf = GetBunchConfigDeclared(beamID);\r
956   if (!conf) return -2;\r
957   int nb = conf->GetSize();\r
958   //\r
959   for (int irec=0;irec<nrec;irec++) {\r
960     AliLHCDipValF* rInt = GetIntensityPerBunch(beamID,irec);\r
961     for (int ib=0;ib<nb;ib++) {\r
962       double val = rInt->GetValue(ib);\r
963       if (val<0) continue;\r
964       int bID = conf->GetValue(ib);\r
965       if (bID<0) colliding += val;\r
966       else noncolliding += val;\r
967     }\r
968   }\r
969   colliding /= nrec;\r
970   noncolliding /= nrec;\r
971   return nrec;\r
972 }\r