% Create an Optickle model of Advanced LIGO
%
% opt = optLIGO2
 
% lPRC = lPR + (lIX + lIY) / 2;
% lSRC = lSR + (lIX + lIY) / 2;
% lasy = lIX - lIY;

% dTune - the SRCL detuning distance
%
% The detuning phase used in the Bench is the round trip phase:
%   ifo.Optics.SRM.Tunephase = 2 * k * dTune
% where k = 2 * pi / lambda
%
% Buonanno & Chen gr-qc/0102012 use the one-way phase, given by:
%   Chen.Tunephase = pi / 2 - k * dTune
%  which is similar to the total offset on the SR set with:
%   opt = setPosOffset(opt, nSR, opt.lambda / 4 + dTune);
%  since
%   Chen.Tunephase = k * (lambda / 4 + dTune)
%
%  The lambda / 4 is there to get close to the resonance, and 
%  dTune to set the detuning frequency.  For the LIGO2 detector,
%  the detuning frequency is roughly given by:
%    detuneFreq =?= tan(k * (lambda / 4 + dTune)) * (-13 Hz)
%
%  (lPR - lSR) is set to resonate the upper 180 MHz SB.  Using
%  -dTune instead resonates the lower 180 MHz SB, which destroys
%  the detectors RSE behaviour.

