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