예제 #1
0
def plot_satellite_orbit_plotly(eccentricity, orbital_period, inclination,
                                RAAN, argument_of_perigee, number):

    standard_gravitational_parameter = 3.986004418e14
    orbital_period = int(orbital_period * 60)
    semi_major_axis = calculate_semi_major_axis(
        orbital_period, standard_gravitational_parameter)
    earth_radius = 6.371009e6
    semi_major_axis = semi_major_axis / earth_radius

    ke = pyasl.KeplerEllipse(
        semi_major_axis,
        orbital_period,
        e=eccentricity,
        Omega=RAAN,
        i=inclination,
        w=argument_of_perigee,
    )
    t = np.linspace(0, orbital_period, 200)
    cis_vector = ke.xyzPos(t)
    ascn, descn = ke.xyzNodes_LOSZ()

    orbit = go.Scatter3d(
        x=cis_vector[:, 0],
        y=cis_vector[:, 1],
        z=cis_vector[:, 2],
        mode="lines",
        name=f"Orbit {number}",
    )
    ascending_node = go.Scatter3d(
        x=[ascn[0]],
        y=[ascn[1]],
        z=[ascn[2]],
        mode="markers",
        name=f"Ascending node {number}",
    )
    descending_node = go.Scatter3d(
        x=[descn[0]],
        y=[descn[1]],
        z=[descn[2]],
        mode="markers",
        name=f"Descending node {number}",
    )
    periapsis = go.Scatter3d(
        x=[cis_vector[0, 0]],
        y=[cis_vector[0, 1]],
        z=[cis_vector[0, 2]],
        mode="markers",
        name=f"Periapsis {number}",
    )
    return [orbit, ascending_node, descending_node, periapsis]
def zeroD_e(plotTitle):
    # Independent Variables
    waterDepth = 4000  # (m)
    albedo = c.albedo_Earth  # how much light gets reflected by atmosphere
    epsilon = c.epsilonSurface_Earth  # how good of a blackbody the body is
    R_star = c.R_Sun  # Radius of star (AU)
    d_planet = c.d_Earth  # Distance of planet from body it is orbiting  (AU)
    T_star = c.T_Sun  # Surface Temperature of star (K)
    e = float(input("Eccentricity (0.01671): "))  # Eccentricity of planet
    periodFractions = 1000  # number of fractions of period

    # Initialisation
    heat_capacity = waterDepth * 1000 * 4200  # (J / K m^2)
    period = math.pow(d_planet, 1.5)  # Period of planet's orbit (years)
    Power_output = PowerOut(T_star)  # Power output of star (Watts/m^2)
    solar_Constant = planetInsolation(Power_output, R_star, d_planet)
    t = [0]
    T = [0]

    ke = pyasl.KeplerEllipse(d_planet, period, e, Omega=0., i=0.0, w=0.0)
    heat_in = generate_heat_in(ke, periodFractions, d_planet, solar_Constant,
                               albedo)
    # print(*heat_in, sep="\n") <- Used for debugging

    # Generating Surface Temperature Data
    heat_content = heat_capacity * T[0]  # (J / m^2)
    periods = int(input('Number of periods (1500): '))
    for i in range(periods):
        for j in range(periodFractions):
            t.append(t[-1] + (period / periodFractions))
            heat_out = epsilon * PowerOut(T[-1])

            heat_content += (heat_in[j] - heat_out) * (period /
                                                       periodFractions) * c.SiY
            T.append(heat_content / heat_capacity)  # (K)

    # Plotting data
    fig = plt.figure(plotTitle)
    plt.plot(t, T, c='r', linewidth=1.75)

    # Modifying Visual aspect of plot
    fig = beautifyPlot(fig, plotTitle, 'time (years)',
                       'Surface temperature (K)')
    fig = plotCelciusLine(fig, t[0], t[-1])
    fig = addLegend(fig)

    return fig
def insolation_single(plotTitle, iterated, parsedE):
    if not iterated:
        e = float(input("Eccentricity: "))
    else:
        e = parsedE

    # Independent Variables
    R_star = c.R_Sun  # Radius of star (AU)
    d_planet = c.d_Earth  # Distance of planet from body it is orbiting  (AU)
    T_star = c.T_Sun  # (K)
    periodFractions = 1000  # fraction of period acts as timeStep

    # Initialisation
    period = math.pow(d_planet, 1.5)
    solar_Constant = solarConstant(T_star, R_star, d_planet)

    t = []
    L = []
    ke = pyasl.KeplerEllipse(d_planet, period, e, Omega=0., i=0.0, w=0.0)

    # Generating Data
    for i in range(periodFractions):
        t.append(((i / periodFractions) * period) * 365.25)
        r = ke.radius((i / periodFractions) * period)  # Applying Kepler's First Law to find r
        newL = solar_Constant / (r / d_planet) ** 2  # Calculating insolation based on position in orbit relative to the starting point
        L.append(newL)

    if not iterated:
        # Plotting data
        fig = plt.figure(plotTitle)
        plt.plot(t, L, c='r', linewidth=1.75)

        # Modifying Visual aspect of plot
        fig = beautifyPlot(fig, plotTitle + ' (e=' + str(e) + ')', 'time (days)', 'Light Insolation (W/m^2)')

        return fig
    else:
        return t, L
