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