ROBAST logo
/******************************************************************************
 * Copyright (C) 2006-, Akira Okumura                                         *
 * All rights reserved.                                                       *
 *****************************************************************************/

///////////////////////////////////////////////////////////////////////////////
//
// ASellmeierFormula
//
// Sellmeier's formula for calculation of refractive index
// See http://en.wikipedia.org/wiki/Sellmeier_equation
//
///////////////////////////////////////////////////////////////////////////////

#include "ASellmeierFormula.h"
#include "AOpticsManager.h"
#include "TMath.h"
#include "TROOT.h"

ClassImp(ASellmeierFormula);

ASellmeierFormula::ASellmeierFormula() : ARefractiveIndex() {}

//______________________________________________________________________________
ASellmeierFormula::ASellmeierFormula(Double_t B1, Double_t B2, Double_t B3,
                                     Double_t C1, Double_t C2, Double_t C3)
    : ARefractiveIndex() {
  // n^2(lambda) = 1 + B1*lamda^2/(lamda^2 - C1) + B2*lamda^2/(lamda^2 - C2) +
  // B3*lamda^2/(lamda^2 - C3) where lambda is measured in (um)
  fPar[0] = B1;
  fPar[1] = B2;
  fPar[2] = B3;
  fPar[3] = C1;
  fPar[4] = C2;
  fPar[5] = C3;
}

//______________________________________________________________________________
ASellmeierFormula::ASellmeierFormula(const Double_t* p) {
  for (Int_t i = 0; i < 6; i++) {
    fPar[i] = p[i];
  }
}

//______________________________________________________________________________
Double_t ASellmeierFormula::GetRefractiveIndex(Double_t lambda) const {
  // Calculate the refractive index at wavelength = lambda (m)
  // Use AOpticsManager::m() to get the unit length in (m)
  lambda /= AOpticsManager::um();  // Convert (nm) to (um)
  Double_t lambda2 = lambda * lambda;
  return TMath::Sqrt(1 + fPar[0] * lambda2 / (lambda2 - fPar[3]) +
                     fPar[1] * lambda2 / (lambda2 - fPar[4]) +
                     fPar[2] * lambda2 / (lambda2 - fPar[5]));
}

//______________________________________________________________________________
TF1* ASellmeierFormula::FitData(TGraph* graph, const char* tf1name,
                                Option_t* option) {
  // Fit the given TGraph with the Sellmeier formula. If function "tf1name"
  // already exists, the existing function is used, otherwise, new TF1 is
  // created. The unit of wavelength must be (m) using AOpticsManager::m().
  if (graph == 0 or tf1name == 0) {
    return 0;
  }

  TF1* f = (TF1*)gROOT->GetFunction(tf1name);
  if (!f) {
    Double_t xmin = TMath::MinElement(graph->GetN(), graph->GetX());
    Double_t xmax = TMath::MaxElement(graph->GetN(), graph->GetX());

    f = MakeGraph(tf1name, xmin, xmax);
  }

  f->SetParLimits(0, 0, 1e1);
  f->SetParLimits(1, 0, 1e0);
  f->SetParLimits(2, 0, 1e1);
  f->SetParLimits(3, 0, 1e-1);
  f->SetParLimits(4, 0, 1e-1);
  f->SetParLimits(5, 0, 1e3);

  // Initialize with typical values
  f->SetParameter(0, 1.);
  f->SetParameter(1, .2);
  f->SetParameter(2, 1.);
  f->SetParameter(3, 5e-3);
  f->SetParameter(4, 2e-2);
  f->SetParameter(5, 1e2);

  graph->Fit(f, option);
  for (Int_t i = 0; i < (Int_t)(sizeof(fPar) / sizeof(Double_t)); i++) {
    fPar[i] = f->GetParameter(i);
  }

  return f;
}

