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 "dip/acc/LHC/Beam/Intensity/Beam%d.totalIntensity",
26 "dip/acc/LHC/Beam/IntensityPerBunchBeam%d.averageBunchIntensity",
27 "dip/acc/LHC/Beam/LuminosityAverage/BRANB.4%c2.meanLuminosity",
28 "dip/acc/LHC/Beam/LuminosityPerBunch/BRANB_4%c2.bunchByBunchLuminosity",
29 "dip/acc/LHC/Beam/LuminosityAverage/BRANB.4%c2.meanCrossingAngle",
30 "dip/acc/LHC/RunControl/CirculatingBunchConfig/Beam%d.value",
31 "dip/acc/LHC/RunControl/FillNumber.payload",
33 "dip/acc/LHC/Beam/Size/Beam%d.planeSet%d",
34 "dip/acc/LHC/Beam/Size/Beam%d.amplitudeSet%d",
35 "dip/acc/LHC/Beam/Size/Beam%d.positionSet%d",
36 "dip/acc/LHC/Beam/Size/Beam%d.sigmaSet%d"};
38 const Char_t* AliLHCData::fgkDCSColNames[] = {
39 "dip/acc/LHC/Machine/CollimatorPositions/TCTVB.4L2.%s",
40 "dip/acc/LHC/Machine/CollimatorPositions/TCTVB.4R2.%s",
41 "dip/acc/LHC/Machine/CollimatorPositions/TCLIA.4R2.%s"};
43 const Char_t* AliLHCData::fgkDCSColJaws[] = {
44 "lvdt_gap_downstream","lvdt_gap_upstream","lvdt_left_downstream",
45 "lvdt_left_upstream","lvdt_right_downstream","lvdt_right_upstream"};
47 //___________________________________________________________________
48 AliLHCData::AliLHCData(const TMap* dcsMap, double tmin, double tmax, int avPeriod)
49 : fPeriod(avPeriod),fTMin(tmin),fTMax(tmax)
51 FillData(dcsMap,tmin,tmax);
54 //___________________________________________________________________
55 Bool_t AliLHCData::FillData(const TMap* dcsMap, double tmin, double tmax)
57 // process DCS map and fill all fields.
58 // Accept only entries with timestamp between tmin and tmax
59 const double ktReal = 1200000000.;
60 const double kCollTolerance = 100e-4; // tolerance on collimator move (cm)
64 Double_t tPeriodEnd=0;
65 Int_t dcsSize,nEntries,iEntry;
70 // -------------------------- extract Fill Number
71 arr = GetDCSEntry(dcsMap,fgkDCSNames[kRecFillNum],iEntry,tmin,tmax);
72 if (arr && iEntry>=0) SetFillNumber( ((AliDCSArray*)arr->At(iEntry))->GetInt(0) );
74 // -------------------------- extract total intensities for beam 1 and 2
75 for (int ibm=0;ibm<2;ibm++) {
77 sprintf(buff,fgkDCSNames[kRecTotInt],ibm+1);
78 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
79 AliLHCDipValD* curVal;
82 nEntries = arr->GetEntriesFast();
83 while (iEntry<nEntries) {
84 dcsVal = (AliDCSArray*) arr->At(iEntry++);
85 double tstamp = dcsVal->GetTimeStamp();
86 if (tstamp>tmax) break;
87 if (tstamp>tPeriodEnd) {
88 curVal = new AliLHCDipValD(1,0.,0); // start new period
89 fIntTot[ibm].Add(curVal);
90 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
91 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
92 tPeriodEnd += fPeriod;
96 for (int i=fIntTot[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntTot[ibm])[i])->Average();
99 // -------------------------- extract total luminosities according L and R detectors
100 for (int ilr=0;ilr<2;ilr++) {
102 sprintf(buff,fgkDCSNames[kRecTotLum],ilr ? 'L':'R');
103 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
104 AliLHCDipValD* curVal = 0;
107 nEntries = arr->GetEntriesFast();
108 while (iEntry<nEntries) {
109 dcsVal = (AliDCSArray*) arr->At(iEntry++);
110 double tstamp = dcsVal->GetTimeStamp();
111 if (tstamp>tmax) break;
112 if (tstamp>tPeriodEnd) {
113 curVal = new AliLHCDipValD(1,0.,0); // start new period
114 fLuminTot[ilr].Add(curVal);
115 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
116 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
117 tPeriodEnd += fPeriod;
121 for (int i=fLuminTot[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fLuminTot[ilr])[i])->Average();
124 // -------------------------- extract mean crossing angles according to L and R detectors
125 for (int ilr=0;ilr<2;ilr++) {
127 sprintf(buff,fgkDCSNames[kRecCrossAngle],ilr ? 'L':'R');
128 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
129 AliLHCDipValD* curVal=0;
132 nEntries = arr->GetEntriesFast();
133 while (iEntry<nEntries) {
134 dcsVal = (AliDCSArray*) arr->At(iEntry++);
135 double tstamp = dcsVal->GetTimeStamp();
136 if (tstamp>tmax) break;
137 if (tstamp>tPeriodEnd) {
138 curVal = new AliLHCDipValD(1,0.,0); // start new period
139 fCrossAngle[ilr].Add(curVal);
140 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
141 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
142 tPeriodEnd += fPeriod;
146 for (int i=fCrossAngle[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fCrossAngle[ilr])[i])->Average();
149 // -------------------------- extract intensities per bunch for beam 1 and 2
150 for (int ibm=0;ibm<2;ibm++) {
152 sprintf(buff,fgkDCSNames[kRecBunchInt],ibm+1);
153 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
154 AliLHCDipValD* curVal=0;
157 dcsVal = (AliDCSArray*)arr->At(iEntry);
158 nEntries = dcsVal->GetNEntries(); // count number of actual bunches
160 while(dcsSize<nEntries && dcsVal->GetDouble(dcsSize)>0) dcsSize++;
162 AliWarning(Form("Beam1 bunch intensities record is present but empty",ibm));
166 nEntries = arr->GetEntriesFast();
167 while (iEntry<nEntries) {
168 dcsVal = (AliDCSArray*) arr->At(iEntry++);
169 double tstamp = dcsVal->GetTimeStamp();
170 if (tstamp>tmax) break;
171 if (tstamp>tPeriodEnd) {
172 curVal = new AliLHCDipValD(dcsSize,0.,0); // start new period
173 fIntBunch[ibm].Add(curVal);
174 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
175 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
176 tPeriodEnd += fPeriod;
180 for (int i=fIntBunch[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntBunch[ibm])[i])->Average();
183 // -------------------------- extract per bunch luminosities according L and R detectors
184 for (int ilr=0;ilr<2;ilr++) {
186 sprintf(buff,fgkDCSNames[kRecBunchLum],ilr ? 'L':'R');
187 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
188 AliLHCDipValD* curVal=0;
191 dcsVal = (AliDCSArray*) arr->At(iEntry);
192 nEntries = dcsVal->GetNEntries(); // count number of actual bunches
194 while(dcsSize<nEntries && dcsVal->GetDouble(dcsSize)>0) dcsSize++;
196 AliWarning(Form("Probe%c bunch luminosities record is present but empty",ilr ? 'R':'L'));
200 nEntries = arr->GetEntriesFast();
201 while (iEntry<nEntries) {
202 dcsVal = (AliDCSArray*) arr->At(iEntry++);
203 double tstamp = dcsVal->GetTimeStamp();
204 if (tstamp>tmax) break;
205 if (tstamp>tPeriodEnd) {
206 curVal = new AliLHCDipValD(dcsSize,0.,0); // start new period
207 fLuminBunch[ilr].Add(curVal);
208 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
209 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
210 tPeriodEnd += fPeriod;
214 for (int i=fLuminBunch[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fLuminBunch[ilr])[i])->Average();
217 // ------------------------- extract bunch configuration for beam 1 and 2
218 for (int ibm=0;ibm<2;ibm++) {
220 sprintf(buff,fgkDCSNames[kRecBunchConf],ibm+1);
221 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
222 dcsVal = (AliDCSArray*) arr->At(iEntry);
223 nEntries = dcsVal->GetNEntries(); // count number of actual bunches
225 while(dcsSize<nEntries && dcsVal->GetInt(dcsSize)) dcsSize++;
227 AliWarning("Bunches configuration record is present but empty");
230 fBunchConfig[ibm].SetSize(dcsSize);
231 fBunchConfig[ibm] += *dcsVal;
234 // ------------------------- extract gaussian fit params for beam 1 and 2 profiles
235 for (int ibm=0;ibm<2;ibm++) {
236 for (int ixy=0;ixy<2;ixy++) {
237 // determine which projection corresponds actually to given ixy
238 sprintf(buff,fgkDCSNames[kRecPrfPrID],ibm+1,ixy+1);
239 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,0/*tmin*/,tmax)) || iEntry<0 ) continue;
240 dcsVal = (AliDCSArray*) arr->At(iEntry);
241 int proj = dcsVal->GetInt(0)-1; // beam projection
243 if (proj!=kX && proj!=kY) {
244 AliError(Form("Unknown beam projection %d for %s",proj,buff));
247 // Amp,Pos,Sig - each one have separate entry and time stamp (though come from the single fit)
249 TObjArray *arrPar[3];
250 AliDCSArray *dcsPar[3];
251 AliLHCDipValD* curVal=0;
254 for (int ipar=0;ipar<3;ipar++) {
255 sprintf(buff,fgkDCSNames[ipar+kRecPrfAmp],ibm+1,ixy+1);
256 if ( !(arrPar[ipar]=GetDCSEntry(dcsMap,buff,entPar[ipar],tmin,tmax)) || entPar[ipar]<0 ) break;
257 dcsPar[ipar] = (AliDCSArray*) arrPar[ipar]->At(entPar[ipar]);
258 if (dcsPar[ipar]->GetTimeStamp()>tstamp) tstamp = dcsPar[ipar]->GetTimeStamp(); // max time among 1st entries
261 if (npars<3) continue; // ignore incomplete data
264 // start recording from max timeStamp:
265 // the entries for different params must correspond to same timestamp
268 // read next timestamp for which all 3 params are present
269 npars = 0; // align the first entries to read to same timestamp
270 for (int ipar=0;ipar<3;ipar++) {
271 while(entPar[ipar]<arrPar[ipar]->GetEntriesFast()) {
272 dcsPar[ipar] = (AliDCSArray*) arrPar[ipar]->At(entPar[ipar]);
273 double df = dcsPar[ipar]->GetTimeStamp() - tstamp;
274 if (TMath::Abs(df)<0.5) { // same time stamp, ok
278 if (df<0) entPar[ipar]++; // check next entry
280 tstamp = dcsPar[ipar]->GetTimeStamp();
281 ipar = -1; // reference tstamp was changed, check all arrays again
287 if (npars<3) break; // no more data
288 for (int ipar=0;ipar<3;ipar++) entPar[ipar]++;
290 if (tstamp>tmax) break;
291 if (tstamp>tPeriodEnd) {
292 curVal = new AliLHCDipValD(3,0.,0); // start new period
293 fBeamPos[ibm][proj].Add(curVal);
294 // if tmin is provided, count periods from it, otherwise from the 1st timestamp
295 if (tPeriodEnd<1) tPeriodEnd = ((tmin>ktReal) ? tmin : tstamp);
296 tPeriodEnd += fPeriod;
298 int nsamp = curVal->GetNSamplesUsed()+1;
299 curVal->SetTimeStamp( (tstamp + curVal->GetNSamplesUsed()*curVal->GetTimeStamp())/nsamp);
300 curVal->SetNSamplesUsed(nsamp);
301 for (int ipar=3;ipar--;) (*curVal)[ipar] += dcsPar[ipar]->GetDouble(0);
305 for (int i=fBeamPos[ibm][proj].GetEntriesFast();i--;) ((AliLHCDipValD*)(fBeamPos[ibm][proj])[i])->Average();
310 // ------------------------- extract collimators data
311 for (int icl=0;icl<kNCollimators;icl++) {
312 for (int jaw=0;jaw<kNJaws;jaw++) {
313 sprintf(buff,fgkDCSColNames[icl],fgkDCSColJaws[jaw]);
314 if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
315 dcsVal = (AliDCSArray*) arr->At(iEntry);
316 AliLHCDipValD* curVal = new AliLHCDipValD(1,dcsVal->GetTimeStamp(),1);
317 (*curVal)[0] = dcsVal->GetDouble(0)/10; // gap in cm
318 fCollimators[icl][jaw].Add(curVal);
320 // now track the changes above the threshold (100 um?)
321 nEntries = arr->GetEntriesFast();
322 while(++iEntry<nEntries) {
323 dcsVal = (AliDCSArray*) arr->At(iEntry);
324 if (dcsVal->GetTimeStamp() > tmax) break; // out of time
325 double val = dcsVal->GetDouble(0)/10;
326 if ( TMath::Abs(val-curVal->GetValue(0))<kCollTolerance ) continue; // no significant change
327 // need to create a new entry
328 curVal = new AliLHCDipValD(1,dcsVal->GetTimeStamp(),1);
329 (*curVal)[0] = val; // gap in cm
330 fCollimators[icl][jaw].Add(curVal);
338 //___________________________________________________________________
339 TObjArray* AliLHCData::GetDCSEntry(const TMap* dcsMap,const char* key,int &entry,double tmin,double tmax) const
341 // extract array from the DCS map and find the first entry within the time limits
342 TObjArray* arr = (TObjArray*)dcsMap->GetValue(key);
343 if (!arr || !arr->GetEntriesFast()) {
344 AliWarning(Form("No data for %s",key));
347 int ntot = arr->GetEntriesFast();
348 for (entry=0;entry<ntot;entry++) {
349 AliDCSArray* ent = (AliDCSArray*)arr->At(entry);
350 if (ent->GetTimeStamp()>=tmin && ent->GetTimeStamp()<=tmax) break;
355 str += AliLHCDipValD::TimeAsString(tmin);
357 str += AliLHCDipValD::TimeAsString(tmax);
358 AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));
363 //___________________________________________________________________
364 void AliLHCData::Print(const Option_t* opt) const
367 printf("LHC DIP Data | Fill Number#%d (Averaging time: %d sec.)",GetFillNumber(),fPeriod);
368 printf("Validity period: %s : %s",
369 fTMin<1.23e9 ? "N/A": AliLHCDipValD::TimeAsString(fTMin),
370 fTMax>7.00e9 ? "N/A": AliLHCDipValD::TimeAsString(fTMax) );
373 for (int ibm=0;ibm<2;ibm++) {
374 printf("*** Bunch Configuration for Beam%d: %s\n",ibm,(n=fBunchConfig[ibm].GetSize()) ? "":"N/A");
375 if (n) fBunchConfig[ibm].Print(opt);
379 for (int ibm=0;ibm<2;ibm++) {
380 printf("*** Total intensity for Beam%d: %s\n",ibm,(n=fIntTot[ibm].GetEntriesFast()) ? "":"N/A");
381 for (int i=0;i<n;i++) (fIntTot[ibm])[i]->Print(opt);
385 for (int ibm=0;ibm<2;ibm++) {
386 printf("*** Bunch intensities for Beam%d: %s\n",ibm,(n=fIntBunch[ibm].GetEntriesFast()) ? "":"N/A");
387 for (int i=0;i<n;i++) (fIntBunch[ibm])[i]->Print(opt);
391 for (int ibm=0;ibm<2;ibm++) {
392 printf("*** Total luminosity for probe%c: %s\n",ibm ? 'R':'L',(n=fLuminTot[ibm].GetEntriesFast()) ? "":"N/A");
393 for (int i=0;i<n;i++) (fLuminTot[ibm])[i]->Print(opt);
397 for (int ibm=0;ibm<2;ibm++) {
398 printf("*** Bunch luminosities for probe%c: %s\n",ibm ? 'R':'L',(n=fLuminBunch[ibm].GetEntriesFast()) ? "":"N/A");
399 for (int i=0;i<n;i++) (fLuminBunch[ibm])[i]->Print(opt);
403 for (int ibm=0;ibm<2;ibm++) {
404 printf("*** Crossing angle for probe%c: %s\n",ibm ? 'L':'R',(n=fCrossAngle[ibm].GetEntriesFast()) ? "":"N/A");
405 for (int i=0;i<n;i++) (fCrossAngle[ibm])[i]->Print(opt);
409 for (int ibm=0;ibm<2;ibm++) {
410 for (int ixy=0;ixy<2;ixy++) {
411 printf("*** Gaussian fit for Beam%d %c profile: %s\n",ibm,ixy ? 'Y':'X',(n=fBeamPos[ibm][ixy].GetEntriesFast()) ? "":"N/A");
412 for (int i=0;i<n;i++) (fBeamPos[ibm][ixy])[i]->Print(opt);
416 for (int icl=0;icl<kNCollimators;icl++) {
418 for (int ij=0;ij<kNJaws;ij++) {
419 printf(fgkDCSColNames[icl],fgkDCSColJaws[ij]);
420 printf(": %s\n",(n=fCollimators[icl][ij].GetEntriesFast()) ? "":"N/A");
421 for (int i=0;i<n;i++) (fCollimators[icl][ij])[i]->Print(opt);