]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliLHCData.cxx
Getter and Setter for ESDpid
[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   "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",
33   //
34   "lhcMon_LHCBeamSizeBeam%d.planeSet%d",
35   "lhcMon_LHCBeamSizeBeam%d.amplitudeSet%d",
36   "lhcMon_LHCBeamSizeBeam%d.positionSet%d",
37   "lhcMon_LHCBeamSizeBeam%d.sigmaSet%d"
38 };
39
40 const Char_t* AliLHCData::fgkDCSColNames[] = {
41   "lhcMon_LHCCollimatorPos_TCTVB_4L2.%s",
42   "lhcMon_LHCCollimatorPos_TCTVB_4R2.%s",  
43   "lhcMon_LHCCollimatorPos_TCLIA_4R2.%s"
44 };
45
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"};
49
50 //___________________________________________________________________
51 AliLHCData::AliLHCData(const TMap* dcsMap, double tmin, double tmax, int avPeriod)
52   : fPeriod(avPeriod),fTMin(tmin),fTMax(tmax)  
53 {
54   FillData(dcsMap,tmin,tmax);
55 }
56
57 //___________________________________________________________________
58 Bool_t AliLHCData::FillData(const TMap* dcsMap, double tmin, double tmax)
59 {
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)
64   char buff[100];
65   TObjArray* arr;
66   AliDCSArray* dcsVal;
67   Double_t tPeriodEnd=0;
68   Int_t dcsSize,nEntries,iEntry;
69   //
70   SetTMin(tmin);
71   SetTMax(tmax);
72   //
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) );
76   //
77   // -------------------------- extract total intensities for beam 1 and 2 (DC BCT: slow average)
78   for (int ibm=0;ibm<2;ibm++) {
79     //
80     sprintf(buff,fgkDCSNames[kRecTotInt],ibm+1);  
81     if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
82     AliLHCDipValD* curVal = 0;
83     tPeriodEnd = 0;
84     //
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;
96       }
97       *curVal += *dcsVal;
98     }
99     for (int i=fIntTot[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntTot[ibm])[i])->Average();
100   }
101   //
102   // -------------------------- extract total intensities for beam 1 and 2 (BCTFR: fast average)
103   for (int ibm=0;ibm<2;ibm++) {
104     //
105     sprintf(buff,fgkDCSNames[kRecTotIntBunch],ibm+1);  
106     if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
107     AliLHCDipValD* curVal = 0;
108     tPeriodEnd = 0;
109     //
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;
121       }
122       *curVal += *dcsVal;
123     }
124     for (int i=fIntTotBunch[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntTotBunch[ibm])[i])->Average();
125   }
126   //  
127   // -------------------------- extract total luminosities according L and R detectors
128   for (int ilr=0;ilr<2;ilr++) {
129     //
130     sprintf(buff,fgkDCSNames[kRecTotLum],ilr ? 'L':'R');  
131     if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
132     AliLHCDipValD* curVal = 0;
133     tPeriodEnd = 0;
134     //
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;
146       }
147       *curVal += *dcsVal;
148     }
149     for (int i=fLuminTot[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fLuminTot[ilr])[i])->Average();
150   }
151   //
152   // -------------------------- extract mean crossing angles according to L and R detectors
153   for (int ilr=0;ilr<2;ilr++) {
154     //
155     sprintf(buff,fgkDCSNames[kRecCrossAngle],ilr ? 'L':'R');  
156     if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
157     AliLHCDipValD* curVal = 0;
158     tPeriodEnd = 0;
159     //
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;
171       }
172       *curVal += *dcsVal;
173     }
174     for (int i=fCrossAngle[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fCrossAngle[ilr])[i])->Average();
175   }
176   //
177   //
178   // ------------------------- extract bunch configuration for beam 1 and 2
179   int nbunch[2];
180   for (int ibm=0;ibm<2;ibm++) {
181     //
182     nbunch[ibm] = -1;
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
187     nbunch[ibm] = 0;
188     while(nbunch[ibm]<nEntries && dcsVal->GetInt(nbunch[ibm])) nbunch[ibm]++;
189     if (!nbunch[ibm]) {
190       AliWarning(Form("Beam%d bunches configuration record is present but empty",ibm+1));
191       continue;
192     }
193     fBunchConfig[ibm].SetSize(nbunch[ibm]);
194     fBunchConfig[ibm] += *dcsVal;
195   }
196   // -------------------------- extract intensities per bunch for beam 1 and 2
197   for (int ibm=0;ibm<2;ibm++) {
198     //
199     sprintf(buff,fgkDCSNames[kRecBunchInt],ibm+1);  
200     if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
201     AliLHCDipValD* curVal = 0;
202     tPeriodEnd = 0;
203     //
204     dcsVal = (AliDCSArray*)arr->At(iEntry);
205     nEntries = dcsVal->GetNEntries();     // count number of actual bunches
206     dcsSize = 0;
207     while(dcsSize<nEntries && dcsVal->GetDouble(dcsSize)>0) dcsSize++;
208     if (!dcsSize) {
209       AliWarning(Form("Beam%d bunch intensities record is present but empty",ibm+1));
210       continue;
211     }
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];
217       }
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));
221         continue;
222       }
223     }
224     //
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;
236       }
237       *curVal += *dcsVal;
238     }
239     for (int i=fIntBunch[ibm].GetEntries();i--;) ((AliLHCDipValD*)(fIntBunch[ibm])[i])->Average();
240   }
241   //
242   // -------------------------- extract per bunch luminosities according L and R detectors
243   for (int ilr=0;ilr<2;ilr++) {
244     //
245     sprintf(buff,fgkDCSNames[kRecBunchLum],ilr ? 'L':'R');  
246     if ( !(arr=GetDCSEntry(dcsMap,buff,iEntry,tmin,tmax)) || iEntry<0 ) continue;
247     AliLHCDipValD* curVal = 0;
248     tPeriodEnd = 0;
249     //
250     dcsVal = (AliDCSArray*) arr->At(iEntry);
251     nEntries = dcsVal->GetNEntries();     // count number of actual bunches
252     dcsSize = 0;
253     while(dcsSize<nEntries && dcsVal->GetDouble(dcsSize)>0) dcsSize++;
254     if (!dcsSize) {
255       AliWarning(Form("Probe%c bunch luminosities record is present but empty",ilr ? 'R':'L'));
256       continue;
257     }
258     //
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];
264       }
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));
268         continue;
269       }
270     }
271     //
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;
283       }
284       *curVal += *dcsVal;
285     }
286     for (int i=fLuminBunch[ilr].GetEntries();i--;) ((AliLHCDipValD*)(fLuminBunch[ilr])[i])->Average();
287   }
288   //
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
297       //
298       if (proj!=kX && proj!=kY) {
299         AliError(Form("Unknown beam projection %d for %s",proj,buff));
300         continue;
301       }
302       // Amp,Pos,Sig - each one have separate entry and time stamp (though come from the single fit)
303       int entPar[3];
304       TObjArray *arrPar[3];
305       AliDCSArray *dcsPar[3];
306       AliLHCDipValD* curVal = 0;
307       double tstamp = 0;
308       int npars = 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
314         npars++;
315       }
316       if (npars<3) continue; // ignore incomplete data
317       //
318       tPeriodEnd = 0;
319       // start recording from max timeStamp: 
320       // the entries for different params must correspond to same timestamp
321       while(1) { 
322         //
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
330               npars++; 
331               break;
332             }
333             if (df<0) entPar[ipar]++;  // check next entry
334             else {
335               tstamp = dcsPar[ipar]->GetTimeStamp();
336               ipar = -1; // reference tstamp was changed, check all arrays again
337               npars = 0;
338               break;
339             }
340           }
341         } // 
342         if (npars<3) break; // no more data
343         for (int ipar=0;ipar<3;ipar++) entPar[ipar]++;
344         //
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;
352         }
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);
357         //
358       }
359       //
360       for (int i=fBeamPos[ibm][proj].GetEntriesFast();i--;) ((AliLHCDipValD*)(fBeamPos[ibm][proj])[i])->Average();
361       //
362     } // projection
363   } // beam
364   //
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);
374       //
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);     
386       }
387     } // jaws
388   } // collimators
389   //
390   return kTRUE;
391 }
392
393 //___________________________________________________________________
394 TObjArray* AliLHCData::GetDCSEntry(const TMap* dcsMap,const char* key,int &entry,double tmin,double tmax) const
395 {
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)); 
400     return 0;
401   }
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;
406   }
407   if (entry==ntot) {
408     entry = -1;
409     TString str;
410     str += AliLHCDipValD::TimeAsString(tmin);
411     str += " : ";
412     str += AliLHCDipValD::TimeAsString(tmax);
413     AliWarning(Form("All entries for %s are outside the requested range:\n%s",key,str.Data()));
414   }
415   return arr;
416 }
417
418 //___________________________________________________________________
419 void AliLHCData::Print(const Option_t* opt) const
420 {
421   // print everything
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) );
426   //
427   int n=0;
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);
431   }
432   printf("\n");
433   //
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);
437   }
438   printf("\n");
439   //
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);
443   }
444   printf("\n");  //
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);
448   }
449   printf("\n");
450   //
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);
454   }
455   printf("\n");
456   //
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);
460   }
461   printf("\n");
462   //
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);
466   }
467   printf("\n");
468   //
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);
473     }
474   }
475   //
476   for (int icl=0;icl<kNCollimators;icl++) {
477     printf("\n");
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);
482     }
483   }
484   //
485 }