%
%---------------------------------------------------------------------  
% function [cavity] = FT_init_cavity(varargin)
% 
% Matlab function that creates a structure `cavity' storing 
% parameters of an optical cavity, consisting of a sequency of
% spaces and mirrors.
%
% Usage for example:
%  space=FT_init_cavity(s1,m2,s2,m3)
% with m2, m3 as mirror structures (see FT_init_mirror.m) and
% s1, s2 as space structures (see FT_init_space.m).
%
% The first component MUST be a space, followed by an alternating sequence
% of mirror and space components, with the last component being the
% input mirror.
%
% The structure has the following fields:
% L - round trip lenth
% Loss - optical loss
% F - Finesse
% FSR - free spectral range
% FWHM - Full with at half maximum
% ncomponents - number of space-mirror pairs
% mirror - array of mirror components
% space - array of space components
%
% Part of the SimTools package
% Andreas Freise, 26.12.2009 afreise@googlemail.com
%---------------------------------------------------------------------  
%

% Description: Creates "cavity" structure for storing parameters of cavity
% Keywords: init, cavity, structure, parameter


function [cavity] = FT_init_cavity(varargin)

  %%% refactor code so that FSR, FHWM etc are computed in dedicated fucntions
  
   baseid='init_cavity';
   clight=299792458.0;
   
   %%% initialise `mirror' structure
   cavity.L=0;
   cavity.Loss=0;
   cavity.F=0;
   cavity.FSR=0;
   cavity.FWHM=0;
   cavity.ncomponents=0;
     
   if (nargin==0)
     msgid=[baseid,':checkinarg'];
     result=sprintf(['No components given.\n']);
     error(msgid,result);
   end
     
   if (mod(nargin,2))
     msgid=[baseid,':checkinarg'];
     result=sprintf(['There must be an even number of spaces + mirrors.\n']);
     error(msgid,result);
   end
   
   cavity.ncomponents=nargin/2;
     
   for q=1:cavity.ncomponents
     tmp=cell2mat(varargin(2*(q-1)+1));
     if (isfield(tmp,'space'))
       cavity.space(q)=tmp;
     else
       msgid=[baseid,':checkinarg'];
       result=sprintf(['Wrong component: ', varargin{2*(q-1)+1}, '.\n Usage FT_init_cavity(space, mirror, space, mirror,...)\n']);
       error(msgid,result);
     end

     tmp=cell2mat(varargin(2*q));
     if (isfield(tmp,'mirror'))
       cavity.mirror(q)=tmp;
     else
       msgid=[baseid,':checkinarg'];
       result=sprintf(['Wrong component: ', varargin{2*q}, '.\n Usage FT_init_cavity(space, mirror, space, mirror,...)\n']);
       error(msgid,result);
     end
   end

   % compute cavity parameters
   power=1;
   for q=1:cavity.ncomponents-1 
     power=power*(1-(cavity.mirror(q).Loss+cavity.mirror(q).T));
   end
   virtual_mirror_T=1-power;
   power=power*(1-(cavity.mirror(cavity.ncomponents).Loss+cavity.mirror(cavity.ncomponents).T));
   cavity.Loss=1-power;
     
   for q=1:cavity.ncomponents
     cavity.L=cavity.L+cavity.space(q).L*cavity.space(q).n;
   end
     
   cavity.FSR=clight/cavity.L;
   
   r1=cavity.mirror(cavity.ncomponents).r;
   r2=sqrt(1-virtual_mirror_T);
   
   cavity.FWHM= 2/pi * cavity.FSR  * asin((1-r1*r2)/(2*sqrt(r1*r2)));
   
   cavity.F=cavity.FSR/cavity.FWHM;
   
   return