]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliLHCData.cxx
Fix in the printout of the validity time-stamps
[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   TString sdtmn = AliLHCDipValI::TimeAsString(fTMin);\r
713   TString sdtmx = AliLHCDipValI::TimeAsString(fTMax);\r
714   printf("Fill#%6d Validity: %s - %s\n",fFillNumber,sdtmn.Data(),sdtmx.Data());\r
715   //\r
716   printf("********** SETTINGS FROM RUN CONTROL **********\n");\r
717   //\r
718   printf("* %-38s","Injection Scheme");\r
719   PrintAux(full,fRCInjScheme);\r
720   //\r
721   printf("* %-38s","Beta Star");\r
722   PrintAux(full,fRCBeta);\r
723   //\r
724   printf("* %-38s","Horisontal Crossing Angle");\r
725   PrintAux(full,fRCAngH);\r
726   //\r
727   printf("* %-38s","Vertical   Crossing Angle");\r
728   PrintAux(full,fRCAngV);\r
729   //\r
730   for (int ib=0;ib<2;ib++) {\r
731     printf("* Beam%d filling  [- interacts at IR2!]  ",ib+1);\r
732     PrintAux(full,fBunchConfDecl[ib]);\r
733   }\r
734   //\r
735   printf("\n**********       MEASURED DATA       **********\n");\r
736   //\r
737   for (int ib=0;ib<2;ib++) {\r
738     printf("* Beam%d filling  [- interacts at IR2!]  ",ib+1);\r
739     PrintAux(full,fBunchConfMeas[ib]);\r
740   } \r
741   //\r
742   for (int ib=0;ib<2;ib++) {\r
743     printf("* Beam%d total intensity                 ",ib+1);\r
744     PrintAux(full,fIntensTotal[ib]);\r
745   } \r
746   //\r
747   for (int ib=0;ib<2;ib++) {\r
748     printf("* Beam%d total intensity (bunch average) ",ib+1);\r
749     PrintAux(full,fIntensTotalAv[ib]);\r
750   } \r
751   //\r
752   for (int ib=0;ib<2;ib++) {\r
753     printf("* Beam%d intensity per bunch             ",ib+1);\r
754     PrintAux(full,fIntensPerBunch[ib]);\r
755   }\r
756   //\r
757   for (int ib=0;ib<2;ib++) {\r
758     printf("* Beam%d bunch lengths                   ",ib+1);\r
759     PrintAux(full,fBunchLengths[ib]);\r
760   } \r
761   //\r
762   for (int ib=0;ib<2;ib++) {\r
763     printf("* Beam%d Horisontal emittance            ",ib+1);\r
764     PrintAux(full,fEmittanceH[ib]);\r
765   }\r
766   //\r
767   for (int ib=0;ib<2;ib++) {\r
768     printf("* Beam%d Vertical emittance              ",ib+1);\r
769     PrintAux(full,fEmittanceV[ib]);\r
770   }\r
771   //\r
772   for (int ib=0;ib<2;ib++) {\r
773     printf("* Beam%d Horisontal sigma                ",ib+1);\r
774     PrintAux(full,fBeamSigmaH[ib]);\r
775   }\r
776   //\r
777   for (int ib=0;ib<2;ib++) {\r
778     printf("* Beam%d Vertical sigma                  ",ib+1);\r
779     PrintAux(full,fBeamSigmaV[ib]);\r
780   }\r
781   //\r
782   for (int lr=0;lr<2;lr++) {\r
783     printf("* Total luminosity from BRANB_4%c2       ",lr ? 'R':'L');\r
784     PrintAux(full,fLuminTotal[lr]);\r
785   } \r
786   //\r
787   for (int lr=0;lr<2;lr++) {\r
788     printf("* Luminosity acq.mode, BRANB_4%c2        ",lr ? 'R':'L');\r
789     PrintAux(full,fLuminAcqMode[lr],"bit");\r
790   } \r
791   //\r
792   for (int lr=0;lr<2;lr++) {\r
793     printf("* Luminosity per BC from BRANB_4%c2      ",lr ? 'R':'L');\r
794     PrintAux(full,fLuminPerBC[lr]);\r
795   }\r
796   //\r
797   for (int lr=0;lr<2;lr++) {\r
798     printf("* Crossing angle, side %c                ",lr ? 'R':'L');\r
799     PrintAux(full,fCrossAngle[lr]);\r
800   }\r
801   //\r
802   for (int coll=0;coll<kNCollimators;coll++)\r
803     for (int jaw=0;jaw<kNJaws;jaw++) {\r
804       printf("* Collimator %10s:%16s",fgkDCSColNames[coll],fgkDCSColJaws[jaw]);\r
805       PrintAux(full,fCollimators[coll][jaw]);\r
806     }\r
807   //\r
808 }\r
809 \r
810 //___________________________________________________________________\r
811 void AliLHCData::PrintAux(Bool_t full, const Int_t refs[2], const Option_t *opt) const\r
812 {\r
813   // aux method to print the reocrds of the same type\r
814   int nrec = refs[kNStor];\r
815   if (nrec<1) {\r
816     printf(": N/A\n"); \r
817     return;\r
818   }\r
819   printf(": (%3d):\t",nrec); // number of records\r
820   if (!full) nrec = 1;\r
821   int sz = ((AliLHCDipValI*)fData[refs[kStart]])->GetSizeTotal(); // dimension of the record\r
822   Bool_t isStr = ((AliLHCDipValI*)fData[refs[kStart]])->IsTypeC();\r
823   if ((!isStr && sz>2) || nrec>1) printf("\n"); // long record, open new line\r
824   for (int i=0;i<nrec;i++) fData[refs[kStart]+i]->Print(opt);\r
825   //\r
826 }\r
827 \r
828 //___________________________________________________________________\r
829 void AliLHCData::Clear(const Option_t *)\r
830 {\r
831   // clear all info\r
832   fData.Delete();\r
833   fFillNumber = 0;\r
834   fTMin = 0;\r
835   fTMax = 1e10;\r
836   fFile2Process = 0;\r
837   fMap2Process  = 0;\r
838   //\r
839   for (int i=2;i--;) {\r
840     fRCInjScheme[i] = 0;\r
841     fRCBeta[i] = 0;\r
842     fRCAngH[i] = 0;\r
843     fRCAngV[i] = 0;\r
844     //\r
845     for (int icl=kNCollimators;icl--;) for (int jaw=kNJaws;jaw--;) fCollimators[icl][jaw][i]=0;\r
846     //\r
847     for (int j=2;j--;) {\r
848       fBunchConfDecl[j][i] = 0;\r
849       fBunchConfMeas[j][i] = 0;\r
850       fBunchLengths[j][i] = 0;\r
851       fIntensTotal[j][i] = 0;\r
852       fIntensTotalAv[j][i] = 0;\r
853       fIntensPerBunch[j][i] = 0;      \r
854       fCrossAngle[j][i] = 0;\r
855       fEmittanceH[j][i] = 0;\r
856       fEmittanceV[j][i] = 0;\r
857       fBeamSigmaH[j][i] = 0;\r
858       fBeamSigmaV[j][i] = 0;\r
859       fLuminTotal[j][i] = 0;\r
860       fLuminPerBC[j][i] = 0;\r
861       fLuminAcqMode[j][i] = 0;\r
862     }\r
863   }\r
864 }\r
865 \r
866 //___________________________________________________________________\r
867 Int_t AliLHCData::GetNInteractingBunchesMeasured(int i) const\r
868 {\r
869   // get number of interacting bunches at IR2\r
870   AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r
871   if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
872   if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1;}\r
873   int n = 0;\r
874   for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;\r
875   return n;\r
876 }\r
877 \r
878 //___________________________________________________________________\r
879 Int_t AliLHCData::GetNInteractingBunchesDeclared(int i) const\r
880 {\r
881   // get number of interacting bunches at IR2\r
882   AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r
883   if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
884   if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1; }\r
885   int n = 0;\r
886   for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;\r
887   return n;\r
888 }\r
889 \r
890 //___________________________________________________________________\r
891 Int_t AliLHCData::IsPilotPresent(int i) const\r
892 {\r
893   // check in the filling scheme is the pilot bunch is present\r
894   AliLHCDipValC* rec = GetInjectionScheme();\r
895   if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r
896   TString scheme = rec->GetValues();\r
897   return scheme.Contains("wp",TString::kIgnoreCase);\r
898 }\r
899 \r
900 //___________________________________________________________________\r
901 void AliLHCData::FlagInteractingBunches(const Int_t beam1[2],const Int_t beam2[2])\r
902 {\r
903   // assign - sign to interacting bunches\r
904   const int kMaxSlots  = 3564;\r
905   const int kOffsBeam1 = 346;\r
906   const int kOffsBeam2 = 3019;\r
907   //\r
908   for (int ib1=0;ib1<beam1[kNStor];ib1++) {\r
909     AliLHCDipValI *bm1 = (AliLHCDipValI*)fData[ beam1[kStart] + ib1];\r
910     if (!bm1) continue;\r
911     AliLHCDipValI *bm2 = (AliLHCDipValI*)FindRecValidFor(beam2[kStart],beam2[kNStor], bm1->GetTimeStamp());\r
912     if (!bm2) continue;\r
913     //\r
914     int nb1 = bm1->GetSize();\r
915     int nb2 = bm2->GetSize();\r
916     int i1,i2;\r
917     for (i1=0;i1<nb1;i1++) {\r
918       int bunch2=-1, bunch1 = TMath::Abs((*bm1)[i1]);\r
919       int slot2 =-1, slot1  = (bunch1/10 + kOffsBeam1)%kMaxSlots;\r
920       for (i2=0;i2<nb2;i2++) {\r
921         bunch2 = TMath::Abs((*bm2)[i2]);\r
922         slot2 = (bunch2/10 + kOffsBeam2)%kMaxSlots;\r
923         if (slot1==slot2) break;\r
924       }\r
925       if (slot1!=slot2) continue;\r
926       (*bm1)[i1] = -bunch1;\r
927       (*bm2)[i2] = -bunch2;\r
928       bm1->SetProcessed1();\r
929       bm2->SetProcessed1();\r
930     }\r
931   }\r
932 }\r