]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliLHCData.cxx
classes for limnosity related info from LHC DIP data.
[u/mrichter/AliRoot.git] / STEER / AliLHCData.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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.                  *
14  *                                                                        *
15  **************************************************************************/
16
17
18 #include "AliLHCData.h"
19 #include "TMap.h"
20
21
22 ClassImp(AliLHCData)
23
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",
32   //
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"};
37
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"};
42
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"};
46
47 //___________________________________________________________________
48 AliLHCData::AliLHCData(const TMap* dcsMap, double tmin, double tmax, int avPeriod)
49   : fPeriod(avPeriod),fTMin(tmin),fTMax(tmax)  
50 {
51   FillData(dcsMap,tmin,tmax);
52 }
53
54 //___________________________________________________________________
55 Bool_t AliLHCData::FillData(const TMap* dcsMap, double tmin, double tmax)
56 {
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)
61   char buff[100];
62   TObjArray* arr;
63   AliDCSArray* dcsVal;
64   Double_t tPeriodEnd=0;
65   Int_t dcsSize,nEntries,iEntry;
66   //
67   SetTMin(tmin);
68   SetTMax(tmax);
69   //
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) );
73   //
74   // -------------------------- extract total intensities for beam 1 and 2
75   for (int ibm=0;ibm<2;ibm++) {
76     //
77     sprintf(buff,fgkDCSNames[kRecTotInt],ibm+1);  
78     if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
79     AliLHCDipValD* curVal;
80     tPeriodEnd = 0;
81     //
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;
93       }
94       *curVal += *dcsVal;
95     }
96     for (int i=fIntTot[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntTot[ibm])[i])->Average();
97   }
98   //  
99   // -------------------------- extract total luminosities according L and R detectors
100   for (int ilr=0;ilr<2;ilr++) {
101     //
102     sprintf(buff,fgkDCSNames[kRecTotLum],ilr ? 'L':'R');  
103     if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
104     AliLHCDipValD* curVal = 0;
105     tPeriodEnd = 0;
106     //
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;
118       }
119       *curVal += *dcsVal;
120     }
121     for (int i=fLuminTot[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fLuminTot[ilr])[i])->Average();
122   }
123   //
124   // -------------------------- extract mean crossing angles according to L and R detectors
125   for (int ilr=0;ilr<2;ilr++) {
126     //
127     sprintf(buff,fgkDCSNames[kRecCrossAngle],ilr ? 'L':'R');  
128     if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
129     AliLHCDipValD* curVal=0;
130     tPeriodEnd = 0;
131     //
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;
143       }
144       *curVal += *dcsVal;
145     }
146     for (int i=fCrossAngle[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fCrossAngle[ilr])[i])->Average();
147   }
148   //
149   // -------------------------- extract intensities per bunch for beam 1 and 2
150   for (int ibm=0;ibm<2;ibm++) {
151     //
152     sprintf(buff,fgkDCSNames[kRecBunchInt],ibm+1);  
153     if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
154     AliLHCDipValD* curVal=0;
155     tPeriodEnd = 0;
156     //
157     dcsVal = (AliDCSArray*)arr->At(iEntry);
158     nEntries = dcsVal->GetNEntries();     // count number of actual bunches
159     dcsSize = 0;
160     while(dcsSize<nEntries && dcsVal->GetDouble(dcsSize)>0) dcsSize++;
161     if (!dcsSize) {
162       AliWarning(Form("Beam1 bunch intensities record is present but empty",ibm));
163       continue;
164     }
165     //
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;
177       }
178       *curVal += *dcsVal;
179     }
180     for (int i=fIntBunch[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntBunch[ibm])[i])->Average();
181   }
182   //
183   // -------------------------- extract per bunch luminosities according L and R detectors
184   for (int ilr=0;ilr<2;ilr++) {
185     //
186     sprintf(buff,fgkDCSNames[kRecBunchLum],ilr ? 'L':'R');  
187     if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
188     AliLHCDipValD* curVal=0;
189     tPeriodEnd = 0;
190     //
191     dcsVal = (AliDCSArray*) arr->At(iEntry);
192     nEntries = dcsVal->GetNEntries();     // count number of actual bunches
193     dcsSize = 0;
194     while(dcsSize<nEntries && dcsVal->GetDouble(dcsSize)>0) dcsSize++;
195     if (!dcsSize) {
196       AliWarning(Form("Probe%c bunch luminosities record is present but empty",ilr ? 'R':'L'));
197       continue;
198     }
199     //
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;
211       }
212       *curVal += *dcsVal;
213     }
214     for (int i=fLuminBunch[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fLuminBunch[ilr])[i])->Average();
215   }
216   //
217   // ------------------------- extract bunch configuration for beam 1 and 2
218   for (int ibm=0;ibm<2;ibm++) {
219     //
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
224     dcsSize = 0;
225     while(dcsSize<nEntries && dcsVal->GetInt(dcsSize)) dcsSize++;
226     if (!dcsSize) {
227       AliWarning("Bunches configuration record is present but empty");
228       continue;
229     }
230     fBunchConfig[ibm].SetSize(dcsSize);
231     fBunchConfig[ibm] += *dcsVal;
232   }
233   //
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
242       //
243       if (proj!=kX && proj!=kY) {
244         AliError(Form("Unknown beam projection %d for %s",proj,buff));
245         continue;
246       }
247       // Amp,Pos,Sig - each one have separate entry and time stamp (though come from the single fit)
248       int entPar[3];
249       TObjArray *arrPar[3];
250       AliDCSArray *dcsPar[3];
251       AliLHCDipValD* curVal=0;
252       double tstamp = 0;
253       int npars = 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
259         npars++;
260       }
261       if (npars<3) continue; // ignore incomplete data
262       //
263       tPeriodEnd = 0;
264       // start recording from max timeStamp: 
265       // the entries for different params must correspond to same timestamp
266       while(1) { 
267         //
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
275               npars++; 
276               break;
277             }
278             if (df<0) entPar[ipar]++;  // check next entry
279             else {
280               tstamp = dcsPar[ipar]->GetTimeStamp();
281               ipar = -1; // reference tstamp was changed, check all arrays again
282               npars = 0;
283               break;
284             }
285           }
286         } // 
287         if (npars<3) break; // no more data
288         for (int ipar=0;ipar<3;ipar++) entPar[ipar]++;
289         //
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;
297         }
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);
302         //
303       }
304       //
305       for (int i=fBeamPos[ibm][proj].GetEntriesFast();i--;) ((AliLHCDipValD*)(fBeamPos[ibm][proj])[i])->Average();
306       //
307     } // projection
308   } // beam
309   //
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);
319       //
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);     
331       }
332     } // jaws
333   } // collimators
334   //
335   return kTRUE;
336 }
337
338 //___________________________________________________________________
339 TObjArray* AliLHCData::GetDCSEntry(const TMap* dcsMap,const char* key,int &entry,double tmin,double tmax) const
340 {
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)); 
345     return 0;
346   }
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;
351   }
352   if (entry==ntot) {
353     entry = -1;
354     TString str;
355     str += AliLHCDipValD::TimeAsString(tmin);
356     str += " : ";
357     str += AliLHCDipValD::TimeAsString(tmax);
358     AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));
359   }
360   return arr;
361 }
362
363 //___________________________________________________________________
364 void AliLHCData::Print(const Option_t* opt) const
365 {
366   // print everything
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) );
371   //
372   int n=0;
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);
376   }
377   printf("\n");
378   //
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);
382   }
383   printf("\n");
384   //
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);
388   }
389   printf("\n");
390   //
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);
394   }
395   printf("\n");
396   //
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);
400   }
401   printf("\n");
402   //
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);
406   }
407   printf("\n");
408   //
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);
413     }
414   }
415   //
416   for (int icl=0;icl<kNCollimators;icl++) {
417     printf("\n");
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);
422     }
423   }
424   //
425 }