initial version
This commit is contained in:
commit
8e602ca6bf
26 changed files with 3306 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
venv
|
556
AnalyticLC/AnalyticLC.m
Normal file
556
AnalyticLC/AnalyticLC.m
Normal file
|
@ -0,0 +1,556 @@
|
|||
function [LC,RV_o_r,Y_o_r,Z_o_r,O] = AnalyticLC(P,Tmid0,ror,aor,mu,ex0,ey0,I0,Omega0,t,u1,u2,varargin)
|
||||
% AnalyticLC: generate an analytic light-curve, and optionally RV and astrometry data, from a set of initial (free) orbital
|
||||
% elements.
|
||||
|
||||
% The full logic of AnalyticLC and the model derivation are described in the paper "An Accurate 3D
|
||||
% Analytic Model for Exoplanetary Photometry, Radial Velocity and
|
||||
% Astrometry" by Judkovsky, Ofir and Aharonson (2021), please cite this
|
||||
% paper upon usage. Model and enjoy :)
|
||||
|
||||
%Inputs:
|
||||
% P - vector of orbital periods,
|
||||
% Tmid0 - vector of refernce times-of-mid-transit,
|
||||
% ror - vector of planets/star radii ratio,
|
||||
% aor - semi-major-axis in stellar radius of innermost planet,
|
||||
% mu - vector of planets/star mass ratio,
|
||||
% ex0 and ey0 - vectors of initial FREE eccentricities components of planets
|
||||
% I0 = vector of initial FREE inclinations (radians),
|
||||
% Omega0 - vector of initial FREE longiudes of ascending nodes (radians),
|
||||
% t - time vector to calculate light curve model at,
|
||||
% u1,u2 - limb darkening coefficients.
|
||||
% Eccentricity components and inclination are defined with respect to the system plane, and NOT with respect to the sky plane. The system plane is
|
||||
% defined such that the x axis points from the star to the observer, and y
|
||||
% is on the sky plane such that the inclinations are measured with respect
|
||||
% to the xy plane. Transits are expected to occur for small
|
||||
% values of sin(I0)*sin(Omega), which is equal to the cosine of the
|
||||
% sky-plane inclination.
|
||||
% The time units are to the user's choice, and should be consistent in all
|
||||
% parameters (t,P,Tmid etc.).
|
||||
|
||||
% Examples for usage:
|
||||
% LC = AnalyticLC(P,Tmid0,ror,aor,mu,ex0,ey0,I0,Omega0,t,u1,u2,'OutputList','');
|
||||
% LC = AnalyticLC(P,Tmid0,ror,aor,mu,ex0,ey0,I0,Omega0,t,u1,u2,'BinningTime',BinningTime,'OutputList','all');
|
||||
% [LC,RV_o_r,Y_o_r,Z_o_r,O] = AnalyticLC(P,Tmid0,ror,aor,mu,ex0,ey0,I0,Omega0,t,u1,u2,'tRV',tRV);
|
||||
|
||||
|
||||
BinningTime = range(t); %rough time steps for performing the binning to construct the light curve. A value per cadence type is allowed, or a single value for all cadence types. For cadences shorter the the binning time, no binning will be introcued.
|
||||
CadenceType = ones(size(t)); %cadence type should label each time stamp. values must be consecutive natural integers: 1, 2,...
|
||||
MaxTTV = inf(1,length(P)); %maximal TTV amplitude allowed for each planet. A value per planet is allowed, or a single value for all planets.
|
||||
tRV = []; %times to evaluate radial velocity at
|
||||
ExtraIters = 0; %extra iterations for the TTV calculations
|
||||
OrdersAll = []; %orders for calculating the forced elements; see function ForcedElements1.
|
||||
OutputList = 'all'; %a list of parameters to give as an additional output in the structure O. Upon "all", a default list is returned.
|
||||
Calculate3PlanetsCrossTerms = 0; %Should the 3-planets cross terms be incorporated.
|
||||
MaxPower = 4; %maximal (joint) power of eccentricities and inclinations used in the expansion
|
||||
OrbitalElementsAsCellArrays = 0; %an option to return (within the structure O) cell arrays including the orbital elements variations. Each such cell array will contain one cell per planet.
|
||||
|
||||
%read optional inputs for the parameters above
|
||||
for i=1:2:numel(varargin)
|
||||
switch lower(varargin{i})
|
||||
case 'binningtime'
|
||||
BinningTime=varargin{i+1};
|
||||
case 'cadencetype'
|
||||
CadenceType=varargin{i+1};
|
||||
case 'maxttv'
|
||||
MaxTTV=varargin{i+1};
|
||||
case 'trv'
|
||||
tRV=vertical(varargin{i+1});
|
||||
case 'extraiters'
|
||||
ExtraIters=(varargin{i+1});
|
||||
case 'ordersall'
|
||||
OrdersAll=(varargin{i+1});
|
||||
case 'maxpower'
|
||||
MaxPower=(varargin{i+1});
|
||||
case 'outputlist'
|
||||
OutputList=(varargin{i+1});
|
||||
case 'calculate3planetscrossterms'
|
||||
Calculate3PlanetsCrossTerms=(varargin{i+1});
|
||||
case 'orbitalelementsascellarrays'
|
||||
OrbitalElementsAsCellArrays=(varargin{i+1});
|
||||
otherwise
|
||||
fprintf('WARNING: Parameter %s is unknown and therefore ignored.\n',varargin{i})
|
||||
end
|
||||
end
|
||||
|
||||
%number of planets and number of time stamps and number of cadence types
|
||||
Npl = length(P);
|
||||
Nt = length(t);
|
||||
Ncad = max(CadenceType);
|
||||
Nrv = length(tRV);
|
||||
|
||||
%prepare a time axis of one point per transit for the calculation of the
|
||||
%orbital dynamics
|
||||
[tT,BeginIdx,EndIdx,Ntr] = DynamicsTimeAxis(P,Tmid0,t);
|
||||
NtT = length(tT);
|
||||
|
||||
%make sure that each cadence type is characterized by its own binning time
|
||||
if length(BinningTime)==1, BinningTime = BinningTime*ones(1,Ncad); end
|
||||
|
||||
%make sure that each planet receives a maximal TTV value
|
||||
if length(MaxTTV)==1, MaxTTV = MaxTTV*ones(1,Npl); end
|
||||
|
||||
%calculate mean motion
|
||||
n = 2*pi./P;
|
||||
|
||||
%calculate time relative to first mid-transit
|
||||
t0_T = vertical(tT)-Tmid0;
|
||||
t0_RV = vertical(tRV)-Tmid0;
|
||||
|
||||
%calculate mean longitudes
|
||||
Lambda_T = t0_T.*repmat(n,NtT,1);
|
||||
|
||||
%calculate period ratio
|
||||
PeriodRatio = P(2:end)./P(1);
|
||||
|
||||
%calculate semi-major axis of outer planets, deduced from Period Ratio
|
||||
if length(aor)==1
|
||||
aor(2:Npl) = aor(1)*PeriodRatio.^(2/3).*(((1+mu(2:end))/(1+mu(1))).^(1/3));
|
||||
end
|
||||
|
||||
%calculate the secular motion of the eccentricities and inclinations
|
||||
[A,B] = SecularInteractionsMatrix(n,mu);
|
||||
free_e_0 = ex0+1i*ey0;
|
||||
free_I_0 = I0.*exp(1i.*Omega0);
|
||||
free_e_T = Vector1stOrderDE(A,free_e_0.',horizontal(tT)-t(1));
|
||||
free_I_T = Vector1stOrderDE(B,free_I_0.',horizontal(tT)-t(1));
|
||||
|
||||
%calculate the near-resonant interactions and their resulting TTV's
|
||||
[dz,dLambda,du,da_oa,dTheta,zT,uT,TTV] = ResonantInteractions2(P,mu,Lambda_T,free_e_T,free_I_T,tT,BeginIdx,EndIdx,ExtraIters,OrdersAll,Calculate3PlanetsCrossTerms,MaxPower);
|
||||
|
||||
|
||||
%check if the solution is invalid. Reasons for invalidity:
|
||||
%if the TTV's do not exceed the maximal value, and if it does - return nans
|
||||
%innermost planet hits star: a(1-e)<Rs
|
||||
%e>1 are invalid
|
||||
if any( max(abs(TTV))>MaxTTV ) || any((1-abs(zT(:,1))).*aor(1)<1) || any(abs(zT(:))>1)
|
||||
LC = nan(size(t));
|
||||
O = [];
|
||||
RV_o_r = nan(size(tRV));
|
||||
Y_o_r = nan(size(tRV));
|
||||
Z_o_r = nan(size(tRV));
|
||||
return
|
||||
end
|
||||
|
||||
%translate the orbital elements to transits properties
|
||||
CalcDurations = nargout>=5;
|
||||
[D,D1,Tau,Tau1,w,w1,d,d1,b,b1,AssociatedTmid,AssociatedInd,dbdt,b0] = TransitsProperties(Nt,Npl,BeginIdx,EndIdx,t,tT,TTV,P,n,da_oa,aor,zT,uT,ror,CalcDurations);
|
||||
|
||||
%construct the light-curve for each planet
|
||||
AllLC = GenerateLightCurve(Nt,Npl,Ncad,CadenceType,t,BinningTime,AssociatedTmid,w,d,b,ror,u1,u2);
|
||||
|
||||
%sum all planets light-curves to get the total light curve. The possibility of mutual transits is neglected.
|
||||
LC = sum(AllLC,2)-Npl+1;
|
||||
|
||||
%calculate the forced elements of the RV time stamps if the output requires doing so
|
||||
if Nrv>0
|
||||
|
||||
Lambda_RV = t0_RV.*repmat(n,Nrv,1);
|
||||
|
||||
%secular interactions at the RV time stamps
|
||||
free_e_RV = Vector1stOrderDE(A,free_e_0.',horizontal(tRV));
|
||||
free_I_RV = Vector1stOrderDE(B,free_I_0.',horizontal(tRV));
|
||||
|
||||
%near-resonant interactions at the RV time stamps
|
||||
[forced_e_RV,dLambda_RV,forced_I_RV] = ForcedElements1(P,Lambda_RV,mu,free_e_RV,free_I_RV,OrdersAll,MaxPower);
|
||||
|
||||
zRV = free_e_RV+forced_e_RV;
|
||||
uRV = free_I_RV+forced_I_RV;
|
||||
Lambda_RV = Lambda_RV+dLambda_RV;
|
||||
|
||||
%calculate the radial velocity/astrometry model
|
||||
[RV_o_r,Y_o_r,Z_o_r] = CalcRV(Lambda_RV,zRV,uRV,mu,aor,n,nargout>2);
|
||||
|
||||
else
|
||||
|
||||
forced_e_RV = zeros(Nrv,Npl);
|
||||
Lambda_RV = zeros(Nrv,Npl);
|
||||
free_e_RV = zeros(Nrv,Npl);
|
||||
free_I_RV = zeros(Nrv,Npl);
|
||||
forced_I_RV = zeros(Nrv,Npl);
|
||||
zRV = free_e_RV+forced_e_RV;
|
||||
uRV = free_I_RV+forced_I_RV;
|
||||
RV_o_r = [];
|
||||
Y_o_r = [];
|
||||
Z_o_r = [];
|
||||
|
||||
end
|
||||
|
||||
%if required, give more outputs then just the light-curve and the RV
|
||||
%values. These outputs are specified in the optinal input variable
|
||||
%OutputList.
|
||||
if nargout>4
|
||||
|
||||
%upon the value of "all", set OutputList to include a default list of
|
||||
%variables
|
||||
if strcmp(OutputList,'all')
|
||||
OutputList = {'tT','tRV','zT','zRV','uT','uRV','D','Tau','w','d','b','AssociatedTmid','AssociatedInd','AllLC','TmidActualCell','free_e_T','free_I_T','free_e_RV','free_I_RV','TTVCell','dzCell','duCell','dLambdaCell','zfreeCell','dbdt','b0','Lambda_T','P','BeginIdx','EndIdx','Ntr'}; %a list of parameters to give as an additional output, if required
|
||||
OrbitalElementsAsCellArrays = 1;
|
||||
end
|
||||
|
||||
%generate cell arrays for the orbital elements
|
||||
if OrbitalElementsAsCellArrays
|
||||
|
||||
TmidActualCell = cell(1,Npl);
|
||||
TTVCell = cell(1,Npl);
|
||||
dzCell = cell(1,Npl);
|
||||
duCell = cell(1,Npl);
|
||||
dLambdaCell = cell(1,Npl);
|
||||
zfreeCell = cell(1,Npl);
|
||||
ufreeCell = cell(1,Npl);
|
||||
da_oaCell = cell(1,Npl);
|
||||
|
||||
for j = 1:Npl
|
||||
TmidActualCell{j} = (tT(BeginIdx(j):EndIdx(j)))'+TTV(BeginIdx(j):EndIdx(j),j).';
|
||||
TTVCell{j} = TTV(BeginIdx(j):EndIdx(j),j).';
|
||||
dzCell{j} = dz(BeginIdx(j):EndIdx(j),j).';
|
||||
duCell{j} = du(BeginIdx(j):EndIdx(j),j).';
|
||||
dLambdaCell{j} = dLambda(BeginIdx(j):EndIdx(j),j).';
|
||||
zfreeCell{j} = free_e_T(BeginIdx(j):EndIdx(j),j).';
|
||||
ufreeCell{j} = free_I_T(BeginIdx(j):EndIdx(j),j).';
|
||||
da_oaCell{j} = da_oa(BeginIdx(j):EndIdx(j),j).';
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
%move all variables specified in OutputList to a single structure
|
||||
%variable O
|
||||
for j = 1:length(OutputList)
|
||||
try
|
||||
eval(['O.',OutputList{j},'=',OutputList{j},';']);
|
||||
catch
|
||||
fprintf('Requested variable %s does not exist \n',OutputList{j});
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
function [AA,BB] = SecularInteractionsMatrix(n,mu)
|
||||
%calculate the interaction matrix that will describe the equation dz/dt=Az
|
||||
%where z is a vector of the complex eccentricities and for the similar
|
||||
%equation for I*exp(i*Omega) using the matrix BB
|
||||
|
||||
Npl = length(n);
|
||||
|
||||
AA = ones(Npl);
|
||||
BB = ones(Npl);
|
||||
|
||||
for j1 = 1:Npl
|
||||
for j2 = j1:Npl
|
||||
|
||||
if j1~=j2
|
||||
alph = (n(j2)/n(j1))^(2/3)*((1+mu(j1))/(1+mu(j2)))^(1/3);
|
||||
A1 = LaplaceCoeffs(alph,1/2,1);
|
||||
|
||||
|
||||
DA1 = LaplaceCoeffs(alph,1/2,1,1);
|
||||
D2A1 = LaplaceCoeffs(alph,1/2,1,2);
|
||||
|
||||
f10 = 0.5*A1-0.5*alph*DA1-0.25*alph^2*D2A1; %calculate f2 and f10 for j=0
|
||||
AA(j1,j2) = n(j1)*mu(j2)/(1+mu(j1))*alph*f10;
|
||||
AA(j2,j1) = n(j2)*mu(j1)/(1+mu(j2))*f10;
|
||||
|
||||
B1 = LaplaceCoeffs(alph,3/2,1);
|
||||
f14 = alph*B1;
|
||||
BB(j1,j2) = 0.25*n(j1)*mu(j2)/(1+mu(j1))*alph*f14;
|
||||
BB(j2,j1) = 0.25*n(j2)*mu(j1)/(1+mu(j2))*f14;
|
||||
|
||||
else
|
||||
alphvec = zeros(1,Npl);
|
||||
alphvec(1:j1) = (n(1:j1)/n(j1)).^(-2/3).*((1+mu(1:j1))./(1+mu(j1))).^(1/3);
|
||||
alphvec(j1+1:end) = (n(j1+1:end)/n(j1)).^(2/3).*((1+mu(j1+1:end))./(1+mu(j1))).^(-1/3);
|
||||
DA0 = LaplaceCoeffs(alphvec,1/2,0,1);
|
||||
D2A0 = LaplaceCoeffs(alphvec,1/2,0,2);
|
||||
f2 = 0.25*alphvec.*DA0+1/8*alphvec.^2.*D2A0;
|
||||
InnerVec = mu(1:(j1-1))/(1+mu(j1)).*f2(1:(j1-1));
|
||||
OuterVec = alphvec((j1+1):end).*mu((j1+1):end)/(1+mu(j1)).*f2((j1+1):end);
|
||||
|
||||
AA(j1,j2) = n(j1)*2*(sum(InnerVec)+sum(OuterVec));
|
||||
|
||||
B1 = LaplaceCoeffs(alphvec,3/2,1);
|
||||
f3 = -0.5*alphvec.*B1;
|
||||
InnerVec = mu(1:(j1-1)).*f3(1:(j1-1));
|
||||
OuterVec = alphvec((j1+1):end).*mu((j1+1):end).*f3((j1+1):end);
|
||||
BB(j1,j2) = 0.25*n(j1)*2*(sum(InnerVec)+sum(OuterVec));
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
AA = 1i*AA;
|
||||
BB = 1i*BB;
|
||||
|
||||
|
||||
function [TmidActualCell,TTVCell,dzCell,duCell,da_oaCell,dLambdaCell,zfreeCell] = ResonantInteractions1(P,mu,Lambda,free_all,free_i,tT,BeginIdx,EndIdx,ExtraIters,OrdersAll,Calculate3PlanetsCrossTerms,MaxPower)
|
||||
%calculate the near-resonant interactions arising from the appropriate
|
||||
%disturbing function terms
|
||||
|
||||
%calculate mean motions
|
||||
n = 2*pi./P;
|
||||
|
||||
% [dz,dLambda] = ForcedEccentricitiesAndMeanLongitudes1(P,Lambda,mu,free_all,OrdersAll);
|
||||
% [dz,dLambda] = ForcedElements(P,Lambda,mu,free_all,free_i,OrdersAll);
|
||||
[dz,dLambda,du,da_oa] = ForcedElements1(P,Lambda,mu,free_all,free_i,OrdersAll,MaxPower);
|
||||
|
||||
if Calculate3PlanetsCrossTerms
|
||||
dLambda = dLambda+ForcedMeanLongitudes3PlanetsCrossTerms(P,Lambda,mu,free_all);
|
||||
end
|
||||
|
||||
for jj = 1:ExtraIters
|
||||
% [dz,dLambda] = ForcedEccentricitiesAndMeanLongitudes1(P,Lambda+dLambda,mu,free_all+dz,OrdersAll);
|
||||
% [dz,dLambda] = ForcedElements(P,Lambda+dLambda,mu,free_all+dz,free_i,OrdersAll);
|
||||
[dz,dLambda,du,da_oa] = ForcedElements1(P,Lambda+dLambda,mu,free_all+dz,free_i+du,OrdersAll,MaxPower);
|
||||
|
||||
%add the 3-planets cross terms
|
||||
if Calculate3PlanetsCrossTerms
|
||||
dLambda = dLambda+ForcedMeanLongitudes3PlanetsCrossTerms(P,Lambda+dLambda,mu,free_all+dz);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
%calculate the total eccentricity for each nominal transit time
|
||||
z = free_all+dz;
|
||||
|
||||
%calculate the true longitude variations
|
||||
dTheta = dLambda+2*real((conj(z).*dLambda+conj(dz)/1i).*(1+5/4*conj(dz)));
|
||||
|
||||
%translate the variations in true longitude to variations in time via the
|
||||
%planetary angular velocity
|
||||
% TTV = -dTheta./repmat(n,size(z,1),1).*((1-abs(z).^2).^(3/2))./((1+real(z)).^2);
|
||||
TTV = -dTheta./(repmat(n,size(z,1),1).*(1-1.5*da_oa)).*((1-abs(z).^2).^(3/2))./((1+real(z)).^2); %taking into account the variations in n - 8.2.2021
|
||||
|
||||
Npl = length(P);
|
||||
%pre allocation
|
||||
TmidActualCell = cell(1,Npl);
|
||||
TTVCell = cell(1,Npl);
|
||||
dzCell = cell(1,Npl);
|
||||
dLambdaCell = cell(1,Npl);
|
||||
zfreeCell = cell(1,Npl);
|
||||
ufreeCell = cell(1,Npl);
|
||||
da_oaCell = cell(1,Npl);
|
||||
|
||||
|
||||
for j = 1:Npl
|
||||
% TmidActualCell{j} = TmidActualCell{j}+TTV(BeginIdx(j):EndIdx(j),j).';
|
||||
TmidActualCell{j} = (tT(BeginIdx(j):EndIdx(j)))'+TTV(BeginIdx(j):EndIdx(j),j).';
|
||||
TTVCell{j} = TTV(BeginIdx(j):EndIdx(j),j).';
|
||||
dzCell{j} = dz(BeginIdx(j):EndIdx(j),j).';
|
||||
duCell{j} = du(BeginIdx(j):EndIdx(j),j).';
|
||||
dLambdaCell{j} = dLambda(BeginIdx(j):EndIdx(j),j).';
|
||||
zfreeCell{j} = free_all(BeginIdx(j):EndIdx(j),j).';
|
||||
ufreeCell{j} = free_i(BeginIdx(j):EndIdx(j),j).';
|
||||
da_oaCell{j} = da_oa(BeginIdx(j):EndIdx(j),j).';
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
function [dz,dLambda,du,da_oa,dTheta,z,u,TTV] = ResonantInteractions2(P,mu,Lambda,free_all,free_i,tT,BeginIdx,EndIdx,ExtraIters,OrdersAll,Calculate3PlanetsCrossTerms,MaxPower)
|
||||
%calculate the forced orbital elements due to near-resonant interactions
|
||||
|
||||
n = 2*pi./P;
|
||||
|
||||
%pair-wise interactions
|
||||
[dz,dLambda,du,da_oa] = ForcedElements1(P,Lambda,mu,free_all,free_i,OrdersAll,MaxPower);
|
||||
|
||||
%triplets interactions
|
||||
if Calculate3PlanetsCrossTerms
|
||||
dLambda = dLambda+ForcedMeanLongitudes3PlanetsCrossTerms(P,Lambda,mu,free_all);
|
||||
end
|
||||
|
||||
%iterative solution to the equations, if desired
|
||||
for jj = 1:ExtraIters
|
||||
[dz,dLambda,du,da_oa] = ForcedElements1(P,Lambda+dLambda,mu,free_all+dz,free_i+du,OrdersAll,MaxPower);
|
||||
if Calculate3PlanetsCrossTerms
|
||||
dLambda = dLambda+ForcedMeanLongitudes3PlanetsCrossTerms(P,Lambda+dLambda,mu,free_all+dz);
|
||||
end
|
||||
end
|
||||
|
||||
%calculate the total eccentricity and inclination for each nominal transit time
|
||||
z = free_all+dz;
|
||||
u = free_i+du;
|
||||
|
||||
%translate to true longitude
|
||||
dTheta = dLambda+...
|
||||
2*real( conj(z).*dLambda+conj(dz)/1i )...
|
||||
+5/2*real( conj(z).^2.*dLambda+conj(z).*conj(dz).*conj(z)/1i )...
|
||||
+13/4*real( conj(z).^3.*dLambda+conj(z).^2.*conj(dz)/1i )...
|
||||
-1/4*real( (conj(z).*dz+z.*conj(dz)).*conj(z)/1i + z.*conj(z).*(conj(z).*dLambda+conj(dz)/1i) )...
|
||||
+103/24*real( conj(z).^4.*dLambda+conj(z).^3.*conj(dz)/1i )...
|
||||
-11/24*real( (conj(z).*dz+z.*conj(dz)).*conj(z).^2/1i + 2*z.*conj(z).*(conj(z).^2.*dLambda+conj(z).*conj(dz)/1i) );
|
||||
|
||||
%translate the variations in true longitude to variations in time using the
|
||||
%planetary angular velocity, taking into account the variations in n
|
||||
TTV = -dTheta./(repmat(n,size(z,1),1).*(1-1.5*da_oa)).*((1-abs(z).^2).^(3/2))./((1+real(z)).^2);
|
||||
|
||||
|
||||
|
||||
function [RV_o_r,Y_o_r,Z_o_r] = CalcRV(Lambda,z,u,mu,aor,n,CalcAstrometry)
|
||||
%calculate the RV at the desired time stamps
|
||||
|
||||
Nt = size(z,1);
|
||||
Pom = angle(z);
|
||||
Om = angle(u);
|
||||
e = abs(z);
|
||||
I = abs(u);
|
||||
om = Pom-Om;
|
||||
M = Lambda-Pom;
|
||||
|
||||
%calculate sin(f) and cos(f) to 2nd order in e, Solar System Dynamics eq.
|
||||
%2.84 and 2.85, page 40
|
||||
sinf = sin(M)+e.*sin(2*M)+e.^2.*(9/8*sin(3*M)-7/8*sin(M));
|
||||
cosf = cos(M)+e.*(cos(2*M)-1)+9/8*e.^2.*(cos(3*M)-cos(M));
|
||||
|
||||
%calculate the planets astrocentric velocities on the x axis
|
||||
Xdot_o_r = -repmat(n,Nt,1).*repmat(aor,Nt,1)./sqrt(1-e.^2).*((cos(om).*cos(Om)-sin(om).*sin(Om).*cos(I)).*sinf+(sin(om).*cos(Om)+cos(om).*sin(Om).*cos(I)).*(e+cosf));
|
||||
|
||||
%sum the astrocentric velocities along x axis to get stellar
|
||||
%barycentric velocity along x axis
|
||||
Xsdot_o_r = -sum(repmat(mu,Nt,1).*Xdot_o_r,2)/(1+sum(mu));
|
||||
|
||||
%the radial velocity is defined positive when the star moves away from the
|
||||
%observer, i.e. it is positive then Xsdot is negative and vice versa.
|
||||
RV_o_r = -Xsdot_o_r;
|
||||
|
||||
if CalcAstrometry
|
||||
%calculate the planets astrocentric positions on the y and z axes
|
||||
y = repmat(aor,Nt,1).*(1-e.^2)./(1+e.*cosf).*(sin(Om).*(cos(om).*cosf-sin(om).*sinf)+cos(Om).*cos(I).*(sin(om).*cosf+cos(om).*sinf));
|
||||
z = repmat(aor,Nt,1).*(1-e.^2)./(1+e.*cosf).*sin(I).*(sin(om).*cosf+cos(om).*sinf);
|
||||
|
||||
%sum the astrocentric positions along x axis to get the
|
||||
%stellar barycentric position along y and z axes
|
||||
Y_o_r = -sum(repmat(mu,Nt,1).*y,2)/(1+sum(mu));
|
||||
Z_o_r = -sum(repmat(mu,Nt,1).*z,2)/(1+sum(mu));
|
||||
else
|
||||
Y_o_r = [];
|
||||
Z_o_r = [];
|
||||
end
|
||||
|
||||
|
||||
function [td,BeginIdx,EndIdx,Ntr] = DynamicsTimeAxis(P,Tmid0,t)
|
||||
%generate a time axis that includes one point per transit event
|
||||
td = [];
|
||||
BeginIdx = zeros(1,length(P));
|
||||
EndIdx = zeros(1,length(P));
|
||||
Ntr = zeros(1,length(P));
|
||||
|
||||
for j = 1:length(P)
|
||||
|
||||
td0 = ((min(t)+mod(Tmid0(j)-min(t),P(j))):P(j):max(t))'; %new version, taking into account the possibility that Tmid0 is not within the range of t
|
||||
td = [td;td0];
|
||||
EndIdx(j) = length(td);
|
||||
if j==1, BeginIdx(j) = 1; else, BeginIdx(j) = EndIdx(j-1)+1; end
|
||||
Ntr(j) = length(td0);
|
||||
|
||||
end
|
||||
|
||||
|
||||
function [D,D1,Tau,Tau1,w,w1,d,d1,b,b1,AssociatedTmid,AssociatedInd,dbdt,b0] = TransitsProperties(Nt,Npl,BeginIdx,EndIdx,t,tT,TTV,P,n,da_oa,aor,zT,uT,ror,CalcDurations)
|
||||
%translate orbital elements at transits to transits parameters
|
||||
|
||||
%pre-allocate memory for transit properties: duration, ingress/egress,
|
||||
%angular velocity, planet-star separation, impact parameter.
|
||||
D = zeros(Nt,Npl);
|
||||
Tau = zeros(Nt,Npl);
|
||||
w = zeros(Nt,Npl);
|
||||
d = zeros(Nt,Npl);
|
||||
b = zeros(Nt,Npl);
|
||||
|
||||
D1 = cell(1,Npl);
|
||||
Tau1 = cell(1,Npl);
|
||||
w1 = cell(1,Npl);
|
||||
d1 = cell(1,Npl);
|
||||
b1 = cell(1,Npl);
|
||||
|
||||
AssociatedTmid = zeros(Nt,Npl);
|
||||
AssociatedInd = zeros(Nt,Npl);
|
||||
|
||||
dbdt = zeros(1,Npl);
|
||||
b0 = zeros(1,Npl);
|
||||
|
||||
|
||||
for j = 1:Npl
|
||||
|
||||
%indices
|
||||
Idx = BeginIdx(j):EndIdx(j);
|
||||
|
||||
%Associate time-of-mid-transit to each time stamp
|
||||
[AssociatedTmid(:,j),AssociatedInd(:,j)] = AssociateTmid(t,tT(Idx)+TTV(Idx,j),P(j));
|
||||
|
||||
%based on the presumed orbital elements as a function of time, calculate
|
||||
%the transit parameters - Duration, Ingress-Egress, angular velocity,
|
||||
%planet-star distance and impact parameter, and translate them to
|
||||
%light-curve
|
||||
if ~CalcDurations
|
||||
[w1{j},d1{j},b1{j}] = OrbitalElements2TransitParams(n(j)*(1-1.5*da_oa(Idx,j)),aor(j)*(1+da_oa(Idx,j)),real(zT(Idx,j)),imag(zT(Idx,j)),abs(uT(Idx,j)),angle(uT(Idx,j)),ror(j)); %treating I, Omega, aor, n as varying
|
||||
w(:,j) = w1{j}(AssociatedInd(:,j));
|
||||
d(:,j) = d1{j}(AssociatedInd(:,j));
|
||||
b(:,j) = b1{j}(AssociatedInd(:,j));
|
||||
|
||||
else
|
||||
[w1{j},d1{j},b1{j},D1{j},Tau1{j}] = OrbitalElements2TransitParams(n(j)*(1-1.5*da_oa(Idx,j)),aor(j)*(1+da_oa(Idx,j)),real(zT(Idx,j)),imag(zT(Idx,j)),abs(uT(Idx,j)),angle(uT(Idx,j)),ror(j)); %treating I, Omega, aor, n as varying
|
||||
w(:,j) = w1{j}(AssociatedInd(:,j));
|
||||
d(:,j) = d1{j}(AssociatedInd(:,j));
|
||||
b(:,j) = b1{j}(AssociatedInd(:,j));
|
||||
D(:,j) = D1{j}(AssociatedInd(:,j));
|
||||
Tau(:,j) = Tau1{j}(AssociatedInd(:,j));
|
||||
|
||||
end
|
||||
|
||||
%calculate db_dt and b0
|
||||
[dbdt(j),b0(j)] = fit_linear(tT(Idx),b1{j});
|
||||
|
||||
end
|
||||
|
||||
|
||||
function AllLC = GenerateLightCurve(Nt,Npl,Ncad,CadenceType,t,BinningTime,AssociatedTmid,w,d,b,ror,u1,u2)
|
||||
%construct the light-curve for each planet based on the transit properties
|
||||
%of each individual event
|
||||
|
||||
%pre-allocate
|
||||
AllLC = zeros(Nt,Npl);
|
||||
|
||||
%go over cadence types
|
||||
for jc = 1:Ncad
|
||||
|
||||
%index of data corresponding to the cadence type
|
||||
indc = CadenceType==jc;
|
||||
|
||||
%construct the integration vector based on half integration time and number
|
||||
%of neighbors on each side, which is a function of the binning time
|
||||
dtHalfIntegration = median(diff(t(indc)))/2;
|
||||
nNeighbors = round(dtHalfIntegration/BinningTime(jc));
|
||||
IntegrationStep = 2*dtHalfIntegration/(2*nNeighbors+1);
|
||||
IntegrationVector = -dtHalfIntegration+IntegrationStep*(0.5:(2*nNeighbors+1));
|
||||
NI = length(IntegrationVector);
|
||||
|
||||
%create a table of times around the original times
|
||||
t1 = vertical(t(indc))+IntegrationVector;
|
||||
|
||||
%go over planets one by one and generate planetary light curve
|
||||
for j = 1:Npl
|
||||
|
||||
%calculate the phase (for the specific cadence type jc)
|
||||
Phi = (t1-repmat(AssociatedTmid(indc,j),1,NI)).*repmat(w(indc,j),1,NI);
|
||||
|
||||
%calculate position on the sky with respect to the stellar center in units
|
||||
%of stellar radii and using its own w, a, b (for the specific cadence type jc)
|
||||
x = repmat(d(indc,j),1,NI).*sin(Phi);
|
||||
y = repmat(b(indc,j),1,NI).*cos(Phi);
|
||||
|
||||
%calculate the distance from stellar disk center. For phases larger than
|
||||
%0.25 null the Mandel-Agol model by using Rsky>1+Rp (for the specific cadence type jc)
|
||||
Rsky = sqrt(x.^2+y.^2);
|
||||
Rsky(abs(Phi)>0.25) = 5;
|
||||
|
||||
%calculate the instanteneous Mandel-Agol model for each time stamp
|
||||
%in the binned time vector (for the specific cadence type jc)
|
||||
%lc = occultquadVec(ror(j),Rsky(:),u1,u2);
|
||||
lc = MALookupTable(ror(j),Rsky(:),u1,u2);
|
||||
|
||||
%bin the light-curve by averaging, and assign in the relevant
|
||||
%positions of AllLC
|
||||
AllLC(indc,j) = mean(reshape(lc,size(Rsky)),2);
|
||||
|
||||
end
|
||||
|
||||
end
|
44
AnalyticLC/AssociateTmid.m
Normal file
44
AnalyticLC/AssociateTmid.m
Normal file
|
@ -0,0 +1,44 @@
|
|||
function [AssociatedTmid,AssociatedInd] = AssociateTmid(t,Tmid,P)
|
||||
% AssociateTmid: Associate a time-of-mid-transit to each time stamp t.
|
||||
|
||||
%Inputs: t - list of times
|
||||
% Tmid - list of times of mid transit
|
||||
% P - orbital period (optional input)
|
||||
|
||||
% Yair Judkovsky, 2.5.2020
|
||||
|
||||
%estimate the period if it is not given
|
||||
if ~exist('P','var')
|
||||
P = median(diff(Tmid));
|
||||
end
|
||||
|
||||
%transit indices - the first transit in the data is one, and going up
|
||||
try
|
||||
Tr_Ind = 1+round((Tmid-Tmid(1))/P);
|
||||
catch
|
||||
AssociatedTmid = nan(size(t));
|
||||
AssociatedInd = nan(size(t));
|
||||
return
|
||||
end
|
||||
|
||||
%associate an index of transit per time stamp. Any event before the first
|
||||
%Tmid will be associated with the first Tmid. Any event after the last Tmid
|
||||
%will be associated with the last Tmid.
|
||||
AssociatedInd = 1+round((t-Tmid(1))/P);
|
||||
AssociatedInd(AssociatedInd<1) = 1;
|
||||
AssociatedInd(AssociatedInd>Tr_Ind(end)) = Tr_Ind(end);
|
||||
|
||||
%Associated transit index
|
||||
try
|
||||
Tmid_Of_Tr_Ind = inf(1,max(Tr_Ind));
|
||||
Tmid_Of_Tr_Ind(Tr_Ind) = Tmid;
|
||||
%next few lines for debugging purposes
|
||||
catch
|
||||
save('debug_tmid');
|
||||
AssociatedTmid = nan(size(t));
|
||||
AssociatedInd = nan(size(t));
|
||||
return
|
||||
end
|
||||
|
||||
%associate a value of Tmid for each time stamp
|
||||
AssociatedTmid = Tmid_Of_Tr_Ind(AssociatedInd);
|
154
AnalyticLC/DisturbingFunctionMultiTermVariations.m
Normal file
154
AnalyticLC/DisturbingFunctionMultiTermVariations.m
Normal file
|
@ -0,0 +1,154 @@
|
|||
function [dLambda1,dLambda2,dz1,dz2,du1,du2,da_oa1,da_oa2] = DisturbingFunctionMultiTermVariations(n1,n2,alph,Lambda1,Lambda2,mu1,mu2,j,k,e1,e2,Pom1,Pom2,I1,I2,s1,s2,Om1,Om2,A,Ap,B,Bp,C,Cp,D,Dp,f,fE,fI,Df,DfE,DfI)
|
||||
|
||||
%get the number of time stamps and number of terms, in order to replicate
|
||||
%the vectors and perform the calculation once for all terms
|
||||
% Ntime = length(Lambda1);
|
||||
% Nterm = length(k);
|
||||
%
|
||||
%
|
||||
% Lambda1 = repmat(Lambda1,1,Nterm);
|
||||
% Lambda2 = repmat(Lambda2,1,Nterm);
|
||||
% e1 = repmat(e1,1,Nterm);
|
||||
% e2 = repmat(e2,1,Nterm);
|
||||
% Pom1 = repmat(Pom1,1,Nterm);
|
||||
% Pom2 = repmat(Pom2,1,Nterm);
|
||||
% I1 = repmat(I1,1,Nterm);
|
||||
% I2 = repmat(I2,1,Nterm);
|
||||
% s1 = repmat(s1,1,Nterm);
|
||||
% s2 = repmat(s2,1,Nterm);
|
||||
% Om1 = repmat(Om1,1,Nterm);
|
||||
% Om2 = repmat(Om2,1,Nterm);
|
||||
%
|
||||
% if length(j)==length(k)
|
||||
% j = repmat(j,Ntime,1);
|
||||
% end
|
||||
% k = repmat(k,Ntime,1);
|
||||
% A = repmat(A,Ntime,1);
|
||||
% Ap = repmat(Ap,Ntime,1);
|
||||
% B = repmat(B,Ntime,1);
|
||||
% Bp = repmat(Bp,Ntime,1);
|
||||
% C = repmat(C,Ntime,1);
|
||||
% Cp = repmat(Cp,Ntime,1);
|
||||
% D = repmat(D,Ntime,1);
|
||||
% Dp = repmat(Dp,Ntime,1);
|
||||
|
||||
f_inner = f+fE;
|
||||
f_outer = f+fI;
|
||||
Df_inner = Df+DfE;
|
||||
Df_outer = Df+DfI;
|
||||
|
||||
% f = repmat(f,Ntime,1);
|
||||
% fE = repmat(fE,Ntime,1);
|
||||
% fI = repmat(fI,Ntime,1);
|
||||
% Df = repmat(Df,Ntime,1);
|
||||
% DfE = repmat(DfE,Ntime,1);
|
||||
% DfI = repmat(DfI,Ntime,1);
|
||||
|
||||
% f_inner = repmat(f_inner,Ntime,1);
|
||||
% f_outer = repmat(f_outer,Ntime,1);
|
||||
% Df_inner = repmat(Df_inner,Ntime,1);
|
||||
% Df_outer = repmat(Df_outer,Ntime,1);
|
||||
|
||||
SQ1 = sqrt(1-e1.^2);
|
||||
SQ2 = sqrt(1-e2.^2);
|
||||
|
||||
%calculate the cosine argument
|
||||
Phi = j.*Lambda2+(k-j).*Lambda1-C.*Pom1-Cp.*Pom2-D.*Om1-Dp.*Om2;
|
||||
|
||||
%calculate Cjk and Sjk
|
||||
PowersFactor = e1.^A.*e2.^Ap.*s1.^B.*s2.^Bp;
|
||||
Cjk = PowersFactor.*cos(Phi);
|
||||
Sjk = PowersFactor.*sin(Phi);
|
||||
|
||||
%calculate the mean-motion of the longitude of conjunction
|
||||
njk = j*n2+(k-j)*n1;
|
||||
|
||||
%orbital elements variations - inner planet
|
||||
da_oa1 = 2*mu2/(1+mu1)*alph*(f_inner).*(k-j)*n1./njk.*Cjk;
|
||||
|
||||
dLambda1 = mu2/(1+mu1)*alph*n1./njk.*Sjk...
|
||||
.*(...
|
||||
3.*(f_inner).*(j-k)*n1./njk...
|
||||
-2*alph*(Df_inner)...
|
||||
+(f_inner).*A.*(SQ1.*(1-SQ1))./(e1.^2)...
|
||||
+(f_inner).*B/2./SQ1...
|
||||
);
|
||||
|
||||
de1 = mu2/(1+mu1)*alph*(f_inner).*SQ1./e1*n1./njk.*Cjk...
|
||||
.*((j-k).*(1-SQ1)+C);
|
||||
|
||||
dPom1 = mu2/(1+mu1)*alph*(f_inner)*n1./njk.*Sjk...
|
||||
.*(A.*SQ1./(e1.^2)+B/2./SQ1);
|
||||
|
||||
dI1 = mu2/(1+mu1)*alph*(f_inner)./SQ1*n1./njk.*Cjk...
|
||||
.*((j-k+C).*tan(I1/2)+D./sin(I1));
|
||||
|
||||
dOm1 = mu2/(1+mu1)*alph*(f_inner).*B/2.*cot(I1/2)./(SQ1.*sin(I1))*n1./njk.*Sjk;
|
||||
|
||||
% dI1 = 0; dOm1 = 0;
|
||||
|
||||
|
||||
|
||||
%orbital elements variations - outer planet
|
||||
da_oa2 = 2*mu1/(1+mu2)*(f_outer).*j*n2./njk.*Cjk;
|
||||
|
||||
dLambda2 = mu1/(1+mu2)*n2./njk.*Sjk.*...
|
||||
(...
|
||||
-3*(f_outer).*j*n2./njk...
|
||||
+2*(f_outer+alph*Df_outer)...
|
||||
+(f_outer).*Ap.*SQ2.*(1-SQ2)./(e2.^2)...
|
||||
+(f_outer).*Bp/2./SQ2...
|
||||
);
|
||||
|
||||
de2 = mu1/(1+mu2)*(f_outer).*SQ2./e2*n2./njk.*Cjk.*...
|
||||
(...
|
||||
-j.*(1-SQ2)+Cp...
|
||||
);
|
||||
|
||||
dPom2 = mu1/(1+mu2)*(f_outer)*n2./njk.*Sjk.*...
|
||||
(...
|
||||
Ap.*SQ2./(e2.^2)+Bp/2./SQ2...
|
||||
);
|
||||
|
||||
dI2 = mu1/(1+mu2)*(f_outer)./SQ2*n2./njk.*Cjk.*...
|
||||
(...
|
||||
(Cp-j).*tan(I2/2)+Dp./sin(I2)...
|
||||
);
|
||||
|
||||
dOm2 = mu1/(1+mu2)*(f_outer).*Bp/2.*cot(I2/2)./(SQ2.*sin(I2))*n2./njk.*Sjk;
|
||||
|
||||
% dI2 = 0; dOm2 = 0;
|
||||
|
||||
NewVersion = 1;
|
||||
|
||||
|
||||
if ~NewVersion
|
||||
%translate to the complex form
|
||||
dz1 = (de1+1i*dPom1.*e1).*exp(1i*Pom1);
|
||||
dz2 = (de2+1i*dPom2.*e2).*exp(1i*Pom2);
|
||||
|
||||
du1 = (dI1+1i*dOm1.*I1).*exp(1i*Om1);
|
||||
du2 = (dI2+1i*dOm2.*I2).*exp(1i*Om2);
|
||||
|
||||
|
||||
%sum the distribution of all terms to get the total effect
|
||||
dz1 = sum(dz1,2);
|
||||
dz2 = sum(dz2,2);
|
||||
du1 = sum(du1,2);
|
||||
du2 = sum(du2,2);
|
||||
da_oa1 = sum(da_oa1,2);
|
||||
da_oa2 = sum(da_oa2,2);
|
||||
dLambda1 = sum(dLambda1,2);
|
||||
dLambda2 = sum(dLambda2,2);
|
||||
|
||||
else
|
||||
%translate to the complex form
|
||||
dz1 = (sum(de1,2)+1i*sum(dPom1,2).*e1).*exp(1i*Pom1);
|
||||
dz2 = (sum(de2,2)+1i*sum(dPom2,2).*e2).*exp(1i*Pom2);
|
||||
du1 = (sum(dI1,2)+1i*sum(dOm1,2).*I1).*exp(1i*Om1);
|
||||
du2 = (sum(dI2,2)+1i*sum(dOm2,2).*I2).*exp(1i*Om2);
|
||||
da_oa1 = sum(da_oa1,2);
|
||||
da_oa2 = sum(da_oa2,2);
|
||||
dLambda1 = sum(dLambda1,2);
|
||||
dLambda2 = sum(dLambda2,2);
|
||||
end
|
1230
AnalyticLC/ForcedElements1.m
Normal file
1230
AnalyticLC/ForcedElements1.m
Normal file
File diff suppressed because it is too large
Load diff
82
AnalyticLC/ForcedMeanLongitudes3PlanetsCrossTerms.m
Normal file
82
AnalyticLC/ForcedMeanLongitudes3PlanetsCrossTerms.m
Normal file
|
@ -0,0 +1,82 @@
|
|||
function dLambda = ForcedMeanLongitudes3PlanetsCrossTerms(P,Lambda,mu,z)
|
||||
% ForcedMeanLongitudes3Planets: calculate the forced mean longitudes of a set of
|
||||
% planets due to the cross-terms among different resonances.
|
||||
|
||||
%Inputs: P - orbital periods, Lambda - mean longitudes, mu - planets/star
|
||||
%mass ratio, z - free eccentricities (if they are not given, zero values
|
||||
%are assumed). Labmda and z can be given as columns of multiple values.
|
||||
|
||||
% Yair Judkovsky, 2.11.2020
|
||||
|
||||
if ~exist('z','var')
|
||||
z = zeros(size(P));
|
||||
end
|
||||
|
||||
%mean motions
|
||||
n = 2*pi./P;
|
||||
|
||||
%absolute values and angles of eccentricities
|
||||
pom = angle(z);
|
||||
e = abs(z);
|
||||
zx = real(z);
|
||||
zy = imag(z);
|
||||
|
||||
%allocate space for 3d matrices that will hold the values of dLambda
|
||||
%according to these dimensios: orders, data points, number of planets
|
||||
dLambda = zeros(size(z,1),length(P));
|
||||
|
||||
%go over all possible planets triplets
|
||||
for j1 = 1:length(P)
|
||||
for j2 = (j1+1):length(P)
|
||||
for j3 = (j2+1):length(P)
|
||||
|
||||
%calculate the nearest 1st order MMR for each pair in the
|
||||
%triplet
|
||||
j = round(P(j2)/(P(j2)-P(j1)));
|
||||
k = round(P(j3)/(P(j3)-P(j2)));
|
||||
nj = j*n(j2)+(1-j)*n(j1);
|
||||
nk = k*n(j3)+(1-k)*n(j2);
|
||||
alph12 = (n(j2)/n(j1))^(2/3)*((1+mu(j1))/(1+mu(j2)))^(1/3);
|
||||
alph23 = (n(j3)/n(j2))^(2/3)*((1+mu(j2))/(1+mu(j3)))^(1/3);
|
||||
|
||||
%longitudes of conjunction
|
||||
Lambda_j = j*Lambda(:,j2)+(1-j)*Lambda(:,j1);
|
||||
Lambda_k = k*Lambda(:,j3)+(1-k)*Lambda(:,j2);
|
||||
|
||||
%laplace coefficients
|
||||
Ak = LaplaceCoeffs(alph23,0.5,k,0);
|
||||
DAk = LaplaceCoeffs(alph23,0.5,k,1);
|
||||
Ajm1 = LaplaceCoeffs(alph12,0.5,j-1,0);
|
||||
DAjm1 = LaplaceCoeffs(alph12,0.5,j-1,1);
|
||||
D2Ajm1 = LaplaceCoeffs(alph12,0.5,j-1,2);
|
||||
f27k = -k*Ak-0.5*alph23*DAk;
|
||||
f31j = (j-0.5)*Ajm1+0.5*alph12*DAjm1;
|
||||
|
||||
Df31j = (j-0.5)*DAjm1+0.5*DAjm1+0.5*alph12*D2Ajm1;
|
||||
|
||||
F=sqrt(1);
|
||||
%calculate and add to the dlambda of the intermediate planet
|
||||
AlphaFactor = -3/2*f27k*(f31j-(j==2)/(2*alph12^2))*alph23;
|
||||
MassFactor = mu(j1)*mu(j3)/(1+mu(j2))^2;
|
||||
SinTerm1 = (j/nk+(1-k)/nj)*sin(Lambda_j+Lambda_k-2*pom(:,j2))/(nj+nk)^2;
|
||||
SinTerm2 = (j/nk-(1-k)/nj)*sin(Lambda_j-Lambda_k)/(nj-nk)^2;
|
||||
dLambda(:,j2) = dLambda(:,j2)+F*AlphaFactor*MassFactor*n(j2)^3*(SinTerm1+SinTerm2);
|
||||
|
||||
%calculate and add to the dlambda of the innermost planet
|
||||
AlphaFactor = 3/2*f27k*(f31j-2*alph12*(j==2))*alph12*alph23;
|
||||
MassFactor = mu(j2)*mu(j3)/(1+mu(j1))/(1+mu(j2));
|
||||
SinTerm1 = sin(Lambda_j+Lambda_k-2*pom(:,j2))/(nj+nk)^2;
|
||||
SinTerm2 = sin(Lambda_j-Lambda_k)/(nj-nk)^2;
|
||||
dLambda(:,j1) = dLambda(:,j1)+F*AlphaFactor*MassFactor*n(j1)^2*n(j2)*(j-1)/nk*(SinTerm1+SinTerm2);
|
||||
|
||||
%calculate and add to the dlambda of the outermost planet
|
||||
AlphaFactor = -3/2*f27k*(f31j-(j==2)/(2*alph12^2));
|
||||
MassFactor = mu(j1)*mu(j2)/(1+mu(j2))/(1+mu(j3));
|
||||
SinTerm1 = sin(Lambda_j+Lambda_k-2*pom(:,j2))/(nj+nk)^2;
|
||||
SinTerm2 = -sin(Lambda_j-Lambda_k)/(nj-nk)^2;
|
||||
dLambda(:,j3) = dLambda(:,j3)+F*AlphaFactor*MassFactor*n(j3)^2*n(j2)*k/nj*(SinTerm1+SinTerm2);
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
166
AnalyticLC/LaplaceCoeffs.m
Normal file
166
AnalyticLC/LaplaceCoeffs.m
Normal file
|
@ -0,0 +1,166 @@
|
|||
function Output = LaplaceCoeffs(varargin)
|
||||
% LaplaceCoeff: get a Laplace coefficient (definition: Solar System
|
||||
% Dynamics, eq. 6.67)
|
||||
|
||||
%Inputs: 'init' - calculate a table of the laplace coefficients and save it
|
||||
% in ~/Matlab/Data/LaplaceCoeffs.mat
|
||||
% 'load' = return all the table and the row/col values in a
|
||||
% structure
|
||||
% alph,s,j = return the laplace coefficient for the given alph,s,j.
|
||||
% alph can be a vector
|
||||
% alph,s,j,D = return the D order derivative of the laplace
|
||||
% coefficient for the given alph, s, j.
|
||||
|
||||
% Yair Judkovsky, 6.4.2020
|
||||
|
||||
persistent jVec sVec DVec alphaVec bTable Nj Ns ND
|
||||
|
||||
|
||||
%return a specific laplace coeff
|
||||
if isnumeric(varargin{1})
|
||||
|
||||
alph = varargin{1};
|
||||
s = varargin{2};
|
||||
j = abs(varargin{3}); %b_s_j = b_s__-j, Solar System Dynamics eq. 6.69
|
||||
|
||||
%a recursive path of the function for the case there's a 4th input -
|
||||
%the laplace coeff derivative.
|
||||
if length(varargin)>3
|
||||
D = varargin{4}; %derivative order
|
||||
else
|
||||
D = 0;
|
||||
end
|
||||
|
||||
jInd = j+1;
|
||||
sInd = s+0.5;
|
||||
DInd = D+1;
|
||||
|
||||
%if the requested derivative is too high, calculate by recursive method
|
||||
if DInd>ND
|
||||
%2nd and higher derivatives of the coeff, Solar System Dynamics eq. 6.71
|
||||
Output = s*(LaplaceCoeffs(alph,s+1,j-1,D-1)-2*alph.*LaplaceCoeffs(alph,s+1,j,D-1)+LaplaceCoeffs(alph,s+1,j+1,D-1)-2*(D-1)*LaplaceCoeffs(alph,s+1,j,D-2));
|
||||
return
|
||||
end
|
||||
|
||||
row = sub2ind([Nj,Ns,ND],jInd,sInd,DInd);
|
||||
|
||||
%find the column corresponding to the alpha given, currently by finding the
|
||||
%closest value in the table
|
||||
F = (length(alphaVec));
|
||||
col = round(alph*F);
|
||||
if col==0
|
||||
col = 1;
|
||||
end
|
||||
|
||||
%return the value from the table
|
||||
Output = bTable(row,col);
|
||||
return
|
||||
end
|
||||
|
||||
%perform the calculation. Table will be made such that each row
|
||||
%corresponds to some j,s combination, and each column corresponds to an
|
||||
%alpha value.
|
||||
if isequal(varargin{1},'init')
|
||||
|
||||
%define the integrand function
|
||||
laplace_integrand=@(j1,s1,alph1) (@(phi) (cos(j1.*phi)./(1-2.*alph1.*cos(phi)+alph1.^2).^s1));
|
||||
|
||||
warning off
|
||||
|
||||
%set range of j, s, D, alpha. Can also be read from varargin if
|
||||
%exists, where the 2,3,4,5 arguments will be Ns, Nj,ND and dalpha
|
||||
Ns =3;
|
||||
Nj = 5;
|
||||
ND = 4;
|
||||
dalpha = 1e-2;
|
||||
%set integration tolerance
|
||||
AbsTol = 1e-5;
|
||||
Path = '~/Matlab/Data/LaplaceCoeffs.mat';
|
||||
|
||||
%read inputs from varargin, if they exist
|
||||
if length(varargin)==5
|
||||
Ns = varargin{2};
|
||||
Nj = varargin{3};
|
||||
ND = varargin{4};
|
||||
dalpha = varargin{5};
|
||||
end
|
||||
|
||||
if length(varargin)>5
|
||||
AbsTol = varargin{6};
|
||||
end
|
||||
|
||||
if length(varargin)>6
|
||||
Path = varargin{7};
|
||||
end
|
||||
|
||||
%set a vector of s and j values
|
||||
sVec = (1:Ns)-0.5;
|
||||
jVec = (1:Nj)-1;
|
||||
DVec = (1:ND)-1;
|
||||
|
||||
%define the alpha vector from dalpha
|
||||
alphaVec = dalpha:dalpha:1;
|
||||
|
||||
%pre-allocate
|
||||
bTable = zeros(Nj*Ns*ND,length(alphaVec));
|
||||
|
||||
for jInd = 1:length(jVec)
|
||||
for sInd = 1:length(sVec)
|
||||
for DInd = 1:length(DVec)
|
||||
for alphaInd = 1:length(alphaVec)
|
||||
|
||||
row = sub2ind([Nj,Ns,ND],jInd,sInd,DInd);
|
||||
|
||||
val = CalculateSingleCoeff(jVec(jInd),sVec(sInd),alphaVec(alphaInd),DVec(DInd),AbsTol,laplace_integrand);
|
||||
|
||||
bTable(row,alphaInd)=val;
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
save(Path,'jVec','sVec','alphaVec','DVec','bTable','Nj','Ns','ND');
|
||||
disp('calculated laplace coeffs');
|
||||
Output = [];
|
||||
return
|
||||
end
|
||||
|
||||
%load the table including the persistent variables for future use. Also
|
||||
%return the persistent variables in a structure as an output.
|
||||
if isequal(varargin{1},'load')
|
||||
Path = '~/Matlab/Data/LaplaceCoeffs.mat';
|
||||
if nargin>1
|
||||
Path = varargin{2};
|
||||
end
|
||||
load(Path);
|
||||
Output = load(Path);
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
% if D==0
|
||||
% Output = LaplaceCoeffs(alph,s,j);
|
||||
% elseif D==1 %first derivative of the coeff, Solar System Dynamics eq. 6.70
|
||||
% Output = s*(LaplaceCoeffs(alph,s+1,j-1)-2*alph.*LaplaceCoeffs(alph,s+1,j)+LaplaceCoeffs(alph,s+1,j+1));
|
||||
% else %2nd and higher derivatives of the coeff, Solar System Dynamics eq. 6.71
|
||||
% Output = s*(LaplaceCoeffs(alph,s+1,j-1,D-1)-2*alph.*LaplaceCoeffs(alph,s+1,j,D-1)+LaplaceCoeffs(alph,s+1,j+1,D-1)-2*(D-1)*LaplaceCoeffs(alph,s+1,j,D-2));
|
||||
% end
|
||||
% return
|
||||
|
||||
function val = CalculateSingleCoeff(j,s,alph,D,AbsTol,laplace_integrand)
|
||||
|
||||
% %define the integrand function
|
||||
% laplace_integrand=@(j1,s1,alph1) (@(phi) (cos(j1.*phi)./(1-2.*alph1.*cos(phi)+alph1.^2).^s1));
|
||||
|
||||
if D==0
|
||||
val = 1/pi*integral(laplace_integrand(j,s,alph),0,2*pi,'AbsTol',AbsTol);
|
||||
elseif D==1 %first derivative of the coeff, Solar System Dynamics eq. 6.70
|
||||
val = s*(CalculateSingleCoeff(j-1,s+1,alph,D-1,AbsTol,laplace_integrand)...
|
||||
-2*alph.*CalculateSingleCoeff(j,s+1,alph,D-1,AbsTol,laplace_integrand)...
|
||||
+CalculateSingleCoeff(j+1,s+1,alph,D-1,AbsTol,laplace_integrand));
|
||||
else %2nd and higher derivatives of the coeff, Solar System Dynamics eq. 6.71
|
||||
val = s*(CalculateSingleCoeff(j-1,s+1,alph,D-1,AbsTol,laplace_integrand)...
|
||||
-2*alph.*CalculateSingleCoeff(j,s+1,alph,D-1,AbsTol,laplace_integrand)...
|
||||
+CalculateSingleCoeff(j+1,s+1,alph,D-1,AbsTol,laplace_integrand)...
|
||||
-2*(D-1)*CalculateSingleCoeff(j,s+1,alph,D-2,AbsTol,laplace_integrand));
|
||||
end
|
105
AnalyticLC/MALookupTable.m
Normal file
105
AnalyticLC/MALookupTable.m
Normal file
|
@ -0,0 +1,105 @@
|
|||
function Output = MALookupTable(varargin)
|
||||
% MALookupTable: generate a look-up table for Mandel-Agol model values, or
|
||||
% use the table and read from it
|
||||
|
||||
%Inputs: 'init' - calculate a table of the MA values for the given rVec,
|
||||
%zVec, u1, u2
|
||||
% 'load' = return all the table and the row/col values in a
|
||||
% structure
|
||||
% r,z = return the Mandel-Agol model values for the given r,z.
|
||||
% u1 and u2 which will be used are the ones that were used for
|
||||
% generating the table. z can be a vector, r must be a scalar.
|
||||
|
||||
% Yair Judkovsky, 25.10.2020
|
||||
|
||||
persistent rVec zVec u1 u2 R Z MATable
|
||||
|
||||
%return a specific Mandel-Agol model value
|
||||
if isnumeric(varargin{1})
|
||||
|
||||
%get r, z values from the input
|
||||
r = varargin{1};
|
||||
z = varargin{2};
|
||||
Requested_u1 = varargin{3};
|
||||
Requested_u2 = varargin{4};
|
||||
|
||||
%if no table exists, or if the requested u1,u2 do not match the table, just calculate the values
|
||||
if isempty(MATable) || Requested_u1~=u1 || Requested_u2~=u2
|
||||
Output = occultquadVec(r,z,Requested_u1,Requested_u2);
|
||||
return
|
||||
end
|
||||
|
||||
Output = ones(size(z));
|
||||
|
||||
%old method - plug in "1" wherever outside the planet radius range
|
||||
% Output(z<1+r) = interp2(R,Z,MATable,z(z<1+r),r,'linear',1);
|
||||
|
||||
%new method - outside the radius range calculate using occultquadVec. This
|
||||
%is useful because now the radius range can be reduce, yielding a fast
|
||||
%calculation for most of the points
|
||||
ind = r>min(rVec) & r<max(rVec);
|
||||
Output(z<1+r & ind) = interp2(R,Z,MATable,z(z<1+r & ind),r,'linear');
|
||||
Output(z<1+r & ~ind) = occultquadVec(r,z(z<1+r & ~ind),u1,u2);
|
||||
|
||||
return
|
||||
|
||||
end
|
||||
|
||||
%perform the calculation. Table will be made such that each row represents
|
||||
%a value of r, and each column represents a value of z
|
||||
if isequal(varargin{1},'init')
|
||||
|
||||
%set range of r, z, u1, u2. Can also be read from varargin if
|
||||
%exists, where the 2,3,4,5 arguments will be rVec, zVec, u1, u2.
|
||||
rVec = 0.5e-2:2e-3:0.2;
|
||||
zVec = 0:2e-3:1.25;
|
||||
u1 = 0.36;
|
||||
u2 = 0.28;
|
||||
|
||||
|
||||
|
||||
%read inputs from varargin, if they exist
|
||||
if length(varargin)==5
|
||||
rVec = varargin{2};
|
||||
zVec = varargin{3};
|
||||
u1 = varargin{4};
|
||||
u2 = varargin{5};
|
||||
end
|
||||
|
||||
%generate a table of r and z values
|
||||
[R,Z] = meshgrid(zVec,rVec);
|
||||
|
||||
%set a table of model values for r and z
|
||||
MATable = zeros(length(rVec),length(zVec));
|
||||
for j = 1:length(rVec)
|
||||
MATable(j,:) = occultquadVec(rVec(j),zVec,u1,u2);
|
||||
end
|
||||
|
||||
fprintf('calculated Mandel-Agol values \n');
|
||||
|
||||
Output = [];
|
||||
return
|
||||
end
|
||||
|
||||
%load the table
|
||||
if isequal(varargin{1},'load')
|
||||
Output.rVec = rVec;
|
||||
Output.zVec = zVec;
|
||||
Output.u1 = u1;
|
||||
Output.u2 = u2;
|
||||
Output.R = R;
|
||||
Output.Z = Z;
|
||||
Output.MATable = MATable;
|
||||
return
|
||||
end
|
||||
|
||||
%clear the values
|
||||
if isequal(varargin{1},'clear')
|
||||
clear rVec zVec u1 u2 R Z MATable
|
||||
Output = [];
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
24
AnalyticLC/OrbitalElements2TransitParams.m
Normal file
24
AnalyticLC/OrbitalElements2TransitParams.m
Normal file
|
@ -0,0 +1,24 @@
|
|||
function [w,d,b,T,Tau] = OrbitalElements2TransitParams(n,aor,ex,ey,I,Omega,r)
|
||||
%OrbitalElements2TransitParams: returns the duration, ingress-egress time and angular velocity as a
|
||||
%function of the orbital properties.
|
||||
|
||||
%inputs: n - mean motion, aor - semi-major axis over stellar radius, ex,ey - eccentricity vector components, x
|
||||
%pointing at observer, I,Omega - inclination with respect to the planet xy,
|
||||
%r - planetary radius in units of stellar radii.
|
||||
%where x points at observer. Outputs: T=Duration, Tau=ingress/egress time,
|
||||
%w = angular velocity at mid-transit, d = planet-star distance at
|
||||
%mid-transit, b = impact parameter
|
||||
|
||||
%Yair Judkovsky, 9.9.2020
|
||||
|
||||
w = n.*(1+ex).^2./(1-ex.^2-ey.^2).^(3/2);
|
||||
d = aor.*(1-ex.^2-ey.^2)./(1+ex);
|
||||
b = d.*sin(I).*sin(Omega);
|
||||
|
||||
if nargout>3
|
||||
asin0 = asin(sqrt(((1+ex).^2./(aor.^2.*(1-ex.^2-ey.^2).^2)-sin(I).^2.*sin(Omega).^2)./(1-sin(I).^2.*sin(Omega).^2)));
|
||||
T=1./n*2.*((1-ex.^2-ey.^2).^(3/2))./((1+ex).^2).*asin0;
|
||||
asin2 = asin(sqrt(((1+r).^2.*(1+ex).^2./(aor.^2.*(1-ex.^2-ey.^2).^2)-sin(I).^2.*sin(Omega).^2)./(1-sin(I).^2.*sin(Omega).^2)));
|
||||
asin1 = asin(sqrt(((1-r).^2.*(1+ex).^2./(aor.^2.*(1-ex.^2-ey.^2).^2)-sin(I).^2.*sin(Omega).^2)./(1-sin(I).^2.*sin(Omega).^2)));
|
||||
Tau=1./n.*((1-ex.^2-ey.^2).^(3/2))./((1+ex).^2).*(asin2-asin1);
|
||||
end
|
1
AnalyticLC/fooo.m
Normal file
1
AnalyticLC/fooo.m
Normal file
|
@ -0,0 +1 @@
|
|||
t = 0:100:0.02
|
16
AnalyticLC/fooo.octave
Normal file
16
AnalyticLC/fooo.octave
Normal file
|
@ -0,0 +1,16 @@
|
|||
P = [9, 19, 32]
|
||||
Tmid0 = [0, 10, 15]
|
||||
ror = [0.03, 0.12, 0.05]
|
||||
aor = 25
|
||||
mu = [0.02, 0.05, 0.01]
|
||||
ex0 = [0, 0, 0]
|
||||
ey0 = [0, 0, 0]
|
||||
I0 = [90, 90, 90]
|
||||
Omega0 = [0, 0, 0]
|
||||
t = [0, 9, 19, 22, 32]
|
||||
u1 = 0.27
|
||||
u2 = 0.13
|
||||
|
||||
LC = AnalyticLC(P, Tmid0, ror, aor, mu, ex0, ey0, I0, Omega0, t, u1, u2)
|
||||
|
||||
print LC
|
16
AnalyticLC/test.octave
Normal file
16
AnalyticLC/test.octave
Normal file
|
@ -0,0 +1,16 @@
|
|||
P = [9, 19, 32]
|
||||
Tmid0 = [0, 10, 15]
|
||||
ror = [0.03, 0.12, 0.05]
|
||||
aor = 25
|
||||
mu = [0.02, 0.05, 0.01]
|
||||
ex0 = [0, 0, 0]
|
||||
ey0 = [0, 0, 0]
|
||||
I0 = [90, 90, 90]
|
||||
Omega0 = [0, 0, 0]
|
||||
t = [0, 9, 19, 22, 32]
|
||||
u1 = 0.27
|
||||
u2 = 0.13
|
||||
|
||||
LC = AnalyticLC(P, Tmid0, ror, aor, mu, ex0, ey0, I0, Omega0, t, u1, u2)
|
||||
|
||||
print LC
|
6
FittingAndMath/CatStructFields.m
Normal file
6
FittingAndMath/CatStructFields.m
Normal file
|
@ -0,0 +1,6 @@
|
|||
function S = CatStructFields(S, T, dim)
|
||||
fields = fieldnames(S);
|
||||
for k = 1:numel(fields)
|
||||
aField = fields{k}; % EDIT: changed to {}
|
||||
S.(aField) = cat(dim, S.(aField), T.(aField));
|
||||
end
|
37
FittingAndMath/Vector1stOrderDE.m
Normal file
37
FittingAndMath/Vector1stOrderDE.m
Normal file
|
@ -0,0 +1,37 @@
|
|||
function xt = Vector1stOrderDE(A,x0,t)
|
||||
%Vector1stOrderDE: - solves the vector equation dx/dt=Ax
|
||||
|
||||
%inputs: A - matrix of the equation, x0 - x for t=0, t - time axis to
|
||||
%evaluate values at. derivation is given at:
|
||||
%https://www.unf.edu/~mzhan/chapter4.pdf
|
||||
|
||||
%Yair Judkovsky, 3.10.2020
|
||||
|
||||
if nargin==0
|
||||
A=[.1,.01;-.002,-.002].*i;
|
||||
x0=[.3,0.0001];
|
||||
t=linspace(0,100,100000);
|
||||
end
|
||||
nt=length(t);
|
||||
if any(~isfinite(A(:))), xt = 123.123; return, end
|
||||
[ev,lam]=eig(A);
|
||||
nev=length(diag(lam));
|
||||
phi0i=inv(ev);
|
||||
% add singleton dimension as the first (time) index and replicate
|
||||
% eigenvectors along that dimension.
|
||||
evp=repmat(reshape(ev,[1,nev,nev]),[length(t),1,1]);
|
||||
|
||||
lamt=reshape(exp(diag(lam)*t).',length(t),1,nev);
|
||||
lamt=repmat(lamt,1,nev,1);
|
||||
phit=lamt.*evp;
|
||||
|
||||
xt=reshape(reshape(phit,nev*nt,nev)*(phi0i*x0),nt,nev);
|
||||
|
||||
if nargin==0
|
||||
figure;
|
||||
plot(xt);
|
||||
hold on
|
||||
plot(real(x0),imag(x0),'o');
|
||||
axis equal
|
||||
end
|
||||
|
45
FittingAndMath/fit_linear.m
Normal file
45
FittingAndMath/fit_linear.m
Normal file
|
@ -0,0 +1,45 @@
|
|||
function [a,b,da,db]=fit_linear(x,y,varargin)
|
||||
%fit_linear: 1st order linear regression.
|
||||
|
||||
%This function fits a dataset of x and y values to the linear equation
|
||||
%y=ax+b. it is optional for the user to insert also y error values for the
|
||||
%estimation of a and b errors.
|
||||
%
|
||||
|
||||
%Yair Judkovsky, 21.8.2013
|
||||
|
||||
if nargin==2 %case of no error input - assuming that all errors are equal
|
||||
dy = ones(size(y));
|
||||
else
|
||||
dy = varargin{1};
|
||||
end
|
||||
|
||||
dy2=dy.^2;
|
||||
x2=x.^2;
|
||||
xy=x.*y;
|
||||
|
||||
S=sum(1./dy2);
|
||||
Sx=sum(x./dy2);
|
||||
Sy=sum(y./dy2);
|
||||
Sxx=sum(x2./dy2);
|
||||
Sxy=sum(xy./dy2);
|
||||
D=S*Sxx-Sx^2;
|
||||
|
||||
a=(S*Sxy-Sx*Sy)/D;
|
||||
b=(Sxx*Sy-Sxy*Sx)/D;
|
||||
|
||||
if nargin==2 %no error given - need to estimate it
|
||||
Ytheo=a*x+b;
|
||||
dy2=mean((Ytheo-y).^2)*ones(size(y));
|
||||
S=sum(1./dy2);
|
||||
Sx=sum(x./dy2);
|
||||
Sxx=sum(x2./dy2);
|
||||
D=S*Sxx-Sx^2;
|
||||
da=sqrt(S/D);
|
||||
db=sqrt(Sxx/D);
|
||||
else
|
||||
da=sqrt(S/D);
|
||||
db=sqrt(Sxx/D);
|
||||
end
|
||||
|
||||
return
|
9
FittingAndMath/horizontal.m
Normal file
9
FittingAndMath/horizontal.m
Normal file
|
@ -0,0 +1,9 @@
|
|||
function horzvec=horizontal(vec)
|
||||
%reshape input vector into row vector
|
||||
|
||||
if min(size(vec))>1
|
||||
horzvec=[];
|
||||
return
|
||||
end
|
||||
|
||||
horzvec=reshape(vec,1,length(vec));
|
3
FittingAndMath/range.m
Normal file
3
FittingAndMath/range.m
Normal file
|
@ -0,0 +1,3 @@
|
|||
function res = range(X)
|
||||
res=max(X(:))-min(X(:));
|
||||
return
|
9
FittingAndMath/vertical.m
Normal file
9
FittingAndMath/vertical.m
Normal file
|
@ -0,0 +1,9 @@
|
|||
function vertvec=vertical(vec)
|
||||
%reshape input vector into row vector
|
||||
|
||||
if min(size(vec))>1
|
||||
vertvec=[];
|
||||
return
|
||||
end
|
||||
|
||||
vertvec=reshape(vec,length(vec),1);
|
17
FluxCalculation/ellecVec.m
Normal file
17
FluxCalculation/ellecVec.m
Normal file
|
@ -0,0 +1,17 @@
|
|||
function ellec=ellecVec(k)
|
||||
% Computes polynomial approximation for the complete elliptic
|
||||
% integral of the second kind (Hasting's approximation):
|
||||
m1=1-k.*k;
|
||||
m1(m1<eps)=eps;
|
||||
a1=0.44325141463;
|
||||
a2=0.06260601220;
|
||||
a3=0.04757383546;
|
||||
a4=0.01736506451;
|
||||
b1=0.24998368310;
|
||||
b2=0.09200180037;
|
||||
b3=0.04069697526;
|
||||
b4=0.00526449639;
|
||||
ee1=1+m1.*(a1+m1.*(a2+m1.*(a3+m1*a4)));
|
||||
%ee2=m1.*(b1+m1.*(b2+m1.*(b3+m1.*b4))).*log(1./m1);
|
||||
ee2=m1.*(b1+m1.*(b2+m1.*(b3+m1.*b4))).*(-1*log(m1));
|
||||
ellec=ee1+ee2;
|
18
FluxCalculation/ellkVec.m
Normal file
18
FluxCalculation/ellkVec.m
Normal file
|
@ -0,0 +1,18 @@
|
|||
function ellk=ellkVec(k)
|
||||
% Computes polynomial approximation for the complete elliptic
|
||||
% integral of the first kind (Hasting's approximation):
|
||||
m1=1-k.*k;
|
||||
m1(m1<eps)=eps;
|
||||
a0=1.38629436112;
|
||||
a1=0.09666344259;
|
||||
a2=0.03590092383;
|
||||
a3=0.03742563713;
|
||||
a4=0.01451196212;
|
||||
b0=0.5;
|
||||
b1=0.12498593597;
|
||||
b2=0.06880248576;
|
||||
b3=0.03328355346;
|
||||
b4=0.00441787012;
|
||||
ek1=a0+m1.*(a1+m1.*(a2+m1.*(a3+m1*a4)));
|
||||
ek2=(b0+m1.*(b1+m1.*(b2+m1.*(b3+m1*b4)))).*log(m1);
|
||||
ellk=ek1-ek2;
|
438
FluxCalculation/occultquadVec.m
Normal file
438
FluxCalculation/occultquadVec.m
Normal file
|
@ -0,0 +1,438 @@
|
|||
function [muo1, mu0]=occultquadVec(p,z,u1,u2,ToPlot,varargin)
|
||||
% Aviv Comments
|
||||
% ==================================================
|
||||
% v.0.32 - vectorize rc,rj,rf
|
||||
% - Allow correcting behaviour near z==p, z=1-p
|
||||
% - Added optinal parameter TolFactor for tolerances control
|
||||
% - Removed all "CloseToOne" and added ToSmooth Parameter
|
||||
|
||||
%%%%%%%%%%%%%%%% - Mandel Agol comments
|
||||
%
|
||||
% This routine computes the lightcurve for occultation
|
||||
% of a quadratically limb-darkened source without microlensing.
|
||||
% Please cite Mandel & Agol (2002) if you make use of this routine
|
||||
% in your research. Please report errors or bugs to agol@tapir.caltech.edu
|
||||
% implicit none
|
||||
% integer i,nz
|
||||
% double precision z0(nz),u1,u2,p,muo1(nz),mu0(nz),
|
||||
% & mu(nz),lambdad(nz),etad(nz),lambdae(nz),lam,
|
||||
% & pi,x1,x2,x3,z,omega,kap0,kap1,q,Kk,Ek,Pk,n,ellec,ellk,rj
|
||||
%
|
||||
% Input:
|
||||
%
|
||||
% rs radius of the source (set to unity)
|
||||
% z impact parameter in units of rs
|
||||
% p occulting star radius in units of rs
|
||||
% u1 linear limb-darkening coefficient (gamma_1 in paper)
|
||||
% u2 quadratic limb-darkening coefficient (gamma_2 in paper)
|
||||
%
|
||||
% Optional input:
|
||||
%
|
||||
% ToPlot: Graphical output [default=false];
|
||||
% Tols: A factor controling the three "ERRTOL" parameters for the three helper functions. If given, all three default ERRTOLs wil be scaled by it: [Default =1 ]
|
||||
% ToSmooth: if true, smooths the original Mandel-Agol model around z=p and around abs(z-p)=1 to produce better-behaving derivative. The value themselves are virtually unchanged. [default=true]
|
||||
%
|
||||
% Output:
|
||||
%
|
||||
% muo1 fraction of flux at each z for a limb-darkened source
|
||||
% mu0 fraction of flux at each z for a uniform source
|
||||
%
|
||||
% Limb darkening has the form:
|
||||
% I(r)=[1-u1*(1-sqrt(1-(r/rs)^2))-u2*(1-sqrt(1-(r/rs)^2))^2]/(1-u1/3-u2/6)/pi
|
||||
%
|
||||
% To use this routine
|
||||
%
|
||||
% Now, compute pure occultation curve:
|
||||
|
||||
% Setting the extra inputs for the case in which only p,z,u1,u2 are given
|
||||
if nargin<5
|
||||
ToPlot=false;
|
||||
end;
|
||||
TolFactor=1;
|
||||
ToSmooth=true;
|
||||
for i=1:2:numel(varargin)
|
||||
switch lower(varargin{i})
|
||||
case 'tolfactor'
|
||||
TolFactor=varargin{i+1};
|
||||
case 'tosmooth'
|
||||
ToSmooth=varargin{i+1};
|
||||
otherwise
|
||||
fprintf('WARNING: parameter %s is unknown, and so ignored.\n',varargin{i});
|
||||
end;
|
||||
end;
|
||||
|
||||
%make z a column vector
|
||||
if size(z,2)>size(z,1) % z is a column vector
|
||||
z=z.';
|
||||
end;
|
||||
|
||||
%set zeros to lambdad, lambda3, 3tad, kap0, kap1
|
||||
lambdad=zeros(size(z));
|
||||
lambdae=lambdad;
|
||||
etad=lambdad;
|
||||
kap0=lambdad;
|
||||
kap1=lambdad;
|
||||
|
||||
%if p is close to 0.5, make it 0.5
|
||||
if abs(p-0.5)<1e-3
|
||||
p=0.5;
|
||||
end;
|
||||
|
||||
omega=1-u1/3-u2/6;
|
||||
x1=(p-z).^2;
|
||||
x2=(p+z).^2;
|
||||
x3=p.^2-z.^2;
|
||||
|
||||
% the source is unocculted:
|
||||
% Table 3, I.
|
||||
i=z>=1+p;
|
||||
if any(i)
|
||||
lambdad(i)=0;
|
||||
etad(i)=0;
|
||||
lambdae(i)=0;
|
||||
end;
|
||||
|
||||
% the source is partly occulted and the occulting object crosses the limb:
|
||||
% Equation (26):
|
||||
i=z>=abs(1-p) & z<=1+p;
|
||||
if any(i)
|
||||
kap1(i)=acos(min((1-p^2+z(i).^2)/2./z(i),1));
|
||||
kap0(i)=acos(min((p*p+z(i).^2-1)/2/p./z(i),1));
|
||||
lambdae(i)=p^2*kap0(i)+kap1(i);
|
||||
lambdae(i)=(lambdae(i)-0.5*sqrt(max(4*z(i).^2-(1+z(i).^2-p^2).^2,0)))/pi;
|
||||
end;
|
||||
|
||||
% the occulting object transits the source star (but doesn't
|
||||
% completely cover it):
|
||||
i=z<=1-p;
|
||||
if any(i)
|
||||
lambdae(i)=p^2;
|
||||
end;
|
||||
|
||||
% the edge of the occulting star lies at the origin- special
|
||||
% expressions in this case:
|
||||
|
||||
i=find(abs(z-p)<1e-4*(z+p));
|
||||
if ~isempty(i)
|
||||
% Table 3, Case V.:
|
||||
j=z(i)>=0.5;
|
||||
if any(j)
|
||||
%lam=0.5*pi;
|
||||
q=0.5/p;
|
||||
Kk=ellkVec(q);
|
||||
Ek=ellecVec(q);
|
||||
% Equation 34: lambda_3
|
||||
lambdad(i(j))=1/3+16*p/9/pi*(2*p^2-1)*Ek-(32*p^4-20*p^2+3)/9/pi/p*Kk;
|
||||
% Equation 34: eta_1
|
||||
etad(i(j))=1/2/pi*(kap1(i(j))+p^2*(p^2+2*z(i(j))).*kap0(i(j))-(1+5*p^2+z(i(j)).^2)./4.*sqrt((1-x1(i(j))).*(x2(i(j))-1)));
|
||||
if p==0.5
|
||||
% Case VIII: p=1/2, z=1/2
|
||||
lambdad(i(j))=1/3-4/pi/9;
|
||||
etad(i(j))=3/32;
|
||||
end;
|
||||
end;
|
||||
j=~j;
|
||||
if any(j)
|
||||
% Table 3, Case VI.:
|
||||
%lam=0.5*pi;
|
||||
q=2*p;
|
||||
Kk=ellkVec(q);
|
||||
Ek=ellecVec(q);
|
||||
% Equation 34: lambda_4
|
||||
lambdad(i(j))=1/3+2/9/pi*(4*(2*p^2-1)*Ek+(1-4*p^2)*Kk);
|
||||
% Equation 34: eta_2
|
||||
etad(i(j))=p^2/2*(p^2+2*z(i(j)).^2);
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
% the occulting star partly occults the source and crosses the limb:
|
||||
% Table 3, Case III:
|
||||
i=find(z>=0.5+abs(p-0.5) & z<1+p | (p>0.5 & z>abs(1-p)*(1+10*eps(1)) & z<p));
|
||||
if any(i)
|
||||
%lam=0.5*pi;
|
||||
q=sqrt((1-(p-z(i)).^2)/4./z(i)/p);
|
||||
Kk=ellkVec(q);
|
||||
Ek=ellecVec(q);
|
||||
n=1./x1(i)-1;
|
||||
Pk=Kk-n/3.*rj(0,1-q.^2,1,1+n,TolFactor);
|
||||
% Equation 34, lambda_1:
|
||||
lambdad(i)=1/9/pi./sqrt(p*z(i)).*(((1-x2(i)).*(2*x2(i)+x1(i)-3)-3*x3(i).*(x2(i)-2)).*Kk+4*p*z(i).*(z(i).^2+7*p^2-4).*Ek-3*x3(i)./x1(i).*Pk);
|
||||
j=z(i)<p;
|
||||
if any(j)
|
||||
lambdad(i(j))=lambdad(i(j))+2/3;
|
||||
end;
|
||||
% Equation 34, eta_1:
|
||||
etad(i)=1/2/pi*(kap1(i)+p^2*(p^2+2*z(i).^2).*kap0(i)-(1+5*p^2+z(i).^2)/4.*sqrt((1-x1(i)).*(x2(i)-1)));
|
||||
end
|
||||
|
||||
% the occulting star transits the source:
|
||||
% Table 3, Case IV.:
|
||||
%i=find(p<=1 & z<=(1-p)*1.0001);
|
||||
i=find(p<=1 & z<=(1-p)*1.0001 & abs(z-p)>10*eps);
|
||||
if any(i)
|
||||
%lam=0.5*pi;
|
||||
q=sqrt((x2(i)-x1(i))./(1-x1(i)));
|
||||
Kk=ellkVec(q);
|
||||
Ek=ellecVec(q);
|
||||
n=x2(i)./x1(i)-1;
|
||||
Pk=Kk-n/3.*rj(0,1-q.^2,1,1+n,TolFactor);
|
||||
% Equation 34, lambda_2:
|
||||
lambdad(i)=2/9/pi./sqrt(1-x1(i)).*((1-5*z(i).^2+p^2+x3(i).^2).*Kk+(1-x1(i)).*(z(i).^2+7*p^2-4).*Ek-3*x3(i)./x1(i).*Pk);
|
||||
j=z(i)<p;
|
||||
if any(j)
|
||||
lambdad(i(j))=lambdad(i(j))+2/3;
|
||||
end
|
||||
j=abs(p+z(i)-1)<=1e-8;
|
||||
if any(j)
|
||||
lambdad(i(j))=2/3/pi*acos(1-2*p)-4/9/pi*sqrt(p*(1-p))*(3+2*p-8*p*p);
|
||||
end
|
||||
% Equation 34, eta_2:
|
||||
etad(i)=p^2/2.*(p^2+2*z(i).^2);
|
||||
end
|
||||
|
||||
% Now, using equation (33):
|
||||
muo1=1-((1-u1-2*u2)*lambdae+(u1+2*u2)*lambdad+u2.*etad)/omega;
|
||||
% Equation 25:
|
||||
mu0=1-lambdae;
|
||||
|
||||
% the source is completely occulted:
|
||||
% Table 3, II.
|
||||
if p>=1
|
||||
i=z<=p-1;
|
||||
if any(i)
|
||||
%lambdad(i)=1;
|
||||
%etad(i)=1;
|
||||
%lambdae(i)=1;
|
||||
muo1(i)=0;
|
||||
mu0(i)=0;
|
||||
end;
|
||||
end
|
||||
|
||||
if ToSmooth>0
|
||||
deg=2;
|
||||
CorrectionRange=2e-4;
|
||||
FitRange=5*CorrectionRange;
|
||||
% i=find(z>=1-p-CorrectionRange & z<=1-p+CorrectionRange); % inner than II/III contact
|
||||
% if ~isempty(i)
|
||||
% if p<1
|
||||
% tmpz=1-p+[linspace(-FitRange,-CorrectionRange,deg*10).'; linspace(CorrectionRange,FitRange,deg*10).'];
|
||||
% else
|
||||
% tmpz=p-1+[linspace(-FitRange,-CorrectionRange,deg*10).'; linspace(CorrectionRange,FitRange,deg*10).'];
|
||||
% end
|
||||
% tmpz(tmpz<0)=[];
|
||||
% tmp_muo1=occultquadVec(p,tmpz,u1,u2,0,'ToSmooth',false);
|
||||
% if ~isempty(tmpz)
|
||||
% pol=IterativePolyfit(tmpz,tmp_muo1,deg,3);
|
||||
% muo1(i)=polyval(pol,z(i));
|
||||
% end
|
||||
% end;
|
||||
|
||||
% inner than II/III contact
|
||||
i=z>=1-p-CorrectionRange & z<=1-p;
|
||||
if ~isempty(i)
|
||||
%if p<1
|
||||
% tmpz=1-p+linspace(-FitRange,-CorrectionRange,deg*10).';
|
||||
%else
|
||||
% tmpz=p-1+linspace(-FitRange,-CorrectionRange,deg*10).';
|
||||
%end
|
||||
tmpz=abs(1-p)+linspace(-FitRange,-CorrectionRange,deg*10).';
|
||||
tmpz(tmpz<0)=[];
|
||||
tmp_muo1=occultquadVec(p,tmpz,u1,u2,0,'ToSmooth',false);
|
||||
if ~isempty(tmpz)
|
||||
pol=polyfit(tmpz,tmp_muo1,deg);
|
||||
muo1(i)=polyval(pol,z(i));
|
||||
end
|
||||
end;
|
||||
|
||||
% outer than II/III contact
|
||||
j=z>=1-p & z<=1-p+CorrectionRange;
|
||||
if ~isempty(j)
|
||||
%if p<1
|
||||
% tmpz=1-p+linspace(CorrectionRange,FitRange,deg*10).';
|
||||
%else
|
||||
% tmpz=p-1+linspace(CorrectionRange,FitRange,deg*10).';
|
||||
%end
|
||||
tmpz=abs(1-p)+linspace(CorrectionRange,FitRange,deg*10).';
|
||||
tmpz(tmpz<0)=[];
|
||||
tmp_muo1=occultquadVec(p,tmpz,u1,u2,0,'ToSmooth',false);
|
||||
if ~isempty(tmpz)
|
||||
pol=polyfit(tmpz,tmp_muo1,deg);
|
||||
muo1(j)=polyval(pol,z(j));
|
||||
end
|
||||
end;
|
||||
|
||||
% close to z=p
|
||||
if p>0.5
|
||||
deg=3;
|
||||
end;
|
||||
CorrectionRange=1e-2;
|
||||
FitRange=5*CorrectionRange;
|
||||
if p<0.5
|
||||
i=find(z-p>-CorrectionRange & z-p<min(CorrectionRange,1-2*p)); % near z~p
|
||||
else
|
||||
i=find(z-p>max(-CorrectionRange,1-2*p) & z-p<CorrectionRange); % near z~p
|
||||
end
|
||||
if ~isempty(i)
|
||||
if p<0.5
|
||||
tmpz=p+linspace(-FitRange,min(FitRange,1-2*p),deg*10).';
|
||||
else
|
||||
tmpz=p+linspace(max(-FitRange,1-2*p),FitRange,deg*10).';
|
||||
end
|
||||
tmpz(abs(tmpz-p)<CorrectionRange | tmpz<0)=[];
|
||||
tmp_muo1=occultquadVec(p,tmpz,u1,u2,0,'ToSmooth',false);
|
||||
if ~isempty(tmpz)
|
||||
pol=polyfit(tmpz,tmp_muo1,deg);
|
||||
muo1(i)=polyval(pol,z(i));
|
||||
end;
|
||||
end;
|
||||
|
||||
end
|
||||
|
||||
|
||||
if ToPlot
|
||||
plot([flipud(-z); z],[flipud(mu0); mu0],'.',[flipud(-z); z],[flipud(muo1); muo1],'.r');
|
||||
a=axis;
|
||||
axis([a(1) a(2) a(3) 1+(1-a(3))*0.1]);
|
||||
title({'Uniform source (blue) and quadratic model for the limb darkening (red)';sprintf('p=%g, u1=%g, u2=%g',p,u1,u2)});
|
||||
end;
|
||||
|
||||
|
||||
function rc=rc(x,y,ERRTOL)
|
||||
xt=zeros(size(x)); yt=xt;
|
||||
w=xt; s=xt;
|
||||
alamb=xt; ave=xt;
|
||||
|
||||
ERRTOL=.04*ERRTOL;
|
||||
THIRD=1/3;
|
||||
C1=.3;
|
||||
C2=1/7;
|
||||
C3=.375;
|
||||
C4=9/22;
|
||||
i=y>0;
|
||||
if any(i)
|
||||
xt(i)=x(i);
|
||||
yt(i)=y(i);
|
||||
w(i)=1;
|
||||
end;
|
||||
i=~i;
|
||||
if any(i)
|
||||
xt(i)=x(i)-y(i);
|
||||
yt(i)=-y(i);
|
||||
w(i)=sqrt(x(i))./sqrt(xt(i));
|
||||
end
|
||||
i=true(size(x));
|
||||
while any(i)
|
||||
alamb(i)=2*sqrt(xt(i)).*sqrt(yt(i))+yt(i);
|
||||
xt(i)=.25*(xt(i)+alamb(i));
|
||||
yt(i)=.25*(yt(i)+alamb(i));
|
||||
ave(i)=THIRD*(xt(i)+yt(i)+yt(i));
|
||||
s(i)=(yt(i)-ave(i))./ave(i);
|
||||
i(i)=abs(s(i))>ERRTOL;
|
||||
end;
|
||||
rc=w.*(1+s.^2.*(C1+s.*(C2+s.*(C3+s.*C4))))./sqrt(ave);
|
||||
% (C) Copr. 1986-92 Numerical Recipes Software
|
||||
|
||||
function rj=rj(x,y,z,p,ERRTOL)
|
||||
% built for x,z scalars and y,p vectors
|
||||
fac=ones(size(y));
|
||||
x=x*fac; z=z*fac; rj=0*fac;
|
||||
xt=rj; yt=rj; zt=rj; pt=rj; a=rj; b=rj; rho=rj; tau=rj; rcx=rj;
|
||||
sqrtx=rj; sqrty=rj; sqrtz=rj; alamb=rj; alpha=rj; beta=rj; Sum=rj; ave=rj;
|
||||
ave4=ave*ones(1,4);
|
||||
|
||||
ERRTOL=.05*ERRTOL;
|
||||
C1=3/14;
|
||||
C2=1/3;
|
||||
C3=3/22;
|
||||
C4=3/26;
|
||||
C5=.75*C3;
|
||||
C6=1.5*C4;
|
||||
C7=.5*C2;
|
||||
C8=C3+C3;
|
||||
i=p>0;
|
||||
if any(i)
|
||||
xt(i)=x(i);
|
||||
yt(i)=y(i);
|
||||
zt(i)=z(i);
|
||||
pt(i)=p(i);
|
||||
end;
|
||||
i=~i;
|
||||
if any(i)
|
||||
xt(i)=min([x(i),y(i),z(i)],[],2);
|
||||
zt(i)=max([x(i),y(i),z(i)],[],2);
|
||||
yt(i)=x(i)+y(i)+z(i)-xt(i)-zt(i);
|
||||
a(i)=1./(yt(i)-p(i));
|
||||
b(i)=a(i).*(zt(i)-yt(i)).*(yt(i)-xt(i));
|
||||
pt(i)=yt(i)+b(i);
|
||||
rho(i)=xt(i).*zt(i)./yt(i);
|
||||
tau(i)=p(i).*pt(i)./yt(i);
|
||||
rcx(i)=rc(rho(i),tau(i),ERRTOL);
|
||||
end
|
||||
%continue % ************** 1 ***************
|
||||
i=true(size(y));
|
||||
while any(i)
|
||||
sqrtx(i)=sqrt(xt(i));
|
||||
sqrty(i)=sqrt(yt(i));
|
||||
sqrtz(i)=sqrt(zt(i));
|
||||
alamb(i)=sqrtx(i).*(sqrty(i)+sqrtz(i))+sqrty(i).*sqrtz(i);
|
||||
alpha(i)=(pt(i).*(sqrtx(i)+sqrty(i)+sqrtz(i))+sqrtx(i).*sqrty(i).*sqrtz(i)).^2;
|
||||
beta(i)=pt(i).*(pt(i)+alamb(i)).^2;
|
||||
Sum(i)=Sum(i)+fac(i).*rc(alpha(i),beta(i),ERRTOL);
|
||||
fac(i)=.25*fac(i);
|
||||
xt(i)=.25*(xt(i)+alamb(i));
|
||||
yt(i)=.25*(yt(i)+alamb(i));
|
||||
zt(i)=.25*(zt(i)+alamb(i));
|
||||
pt(i)=.25*(pt(i)+alamb(i));
|
||||
ave(i)=.2*(xt(i)+yt(i)+zt(i)+pt(i)+pt(i));
|
||||
ave4(i,:)=ave(i)*ones(1,4);
|
||||
%delx=(ave-xt)/ave;
|
||||
%dely=(ave-yt)/ave;
|
||||
%delz=(ave-zt)/ave;
|
||||
%delp=(ave-pt)/ave;
|
||||
del4=(ave4-[xt yt zt pt])./ave4;
|
||||
i=max(abs(del4),[],2)>ERRTOL;
|
||||
end;
|
||||
ea=del4(:,1).*(del4(:,2)+del4(:,3))+del4(:,2).*del4(:,3);
|
||||
eb=del4(:,1).*del4(:,2).*del4(:,3);
|
||||
ec=del4(:,4).^2;
|
||||
ed=ea-3*ec;
|
||||
ee=eb+2*del4(:,4).*(ea-ec);
|
||||
rj=3*Sum+fac.*(1+ed.*(-C1+C5*ed-C6*ee)+eb.*(C7+del4(:,4).*(-C8+del4(:,4).*C4))+del4(:,4).*ea.*(C2-del4(:,4)*C3)-C2*del4(:,4).*ec)./(ave.*sqrt(ave));
|
||||
i=p<=0;
|
||||
if any(i)
|
||||
rj(i)=a.*(b.*rj(i)+3*(rcx(i)-rf(xt(i),yt(i),zt(i),ERRTOL)));
|
||||
end;
|
||||
% (C) Copr. 1986-92 Numerical Recipes Software
|
||||
|
||||
function rf=rf(x,y,z,ERRTOL)
|
||||
xyz=[x y z];
|
||||
sqrtxyz=zeros(size(xyz));
|
||||
alamb=sqrtxyz;
|
||||
ave=sqrtxyz;
|
||||
ave3=sqrtxyz;
|
||||
del3=sqrtxyz;
|
||||
|
||||
ERRTOL=.08*ERRTOL;
|
||||
THIRD=1/3;
|
||||
C1=1/24;
|
||||
C2=.1;
|
||||
C3=3/44;
|
||||
C4=1/14;
|
||||
xyzt=xyz;
|
||||
%continue % **************** 1 *****************
|
||||
i=true(size(x));
|
||||
while any(i)
|
||||
sqrtxyz(i,:)=sqrt(xyz(i,:));
|
||||
%alamb(i,:)=sqrtxyz(i,1).*(sqrtxyz(i,2)+sqrtxy(i,3))+sqrtxyz(i,2).*sqrtxyz(i,3);
|
||||
alamb(i,:)=sqrtxyz(i,1).*(sqrtxyz(i,2)+sqrtxyz(i,3))+sqrtxyz(i,2).*sqrtxyz(i,3);
|
||||
xyzt(i,:)=.25*(xyzt(i,:)+alamb(i,:)*ones(1,3));
|
||||
ave(i)=THIRD*(sum(xyzt(i,:),2));
|
||||
ave3(i,:)=ave(i)*ones(1,3);
|
||||
del3(i,:)=(ave3(i,:)-xyzt(i,:))./ave3(i,:);
|
||||
i(i)=max(abs(del3(i,:)),[],2)>ERRTOL;
|
||||
end;
|
||||
e2=del3(:,1).*del3(:,2)-del3(:,3)^2;
|
||||
e3=del3(:,1).*del3(:,2).*del3(:,3);
|
||||
rf=(1+(C1*e2-C2-C3*e3).*e2+C4*e3)./sqrt(ave);
|
||||
% (C) Copr. 1986-92 Numerical Recipes Software 0NL&WR2.
|
BIN
LaplaceCoeffs.mat
Normal file
BIN
LaplaceCoeffs.mat
Normal file
Binary file not shown.
287
anac_2_2p.py
Normal file
287
anac_2_2p.py
Normal file
|
@ -0,0 +1,287 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
abgewandelt von:
|
||||
Created on Fri Dec 3 08:49:07 2021
|
||||
|
||||
@author: dreizler
|
||||
"""
|
||||
import pdb
|
||||
|
||||
from scipy.stats import gamma,norm,beta,truncnorm
|
||||
import numpy as np
|
||||
|
||||
from types import SimpleNamespace
|
||||
|
||||
import dynesty
|
||||
from dynesty.utils import resample_equal
|
||||
|
||||
# system functions that are always useful to have
|
||||
import time, sys, os
|
||||
|
||||
# basic numeric setup
|
||||
import numpy as np
|
||||
|
||||
from dynesty import plotting as dyplot
|
||||
|
||||
from oct2py import Oct2Py
|
||||
|
||||
from multiprocessing import Pool
|
||||
|
||||
# plotting
|
||||
import matplotlib
|
||||
from matplotlib import pyplot as plt
|
||||
# inline plotting
|
||||
#%matplotlib inline
|
||||
|
||||
import csv
|
||||
import json
|
||||
import pickle
|
||||
|
||||
def parse_parameters(settings):
|
||||
p = []
|
||||
fix = {}
|
||||
for planet in settings["planets"]:
|
||||
for key, value in planet.items():
|
||||
fix[key] = [(None, None)] * len(settings["planets"])
|
||||
|
||||
i = 0
|
||||
for planet in settings["planets"]:
|
||||
for key, value in planet.items():
|
||||
if value["type"] != "fixed":
|
||||
p += [(i, key, value["type"], value["values"])]
|
||||
else:
|
||||
fix[key][i] = value["values"]
|
||||
i += 1
|
||||
|
||||
for key, value in settings["parameters"].items():
|
||||
if value["type"] != "fixed":
|
||||
p += [(-1, key, value["type"], value["values"])]
|
||||
else:
|
||||
fix[key] = value["values"]
|
||||
|
||||
return p, fix
|
||||
|
||||
def parse_settings():
|
||||
settings = json.load(open("parameter.json"))
|
||||
|
||||
p, fix = parse_parameters(settings)
|
||||
|
||||
return p, fix, settings["nkern"], settings["nlivepoints"]
|
||||
|
||||
|
||||
def generate_mockdata():
|
||||
np.random.seed(56101)
|
||||
|
||||
P_true=[12.3456, 29.3]
|
||||
Tmid0_true=[9.8765432, 15.4029]
|
||||
ror_true=[0.021, 0.027]
|
||||
aor_true=30
|
||||
mu_true=[1.24e-5, 3e-5]
|
||||
ex0_true=[0.01234, 0.00998]
|
||||
ey0_true=[0.02345, 0.0189]
|
||||
I0_true=[0.01745329, 0.0203]
|
||||
Omega0_true=[0.4014257, 0.369]
|
||||
sig_true = np.log(0.000084)
|
||||
|
||||
#t_mock = np.linspace(0,100,500)
|
||||
u1=0.5;
|
||||
u2=0.3;
|
||||
t=np.linspace(0,100,2) #0:0.002:100;
|
||||
tRV=np.linspace(0,100,1000)
|
||||
|
||||
init_octpy()
|
||||
LC,RV_o_r,Y_o_r,Z_o_r,O = octave.feval("AnalyticLC",P_true, Tmid0_true, ror_true, aor_true, mu_true, ex0_true, ey0_true, I0_true, Omega0_true, t, u1, u2,'tRV',tRV, nout=5)
|
||||
|
||||
#y_old = octave.AnalyticLC(P_true, Tmid0_true, ror_true, aor_true, mu_true, ex0_true, ey0_true, I0_true, Omega0_true, t, u1, u2)
|
||||
y_true2 = []
|
||||
for i in RV_o_r:
|
||||
y_true2.append(i[0])
|
||||
y_true2 = np.array(y_true2)
|
||||
y_true = y_true2[(np.isfinite(y_true2))]
|
||||
|
||||
y = y_true + 0.0001*np.random.randn(len(y_true)) #0.0001
|
||||
yerr = 0.00005 + np.zeros(len(y)) #0.00005
|
||||
|
||||
# plot results
|
||||
plt.figure(figsize=(10, 5))
|
||||
plt.errorbar(tRV, y, yerr=yerr, fmt='ko', ecolor='red')
|
||||
plt.plot(tRV, y_true, color='blue', lw=3)
|
||||
plt.xlabel(r'$t$')
|
||||
plt.ylabel(r'$y_true$')
|
||||
plt.tight_layout()
|
||||
plt.show()
|
||||
plt.close()
|
||||
|
||||
return y, yerr, y_true
|
||||
|
||||
def calculate(nkern, nlivepoints, parameters, fixed_parameters):
|
||||
ndim = len(parameters)
|
||||
p = Pool(nkern, init, [parameters, fixed_parameters])
|
||||
|
||||
#P, Tmid0, ror, aor, mu, ex0, ey0, I0, Omega0, sig
|
||||
dsampler = dynesty.NestedSampler(loglike, prior_transform, ndim=ndim, periodic=None,
|
||||
bound='multi', sample='auto',nlive=nlivepoints,pool=p, queue_size=nkern) #n*n/2 live points mind.
|
||||
dsampler.run_nested(dlogz=0.001)
|
||||
dres = dsampler.results
|
||||
with open('data_4dim.pickle', 'wb') as f:
|
||||
pickle.dump(dres, f, pickle.HIGHEST_PROTOCOL)
|
||||
|
||||
return dres
|
||||
|
||||
def create_plot(dres):
|
||||
P_true=[12.3456, 29.3]
|
||||
Tmid0_true=[9.8765432, 15.4029]
|
||||
ror_true=[0.021, 0.027]
|
||||
aor_true=30
|
||||
mu_true=[1.24e-5, 3e-5]
|
||||
ex0_true=[0.01234, 0.00998]
|
||||
ey0_true=[0.02345, 0.0189]
|
||||
I0_true=[0.01745329, 0.0203]
|
||||
Omega0_true=[0.4014257, 0.369]
|
||||
sig_true = np.log(0.000084)
|
||||
|
||||
truths = [P_true[0], P_true[1], sig_true]
|
||||
labels = [r'P $d$',r'P $d$', r'T $d$',r'T $d$', r'ex0', r'ex0', r'ey0', r'ey0',r'$\sigma \log(m/s)$']
|
||||
fig, axes = dyplot.traceplot(dres, truths=truths, truth_color='black', labels=labels, connect=True,
|
||||
fig=plt.subplots(ndim, 2, constrained_layout=True))
|
||||
fig.tight_layout()
|
||||
plt.savefig("tmp_2p/plot_test1.png")
|
||||
fig, axes = dyplot.cornerplot(dres, truths=truths, show_titles=True,
|
||||
title_kwargs={'y': 1.04}, labels=labels,
|
||||
fig=plt.subplots(ndim, ndim,constrained_layout=True))
|
||||
|
||||
fig.tight_layout()
|
||||
plt.savefig("tmp_2p/plot_test2.png")
|
||||
#lt.close()
|
||||
|
||||
def init(parameters, fixed_parameters):
|
||||
global p
|
||||
p = parameters
|
||||
global fix
|
||||
fix = fixed_parameters
|
||||
init_octpy()
|
||||
|
||||
def init_octpy():
|
||||
global octave
|
||||
octave = Oct2Py()
|
||||
BaseDir='/home/end/anal/endsversion/'
|
||||
octave.addpath(BaseDir)
|
||||
octave.addpath(BaseDir + 'AnalyticLC/')
|
||||
octave.addpath(BaseDir + 'FittingAndMath/')
|
||||
octave.addpath(BaseDir + 'FluxCalculation/')
|
||||
octave.LaplaceCoeffs('load',BaseDir + 'LaplaceCoeffs.mat')
|
||||
|
||||
# Prior transforms for nested samplers:
|
||||
def transform_uniform(x, hyperparameters):
|
||||
a, b = hyperparameters
|
||||
return a + (b-a)*x
|
||||
|
||||
def transform_loguniform(x, hyperparameters):
|
||||
a, b = hyperparameters
|
||||
la = np.log(a)
|
||||
lb = np.log(b)
|
||||
return np.exp(la + x * (lb - la))
|
||||
|
||||
def transform_normal(x, hyperparameters):
|
||||
mu, sigma = hyperparameters
|
||||
return norm.ppf(x, loc=mu, scale=sigma)
|
||||
|
||||
def transform_beta(x, hyperparameters):
|
||||
a, b = hyperparameters
|
||||
return beta.ppf(x, a, b)
|
||||
|
||||
def transform_exponential(x, hyperparameters):
|
||||
a = hyperparameters
|
||||
return gamma.ppf(x, a)
|
||||
|
||||
def transform_truncated_normal(x, hyperparameters):
|
||||
mu, sigma, a, b = hyperparameters
|
||||
ar, br = (a - mu) / sigma, (b - mu) / sigma
|
||||
return truncnorm.ppf(x, ar, br, loc=mu, scale=sigma)
|
||||
|
||||
def transform_modifiedjeffreys(x, hyperparameters):
|
||||
turn, hi = hyperparameters
|
||||
return turn * (np.exp( (x + 1e-10) * np.log(hi/turn + 1)) - 1)
|
||||
|
||||
# prior transform
|
||||
def prior_transform(utheta):
|
||||
global p;
|
||||
global fix;
|
||||
|
||||
transforms = [x[2] for x in p]
|
||||
hyperparams = [x[3] for x in p]
|
||||
transformed_priors = np.zeros(len(utheta))
|
||||
for k,param in enumerate(utheta):
|
||||
if transforms[k] == 'uniform':
|
||||
transformed_priors[k] = transform_uniform(param,hyperparams[k])
|
||||
elif transforms[k] == 'loguniform':
|
||||
transformed_priors[k] = transform_loguniform(param,hyperparams[k])
|
||||
elif transforms[k] == 'normal':
|
||||
transformed_priors[k] = transform_normal(param,hyperparams[k])
|
||||
else:
|
||||
raise ValueError("Transform not known")
|
||||
|
||||
return transformed_priors
|
||||
|
||||
# log-likelihood
|
||||
def loglike(theta):
|
||||
global octave;
|
||||
global p;
|
||||
global fix;
|
||||
parameters = fix.copy()
|
||||
|
||||
for i in range(len(theta)):
|
||||
planetid = p[i][0]
|
||||
keyname = p[i][1]
|
||||
if planetid == -1:
|
||||
parameters[keyname] = theta[i]
|
||||
else:
|
||||
parameters[keyname][planetid] = theta[i]
|
||||
|
||||
n = SimpleNamespace(**parameters)
|
||||
|
||||
u1=0.5;
|
||||
u2=0.3;
|
||||
t=np.linspace(0,100,2) #0:0.002:100;
|
||||
tRV=np.linspace(0,100,1000)
|
||||
|
||||
try:
|
||||
LC,RV_o_r,Y_o_r,Z_o_r,O = octave.feval("AnalyticLC",n.P, n.Tmid0, n.ror, n.aor, n.mu, n.ex0, n.ey0, n.I0, n.Omega0, t, u1, u2,'tRV',tRV, nout=5)
|
||||
|
||||
model =[]
|
||||
for i in RV_o_r:
|
||||
model.append(i[0])
|
||||
model = np.array(model)
|
||||
model23 = model[~(np.isnan(model))]
|
||||
model2 = model23[~(np.iscomplex(model23))]
|
||||
#print("Model:")
|
||||
#print(model2)
|
||||
#print("y:")
|
||||
#print(y)
|
||||
if (model2.size == 0):
|
||||
#print("error")
|
||||
return -np.inf
|
||||
inv_sigma2 = 1.0 / (n.yerr**2 + np.exp(2 * n.sig))
|
||||
ret = -0.5 * (np.sum((n.y-model2)**2 * inv_sigma2 - np.log(inv_sigma2)))
|
||||
#if np.imag(ret)!=0:
|
||||
# return -np.inf
|
||||
#print(ret)
|
||||
return ret
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return -np.inf
|
||||
|
||||
def main():
|
||||
parameters, fixed, nkern, nlivepoints = parse_settings()
|
||||
|
||||
y, yerr, y_true = generate_mockdata()
|
||||
|
||||
fixed["y"] = y
|
||||
fixed["yerr"] = yerr
|
||||
fixed["y_true"] = y_true
|
||||
|
||||
results = calculate(nkern, nlivepoints, parameters, fixed)
|
||||
create_plot(results)
|
||||
|
||||
main()
|
BIN
octave-workspace
Normal file
BIN
octave-workspace
Normal file
Binary file not shown.
39
parameter.json
Normal file
39
parameter.json
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"planets": [
|
||||
{
|
||||
"P": {"type": "uniform", "values": [11,13]},
|
||||
"Tmid0": {"type": "fixed", "values": 9.876},
|
||||
"ex0": {"type": "fixed", "values": 0.01234},
|
||||
"ey0": {"type": "fixed", "values": 0.02345},
|
||||
"ror": {"type": "fixed", "values": 0.021},
|
||||
"mu": {"type": "fixed", "values": 1.24e-5},
|
||||
"I0": {"type": "fixed", "values": 0.01745},
|
||||
"Omega0": {"type": "fixed", "values": 0.4014257}
|
||||
},
|
||||
{
|
||||
"P": {"type": "uniform", "values": [29,31]},
|
||||
"Tmid0": {"type": "fixed", "values": 15.4029},
|
||||
"ex0": {"type": "fixed", "values": 0.00998},
|
||||
"ey0": {"type": "fixed", "values": 0.0189},
|
||||
"ror": {"type": "fixed", "values": 0.027},
|
||||
"mu": {"type": "fixed", "values": 3e-5},
|
||||
"I0": {"type": "fixed", "values": 0.0203},
|
||||
"Omega0": {"type": "fixed", "values": 0.369}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"sig": {"type": "uniform", "values": [-10000,100]},
|
||||
"aor": {"type": "fixed", "values": 30},
|
||||
"u1" : {"type": "fixed", "values": 0.5},
|
||||
"u2" : {"type": "fixed", "values": 0.3}
|
||||
},
|
||||
|
||||
"LC_datapath": "/dev/null",
|
||||
"RV_datapath": "/dev/null",
|
||||
"AnalyticLC_datapath": "/dev/null",
|
||||
"atrometry_datapath": "/dev/null",
|
||||
|
||||
"nlivepoints": 1000,
|
||||
"nkern": 16
|
||||
}
|
||||
|
3
requirements.txt
Normal file
3
requirements.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
oct2py
|
||||
dynesty
|
||||
matplotlib
|
Loading…
Reference in a new issue