// Author: M.A. Kagarlis
// Written: 15.12.98
// Revised: 17.10.00 by R. Holzmann
// Utilities Class Header

#ifndef _PUTILS_H_
#define _PUTILS_H_

#include "TRandom3.h"
#include "TMath.h"
using namespace std;
#include <iostream>
#include <cstdlib>
#include "TH1.h"
#include "PKinematics.h"
#include "PStaticData.h"


//#define SEED 65539   
// set to 0 for random initialization of seed at startup
// (this initializes TRandom3 with systime (but only a
// granularity of 1 second)

//This is the new default (IF 20.09.2009)
#define SEED 0

#define PLUTOVERSION_FOR_FAIR 1

class PUtilsREngine;
PUtilsREngine &fPUtilsREngine();
PUtilsREngine *makePUtilsREngine();


class PUtilsREngine : public TObject {
    
 public:
    PUtilsREngine ();
  
    Double_t sampleFlat() {
	// Samples uniformly between 0 and 1
	return rnd->Rndm();
    }
    
    Double_t sampleGaus(Double_t c, Double_t s) {
	// Samples from a Gaussian distribution
	return rnd->Gaus(c,s);
    }
    
    Int_t samplePoisson(Double_t mean) {
	// Samples from a Poisson distribution
	return rnd->Poisson(mean);
    }

    Int_t sampleBinomial(Int_t ntot, Float_t prob) {
	// Samples from a binomial distribution
	return rnd->Binomial(ntot,prob);
    }
    
    Double_t sampleBW(Double_t c, Double_t g) {
	// Samples from a Breit Wigner distribution
	if (g == 0.) return c;
	return (c+0.5*g*TMath::Tan((2.0*rnd->Rndm()-1.0)*TMath::Pi()*0.5));
    }
    
    void SetSeed(UInt_t s);

    Double_t lambda(double M, double m1, double m2) {
	return PKinematics::lambda(M, m1, m2);
    }
    
    Double_t pcms2(double M, double m1, double m2) {
	return PKinematics::pcms2(M, m1, m2);
    }
    
    Double_t pcms(double M, double m1, double m2) {
	// cm momentum for the decay of M to m1 and m2
	return PKinematics::pcms(M, m1, m2);
    }


 private:
    
    TRandom3 *rnd;
    
    ClassDef(PUtilsREngine, 0) //Pluto Utilities Class (random wrapper)
};


class PUtils : public TObject {

 public:
  PUtils() { 
      cout << "seed: " << SEED << endl;
      SetSeed(SEED); 
  }
  // create former behaviour

  static void dsort(Double_t *, int);
  // Sort in ascending order the first (int) entries of the array (Double_t *).
  // Adapted from Ref 1

  static void isort(int *i, int n) {
      // Sort in ascending order the first (int) entries of the array (int *).

      //BUGBUG: Quickersort is unstable
      //see example:
      //Int_t a[3]={8,9,9};
      //PUtils::isort(a,3);
      
      //workaround: add very small number
      
    Double_t x[n];

    for (int j=0; j<n; ++j) 
	x[j] = ((Double_t)i[j]) + ((Double_t)j)*0.00001;
    dsort(x, n);
    for (int j=0; j<n; ++j) 
	i[j] = (int)x[j];
  }

  static Double_t sampleFlat() {
    // Samples uniformly between 0 and 1
    return makePUtilsREngine()->sampleFlat();
  }

  static Double_t sampleGaus(Double_t c, Double_t s) {
    // Samples from a Gaussian distribution
    return makePUtilsREngine()->sampleGaus(c, s);
  }

  static int samplePoisson(Double_t mean) {
    // Samples from a Poisson distribution
    return makePUtilsREngine()->samplePoisson(mean);
  }

  static Int_t sampleBinomial(Int_t ntot, Float_t prob) {
      // Samples from a binomial distribution
    return makePUtilsREngine()->sampleBinomial(ntot, prob);
  }

  static Double_t sampleBW(Double_t c, Double_t g) {
      // Samples from a Breit Wigner distribution
      return makePUtilsREngine()->sampleBW(c, g);
  }

  static Double_t cgc(const int &, const int &, const int &,
		      const int &, const int &);
  // Clebsch-Gordan coefficients (arguments are 2 x j or m)
  
  static Double_t s3j(const Double_t &, const Double_t &, const Double_t &,
		      const Double_t &, const Double_t &, Double_t m3 = 0.);
  // 3j-symbol, related to Clebsch-Gordan coefficient
  
  static Double_t racah(const int &, const int &, const int &,
			const int &, const int &, const int &);
  // Racah coefficients (arguments are 2 x j or m)
  
  static Double_t s6j(const Double_t &, const Double_t &, const Double_t &,
		      const Double_t &, const Double_t &, const Double_t &);
  // 6j-symbol, related to Racah coefficient

  static Int_t FindIndex(Int_t n, Double_t *a, Double_t r);
  
  static void SetSeed(UInt_t s) { makePUtilsREngine()->SetSeed(s); }

  static Bool_t Tokenize(const char *options, const char *delimiter, char **array, int *size);
  static void remove_spaces(char **partc);
  static Int_t remove_brackets(char **partc, char a, char b);
  static Bool_t ValidVariableName(const char *name, unsigned int len = 0);
  static Bool_t IsInt(const char *name);
  static char *NewString(const char *var) {
      char *newvar = new char[strlen(var)+1];
      sprintf(newvar, "%s", var);
      return newvar;
  };
  
  static void correct_histo(TH1 *histo);
  static void correct(TH1 *histo);

 private:

  static Double_t phasef(const int &n) { return 1.- 2.*(abs(n)%2); }
  // (-1)**n

  static Double_t j123(const int &, const int &, const int &);
  // used by racah


  ClassDef(PUtils, 0) //Pluto Utilities Class
};



#endif // _PUTILS_H_

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