예제 #4
0
Produced for "Python for Mechanical and Aerospace Engineering" by Alex Kenan, ISBN 978-1-7360606-0-5 and 978-1-7360606-1-2.
Copyright © 2020 Alexander Kenan. Some Rights Reserved. This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. 
See http://creativecommons.org/licenses/by-nc-sa/4.0/ for more information.
"""
import numpy as np
from PyAstronomy import pyasl
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import mpl_toolkits.mplot3d.axes3d as p3

# Create a Keplerian elliptical orbit with
# semi-major axis of 1.0 length units,
# a period of 1.0 time units, eccentricity of 0.5,
# longitude of ascending node of 0 degrees, an inclination
# of 30 deg, and a periapsis argument of 0 deg.
orbit = pyasl.KeplerEllipse(a=1.0, per=1.0, e=0.50, Omega=0.0,
                            i=30.0, w=0.0)

# Get a time axis
t = np.linspace(0, 4, 200)

# Calculate the orbit position at the given points
# in a Cartesian coordinate system.
pos = orbit.xyzPos(t)

# Plot x and y coordinates of the orbit with a few different options

# 2D, animated, and space
'''
plt.style.use('dark_background')
fig, ax = plt.subplots()
l = plt.plot(pos[::,1], pos[::,0], 'k-')
예제 #5
0
def calcOrbit():
    """
    This is a tool to produce a Keplerian orbit in RA,Dec,RV to verify exosoft.
    It just computes Kepler orbit positions and velocities then rotates
    them into the observed values in the plane of the sky.

    NOTE: the accuracy of the output values is to 'one part in 10^5',
          due to the simple center differencing used to calculate the velocities
          from the positions and times.

    Outputs are 2 files matching formats used in exosoft DI and RV.
    outBaseName+'DIdata.dat' has columns:
    #1. JD
    #2. RA (x) ["]
    #3. RA ERROR ["]
    #4. Dec (y) ["]
    #5. Dec ERROR ["]
    outBaseName+'RVdata.dat' has colunns:
    #1. JD
    #6. RV of primary (or secondary) rel to CofM [m/s]
    #7. RV ERROR [m/s]
    """
    quiet = False
    ## Important output directory and filename settings 
    ###################################################
    # Computer Directory
    outDir='./' 
    # Base name for output files
    outBaseName='syntheticdata_'
    
    ## Basic sample settings
    ########################
    NumDataPointsOutRV = 25 #must be much less than 10000.  values between 10-500 are suitable.
    NumDataPointsOutDI = 10 #must be much less than 10000.  values between 10-500 are suitable.
    storePrimaryRVs = True
    percentError = 0.5 #error is set to a percentage of the median
    realizeErrors = True
    percentCoverage = 100.00 #percent of total orbit for data to span.  Over 100% is ok if you want overlapping data.

    ## System settings
    ##################
    M_secondary =  1.0*(const.M_jup.value/const.M_sun.value)    # [Solar masses]
    M_primary = 1.0 # [Solar masses]
    distance = 20.0 # [parsecs]
    #Orbital Elements
    TimeLastPeri =2450639.5  # [JD]
    e =0.048 # Eccentricity [unitless]
    period = 11.9 # [years]
    Omega =100.6*np.pi/180# Longitude of ascending node [deg]
    omega = 14.8*np.pi/180 # Argument of periastron [deg]
    i = 45.0*np.pi/180 # Inclination [deg]

    km_to_arcsec = 1.0/(const.au.value/1000.0)/distance # convert km to arcsecond
    massratio=M_primary/M_secondary
    mu = const.G.cgs.value*M_primary*(const.M_sun.value*1000.0)*(1.0 + 1.0/massratio) #gravitational parameter
    a = (mu*(period*sec_per_year)**2/4.0/np.pi**2)**(1.0/3.0) #in cm
    a_km = a/1.0e5 #to km
    a_AU = a_km/(const.au.value/1000.0) #to AU
    a2 = a_km/(massratio + 1.0)
    a1 = a_km - a2 # Semimajor axis of the low-mass component (in km)

    # print input orbital elements
    if quiet==False:
        print("\n\nOrbital Elements Used:\ne = "+str(e))
        print("period = "+str(period)+" Years")
        print("LongAN = "+str(Omega*180.0/np.pi)+" deg")
        print("ArgPeri = "+str(omega*180.0/np.pi)+" deg")
        print("a_total = "+str(a_AU)+" AU")
        print("inclination = "+str(i*180.0/np.pi)+" deg")
        print("Time of Last Periapsis = "+str(TimeLastPeri)+" JD")
        print("Mass 1 = "+str(M_primary)+" Msun")
        print("Mass 2 = "+str(M_secondary)+" Msun")
        print("Mass 2 = "+str(M_secondary*(const.M_sun.value/const.M_jup.value))+" Mjupiter")
        print("System distance = "+str(distance)+" PC, or "+str(1.0/(distance/1000.0))+' [mas]')
        #settings prints
        if storePrimaryRVs:
            print("Saving RVs of primary star relative to Center of Mass\n")
        else:
            print("Saving RVs of companion relative to Center of Mass\n")
        print('Errors were calculated as '+str(percentError)+"% of the median value in the observables")
        if realizeErrors:
            print('Data values were realized from the errors')
        else:
            print('Data values are perfect with NO realization of the errors')
        print(str(NumDataPointsOutRV)+" RV, and "+str(NumDataPointsOutDI)+" DI epochs will be calculated and stored")
        print('The data will cover '+str(percentCoverage)+'% of the total orbit.\n')

    # Positions of both components in km relative to center of mass
    ke = pyasl.KeplerEllipse(a1, period, e=e, Omega=0.)
    NptsBIG = 10000
    t = (np.arange(NptsBIG) - 1)/(NptsBIG - 2.)*period

    ## update t to cover the percent of total orbit requested.
    #print 'len(t) before = '+str(len(t))
    t2=np.empty(( int((percentCoverage/100)*len(t)) ))
    if percentCoverage<=100.0:
        t2[0:t2.size]=t[0:t2.size]
    elif percentCoverage<200.0:
        t2[0:t.size]=t
        t2[t.size:]=t[0:( int(((percentCoverage-100.0)/100)*len(t)) )]+period
    t=t2
    #print 'len(t) after = '+str(len(t))
    pos_A = ke.xyzPos(t)
    pos_B = -pos_A/massratio

    # Velocities in km/s using centered differencing
    vel_A = (pos_A[2:] - pos_A[:-2])/(t[2] - t[0])/(86400*365.2422)
    pos_A = pos_A[1:-1]
    vel_B = (pos_B[2:] - pos_B[:-2])/(t[2] - t[0])/(86400*365.2422)
    pos_B = pos_B[1:-1]
    t = t[1:-1]

    # Construct rotation matrix (from wikipedia [http://en.wikipedia.org/wiki/Orbital_elements#Euler_angle_transformations])
    x1 = np.cos(Omega)*np.cos(omega) - np.sin(Omega)*np.cos(i)*np.sin(omega)
    x2 = np.sin(Omega)*np.cos(omega) + np.cos(Omega)*np.cos(i)*np.sin(omega)
    x3 = np.sin(i)*np.sin(omega)

    y1 = -np.cos(Omega)*np.sin(omega) - np.sin(Omega)*np.cos(i)*np.cos(omega)
    y2 = -np.sin(Omega)*np.sin(omega) + np.cos(Omega)*np.cos(i)*np.cos(omega)
    y3 = np.sin(i)*np.cos(omega)

    z1 = np.sin(i)*np.sin(Omega)
    z2 = -np.sin(i)*np.cos(Omega)
    z3 = np.cos(i)

    rotmat = np.asarray([[x1, x2, x3], [y1, y2, y3], [z1, z2, z3]])

    # Rotate positions, velocities
    pos_A = np.dot(pos_A, rotmat)
    vel_A = np.dot(vel_A, rotmat)
    pos_B = np.dot(pos_B, rotmat)
    vel_B = np.dot(vel_B, rotmat)

    ## Randomly re-sample position, vel and time arrays to requested number of samples
    pos_Anew = []
    pos_Bnew = []
    vel_Anew = []
    vel_Bnew = []
    tnew = []
    i=0
    js=[]
    while i<NumDataPointsOutRV:
        j = np.random.randint(0,len(t))
        if j not in js:
            js.append(j)
            pos_Anew.append(pos_A[j])
            pos_Bnew.append(pos_B[j])
            vel_Anew.append(vel_A[j])
            vel_Bnew.append(vel_B[j])
            tnew.append(t[j])
            i+=1

    pos_A = np.array(pos_Anew)
    pos_B = np.array(pos_Bnew)
    vel_A = np.array(vel_Anew)
    vel_B = np.array(vel_Bnew)
    t=np.array(tnew)

    #make an ary for raw forms of the data.
    data = np.zeros((pos_A.shape[0], 8))
    data[:, 0] = t*2*np.pi/period #1. phase
    data[:, 1] = t # 2. time (years)
    data[:, 2] = pos_A[:, 0]*km_to_arcsec #3. x position of secondary (arcsec)
    data[:, 3] = pos_A[:, 1]*km_to_arcsec #4. y position of secondary (arcsec)
    data[:, 4] = vel_A[:, 2] #5. radial velocity of secondary (km/s)
    data[:, 5] = pos_B[:, 0]*km_to_arcsec #6. x position of primary (arcsec)
    data[:, 6] = pos_B[:, 1]*km_to_arcsec #7. y position of primary (arcsec)
    data[:, 7] = vel_B[:, 2] #8. radial velocity of primary (km/s)

    #update raw forms to initial NewBEAT versions
    data2 = np.zeros((pos_A.shape[0],5))
    data2[:,0] = data[:, 1]*days_per_year+TimeLastPeri #JD
    data2[:,1] = pos_A[:, 1]*km_to_arcsec - pos_B[:, 1]*km_to_arcsec #Ythi=Xplot=RA  separation between two bodies based on primary being at 0,0 ["]
    data2[:,2] = pos_A[:, 0]*km_to_arcsec - pos_B[:, 0]*km_to_arcsec #Xthi=Yplot=Dec  separation between two bodies based on primary being at 0,0 ["]
    data2[:,3] = vel_B[:, 2]*1000.0 # RV of primary compared to center of mass origin[ m/s]
    data2[:,4] = vel_A[:, 2]*1000.0 # RV of secondary compared to center of mass origin[ m/s]

    #calculate error and use it to realize the errors in the DI data if requested
    errorRA = np.median(np.abs(data2[:,1]))*(percentError/100.0)
    errorDec = np.median(np.abs(data2[:,2]))*(percentError/100.0)
    errorRA = np.max([errorRA,errorDec])
    errorDec = np.max([errorRA,errorDec])
    #print 'Using larger of two DI errors for both = '+str(errorDec)
    if realizeErrors:
        for i in range(pos_A.shape[0]):
            data2[i,1]+=np.random.normal(0,errorRA)
            data2[i,2] += np.random.normal(0,errorDec)
    #calculate error and use it to realize the errors in the RV data if requested
    errorRVprimary = np.median(np.abs(data2[:,3]))*(percentError/100.0)
    errorRVsecondary = np.median(np.abs(data2[:,4]))*(percentError/100.0)
    if realizeErrors:
        for i in range(pos_A.shape[0]):
            data2[i,3] += np.random.normal(0,errorRVprimary)
            data2[i,4] += np.random.normal(0,errorRVsecondary)

    #########################################################
    #load up data for into arys for exosoft DI, exosoft RV.
    #########################################################
    #dataDI2 has columns:
    #1. JD
    #2. RA (x) ["]
    #3. RA ERROR ["]
    #4. Dec (y) ["]
    #5. Dec ERROR ["]
    #dataRV has colunns:
    #1. JD
    #6. RV of primary (or secondary) rel to CofM [m/s]
    #7. RV ERROR [m/s]
    dataDI2 = np.empty((pos_A.shape[0],5))
    dataDI2[:,0] = data2[:, 0]#1. JD
    dataDI2[:,1] = data2[:,1]#2. RA (x) ["]
    dataDI2[:,2] = errorRA #3. RA ERROR ["]
    dataDI2[:,3] = data2[:,2]#4. Dec (y) ["]
    dataDI2[:,4] = errorDec#5. Dec ERROR ["]
    dataRV = np.empty((pos_A.shape[0],3))
    dataRV[:,0] = data2[:, 0]#1. JD
    if storePrimaryRVs:
        dataRV[:,1] = data2[:,3] #RV primary [m/s]
        dataRV[:,2] = errorRVprimary#RV primary error [m/s]
    else:
        dataRV[:,1] = data2[:,4]#RV secondary [m/s]
        dataRV[:,2] = errorRVsecondary#RV secondary error [m/s]

    if True:
        ## Randomly re-sample the DI data to half that of the RV to mimick the fact that there is usually more much RV data than DI data
        dataDI3=[]
        i=0
        js=[]
        while i<NumDataPointsOutDI:
            j = np.random.randint(0,len(dataDI2[:,0]))
            if j not in js:
                js.append(j)
                dataDI3.append(dataDI2[j,:])
                i+=1
        dataDI3 = np.array(dataDI3)
    else:
        dataDI3 = dataDI2
    #print "resulting RV data files have "+str(len(dataRV[:,0]))+" epochs"
    #print "resulting DI data files have "+str(len(dataDI3[:,0]))+" epochs"

    ##write files to disk
    if False:
        # raw all-in-one format, NOT for ExoSOFT use.
        np.savetxt(os.path.join(outDir,outBaseName+'.dat'), data, fmt="%.10g")
    if True:
        # 2 files for ExoSOFT use
        np.savetxt(os.path.join(outDir,outBaseName+'RVdata.dat'), dataRV, fmt="%.10g")
        np.savetxt(os.path.join(outDir,outBaseName+'DIdata.dat'), dataDI3, fmt="%.10g")
    if quiet==False:
        print('\nOutput data files written to:\n'+outDir)
예제 #6
0
def modelview(StellarRadius, limb1, limb2, PlanetRadius, PlanetImpact,
              MoonRadius, MoonAxis, MoonEccentricity, MoonAscendingNode,
              MoonLongitudePeriastron, MoonInclination, PhaseToHighlight,
              Quality):
    """Calculate the 3D model view. This is the vector version (v2)"""

    # Convert values from km to internal measure (stellar radius = 1)
    PlanetRadius = PlanetRadius / StellarRadius
    MoonRadius = MoonRadius / StellarRadius
    MoonAxis = MoonAxis / StellarRadius

    # Make background unicolor black or white
    #allwhite = plt.Circle((0, 0), 100, color=(1, 1, 1))
    #allblack = plt.Circle((0, 0), 100, color=(0, 0, 0))
    #plt.gcf().gca().add_artist(allwhite)

    # Alternatively plot a gradient map as background
    X = [[-1, 0], [0, 1]]
    plt.imshow(X,
               interpolation='bicubic',
               cmap=cm.gray,
               extent=(-1.1, 1.1, -1.1, 1.1),
               alpha=1)

    # Star
    StarQuality = Quality
    StarQuality = 100

    for i in range(StarQuality):
        Impact = i / float(StarQuality)
        LimbDarkening = QuadraticLimbDarkening(Impact, limb1, limb2)
        Sun = plt.Circle((0, 0),
                         1 - i / float(StarQuality),
                         color=(LimbDarkening, LimbDarkening, LimbDarkening))
        # for a yellow shaded star, replace the last LimbDarkening with 0
        plt.gcf().gca().add_artist(Sun)

    # Moon's orbit: Kepler ellipse normalized to 1x1 stellar radii
    Ellipse = pyasl.KeplerEllipse(MoonAxis,
                                  MoonAxis,
                                  e=MoonEccentricity,
                                  Omega=MoonAscendingNode,
                                  w=MoonLongitudePeriastron,
                                  i=MoonInclination)
    NumerOfSamples = 1 / float(Quality)
    time = np.linspace(0., MoonAxis, Quality)
    coordinates = np.zeros((len(time), 3), dtype=np.float)
    for i in xrange(len(time)):
        coordinates[i, ::] = Ellipse.xyzPos(time[i])

    OccultedDataPoints = []  # To clip the moon ellipse "behind" the planet
    for i in range(Quality / 2):
        CurrentMoonImpact = coordinates[i, 1]
        CurrentHorizontalMoonPosition = coordinates[i, 0]
        CurrentDistanceMoonPlanet = sqrt(
            CurrentMoonImpact**2 +
            CurrentHorizontalMoonPosition**2) * StellarRadius
        if CurrentDistanceMoonPlanet < PlanetRadius * StellarRadius:
            OccultedDataPoints.append(i)
    if len(OccultedDataPoints) > 0:
        FirstOcculted = OccultedDataPoints[0]
        LastOcculted = OccultedDataPoints[-1] + 1
        plt.plot(-coordinates[:FirstOcculted, 0],
                 coordinates[:FirstOcculted, 1] + PlanetImpact,
                 'k',
                 zorder=5)
        plt.plot(-coordinates[LastOcculted:, 0],
                 coordinates[LastOcculted:, 1] + PlanetImpact,
                 'k',
                 zorder=5)
    else:
        plt.plot(-coordinates[::, 0],
                 coordinates[::, 1] + PlanetImpact,
                 'k',
                 zorder=5)

    # Planet
    PlanetCircle = plt.Circle((0, PlanetImpact),
                              PlanetRadius,
                              color='k',
                              zorder=4)
    plt.gcf().gca().add_artist(PlanetCircle)

    # Moon
    PosPhase = PhaseToHighlight / float(NumerOfSamples)
    coordinates[1, ::] = Ellipse.xyzPos(time[PosPhase])
    if PhaseToHighlight < 0.5:
        CurrentOrder = 2  # behind the planet
    else:
        CurrentOrder = 4  # in front of the planet
    MoonCircle = plt.Circle(
        (-coordinates[1, 0], coordinates[1, 1] + PlanetImpact),
        MoonRadius,
        color='k',
        zorder=CurrentOrder)
    plt.gcf().gca().add_artist(MoonCircle)
    # Square not functional?
    plt.axis([-1.1, +1.1, -1.1, +1.1], set_aspect='equal', fontsize=16)
    return plt
예제 #7
0
def riverwithoutnoise(StellarRadius, limb1, limb2, PlanetRadius, PlanetAxis,
                      PlanetImpact, PlanetPeriod, MoonRadius, MoonAxis,
                      MoonEccentricity, MoonAscendingNode,
                      MoonLongitudePeriastron, MoonInclination,
                      ShowPlanetMoonEclipses, Quality, NumberOfSamples):
    """Core function projecting Kepler Moon Ellipse onto PixelGrid"""

    # Moon's orbit: Kepler ellipse normalized to 1x1 stellar radii
    NormalizedMoonAxis = MoonAxis / StellarRadius
    NormalizedMoonRadius = MoonRadius / StellarRadius
    CounterFullEclipses = 0
    CounterPartialEclipses = 0
    CurrentEclipsedRatio = 0
    Ellipse = pyasl.KeplerEllipse(NormalizedMoonAxis,
                                  NormalizedMoonAxis,
                                  e=MoonEccentricity,
                                  Omega=MoonAscendingNode,
                                  w=MoonLongitudePeriastron,
                                  i=MoonInclination)
    time = np.linspace(0., NormalizedMoonAxis, NumberOfSamples)
    coordinates = np.zeros((len(time), 3), dtype=np.float)
    for i in xrange(len(time)):
        coordinates[i, ::] = Ellipse.xyzPos(time[i])
    StretchSpace = 5  # 5 Grid size [multiples of planet transit duration]
    UnStretchedTransitDuration = PlanetPeriod / pi * arcsin(
        sqrt((MoonRadius + StellarRadius)**2) / PlanetAxis)
    cache = np.zeros((NumberOfSamples, Quality), dtype=np.float)
    output = np.zeros((NumberOfSamples, StretchSpace * Quality),
                      dtype=np.float)

    ma = forTrans.MandelAgolLC()  # Prepare light curves
    ma["T0"] = 0
    ma["b"] = 0.
    ma["linLimb"] = limb1
    ma["quadLimb"] = limb2
    ma["per"] = PlanetPeriod
    ma["a"] = PlanetAxis / StellarRadius
    ma["p"] = MoonRadius / StellarRadius
    time = np.linspace(ma["per"] - (0.5 * UnStretchedTransitDuration),
                       ma["per"] + (0.5 * UnStretchedTransitDuration), Quality)

    for i in range(NumberOfSamples):  # Fetch curves: The core of this function
        CurrentMoonImpact = coordinates[i, 1]  # Position-dependent moon impact
        CurrentHorizontalMoonPosition = coordinates[i, 0]
        ma["i"] = ImpactToInclination(CurrentMoonImpact + PlanetImpact,
                                      StellarRadius, PlanetAxis)
        cache[i, ::] = ma.evaluate(time)  # Fetch each curve

        # Mutual eclipses: calculate distance moon --> planet [km]
        if ShowPlanetMoonEclipses:
            CurrentDistanceMoonPlanet = sqrt(
                CurrentMoonImpact**2 +
                CurrentHorizontalMoonPosition**2) * StellarRadius
            CurrentEclipsedRatio = EclipsedRatio(CurrentDistanceMoonPlanet,
                                                 PlanetRadius, MoonRadius)

        for k in range(Quality):  # Transform flux from e.g. 0.995 to -5ppm
            cache[i, k] = -(1 - cache[i, k]) * 10**6
            # And reduce the flux according to the eclipsed area
            if ShowPlanetMoonEclipses and cache[i, k] < 0:
                cache[i, k] = -(1 - cache[i, k]) * (1 - CurrentEclipsedRatio)

    for i in range(NumberOfSamples):  # Apply time shift due to moon orbit
        for k in range(Quality):
            HorizontalPixelPosition = (coordinates[i, 0] * Quality) / 2
            MidShift = (0.5 * StretchSpace - 0.5) * Quality
            output[i, k + HorizontalPixelPosition + MidShift] = cache[i, k]

    return output
예제 #8
0
    def __init__(self,
                 planes=1,
                 nodes_per_plane=4,
                 inclination=0,
                 semi_major_axis=6372000,
                 ecc=0.0,
                 minCommunicationsAltitude=100000,
                 minSatElevation=40,
                 linkingMethod='SPARSE',
                 arcOfAscendingNodes=360.0):
        """
		Parameters
		----------
		planes : int
			the number of planes in the constillation
		nodes_per_plane : int
			the number of satellites per plane
		inclination : float
			the inclination of all planes in constillation
		semi_major_axis : float
			semi major axis of the orbits (radius, if orbits circular)
		ecc : float
			the eccentricity of the orbits; range = 0.0 - 1.0
		minCommunicationsAltitude : int32
			The minimum altitude that inter satellite links must pass
			above the Earth's surface.
		minSatElevation : int
			The minimum angle of elevation in degrees above the horizon a satellite
			needs to have for a ground station to communicate with it.
		linkingMethod : string
			The current linking method used by the constillation
			currently only used for generating GML files.
		arcOfAscendingNodes : float
			The angle of arc (in degrees) that the ascending nodes of all the
			orbital planes is evenly spaced along. Ex, seting this to 180 results
			in a Pi constellation like Iridium
		"""

        self.number_of_planes = planes
        self.nodes_per_plane = nodes_per_plane
        self.total_sats = planes * nodes_per_plane
        self.ground_node_counter = 0
        self.inclination = inclination
        self.semi_major_axis = semi_major_axis
        self.period = self.calculateOrbitPeriod(
            semi_major_axis=self.semi_major_axis)
        self.eccentricity = ecc
        self.current_time = 0
        self.number_of_isl_links = 0
        self.number_of_gnd_links = 0
        self.total_links = 0
        self.link_array_size = LINK_ARRAY_SIZE
        self.min_communications_altitude = 100000
        self.min_sat_elevation = 40
        self.linking_method = 'SPARSE'
        self.G = None

        # this is not written to zero, because it has it's own init
        # function a a few lines down: initSatelliteArray()
        self.satellites_array = np.empty(self.total_sats,
                                         dtype=SATELLITE_DTYPE)

        # declare an empty ground
        self.groundpoints_array = np.zeros(NUM_GROUND_POINTS,
                                           dtype=GROUNDPOINT_DTYPE)

        # declare an empty link array
        self.link_array = np.zeros(self.link_array_size, dtype=LINK_DTYPE)

        # figure out how many degrees to space right ascending nodes of the planes
        self.raan_offsets = [(arcOfAscendingNodes / self.number_of_planes) * i
                             for i in range(0, self.number_of_planes)]

        # generate a list with a kepler ellipse solver object for each plane
        self.plane_solvers = []
        for raan in self.raan_offsets:
            self.plane_solvers.append(
                pyasl.KeplerEllipse(
                    per=self.period,  # how long the orbit takes in seconds
                    a=self.
                    semi_major_axis,  # if circular orbit, this is same as radius
                    e=self.
                    eccentricity,  # generally close to 0 for leo constillations
                    Omega=raan,  # right ascention of the ascending node
                    w=0.0,  # initial time offset / mean anamoly
                    i=self.inclination))  # orbit inclination

        # figure out the time offsets for nodes withen a plane
        self.time_offsets = [(self.period / nodes_per_plane) * i
                             for i in range(0, nodes_per_plane)]

        # initialize the satellite array
        self.initSatelliteArray()
def zeroD_e_mmm(plotTitle):
    # Independent Variables
    waterDepth = 4000  # (m)
    albedo = c.albedo_Earth  # how much light gets reflected by atmosphere
    epsilon = c.epsilonSurface_Earth  # how good of a blackbody the body is
    R_star = c.R_Sun  # Radius of star (AU)
    d_planet = c.d_Earth  # Distance of planet from body it is orbiting  (AU)
    T_star = c.T_Sun  # Surface Temperature of star (K)
    periodFractions = 365  # number of fractions of period

    # Global Initialisation
    heat_capacity = waterDepth * 1000 * 4200  # (J / K m^2)
    period = math.pow(d_planet, 1.5)  # Period of planet's orbit (years)
    Power_Output = PowerOut(T_star)  # incidentPower from star (W)
    solar_Constant = planetInsolation(Power_Output, R_star, d_planet)  # Insolation incident on the planet's surface (W/m^2)
    eccentricities = generateList(0, 1, 0.01)
    minTemps = []
    meanTemps = []
    maxTemps = []

    for e in eccentricities:  # Iterating through each eccentricity from 0.01 to 0.99

        # Initialisation
        T = [0]
        heat_content = heat_capacity * T[0]  # (J / m^2)
        periods = 1000
        tempMin = 1E24
        ke = pyasl.KeplerEllipse(d_planet, period, e, Omega=0., i=0.0, w=0.0)
        heat_in = generate_heat_in(ke, periodFractions, d_planet, solar_Constant, albedo)
        tempMean = 0
        countMean = 0

        for k in range(periods):
            for i in range(periodFractions):
                heat_out = epsilon * PowerOut(T[-1])

                heat_content += (heat_in[i] - heat_out) * (period / periodFractions * c.SiY)
                T.append(heat_content / heat_capacity)  # (K)

                if periods - k < 20:  # Only keeps track of minimum temperatures for the last 20 periods in EBM
                    if T[-1] < tempMin:
                        tempMin = T[-1]  # keeping track of the minimum temperature

                    tempMean += T[-1]
                    countMean += 1

        minTemps.append(tempMin)
        maxTemps.append(max(T))
        meanTemps.append(tempMean / countMean)

        print(str(round(e, 2)))

    # Plotting data
    fig = plt.figure(plotTitle)

    plt.plot(eccentricities, minTemps, c='r', linewidth=0.75, label='Minimum')
    plt.plot(eccentricities, meanTemps, c='g', linewidth=0.75, label="Mean")
    plt.plot(eccentricities, maxTemps, c='b', linewidth=0.75, label='Maximum')

    # Modifying Visual aspect of plot
    fig = beautifyPlot(fig, plotTitle, 'Eccentricity', 'Surface temperature (K)')
    fig = plotCelciusLine(fig, min(eccentricities), max(eccentricities))
    fig = addLegend(fig, 'upper left', 'Plots: ')

    return fig
예제 #10
0
def orbit():
    # Instantiate a Keplerian elliptical orbit with
    # semi-major axis of __ length units,
    # a period of __ time units, eccentricity of __,
    # longitude of ascending node of __ degrees, an inclination
    # of __ deg, and a periapsis argument of __ deg.
    ke = pyasl.KeplerEllipse(1.3, 10., e=0.9, Omega=70., i=10.0, w=110.0)

    # Get a time axis
    t = np.linspace(0, 20, 100)

    # Calculate the orbit position at the given points
    # in a Cartesian coordinate system.
    pos = ke.xyzPos(t)
    #print("Shape of output array: ", pos.shape)

    # x, y, and z coordinates for 50th time point
    #print("x, y, z for 50th point: ", pos[50, ::])

    # Calculate orbit radius
    radius = ke.radius(t)

    # Calculate velocity on orbit
    vel = ke.xyzVel(t)
    # Find the nodes of the orbit (Observer at -z)
    ascn, descn = ke.xyzNodes_LOSZ()

    velocity = np.zeros(vel.shape[0])
    for i in range(vel.shape[0]):
        velocity[i] = velocity[i] + (vel[i][0]**2 + vel[i][1]**2 +
                                     vel[i][2]**2)**(0.5)
    print(velocity.size)
    vmin = velocity.min()
    vmax = velocity.max()

    #Freq Shift
    smax = 480
    smin = 240
    if (vmax - vmin < 0.001):
        sh = 0
    else:
        sh = (smax - smin) / (vmax - vmin)
    for i in range(velocity.shape[0]):
        velocity[i] = (velocity[i] - vmin) * sh + smin

    s = np.zeros(1)
    for i in range(velocity.size):
        if (velocity[i] < 270):
            f = 240
        elif (velocity[i] < 300):
            f = 270
        elif (velocity[i] < 320):
            f = 300
        elif (velocity[i] < 360):
            f = 320
        elif (velocity[i] < 400):
            f = 360
        elif (velocity[i] < 450):
            f = 400
        else:
            f = 450
        #print(f)
        x = np.zeros(480)
        #x[f]=20/radius[i]
        x[f] = np.exp(-1 * radius[i]) * 100
        y = np.fft.irfft(x)
        s = np.concatenate((s, y), axis=0)

    print(s.size)
    write_wavfile("e=0.9_exp.wav", 4096, s)
def zeroD_e_bar(plotTitle):
    # Independent Variables
    waterDepth = 4000  # (m)
    albedo = c.albedo_Earth  # how much light gets reflected by atmosphere (0-1)
    epsilon = c.epsilonSurface_Earth  # how good of a blackbody the body is (0-1)
    R_star = c.R_Sun  # Radius of star (AU)
    d_planet = c.d_Earth  # Distance of planet from body it is orbiting  (AU)
    T_star = c.T_Sun  # Surface Temperature of star (K)
    periodFractions = 365  # number of fractions of period

    # Global Initialisation
    heat_capacity = waterDepth * 1000 * 4200  # (J / K m^2)
    period = math.pow(d_planet, 1.5)  # Period of planet's orbit (years)
    Power_Output = PowerOut(
        T_star)  # Power irradiated from the star's surface (W/m^2)
    solar_Constant = planetInsolation(
        Power_Output, R_star,
        d_planet)  # Insolation incident on the planet's surface (W/m^2)
    eccentricities = generateList(
        0, 1, 0.01)  # List containing all the eccentricities being plotted
    minTemps = []
    maxTemps = []

    for e in eccentricities:  # Iterating through each eccentricity from 0.01 to 0.99

        # Initialisation
        T = [0]
        heat_content = heat_capacity * T[0]  # (J / m^2)
        periods = 1000
        tempMin = 1E24
        ke = pyasl.KeplerEllipse(d_planet, period, e, Omega=0., i=0.0, w=0.0)
        heat_in = generate_heat_in(ke, periodFractions, d_planet,
                                   solar_Constant, albedo)
        for k in range(periods):
            for i in range(periodFractions):
                heat_out = epsilon * PowerOut(T[-1])

                heat_content += (heat_in[i] -
                                 heat_out) * (period / periodFractions * c.SiY)
                T.append(heat_content / heat_capacity)  # (K)
                if periods - k < 20:  # Only keeps track of minimum temperatures for the last 20 periods in EBM
                    if T[-1] < tempMin:
                        tempMin = T[
                            -1]  # Keeping track of the minimum temperature
        print(str(round(e, 2)))
        minTemps.append(tempMin)
        maxTemps.append(max(T))

    # Plotting data
    fig = plt.figure(plotTitle)

    for i in range(len(eccentricities)):
        # Height minimum
        minBarHeight = 2
        height = round(maxTemps[i] - minTemps[i], 3)
        if height < minBarHeight:
            height = minBarHeight

        barWidth = 0.006  # Set to 0.006 for default or 0.01 for connected bars
        plt.bar(round(eccentricities[i], 2),
                height,
                width=barWidth,
                bottom=round(minTemps[i], 3),
                align='center',
                color='r')

    # Modifying Visual aspect of plot
    fig = beautifyPlot(fig, plotTitle, 'Eccentricity',
                       'Surface temperature (K)')
    fig = plotCelciusLine(fig, min(eccentricities), max(eccentricities))
    fig = addLegend(fig, 'upper left', 'Plots: ')

    return fig