Changeset 4889 for trunk/MagicSoft/Mars/mhist
- Timestamp:
- 09/08/04 18:49:00 (20 years ago)
- Location:
- trunk/MagicSoft/Mars/mhist
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/MagicSoft/Mars/mhist/MHEffectiveOnTime.cc
r4887 r4889 42 42 #include <TCanvas.h> 43 43 #include <TMinuit.h> 44 #include <TRandom.h> 44 45 45 46 #include "MTime.h" … … 62 63 // 63 64 MHEffectiveOnTime::MHEffectiveOnTime(const char *name, const char *title) 64 : /*fLastTime(0), fFirstTime(-1),*/fIsFinalized(kFALSE), fInterval(60)65 : fPointPos(0), fTime(0), fParam(0), fIsFinalized(kFALSE), fInterval(60) 65 66 { 66 67 // … … 141 142 } 142 143 143 Double_t testval = 0; 144 Double_t testerr = 0; 144 // FIXME: Just for a preliminary check 145 static Double_t testval = 0; 146 static Double_t testerr = 0; 145 147 146 148 // -------------------------------------------------------------------------- … … 185 187 Bool_t MHEffectiveOnTime::Finalize() 186 188 { 187 Fit(); 189 FitThetaBins(); 190 Calc(); 191 188 192 fIsFinalized = kTRUE; 193 189 194 return kTRUE; 190 195 } 191 196 192 void MHEffectiveOnTime::Fit() 193 { 197 void MHEffectiveOnTime::FitThetaBins() 198 { 199 const TString name = Form("CalcTheta%d", (UInt_t)gRandom->Uniform(999999999)); 200 194 201 // nbins = number of Theta bins 195 202 const Int_t nbins = fHTimeDiff.GetNbinsY(); 196 203 204 TH1D *h=0; 197 205 for (int i=1; i<=nbins; i++) 198 206 { 199 207 // TH1D &h = *hist->ProjectionX("Calc-theta", i, i); 200 TH1D *h = fHTimeDiff.ProjectionX("CalcTheta", i, i, "E"); 201 202 const Double_t Nm = h->Integral(); 203 204 if (Nm<=0) 208 h = fHTimeDiff.ProjectionX(name, i, i, "E"); 209 210 Double_t res[7]; 211 if (!FitH(h, res)) 205 212 continue; 206 213 207 // determine range (yq[0], yq[1]) of time differences 208 // where fit should be performed; 209 // require a fraction >=xq[0] of all entries to lie below yq[0] 210 // and a fraction <=xq[1] of all entries to lie below yq[1]; 211 // within the range (yq[0], yq[1]) there must be no empty bin; 212 // choose pedestrian approach as long as GetQuantiles is not available 213 Double_t xq[2] = { 0.15, 0.95 }; 214 Double_t yq[2]; 215 216 // GetQuantiles doesn't seem to be available in root 3.01/06 217 h->GetQuantiles(2, yq, xq); 218 219 // Nmdel = Nm * binwidth, with Nm = number of observed events 220 const Double_t Nmdel = h->Integral("width"); 221 222 // 223 // Setup Poisson function for the fit: 224 // lambda [Hz], N0 = ideal no of evts, del = bin width of dt 225 // 226 // parameter 0 = lambda 227 // parameter 1 = N0*del 228 // 229 TF1 func("Poisson", " [1]*[2] * [0] * exp(-[0] *x)", yq[0], yq[1]); 230 func.SetParNames("lambda", "N0", "del"); 231 232 func.SetParameter(0, 100); // Hz 233 func.SetParameter(1, Nm); 234 func.FixParameter(2, Nmdel/Nm); 235 236 // options : 0 do not plot the function 237 // I use integral of function in bin rather than value at bin center 238 // R use the range specified in the function range 239 // Q quiet mode 240 h->Fit(&func, "0IRQ"); 241 242 const Double_t chi2 = func.GetChisquare(); 243 const Int_t NDF = func.GetNDF(); 244 245 // was fit successful ? 246 if (NDF>0 && chi2<2.5*NDF) 247 { 248 const Double_t lambda = func.GetParameter(0); 249 const Double_t N0 = func.GetParameter(1); 250 const Double_t prob = func.GetProb(); 251 252 /* 253 *fLog << all << "Nm/lambda=" << Nm/lambda << " chi2/NDF="; 254 *fLog << (NDF ? chi2/NDF : 0.0) << " lambda="; 255 *fLog << lambda << " N0=" << N0 << endl; 256 */ 257 258 Double_t emat[2][2]; 259 gMinuit->mnemat((Double_t*)emat, 2); 260 261 const Double_t dldl = emat[0][0]; 262 //const Double_t dN0dN0 = emat[1][1]; 263 264 const Double_t teff = Nm/lambda; 265 const Double_t dteff = teff * TMath::Sqrt(dldl/(lambda*lambda) + 1.0/Nm); 266 267 const Double_t dl = TMath::Sqrt(dldl); 268 269 //const Double_t kappa = Nm/N0; 270 //const Double_t Rdead = 1.0 - kappa; 271 //const Double_t dRdead = kappa * TMath::Sqrt(dN0dN0/(N0*N0) + 1.0/Nm); 272 273 // the effective on time is Nm/lambda 274 fHEffOn.SetBinContent(i, teff); 275 fHEffOn.SetBinError (i, dteff); 276 277 // plot chi2-probability of fit 278 fHProb.SetBinContent(i, prob*100); 279 280 // plot chi2/NDF of fit 281 fHChi2.SetBinContent(i, NDF ? chi2/NDF : 0.0); 282 283 // lambda of fit 284 fHLambda.SetBinContent(i, lambda); 285 fHLambda.SetBinError (i, dl); 286 287 // N0 of fit 288 fHN0.SetBinContent(i, N0); 289 290 // Rdead (from fit) is the fraction from real time lost by the dead time 291 //fHRdead.SetBinContent(i, Rdead); 292 //fHRdead.SetBinError (i,dRdead); 293 } 294 214 // the effective on time is Nm/lambda 215 fHEffOn.SetBinContent(i, res[0]); 216 fHEffOn.SetBinError (i, res[1]); 217 218 // plot chi2-probability of fit 219 fHProb.SetBinContent(i, res[2]); 220 221 // plot chi2/NDF of fit 222 fHChi2.SetBinContent(i, res[3]); 223 224 // lambda of fit 225 fHLambda.SetBinContent(i, res[4]); 226 fHLambda.SetBinError (i, res[5]); 227 228 // N0 of fit 229 fHN0.SetBinContent(i, res[6]); 230 231 // Rdead (from fit) is the fraction from real time lost by the dead time 232 //fHRdead.SetBinContent(i, Rdead); 233 //fHRdead.SetBinError (i,dRdead); 234 } 235 236 // Histogram is reused via gROOT->FindObject() 237 // Need to be deleted only once 238 if (h) 295 239 delete h; 296 } 297 } 298 240 } 241 242 Bool_t MHEffectiveOnTime::FitH(TH1D *h, Double_t *res) const 243 { 244 const Double_t Nm = h->Integral(); 245 246 // FIXME: Do fit only if contents of bin has changed 247 if (Nm<=0) 248 return kFALSE; 249 250 // determine range (yq[0], yq[1]) of time differences 251 // where fit should be performed; 252 // require a fraction >=xq[0] of all entries to lie below yq[0] 253 // and a fraction <=xq[1] of all entries to lie below yq[1]; 254 // within the range (yq[0], yq[1]) there must be no empty bin; 255 // choose pedestrian approach as long as GetQuantiles is not available 256 Double_t xq[2] = { 0.05, 0.95 }; 257 Double_t yq[2]; 258 h->GetQuantiles(2, yq, xq); 259 260 // Nmdel = Nm * binwidth, with Nm = number of observed events 261 const Double_t Nmdel = h->Integral("width"); 262 263 // 264 // Setup Poisson function for the fit: 265 // lambda [Hz], N0 = ideal no of evts, del = bin width of dt 266 // 267 // parameter 0 = lambda 268 // parameter 1 = N0*del 269 // 270 TF1 func("Poisson", " [1]*[2] * [0] * exp(-[0] *x)", yq[0], yq[1]); 271 func.SetParNames("lambda", "N0", "del"); 272 273 func.SetParameter(0, 100); // Hz 274 func.SetParameter(1, Nm); 275 func.FixParameter(2, Nmdel/Nm); 276 277 // options : 0 do not plot the function 278 // I use integral of function in bin rather than value at bin center 279 // R use the range specified in the function range 280 // Q quiet mode 281 h->Fit(&func, "0IRQ"); 282 283 const Double_t chi2 = func.GetChisquare(); 284 const Int_t NDF = func.GetNDF(); 285 286 // was fit successful ? 287 if (NDF<=0 || chi2>=2.5*NDF) 288 return kFALSE; 289 290 const Double_t lambda = func.GetParameter(0); 291 const Double_t N0 = func.GetParameter(1); 292 const Double_t prob = func.GetProb(); 293 294 /* 295 *fLog << all << "Nm/lambda=" << Nm/lambda << " chi2/NDF="; 296 *fLog << (NDF ? chi2/NDF : 0.0) << " lambda="; 297 *fLog << lambda << " N0=" << N0 << endl; 298 */ 299 300 Double_t emat[2][2]; 301 gMinuit->mnemat((Double_t*)emat, 2); 302 303 const Double_t dldl = emat[0][0]; 304 //const Double_t dN0dN0 = emat[1][1]; 305 306 const Double_t teff = Nm/lambda; 307 const Double_t dteff = teff * TMath::Sqrt(dldl/(lambda*lambda) + 1.0/Nm); 308 309 const Double_t dl = TMath::Sqrt(dldl); 310 311 //const Double_t kappa = Nm/N0; 312 //const Double_t Rdead = 1.0 - kappa; 313 //const Double_t dRdead = kappa * TMath::Sqrt(dN0dN0/(N0*N0) + 1.0/Nm); 314 315 // the effective on time is Nm/lambda 316 res[0] = teff; 317 res[1] = dteff; 318 319 // plot chi2-probability of fit 320 res[2] = prob*100; 321 322 // plot chi2/NDF of fit 323 res[3] = NDF ? chi2/NDF : 0.0; 324 325 // lambda of fit 326 res[4] = lambda; 327 res[5] = dl; 328 329 // N0 of fit 330 res[6] = N0; 331 332 // Rdead (from fit) is the fraction from real time lost by the dead time 333 //fHRdead.SetBinContent(i, Rdead); 334 //fHRdead.SetBinError (i,dRdead); 335 336 return kTRUE; 337 } 299 338 300 339 void MHEffectiveOnTime::Paint(Option_t *opt) … … 320 359 321 360 if (!fIsFinalized) 322 Fit ();361 FitThetaBins(); 323 362 } 324 363 if (o==(TString)"paint") … … 386 425 void MHEffectiveOnTime::Calc() 387 426 { 388 const Double_t val = fHEffOn.Integral(); 389 390 Double_t error = 0; 391 for (int i=0; i<fHEffOn.GetXaxis()->GetNbins(); i++) 392 error += fHEffOn.GetBinError(i); 427 TH1D *h = fHTimeDiff.ProjectionX("", -1, 99999, "E"); 428 h->SetDirectory(0); 429 430 Double_t res[7]; 431 Bool_t rc = FitH(h, res); 432 delete h; 433 434 if (!rc) 435 return; 436 437 const Double_t val = res[0]; 438 const Double_t error = res[1]; 393 439 394 440 fParam->SetVal(val-fEffOnTime0, error-fEffOnErr0); … … 403 449 MTime now(*fTime); 404 450 now.AddMilliSeconds(fInterval*1000); 451 405 452 *fLog <<all << now << " - ";// << fLastTime-fTime; 406 453 *fLog << Form("T_{eff} = %.1fs \\pm %.1fs", … … 435 482 436 483 *fTime = *time; 437 // fTime->MinusNull() 484 485 // Make this just a ns before the first event 486 fTime->Minus1ns(); 438 487 } 439 488 440 489 if (*fTime+fInterval<*time) 441 490 { 442 Fit ();491 FitThetaBins(); 443 492 Calc(); 444 493 } -
trunk/MagicSoft/Mars/mhist/MHEffectiveOnTime.h
r4887 r4889 24 24 { 25 25 private: 26 MPointingPos *fPointPos; //!27 MTime fLastTime; //!26 MPointingPos *fPointPos; //! 27 MTime fLastTime; //! 28 28 29 Double_t fEffOnTime0; //!30 Double_t fEffOnErr0; //!29 Double_t fEffOnTime0; //! 30 Double_t fEffOnErr0; //! 31 31 32 MTime *fTime; 33 MParameterDerr *fParam; 32 MTime *fTime; //! 33 MParameterDerr *fParam; //! 34 34 35 35 TH2D fHTimeDiff; … … 44 44 Int_t fInterval; 45 45 46 void Fit(); 46 Bool_t FitH(TH1D *h, Double_t *res) const; 47 void FitThetaBins(); 47 48 void Calc(); 48 49
Note:
See TracChangeset
for help on using the changeset viewer.