//______________________________________________________________________________
TF1* ASellmeierFormula::MakeGraph(const char* tf1name, Double_t xmin,
                                  Double_t xmax) {
  Double_t um = AOpticsManager::um();
  TF1* f = new TF1(tf1name,
                   Form("sqrt(1 + [0]*(x/%f)**2/((x/%f)**2 - [3]) + "
                        "[1]*(x/%f)**2/((x/%f)**2 - [4]) + "
                        "[2]*(x/%f)**2/((x/%f)**2 - [5]))",
                        um, um, um, um, um, um),
                   xmin, xmax);

  for (Int_t i = 0; i < (Int_t)(sizeof(fPar) / sizeof(Double_t)); i++) {
    f->SetParameter(i, fPar[i]);
  }
  f->SetParNames("B1", "B2", "B3", "C1", "C2", "C3");

  return f;
}
 ASellmeierFormula.cxx:1
 ASellmeierFormula.cxx:2
 ASellmeierFormula.cxx:3
 ASellmeierFormula.cxx:4
 ASellmeierFormula.cxx:5
 ASellmeierFormula.cxx:6
 ASellmeierFormula.cxx:7
 ASellmeierFormula.cxx:8
 ASellmeierFormula.cxx:9
 ASellmeierFormula.cxx:10
 ASellmeierFormula.cxx:11
 ASellmeierFormula.cxx:12
 ASellmeierFormula.cxx:13
 ASellmeierFormula.cxx:14
 ASellmeierFormula.cxx:15
 ASellmeierFormula.cxx:16
 ASellmeierFormula.cxx:17
 ASellmeierFormula.cxx:18
 ASellmeierFormula.cxx:19
 ASellmeierFormula.cxx:20
 ASellmeierFormula.cxx:21
 ASellmeierFormula.cxx:22
 ASellmeierFormula.cxx:23
 ASellmeierFormula.cxx:24
 ASellmeierFormula.cxx:25
 ASellmeierFormula.cxx:26
 ASellmeierFormula.cxx:27
 ASellmeierFormula.cxx:28
 ASellmeierFormula.cxx:29
 ASellmeierFormula.cxx:30
 ASellmeierFormula.cxx:31
 ASellmeierFormula.cxx:32
 ASellmeierFormula.cxx:33
 ASellmeierFormula.cxx:34
 ASellmeierFormula.cxx:35
 ASellmeierFormula.cxx:36
 ASellmeierFormula.cxx:37
 ASellmeierFormula.cxx:38
 ASellmeierFormula.cxx:39
 ASellmeierFormula.cxx:40
 ASellmeierFormula.cxx:41
 ASellmeierFormula.cxx:42
 ASellmeierFormula.cxx:43
 ASellmeierFormula.cxx:44
 ASellmeierFormula.cxx:45
 ASellmeierFormula.cxx:46
 ASellmeierFormula.cxx:47
 ASellmeierFormula.cxx:48
 ASellmeierFormula.cxx:49
 ASellmeierFormula.cxx:50
 ASellmeierFormula.cxx:51
 ASellmeierFormula.cxx:52
 ASellmeierFormula.cxx:53
 ASellmeierFormula.cxx:54
 ASellmeierFormula.cxx:55
 ASellmeierFormula.cxx:56
 ASellmeierFormula.cxx:57
 ASellmeierFormula.cxx:58
 ASellmeierFormula.cxx:59
 ASellmeierFormula.cxx:60
 ASellmeierFormula.cxx:61
 ASellmeierFormula.cxx:62
 ASellmeierFormula.cxx:63
 ASellmeierFormula.cxx:64
 ASellmeierFormula.cxx:65
 ASellmeierFormula.cxx:66
 ASellmeierFormula.cxx:67
 ASellmeierFormula.cxx:68
 ASellmeierFormula.cxx:69
 ASellmeierFormula.cxx:70
 ASellmeierFormula.cxx:71
 ASellmeierFormula.cxx:72
 ASellmeierFormula.cxx:73
 ASellmeierFormula.cxx:74
 ASellmeierFormula.cxx:75
 ASellmeierFormula.cxx:76
 ASellmeierFormula.cxx:77
 ASellmeierFormula.cxx:78
 ASellmeierFormula.cxx:79
 ASellmeierFormula.cxx:80
 ASellmeierFormula.cxx:81
 ASellmeierFormula.cxx:82
 ASellmeierFormula.cxx:83
 ASellmeierFormula.cxx:84
 ASellmeierFormula.cxx:85
 ASellmeierFormula.cxx:86
 ASellmeierFormula.cxx:87
 ASellmeierFormula.cxx:88
 ASellmeierFormula.cxx:89
 ASellmeierFormula.cxx:90
 ASellmeierFormula.cxx:91
 ASellmeierFormula.cxx:92
 ASellmeierFormula.cxx:93
 ASellmeierFormula.cxx:94
 ASellmeierFormula.cxx:95
 ASellmeierFormula.cxx:96
 ASellmeierFormula.cxx:97
 ASellmeierFormula.cxx:98
 ASellmeierFormula.cxx:99
 ASellmeierFormula.cxx:100
 ASellmeierFormula.cxx:101
 ASellmeierFormula.cxx:102
 ASellmeierFormula.cxx:103
 ASellmeierFormula.cxx:104
 ASellmeierFormula.cxx:105
 ASellmeierFormula.cxx:106
 ASellmeierFormula.cxx:107
 ASellmeierFormula.cxx:108
 ASellmeierFormula.cxx:109
 ASellmeierFormula.cxx:110
 ASellmeierFormula.cxx:111
 ASellmeierFormula.cxx:112
 ASellmeierFormula.cxx:113
 ASellmeierFormula.cxx:114