function opt = optLIGO2

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Detector Parameters

  % detector geometry (distances in meters)
  Ri = 2076;		% radius of curvature of input mirrors (IX and IY)
  Re = 2076;		% radius of curvature of end mirrors (EX and EY)
  Rr = 1442;		% radius of curvature of recycling mirrors (PR and SR)

  lPR = 3.5;		% distance from PR to BS
  lSR = 3.412;		% distance from SR to BS
  dTune = 1e-8;		% SR micro detuning (see note)
  
  lIX = 5.106;		% distance from BS to IX
  lIY = 4.63;		% distance from BS to IY

  lEX = 3995.14;	% length of the X arm
  lEY = 3995.15;        % length of the Y arm
  
  % mechanical parameters
  wI = 2 * pi * 0.5;		% resonance frequency of input mirror (rad/s)
  mI = 40;			% mass of input mirror (kg)
  wE = 2 * pi * 0.5;		% resonance frequency of end mirror (rad/s)
  mE = 40;			% mass of end mirror (kg)

  % input beam parameters
  Pin = 125;			% input power (W)
  f1 = 9e6;			% first modulation frequency
  f2 = 20 * f1;			% second modulation frequency
  g1 = 0.1;			% first modulation depth
  g2 = 0.1;			% second modulation depth
  Nmod1 = 1;			% first modulation order
  Nmod2 = 1;			% second modulation order

  % construct modulation vectors
  n1 = (-Nmod1:Nmod1)';
  n2 = (-Nmod2:Nmod2)';
  N1 = length(n1);
  N2 = length(n2);
  vMod = zeros(N1 * N2, 2);
  for n = 1:N1
    nn = N1 * (n - 1) + (1:N2);
    ff = n1(n) * f1 + n2 * f2;
    aa = sqrt(Pin) * bessel(n1(n), g1) * bessel(n2, g2);
    vMod(nn, :) = [ff, aa];
  end
  vMod = sortrows(vMod, 1);
  
  % create an empty model
  opt = Optickle;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Add a Field Source

  % make the modulation vectors and add a source
  [opt, nSrc] = addSource(opt, 'Source', vMod);

  % add an AM modulator
  [opt, nAM] = addModulator(opt, 'AM', 1);

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Add Mirrors
  % The argument list for addMirror is:
  % [opt, sn] = addMirror(opt, name, aio, Chr, Thr, Lhr, Rar)
  % type "help addMirror" for more information
  
  % add recycling mirrors
  [opt, nPR] = addMirror(opt, 'PR', 0, 1 / Rr, 0.07, 10e-6);
  [opt, nSR] = addMirror(opt, 'SR', 0, 1 / Rr, 0.07, 10e-6);

  % add beam-splitter
  [opt, nBS] = addBeamSplitter(opt, 'BS', 45, 0, 0.5, 10e-6, 50e-6);

  % add arm mirrors (a.k.a. test-masses)
  [opt, nIX] = addMirror(opt, 'IX', 0, 1 / Ri, 0.005, 1e-6, 25e-6);
  [opt, nIY] = addMirror(opt, 'IY', 0, 1 / Ri, 0.005, 1e-6, 45e-6);
  [opt, nEX] = addMirror(opt, 'EX', 0, 1 / Re, 10e-6, 1e-6);
  [opt, nEY] = addMirror(opt, 'EY', 0, 1 / Re, 10e-6, 1e-6);

  % set mechanical transfer-functions for the test-masses (m/N)
  dampedRes = [-0.1 + 1i, -0.1 - 1i];

  opt = setMechTF(opt, nIX, zpk([], wI * dampedRes, 1 / mI));
  opt = setMechTF(opt, nEX, zpk([], wE * dampedRes, 1 / mE));
  opt = setMechTF(opt, nIY, zpk([], wI * dampedRes, 1 / mI));
  opt = setMechTF(opt, nEY, zpk([], wE * dampedRes, 1 / mE));

  % set position offsets for SR
  opt = setPosOffset(opt, nSR, opt.lambda / 4 + dTune);
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Add Field Sinks (needed by the probes)

  [opt, nREFL] = addSink(opt, 'REFL');
  [opt, nAS] = addSink(opt, 'AS');
  [opt, nPOX] = addSink(opt, 'POX');
  [opt, nPOY] = addSink(opt, 'POY');
  [opt, nTRX] = addSink(opt, 'TRX');
  [opt, nTRY] = addSink(opt, 'TRY');

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Add Links

  % link input to PR
  opt = addLink(opt, nSrc, 'out', nAM, 'in', 1);
  opt = addLink(opt, nAM, 'out', nPR, 'bk', 10);

  % link BS A-side inputs to PR and SR front outputs
  opt = addLink(opt, nPR, 'fr', nBS, 'frA', lPR);
  opt = addLink(opt, nSR, 'fr', nBS, 'bkA', lSR);

  % link BS A-side outputs to and IX and IY back inputs
  opt = addLink(opt, nBS, 'frA', nIY, 'bk', lIY);
  opt = addLink(opt, nBS, 'bkA', nIX, 'bk', lIX);

  % link BS B-side inputs to and IX and IY back outputs
  opt = addLink(opt, nIY, 'bk', nBS, 'frB', lIY);
  opt = addLink(opt, nIX, 'bk', nBS, 'bkB', lIX);

  % link BS B-side outputs to PR and SR front inputs
  opt = addLink(opt, nBS, 'frB', nPR, 'fr', lPR);
  opt = addLink(opt, nBS, 'bkB', nSR, 'fr', lSR);

  % link the arms
  opt = addLink(opt, nIX, 'fr', nEX, 'fr', lEX);
  opt = addLink(opt, nEX, 'fr', nIX, 'fr', lEX);

  opt = addLink(opt, nIY, 'fr', nEY, 'fr', lEY);
  opt = addLink(opt, nEY, 'fr', nIY, 'fr', lEY);

  % link the detectors
  opt = addLink(opt, nPR, 'bk', nREFL, 'in', 5);
  opt = addLink(opt, nSR, 'bk', nAS, 'in', 5);
  opt = addLink(opt, nIX, 'po', nPOX, 'in', 5);
  opt = addLink(opt, nIY, 'po', nPOY, 'in', 5);
  opt = addLink(opt, nEX, 'bk', nTRX, 'in', 5);
  opt = addLink(opt, nEY, 'bk', nTRY, 'in', 5);

  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Add Probes

  % double-demod sum (plus) and difference (minus) frequencies
  fp = f2 + f1;
  fm = f2 - f1;
  
  % REFL signals (reflected or symmetric port)
  %   REFL_I1 phase is set to maximize CARM
  %   REFL DD phases set for PRCL
  opt = addProbeAt(opt, 'REFL DC', nREFL, 'in',  0,   0);	% DC
  opt = addProbeAt(opt, 'REFL I1', nREFL, 'in', f1, -37);	% f1 demod I
  opt = addProbeAt(opt, 'REFL Q1', nREFL, 'in', f1,  53);	% f1 demod Q
  opt = addProbeAt(opt, 'REFL IM', nREFL, 'in', fm, -10);	% fm demod I
  opt = addProbeAt(opt, 'REFL QM', nREFL, 'in', fm,  80);	% fm demod Q
  opt = addProbeAt(opt, 'REFL IP', nREFL, 'in', fp,  92);	% fp demod I
  opt = addProbeAt(opt, 'REFL QP', nREFL, 'in', fp, 182);	% fp demod Q

  % AS signals (anti-symmetric port)
  %   AS_Q2 phase is set to maximize DARM above the optical spring
  %   AS_I2 phase is set 90 degrees away from AS_Q2
  %   AS DD phases set for MICH
  opt = addProbeAt(opt, 'AS DC', nAS, 'in',  0,   0);		% DC
  opt = addProbeAt(opt, 'AS I1', nAS, 'in', f1,   0);		% f1 demod I
  opt = addProbeAt(opt, 'AS Q1', nAS, 'in', f1,  90);		% f1 demod Q
  opt = addProbeAt(opt, 'AS IM', nAS, 'in', fm,   0);		% fm demod I
  opt = addProbeAt(opt, 'AS QM', nAS, 'in', fm,  90);		% fm demod Q
  opt = addProbeAt(opt, 'AS IP', nAS, 'in', fp,   0);		% fp demod I
  opt = addProbeAt(opt, 'AS QP', nAS, 'in', fp,  90);		% fp demod Q
  opt = addProbeAt(opt, 'AS I2', nAS, 'in', f2,  27);		% f2 demod Q
  opt = addProbeAt(opt, 'AS Q2', nAS, 'in', f2, 117);		% f2 demod Q

  % POX signals (IX pick-off)
  %   POX DD phases set for SRCL
  opt = addProbeAt(opt, 'POX DC', nPOX, 'in',  0,   0);		% DC
  opt = addProbeAt(opt, 'POX I1', nPOX, 'in', f1,   0);		% f1 demod I
  opt = addProbeAt(opt, 'POX Q1', nPOX, 'in', f1,  90);		% f1 demod Q
  opt = addProbeAt(opt, 'POX IM', nPOX, 'in', fm, -90);		% fm demod I
  opt = addProbeAt(opt, 'POX QM', nPOX, 'in', fm,   0);		% fm demod Q
  opt = addProbeAt(opt, 'POX IP', nPOX, 'in', fp, -10);		% fp demod I
  opt = addProbeAt(opt, 'POX QP', nPOX, 'in', fp,  80);		% fp demod Q

  % POY signals (IY pick-off)
  opt = addProbeAt(opt, 'POY DC', nPOY, 'in',  0,   0);		% DC
  opt = addProbeAt(opt, 'POY I1', nPOY, 'in', f1,   0);		% f1 demod I
  opt = addProbeAt(opt, 'POY Q1', nPOY, 'in', f1,  90);		% f1 demod Q

  % transmitted DC signals
  opt = addProbeAt(opt, 'TRX DC', nTRX, 'in', 0, 0);		% DC
  opt = addProbeAt(opt, 'TRY DC', nTRY, 'in', 0, 0);		% DC

  % temporary probe
  opt = addProbeAt(opt, 'TMP', nPR, 'bk', 0, 0);
