00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TROOT.h"
00013 #include "TF3.h"
00014 #include "TMath.h"
00015 #include "TH3.h"
00016 #include "TVirtualPad.h"
00017 #include "TRandom.h"
00018 #include "TVectorD.h"
00019 #include "Riostream.h"
00020 #include "TColor.h"
00021 #include "TVirtualFitter.h"
00022 #include "TVirtualHistPainter.h"
00023 #include "TClass.h"
00024
00025 ClassImp(TF3)
00026
00027
00028
00029
00030
00031
00032
00033 TF3::TF3(): TF2()
00034 {
00035
00036
00037
00038 fNpz = 0;
00039 fZmin = 0;
00040 fZmax = 1;
00041 }
00042
00043
00044
00045 TF3::TF3(const char *name,const char *formula, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax)
00046 :TF2(name,formula,xmin,xmax,ymax,ymin)
00047 {
00048
00049
00050
00051
00052
00053
00054
00055
00056 fZmin = zmin;
00057 fZmax = zmax;
00058 fNpz = 30;
00059 if (fNdim != 3 && xmin < xmax) {
00060 Error("TF3","function: %s/%s has %d parameters instead of 3",name,formula,fNdim);
00061 MakeZombie();
00062 }
00063 }
00064
00065
00066
00067 TF3::TF3(const char *name,void *fcn, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax, Int_t npar)
00068 :TF2(name,fcn,xmin,xmax,ymin,ymax,npar)
00069 {
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 fZmin = zmin;
00087 fZmax = zmax;
00088 fNpz = 30;
00089 fNdim = 3;
00090 }
00091
00092
00093 TF3::TF3(const char *name,Double_t (*fcn)(Double_t *, Double_t *), Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax, Int_t npar)
00094 :TF2(name,fcn,xmin,xmax,ymin,ymax,npar)
00095 {
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 fZmin = zmin;
00111 fZmax = zmax;
00112 fNpz = 30;
00113 fNdim = 3;
00114 }
00115
00116
00117 TF3::TF3(const char *name,Double_t (*fcn)(const Double_t *, const Double_t *), Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax, Int_t npar)
00118 : TF2(name,fcn,xmin,xmax,ymin,ymax,npar),
00119 fZmin(zmin),
00120 fZmax(zmax),
00121 fNpz(30)
00122 {
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 fNdim = 3;
00138 }
00139
00140
00141 TF3::TF3(const char *name, ROOT::Math::ParamFunctor f, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax, Int_t npar)
00142 : TF2(name, f, xmin, xmax, ymin, ymax, npar),
00143 fZmin(zmin),
00144 fZmax(zmax),
00145 fNpz(30)
00146 {
00147
00148
00149
00150
00151
00152
00153
00154
00155 fNdim = 3;
00156 }
00157
00158
00159 TF3::TF3(const char *name, void * ptr, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax, Int_t npar, const char *className)
00160 : TF2(name, ptr, xmin, xmax, ymin, ymax, npar, className),
00161 fZmin(zmin),
00162 fZmax(zmax),
00163 fNpz(30)
00164 {
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 fNdim = 3;
00175 }
00176
00177
00178 TF3::TF3(const char *name, void * ptr, void *,Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax, Int_t npar, const char *className, const char * methodName)
00179 : TF2(name, ptr, (void*)0,xmin, xmax, ymin, ymax, npar,className, methodName),
00180 fZmin(zmin),
00181 fZmax(zmax),
00182 fNpz(30)
00183 {
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 fNdim = 3;
00195 }
00196
00197
00198
00199 TF3& TF3::operator=(const TF3 &rhs)
00200 {
00201
00202
00203 if (this != &rhs) {
00204 rhs.Copy(*this);
00205 }
00206 return *this;
00207 }
00208
00209
00210 TF3::~TF3()
00211 {
00212
00213
00214
00215 }
00216
00217
00218 TF3::TF3(const TF3 &f3) : TF2()
00219 {
00220
00221
00222 ((TF3&)f3).Copy(*this);
00223 }
00224
00225
00226 void TF3::Copy(TObject &obj) const
00227 {
00228
00229
00230
00231 TF2::Copy(obj);
00232 ((TF3&)obj).fZmin = fZmin;
00233 ((TF3&)obj).fZmax = fZmax;
00234 ((TF3&)obj).fNpz = fNpz;
00235 }
00236
00237
00238 Int_t TF3::DistancetoPrimitive(Int_t px, Int_t py)
00239 {
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 return TF1::DistancetoPrimitive(px, py);
00251
00252 }
00253
00254
00255 void TF3::Draw(Option_t *option)
00256 {
00257
00258
00259
00260 TString opt = option;
00261 opt.ToLower();
00262 if (gPad && !opt.Contains("same")) gPad->Clear();
00263
00264 AppendPad(option);
00265
00266 }
00267
00268
00269 void TF3::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00270 {
00271
00272
00273
00274
00275
00276
00277 TF1::ExecuteEvent(event, px, py);
00278 }
00279
00280
00281 void TF3::GetMinimumXYZ(Double_t &x, Double_t &y, Double_t &z)
00282 {
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 Double_t xx, yy, zz, tt;
00295 Double_t dx = (fXmax - fXmin)/fNpx;
00296 Double_t dy = (fYmax - fYmin)/fNpy;
00297 Double_t dz = (fZmax - fZmin)/fNpz;
00298
00299 Double_t xxmin = fXmin;
00300 Double_t yymin = fYmin;
00301 Double_t zzmin = fZmin;
00302 Double_t ttmin = Eval(xxmin, yymin, zzmin+dz);
00303 for (Int_t i=0; i<fNpx; i++){
00304 xx=fXmin + (i+0.5)*dx;
00305 for (Int_t j=0; j<fNpy; j++){
00306 yy=fYmin+(j+0.5)*dy;
00307 for (Int_t k=0; k<fNpz; k++){
00308 zz = fZmin+(k+0.5)*dz;
00309 tt = Eval(xx, yy, zz);
00310 if (tt<ttmin) {xxmin = xx, yymin = yy; zzmin = zz; ttmin=tt;}
00311 }
00312 }
00313 }
00314
00315 x = TMath::Min(fXmax, xxmin);
00316 y = TMath::Min(fYmax, yymin);
00317 z = TMath::Min(fZmax, zzmin);
00318
00319
00320 char f[]="TFitter";
00321
00322 Int_t strdiff = 0;
00323 if (TVirtualFitter::GetFitter()){
00324
00325
00326 strdiff = strcmp(TVirtualFitter::GetFitter()->IsA()->GetName(), f);
00327 if (strdiff!=0)
00328 delete TVirtualFitter::GetFitter();
00329 }
00330
00331 TVirtualFitter *minuit = TVirtualFitter::Fitter(this, 3);
00332 minuit->Clear();
00333 minuit->SetFitMethod("F3Minimizer");
00334 Double_t arglist[10];
00335 arglist[0]=-1;
00336 minuit->ExecuteCommand("SET PRINT", arglist, 1);
00337
00338 minuit->SetParameter(0, "x", x, 0.1, 0, 0);
00339 minuit->SetParameter(1, "y", y, 0.1, 0, 0);
00340 minuit->SetParameter(2, "z", z, 0.1, 0, 0);
00341 arglist[0] = 5;
00342 arglist[1] = 1e-5;
00343
00344
00345 Int_t fitResult = minuit->ExecuteCommand("MIGRAD", arglist, 0);
00346 if (fitResult!=0){
00347
00348 Warning("GetMinimumXYZ", "Abnormal termination of minimization");
00349 }
00350 Double_t xtemp = minuit->GetParameter(0);
00351 Double_t ytemp = minuit->GetParameter(1);
00352 Double_t ztemp = minuit->GetParameter(2);
00353 if (xtemp>fXmax || xtemp<fXmin || ytemp>fYmax || ytemp<fYmin || ztemp>fZmax || ztemp<fZmin){
00354
00355 minuit->SetParameter(0, "x", x, 0.1, fXmin, fXmax);
00356 minuit->SetParameter(1, "y", y, 0.1, fYmin, fYmax);
00357 minuit->SetParameter(2, "z", z, 0.1, fZmin, fZmax);
00358 fitResult = minuit->ExecuteCommand("MIGRAD", arglist, 0);
00359 if (fitResult!=0){
00360
00361 Warning("GetMinimumXYZ", "Abnormal termination of minimization");
00362 }
00363 }
00364 x = minuit->GetParameter(0);
00365 y = minuit->GetParameter(1);
00366 z = minuit->GetParameter(2);
00367 }
00368
00369
00370 void TF3::GetRandom3(Double_t &xrandom, Double_t &yrandom, Double_t &zrandom)
00371 {
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 Int_t i,j,k,cell;
00392 Double_t dx = (fXmax-fXmin)/fNpx;
00393 Double_t dy = (fYmax-fYmin)/fNpy;
00394 Double_t dz = (fZmax-fZmin)/fNpz;
00395 Int_t ncells = fNpx*fNpy*fNpz;
00396 Double_t xx[3];
00397 InitArgs(xx,fParams);
00398 if (fIntegral == 0) {
00399 fIntegral = new Double_t[ncells+1];
00400 fIntegral[0] = 0;
00401 Double_t integ;
00402 Int_t intNegative = 0;
00403 cell = 0;
00404 for (k=0;k<fNpz;k++) {
00405 xx[2] = fZmin+(k+0.5)*dz;
00406 for (j=0;j<fNpy;j++) {
00407 xx[1] = fYmin+(j+0.5)*dy;
00408 for (i=0;i<fNpx;i++) {
00409 xx[0] = fXmin+(i+0.5)*dx;
00410 integ = EvalPar(xx,fParams);
00411 if (integ < 0) {intNegative++; integ = -integ;}
00412 fIntegral[cell+1] = fIntegral[cell] + integ;
00413 cell++;
00414 }
00415 }
00416 }
00417 if (intNegative > 0) {
00418 Warning("GetRandom3","function:%s has %d negative values: abs assumed",GetName(),intNegative);
00419 }
00420 if (fIntegral[ncells] == 0) {
00421 Error("GetRandom3","Integral of function is zero");
00422 return;
00423 }
00424 for (i=1;i<=ncells;i++) {
00425 fIntegral[i] /= fIntegral[ncells];
00426 }
00427 }
00428
00429
00430 Double_t r;
00431 r = gRandom->Rndm();
00432 cell = TMath::BinarySearch(ncells,fIntegral,r);
00433 k = cell/(fNpx*fNpy);
00434 j = (cell -k*fNpx*fNpy)/fNpx;
00435 i = cell -fNpx*(j +fNpy*k);
00436 xrandom = fXmin +dx*i +dx*gRandom->Rndm();
00437 yrandom = fYmin +dy*j +dy*gRandom->Rndm();
00438 zrandom = fZmin +dz*k +dz*gRandom->Rndm();
00439 }
00440
00441
00442 void TF3::GetRange(Double_t &xmin, Double_t &ymin, Double_t &zmin, Double_t &xmax, Double_t &ymax, Double_t &zmax) const
00443 {
00444
00445
00446
00447 xmin = fXmin;
00448 xmax = fXmax;
00449 ymin = fYmin;
00450 ymax = fYmax;
00451 zmin = fZmin;
00452 zmax = fZmax;
00453 }
00454
00455
00456
00457 Double_t TF3::GetSave(const Double_t *xx)
00458 {
00459
00460
00461 if (fNsave <= 0) return 0;
00462 if (fSave == 0) return 0;
00463 Int_t np = fNsave - 9;
00464 Double_t xmin = Double_t(fSave[np+0]);
00465 Double_t xmax = Double_t(fSave[np+1]);
00466 Double_t ymin = Double_t(fSave[np+2]);
00467 Double_t ymax = Double_t(fSave[np+3]);
00468 Double_t zmin = Double_t(fSave[np+4]);
00469 Double_t zmax = Double_t(fSave[np+5]);
00470 Int_t npx = Int_t(fSave[np+6]);
00471 Int_t npy = Int_t(fSave[np+7]);
00472 Int_t npz = Int_t(fSave[np+8]);
00473 Double_t x = Double_t(xx[0]);
00474 Double_t dx = (xmax-xmin)/npx;
00475 if (x < xmin || x > xmax) return 0;
00476 if (dx <= 0) return 0;
00477 Double_t y = Double_t(xx[1]);
00478 Double_t dy = (ymax-ymin)/npy;
00479 if (y < ymin || y > ymax) return 0;
00480 if (dy <= 0) return 0;
00481 Double_t z = Double_t(xx[2]);
00482 Double_t dz = (zmax-zmin)/npz;
00483 if (z < zmin || z > zmax) return 0;
00484 if (dz <= 0) return 0;
00485
00486
00487 Int_t ibin = Int_t((x-xmin)/dx);
00488 Int_t jbin = Int_t((y-ymin)/dy);
00489 Int_t kbin = Int_t((z-zmin)/dz);
00490 Double_t xlow = xmin + ibin*dx;
00491 Double_t ylow = ymin + jbin*dy;
00492 Double_t zlow = zmin + kbin*dz;
00493 Double_t t = (x-xlow)/dx;
00494 Double_t u = (y-ylow)/dy;
00495 Double_t v = (z-zlow)/dz;
00496 Int_t k1 = (ibin ) + (npx+1)*((jbin ) + (npy+1)*(kbin ));
00497 Int_t k2 = (ibin+1) + (npx+1)*((jbin ) + (npy+1)*(kbin ));
00498 Int_t k3 = (ibin+1) + (npx+1)*((jbin+1) + (npy+1)*(kbin ));
00499 Int_t k4 = (ibin ) + (npx+1)*((jbin+1) + (npy+1)*(kbin ));
00500 Int_t k5 = (ibin ) + (npx+1)*((jbin ) + (npy+1)*(kbin+1));
00501 Int_t k6 = (ibin+1) + (npx+1)*((jbin ) + (npy+1)*(kbin+1));
00502 Int_t k7 = (ibin+1) + (npx+1)*((jbin+1) + (npy+1)*(kbin+1));
00503 Int_t k8 = (ibin ) + (npx+1)*((jbin+1) + (npy+1)*(kbin+1));
00504 Double_t r = (1-t)*(1-u)*(1-v)*fSave[k1] + t*(1-u)*(1-v)*fSave[k2] + t*u*(1-v)*fSave[k3] + (1-t)*u*(1-v)*fSave[k4] +
00505 (1-t)*(1-u)*v*fSave[k5] + t*(1-u)*v*fSave[k6] + t*u*v*fSave[k7] + (1-t)*u*v*fSave[k8];
00506 return r;
00507 }
00508
00509
00510 Double_t TF3::Integral(Double_t ax, Double_t bx, Double_t ay, Double_t by, Double_t az, Double_t bz, Double_t epsilon)
00511 {
00512
00513
00514 Double_t a[3], b[3];
00515 a[0] = ax;
00516 b[0] = bx;
00517 a[1] = ay;
00518 b[1] = by;
00519 a[2] = az;
00520 b[2] = bz;
00521 Double_t relerr = 0;
00522 Int_t n = 3;
00523 Int_t minpts = 2*2*2+2*n*(n+1)+1;
00524 Int_t maxpts = 20*fNpx*fNpy*fNpz;
00525 Int_t nfnevl,ifail;
00526 Double_t result = IntegralMultiple(n,a,b,minpts,maxpts,epsilon,relerr,nfnevl,ifail);
00527 if (ifail > 0) {
00528 Warning("Integral","failed code=%d, minpts=%d, maxpts=%d, epsilon=%g, nfnevl=%d, relerr=%g ",ifail,minpts,maxpts,epsilon,nfnevl,relerr);
00529 }
00530 return result;
00531 }
00532
00533
00534 Bool_t TF3::IsInside(const Double_t *x) const
00535 {
00536
00537
00538 if (x[0] < fXmin || x[0] > fXmax) return kFALSE;
00539 if (x[1] < fYmin || x[1] > fYmax) return kFALSE;
00540 if (x[2] < fZmin || x[2] > fZmax) return kFALSE;
00541 return kTRUE;
00542 }
00543
00544
00545 TH1* TF3::CreateHistogram()
00546 {
00547
00548
00549 TH1* h = new TH3F("R__TF3",(char*)GetTitle(),fNpx,fXmin,fXmax
00550 ,fNpy,fYmin,fYmax
00551 ,fNpz,fZmin,fZmax);
00552 h->SetDirectory(0);
00553 return h;
00554 }
00555
00556
00557 void TF3::Paint(Option_t *option)
00558 {
00559
00560
00561
00562
00563 TString opt = option;
00564 opt.ToLower();
00565
00566
00567 if (!fHistogram) {
00568 fHistogram = new TH3F("R__TF3",(char*)GetTitle(),fNpx,fXmin,fXmax
00569 ,fNpy,fYmin,fYmax
00570 ,fNpz,fZmin,fZmax);
00571 fHistogram->SetDirectory(0);
00572 }
00573
00574 fHistogram->GetPainter(option)->ProcessMessage("SetF3",this);
00575 if (opt.Length() == 0 ) {
00576 fHistogram->Paint("tf3");
00577 } else {
00578 opt += "tf3";
00579 fHistogram->Paint(opt.Data());
00580 }
00581 }
00582
00583
00584 void TF3::SetClippingBoxOff()
00585 {
00586
00587
00588 if (!fHistogram) {
00589 fHistogram = new TH3F("R__TF3",(char*)GetTitle(),fNpx,fXmin,fXmax
00590 ,fNpy,fYmin,fYmax
00591 ,fNpz,fZmin,fZmax);
00592 fHistogram->SetDirectory(0);
00593 }
00594 fHistogram->GetPainter()->ProcessMessage("SetF3ClippingBoxOff",0);
00595 }
00596
00597
00598 void TF3::Save(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax, Double_t zmin, Double_t zmax)
00599 {
00600
00601
00602 if (fSave != 0) {delete [] fSave; fSave = 0;}
00603 Int_t nsave = (fNpx+1)*(fNpy+1)*(fNpz+1);
00604 fNsave = nsave+9;
00605 if (fNsave <= 9) {fNsave=0; return;}
00606 fSave = new Double_t[fNsave];
00607 Int_t i,j,k,l=0;
00608 Double_t dx = (xmax-xmin)/fNpx;
00609 Double_t dy = (ymax-ymin)/fNpy;
00610 Double_t dz = (zmax-zmin)/fNpz;
00611 if (dx <= 0) {
00612 dx = (fXmax-fXmin)/fNpx;
00613 xmin = fXmin +0.5*dx;
00614 xmax = fXmax -0.5*dx;
00615 }
00616 if (dy <= 0) {
00617 dy = (fYmax-fYmin)/fNpy;
00618 ymin = fYmin +0.5*dy;
00619 ymax = fYmax -0.5*dy;
00620 }
00621 if (dz <= 0) {
00622 dz = (fZmax-fZmin)/fNpz;
00623 zmin = fZmin +0.5*dz;
00624 zmax = fZmax -0.5*dz;
00625 }
00626 Double_t xv[3];
00627 InitArgs(xv,fParams);
00628 for (k=0;k<=fNpz;k++) {
00629 xv[2] = zmin + dz*k;
00630 for (j=0;j<=fNpy;j++) {
00631 xv[1] = ymin + dy*j;
00632 for (i=0;i<=fNpx;i++) {
00633 xv[0] = xmin + dx*i;
00634 fSave[l] = EvalPar(xv,fParams);
00635 l++;
00636 }
00637 }
00638 }
00639 fSave[nsave+0] = xmin;
00640 fSave[nsave+1] = xmax;
00641 fSave[nsave+2] = ymin;
00642 fSave[nsave+3] = ymax;
00643 fSave[nsave+4] = zmin;
00644 fSave[nsave+5] = zmax;
00645 fSave[nsave+6] = fNpx;
00646 fSave[nsave+7] = fNpy;
00647 fSave[nsave+8] = fNpz;
00648 }
00649
00650
00651 void TF3::SavePrimitive(ostream &out, Option_t *option )
00652 {
00653
00654
00655 char quote = '"';
00656 out<<" "<<endl;
00657 if (gROOT->ClassSaved(TF3::Class())) {
00658 out<<" ";
00659 } else {
00660 out<<" TF3 *";
00661 }
00662 if (!fMethodCall) {
00663 out<<GetName()<<" = new TF3("<<quote<<GetName()<<quote<<","<<quote<<GetTitle()<<quote<<","<<fXmin<<","<<fXmax<<","<<fYmin<<","<<fYmax<<","<<fZmin<<","<<fZmax<<");"<<endl;
00664 } else {
00665 out<<GetName()<<" = new TF3("<<quote<<GetName()<<quote<<","<<GetTitle()<<","<<fXmin<<","<<fXmax<<","<<fYmin<<","<<fYmax<<","<<fZmin<<","<<fZmax<<","<<GetNpar()<<");"<<endl;
00666 }
00667
00668 if (GetFillColor() != 0) {
00669 if (GetFillColor() > 228) {
00670 TColor::SaveColor(out, GetFillColor());
00671 out<<" "<<GetName()<<"->SetFillColor(ci);" << endl;
00672 } else
00673 out<<" "<<GetName()<<"->SetFillColor("<<GetFillColor()<<");"<<endl;
00674 }
00675 if (GetLineColor() != 1) {
00676 if (GetLineColor() > 228) {
00677 TColor::SaveColor(out, GetLineColor());
00678 out<<" "<<GetName()<<"->SetLineColor(ci);" << endl;
00679 } else
00680 out<<" "<<GetName()<<"->SetLineColor("<<GetLineColor()<<");"<<endl;
00681 }
00682 if (GetNpz() != 100) {
00683 out<<" "<<GetName()<<"->SetNpz("<<GetNpz()<<");"<<endl;
00684 }
00685 if (GetChisquare() != 0) {
00686 out<<" "<<GetName()<<"->SetChisquare("<<GetChisquare()<<");"<<endl;
00687 }
00688 Double_t parmin, parmax;
00689 for (Int_t i=0;i<fNpar;i++) {
00690 out<<" "<<GetName()<<"->SetParameter("<<i<<","<<GetParameter(i)<<");"<<endl;
00691 out<<" "<<GetName()<<"->SetParError("<<i<<","<<GetParError(i)<<");"<<endl;
00692 GetParLimits(i,parmin,parmax);
00693 out<<" "<<GetName()<<"->SetParLimits("<<i<<","<<parmin<<","<<parmax<<");"<<endl;
00694 }
00695 out<<" "<<GetName()<<"->Draw("
00696 <<quote<<option<<quote<<");"<<endl;
00697 }
00698
00699
00700 void TF3::SetClippingBoxOn(Double_t xclip, Double_t yclip, Double_t zclip)
00701 {
00702
00703
00704
00705
00706 if (!fHistogram) {
00707 fHistogram = new TH3F("R__TF3",(char*)GetTitle(),fNpx,fXmin,fXmax
00708 ,fNpy,fYmin,fYmax
00709 ,fNpz,fZmin,fZmax);
00710 fHistogram->SetDirectory(0);
00711 }
00712
00713 TVectorD v(3);
00714 v(0) = xclip;
00715 v(1) = yclip;
00716 v(2) = zclip;
00717 fHistogram->GetPainter()->ProcessMessage("SetF3ClippingBoxOn",&v);
00718 }
00719
00720
00721 void TF3::SetNpz(Int_t npz)
00722 {
00723
00724
00725
00726
00727
00728
00729
00730 if (npz < 4) {
00731 Warning("SetNpz","Number of points must be >4 && < 10000, fNpz set to 4");
00732 fNpz = 4;
00733 } else if(npz > 100000) {
00734 Warning("SetNpz","Number of points must be >4 && < 10000, fNpz set to 10000");
00735 fNpz = 10000;
00736 } else {
00737 fNpz = npz;
00738 }
00739 Update();
00740 }
00741
00742
00743 void TF3::SetRange(Double_t xmin, Double_t ymin, Double_t zmin, Double_t xmax, Double_t ymax, Double_t zmax)
00744 {
00745
00746
00747
00748 fXmin = xmin;
00749 fXmax = xmax;
00750 fYmin = ymin;
00751 fYmax = ymax;
00752 fZmin = zmin;
00753 fZmax = zmax;
00754 Update();
00755 }
00756
00757
00758 void TF3::Streamer(TBuffer &R__b)
00759 {
00760
00761
00762 if (R__b.IsReading()) {
00763 UInt_t R__s, R__c;
00764 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
00765 if (R__v > 0) {
00766 R__b.ReadClassBuffer(TF3::Class(), this, R__v, R__s, R__c);
00767 return;
00768 }
00769
00770 } else {
00771 Int_t saved = 0;
00772 if (fType > 0 && fNsave <= 0) { saved = 1; Save(fXmin,fXmax,fYmin,fYmax,fZmin,fZmax);}
00773
00774 R__b.WriteClassBuffer(TF3::Class(),this);
00775
00776 if (saved) {delete [] fSave; fSave = 0; fNsave = 0;}
00777 }
00778 }
00779
00780
00781 Double_t TF3::Moment3(Double_t nx, Double_t ax, Double_t bx, Double_t ny, Double_t ay, Double_t by, Double_t nz, Double_t az, Double_t bz, Double_t epsilon)
00782 {
00783
00784
00785
00786 Double_t norm = Integral(ax,bx,ay,by,az,bz,epsilon);
00787 if (norm == 0) {
00788 Error("Moment3", "Integral zero over range");
00789 return 0;
00790 }
00791
00792 TF3 fnc("TF3_ExpValHelper",Form("%s*pow(x,%f)*pow(y,%f)*pow(z,%f)",GetName(),nx,ny,nz));
00793 return fnc.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
00794 }
00795
00796
00797 Double_t TF3::CentralMoment3(Double_t nx, Double_t ax, Double_t bx, Double_t ny, Double_t ay, Double_t by, Double_t nz, Double_t az, Double_t bz, Double_t epsilon)
00798 {
00799
00800
00801
00802 Double_t norm = Integral(ax,bx,ay,by,az,bz,epsilon);
00803 if (norm == 0) {
00804 Error("CentralMoment3", "Integral zero over range");
00805 return 0;
00806 }
00807
00808 Double_t xbar = 0;
00809 Double_t ybar = 0;
00810 Double_t zbar = 0;
00811 if (nx!=0) {
00812 TF3 fncx("TF3_ExpValHelperx",Form("%s*x",GetName()));
00813 xbar = fncx.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
00814 }
00815 if (ny!=0) {
00816 TF3 fncy("TF3_ExpValHelpery",Form("%s*y",GetName()));
00817 ybar = fncy.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
00818 }
00819 if (nz!=0) {
00820 TF3 fncz("TF3_ExpValHelperz",Form("%s*z",GetName()));
00821 zbar = fncz.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
00822 }
00823 TF3 fnc("TF3_ExpValHelper",Form("%s*pow(x-%f,%f)*pow(y-%f,%f)*pow(z-%f,%f)",GetName(),xbar,nx,ybar,ny,zbar,nz));
00824 return fnc.Integral(ax,bx,ay,by,az,bz,epsilon)/norm;
00825 }
00826