]>
Commit | Line | Data |
---|---|---|
799c6677 | 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 | |
bab62329 | 45 | #include "AliLHCReader.h"\r |
2af04ffd | 46 | #include "AliTriggerBCMask.h"\r |
799c6677 | 47 | #include <TString.h>\r |
48 | #include <TObjArray.h>\r | |
46d3b556 | 49 | #include <TGraph.h>\r |
799c6677 | 50 | \r |
51 | ClassImp(AliLHCData)\r | |
52 | \r | |
53 | const Char_t* AliLHCData::fgkDCSNames[] = {\r | |
d97d27ff | 54 | "LHC_IntensityBeam%1d_totalIntensity",\r |
55 | "LHC_BeamIntensityPerBunchBeam%1d_averageBeamIntensity",\r | |
56 | "LHC_BeamIntensityPerBunchBeam%1d_Average_BunchIntensities",\r | |
799c6677 | 57 | //\r |
58 | "LHC_LumAverageBRANB_4%c2_acqMode",\r | |
59 | "LHC_LumAverageBRANB_4%c2_meanLuminosity",\r | |
60 | "LHC_LumAverageBRANB_4%c2_meanLuminosityError",\r | |
61 | "LHC_BeamLuminosityPerBunchBRANB_4%c2_Average_BunchLuminosity",\r | |
62 | "LHC_BeamLuminosityPerBunchBRANB_4%c2_BunchLuminosityError",\r | |
63 | "LHC_LumAverageBRANB_4%c2_meanCrossingAngle",\r | |
64 | "LHC_LumAverageBRANB_4%c2_meanCrossingAngleError",\r | |
65 | "LHC_CirculatingBunchConfig_Beam%d",\r | |
66 | "LHC_FillNumber",\r | |
67 | //\r | |
d97d27ff | 68 | "LHC_BunchLengthBeam%1d_nBunches",\r |
69 | "LHC_BunchLengthBeam%1d_bunchesLenghts",\r | |
70 | "LHC_BunchLengthBeam%1d_filledBuckets",\r | |
799c6677 | 71 | //\r |
72 | "LHC_RunControl_ActiveInjectionScheme",\r | |
73 | "LHC_RunControl_BetaStar",\r | |
74 | "LHC_RunControl_IP2_Xing_Murad",\r | |
75 | "LHC_RunControl_IP2_ALICE_Murad",\r | |
76 | \r | |
d97d27ff | 77 | "LHC_BeamSizeBeam%1d_acqMode",\r |
78 | "LHC_BeamSizeBeam%1d_sigmaH",\r | |
79 | "LHC_BeamSizeBeam%1d_sigmaV",\r | |
80 | "LHC_BeamSizeBeam%1d_emittanceH",\r | |
81 | "LHC_BeamSizeBeam%1d_emittanceV",\r | |
82 | "LHC_BeamSizeBeam%1d_errorSigmaH",\r | |
83 | "LHC_BeamSizeBeam%1d_errorSigmaV",\r | |
799c6677 | 84 | //\r |
46d3b556 | 85 | "LHC_CollimatorPos_%s_lvdt_%s",\r |
86 | "ALICE_LumiIntFill",\r | |
87 | "ALICE_BckgIntFill"\r | |
799c6677 | 88 | };\r |
89 | \r | |
90 | const Char_t* AliLHCData::fgkDCSColNames[] = {\r | |
91 | "TCTVB_4L2",\r | |
92 | "TCTVB_4R2",\r | |
93 | "TCLIA_4R2"\r | |
94 | };\r | |
95 | \r | |
96 | const Char_t* AliLHCData::fgkDCSColJaws[] = {\r | |
97 | "gap_downstream","gap_upstream","left_downstream",\r | |
98 | "left_upstream","right_downstream","right_upstream"};\r | |
99 | \r | |
100 | //___________________________________________________________________\r | |
0e9ab7ce | 101 | AliLHCData::AliLHCData(const TMap* dcsMap, double tmin, double tmax)\r |
339fbe23 | 102 | : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fkFile2Process(0),fkMap2Process(0)\r |
799c6677 | 103 | {\r |
bab62329 | 104 | FillData(dcsMap,tmin,tmax);\r |
105 | }\r | |
106 | \r | |
107 | //___________________________________________________________________\r | |
0e9ab7ce | 108 | AliLHCData::AliLHCData(const Char_t* dcsFile, double tmin, double tmax)\r |
339fbe23 | 109 | : fTMin(0),fTMax(0),fFillNumber(0),fData(0),fkFile2Process(dcsFile),fkMap2Process(0)\r |
bab62329 | 110 | {\r |
111 | FillData(dcsFile,tmin,tmax);\r | |
112 | }\r | |
113 | \r | |
114 | //___________________________________________________________________\r | |
115 | Bool_t AliLHCData::FillData(const TMap* dcsMap,double tmin, double tmax)\r | |
116 | {\r | |
117 | // process DCS map and fill all fields. \r | |
799c6677 | 118 | Clear();\r |
339fbe23 | 119 | fkMap2Process = dcsMap;\r |
bab62329 | 120 | FillData(tmin,tmax);\r |
94179526 | 121 | return kTRUE;\r |
799c6677 | 122 | }\r |
123 | \r | |
124 | //___________________________________________________________________\r | |
bab62329 | 125 | Bool_t AliLHCData::FillData(const Char_t* dcsFile,double tmin, double tmax)\r |
126 | {\r | |
127 | // process DCS file and fill all fields. \r | |
128 | Clear();\r | |
339fbe23 | 129 | fkFile2Process = dcsFile;\r |
bab62329 | 130 | FillData(tmin,tmax);\r |
94179526 | 131 | return kTRUE;\r |
bab62329 | 132 | }\r |
133 | \r | |
134 | //___________________________________________________________________\r | |
135 | Bool_t AliLHCData::FillData(double tmin, double tmax)\r | |
799c6677 | 136 | {\r |
137 | // process DCS map and fill all fields. \r | |
138 | // Accept only entries with timestamp between tmin and tmax\r | |
139 | //\r | |
140 | char buff[100],buff1[100];\r | |
141 | //\r | |
142 | SetTMin(tmin);\r | |
143 | SetTMax(tmax);\r | |
144 | //\r | |
145 | // -------------------------- extract Fill Number\r | |
0e9ab7ce | 146 | int iFirst=0,iLast=0;\r |
147 | TObjArray* arr = GetDCSEntry(fgkDCSNames[kFillNum],iFirst,iLast,fTMin,fTMax);\r | |
148 | if (arr) SetFillNumber( ExtractInt( (AliDCSArray*)arr->At(iFirst), 0) );\r | |
339fbe23 | 149 | if (fkFile2Process) delete arr; // array was created on demand\r |
799c6677 | 150 | //\r |
151 | for (int ibm=0;ibm<2;ibm++) {\r | |
152 | //\r | |
d97d27ff | 153 | snprintf(buff,99,fgkDCSNames[kBunchConf],ibm+1); // ----- declared bunch configuration\r |
bab62329 | 154 | FillBunchConfig(fBunchConfDecl[ibm], buff);\r |
799c6677 | 155 | //\r |
d97d27ff | 156 | snprintf(buff,99,fgkDCSNames[kBunchLgtFillB],ibm+1); // ----- measured bunch configuration\r |
bab62329 | 157 | FillBunchConfig(fBunchConfMeas[ibm], buff);\r |
799c6677 | 158 | //\r |
d97d27ff | 159 | snprintf(buff,99,fgkDCSNames[kBunchLgt],ibm+1); // ----- measured bunch lenghts\r |
bab62329 | 160 | FillBunchInfo(fBunchLengths[ibm],buff,ibm,kFALSE); \r |
799c6677 | 161 | //\r |
d97d27ff | 162 | snprintf(buff,99,fgkDCSNames[kIntBunchAv],ibm+1); // ----- B-by-B intensities\r |
bab62329 | 163 | FillBunchInfo(fIntensPerBunch[ibm],buff,ibm,kTRUE);\r |
799c6677 | 164 | //\r |
165 | //\r | |
d97d27ff | 166 | snprintf(buff,99,fgkDCSNames[kIntTot],ibm+1); // ----- total intensities for beam 1 and 2\r |
bab62329 | 167 | FillScalarRecord(fIntensTotal[ibm], buff);\r |
799c6677 | 168 | //\r |
d97d27ff | 169 | snprintf(buff,99,fgkDCSNames[kIntTotAv],ibm+1); // ----- total intensities for beam 1 and 2 from B-by-B average\r |
bab62329 | 170 | FillScalarRecord(fIntensTotalAv[ibm], buff);\r |
799c6677 | 171 | //\r |
d97d27ff | 172 | snprintf(buff,99,fgkDCSNames[kBeamSzEmittH],ibm+1); // ----- H emittance for beam 1 and 2 \r |
bab62329 | 173 | FillScalarRecord(fEmittanceH[ibm], buff);\r |
799c6677 | 174 | //\r |
d97d27ff | 175 | snprintf(buff,99,fgkDCSNames[kBeamSzEmittV],ibm+1); // ----- V emittance for beam 1 and 2 \r |
bab62329 | 176 | FillScalarRecord(fEmittanceV[ibm], buff);\r |
799c6677 | 177 | //\r |
d97d27ff | 178 | snprintf(buff,99 ,fgkDCSNames[kBeamSzSigH], ibm+1); // ----- H sigmas and errors for beam 1 and 2 \r |
179 | snprintf(buff1,99,fgkDCSNames[kBeamSzSigHErr],ibm+1);\r | |
bab62329 | 180 | FillScalarRecord(fBeamSigmaH[ibm], buff, buff1);\r |
799c6677 | 181 | //\r |
d97d27ff | 182 | snprintf(buff,99 ,fgkDCSNames[kBeamSzSigV], ibm+1); // ----- V sigmas and errors for beam 1 and 2 \r |
183 | snprintf(buff1,99,fgkDCSNames[kBeamSzSigVErr],ibm+1);\r | |
bab62329 | 184 | FillScalarRecord(fBeamSigmaV[ibm], buff, buff1);\r |
799c6677 | 185 | //\r |
186 | }\r | |
187 | //\r | |
3760aa6b | 188 | FlagInteractingBunches(fBunchConfMeas[0],fBunchConfMeas[1]);\r |
189 | FlagInteractingBunches(fBunchConfDecl[0],fBunchConfDecl[1]);\r | |
190 | //\r | |
799c6677 | 191 | for (int ilr=0;ilr<2;ilr++) {\r |
192 | //\r | |
d97d27ff | 193 | snprintf(buff,99 ,fgkDCSNames[kLumBunch], ilr ? 'R':'L'); // ---- BC-by-BC luminosity at IP2 and its error\r |
194 | snprintf(buff1,99,fgkDCSNames[kLumBunchErr], ilr ? 'R':'L');\r | |
bab62329 | 195 | FillBCLuminosities(fLuminPerBC[ilr], buff, buff1, 0); // BRAN L uses beam2 as a reference, BRAN R - beam1\r |
799c6677 | 196 | //\r |
d97d27ff | 197 | snprintf(buff,99 ,fgkDCSNames[kLumTot] , ilr ? 'R':'L'); // ---- total luminosity at IP2 and its error\r |
198 | snprintf(buff1,99,fgkDCSNames[kLumTotErr], ilr ? 'R':'L');\r | |
bab62329 | 199 | FillScalarRecord(fLuminTotal[ilr], buff, buff1);\r |
799c6677 | 200 | //\r |
d97d27ff | 201 | snprintf(buff,99 ,fgkDCSNames[kLumAcqMode], ilr ? 'R':'L'); // ---- luminosity acquisition mode\r |
bab62329 | 202 | FillAcqMode(fLuminAcqMode[ilr], buff);\r |
799c6677 | 203 | //\r |
d97d27ff | 204 | snprintf(buff,99, fgkDCSNames[kLumCrossAng] , ilr ? 'R':'L'); //----- crossing angle at IP2 and its error\r |
205 | snprintf(buff1,99,fgkDCSNames[kLumCrossAngErr], ilr ? 'R':'L');\r | |
bab62329 | 206 | FillScalarRecord(fCrossAngle[ilr], buff, buff1);\r |
799c6677 | 207 | // \r |
208 | }\r | |
209 | //\r | |
210 | for (int icl=0;icl<kNCollimators;icl++) { // ----- collimators positions\r | |
211 | for (int jaw=0;jaw<kNJaws;jaw++) {\r | |
d97d27ff | 212 | snprintf(buff,99,fgkDCSNames[kCollPos], fgkDCSColNames[icl],fgkDCSColJaws[jaw]); \r |
bab62329 | 213 | FillScalarRecord(fCollimators[icl][jaw], buff);\r |
799c6677 | 214 | } // jaws\r |
215 | } // collimators\r | |
216 | //\r | |
217 | //\r | |
218 | // RunControl info\r | |
bab62329 | 219 | FillStringRecord(fRCInjScheme, fgkDCSNames[kRCInjSch]); // ---- active injection scheme\r |
220 | FillScalarRecord(fRCBeta, fgkDCSNames[kRCBeta]); // ---- target beta \r | |
221 | FillScalarRecord(fRCAngH, fgkDCSNames[kRCCrossAng]); // ---- horisontal angle\r | |
222 | FillScalarRecord(fRCAngV,fgkDCSNames[kRCVang] ); // ---- vertical angle\r | |
799c6677 | 223 | //\r |
224 | return kTRUE;\r | |
225 | }\r | |
226 | \r | |
227 | //___________________________________________________________________\r | |
0e9ab7ce | 228 | TObjArray* AliLHCData::GetDCSEntry(const char* key,int &entry,int &last,double tmin,double tmax) const\r |
799c6677 | 229 | {\r |
bab62329 | 230 | // extract array from the DCS map or file and find the first entry within the time limits\r |
799c6677 | 231 | entry = -1;\r |
0e9ab7ce | 232 | last = -2;\r |
bab62329 | 233 | TObjArray* arr;\r |
339fbe23 | 234 | if (fkMap2Process) arr = (TObjArray*)fkMap2Process->GetValue(key);\r |
235 | else if (fkFile2Process) {\r | |
bab62329 | 236 | AliLHCReader rd;\r |
339fbe23 | 237 | arr = rd.ReadSingleLHCDP(fkFile2Process,key);\r |
bab62329 | 238 | }\r |
239 | else {\r | |
240 | AliError("Neither DCS map nor DCS filename are set");\r | |
241 | return 0; \r | |
242 | }\r | |
243 | //\r | |
799c6677 | 244 | if (!arr || !arr->GetEntriesFast()) { \r |
245 | AliWarning(Form("No data for %s",key)); \r | |
339fbe23 | 246 | if (fkMap2Process) delete arr; // created on demand\r |
799c6677 | 247 | return 0;\r |
248 | }\r | |
249 | int ntot = arr->GetEntriesFast();\r | |
0e9ab7ce | 250 | //\r |
251 | // search 1st entry before or at tmin\r | |
252 | AliDCSArray* ent = 0;\r | |
253 | Bool_t found = kFALSE;\r | |
799c6677 | 254 | for (entry=0;entry<ntot;entry++) {\r |
0e9ab7ce | 255 | ent = (AliDCSArray*)arr->At(entry);\r |
256 | if (ent->GetTimeStamp()>=tmin-kMarginSOR && ent->GetTimeStamp()<=tmax+kMarginEOR) {\r | |
257 | found = kTRUE;\r | |
258 | if (ent->GetTimeStamp()>tmin) break;\r | |
259 | }\r | |
799c6677 | 260 | }\r |
0e9ab7ce | 261 | if (!found) {\r |
799c6677 | 262 | entry = -1;\r |
263 | TString str;\r | |
a1063d3a | 264 | str += AliLHCDipValF::TimeAsString(tmin);\r |
799c6677 | 265 | str += " : ";\r |
a1063d3a | 266 | str += AliLHCDipValF::TimeAsString(tmax);\r |
799c6677 | 267 | AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));\r |
339fbe23 | 268 | if (fkMap2Process) delete arr; // created on demand\r |
bab62329 | 269 | return 0;\r |
799c6677 | 270 | }\r |
0e9ab7ce | 271 | if (entry>0) entry--;\r |
272 | //\r | |
273 | // search last entry at or after tmin\r | |
274 | ent = 0;\r | |
275 | for (last=entry;last<ntot;last++) {\r | |
276 | ent = (AliDCSArray*)arr->At(last);\r | |
277 | if (ent->GetTimeStamp()>tmax) break;\r | |
278 | }\r | |
279 | if (last == ntot) last--;\r | |
280 | else if (ent->GetTimeStamp()>tmax+kMarginEOR) last--;\r | |
281 | //\r | |
799c6677 | 282 | return arr;\r |
283 | }\r | |
284 | \r | |
285 | //___________________________________________________________________\r | |
286 | Int_t AliLHCData::TimeDifference(double v1,double v2,double tol) const\r | |
287 | {\r | |
288 | // return 0 if the times are the same within the tolerance\r | |
289 | // 1 if v1>v2\r | |
290 | // -1 if v1<v2\r | |
291 | v1-=v2;\r | |
292 | if (v1>tol) return 1;\r | |
293 | if (v1<-tol) return -1;\r | |
294 | return 0;\r | |
295 | }\r | |
296 | \r | |
297 | //___________________________________________________________________\r | |
298 | Bool_t AliLHCData::GoodPairID(int beam) const\r | |
299 | {\r | |
300 | // check for correct beam identifier \r | |
301 | if (beam>kBeam2||beam<0) {AliError(Form("BeamID can be 0 or 1, %d requested",beam)); return kFALSE;}\r | |
302 | return kTRUE;\r | |
303 | }\r | |
304 | \r | |
305 | //___________________________________________________________________\r | |
306 | AliLHCDipValI* AliLHCData::GetBunchConfigMeasured(int beam,double tstamp) const\r | |
307 | {\r | |
308 | // find measured bunch configuration valid for given tstamp\r | |
309 | if (!GoodPairID(beam)) return 0;\r | |
310 | return (AliLHCDipValI*)FindRecValidFor(fBunchConfMeas[beam][kStart],fBunchConfMeas[beam][kNStor],tstamp);\r | |
311 | }\r | |
312 | \r | |
313 | //___________________________________________________________________\r | |
314 | AliLHCDipValI* AliLHCData::GetBunchConfigDeclared(int beam,double tstamp) const\r | |
315 | {\r | |
316 | // find declared bunch configuration valid for given tstamp\r | |
317 | if (!GoodPairID(beam)) return 0;\r | |
318 | return (AliLHCDipValI*)FindRecValidFor(fBunchConfDecl[beam][kStart],fBunchConfDecl[beam][kNStor],tstamp);\r | |
319 | }\r | |
320 | \r | |
321 | //___________________________________________________________________\r | |
322 | TObject* AliLHCData::FindRecValidFor(int start,int nrec, double tstamp) const\r | |
323 | {\r | |
324 | // find record within this limits valid for given tstamp (i.e. the last one before or equal to tstamp)\r | |
325 | AliLHCDipValI *prevObj = 0;\r | |
326 | for (int i=0;i<nrec;i++) {\r | |
327 | AliLHCDipValI* curObj = (AliLHCDipValI*)fData[start+i];\r | |
46d3b556 | 328 | if (TimeDifference(tstamp,curObj->GetTimeStamp())<=0) break;\r |
799c6677 | 329 | prevObj = curObj;\r |
330 | }\r | |
331 | if (!prevObj && nrec>0) prevObj = (AliLHCDipValI*)fData[start]; // if no exact match, return the 1st one\r | |
332 | return prevObj;\r | |
333 | }\r | |
334 | \r | |
335 | //___________________________________________________________________\r | |
5ef3791d | 336 | Int_t AliLHCData::FillScalarRecord(int refs[2], const char* rec, const char* recErr, Double_t maxAbsVal)\r |
799c6677 | 337 | {\r |
338 | // fill record for scalar value, optionally accompanied by measurement error \r | |
339 | //\r | |
340 | AliInfo(Form("Acquiring record: %s",rec));\r | |
341 | //\r | |
e08ebb54 | 342 | TObjArray *arr=0,*arrE=0;\r |
0e9ab7ce | 343 | Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;\r |
799c6677 | 344 | //\r |
345 | refs[kStart] = fData.GetEntriesFast();\r | |
346 | refs[kNStor] = 0;\r | |
347 | //\r | |
0e9ab7ce | 348 | if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r |
799c6677 | 349 | //\r |
350 | int dim = 1;\r | |
351 | if (recErr) {\r | |
0e9ab7ce | 352 | arrE = GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);\r |
799c6677 | 353 | dim += 1;\r |
354 | }\r | |
355 | //\r | |
f8b1c575 | 356 | // Bool_t last = kFALSE;\r |
0e9ab7ce | 357 | while (iFirst<=iLast) {\r |
358 | AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r | |
799c6677 | 359 | double tstamp = dcsVal->GetTimeStamp();\r |
799c6677 | 360 | //\r |
a1063d3a | 361 | AliLHCDipValF* curValD = new AliLHCDipValF(dim,tstamp); // start new period\r |
5ef3791d | 362 | double vcheck = ExtractDouble(dcsVal,0); // value\r |
363 | if (TMath::Abs(vcheck) > maxAbsVal) {\r | |
364 | AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",vcheck, 0, rec, maxAbsVal));\r | |
365 | vcheck = 0.;\r | |
366 | } \r | |
367 | (*curValD)[0] = vcheck;\r | |
799c6677 | 368 | //\r |
369 | if (recErr) {\r | |
370 | double errVal = -1;\r | |
0e9ab7ce | 371 | while (iFirstE<=iLastE) { // try to find corresponding error\r |
372 | AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);\r | |
799c6677 | 373 | double tstampE = dcsValE->GetTimeStamp();\r |
799c6677 | 374 | int tdif = TimeDifference(tstamp,tstampE);\r |
375 | if (!tdif) { // error matches to value\r | |
649fda12 | 376 | errVal = ExtractDouble(dcsVal,0); // value\r |
5ef3791d | 377 | if (TMath::Abs(errVal) > maxAbsVal) {\r |
378 | AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",errVal, 0, recErr, maxAbsVal));\r | |
379 | errVal = 0.;\r | |
380 | }\r | |
0e9ab7ce | 381 | iFirstE++; \r |
799c6677 | 382 | break;\r |
383 | }\r | |
0e9ab7ce | 384 | else if (tdif>0) iFirstE++; // error time lags behind, read the next one\r |
799c6677 | 385 | else break; // error time is ahead of value, no error associated\r |
386 | }\r | |
649fda12 | 387 | (*curValD)[dim-1] = errVal; // error\r |
388 | curValD->SetLastSpecial(); // lable the last entry as an error\r | |
799c6677 | 389 | }\r |
390 | //\r | |
649fda12 | 391 | fData.Add(curValD);\r |
799c6677 | 392 | refs[kNStor]++;\r |
f8b1c575 | 393 | // if (last) break;\r |
799c6677 | 394 | }\r |
395 | //\r | |
339fbe23 | 396 | if (fkFile2Process) {\r |
bab62329 | 397 | delete arr;\r |
398 | delete arrE;\r | |
399 | }\r | |
799c6677 | 400 | return refs[kNStor];\r |
401 | }\r | |
402 | \r | |
403 | //___________________________________________________________________\r | |
bab62329 | 404 | Int_t AliLHCData::FillBunchConfig(int refs[2],const char* rec)\r |
799c6677 | 405 | {\r |
406 | // fill record for bunch configuration\r | |
407 | //\r | |
408 | AliInfo(Form("Acquiring record: %s",rec));\r | |
409 | TObjArray *arr;\r | |
0e9ab7ce | 410 | Int_t iLast,iFirst;\r |
799c6677 | 411 | //\r |
412 | refs[kStart] = fData.GetEntriesFast();\r | |
413 | refs[kNStor] = 0;\r | |
414 | //\r | |
0e9ab7ce | 415 | if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r |
799c6677 | 416 | //\r |
417 | AliLHCDipValI* prevRecI=0;\r | |
0e9ab7ce | 418 | // \r |
419 | while (iFirst<=iLast) {\r | |
420 | AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r | |
799c6677 | 421 | double tstamp = dcsVal->GetTimeStamp();\r |
799c6677 | 422 | //\r |
423 | int bucket=0, nbunch=0, ndiff=0;\r | |
424 | int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)\r | |
425 | int* dcsArr = dcsVal->GetInt();\r | |
426 | while(nbunch<nSlots && (bucket=dcsArr[nbunch])) {\r | |
427 | if (prevRecI && prevRecI->GetSize()>nbunch && bucket!=prevRecI->GetValue(nbunch)) ndiff++;\r | |
428 | nbunch++;\r | |
429 | }\r | |
430 | if (!nbunch) AliWarning(Form("%s record is present but empty: no beam?",rec));\r | |
431 | if (prevRecI && !ndiff && nbunch==prevRecI->GetSize()) continue; // record similar to previous one\r | |
432 | AliLHCDipValI* curValI = new AliLHCDipValI(nbunch,tstamp); \r | |
433 | for (int i=nbunch;i--;) (*curValI)[i] = dcsArr[i];\r | |
434 | fData.Add(curValI);\r | |
435 | refs[kNStor]++;\r | |
436 | prevRecI = curValI;\r | |
437 | }\r | |
438 | //\r | |
339fbe23 | 439 | if (fkFile2Process) delete arr;\r |
799c6677 | 440 | return refs[kNStor];\r |
441 | }\r | |
442 | \r | |
443 | //___________________________________________________________________\r | |
bab62329 | 444 | Int_t AliLHCData::FillAcqMode(int refs[2],const char* rec)\r |
799c6677 | 445 | {\r |
446 | // fill acquisition mode\r | |
447 | //\r | |
448 | AliInfo(Form("Acquiring record: %s",rec));\r | |
449 | TObjArray *arr;\r | |
0e9ab7ce | 450 | Int_t iLast,iFirst;\r |
799c6677 | 451 | //\r |
452 | refs[kStart] = fData.GetEntriesFast();\r | |
453 | refs[kNStor] = 0;\r | |
454 | //\r | |
0e9ab7ce | 455 | if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r |
799c6677 | 456 | //\r |
457 | AliLHCDipValI* prevRecI=0;\r | |
0e9ab7ce | 458 | while (iFirst<=iLast) {\r |
459 | AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r | |
799c6677 | 460 | double tstamp = dcsVal->GetTimeStamp();\r |
799c6677 | 461 | //\r |
462 | int nSlots = dcsVal->GetNEntries();\r | |
463 | if (nSlots<1) continue;\r | |
464 | int acqMode = dcsVal->GetInt()[0];\r | |
465 | if (prevRecI && (*prevRecI)[0] == acqMode) continue; // record similar to previous one\r | |
466 | AliLHCDipValI* curValI = new AliLHCDipValI(1,tstamp); \r | |
467 | (*curValI)[0] = acqMode;\r | |
468 | fData.Add(curValI);\r | |
469 | refs[kNStor]++;\r | |
470 | prevRecI = curValI;\r | |
471 | }\r | |
472 | //\r | |
339fbe23 | 473 | if (fkFile2Process) delete arr;\r |
799c6677 | 474 | return refs[kNStor];\r |
475 | }\r | |
476 | \r | |
477 | //___________________________________________________________________\r | |
bab62329 | 478 | Int_t AliLHCData::FillStringRecord(int refs[2],const char* rec)\r |
799c6677 | 479 | {\r |
480 | // fill record with string value\r | |
481 | //\r | |
482 | AliInfo(Form("Acquiring record: %s",rec));\r | |
483 | TString prevRec;\r | |
484 | TObjArray *arr;\r | |
0e9ab7ce | 485 | Int_t iLast,iFirst;\r |
799c6677 | 486 | //\r |
487 | refs[kStart] = fData.GetEntriesFast();\r | |
488 | refs[kNStor] = 0;\r | |
489 | //\r | |
0e9ab7ce | 490 | if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r |
799c6677 | 491 | //\r |
0e9ab7ce | 492 | while (iFirst<=iLast) {\r |
493 | AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r | |
799c6677 | 494 | double tstamp = dcsVal->GetTimeStamp();\r |
799c6677 | 495 | //\r |
496 | TString &str = ExtractString(dcsVal);\r | |
497 | if (!prevRec.IsNull()) {if (str == prevRec) continue;} // skip similar record\r | |
498 | else prevRec = str;\r | |
499 | //\r | |
500 | AliLHCDipValC* curValS = new AliLHCDipValC(1,tstamp); \r | |
501 | curValS->SetValues(str.Data(),str.Length()+1);\r | |
502 | //\r | |
503 | fData.Add(curValS);\r | |
504 | refs[kNStor]++;\r | |
505 | }\r | |
339fbe23 | 506 | if (fkFile2Process) delete arr;\r |
799c6677 | 507 | return refs[kNStor];\r |
508 | }\r | |
509 | \r | |
510 | //___________________________________________________________________\r | |
5ef3791d | 511 | Int_t AliLHCData::FillBunchInfo(int refs[2],const char* rec, int ibm, Bool_t inRealSlots, Double_t maxAbsVal)\r |
799c6677 | 512 | {\r |
513 | // fill bunch properties for beam ibm\r | |
514 | // if inRealSlots = true, then the value is taken from bunchRFbucket/10, otherwise, the value \r | |
515 | // for the i-th bunch is taken from the i-th element\r | |
516 | //\r | |
517 | AliInfo(Form("Acquiring record: %s",rec));\r | |
518 | TObjArray *arr;\r | |
0e9ab7ce | 519 | Int_t iLast,iFirst;\r |
799c6677 | 520 | //\r |
521 | refs[kStart] = fData.GetEntriesFast();\r | |
522 | refs[kNStor] = 0;\r | |
523 | //\r | |
0e9ab7ce | 524 | if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r |
41ff94a3 | 525 | //\r |
0e9ab7ce | 526 | while (iFirst<=iLast) {\r |
527 | AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r | |
799c6677 | 528 | double tstamp = dcsVal->GetTimeStamp();\r |
799c6677 | 529 | //\r |
530 | AliLHCDipValI *bconf = GetBunchConfigMeasured(ibm,tstamp);\r | |
531 | if (!bconf) {\r | |
532 | AliWarning(Form("Mearured bunch configuration for beam %d at t=%.1f is not available, trying declared one",ibm+1,tstamp));\r | |
533 | bconf = GetBunchConfigDeclared(ibm,tstamp);\r | |
534 | }\r | |
535 | if (!bconf) {\r | |
536 | AliWarning(Form("Declared bunch configuration for beam %d at t=%.1f is not available, skip this record",ibm+1,tstamp));\r | |
537 | return -1;\r | |
538 | }\r | |
539 | int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)\r | |
540 | int nbunch = bconf->GetSize();\r | |
541 | if (nbunch>nSlots) {\r | |
542 | AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));\r | |
543 | continue;\r | |
544 | }\r | |
545 | double* dcsArr = dcsVal->GetDouble();\r | |
a1063d3a | 546 | AliLHCDipValF* curValD = new AliLHCDipValF(nbunch,tstamp);\r |
799c6677 | 547 | for (int i=nbunch;i--;) {\r |
548 | int ind = inRealSlots ? (*bconf)[i]/10 : i;\r | |
549 | if (ind>nSlots) {\r | |
550 | AliError(Form("Bunch %d refers to wrong slot %d, set to -1",i,(*bconf)[i]));\r | |
649fda12 | 551 | (*curValD)[i] = -1;\r |
799c6677 | 552 | }\r |
5ef3791d | 553 | else {\r |
554 | double vcheck = dcsArr[ind];\r | |
555 | if (TMath::Abs(vcheck) > maxAbsVal) {\r | |
556 | AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",vcheck, ind, rec, maxAbsVal));\r | |
557 | vcheck = 0.;\r | |
558 | }\r | |
559 | (*curValD)[i] = vcheck;\r | |
560 | }\r | |
799c6677 | 561 | }\r |
649fda12 | 562 | fData.Add(curValD);\r |
799c6677 | 563 | refs[kNStor]++;\r |
564 | }\r | |
339fbe23 | 565 | if (fkFile2Process) delete arr;\r |
799c6677 | 566 | return refs[kNStor];\r |
567 | //\r | |
568 | }\r | |
569 | \r | |
570 | //___________________________________________________________________\r | |
5ef3791d | 571 | Int_t AliLHCData::FillBCLuminosities(int refs[2],const char* rec, const char* recErr, int useBeam, Double_t maxAbsVal)\r |
799c6677 | 572 | {\r |
573 | // fill luminosities per bunch crossing\r | |
574 | //\r | |
575 | AliInfo(Form("Acquiring record: %s",rec));\r | |
e08ebb54 | 576 | TObjArray *arr,*arrE=0;\r |
0e9ab7ce | 577 | Int_t iLast=0,iLastE=0,iFirst=0,iFirstE=0;\r |
799c6677 | 578 | //\r |
579 | refs[kStart] = fData.GetEntriesFast();\r | |
580 | refs[kNStor] = 0;\r | |
581 | //\r | |
0e9ab7ce | 582 | if ( !(arr=GetDCSEntry(rec,iFirst,iLast,fTMin,fTMax)) ) return -1;\r |
799c6677 | 583 | //\r |
0e9ab7ce | 584 | while (iFirst<=iLast) {\r |
585 | AliDCSArray *dcsVal = (AliDCSArray*) arr->At(iFirst++);\r | |
799c6677 | 586 | double tstamp = dcsVal->GetTimeStamp();\r |
799c6677 | 587 | //\r |
3760aa6b | 588 | AliLHCDipValI *bconf;\r |
589 | bconf = GetBunchConfigMeasured(useBeam,tstamp); // luminosities are stored according to beam bunches\r | |
799c6677 | 590 | if (!bconf) {\r |
3760aa6b | 591 | AliWarning(Form("Mearured bunch configuration for beam%d at t=%.1f is not available, trying declared one",useBeam,tstamp));\r |
592 | bconf = GetBunchConfigDeclared(useBeam,tstamp);\r | |
799c6677 | 593 | }\r |
594 | if (!bconf) {\r | |
3760aa6b | 595 | AliWarning(Form("Declared bunch configuration for beam%i at t=%.1f is not available, skip this record",useBeam,tstamp));\r |
799c6677 | 596 | return -1;\r |
597 | }\r | |
598 | int nSlots = dcsVal->GetNEntries(); // count number of actual bunches (non-zeros)\r | |
599 | int nbunch = bconf->GetSize();\r | |
600 | double* dcsArr = dcsVal->GetDouble();\r | |
601 | //\r | |
799c6677 | 602 | if (nbunch>nSlots) {\r |
603 | AliWarning(Form("More N bunches than slots in %s at time %.1f",rec,tstamp));\r | |
604 | continue;\r | |
605 | }\r | |
3760aa6b | 606 | int dim = 0;\r |
607 | if (!bconf->IsProcessed1()) {\r | |
608 | AliWarning(Form("Bunch conf. for beam%d has no marked interacting bunches, store all luminosity for all filled bunches",useBeam));\r | |
609 | dim = nbunch;\r | |
610 | }\r | |
611 | else { // count number of interacting bunches\r | |
612 | for (int i=nbunch;i--;) if ((*bconf)[i]<0) dim++;\r | |
613 | }\r | |
614 | //\r | |
799c6677 | 615 | if (recErr) {\r |
0e9ab7ce | 616 | arrE=GetDCSEntry(recErr,iFirstE,iLastE,fTMin,fTMax);\r |
799c6677 | 617 | dim += 1;\r |
618 | }\r | |
a1063d3a | 619 | AliLHCDipValF* curValD = new AliLHCDipValF(dim,tstamp);\r |
3760aa6b | 620 | int cnt = 0;\r |
621 | for (int i=0;i<nbunch;i++) {\r | |
622 | int slot = (*bconf)[i];\r | |
623 | if (bconf->IsProcessed1() && slot>0) continue;\r | |
624 | //\r | |
625 | int ind = TMath::Abs(slot)/10;\r | |
799c6677 | 626 | if (ind>nSlots) {\r |
3760aa6b | 627 | AliError(Form("Bunch %d refers to wrong slot %d, set to -1",cnt,slot));\r |
649fda12 | 628 | (*curValD)[cnt] = -1;\r |
799c6677 | 629 | }\r |
5ef3791d | 630 | else {\r |
631 | double vcheck = dcsArr[ind];\r | |
632 | if (TMath::Abs(vcheck) > maxAbsVal) {\r | |
633 | AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",vcheck, ind, rec, maxAbsVal));\r | |
634 | vcheck = 0.;\r | |
635 | }\r | |
636 | (*curValD)[i] = vcheck;\r | |
637 | }\r | |
3760aa6b | 638 | cnt++;\r |
799c6677 | 639 | }\r |
640 | //\r | |
641 | if (recErr) {\r | |
642 | double errVal = -1;\r | |
0e9ab7ce | 643 | while (iFirstE<=iLastE) { // try to find corresponding error\r |
644 | AliDCSArray *dcsValE = (AliDCSArray*) arrE->At(iFirstE);\r | |
799c6677 | 645 | double tstamp1 = dcsValE->GetTimeStamp();\r |
799c6677 | 646 | int tdif = TimeDifference(tstamp,tstamp1);\r |
647 | if (!tdif) { // error matches to value\r | |
648 | errVal = dcsValE->GetDouble()[0];\r | |
5ef3791d | 649 | if (TMath::Abs(errVal) > maxAbsVal) {\r |
650 | AliError(Form("ANOMALOUS VALUE %e for slot %d of %s: exceeds %e",errVal,0, rec, maxAbsVal));\r | |
651 | errVal = 0.;\r | |
652 | } \r | |
0e9ab7ce | 653 | iFirstE++; \r |
799c6677 | 654 | break;\r |
655 | }\r | |
0e9ab7ce | 656 | else if (tdif>0) iFirstE++; // error time lags behind, read the next one\r |
799c6677 | 657 | else break; // error time is ahead of value, no error associated\r |
658 | }\r | |
649fda12 | 659 | (*curValD)[dim-1] = errVal; // error\r |
660 | curValD->SetLastSpecial(); // lable the last entry as an error\r | |
799c6677 | 661 | }\r |
662 | //\r | |
649fda12 | 663 | fData.Add(curValD);\r |
799c6677 | 664 | refs[kNStor]++;\r |
665 | }\r | |
339fbe23 | 666 | if (fkFile2Process) {\r |
bab62329 | 667 | delete arr;\r |
668 | delete arrE;\r | |
669 | }\r | |
799c6677 | 670 | return refs[kNStor];\r |
671 | //\r | |
672 | }\r | |
673 | \r | |
674 | //___________________________________________________________________\r | |
675 | Int_t AliLHCData::ExtractInt(AliDCSArray* dcsArray,Int_t el) const\r | |
676 | {\r | |
677 | // extract integer from the dcsArray\r | |
678 | int val = -1;\r | |
679 | //\r | |
680 | int sz = dcsArray->GetNEntries();\r | |
681 | if (sz<=el) return val;\r | |
682 | //\r | |
683 | if (dcsArray->GetType()==AliDCSArray::kInt) val = dcsArray->GetInt(el);\r | |
684 | else if (dcsArray->GetType()==AliDCSArray::kString) {\r | |
685 | TObjString *stro = dcsArray->GetStringArray(el);\r | |
686 | if (stro) val = stro->GetString().Atoi();\r | |
687 | else AliError(Form("DCSArray TObjString for element %d is missing",el));\r | |
688 | }\r | |
689 | else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);\r | |
690 | else AliError(Form("Integer requested from DCSArray of type %d",dcsArray->GetType()));\r | |
691 | return val;\r | |
692 | }\r | |
693 | \r | |
694 | //___________________________________________________________________\r | |
695 | Double_t AliLHCData::ExtractDouble(AliDCSArray* dcsArray,Int_t el) const\r | |
696 | {\r | |
697 | // extract double from the dcsArray\r | |
698 | double val = 0;\r | |
699 | //\r | |
700 | int sz = dcsArray->GetNEntries();\r | |
701 | if (sz<=el) return val;\r | |
702 | //\r | |
703 | if (dcsArray->GetType()==AliDCSArray::kDouble) val = dcsArray->GetDouble(el);\r | |
704 | else if (dcsArray->GetType()==AliDCSArray::kFloat) val = dcsArray->GetFloat(el);\r | |
705 | else if (dcsArray->GetType()==AliDCSArray::kString) {\r | |
706 | TObjString *stro = dcsArray->GetStringArray(el);\r | |
707 | if (stro) val = stro->GetString().Atof();\r | |
708 | else AliError(Form("DCSArray has TObjString for element %d is missing",el));\r | |
709 | }\r | |
710 | else if (dcsArray->GetType()==AliDCSArray::kChar) val = dcsArray->GetChar(el);\r | |
711 | else if (dcsArray->GetType()==AliDCSArray::kInt) val = dcsArray->GetInt(el);\r | |
712 | else if (dcsArray->GetType()==AliDCSArray::kUInt) val = dcsArray->GetUInt(el);\r | |
713 | else AliError(Form("Double requested from DCSArray of type %d",dcsArray->GetType()));\r | |
714 | return val;\r | |
715 | }\r | |
716 | \r | |
717 | //___________________________________________________________________\r | |
718 | TString& AliLHCData::ExtractString(AliDCSArray* dcsArray) const\r | |
719 | {\r | |
720 | // extract string from the dcsArray\r | |
721 | static TString str;\r | |
722 | str = "";\r | |
723 | //\r | |
724 | int sz = dcsArray->GetNEntries();\r | |
725 | if (dcsArray->GetType()!=AliDCSArray::kString) {\r | |
726 | AliError(Form("String requested from DCSArray of type %d",dcsArray->GetType()));\r | |
727 | return str;\r | |
728 | }\r | |
729 | //\r | |
730 | for (int i=0;i<sz;i++) {\r | |
731 | str += dcsArray->GetStringArray(i)->GetString();\r | |
732 | if (i<sz-1) str += " ";\r | |
733 | }\r | |
734 | return str;\r | |
735 | }\r | |
736 | \r | |
737 | //___________________________________________________________________\r | |
738 | void AliLHCData::Print(const Option_t* opt) const\r | |
739 | {\r | |
740 | // print full info\r | |
741 | TString opts = opt;\r | |
742 | opts.ToLower();\r | |
41ff94a3 | 743 | Bool_t utcTime = opts.Contains("loc") ? kFALSE:kTRUE;\r |
799c6677 | 744 | Bool_t full = kTRUE;\r |
745 | if (!opts.Contains("f")) {\r | |
746 | printf("Use Print(\"f\") to print full info\n");\r | |
747 | printf("Printing short info:\n<RecordType>(number of records): <TimeStamp, value> for 1st record only\n");\r | |
748 | full = kFALSE;\r | |
749 | }\r | |
41ff94a3 | 750 | TString sdtmn = AliLHCDipValI::TimeAsString(fTMin,utcTime);\r |
751 | TString sdtmx = AliLHCDipValI::TimeAsString(fTMax,utcTime);\r | |
752 | printf("Fill#%6d Validity: %s - %s (%s)\n",fFillNumber,sdtmn.Data(),sdtmx.Data(),utcTime ? "UTC":"LOC");\r | |
799c6677 | 753 | //\r |
754 | printf("********** SETTINGS FROM RUN CONTROL **********\n");\r | |
755 | //\r | |
3760aa6b | 756 | printf("* %-38s","Injection Scheme");\r |
41ff94a3 | 757 | PrintAux(full,fRCInjScheme,opts);\r |
799c6677 | 758 | //\r |
3760aa6b | 759 | printf("* %-38s","Beta Star");\r |
41ff94a3 | 760 | PrintAux(full,fRCBeta,opts);\r |
799c6677 | 761 | //\r |
3760aa6b | 762 | printf("* %-38s","Horisontal Crossing Angle");\r |
41ff94a3 | 763 | PrintAux(full,fRCAngH,opts);\r |
799c6677 | 764 | //\r |
3760aa6b | 765 | printf("* %-38s","Vertical Crossing Angle");\r |
41ff94a3 | 766 | PrintAux(full,fRCAngV,opts);\r |
799c6677 | 767 | //\r |
768 | for (int ib=0;ib<2;ib++) {\r | |
3760aa6b | 769 | printf("* Beam%d filling [- interacts at IR2!] ",ib+1);\r |
41ff94a3 | 770 | PrintAux(full,fBunchConfDecl[ib],opts);\r |
799c6677 | 771 | }\r |
772 | //\r | |
773 | printf("\n********** MEASURED DATA **********\n");\r | |
774 | //\r | |
775 | for (int ib=0;ib<2;ib++) {\r | |
3760aa6b | 776 | printf("* Beam%d filling [- interacts at IR2!] ",ib+1);\r |
41ff94a3 | 777 | PrintAux(full,fBunchConfMeas[ib],opts);\r |
799c6677 | 778 | } \r |
779 | //\r | |
780 | for (int ib=0;ib<2;ib++) {\r | |
3760aa6b | 781 | printf("* Beam%d total intensity ",ib+1);\r |
41ff94a3 | 782 | PrintAux(full,fIntensTotal[ib],opts);\r |
799c6677 | 783 | } \r |
784 | //\r | |
785 | for (int ib=0;ib<2;ib++) {\r | |
3760aa6b | 786 | printf("* Beam%d total intensity (bunch average) ",ib+1);\r |
41ff94a3 | 787 | PrintAux(full,fIntensTotalAv[ib],opts);\r |
799c6677 | 788 | } \r |
789 | //\r | |
790 | for (int ib=0;ib<2;ib++) {\r | |
3760aa6b | 791 | printf("* Beam%d intensity per bunch ",ib+1);\r |
41ff94a3 | 792 | PrintAux(full,fIntensPerBunch[ib],opts);\r |
799c6677 | 793 | }\r |
794 | //\r | |
795 | for (int ib=0;ib<2;ib++) {\r | |
3760aa6b | 796 | printf("* Beam%d bunch lengths ",ib+1);\r |
41ff94a3 | 797 | PrintAux(full,fBunchLengths[ib],opts);\r |
799c6677 | 798 | } \r |
799 | //\r | |
800 | for (int ib=0;ib<2;ib++) {\r | |
3760aa6b | 801 | printf("* Beam%d Horisontal emittance ",ib+1);\r |
41ff94a3 | 802 | PrintAux(full,fEmittanceH[ib],opts);\r |
799c6677 | 803 | }\r |
804 | //\r | |
805 | for (int ib=0;ib<2;ib++) {\r | |
3760aa6b | 806 | printf("* Beam%d Vertical emittance ",ib+1);\r |
41ff94a3 | 807 | PrintAux(full,fEmittanceV[ib],opts);\r |
799c6677 | 808 | }\r |
809 | //\r | |
810 | for (int ib=0;ib<2;ib++) {\r | |
3760aa6b | 811 | printf("* Beam%d Horisontal sigma ",ib+1);\r |
41ff94a3 | 812 | PrintAux(full,fBeamSigmaH[ib],opts);\r |
799c6677 | 813 | }\r |
814 | //\r | |
815 | for (int ib=0;ib<2;ib++) {\r | |
3760aa6b | 816 | printf("* Beam%d Vertical sigma ",ib+1);\r |
41ff94a3 | 817 | PrintAux(full,fBeamSigmaV[ib],opts);\r |
799c6677 | 818 | }\r |
819 | //\r | |
820 | for (int lr=0;lr<2;lr++) {\r | |
3760aa6b | 821 | printf("* Total luminosity from BRANB_4%c2 ",lr ? 'R':'L');\r |
41ff94a3 | 822 | PrintAux(full,fLuminTotal[lr],opts);\r |
799c6677 | 823 | } \r |
824 | //\r | |
825 | for (int lr=0;lr<2;lr++) {\r | |
3760aa6b | 826 | printf("* Luminosity acq.mode, BRANB_4%c2 ",lr ? 'R':'L');\r |
41ff94a3 | 827 | PrintAux(full,fLuminAcqMode[lr],opts+"bit");\r |
799c6677 | 828 | } \r |
829 | //\r | |
830 | for (int lr=0;lr<2;lr++) {\r | |
3760aa6b | 831 | printf("* Luminosity per BC from BRANB_4%c2 ",lr ? 'R':'L');\r |
41ff94a3 | 832 | PrintAux(full,fLuminPerBC[lr],opts);\r |
799c6677 | 833 | }\r |
834 | //\r | |
835 | for (int lr=0;lr<2;lr++) {\r | |
3760aa6b | 836 | printf("* Crossing angle, side %c ",lr ? 'R':'L');\r |
41ff94a3 | 837 | PrintAux(full,fCrossAngle[lr],opts);\r |
799c6677 | 838 | }\r |
839 | //\r | |
840 | for (int coll=0;coll<kNCollimators;coll++)\r | |
841 | for (int jaw=0;jaw<kNJaws;jaw++) {\r | |
3760aa6b | 842 | printf("* Collimator %10s:%16s",fgkDCSColNames[coll],fgkDCSColJaws[jaw]);\r |
41ff94a3 | 843 | PrintAux(full,fCollimators[coll][jaw],opts);\r |
799c6677 | 844 | }\r |
845 | //\r | |
46d3b556 | 846 | printf("* Alice fill integrated luminosity data: ");\r |
847 | PrintAux(full,fLumiAlice,opts);\r | |
848 | //\r | |
849 | printf("* Alice fill integrated background data ");\r | |
850 | PrintAux(full,fBckgAlice,opts);\r | |
851 | //\r | |
852 | \r | |
799c6677 | 853 | }\r |
854 | \r | |
855 | //___________________________________________________________________\r | |
bab62329 | 856 | void AliLHCData::PrintAux(Bool_t full, const Int_t refs[2], const Option_t *opt) const\r |
799c6677 | 857 | {\r |
858 | // aux method to print the reocrds of the same type\r | |
859 | int nrec = refs[kNStor];\r | |
860 | if (nrec<1) {\r | |
861 | printf(": N/A\n"); \r | |
862 | return;\r | |
863 | }\r | |
3760aa6b | 864 | printf(": (%3d):\t",nrec); // number of records\r |
799c6677 | 865 | if (!full) nrec = 1;\r |
866 | int sz = ((AliLHCDipValI*)fData[refs[kStart]])->GetSizeTotal(); // dimension of the record\r | |
867 | Bool_t isStr = ((AliLHCDipValI*)fData[refs[kStart]])->IsTypeC();\r | |
868 | if ((!isStr && sz>2) || nrec>1) printf("\n"); // long record, open new line\r | |
bab62329 | 869 | for (int i=0;i<nrec;i++) fData[refs[kStart]+i]->Print(opt);\r |
799c6677 | 870 | //\r |
871 | }\r | |
872 | \r | |
873 | //___________________________________________________________________\r | |
874 | void AliLHCData::Clear(const Option_t *)\r | |
875 | {\r | |
876 | // clear all info\r | |
877 | fData.Delete();\r | |
878 | fFillNumber = 0;\r | |
879 | fTMin = 0;\r | |
880 | fTMax = 1e10;\r | |
339fbe23 | 881 | fkFile2Process = 0;\r |
882 | fkMap2Process = 0;\r | |
bab62329 | 883 | //\r |
799c6677 | 884 | for (int i=2;i--;) {\r |
885 | fRCInjScheme[i] = 0;\r | |
886 | fRCBeta[i] = 0;\r | |
887 | fRCAngH[i] = 0;\r | |
888 | fRCAngV[i] = 0;\r | |
46d3b556 | 889 | fLumiAlice[i] = 0;\r |
890 | fBckgAlice[i] = 0; \r | |
799c6677 | 891 | //\r |
892 | for (int icl=kNCollimators;icl--;) for (int jaw=kNJaws;jaw--;) fCollimators[icl][jaw][i]=0;\r | |
893 | //\r | |
894 | for (int j=2;j--;) {\r | |
895 | fBunchConfDecl[j][i] = 0;\r | |
896 | fBunchConfMeas[j][i] = 0;\r | |
897 | fBunchLengths[j][i] = 0;\r | |
898 | fIntensTotal[j][i] = 0;\r | |
899 | fIntensTotalAv[j][i] = 0;\r | |
900 | fIntensPerBunch[j][i] = 0; \r | |
901 | fCrossAngle[j][i] = 0;\r | |
902 | fEmittanceH[j][i] = 0;\r | |
903 | fEmittanceV[j][i] = 0;\r | |
904 | fBeamSigmaH[j][i] = 0;\r | |
905 | fBeamSigmaV[j][i] = 0;\r | |
906 | fLuminTotal[j][i] = 0;\r | |
907 | fLuminPerBC[j][i] = 0;\r | |
908 | fLuminAcqMode[j][i] = 0;\r | |
909 | }\r | |
910 | }\r | |
911 | }\r | |
912 | \r | |
913 | //___________________________________________________________________\r | |
914 | Int_t AliLHCData::GetNInteractingBunchesMeasured(int i) const\r | |
915 | {\r | |
916 | // get number of interacting bunches at IR2\r | |
917 | AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r | |
918 | if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r | |
919 | if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1;}\r | |
920 | int n = 0;\r | |
e08ebb54 | 921 | for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;\r |
799c6677 | 922 | return n;\r |
923 | }\r | |
924 | \r | |
925 | //___________________________________________________________________\r | |
926 | Int_t AliLHCData::GetNInteractingBunchesDeclared(int i) const\r | |
927 | {\r | |
928 | // get number of interacting bunches at IR2\r | |
929 | AliLHCDipValI* rec = GetBunchConfigMeasured(kBeam1,i);\r | |
930 | if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r | |
931 | if (!rec->IsProcessed1()) { AliInfo("Interacting bunches were not marked"); return -1; }\r | |
932 | int n = 0;\r | |
e08ebb54 | 933 | for (int j=rec->GetSize();j--;) if ( (*rec)[j]<0 ) n++;\r |
799c6677 | 934 | return n;\r |
935 | }\r | |
936 | \r | |
937 | //___________________________________________________________________\r | |
938 | Int_t AliLHCData::IsPilotPresent(int i) const\r | |
939 | {\r | |
940 | // check in the filling scheme is the pilot bunch is present\r | |
941 | AliLHCDipValC* rec = GetInjectionScheme();\r | |
942 | if (!rec) {AliInfo(Form("No record %d found",i)); return -1;}\r | |
943 | TString scheme = rec->GetValues();\r | |
944 | return scheme.Contains("wp",TString::kIgnoreCase);\r | |
945 | }\r | |
3760aa6b | 946 | \r |
947 | //___________________________________________________________________\r | |
948 | void AliLHCData::FlagInteractingBunches(const Int_t beam1[2],const Int_t beam2[2])\r | |
949 | {\r | |
950 | // assign - sign to interacting bunches\r | |
3760aa6b | 951 | //\r |
952 | for (int ib1=0;ib1<beam1[kNStor];ib1++) {\r | |
953 | AliLHCDipValI *bm1 = (AliLHCDipValI*)fData[ beam1[kStart] + ib1];\r | |
954 | if (!bm1) continue;\r | |
955 | AliLHCDipValI *bm2 = (AliLHCDipValI*)FindRecValidFor(beam2[kStart],beam2[kNStor], bm1->GetTimeStamp());\r | |
956 | if (!bm2) continue;\r | |
957 | //\r | |
958 | int nb1 = bm1->GetSize();\r | |
959 | int nb2 = bm2->GetSize();\r | |
960 | int i1,i2;\r | |
961 | for (i1=0;i1<nb1;i1++) {\r | |
962 | int bunch2=-1, bunch1 = TMath::Abs((*bm1)[i1]);\r | |
2af04ffd | 963 | int slot2 =-1, slot1 = GetBCId(bunch1,0);\r |
3760aa6b | 964 | for (i2=0;i2<nb2;i2++) {\r |
965 | bunch2 = TMath::Abs((*bm2)[i2]);\r | |
2af04ffd | 966 | slot2 = GetBCId(bunch2,1);\r |
3760aa6b | 967 | if (slot1==slot2) break;\r |
968 | }\r | |
969 | if (slot1!=slot2) continue;\r | |
970 | (*bm1)[i1] = -bunch1;\r | |
971 | (*bm2)[i2] = -bunch2;\r | |
972 | bm1->SetProcessed1();\r | |
973 | bm2->SetProcessed1();\r | |
974 | }\r | |
975 | }\r | |
976 | }\r | |
3d84ad67 | 977 | \r |
978 | //___________________________________________________________________\r | |
2af04ffd | 979 | Int_t AliLHCData::GetMeanIntensity(int beamID, Double_t &colliding, Double_t &noncolliding, const TObjArray* bcmasks) const\r |
3d84ad67 | 980 | {\r |
981 | // get average intensity for all, colliding and non-colliding bunches\r | |
982 | // on success returns number of intensity records used (1 per ~10 min)\r | |
2af04ffd | 983 | // If triggered BC masks are provided, calculation is done for Triggered BC only\r |
3d84ad67 | 984 | colliding = noncolliding = -1.;\r |
985 | if (beamID<0||beamID>1) {\r | |
986 | AliError(Form("BeamID must be either 0 or 1, %d requested",beamID));\r | |
987 | return -10;\r | |
988 | }\r | |
989 | //\r | |
2af04ffd | 990 | AliTriggerBCMask *bcMaskBoth=0,*bcMaskSingle=0;\r |
991 | int nbcm = 0;\r | |
992 | if (bcmasks && (nbcm=bcmasks->GetEntries())) {\r | |
993 | if (nbcm>1) bcMaskBoth = (AliTriggerBCMask*)bcmasks->At(1);\r | |
994 | if (nbcm>0 && beamID==kBeam1) bcMaskSingle = (AliTriggerBCMask*)bcmasks->At(0);\r | |
995 | else if (nbcm>2 && beamID==kBeam2) bcMaskSingle = (AliTriggerBCMask*)bcmasks->At(2);\r | |
996 | //\r | |
997 | if (!bcMaskSingle) AliError(Form("Only triggered BSs are requested but %c mask is not provided",beamID ? 'C':'A'));\r | |
998 | if (!bcMaskBoth) AliError("Only triggered BSs are requested but B mask is not provided");\r | |
999 | }\r | |
1000 | else {\r | |
1001 | AliWarning("No BC masks are provided");\r | |
1002 | }\r | |
1003 | //\r | |
3d84ad67 | 1004 | int nrec = GetNIntensityPerBunch(beamID);\r |
1005 | if (nrec<1) return -1;\r | |
1006 | AliLHCDipValI *conf = GetBunchConfigMeasured(beamID);\r | |
1007 | if (!conf) conf = GetBunchConfigDeclared(beamID);\r | |
1008 | if (!conf) return -2;\r | |
1009 | int nb = conf->GetSize();\r | |
1010 | //\r | |
1011 | for (int irec=0;irec<nrec;irec++) {\r | |
2af04ffd | 1012 | //\r |
a1063d3a | 1013 | AliLHCDipValD* rIntD = 0;\r |
1014 | AliLHCDipValF* rIntF = GetIntensityPerBunch(beamID,irec);\r | |
1015 | // for BWD compatibility of some periods\r | |
1016 | if (rIntF->IsA() == AliLHCDipValD::Class()) {rIntD=(AliLHCDipValD*)rIntF; rIntF=0;}\r | |
5c817c06 | 1017 | if (!rIntF && !rIntD) {\r |
1018 | AliError(Form("Failed to get GetIntensityPerBunch(%d,%d)",beamID,irec));\r | |
1019 | continue;\r | |
1020 | }\r | |
3d84ad67 | 1021 | for (int ib=0;ib<nb;ib++) {\r |
5c817c06 | 1022 | double val = 0;\r |
1023 | if (rIntF) val = rIntF->GetValue(ib);\r | |
1024 | else if (rIntD) val = rIntD->GetValue(ib);\r | |
3d84ad67 | 1025 | if (val<0) continue;\r |
1026 | int bID = conf->GetValue(ib);\r | |
2af04ffd | 1027 | // check if this is a triggered bunch\r |
1028 | int bcID = GetBCId(bID, beamID);\r | |
1029 | if (bID<0) { // interacting\r | |
1030 | if (bcMaskBoth && bcMaskBoth->GetMask(bcID)) continue; // masked\r | |
1031 | colliding += val;\r | |
1032 | }\r | |
1033 | else {\r | |
1034 | if (bcMaskSingle && bcMaskSingle->GetMask(bcID)) continue; // masked \r | |
1035 | noncolliding += val;\r | |
1036 | }\r | |
3d84ad67 | 1037 | }\r |
1038 | }\r | |
1039 | colliding /= nrec;\r | |
1040 | noncolliding /= nrec;\r | |
1041 | return nrec;\r | |
1042 | }\r | |
46d3b556 | 1043 | \r |
1044 | //___________________________________________________________________\r | |
1045 | void AliLHCData::FillLumiAlice(Int_t nrec, Int_t* timeArr, Double_t* valArr)\r | |
1046 | {\r | |
1047 | // Create a record for lumi integrated from the beginning of fill\r | |
1048 | // We need dedicated method since this info comes from Alice (not LHCDip) as instantaneous values\r | |
1049 | // and is retrofitted for past runs\r | |
1050 | fLumiAlice[kStart] = fData.GetEntriesFast();\r | |
1051 | fLumiAlice[kNStor] = 0;\r | |
1052 | if (nrec<2 || !timeArr || !valArr) return;\r | |
1053 | double tprv,period,currTime;\r | |
1054 | if ((currTime=double(UInt_t(timeArr[0])))>fTMin) {\r | |
1055 | AliError(Form("TimeStamp of 1st record: %s > TimeStamp of SOR: %s, STOP",\r | |
1056 | AliLHCDipValI::TimeAsString(currTime),AliLHCDipValI::TimeAsString(fTMin)));\r | |
1057 | return;\r | |
1058 | }\r | |
1059 | //\r | |
1060 | if ((tprv=double(UInt_t(timeArr[nrec-1])))<fTMax) {\r | |
1061 | AliWarning(Form("TimeStamp of last (%d) record: %s < TimeStamp of EOR: %s, Data will be truncated",nrec-1,\r | |
1062 | AliLHCDipValI::TimeAsString(tprv),AliLHCDipValI::TimeAsString(fTMax)));\r | |
1063 | }\r | |
1064 | //\r | |
1065 | // init the average time step\r | |
1066 | period = (tprv - currTime)/(nrec-1);\r | |
1067 | double lumiInt = 0;\r | |
1068 | //\r | |
1069 | for (int i=0;i<nrec;i++) {\r | |
1070 | tprv = currTime;\r | |
1071 | currTime = double(UInt_t(timeArr[i]));\r | |
1072 | if (i>0) period = currTime - tprv;\r | |
1073 | if (currTime-period>fTMax) continue; \r | |
1074 | lumiInt += valArr[i]*period; \r | |
1075 | // printf("%d %.2f V:%f Int:%f\n",i,period,valArr[i],lumiInt);\r | |
1076 | if (currTime+period<fTMin) continue;\r | |
1077 | AliLHCDipValF* curValF = new AliLHCDipValF(1,currTime);\r | |
1078 | (*curValF)[0] = lumiInt;\r | |
1079 | fData.Add(curValF);\r | |
1080 | fLumiAlice[kNStor]++;\r | |
1081 | }\r | |
1082 | //\r | |
1083 | printf("Stored %d Alice Integrated luminosity records out of %d provided\n",fLumiAlice[kNStor],nrec);\r | |
1084 | }\r | |
1085 | \r | |
1086 | //___________________________________________________________________\r | |
1087 | void AliLHCData::FillBckgAlice(Int_t nrec, Int_t* timeArr, Double_t* valArr)\r | |
1088 | {\r | |
1089 | // Create a record for lumi integrated from the beginning of fill\r | |
1090 | // We need dedicated method since this info comes from Alice (not LHCDip) as instantaneous values\r | |
1091 | // and is retrofitted for past runs\r | |
1092 | fBckgAlice[kStart] = fData.GetEntriesFast();\r | |
1093 | fBckgAlice[kNStor] = 0;\r | |
1094 | if (nrec<2 || !timeArr || !valArr) return;\r | |
1095 | double tprv,period,currTime;\r | |
1096 | if ((currTime=double(UInt_t(timeArr[0])))>fTMin) {\r | |
1097 | AliError(Form("TimeStamp of 1st record: %s > TimeStamp of SOR: %s, STOP",\r | |
1098 | AliLHCDipValI::TimeAsString(currTime),AliLHCDipValI::TimeAsString(fTMin)));\r | |
1099 | return;\r | |
1100 | }\r | |
1101 | //\r | |
1102 | if ((tprv=double(UInt_t(timeArr[nrec-1])))<fTMax) {\r | |
1103 | AliWarning(Form("TimeStamp of last (%d) record: %s < TimeStamp of EOR: %s, Data will be truncated",nrec-1,\r | |
1104 | AliLHCDipValI::TimeAsString(tprv),AliLHCDipValI::TimeAsString(fTMax)));\r | |
1105 | }\r | |
1106 | //\r | |
1107 | // init the average time step\r | |
1108 | period = (tprv - currTime)/(nrec-1);\r | |
1109 | double bckgInt = 0;\r | |
1110 | //\r | |
1111 | for (int i=0;i<nrec;i++) {\r | |
1112 | tprv = currTime;\r | |
1113 | currTime = double(UInt_t(timeArr[i]));\r | |
1114 | if (i>0) period = currTime - tprv;\r | |
1115 | if (currTime-period>fTMax) continue; \r | |
1116 | bckgInt += valArr[i]*period; \r | |
1117 | if (currTime+period<fTMin) continue;\r | |
1118 | AliLHCDipValF* curValF = new AliLHCDipValF(1,currTime);\r | |
1119 | (*curValF)[0] = bckgInt;\r | |
1120 | fData.Add(curValF);\r | |
1121 | fBckgAlice[kNStor]++;\r | |
1122 | }\r | |
1123 | //\r | |
1124 | printf("Stored %d Alice Integrated Background records out of %d provided\n",fBckgAlice[kNStor],nrec);\r | |
1125 | }\r | |
1126 | \r | |
1127 | //_____________________________________________________________________________\r | |
1128 | Float_t AliLHCData::GetLumiInstAlice(Double_t tStamp) const \r | |
1129 | {\r | |
1130 | // get closest in time value on inst luminosity\r | |
1131 | int idx = FindEntryValidFor(fLumiAlice[kStart],fLumiAlice[kNStor],tStamp);\r | |
1132 | if (idx<0) return -1;\r | |
1133 | AliLHCDipValF *rec=GetLumiAliceRecord(idx),*rec1=GetLumiAliceRecord(idx>0 ? idx-1:idx+1);\r | |
1134 | if (!rec || !rec1) return -1;\r | |
1135 | double dt = rec->GetTimeStamp() - rec1->GetTimeStamp();\r | |
1136 | return TMath::Abs(dt)>1e-6 ? (rec->GetValue()-rec1->GetValue())/dt : -1;\r | |
1137 | }\r | |
1138 | \r | |
1139 | //_____________________________________________________________________________\r | |
1140 | Float_t AliLHCData::GetBckgInstAlice(Double_t tStamp) const \r | |
1141 | {\r | |
1142 | // get closest in time value on inst luminosity\r | |
1143 | int idx = FindEntryValidFor(fBckgAlice[kStart],fBckgAlice[kNStor],tStamp);\r | |
1144 | if (idx<0) return -1;\r | |
1145 | AliLHCDipValF *rec=GetBckgAliceRecord(idx),*rec1=GetBckgAliceRecord(idx>0 ? idx-1:idx+1);\r | |
1146 | if (!rec || !rec1) return -1;\r | |
1147 | double dt = rec->GetTimeStamp() - rec1->GetTimeStamp();\r | |
1148 | return TMath::Abs(dt)>1e-6 ? (rec->GetValue()-rec1->GetValue())/dt : -1;\r | |
1149 | }\r | |
1150 | \r | |
1151 | //_____________________________________________________________________________\r | |
1152 | TGraph* AliLHCData::ExportGraph(Int_t *coord, Int_t elID) const\r | |
1153 | {\r | |
1154 | // export time/values to graph:\r | |
1155 | // coord: int[2] array with 1st entry and number of entries stored, obtained via GetOffs... method \r | |
1156 | // elID - element of the AliLHCDipValT array to extract\r | |
1157 | if (!coord || coord[1]<1) return 0;\r | |
1158 | TGraph* gr = new TGraph(coord[1]);\r | |
1159 | for (int i=0;i<coord[1];i++) {\r | |
1160 | TObject* obj = fData.At(coord[0]+i);\r | |
1161 | if (!obj) {\r | |
1162 | AliError(Form("Entry %d does not exist",i));\r | |
1163 | continue;\r | |
1164 | }\r | |
1165 | if (obj->IsA()==AliLHCDipValD::Class()) {\r | |
1166 | AliLHCDipValD* objD = (AliLHCDipValD*)obj;\r | |
1167 | gr->SetPoint(i,objD->GetTimeStamp(),objD->GetValue(elID));\r | |
1168 | }\r | |
1169 | else if (obj->IsA()==AliLHCDipValF::Class()) {\r | |
1170 | AliLHCDipValF* objF = (AliLHCDipValF*)obj;\r | |
1171 | gr->SetPoint(i,objF->GetTimeStamp(),objF->GetValue(elID));\r | |
1172 | }\r | |
1173 | else if (obj->IsA()==AliLHCDipValI::Class()) {\r | |
1174 | AliLHCDipValI* objI = (AliLHCDipValI*)obj;\r | |
1175 | gr->SetPoint(i,objI->GetTimeStamp(),objI->GetValue(elID));\r | |
1176 | }\r | |
1177 | else if (obj->IsA()==AliLHCDipValC::Class()) {\r | |
1178 | AliLHCDipValC* objC = (AliLHCDipValC*)obj;\r | |
1179 | gr->SetPoint(i,objC->GetTimeStamp(),objC->GetValue(elID));\r | |
1180 | }\r | |
1181 | else {\r | |
1182 | AliError(Form("Graph cannot be exported for records of type %s",obj->IsA()->GetName()));\r | |
1183 | }\r | |
1184 | }\r | |
1185 | return gr;\r | |
1186 | }\r |