/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 * @(#)root/roofitcore:$Id$
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
 *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
// 
// BEGIN_HTML
// A RooEllipse is a two-dimensional ellipse that can be used to represent
// an error contour.
// END_HTML
//


#include "RooFit.h"

#include "RooEllipse.h"
#include "RooEllipse.h"
#include "TMath.h"
#include "RooMsgService.h"

#include "Riostream.h"
#include "TClass.h"
#include <math.h>
#include <assert.h>

using namespace std;

ClassImp(RooEllipse)



//_____________________________________________________________________________
RooEllipse::RooEllipse() 
{ 
  // Default constructor
}


//_____________________________________________________________________________
RooEllipse::~RooEllipse() 
{
  // Destructor
}


//_____________________________________________________________________________
RooEllipse::RooEllipse(const char *name, Double_t x1, Double_t x2, Double_t s1, Double_t s2, Double_t rho, Int_t points) 
{
  // Create a 2-dimensional ellipse centered at (x1,x2) that represents the confidence
  // level contour for a measurement with errors (s1,s2) and correlation coefficient rho.
  // The resulting curve is defined as the unique ellipse that passes through these points:
  //
  //   (x1+rho*s1,x2+s2) , (x1-rho*s1,x2-s2) , (x1+s1,x2+rho*s2) , (x1-s1,x2-rho*s2)
  //
  // and is described by the implicit equation:
  //
  //   x*x      2*rho*x*y      y*y
  //  -----  -  ---------  +  -----  =  1 - rho*rho
  //  s1*s1       s1*s2       s2*s2
  //
  // The input parameters s1,s2 must be > 0 and also |rho| <= 1.
  // The degenerate case |rho|=1 corresponds to a straight line and
  // is handled as a special case.

  SetName(name);
  SetTitle(name);

  if(s1 <= 0 || s2 <= 0) {
    coutE(InputArguments) << "RooEllipse::RooEllipse: bad parameter s1 or s2 < 0" << endl;
    return;
  }
  Double_t tmp= 1-rho*rho;
  if(tmp < 0) {
    coutE(InputArguments) << "RooEllipse::RooEllipse: bad parameter |rho| > 1" << endl;
    return;
  }

  if(tmp == 0) {
    // handle the degenerate case of |rho|=1
    SetPoint(0,x1-s1,x2-s2);
    SetPoint(1,x1+s1,x2+s2);
    setYAxisLimits(x2-s2,x2+s2);
  }
  else {
    Double_t r,psi,phi,u1,u2,xx1,xx2,dphi(2*TMath::Pi()/points);
    for(Int_t index= 0; index < points; index++) {
      phi= index*dphi;
      // adjust the angular spacing of the points for the aspect ratio
      psi= atan2(s2*sin(phi),s1*cos(phi));
      u1= cos(psi)/s1;
      u2= sin(psi)/s2;
      r= sqrt(tmp/(u1*u1 - 2*rho*u1*u2 + u2*u2));
      xx1= x1 + r*u1*s1;
      xx2= x2 + r*u2*s2;
      SetPoint(index, xx1, xx2);
      if(index == 0) {
	setYAxisLimits(xx2,xx2);
	// add an extra segment to close the curve
	SetPoint(points, xx1, xx2);
      }
      else {
	updateYAxisLimits(xx2);
      }
    }
  }
}



//_____________________________________________________________________________
void RooEllipse::printName(ostream& os) const 
{
  // Print name of ellipse on ostream
  os << GetName() ;
}


//_____________________________________________________________________________
void RooEllipse::printTitle(ostream& os) const 
{
  // Print title of ellipse on ostream
  os << GetName() ;
}


//_____________________________________________________________________________
void RooEllipse::printClassName(ostream& os) const 
{
  // Print class name of ellipse on ostream
  os << IsA()->GetName() ;
}


//_____________________________________________________________________________
void RooEllipse::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
{
  // Print detailed multi line information on ellipse on ostreamx
  RooPlotable::printMultiline(os,contents,verbose,indent);
  for(Int_t index=0; index < fNpoints; index++) {
    os << indent << "Point [" << index << "] is at (" << fX[index] << "," << fY[index] << ")" << endl;
  }
}
 RooEllipse.cxx:1
 RooEllipse.cxx:2
 RooEllipse.cxx:3
 RooEllipse.cxx:4
 RooEllipse.cxx:5
 RooEllipse.cxx:6
 RooEllipse.cxx:7
 RooEllipse.cxx:8
 RooEllipse.cxx:9
 RooEllipse.cxx:10
 RooEllipse.cxx:11
 RooEllipse.cxx:12
 RooEllipse.cxx:13
 RooEllipse.cxx:14
 RooEllipse.cxx:15
 RooEllipse.cxx:16
 RooEllipse.cxx:17
 RooEllipse.cxx:18
 RooEllipse.cxx:19
 RooEllipse.cxx:20
 RooEllipse.cxx:21
 RooEllipse.cxx:22
 RooEllipse.cxx:23
 RooEllipse.cxx:24
 RooEllipse.cxx:25
 RooEllipse.cxx:26
 RooEllipse.cxx:27
 RooEllipse.cxx:28
 RooEllipse.cxx:29
 RooEllipse.cxx:30
 RooEllipse.cxx:31
 RooEllipse.cxx:32
 RooEllipse.cxx:33
 RooEllipse.cxx:34
 RooEllipse.cxx:35
 RooEllipse.cxx:36
 RooEllipse.cxx:37
 RooEllipse.cxx:38
 RooEllipse.cxx:39
 RooEllipse.cxx:40
 RooEllipse.cxx:41
 RooEllipse.cxx:42
 RooEllipse.cxx:43
 RooEllipse.cxx:44
 RooEllipse.cxx:45
 RooEllipse.cxx:46
 RooEllipse.cxx:47
 RooEllipse.cxx:48
 RooEllipse.cxx:49
 RooEllipse.cxx:50
 RooEllipse.cxx:51
 RooEllipse.cxx:52
 RooEllipse.cxx:53
 RooEllipse.cxx:54
 RooEllipse.cxx:55
 RooEllipse.cxx:56
 RooEllipse.cxx:57
 RooEllipse.cxx:58
 RooEllipse.cxx:59
 RooEllipse.cxx:60
 RooEllipse.cxx:61
 RooEllipse.cxx:62
 RooEllipse.cxx:63
 RooEllipse.cxx:64
 RooEllipse.cxx:65
 RooEllipse.cxx:66
 RooEllipse.cxx:67
 RooEllipse.cxx:68
 RooEllipse.cxx:69
 RooEllipse.cxx:70
 RooEllipse.cxx:71
 RooEllipse.cxx:72
 RooEllipse.cxx:73
 RooEllipse.cxx:74
 RooEllipse.cxx:75
 RooEllipse.cxx:76
 RooEllipse.cxx:77
 RooEllipse.cxx:78
 RooEllipse.cxx:79
 RooEllipse.cxx:80
 RooEllipse.cxx:81
 RooEllipse.cxx:82
 RooEllipse.cxx:83
 RooEllipse.cxx:84
 RooEllipse.cxx:85
 RooEllipse.cxx:86
 RooEllipse.cxx:87
 RooEllipse.cxx:88
 RooEllipse.cxx:89
 RooEllipse.cxx:90
 RooEllipse.cxx:91
 RooEllipse.cxx:92
 RooEllipse.cxx:93
 RooEllipse.cxx:94
 RooEllipse.cxx:95
 RooEllipse.cxx:96
 RooEllipse.cxx:97
 RooEllipse.cxx:98
 RooEllipse.cxx:99
 RooEllipse.cxx:100
 RooEllipse.cxx:101
 RooEllipse.cxx:102
 RooEllipse.cxx:103
 RooEllipse.cxx:104
 RooEllipse.cxx:105
 RooEllipse.cxx:106
 RooEllipse.cxx:107
 RooEllipse.cxx:108
 RooEllipse.cxx:109
 RooEllipse.cxx:110
 RooEllipse.cxx:111
 RooEllipse.cxx:112
 RooEllipse.cxx:113
 RooEllipse.cxx:114
 RooEllipse.cxx:115
 RooEllipse.cxx:116
 RooEllipse.cxx:117
 RooEllipse.cxx:118
 RooEllipse.cxx:119
 RooEllipse.cxx:120
 RooEllipse.cxx:121
 RooEllipse.cxx:122
 RooEllipse.cxx:123
 RooEllipse.cxx:124
 RooEllipse.cxx:125
 RooEllipse.cxx:126
 RooEllipse.cxx:127
 RooEllipse.cxx:128
 RooEllipse.cxx:129
 RooEllipse.cxx:130
 RooEllipse.cxx:131
 RooEllipse.cxx:132
 RooEllipse.cxx:133
 RooEllipse.cxx:134
 RooEllipse.cxx:135
 RooEllipse.cxx:136
 RooEllipse.cxx:137
 RooEllipse.cxx:138
 RooEllipse.cxx:139
 RooEllipse.cxx:140
 RooEllipse.cxx:141
 RooEllipse.cxx:142
 RooEllipse.cxx:143
 RooEllipse.cxx:144
 RooEllipse.cxx:145
 RooEllipse.cxx:146
 RooEllipse.cxx:147
 RooEllipse.cxx:148
 RooEllipse.cxx:149
 RooEllipse.cxx:150
 RooEllipse.cxx:151
 RooEllipse.cxx:152
 RooEllipse.cxx:153
 RooEllipse.cxx:154