]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliLHCData.cxx
The class for LHC DIP data was completely changed
[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   SetTMin(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);          // ----- maesured 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   for (int ilr=0;ilr<2;ilr++) {\r
159     //\r
160     sprintf(buff ,fgkDCSNames[kLumBunch], ilr ? 'R':'L');       // ---- BC-by-BC luminosity at IP2 and its error\r
161     sprintf(buff1,fgkDCSNames[kLumBunchErr], ilr ? 'R':'L');\r
162     FillBCLuminosities(dcsMap, fLuminPerBC[ilr], buff, buff1, kTRUE);\r
163     //\r
164     sprintf(buff ,fgkDCSNames[kLumTot]   , ilr ? 'R':'L');       // ---- total luminosity at IP2 and its error\r
165     sprintf(buff1,fgkDCSNames[kLumTotErr], ilr ? 'R':'L');\r
166     FillScalarRecord(dcsMap, fLuminTotal[ilr], buff, buff1);\r
167     //\r
168     sprintf(buff ,fgkDCSNames[kLumAcqMode], ilr ? 'R':'L');      // ---- luminosity acquisition mode\r
169     FillAcqMode(dcsMap, fLuminAcqMode[ilr], buff);\r
170     //\r
171     sprintf(buff, fgkDCSNames[kLumCrossAng]   , ilr ? 'R':'L');  //----- crossing angle at IP2 and its error\r
172     sprintf(buff1,fgkDCSNames[kLumCrossAngErr], ilr ? 'R':'L');\r
173     FillScalarRecord(dcsMap, fCrossAngle[ilr], buff, buff1);\r
174     //    \r
175   }\r
176   //\r
177   for (int icl=0;icl<kNCollimators;icl++) {             // ----- collimators positions\r
178     for (int jaw=0;jaw<kNJaws;jaw++) {\r
179       sprintf(buff,fgkDCSNames[kCollPos], fgkDCSColNames[icl],fgkDCSColJaws[jaw]);        \r
180       FillScalarRecord(dcsMap, fCollimators[icl][jaw], buff);\r
181     } // jaws\r
182   } // collimators\r
183   //\r
184   //\r
185   // RunControl info\r
186   FillStringRecord(dcsMap, fRCInjScheme, fgkDCSNames[kRCInjSch]);   // ---- active injection scheme\r
187   FillScalarRecord(dcsMap, fRCBeta, fgkDCSNames[kRCBeta]);          // ---- target beta \r
188   FillScalarRecord(dcsMap, fRCAngH, fgkDCSNames[kRCCrossAng]);      // ---- horisontal angle\r
189   FillScalarRecord(dcsMap, fRCAngV,fgkDCSNames[kRCVang] );          // ---- vertical angle\r
190   //\r
191   return kTRUE;\r
192 }\r
193 \r
194 //___________________________________________________________________\r
195 TObjArray* AliLHCData::GetDCSEntry(const TMap* dcsMap,const char* key,int &entry,double tmin,double tmax) const\r
196 {\r
197   // extract array from the DCS map and find the first entry within the time limits\r
198   entry = -1;\r
199   TObjArray* arr = (TObjArray*)dcsMap->GetValue(key);\r
200   if (!arr || !arr->GetEntriesFast()) { \r
201     AliWarning(Form("No data for %s",key)); \r
202     return 0;\r
203   }\r
204   int ntot = arr->GetEntriesFast();\r
205   for (entry=0;entry<ntot;entry++) {\r
206     AliDCSArray* ent = (AliDCSArray*)arr->At(entry);\r
207     if (ent->GetTimeStamp()>=tmin && ent->GetTimeStamp()<=tmax) break;\r
208   }\r
209   if (entry==ntot) {\r
210     entry = -1;\r
211     TString str;\r
212     str += AliLHCDipValD::TimeAsString(tmin);\r
213     str += " : ";\r
214     str += AliLHCDipValD::TimeAsString(tmax);\r
215     AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));\r
216   }\r
217   return arr;\r
218 }\r
219 \r
220 //___________________________________________________________________\r
221 Int_t AliLHCData::TimeDifference(double v1,double v2,double tol) const\r
222 {\r
223   // return 0 if the times are the same within the tolerance\r
224   //        1 if v1>v2\r
225   //       -1 if v1<v2\r
226   v1-=v2;\r
227   if (v1>tol)  return  1;\r
228   if (v1<-tol) return -1;\r
229   return 0;\r
230 }\r
231 \r
232 //___________________________________________________________________\r
233 Bool_t AliLHCData::GoodPairID(int beam) const\r
234 {\r
235   // check for correct beam identifier \r
236   if (beam>kBeam2||beam<0) {AliError(Form("BeamID can be 0 or 1, %d requested",beam)); return kFALSE;}\r
237   return kTRUE;\r
238 }\r
239 \r
240 //___________________________________________________________________\r
241 AliLHCDipValI* AliLHCData::GetBunchConfigMeasured(int beam,double tstamp) const\r
242 {\r
243   // find measured bunch configuration valid for given tstamp\r
244   if (!GoodPairID(beam)) return 0;\r
245   return (AliLHCDipValI*)FindRecValidFor(fBunchConfMeas[beam][kStart],fBunchConfMeas[beam][kNStor],tstamp);\r
246 }\r
247 \r
248 //___________________________________________________________________\r
249 AliLHCDipValI* AliLHCData::GetBunchConfigDeclared(int beam,double tstamp) const\r
250 {\r
251   // find declared bunch configuration valid for given tstamp\r
252   if (!GoodPairID(beam)) return 0;\r
253   return (AliLHCDipValI*)FindRecValidFor(fBunchConfDecl[beam][kStart],fBunchConfDecl[beam][kNStor],tstamp);\r
254 }\r
255 \r
256 //___________________________________________________________________\r
257 TObject* AliLHCData::FindRecValidFor(int start,int nrec, double tstamp) const\r
258 {\r
259   // find record within this limits valid for given tstamp (i.e. the last one before or equal to tstamp)\r
260   AliLHCDipValI *prevObj = 0;\r
261   for (int i=0;i<nrec;i++) {\r
262     AliLHCDipValI* curObj = (AliLHCDipValI*)fData[start+i];\r
263     if (TimeDifference(tstamp,curObj->GetTimeStamp())>0) break;\r
264     prevObj = curObj;\r
265   }\r
266   if (!prevObj && nrec>0) prevObj = (AliLHCDipValI*)fData[start]; // if no exact match, return the 1st one\r
267   return prevObj;\r
268 }\r
269 \r
270 //___________________________________________________________________\r
271 Int_t AliLHCData::FillScalarRecord(const TMap* dcsMap, int refs[2], const char* rec, const char* recErr)\r
272 {\r
273   // fill record for scalar value, optionally accompanied by measurement error \r
274   //\r
275   AliInfo(Form("Acquiring record: %s",rec));\r
276   //\r
277   TObjArray *arr,*arrE;\r
278   Int_t nEntries,nEntriesE,iEntry,iEntryE;\r
279   //\r
280   refs[kStart] = fData.GetEntriesFast();\r
281   refs[kNStor] = 0;\r
282   //\r
283   if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
284   nEntries = arr->GetEntriesFast();\r
285   //\r
286   int dim = 1;\r
287   if (recErr) {\r
288     if ( !(arrE=GetDCSEntry(dcsMap,recErr,iEntryE,fTMin,fTMax)) || iEntryE<0 ) nEntriesE = -999;\r
289     else nEntriesE = arrE->GetEntriesFast();\r
290     dim += 1;\r
291   }\r
292   //\r
293   while (iEntry<nEntries) {\r
294     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
295     double tstamp = dcsVal->GetTimeStamp();\r
296     if (tstamp>fTMax) break;\r
297     //\r
298     AliLHCDipValF* curValF = new AliLHCDipValF(dim,tstamp);  // start new period\r
299     (*curValF)[0] = ExtractDouble(dcsVal,0);     // value\r
300     //\r
301     if (recErr) {\r
302       double errVal = -1;\r
303       while (iEntryE<nEntriesE) {       // try to find corresponding error\r
304         AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iEntryE);\r
305         double tstampE = dcsValE->GetTimeStamp();\r
306         if (tstampE>fTMax) break;\r
307         int tdif = TimeDifference(tstamp,tstampE);\r
308         if (!tdif) { // error matches to value\r
309           errVal = ExtractDouble(dcsValE,0);\r
310           iEntryE++; \r
311           break;\r
312         }\r
313         else if (tdif>0) iEntryE++; // error time lags behind, read the next one\r
314         else break;                 // error time is ahead of value, no error associated\r
315       }\r
316       (*curValF)[dim-1] = errVal;   // error\r
317       curValF->SetLastSpecial();    // lable the last entry as an error\r
318     }\r
319     //\r
320     fData.Add(curValF);\r
321     refs[kNStor]++;\r
322   }\r
323   //\r
324   return refs[kNStor];\r
325 }\r
326 \r
327 //___________________________________________________________________\r
328 Int_t AliLHCData::FillBunchConfig(const TMap* dcsMap, int refs[2],const char* rec)\r
329 {\r
330   // fill record for bunch configuration\r
331   //\r
332   AliInfo(Form("Acquiring record: %s",rec));\r
333   TObjArray *arr;\r
334   Int_t nEntries,iEntry;\r
335   //\r
336   refs[kStart] = fData.GetEntriesFast();\r
337   refs[kNStor] = 0;\r
338   //\r
339   if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
340   nEntries = arr->GetEntriesFast();\r
341   //\r
342   AliLHCDipValI* prevRecI=0;\r
343   while (iEntry<nEntries) {\r
344     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
345     double tstamp = dcsVal->GetTimeStamp();\r
346     if (tstamp>fTMax) break;\r
347     //\r
348     int bucket=0, nbunch=0, ndiff=0;\r
349     int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)\r
350     int* dcsArr = dcsVal->GetInt();\r
351     while(nbunch<nSlots && (bucket=dcsArr[nbunch])) {\r
352       if (prevRecI && prevRecI->GetSize()>nbunch && bucket!=prevRecI->GetValue(nbunch)) ndiff++;\r
353       nbunch++;\r
354     }\r
355     if (!nbunch) AliWarning(Form("%s record is present but empty: no beam?",rec));\r
356     if (prevRecI && !ndiff && nbunch==prevRecI->GetSize()) continue; // record similar to previous one\r
357     AliLHCDipValI* curValI = new AliLHCDipValI(nbunch,tstamp);      \r
358     for (int i=nbunch;i--;) (*curValI)[i] = dcsArr[i];\r
359     fData.Add(curValI);\r
360     refs[kNStor]++;\r
361     prevRecI = curValI;\r
362   }\r
363   //\r
364   return refs[kNStor];\r
365 }\r
366  \r
367 //___________________________________________________________________\r
368 Int_t AliLHCData::FillAcqMode(const TMap* dcsMap, int refs[2],const char* rec)\r
369 {\r
370   // fill acquisition mode\r
371   //\r
372   AliInfo(Form("Acquiring record: %s",rec));\r
373   TObjArray *arr;\r
374   Int_t nEntries,iEntry;\r
375   //\r
376   refs[kStart] = fData.GetEntriesFast();\r
377   refs[kNStor] = 0;\r
378   //\r
379   if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
380   nEntries = arr->GetEntriesFast();\r
381   //\r
382   AliLHCDipValI* prevRecI=0;\r
383   while (iEntry<nEntries) {\r
384     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
385     double tstamp = dcsVal->GetTimeStamp();\r
386     if (tstamp>fTMax) break;\r
387     //\r
388     int nSlots = dcsVal->GetNEntries();\r
389     if (nSlots<1) continue;\r
390     int acqMode = dcsVal->GetInt()[0];\r
391     if (prevRecI && (*prevRecI)[0] == acqMode) continue; // record similar to previous one\r
392     AliLHCDipValI* curValI = new AliLHCDipValI(1,tstamp);      \r
393     (*curValI)[0] = acqMode;\r
394     fData.Add(curValI);\r
395     refs[kNStor]++;\r
396     prevRecI = curValI;\r
397   }\r
398   //\r
399   return refs[kNStor];\r
400 }\r
401  \r
402 //___________________________________________________________________\r
403 Int_t AliLHCData::FillStringRecord(const TMap* dcsMap, int refs[2],const char* rec)\r
404 {\r
405   // fill record with string value\r
406   //\r
407   AliInfo(Form("Acquiring record: %s",rec));\r
408   TString prevRec;\r
409   TObjArray *arr;\r
410   Int_t nEntries,iEntry;\r
411   //\r
412   refs[kStart] = fData.GetEntriesFast();\r
413   refs[kNStor] = 0;\r
414   //\r
415   if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
416   nEntries = arr->GetEntriesFast();\r
417   //\r
418   while (iEntry<nEntries) {\r
419     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
420     double tstamp = dcsVal->GetTimeStamp();\r
421     if (tstamp>fTMax) break;\r
422     //\r
423     TString &str = ExtractString(dcsVal);\r
424     if (!prevRec.IsNull()) {if (str == prevRec) continue;} // skip similar record\r
425     else prevRec = str;\r
426     //\r
427     AliLHCDipValC* curValS = new AliLHCDipValC(1,tstamp);      \r
428     curValS->SetValues(str.Data(),str.Length()+1);\r
429     //\r
430     fData.Add(curValS);\r
431     refs[kNStor]++;\r
432   }\r
433   return refs[kNStor];\r
434 }\r
435 \r
436 //___________________________________________________________________\r
437 Int_t AliLHCData::FillBunchInfo(const TMap* dcsMap, int refs[2],const char* rec, int ibm, Bool_t inRealSlots)\r
438 {\r
439   // fill bunch properties for beam ibm\r
440   // if inRealSlots = true, then the value is taken from bunchRFbucket/10, otherwise, the value \r
441   // for the i-th bunch is taken from the i-th element\r
442   //\r
443   AliInfo(Form("Acquiring record: %s",rec));\r
444   TObjArray *arr;\r
445   Int_t nEntries,iEntry;\r
446   //\r
447   refs[kStart] = fData.GetEntriesFast();\r
448   refs[kNStor] = 0;\r
449   //\r
450   if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
451   nEntries = arr->GetEntriesFast();\r
452   //\r
453   while (iEntry<nEntries) {\r
454     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
455     double tstamp = dcsVal->GetTimeStamp();\r
456     if (tstamp>fTMax) break;\r
457     //\r
458     AliLHCDipValI *bconf = GetBunchConfigMeasured(ibm,tstamp);\r
459     if (!bconf) {\r
460       AliWarning(Form("Mearured bunch configuration for beam %d at t=%.1f is not available, trying declared one",ibm+1,tstamp));\r
461       bconf = GetBunchConfigDeclared(ibm,tstamp);\r
462     }\r
463     if (!bconf) {\r
464       AliWarning(Form("Declared bunch configuration for beam %d at t=%.1f is not available, skip this record",ibm+1,tstamp));\r
465       return -1;\r
466     }\r
467     int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)\r
468     int nbunch = bconf->GetSize();\r
469     if (nbunch>nSlots) {\r
470       AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));\r
471       continue;\r
472     }\r
473     double* dcsArr = dcsVal->GetDouble();\r
474     AliLHCDipValF* curValF = new AliLHCDipValF(nbunch,tstamp);\r
475     for (int i=nbunch;i--;) {\r
476       int ind = inRealSlots ? (*bconf)[i]/10 : i;\r
477       if (ind>nSlots) {\r
478         AliError(Form("Bunch %d refers to wrong slot %d, set to -1",i,(*bconf)[i]));\r
479         (*curValF)[i] = -1;\r
480       }\r
481       else (*curValF)[i] = dcsArr[ind];\r
482     }\r
483     fData.Add(curValF);\r
484     refs[kNStor]++;\r
485   }\r
486   return refs[kNStor];\r
487   //\r
488 }\r
489  \r
490 //___________________________________________________________________\r
491 Int_t AliLHCData::FillBCLuminosities(const TMap* dcsMap, int refs[2],const char* rec, const char* recErr, Bool_t opt)\r
492 {\r
493   // fill luminosities per bunch crossing\r
494   //\r
495   AliInfo(Form("Acquiring record: %s",rec));\r
496   TObjArray *arr,*arrE;\r
497   Int_t nEntries,nEntriesE,iEntry,iEntryE;\r
498   //\r
499   refs[kStart] = fData.GetEntriesFast();\r
500   refs[kNStor] = 0;\r
501   //\r
502   if ( !(arr=GetDCSEntry(dcsMap,rec,iEntry,fTMin,fTMax)) || iEntry<0 ) return -1;\r
503   nEntries = arr->GetEntriesFast();\r
504   //\r
505   while (iEntry<nEntries) {\r
506     AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iEntry++);\r
507     double tstamp = dcsVal->GetTimeStamp();\r
508     if (tstamp>fTMax) break;\r
509     //\r
510     AliLHCDipValI *bconf = GetBunchConfigMeasured(0,tstamp);  // luminosities are stored according to 1st beam bunches\r
511     if (!bconf) {\r
512       AliWarning(Form("Mearured bunch configuration for beam 1 at t=%.1f is not available, trying declared one",tstamp));\r
513       bconf = GetBunchConfigDeclared(0,tstamp);\r
514     }\r
515     if (!bconf) {\r
516       AliWarning(Form("Declared bunch configuration for beam 1 at t=%.1f is not available, skip this record",tstamp));\r
517       return -1;\r
518     }\r
519     int nSlots = dcsVal->GetNEntries();     // count number of actual bunches (non-zeros)\r
520     int nbunch = bconf->GetSize();\r
521     double* dcsArr = dcsVal->GetDouble();\r
522     //\r
523     // ATTENTION: FOR THE MOMENT STORE ALL SLOTS CORRESPONDING TO FILLED BUNCHES (until the scheme is clarified)\r
524     if (nbunch>nSlots) {\r
525       AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));\r
526       continue;\r
527     }\r
528     int dim = nbunch;\r
529     if (recErr) {\r
530       if ( !(arrE=GetDCSEntry(dcsMap,recErr,iEntryE,fTMin,fTMax)) || iEntryE<0 ) nEntriesE = -999;\r
531       else nEntriesE = arrE->GetEntriesFast();\r
532       dim += 1;\r
533     }\r
534     AliLHCDipValF* curValF = new AliLHCDipValF(dim,tstamp);\r
535     for (int i=nbunch;i--;) {\r
536       int ind = opt ? (*bconf)[i]/10 : i;\r
537       if (ind>nSlots) {\r
538         AliError(Form("Bunch %d refers to wrong slot %d, set to -1",i,(*bconf)[i]));\r
539         (*curValF)[i] = -1;\r
540       }\r
541       else (*curValF)[i] = dcsArr[ind];\r
542     }\r
543     //\r
544     if (recErr) {\r
545       double errVal = -1;\r
546       while (iEntryE<nEntriesE) {       // try to find corresponding error\r
547         AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iEntryE);\r
548         double tstamp1 = dcsValE->GetTimeStamp();\r
549         if (tstamp1>fTMax) break;\r
550         int tdif = TimeDifference(tstamp,tstamp1);\r
551         if (!tdif) { // error matches to value\r
552           errVal = dcsValE->GetDouble()[0];\r
553           iEntryE++; \r
554           break;\r
555         }\r
556         else if (tdif>0) iEntryE++; // error time lags behind, read the next one\r
557         else break;                 // error time is ahead of value, no error associated\r
558       }\r
559       (*curValF)[dim-1] = errVal;   // error\r
560       curValF->SetLastSpecial();    // lable the last entry as an error\r
561     }\r
562     //\r
563     fData.Add(curValF);\r
564     refs[kNStor]++;\r
565   }\r
566   return refs[kNStor];\r
567   //\r
568 }\r
569 \r
570 //___________________________________________________________________\r
571 Int_t AliLHCData::ExtractInt(AliDCSArray* dcsArray,Int_t el) const\r
572 {\r
573   // extract integer from the dcsArray\r
574   int val = -1;\r
575   //\r
576   int sz = dcsArray->GetNEntries();\r
577   if (sz<=el) return val;\r
578   //\r
579   if (dcsArray->GetType()==AliDCSArray::kInt)  val = dcsArray->GetInt(el);\r
580   else if (dcsArray->GetType()==AliDCSArray::kString) {\r
581     TObjString *stro = dcsArray->GetStringArray(el);\r
582     if (stro) val = stro->GetString().Atoi();\r
583     else AliError(Form("DCSArray TObjString for element %d is missing",el));\r
584   }\r
585   else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);\r
586   else AliError(Form("Integer requested from DCSArray of type %d",dcsArray->GetType()));\r
587   return val;\r
588 }\r
589 \r
590 //___________________________________________________________________\r
591 Double_t AliLHCData::ExtractDouble(AliDCSArray* dcsArray,Int_t el) const\r
592 {\r
593   // extract double from the dcsArray\r
594   double val = 0;\r
595   //\r
596   int sz = dcsArray->GetNEntries();\r
597   if (sz<=el) return val;\r
598   //\r
599   if      (dcsArray->GetType()==AliDCSArray::kDouble) val = dcsArray->GetDouble(el);\r
600   else if (dcsArray->GetType()==AliDCSArray::kFloat)  val = dcsArray->GetFloat(el);\r
601   else if (dcsArray->GetType()==AliDCSArray::kString) {\r
602     TObjString *stro = dcsArray->GetStringArray(el);\r
603     if (stro) val = stro->GetString().Atof();\r
604     else AliError(Form("DCSArray has TObjString for element %d is missing",el));\r
605   }\r
606   else if (dcsArray->GetType()==AliDCSArray::kChar)   val = dcsArray->GetChar(el);\r
607   else if (dcsArray->GetType()==AliDCSArray::kInt)    val = dcsArray->GetInt(el);\r
608   else if (dcsArray->GetType()==AliDCSArray::kUInt)   val = dcsArray->GetUInt(el);\r
609   else     AliError(Form("Double requested from DCSArray of type %d",dcsArray->GetType()));\r
610   return val;\r
611 }\r
612 \r
613 //___________________________________________________________________\r
614 TString& AliLHCData::ExtractString(AliDCSArray* dcsArray) const\r
615 {\r
616   // extract string from the dcsArray\r
617   static TString str;\r
618   str = "";\r
619   //\r
620   int sz = dcsArray->GetNEntries();\r
621   if (dcsArray->GetType()!=AliDCSArray::kString)  {\r
622     AliError(Form("String requested from DCSArray of type %d",dcsArray->GetType()));\r
623     return str;\r
624   }\r
625   //\r
626   for (int i=0;i<sz;i++) {\r
627     str += dcsArray->GetStringArray(i)->GetString();\r
628     if (i<sz-1) str += " ";\r
629   }\r
630   return str;\r
631 }\r
632 \r
633 //___________________________________________________________________\r
634 void AliLHCData::Print(const Option_t* opt) const\r
635 {\r
636   // print full info\r
637   TString opts = opt;\r
638   opts.ToLower();\r
639   Bool_t full = kTRUE;\r
640   if (!opts.Contains("f")) {\r
641     printf("Use Print(\"f\") to print full info\n");\r
642     printf("Printing short info:\n<RecordType>(number of records): <TimeStamp, value> for 1st record only\n");\r
643     full = kFALSE;\r
644   }\r
645   printf("Fill#%6d Validity: %s - %s\n",fFillNumber,\r
646          AliLHCDipValI::TimeAsString(fTMin),AliLHCDipValI::TimeAsString(fTMax));\r
647   //\r
648   printf("********** SETTINGS FROM RUN CONTROL **********\n");\r
649   //\r
650   printf("** Injection Scheme");\r
651   PrintAux(full,fRCInjScheme);\r
652   //\r
653   printf("** Beta Star");\r
654   PrintAux(full,fRCBeta);\r
655   //\r
656   printf("** Horisontal Crossing Angle");\r
657   PrintAux(full,fRCAngH);\r
658   //\r
659   printf("** Vertical   Crossing Angle");\r
660   PrintAux(full,fRCAngV);\r
661   //\r
662   for (int ib=0;ib<2;ib++) {\r
663     printf("** Beam%d bunch filling scheme [negative: bunch interacting at IR2!]",ib+1);\r
664     PrintAux(full,fBunchConfDecl[ib]);\r
665   }\r
666   //\r
667   printf("\n**********       MEASURED DATA       **********\n");\r
668   //\r
669   for (int ib=0;ib<2;ib++) {\r
670     printf("** Beam%d bunch filling scheme [negative: bunch interacts at IR2!]",ib+1);\r
671     PrintAux(full,fBunchConfMeas[ib]);\r
672   } \r
673   //\r
674   for (int ib=0;ib<2;ib++) {\r
675     printf("** Beam%d total intensity",ib+1);\r
676     PrintAux(full,fIntensTotal[ib]);\r
677   } \r
678   //\r
679   for (int ib=0;ib<2;ib++) {\r
680     printf("** Beam%d total intensity from bunch average",ib+1);\r
681     PrintAux(full,fIntensTotalAv[ib]);\r
682   } \r
683   //\r
684   for (int ib=0;ib<2;ib++) {\r
685     printf("** Beam%d intensity per bunch",ib+1);\r
686     PrintAux(full,fIntensPerBunch[ib]);\r
687   }\r
688   //\r
689   for (int ib=0;ib<2;ib++) {\r
690     printf("** Beam%d bunch lengths",ib+1);\r
691     PrintAux(full,fBunchLengths[ib]);\r
692   } \r
693   //\r
694   for (int ib=0;ib<2;ib++) {\r
695     printf("** Beam%d H. emittance",ib+1);\r
696     PrintAux(full,fEmittanceH[ib]);\r
697   }\r
698   //\r
699   for (int ib=0;ib<2;ib++) {\r
700     printf("** Beam%d V. emittance",ib+1);\r
701     PrintAux(full,fEmittanceV[ib]);\r
702   }\r
703   //\r
704   for (int ib=0;ib<2;ib++) {\r
705     printf("** Beam%d H. sigma",ib+1);\r
706     PrintAux(full,fBeamSigmaH[ib]);\r
707   }\r
708   //\r
709   for (int ib=0;ib<2;ib++) {\r
710     printf("** Beam%d V. sigma",ib+1);\r
711     PrintAux(full,fBeamSigmaV[ib]);\r
712   }\r
713   //\r
714   for (int lr=0;lr<2;lr++) {\r
715     printf("** Total luminosity from BRANB_4%c2",lr ? 'R':'L');\r
716     PrintAux(full,fLuminTotal[lr]);\r
717   } \r
718   //\r
719   for (int lr=0;lr<2;lr++) {\r
720     printf("** Luminosity acquisition mode, BRANB_4%c2",lr ? 'R':'L');\r
721     PrintAux(full,fLuminPerBC[lr]);\r
722   } \r
723   //\r
724   for (int lr=0;lr<2;lr++) {\r
725     printf("** Luminosity per Bunch Crossing from BRANB_4%c2",lr ? 'R':'L');\r
726     PrintAux(full,fLuminPerBC[lr]);\r
727   }\r
728   //\r
729   for (int lr=0;lr<2;lr++) {\r
730     printf("** Crossing angle, side %c",lr ? 'R':'L');\r
731     PrintAux(full,fCrossAngle[lr]);\r
732   }\r
733   //\r
734   for (int coll=0;coll<kNCollimators;coll++)\r
735     for (int jaw=0;jaw<kNJaws;jaw++) {\r
736       printf("** Collimator %s:%s",fgkDCSColNames[coll],fgkDCSColJaws[jaw]);\r
737       PrintAux(full,fCollimators[coll][jaw]);\r
738     }\r
739   //\r
740 }\r
741 \r
742 //___________________________________________________________________\r
743 void AliLHCData::PrintAux(Bool_t full, const Int_t refs[2]) const\r
744 {\r
745   // aux method to print the reocrds of the same type\r
746   int nrec = refs[kNStor];\r
747   if (nrec<1) {\r
748     printf(": N/A\n"); \r
749     return;\r
750   }\r
751   printf(": (%d):\t",nrec); // number of records\r
752   if (!full) nrec = 1;\r
753   int sz = ((AliLHCDipValI*)fData[refs[kStart]])->GetSizeTotal(); // dimension of the record\r
754   Bool_t isStr = ((AliLHCDipValI*)fData[refs[kStart]])->IsTypeC();\r
755   if ((!isStr && sz>2) || nrec>1) printf("\n"); // long record, open new line\r
756   for (int i=0;i<nrec;i++) fData[refs[kStart]+i]->Print();\r
757   //\r
758 }\r
759 \r
760 //___________________________________________________________________\r
761 void AliLHCData::Clear(const Option_t *)\r
762 {\r
763   // clear all info\r
764   fData.Delete();\r
765   fFillNumber = 0;\r
766   fTMin = 0;\r
767   fTMax = 1e10;\r
768   for (int i=2;i--;) {\r
769     fRCInjScheme[i] = 0;\r
770     fRCBeta[i] = 0;\r
771     fRCAngH[i] = 0;\r
772     fRCAngV[i] = 0;\r
773     //\r
774     for (int icl=kNCollimators;icl--;) for (int jaw=kNJaws;jaw--;) fCollimators[icl][jaw][i]=0;\r
775     //\r
776     for (int j=2;j--;) {\r
777       fBunchConfDecl[j][i] = 0;\r
778       fBunchConfMeas[j][i] = 0;\r
779       fBunchLengths[j][i] = 0;\r
780       fIntensTotal[j][i] = 0;\r
781       fIntensTotalAv[j][i] = 0;\r
782       fIntensPerBunch[j][i] = 0;      \r
783       fCrossAngle[j][i] = 0;\r
784       fEmittanceH[j][i] = 0;\r
785       fEmittanceV[j][i] = 0;\r
786       fBeamSigmaH[j][i] = 0;\r
787       fBeamSigmaV[j][i] = 0;\r
788       fLuminTotal[j][i] = 0;\r
789       fLuminPerBC[j][i] = 0;\r
790       fLuminAcqMode[j][i] = 0;\r
791     }\r
792   }\r
793 }\r
794 \r
795 //___________________________________________________________________\r
796 Int_t AliLHCData::GetNInteractingBunchesMeasured(int i) const\r
797 {\r
798   // get number of interacting bunches at IR2\r
799   AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r
800   if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
801   if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1;}\r
802   int n = 0;\r
803   for (int i=rec->GetSize();i--;) if ( (*rec)[i]<0 ) n++;\r
804   return n;\r
805 }\r
806 \r
807 //___________________________________________________________________\r
808 Int_t AliLHCData::GetNInteractingBunchesDeclared(int i) const\r
809 {\r
810   // get number of interacting bunches at IR2\r
811   AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r
812   if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
813   if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1; }\r
814   int n = 0;\r
815   for (int i=rec->GetSize();i--;) if ( (*rec)[i]<0 ) n++;\r
816   return n;\r
817 }\r
818 \r
819 //___________________________________________________________________\r
820 Int_t AliLHCData::IsPilotPresent(int i) const\r
821 {\r
822   // check in the filling scheme is the pilot bunch is present\r
823   AliLHCDipValC* rec = GetInjectionScheme();\r
824   if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
825   TString scheme = rec->GetValues();\r
826   return scheme.Contains("wp",TString::kIgnoreCase);\r
827 }\r