]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONRecoParam.cxx
Update of parameters (Philippe Pillot)
[u/mrichter/AliRoot.git] / MUON / AliMUONRecoParam.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-2007, 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 // $Id$
17
18 //-----------------------------------------------------------------------------
19 /// \class AliMUONRecoParam
20 ///
21 /// Class with MUON reconstruction parameters
22 ///
23 ///  \author Philippe Pillot
24 //-----------------------------------------------------------------------------
25
26
27
28 #include "AliMUONRecoParam.h"
29 #include "AliMUONPadStatusMaker.h"
30
31 #include "AliRecoParam.h"
32 #include "AliLog.h"
33
34 #include <Riostream.h>
35
36 ClassImp(AliMUONRecoParam)
37
38
39 //_____________________________________________________________________________
40 AliMUONRecoParam::AliMUONRecoParam()
41 : AliDetectorRecoParam(),
42   fClusteringMode("MLEM"),
43   fTrackingMode("KALMAN"),
44   fMinBendingMomentum(0.),
45   fMaxBendingMomentum(0.),
46   fMaxNonBendingSlope(0.),
47   fMaxBendingSlope(0.),
48   fNonBendingVertexDispersion(0.),
49   fBendingVertexDispersion(0.),
50   fMaxNonBendingDistanceToTrack(0.),
51   fMaxBendingDistanceToTrack(0.),
52   fSigmaCutForTracking(0.),
53   fSigmaCutForImprovement(0.),
54   fSigmaCutForTrigger(0.),
55   fStripCutForTrigger(0.),
56   fMaxStripAreaForTrigger(0.),
57   fMaxNormChi2MatchTrigger(0.),
58   fPercentOfFullClusterInESD(10.),
59   fCombinedClusterTrackReco(kFALSE),
60   fTrackAllTracks(kFALSE),
61   fRecoverTracks(kFALSE),
62   fMakeTrackCandidatesFast(kFALSE),
63   fMakeMoreTrackCandidates(kFALSE),
64   fComplementTracks(kFALSE),
65   fImproveTracks(kFALSE),
66   fUseSmoother(kFALSE),
67   fSaveFullClusterInESD(kTRUE),
68   fCalibrationMode("NOGAIN"),
69   fBypassSt45(0),
70   fPadGoodnessMask(0),
71   fChargeSigmaCut(4.0),
72   fRemoveConnectedTracksInSt12(kFALSE),
73   fMaxTriggerTracks(0),
74   fMaxTrackCandidates(0),
75   fSelectTrackOnSlope(kFALSE)
76 {
77   /// Constructor
78   
79   SetNameTitle("Dummy","Dummy");
80   for (Int_t iCh = 0; iCh < 10; iCh++) {
81     fUseChamber[iCh] = kTRUE;
82     fDefaultNonBendingReso[iCh] = 0.;
83     fDefaultBendingReso[iCh] = 0.;
84   }
85   for (Int_t iSt = 0; iSt < 5; iSt++) fRequestStation[iSt] = kTRUE;
86   SetDefaultLimits();
87 }
88
89 //_____________________________________________________________________________
90 AliMUONRecoParam::~AliMUONRecoParam() 
91 {
92   /// Destructor
93 }
94
95 //_____________________________________________________________________________
96 void
97 AliMUONRecoParam::BypassSt45(Bool_t st4, Bool_t st5)
98 {
99         /// Set the bypass status
100         
101         if ( st4 && st5 ) fBypassSt45 = 45;
102         else if ( st4 ) fBypassSt45 = 4;
103         else if ( st5 ) fBypassSt45 = 5;
104         else fBypassSt45 = 0;
105 }
106
107 //_____________________________________________________________________________
108 Option_t*
109 AliMUONRecoParam::GetCalibrationMode() const
110 {
111   /// Return the calibration mode. Can be : 
112   /// NOGAIN : only do pedestal subtraction
113   /// GAIN : do pedestal subtraction, and apply gain correction, but with a
114   ///        single capacitance value for all channels
115   /// INJECTIONGAIN : as GAIN, but with gain values taken as EMELEC factory values
116   /// GAINCONSTANTCAPA : as GAIN, but with a channel-dependent capacitance value
117   
118   return fCalibrationMode.Data();
119 }
120
121 //_____________________________________________________________________________
122 AliMUONRecoParam *AliMUONRecoParam::GetLowFluxParam() 
123 {
124   /// Return default reconstruction parameters for low flux environment
125   
126   AliMUONRecoParam *param = new AliMUONRecoParam();
127   param->SetLowFluxParam();
128   
129   return param;
130 }
131
132 //_____________________________________________________________________________
133 AliMUONRecoParam *AliMUONRecoParam::GetHighFluxParam() 
134 {
135   /// Return default reconstruction parameters for high flux environment
136   
137   AliMUONRecoParam *param = new AliMUONRecoParam();
138   param->SetHighFluxParam();
139  
140   return param;
141 }
142
143 //_____________________________________________________________________________
144 AliMUONRecoParam *AliMUONRecoParam::GetCosmicParam() 
145 {
146   /// Return default reconstruction parameters for high flux environment
147   
148   AliMUONRecoParam *param = new AliMUONRecoParam();
149   param->SetCosmicParam();
150   
151   return param;
152 }
153
154 //_____________________________________________________________________________
155 AliMUONRecoParam *AliMUONRecoParam::GetCalibrationParam() 
156 {
157   /// Return default (dummy) reconstruction parameters for calibration environment
158   
159   AliMUONRecoParam *param = new AliMUONRecoParam();
160   param->SetCalibrationParam();
161   
162   return param;
163 }
164
165
166 //_____________________________________________________________________________
167 void AliMUONRecoParam::SetLowFluxParam() 
168 {
169   /// Set reconstruction parameters for low flux environment
170   
171   SetNameTitle("Low Flux","Low Flux");
172   SetEventSpecie(AliRecoParam::kLowMult);
173   fMinBendingMomentum = 0.8;
174   fMaxBendingMomentum = 1.e10;
175   fMaxNonBendingSlope = 0.3;
176   fMaxBendingSlope = 0.4;
177   fSelectTrackOnSlope = kFALSE;
178   fNonBendingVertexDispersion = 70.;
179   fBendingVertexDispersion = 70.;
180   fMaxNonBendingDistanceToTrack = 1.;
181   fMaxBendingDistanceToTrack = 1.;
182   fSigmaCutForTracking = 6.;
183   fSigmaCutForImprovement = 5.;
184   fSigmaCutForTrigger = 8.;
185   fStripCutForTrigger = 1.;
186   fMaxStripAreaForTrigger = 3.;
187   fMaxNormChi2MatchTrigger = 16.;
188   fCombinedClusterTrackReco = kFALSE;
189   fTrackAllTracks = kTRUE;
190   fRecoverTracks = kTRUE;
191   fMakeTrackCandidatesFast = kFALSE;
192   fMakeMoreTrackCandidates = kFALSE;
193   fComplementTracks = kTRUE;
194   fImproveTracks = kTRUE;
195   fRemoveConnectedTracksInSt12 = kTRUE;
196   fUseSmoother = kTRUE;
197   for (Int_t iCh = 0; iCh < 10; iCh++) {
198     fUseChamber[iCh] = kTRUE;
199     fDefaultNonBendingReso[iCh] = 0.144;
200     fDefaultBendingReso[iCh] = 0.01;
201   }
202   for (Int_t iSt = 0; iSt < 5; iSt++) fRequestStation[iSt] = kTRUE;
203   fBypassSt45 = 0;
204   fMaxTriggerTracks = 100;
205   fMaxTrackCandidates = 10000;
206   
207 }
208
209 //_____________________________________________________________________________
210 void AliMUONRecoParam::SetHighFluxParam() 
211 {
212   /// Set reconstruction parameters for high flux environment
213   
214   SetNameTitle("High Flux","High Flux");
215   SetEventSpecie(AliRecoParam::kHighMult);
216   fMinBendingMomentum = 0.8;
217   fMaxBendingMomentum = 1.e10;
218   fMaxNonBendingSlope = 0.3;
219   fMaxBendingSlope = 0.4;
220   fSelectTrackOnSlope = kFALSE;
221   fNonBendingVertexDispersion = 70.;
222   fBendingVertexDispersion = 70.;
223   fMaxNonBendingDistanceToTrack = 1.;
224   fMaxBendingDistanceToTrack = 1.;
225   fSigmaCutForTracking = 6.;
226   fSigmaCutForImprovement = 5.;
227   fSigmaCutForTrigger = 8.;
228   fStripCutForTrigger = 1.;
229   fMaxStripAreaForTrigger = 3.;
230   fMaxNormChi2MatchTrigger = 16.;
231   fCombinedClusterTrackReco = kFALSE;
232   fTrackAllTracks = kTRUE;
233   fRecoverTracks = kTRUE;
234   fMakeTrackCandidatesFast = kFALSE;
235   fMakeMoreTrackCandidates = kFALSE;
236   fComplementTracks = kTRUE;
237   fImproveTracks = kTRUE;
238   fRemoveConnectedTracksInSt12 = kFALSE;
239   fUseSmoother = kTRUE;
240   for (Int_t iCh = 0; iCh < 10; iCh++) {
241     fUseChamber[iCh] = kTRUE;
242     fDefaultNonBendingReso[iCh] = 0.144;
243     fDefaultBendingReso[iCh] = 0.01;
244   }
245   for (Int_t iSt = 0; iSt < 5; iSt++) fRequestStation[iSt] = kTRUE;
246   fBypassSt45 = 0;
247   fMaxTriggerTracks = 100;
248   fMaxTrackCandidates = 10000;
249   
250 }
251
252 //_____________________________________________________________________________
253 void AliMUONRecoParam::SetCosmicParam() 
254 {
255   /// Set reconstruction parameters for high flux environment
256   
257   SetNameTitle("Cosmic","Cosmic");
258   SetEventSpecie(AliRecoParam::kCosmic);
259   fMinBendingMomentum = 0.8;
260   fMaxBendingMomentum = 1.e10;
261   fMaxNonBendingSlope = 0.3;
262   fMaxBendingSlope = 0.4;
263   fSelectTrackOnSlope = kTRUE;
264   fNonBendingVertexDispersion = 170.;
265   fBendingVertexDispersion = 170.;
266   fMaxNonBendingDistanceToTrack = 1.;
267   fMaxBendingDistanceToTrack = 1.;
268   fSigmaCutForTracking = 7.;
269   fSigmaCutForImprovement = 6.;
270   fSigmaCutForTrigger = 8.;
271   fStripCutForTrigger = 1.5;
272   fMaxStripAreaForTrigger = 3.;
273   fMaxNormChi2MatchTrigger = 16.;
274   fPercentOfFullClusterInESD = 100.;
275   fCombinedClusterTrackReco = kFALSE;
276   fTrackAllTracks = kTRUE;
277   fRecoverTracks = kTRUE;
278   fMakeTrackCandidatesFast = kFALSE;
279   fMakeMoreTrackCandidates = kFALSE;
280   fComplementTracks = kTRUE;
281   fImproveTracks = kTRUE;
282   fRemoveConnectedTracksInSt12 = kTRUE;
283   fUseSmoother = kTRUE;
284   fSaveFullClusterInESD = kTRUE;
285   for (Int_t iCh = 0; iCh < 10; iCh++) {
286     fUseChamber[iCh] = kTRUE;
287     fDefaultNonBendingReso[iCh] = 0.4;
288     fDefaultBendingReso[iCh] = 0.4;
289   }
290   fRequestStation[0] = kTRUE;
291   fRequestStation[1] = kTRUE;
292   fRequestStation[2] = kTRUE;
293   fRequestStation[3] = kTRUE;
294   fRequestStation[4] = kTRUE;
295   fBypassSt45 = 0;
296   fPadGoodnessMask = 0x400BE80; // Ped Mean is Zero | Ped Mean Too Low | Ped Mean Too High | Ped Sigma Too Low | Ped Sigma Too High | Ped is missing | HV is missing | manu occupancy too high
297   fMaxTriggerTracks = 100;
298   fMaxTrackCandidates = 10000;
299   SetPedMeanLimits(20, 700);
300   SetManuOccupancyLimits(-1.,0.01); // reject manu above occ=1%
301   
302 }
303
304
305 //_____________________________________________________________________________
306 void AliMUONRecoParam::SetCalibrationParam() 
307 {
308   /// Set (dummy) reconstruction parameters for calibration environment
309   
310   SetNameTitle("Calibration","Calibration");
311   SetEventSpecie(AliRecoParam::kCalib);
312
313   fPedMeanLimits[0] = 5000;
314   fPedMeanLimits[1] = 0;
315
316   fPadGoodnessMask = 0x8C00; // Pedestal is missing | is too low | too high
317
318 }
319
320 //_____________________________________________________________________________
321 UInt_t
322 AliMUONRecoParam::RequestedStationMask() const
323 {
324   /// Get the mask of the requested station, i.e. an integer where 
325   /// bit n is set to one if the station n was requested
326   
327   UInt_t m(0);
328   
329   for ( Int_t i = 0; i < 5; ++i ) 
330   {
331     if ( RequestStation(i) ) m |= ( 1 << i );
332   }
333   return m;
334 }
335
336 //_____________________________________________________________________________
337 void AliMUONRecoParam::Print(Option_t *option) const
338 {
339   /// print reconstruction parameters
340   /// if option = FULL then print also unused parameters
341   
342   cout<<endl<<"\t------MUON Reconstruction parameters ("<<GetName()<<")------"<<endl;
343   
344   if (IsDefault()) cout<<"\t\t*** Parameters used by default ***"<<endl;
345   
346   cout<<Form("Calibration mode = %s",fCalibrationMode.Data())<<endl;
347   cout<<Form("Clustering mode = %s",fClusteringMode.Data())<<endl;
348   cout<<Form("Tracking mode = %s",fTrackingMode.Data())<<endl;
349
350         TString bypass;
351         
352         if ( BypassSt45() )
353         {
354                 bypass = "stations 4 and 5";
355         }
356         else if ( BypassSt4() ) 
357         {
358                 bypass = "station 4";
359         }
360         else if ( BypassSt5() ) 
361         {
362                 bypass = "station 5";
363         }
364         
365   if (bypass.Length()) cout << "Will bypass " << bypass.Data() << " (replacing real clusters by generated ones from trigger tracks)" << endl;
366   
367   if (fCombinedClusterTrackReco) cout<<"Combined cluster/track reconstruction: ON"<<endl;
368   else cout<<"Combined cluster/track reconstruction: OFF"<<endl;
369   
370   if (fSaveFullClusterInESD) cout<<Form("Save all cluster info in ESD for %5.2f %% of events",fPercentOfFullClusterInESD)<<endl;
371   else cout<<"Save partial cluster info in ESD"<<endl;
372     
373   cout<<"Selection of track candidates:"<<endl;
374   if (fSelectTrackOnSlope) cout<<Form("\t- Non-bending slope < %5.2f",fMaxNonBendingSlope)<<endl;
375   else cout<<"\t- Impact parameter < 3 * vertex dispersion in the non-bending direction"<<endl;
376   cout<<Form("\t- if B!=0: Bending momentum > %5.2f",fMinBendingMomentum)<<endl;
377   if (fSelectTrackOnSlope) cout<<Form("\t  if B==0: Bending slope < %5.2f",fMaxBendingSlope)<<endl;
378   else cout<<"\t  if B==0: Impact parameter < 3 * vertex dispersion in the bending direction"<<endl;
379   
380   cout<<Form("Vertex dispersion (used to estimate initial bending momentum resolution) = (%5.2f,%5.2f)",fNonBendingVertexDispersion,fBendingVertexDispersion)<<endl;
381   
382   cout<<Form("Maximum distance to track = (%5.2f,%5.2f)",fMaxNonBendingDistanceToTrack,fMaxBendingDistanceToTrack)<<endl;
383   
384   cout<<Form("Sigma cut for tracking = %5.2f",fSigmaCutForTracking)<<endl;
385
386   cout<<Form("Sigma cut for trigger hit pattern = %5.2f",fSigmaCutForTrigger)<<endl;
387
388   cout<<Form("Cut in strips for trigger chamber efficiency = %5.2f",fStripCutForTrigger)<<endl;
389
390   cout<<Form("Max search area in strips for trigger chamber efficiency = %5.2f",fMaxStripAreaForTrigger)<<endl;
391
392   if (fTrackAllTracks) cout<<"Track all the possible candidates"<<endl;
393   else cout<<"Track only the best candidates"<<endl;
394   
395   if (strstr(option,"FULL")) {
396     cout<<"Make track candidates assuming linear propagation between stations 4 and 5: ";
397     if (fMakeTrackCandidatesFast) cout<<"ON"<<endl;
398     else cout<<"OFF"<<endl;
399   } else if (fMakeTrackCandidatesFast)
400     cout<<"Make track candidates assuming linear propagation between stations 4 and 5"<<endl;
401   
402   if (strstr(option,"FULL")) {
403     cout<<"Make track candidates starting from 1 cluster in each of the stations 4 and 5: ";
404     if (fMakeMoreTrackCandidates) cout<<"ON"<<endl;
405     else cout<<"OFF"<<endl;
406   } else if (fMakeMoreTrackCandidates)
407     cout<<"Make track candidates starting from 1 cluster in each of the stations 4 and 5"<<endl;
408   
409   if (strstr(option,"FULL")) {
410     cout<<"Try to recover tracks getting lost during tracking: ";
411     if (fRecoverTracks) cout<<"ON"<<endl;
412     else cout<<"OFF"<<endl;
413   } else if (fRecoverTracks)
414     cout<<"Try to recover tracks getting lost during tracking"<<endl;
415   
416   if (strstr(option,"FULL")) {
417     cout<<"Try to complete the reconstructed tracks by adding missing clusters: ";
418     if (fComplementTracks) cout<<"ON"<<endl;
419     else cout<<"OFF"<<endl;
420   } else if (fComplementTracks)
421     cout<<"Try to complete the reconstructed tracks by adding missing clusters"<<endl;
422   
423   if (strstr(option,"FULL")) {
424     cout<<"Try to improve the reconstructed tracks by removing bad clusters: ";
425     if (fImproveTracks) cout<<Form("ON (sigma cut = %5.2f)",fSigmaCutForImprovement)<<endl;
426     else cout<<"OFF"<<endl;
427   } else if (fImproveTracks)
428     cout<<Form("Try to improve the reconstructed tracks by removing bad clusters (sigma cut = %5.2f)",fSigmaCutForImprovement)<<endl;
429   
430   if (fRemoveConnectedTracksInSt12) cout<<"Remove tracks sharing one cluster or more in any station"<<endl;
431   else cout<<"Remove tracks sharing one cluster or more in stations 3, 4 and 5"<<endl;
432   
433   if (strstr(option,"FULL")) {
434     cout<<"Use smoother to compute final track parameters, etc, at each cluster (used for Kalman tracking only): ";
435     if (fUseSmoother) cout<<"ON"<<endl;
436     else cout<<"OFF"<<endl;
437   } else if (fUseSmoother)
438     cout<<"Use smoother to compute final track parameters, etc, at each cluster"<<endl;
439   
440   cout<<Form("Maximum normalized chi2 of tracking/trigger track matching = %5.2f",fMaxNormChi2MatchTrigger)<<endl;
441   
442   Bool_t discardedCh = kFALSE;
443   Int_t ch = 0;
444   do {
445     if (!UseChamber(ch)) {
446       if (!discardedCh) {
447         cout<<"Discarded chambers(1..): "<<ch+1;
448         discardedCh = kTRUE;
449       }
450       else cout<<" "<<ch+1;
451     }
452   } while (++ch < 10);
453   if (discardedCh) cout<<endl;
454   
455   Bool_t discardedSt = kFALSE;
456   Int_t st = 0;
457   do {
458     if (!RequestStation(st)) {
459       if (!discardedSt) {
460         cout<<"Not requested stations(1..): "<<st+1;
461         discardedSt = kTRUE;
462       }
463       else cout<<" "<<st+1;
464     }
465   } while (++st < 5);
466   if (discardedSt) cout<<endl;
467   
468   cout << Form("Pad goodness policy mask is 0x%x",PadGoodnessMask()) << endl;
469   cout << "Which means we reject pads having the condition = " <<
470   AliMUONPadStatusMaker::AsCondition(PadGoodnessMask()).Data() << endl;
471   
472   cout << "The pad limits we are using are :" << endl;
473   
474   cout << Form("%5.0f <= HVSt12 <= %5.0f Volts",HVSt12LowLimit(),HVSt12HighLimit()) << endl;
475   cout << Form("%5.0f <= HVSt345 <= %5.0f Volts",HVSt345LowLimit(),HVSt345HighLimit()) << endl;
476   cout << Form("%7.2f <= Pedestal mean <= %7.2f",PedMeanLowLimit(),PedMeanHighLimit()) << endl;
477   cout << Form("%7.2f <= Pedestal sigma <= %7.2f",PedSigmaLowLimit(),PedSigmaHighLimit()) << endl;
478   cout << Form("%e <= Gain linear term <= %e",GainA1LowLimit(),GainA1HighLimit()) << endl;
479   cout << Form("%e <= Gain quadratic term <= %e",GainA2LowLimit(),GainA2HighLimit()) << endl;
480   cout << Form("%5.0f <= Gain threshold term <= %5.0f",GainThresLowLimit(),GainThresHighLimit()) << endl;
481     
482   cout << Form("And we cut on charge >= %7.2f x ( pedestal sigma ) ",ChargeSigmaCut()) << endl;
483   
484   cout << "Occupancy limits are :" << endl;
485   
486   cout << Form("%7.2f <= Manu occupancy < %7.2f",ManuOccupancyLowLimit(),ManuOccupancyHighLimit()) << endl;
487   cout << Form("%7.2f <= Buspatch occupancy < %7.2f",BuspatchOccupancyLowLimit(),BuspatchOccupancyHighLimit()) << endl;
488   cout << Form("%7.2f <= DE occupancy < %7.2f",DEOccupancyLowLimit(),DEOccupancyHighLimit()) << endl;
489   
490   cout << "chamber non bending resolution = |";
491   for (Int_t iCh = 0; iCh < 10; iCh++) cout << Form(" %6.3f |",fDefaultNonBendingReso[iCh]);
492   cout << endl;
493   cout << "chamber bending resolution = |";
494   for (Int_t iCh = 0; iCh < 10; iCh++) cout << Form(" %6.3f |",fDefaultBendingReso[iCh]);
495   cout << endl;
496   cout<<Form("maximum number of trigger tracks above which the tracking is cancelled = %d",fMaxTriggerTracks)<<endl;
497   cout<<Form("maximum number of track candidates above which the tracking is abandonned = %d",fMaxTrackCandidates)<<endl;
498   
499   cout<<"\t-----------------------------------------------------"<<endl<<endl;
500   
501 }
502
503 //_____________________________________________________________________________
504 void
505 AliMUONRecoParam::SetDefaultLimits()
506 {
507         /// Set the default limits and pad goodness policy
508
509         fHVSt12Limits[0]=1500;
510         fHVSt12Limits[1]=2000;
511
512         fHVSt345Limits[0]=1500;
513         fHVSt345Limits[1]=2000;
514
515         fPedMeanLimits[0] = 20;
516         fPedMeanLimits[1] = 1024;
517         
518         fPedSigmaLimits[0] = 0.6;
519         fPedSigmaLimits[1] = 100;
520
521         fGainA1Limits[0] = 0.1;
522         fGainA1Limits[1] = 10;
523
524         fGainA2Limits[0] = -1E30;
525         fGainA2Limits[1] = 1E30;
526         
527         fGainThresLimits[0] = 0;
528         fGainThresLimits[1] = 4095;
529         
530         fPadGoodnessMask = 0x8080; // Ped is missing | HV is missing
531
532   fManuOccupancyLimits[0] = -1.0; 
533   fManuOccupancyLimits[1] = 1.0;
534
535   fBuspatchOccupancyLimits[0] = -1.0; 
536   fBuspatchOccupancyLimits[1] = 1.0;
537
538   fDEOccupancyLimits[0] = -1.0; 
539   fDEOccupancyLimits[1] = 1.0;
540
541   fChargeSigmaCut = 4.0;
542 }
543