1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
18 #include "AliLHCData.h"
24 const Char_t* AliLHCData::fgkDCSNames[] = {
25 "lhcMon_LHCIntensityBeam%d.totalIntensity",
26 "lhcInst_BeamIntensityPerBunchBeam%d.averageBeamIntensity",
27 "lhcInst_BeamIntensityPerBunchBeam%d_Avgerage.averageBunchIntensities",
28 "lhcMon_LHCLumAverageBRANB_4%c2.meanLuminosity",
29 "lhcInst_BeamLuminosityPerBunchBRANB_4%c2_Average.bunchByBunchLuminosity",
30 "lhcMon_LHCLumAverageBRANB_4%c2.meanCrossingAngle",
31 "lhcMon_LHCCirculatingBunchConfig_Beam%d.value",
32 "lhcMon_LHCFillNumber.payload",
34 "lhcMon_LHCBeamSizeBeam%d.planeSet%d",
35 "lhcMon_LHCBeamSizeBeam%d.amplitudeSet%d",
36 "lhcMon_LHCBeamSizeBeam%d.positionSet%d",
37 "lhcMon_LHCBeamSizeBeam%d.sigmaSet%d"
40 const Char_t* AliLHCData::fgkDCSColNames[] = {
41 "lhcMon_LHCCollimatorPos_TCTVB_4L2.%s",
42 "lhcMon_LHCCollimatorPos_TCTVB_4R2.%s",
43 "lhcMon_LHCCollimatorPos_TCLIA_4R2.%s"
46 const Char_t* AliLHCData::fgkDCSColJaws[] = {
47 "lvdt_gap_downstream","lvdt_gap_upstream","lvdt_left_downstream",
48 "lvdt_left_upstream","lvdt_right_downstream","lvdt_right_upstream"};
50 //___________________________________________________________________
51 AliLHCData::AliLHCData(const TMap* dcsMap, double tmin, double tmax, int avPeriod)
52 : fPeriod(avPeriod),fTMin(tmin),fTMax(tmax)
54 FillData(dcsMap,tmin,tmax);
57 //___________________________________________________________________
58 Bool_t AliLHCData::FillData(const TMap* dcsMap, double tmin, double tmax)
60 // process DCS map and fill all fields.
61 // Accept only entries with timestamp between tmin and tmax
62 const double ktReal = 1200000000.;
63 const double kCollTolerance = 100e-4; // tolerance on collimator move (cm)
67 Double_t tPeriodEnd=0;
68 Int_t dcsSize,nEntries,iEntry;
73 // -------------------------- extract Fill Number
74 arr = GetDCSEntry(dcsMap,fgkDCSNames[kRecFillNum],iEntry,tmin,tmax);
75 if (arr && iEntry>=0) SetFillNumber( ((AliDCSArray*)arr->At(iEntry))->GetInt(0) );
77 // -------------------------- extract total intensities for beam 1 and 2 (DC BCT: slow average)
78 for (int ibm=0;ibm<2;ibm++) {
80 sprintf(buff,fgkDCSNames[kRecTotInt],ibm+1);
81 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
82 AliLHCDipValD* curVal = 0;
85 nEntries = arr->GetEntriesFast();
86 while (iEntry<nEntries) {
87 dcsVal = (AliDCSArray*) arr->At(iEntry++);
88 double tstamp = dcsVal->GetTimeStamp();
89 if (tstamp>tmax) break;
90 if (tstamp>tPeriodEnd) {
91 curVal = new AliLHCDipValD(1,0.,0); // start new period
92 fIntTot[ibm].Add(curVal);
93 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
94 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
95 tPeriodEnd += fPeriod;
99 for (int i=fIntTot[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntTot[ibm])[i])->Average();
102 // -------------------------- extract total intensities for beam 1 and 2 (BCTFR: fast average)
103 for (int ibm=0;ibm<2;ibm++) {
105 sprintf(buff,fgkDCSNames[kRecTotIntBunch],ibm+1);
106 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
107 AliLHCDipValD* curVal = 0;
110 nEntries = arr->GetEntriesFast();
111 while (iEntry<nEntries) {
112 dcsVal = (AliDCSArray*) arr->At(iEntry++);
113 double tstamp = dcsVal->GetTimeStamp();
114 if (tstamp>tmax) break;
115 if (tstamp>tPeriodEnd) {
116 curVal = new AliLHCDipValD(1,0.,0); // start new period
117 fIntTotBunch[ibm].Add(curVal);
118 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
119 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
120 tPeriodEnd += fPeriod;
124 for (int i=fIntTotBunch[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntTotBunch[ibm])[i])->Average();
127 // -------------------------- extract total luminosities according L and R detectors
128 for (int ilr=0;ilr<2;ilr++) {
130 sprintf(buff,fgkDCSNames[kRecTotLum],ilr ? 'L':'R');
131 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
132 AliLHCDipValD* curVal = 0;
135 nEntries = arr->GetEntriesFast();
136 while (iEntry<nEntries) {
137 dcsVal = (AliDCSArray*) arr->At(iEntry++);
138 double tstamp = dcsVal->GetTimeStamp();
139 if (tstamp>tmax) break;
140 if (tstamp>tPeriodEnd) {
141 curVal = new AliLHCDipValD(1,0.,0); // start new period
142 fLuminTot[ilr].Add(curVal);
143 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
144 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
145 tPeriodEnd += fPeriod;
149 for (int i=fLuminTot[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fLuminTot[ilr])[i])->Average();
152 // -------------------------- extract mean crossing angles according to L and R detectors
153 for (int ilr=0;ilr<2;ilr++) {
155 sprintf(buff,fgkDCSNames[kRecCrossAngle],ilr ? 'L':'R');
156 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
157 AliLHCDipValD* curVal = 0;
160 nEntries = arr->GetEntriesFast();
161 while (iEntry<nEntries) {
162 dcsVal = (AliDCSArray*) arr->At(iEntry++);
163 double tstamp = dcsVal->GetTimeStamp();
164 if (tstamp>tmax) break;
165 if (tstamp>tPeriodEnd) {
166 curVal = new AliLHCDipValD(1,0.,0); // start new period
167 fCrossAngle[ilr].Add(curVal);
168 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
169 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
170 tPeriodEnd += fPeriod;
174 for (int i=fCrossAngle[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fCrossAngle[ilr])[i])->Average();
178 // ------------------------- extract bunch configuration for beam 1 and 2
180 for (int ibm=0;ibm<2;ibm++) {
183 sprintf(buff,fgkDCSNames[kRecBunchConf],ibm+1);
184 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
185 dcsVal = (AliDCSArray*) arr->At(iEntry);
186 nEntries = dcsVal->GetNEntries(); // count number of actual bunches
188 while(nbunch[ibm]<nEntries && dcsVal->GetInt(nbunch[ibm])) nbunch[ibm]++;
190 AliWarning(Form("Beam%d bunches configuration record is present but empty",ibm+1));
193 fBunchConfig[ibm].SetSize(nbunch[ibm]);
194 fBunchConfig[ibm] += *dcsVal;
196 // -------------------------- extract intensities per bunch for beam 1 and 2
197 for (int ibm=0;ibm<2;ibm++) {
199 sprintf(buff,fgkDCSNames[kRecBunchInt],ibm+1);
200 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
201 AliLHCDipValD* curVal = 0;
204 dcsVal = (AliDCSArray*)arr->At(iEntry);
205 nEntries = dcsVal->GetNEntries(); // count number of actual bunches
207 while(dcsSize<nEntries && dcsVal->GetDouble(dcsSize)>0) dcsSize++;
209 AliWarning(Form("Beam%d bunch intensities record is present but empty",ibm+1));
212 if (nbunch[ibm]>0) { // bunch pattern was provided
213 if (dcsSize>nbunch[ibm]) {
214 AliWarning(Form("Beam%d declares %d bunches but %d bunch intensities are non-0. Take first %d",
215 ibm+1,nbunch[ibm],dcsSize,nbunch[ibm]));
216 dcsSize = nbunch[ibm];
218 else if (dcsSize<nbunch[ibm]) {
219 AliWarning(Form("Beam%d declares %d bunches but %d bunch intensities are non-0. Skip",
220 ibm+1,nbunch[ibm],dcsSize));
225 nEntries = arr->GetEntriesFast();
226 while (iEntry<nEntries) {
227 dcsVal = (AliDCSArray*) arr->At(iEntry++);
228 double tstamp = dcsVal->GetTimeStamp();
229 if (tstamp>tmax) break;
230 if (tstamp>tPeriodEnd) {
231 curVal = new AliLHCDipValD(dcsSize,0.,0); // start new period
232 fIntBunch[ibm].Add(curVal);
233 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
234 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
235 tPeriodEnd += fPeriod;
239 for (int i=fIntBunch[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntBunch[ibm])[i])->Average();
242 // -------------------------- extract per bunch luminosities according L and R detectors
243 for (int ilr=0;ilr<2;ilr++) {
245 sprintf(buff,fgkDCSNames[kRecBunchLum],ilr ? 'L':'R');
246 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
247 AliLHCDipValD* curVal = 0;
250 dcsVal = (AliDCSArray*) arr->At(iEntry);
251 nEntries = dcsVal->GetNEntries(); // count number of actual bunches
253 while(dcsSize<nEntries && dcsVal->GetDouble(dcsSize)>0) dcsSize++;
255 AliWarning(Form("Probe%c bunch luminosities record is present but empty",ilr ? 'R':'L'));
259 if (nbunch[ilr]>0) { // bunch pattern was provided
260 if (dcsSize>nbunch[ilr]) {
261 AliWarning(Form("Beam%d declares %d bunches but %d bunch luminosities are non-0. Take first %d",
262 ilr+1,nbunch[ilr],dcsSize,nbunch[ilr]));
263 dcsSize = nbunch[ilr];
265 else if (dcsSize<nbunch[ilr]) {
266 AliWarning(Form("Beam%d declares %d bunches but %d bunch luminosities are non-0. Skip",
267 ilr+1,nbunch[ilr],dcsSize));
272 nEntries = arr->GetEntriesFast();
273 while (iEntry<nEntries) {
274 dcsVal = (AliDCSArray*) arr->At(iEntry++);
275 double tstamp = dcsVal->GetTimeStamp();
276 if (tstamp>tmax) break;
277 if (tstamp>tPeriodEnd) {
278 curVal = new AliLHCDipValD(dcsSize,0.,0); // start new period
279 fLuminBunch[ilr].Add(curVal);
280 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
281 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
282 tPeriodEnd += fPeriod;
286 for (int i=fLuminBunch[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fLuminBunch[ilr])[i])->Average();
289 // ------------------------- extract gaussian fit params for beam 1 and 2 profiles
290 for (int ibm=0;ibm<2;ibm++) {
291 for (int ixy=0;ixy<2;ixy++) {
292 // determine which projection corresponds actually to given ixy
293 sprintf(buff,fgkDCSNames[kRecPrfPrID],ibm+1,ixy+1);
294 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,0/*tmin*/,tmax)) || iEntry<0 ) continue;
295 dcsVal = (AliDCSArray*) arr->At(iEntry);
296 int proj = dcsVal->GetInt(0)-1; // beam projection
298 if (proj!=kX && proj!=kY) {
299 AliError(Form("Unknown beam projection %d for %s",proj,buff));
302 // Amp,Pos,Sig - each one have separate entry and time stamp (though come from the single fit)
304 TObjArray *arrPar[3];
305 AliDCSArray *dcsPar[3];
306 AliLHCDipValD* curVal = 0;
309 for (int ipar=0;ipar<3;ipar++) {
310 sprintf(buff,fgkDCSNames[ipar+kRecPrfAmp],ibm+1,ixy+1);
311 if ( !(arrPar[ipar]=GetDCSEntry(dcsMap,buff,entPar[ipar],tmin,tmax)) || entPar[ipar]<0 ) break;
312 dcsPar[ipar] = (AliDCSArray*) arrPar[ipar]->At(entPar[ipar]);
313 if (dcsPar[ipar]->GetTimeStamp()>tstamp) tstamp = dcsPar[ipar]->GetTimeStamp(); // max time among 1st entries
316 if (npars<3) continue; // ignore incomplete data
319 // start recording from max timeStamp:
320 // the entries for different params must correspond to same timestamp
323 // read next timestamp for which all 3 params are present
324 npars = 0; // align the first entries to read to same timestamp
325 for (int ipar=0;ipar<3;ipar++) {
326 while(entPar[ipar]<arrPar[ipar]->GetEntriesFast()) {
327 dcsPar[ipar] = (AliDCSArray*) arrPar[ipar]->At(entPar[ipar]);
328 double df = dcsPar[ipar]->GetTimeStamp() - tstamp;
329 if (TMath::Abs(df)<0.5) { // same time stamp, ok
333 if (df<0) entPar[ipar]++; // check next entry
335 tstamp = dcsPar[ipar]->GetTimeStamp();
336 ipar = -1; // reference tstamp was changed, check all arrays again
342 if (npars<3) break; // no more data
343 for (int ipar=0;ipar<3;ipar++) entPar[ipar]++;
345 if (tstamp>tmax) break;
346 if (tstamp>tPeriodEnd) {
347 curVal = new AliLHCDipValD(3,0.,0); // start new period
348 fBeamPos[ibm][proj].Add(curVal);
349 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
350 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
351 tPeriodEnd += fPeriod;
353 int nsamp = curVal->GetNSamplesUsed()+1;
354 curVal->SetTimeStamp( (tstamp + curVal->GetNSamplesUsed()*curVal->GetTimeStamp())/nsamp);
355 curVal->SetNSamplesUsed(nsamp);
356 for (int ipar=3;ipar--;) (*curVal)[ipar] += dcsPar[ipar]->GetDouble(0);
360 for (int i=fBeamPos[ibm][proj].GetEntriesFast();i--;) ((AliLHCDipValD*)(fBeamPos[ibm][proj])[i])->Average();
365 // ------------------------- extract collimators data
366 for (int icl=0;icl<kNCollimators;icl++) {
367 for (int jaw=0;jaw<kNJaws;jaw++) {
368 sprintf(buff,fgkDCSColNames[icl],fgkDCSColJaws[jaw]);
369 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
370 dcsVal = (AliDCSArray*) arr->At(iEntry);
371 AliLHCDipValD* curVal = new AliLHCDipValD(1,dcsVal->GetTimeStamp(),1);
372 (*curVal)[0] = dcsVal->GetDouble(0)/10; // gap in cm
373 fCollimators[icl][jaw].Add(curVal);
375 // now track the changes above the threshold (100 um?)
376 nEntries = arr->GetEntriesFast();
377 while(++iEntry<nEntries) {
378 dcsVal = (AliDCSArray*) arr->At(iEntry);
379 if (dcsVal->GetTimeStamp() > tmax) break; // out of time
380 double val = dcsVal->GetDouble(0)/10;
381 if ( TMath::Abs(val-curVal->GetValue(0))<kCollTolerance ) continue; // no significant change
382 // need to create a new entry
383 curVal = new AliLHCDipValD(1,dcsVal->GetTimeStamp(),1);
384 (*curVal)[0] = val; // gap in cm
385 fCollimators[icl][jaw].Add(curVal);
393 //___________________________________________________________________
394 TObjArray* AliLHCData::GetDCSEntry(const TMap* dcsMap,const char* key,int &entry,double tmin,double tmax) const
396 // extract array from the DCS map and find the first entry within the time limits
397 TObjArray* arr = (TObjArray*)dcsMap->GetValue(key);
398 if (!arr || !arr->GetEntriesFast()) {
399 AliWarning(Form("No data for %s",key));
402 int ntot = arr->GetEntriesFast();
403 for (entry=0;entry<ntot;entry++) {
404 AliDCSArray* ent = (AliDCSArray*)arr->At(entry);
405 if (ent->GetTimeStamp()>=tmin && ent->GetTimeStamp()<=tmax) break;
410 str += AliLHCDipValD::TimeAsString(tmin);
412 str += AliLHCDipValD::TimeAsString(tmax);
413 AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));
418 //___________________________________________________________________
419 void AliLHCData::Print(const Option_t* opt) const
422 printf("LHC DIP Data | Fill Number#%d (Averaging time: %d sec.)\n",GetFillNumber(),fPeriod);
423 printf("Validity period: %s : %s\n\n",
424 fTMin<1.23e9 ? "N/A": AliLHCDipValD::TimeAsString(fTMin),
425 fTMax>7.00e9 ? "N/A": AliLHCDipValD::TimeAsString(fTMax) );
428 for (int ibm=0;ibm<2;ibm++) {
429 printf("*** Bunch Configuration for Beam%d: %s\n",ibm,(n=fBunchConfig[ibm].GetSize()) ? "":"N/A");
430 if (n) fBunchConfig[ibm].Print(opt);
434 for (int ibm=0;ibm<2;ibm++) {
435 printf("*** Average total intensity for Beam%d (DCBCT): %s\n",ibm,(n=fIntTot[ibm].GetEntriesFast()) ? "":"N/A");
436 for (int i=0;i<n;i++) (fIntTot[ibm])[i]->Print(opt);
440 for (int ibm=0;ibm<2;ibm++) {
441 printf("*** Total intensity for Beam%d (BCTFR): %s\n",ibm,(n=fIntTotBunch[ibm].GetEntriesFast()) ? "":"N/A");
442 for (int i=0;i<n;i++) (fIntTotBunch[ibm])[i]->Print(opt);
445 for (int ibm=0;ibm<2;ibm++) {
446 printf("*** Bunch intensities for Beam%d: %s\n",ibm,(n=fIntBunch[ibm].GetEntriesFast()) ? "":"N/A");
447 for (int i=0;i<n;i++) (fIntBunch[ibm])[i]->Print(opt);
451 for (int ibm=0;ibm<2;ibm++) {
452 printf("*** Total luminosity for probe%c: %s\n",ibm ? 'R':'L',(n=fLuminTot[ibm].GetEntriesFast()) ? "":"N/A");
453 for (int i=0;i<n;i++) (fLuminTot[ibm])[i]->Print(opt);
457 for (int ibm=0;ibm<2;ibm++) {
458 printf("*** Bunch luminosities for probe%c: %s\n",ibm ? 'R':'L',(n=fLuminBunch[ibm].GetEntriesFast()) ? "":"N/A");
459 for (int i=0;i<n;i++) (fLuminBunch[ibm])[i]->Print(opt);
463 for (int ibm=0;ibm<2;ibm++) {
464 printf("*** Crossing angle for probe%c: %s\n",ibm ? 'L':'R',(n=fCrossAngle[ibm].GetEntriesFast()) ? "":"N/A");
465 for (int i=0;i<n;i++) (fCrossAngle[ibm])[i]->Print(opt);
469 for (int ibm=0;ibm<2;ibm++) {
470 for (int ixy=0;ixy<2;ixy++) {
471 printf("*** Gaussian fit for Beam%d %c profile: %s\n",ibm,ixy ? 'Y':'X',(n=fBeamPos[ibm][ixy].GetEntriesFast()) ? "":"N/A");
472 for (int i=0;i<n;i++) (fBeamPos[ibm][ixy])[i]->Print(opt);
476 for (int icl=0;icl<kNCollimators;icl++) {
478 for (int ij=0;ij<kNJaws;ij++) {
479 printf(fgkDCSColNames[icl],fgkDCSColJaws[ij]);
480 printf(": %s\n",(n=fCollimators[icl][ij].GetEntriesFast()) ? "":"N/A");
481 for (int i=0;i<n;i++) (fCollimators[icl][ij])[i]->Print(opt);