00001 // @(#)root/hist:$Id: TF12.cxx 20882 2007-11-19 11:31:26Z rdm $ 00002 // Author: Rene Brun 05/04/2003 00003 00004 /************************************************************************* 00005 * Copyright (C) 1995-2003, Rene Brun and Fons Rademakers. * 00006 * All rights reserved. * 00007 * * 00008 * For the licensing terms see $ROOTSYS/LICENSE. * 00009 * For the list of contributors see $ROOTSYS/README/CREDITS. * 00010 *************************************************************************/ 00011 00012 #include "TF12.h" 00013 #include "TH1.h" 00014 #include "TVirtualPad.h" 00015 00016 ClassImp(TF12) 00017 00018 //______________________________________________________________________________ 00019 // 00020 // a projection of a TF2 along X or Y 00021 // has the same behaviour as a TF1 00022 // 00023 // Example of a function 00024 // 00025 // TF2 *f2 = new TF2("f2","sin(x)*sin(y)/(x*y)",0,5,0,5); 00026 // TF12 *f12 = new TF12("f12",f2,0.1,"y"); 00027 // f12->Draw(); 00028 00029 00030 //______________________________________________________________________________ 00031 TF12::TF12(): TF1() 00032 { 00033 // TF12 default constructor 00034 00035 fCase = 0; 00036 fF2 = 0; 00037 fXY = 0; 00038 } 00039 00040 00041 //______________________________________________________________________________ 00042 TF12::TF12(const char *name, TF2 *f2, Double_t xy, Option_t *option) 00043 :TF1(name,"x",0,0) 00044 { 00045 // TF12 normal constructor. 00046 // Create a TF12 (special TF1) from a projection of a TF2 00047 // for a fix value of Y if option="X" or X if option="Y" 00048 // This value may be changed at any time via TF12::SetXY(xy) 00049 00050 SetName(name); 00051 fF2 = f2; 00052 TString opt=option; 00053 opt.ToLower(); 00054 if (!f2) { 00055 Error("TF12","Pointer to TF2 is null"); 00056 return; 00057 } 00058 SetXY(xy); 00059 if (opt.Contains("y")) { 00060 fXmin = f2->GetYmin(); 00061 fXmax = f2->GetYmax(); 00062 fCase = 1; 00063 } else { 00064 fXmin = f2->GetXmin(); 00065 fXmax = f2->GetXmax(); 00066 fCase = 0; 00067 } 00068 } 00069 00070 00071 //______________________________________________________________________________ 00072 TF12::~TF12() 00073 { 00074 // F2 default destructor. 00075 } 00076 00077 00078 //______________________________________________________________________________ 00079 TF12::TF12(const TF12 &f12) : TF1(f12) 00080 { 00081 // Copy constructor. 00082 00083 ((TF12&)f12).Copy(*this); 00084 } 00085 00086 00087 //______________________________________________________________________________ 00088 void TF12::Copy(TObject &obj) const 00089 { 00090 // Copy this F2 to a new F2. 00091 00092 TF1::Copy(obj); 00093 ((TF12&)obj).fXY = fXY; 00094 ((TF12&)obj).fCase = fCase; 00095 ((TF12&)obj).fF2 = fF2; 00096 } 00097 00098 00099 //______________________________________________________________________________ 00100 TF1 *TF12::DrawCopy(Option_t *option) const 00101 { 00102 // Draw a copy of this function with its current attributes. 00103 // 00104 // This function MUST be used instead of Draw when you want to draw 00105 // the same function with different parameters settings in the same canvas. 00106 // 00107 // Possible option values are: 00108 // "SAME" superimpose on top of existing picture 00109 // "L" connect all computed points with a straight line 00110 // "C" connect all computed points with a smooth curve. 00111 // 00112 // Note that the default value is "F". Therefore to draw on top 00113 // of an existing picture, specify option "SL" 00114 00115 TF12 *newf2 = new TF12(); 00116 Copy(*newf2); 00117 newf2->AppendPad(option); 00118 newf2->SetBit(kCanDelete); 00119 return newf2; 00120 } 00121 00122 00123 //______________________________________________________________________________ 00124 Double_t TF12::Eval(Double_t x, Double_t /*y*/, Double_t /*z*/, Double_t /*t*/) const 00125 { 00126 // Evaluate this formula 00127 // 00128 // Computes the value of the referenced TF2 for a fix value of X or Y 00129 00130 if (!fF2) return 0; 00131 if (fCase == 0) { 00132 return fF2->Eval(x,fXY,0); 00133 } else { 00134 return fF2->Eval(fXY,x,0); 00135 } 00136 } 00137 00138 00139 //______________________________________________________________________________ 00140 Double_t TF12::EvalPar(const Double_t *x, const Double_t *params) 00141 { 00142 // Evaluate this function at point x[0] 00143 // x[0] is the value along X if fCase =0, the value along Y if fCase=1 00144 // if params is non null, the array will be used instead of the internal TF2 00145 // parameters 00146 00147 if (!fF2) return 0; 00148 Double_t xx[2]; 00149 if (fCase == 0) { 00150 xx[0] = x[0]; 00151 xx[1] = fXY; 00152 } else { 00153 xx[0] = fXY; 00154 xx[1] = x[0]; 00155 } 00156 fF2->InitArgs(xx,params); 00157 return fF2->EvalPar(xx,params); 00158 } 00159 00160 00161 //______________________________________________________________________________ 00162 void TF12::SavePrimitive(ostream & /*out*/, Option_t * /*option*/ /*= ""*/) 00163 { 00164 // Save primitive as a C++ statement(s) on output stream out 00165 00166 Error("SavePrimitive","Function not yet implemented"); 00167 } 00168 00169 00170 //______________________________________________________________________________ 00171 void TF12::SetXY(Double_t xy) 00172 { 00173 // set the value of the constant for the TF2 00174 // constant in X when projecting along Y 00175 // constant in Y when projecting along X 00176 // The function title is set to include the value of the constant 00177 // The current pad is updated 00178 00179 fXY = xy; 00180 if (!fF2) return; 00181 if (fCase == 0) SetTitle(Form("%s (y=%g)",fF2->GetTitle(),xy)); 00182 else SetTitle(Form("%s (x=%g)",fF2->GetTitle(),xy)); 00183 if (fHistogram) fHistogram->SetTitle(GetTitle()); 00184 if (gPad) gPad->Modified(); 00185 }