// @(#)root/hist:$Id$
// Author: Rene Brun   05/04/2003

/*************************************************************************
 * Copyright (C) 1995-2003, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TF12.h"
#include "TH1.h"
#include "TVirtualPad.h"

ClassImp(TF12)

//______________________________________________________________________________
//
// a projection of a TF2 along X or Y
// has the same behaviour as a TF1
//
//      Example of a function
//
//   TF2 *f2 = new TF2("f2","sin(x)*sin(y)/(x*y)",0,5,0,5);
//   TF12 *f12 = new TF12("f12",f2,0.1,"y");
//   f12->Draw();


//______________________________________________________________________________
TF12::TF12(): TF1()
{
   // TF12 default constructor

   fCase = 0;
   fF2   = 0;
   fXY   = 0;
}


//______________________________________________________________________________
TF12::TF12(const char *name, TF2 *f2, Double_t xy, Option_t *option)
      :TF1(name,"x",0,0)
{
   // TF12 normal constructor.
   //   Create a TF12 (special TF1) from a projection of a TF2
   //   for a fix value of Y if option="X" or X if option="Y"
   // This value may be changed at any time via TF12::SetXY(xy)

   SetName(name);
   fF2 = f2;
   TString opt=option;
   opt.ToLower();
   if (!f2) {
      Error("TF12","Pointer to TF2 is null");
      return;
   }
   SetXY(xy);
   if (opt.Contains("y")) {
      fXmin = f2->GetYmin();
      fXmax = f2->GetYmax();
      fCase = 1;
   } else {
      fXmin = f2->GetXmin();
      fXmax = f2->GetXmax();
      fCase = 0;
   }
}


//______________________________________________________________________________
TF12::~TF12()
{
   // F2 default destructor.
}


//______________________________________________________________________________
TF12::TF12(const TF12 &f12) : TF1(f12)
{
   // Copy constructor.

   ((TF12&)f12).Copy(*this);
}


//______________________________________________________________________________
void TF12::Copy(TObject &obj) const
{
   // Copy this F2 to a new F2.

   TF1::Copy(obj);
   ((TF12&)obj).fXY      = fXY;
   ((TF12&)obj).fCase    = fCase;
   ((TF12&)obj).fF2      = fF2;
}


//______________________________________________________________________________
TF1 *TF12::DrawCopy(Option_t *option) const
{
   // Draw a copy of this function with its current attributes.
   //
   //  This function MUST be used instead of Draw when you want to draw
   //  the same function with different parameters settings in the same canvas.
   //
   // Possible option values are:
   //   "SAME"  superimpose on top of existing picture
   //   "L"     connect all computed points with a straight line
   //   "C"     connect all computed points with a smooth curve.
   //
   // Note that the default value is "F". Therefore to draw on top
   // of an existing picture, specify option "SL"

   TF12 *newf2 = new TF12();
   Copy(*newf2);
   newf2->AppendPad(option);
   newf2->SetBit(kCanDelete);
   return newf2;
}


//______________________________________________________________________________
Double_t TF12::Eval(Double_t x, Double_t /*y*/, Double_t /*z*/, Double_t /*t*/) const
{
   // Evaluate this formula
   //
   //   Computes the value of the referenced TF2 for a fix value of X or Y

   if (!fF2) return 0;
   if (fCase == 0) {
      return fF2->Eval(x,fXY,0);
   } else {
      return fF2->Eval(fXY,x,0);
   }
}


//______________________________________________________________________________
Double_t TF12::EvalPar(const Double_t *x, const Double_t *params)
{
   // Evaluate this function at point x[0]
   //   x[0] is the value along X if fCase =0, the value along Y if fCase=1
   // if params is non null, the array will be used instead of the internal TF2
   // parameters

   if (!fF2) return 0;
   Double_t xx[2];
   if (fCase == 0) {
      xx[0] = x[0];
      xx[1] = fXY;
   } else {
      xx[0] = fXY;
      xx[1] = x[0];
   }
   fF2->InitArgs(xx,params);
   return fF2->EvalPar(xx,params);
}


//______________________________________________________________________________
void TF12::SavePrimitive(std::ostream & /*out*/, Option_t * /*option*/ /*= ""*/)
{
   // Save primitive as a C++ statement(s) on output stream out

   Error("SavePrimitive","Function not yet implemented");
}


//______________________________________________________________________________
void TF12::SetXY(Double_t xy)
{
   // set the value of the constant for the TF2
   //   constant in X when projecting along Y
   //   constant in Y when projecting along X
   //  The function title is set to include the value of the constant
   //  The current pad is updated

   fXY = xy;
   if (!fF2) return;
   if (fCase == 0) SetTitle(Form("%s (y=%g)",fF2->GetTitle(),xy));
   else            SetTitle(Form("%s (x=%g)",fF2->GetTitle(),xy));
   if (fHistogram) fHistogram->SetTitle(GetTitle());
   if (gPad) gPad->Modified();
}
 TF12.cxx:1
 TF12.cxx:2
 TF12.cxx:3
 TF12.cxx:4
 TF12.cxx:5
 TF12.cxx:6
 TF12.cxx:7
 TF12.cxx:8
 TF12.cxx:9
 TF12.cxx:10
 TF12.cxx:11
 TF12.cxx:12
 TF12.cxx:13
 TF12.cxx:14
 TF12.cxx:15
 TF12.cxx:16
 TF12.cxx:17
 TF12.cxx:18
 TF12.cxx:19
 TF12.cxx:20
 TF12.cxx:21
 TF12.cxx:22
 TF12.cxx:23
 TF12.cxx:24
 TF12.cxx:25
 TF12.cxx:26
 TF12.cxx:27
 TF12.cxx:28
 TF12.cxx:29
 TF12.cxx:30
 TF12.cxx:31
 TF12.cxx:32
 TF12.cxx:33
 TF12.cxx:34
 TF12.cxx:35
 TF12.cxx:36
 TF12.cxx:37
 TF12.cxx:38
 TF12.cxx:39
 TF12.cxx:40
 TF12.cxx:41
 TF12.cxx:42
 TF12.cxx:43
 TF12.cxx:44
 TF12.cxx:45
 TF12.cxx:46
 TF12.cxx:47
 TF12.cxx:48
 TF12.cxx:49
 TF12.cxx:50
 TF12.cxx:51
 TF12.cxx:52
 TF12.cxx:53
 TF12.cxx:54
 TF12.cxx:55
 TF12.cxx:56
 TF12.cxx:57
 TF12.cxx:58
 TF12.cxx:59
 TF12.cxx:60
 TF12.cxx:61
 TF12.cxx:62
 TF12.cxx:63
 TF12.cxx:64
 TF12.cxx:65
 TF12.cxx:66
 TF12.cxx:67
 TF12.cxx:68
 TF12.cxx:69
 TF12.cxx:70
 TF12.cxx:71
 TF12.cxx:72
 TF12.cxx:73
 TF12.cxx:74
 TF12.cxx:75
 TF12.cxx:76
 TF12.cxx:77
 TF12.cxx:78
 TF12.cxx:79
 TF12.cxx:80
 TF12.cxx:81
 TF12.cxx:82
 TF12.cxx:83
 TF12.cxx:84
 TF12.cxx:85
 TF12.cxx:86
 TF12.cxx:87
 TF12.cxx:88
 TF12.cxx:89
 TF12.cxx:90
 TF12.cxx:91
 TF12.cxx:92
 TF12.cxx:93
 TF12.cxx:94
 TF12.cxx:95
 TF12.cxx:96
 TF12.cxx:97
 TF12.cxx:98
 TF12.cxx:99
 TF12.cxx:100
 TF12.cxx:101
 TF12.cxx:102
 TF12.cxx:103
 TF12.cxx:104
 TF12.cxx:105
 TF12.cxx:106
 TF12.cxx:107
 TF12.cxx:108
 TF12.cxx:109
 TF12.cxx:110
 TF12.cxx:111
 TF12.cxx:112
 TF12.cxx:113
 TF12.cxx:114
 TF12.cxx:115
 TF12.cxx:116
 TF12.cxx:117
 TF12.cxx:118
 TF12.cxx:119
 TF12.cxx:120
 TF12.cxx:121
 TF12.cxx:122
 TF12.cxx:123
 TF12.cxx:124
 TF12.cxx:125
 TF12.cxx:126
 TF12.cxx:127
 TF12.cxx:128
 TF12.cxx:129
 TF12.cxx:130
 TF12.cxx:131
 TF12.cxx:132
 TF12.cxx:133
 TF12.cxx:134
 TF12.cxx:135
 TF12.cxx:136
 TF12.cxx:137
 TF12.cxx:138
 TF12.cxx:139
 TF12.cxx:140
 TF12.cxx:141
 TF12.cxx:142
 TF12.cxx:143
 TF12.cxx:144
 TF12.cxx:145
 TF12.cxx:146
 TF12.cxx:147
 TF12.cxx:148
 TF12.cxx:149
 TF12.cxx:150
 TF12.cxx:151
 TF12.cxx:152
 TF12.cxx:153
 TF12.cxx:154
 TF12.cxx:155
 TF12.cxx:156
 TF12.cxx:157
 TF12.cxx:158
 TF12.cxx:159
 TF12.cxx:160
 TF12.cxx:161
 TF12.cxx:162
 TF12.cxx:163
 TF12.cxx:164
 TF12.cxx:165
 TF12.cxx:166
 TF12.cxx:167
 TF12.cxx:168
 TF12.cxx:169
 TF12.cxx:170
 TF12.cxx:171
 TF12.cxx:172
 TF12.cxx:173
 TF12.cxx:174
 TF12.cxx:175
 TF12.cxx:176
 TF12.cxx:177
 TF12.cxx:178
 TF12.cxx:179
 TF12.cxx:180
 TF12.cxx:181
 TF12.cxx:182
 TF12.cxx:183
 TF12.cxx:184
 TF12.cxx:185