コード例 #1
0
 def _signal_electrons_in_well_dbe(self, model):
     E_sensor = model.energy_at_sensor_dbj
     E_pixel = E_sensor - pylink.to_db(model.spatial_channels)
     P_r = E_pixel + model.sensor_quantum_efficiency_db
     lambda_dbm = pylink.to_db(model.lambda_nm) - 90
     h_db = pylink.to_db(model.plancks_constant)
     c_db = pylink.to_db(model.speed_of_light_m_s)
     return P_r + lambda_dbm - h_db - c_db
コード例 #2
0
 def _power_flux_at_lens_dbw_m2(self, model):
     # Approximate the pixel as a point source and apply spreading loss
     # The approsimate transmission gain is 3dB as lambertian reflectors
     D = model.slant_range_km * 1000
     spreading_loss_db = pylink.to_db(math.pi * 2 * D**2)
     return (0.0 + model.reflected_power_dbw - spreading_loss_db -
             model.atmospheric_loss_db)
コード例 #3
0
    def _received_power_dbw(self, model):
        # Incident Power Flux
        Pi = model.power_flux_at_lens_dbw_m2

        # Collecting Aperture Area
        A = pylink.to_db(math.pi * model.lens_radius_m**2)

        return Pi + A
コード例 #4
0
    def _energy_at_sensor_dbj(self, model):
        # Energy striking the primary lens
        P_lens = model.received_power_dbw + pylink.to_db(model.shutter_time_s)

        # Optical losses associated with inefficiencies
        # Losses associated with the focal plane sensor
        P_sensor = P_lens - model.optical_loss_db

        return P_sensor
コード例 #5
0
    def _atmospheric_loss_db(self, model):
        # Power incident on the atmosphere
        Pi = _interpolate(model.lambda_nm, model.orbital_solar_irradiance_w, 1)
        Pi = pylink.to_db(Pi)

        # Power transmitted through the atmosphere
        Pt = model.incident_power_flux_density_dbw_m2_nm

        return Pi - Pt
コード例 #6
0
ファイル: utils_test.py プロジェクト: spetten/pylink
 def test_spreading_loss_db(self):
     assert abs(pylink.spreading_loss_db(0.5e-3) -
                pylink.to_db(math.pi)) < 1e-3
コード例 #7
0
ファイル: utils_test.py プロジェクト: spetten/pylink
 def test_to_db(self):
     assert abs(pylink.to_db(10) - 10) < 1e-6
     assert abs(pylink.to_db(2) - 3) < 0.1
コード例 #8
0
ファイル: pfd.py プロジェクト: spetten/pylink
]

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

x = [p[0] for p in restrictions]
y = [p[1] for p in restrictions]
plt.plot(x, y, color='r', linewidth=2, label='Limit')
ax.set_xlabel('Elevation Angle (degrees)')
ax.set_ylabel('Boresight PFD (dBW/m^2/%d%s)' % pylink.human_hz(4000))

x = np.linspace(10.0, 90.0)
y = np.linspace(10.0, 90.0)
for i in range(len(x)):
    m.override(e.min_elevation_deg, x[i])
    pfd = m.pfd_dbw_per_m2_per_hz + pylink.to_db(4000)
    y[i] = pfd

low = min(min(y), min([v[1] for v in restrictions]))
hi = max(max(y), max([v[1] for v in restrictions]))

delta = (hi - low) * 0.1
low -= delta
hi += delta

ax.set_ylim(low, hi)

plt.plot(x, y)

d = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'export')
f = os.path.join(d, 'pfd.png')
コード例 #9
0
ファイル: getLinkBudget.py プロジェクト: TateWalker/ppe_sim
def main():
    m = linkBudgetConstants.DOWNLINK
    return m.max_bitrate_hz * m.allocation_hz
    # The same here with 'e' instead of 'enum'...'e' also doesn't
    # collide with the 'enum' package name.
    e = m.enum

    # First, we create the report object.  Most of the interesting
    # stuff happens in the to_latex method.
    r = pylink.Report(m)

    # This example is designed to place the result in the export directory
    output_dir = os.path.join(os.getcwd(), 'export')
    output_path = os.path.join(output_dir, 'interference_analysis.tex')
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # We use a LaTeX import directive to include a complicated
    # introduction tex document, so we want to make sure we copy it
    # into the output directoy so that pdflatex will pick it up.

    # ITU-R SF.358-5 Lays out the maximum permissible PFD values for
    # various bands.
    limits = [(0, -115), (5, -115), (25, -105), (90, -105)]

    # The Canonical PFD figure is the 4kHz BW (though that is tunable
    # if you so desire) peak PFD at the Earth's surface (ie max xmit
    # power, peak antenna gain) as a function of elevation angle,
    # ignoring things like rain fade, since this figure is mostly
    # useful for compliance.
    title = 'Peak PFD at Surface (1MHz BW)'
    canonical_pfd = pylink.CanonicalPFDFigure(m,
                                              title=title,
                                              pfd_limits=limits)

    # Expected PFD is more complicated, as it assumes normal satellite
    # operations (ie Nadir pointing for example), and real antenna
    # patterns instead of peak gain, etc.
    title = 'Expected PFD at Surface (1kHz BW)'
    expected_pfd = pylink.ExpectedPFDFigure(m, title=title, pfd_limits=limits)

    # In some cases, it can be useful to produce graphs of peak PFD vs
    # bandwidth to show compliance with various limits.  That's where
    # this class comes in handy.
    title = 'Peak PFD vs Bandwidth at Potential Victim GS'
    rx_bw_pfd = pylink.PFDvsBWFigure(m,
                                     start_hz=1e3,
                                     end_hz=5e3,
                                     is_gso=False,
                                     pfd_limits=None,
                                     title=title)
    title = 'Peak PFD vs Bandwidth at Potential Victim GSO'
    gso_bw_pfd = pylink.PFDvsBWFigure(m,
                                      start_hz=1e3,
                                      end_hz=5e3,
                                      is_gso=True,
                                      pfd_limits=None,
                                      title=title)

    # To make things clear to the regulators for whom this report is
    # being prepared, we're going to want to call out, specifically,
    # the PFD limit, as well as the max potential interference we
    # could cause.
    #
    # And before you say it, I know, the format for these added
    # sections aren't terribly clean...I'll add a ticket to clean this
    # up at some point.  In the meantime, you have a working example
    # below.
    elevation = m.min_elevation_deg
    m.override(e.min_elevation_deg, 90)
    peak_pf = m.peak_pfd_dbw_per_m2_per_hz
    m.override(e.min_elevation_deg, elevation)
    extra_interference_sections = [('Hey Regulators, Look In this Section', [
        ('Lowest Permissible PFD (4kHz BW) at Receiver', -150, 'dBW/m^2'),
        ('Peak Possible PFD (4kHz BW) at Receiver',
         peak_pf + pylink.to_db(4e3), 'dBW/m^2'),
    ])]

    # It may also be worth adding a couple of other random sections to
    # call out something necessary to the business case, or some other
    # computation.  Note the way we escape the ampersand in the title
    # below.  That's because, at the end of the day, a LaTeX file is
    # generated, and & is a reserved character.
    sub_ttc = ('Bitrate Requirements for TT\\&C', [
        ('Number of Log Files', 1000, ''),
        ('Size of Each Log File', 16, 'kB'),
        ('Minimum Average Bitrate', 9600, 'kbps'),
    ])
    sub_images = ('Bitrate Requirements for Images', [
        ('Number of Images', 1000, ''),
        ('Size of Each Image', 32, 'MB'),
        ('Minimum Average Bitrate', 32, 'mbps'),
    ])
    extra_regular_sections = [
        ('Bitrates (Custom Section Example)', [sub_ttc, sub_images]),
    ]

    # Now that we've lined everything up, it's time to build some LaTeX
    r.to_latex(
        output_path,
        author='Tate Walker',
        intro='Link Budget Report for PPE Module of Gateway',
        expo='So long, and thanks for all the Fish!',
        rx_pfd_bws=[1e3, 4e3, 1e6],
        gso_pfd_bws=[1e3, 4e3, 1e6],
        bitrate_figure=pylink.BitrateFigure(m, 'Max Bitrate'),
        added_sections=extra_regular_sections,
        added_interference_sections=extra_interference_sections,
    )
コード例 #10
0
    #
    # And before you say it, I know, the format for these added
    # sections aren't terribly clean...I'll add a ticket to clean this
    # up at some point.  In the meantime, you have a working example
    # below.
    elevation = m.min_elevation_deg
    m.override(e.min_elevation_deg, 90)
    peak_pf = m.peak_pfd_dbw_per_m2_per_hz
    m.override(e.min_elevation_deg, elevation)
    extra_interference_sections = [
        ('Hey Regulators, Look In this Section',
         [('Lowest Permissible PFD (4kHz BW) at Receiver',
           -150,
           'dBW/m^2'),
          ('Peak Possible PFD (4kHz BW) at Receiver',
           peak_pf + pylink.to_db(4e3),
           'dBW/m^2'),
             ])]

    # It may also be worth adding a couple of other random sections to
    # call out something necessary to the business case, or some other
    # computation.  Note the way we escape the ampersand in the title
    # below.  That's because, at the end of the day, a LaTeX file is
    # generated, and & is a reserved character.
    sub_ttc = (
        'Bitrate Requirements for TT\\&C',
         [
            ('Number of Log Files',   1000, ''),
            ('Size of Each Log File', 16, 'kB'),
            ('Minimum Average Bitrate', 9600, 'kbps'),
            ]
コード例 #11
0
    def __init__(self,
                 orbital_solar_irradiance,
                 ground_solar_irradiance,
                 reflectance_db=pylink.to_db(0.5),
                 fore_optics_efficiency_db=pylink.to_db(0.95),
                 focusing_optics_efficiency_db=pylink.to_db(0.95),
                 grating_efficiency_db=pylink.to_db(0.8),
                 sensor_quantum_efficiency_db=pylink.to_db(0.8),
                 read_out_noise_e=50,
                 pixel_pitch_um=15,
                 fwhm_nm=10,
                 gsd_m=15,
                 gmc=1,
                 lambda_nm=1990,
                 lens_radius_m=0.3,
                 bits_per_sample=12,
                 spatial_channels=640):

        self.tribute = {
            # Constants
            'orbital_solar_irradiance_w': orbital_solar_irradiance,
            'ground_solar_irradiance_w': ground_solar_irradiance,
            'speed_of_light_m_s': 299792458,
            'plancks_constant': 6.626068 * 10**-34,
            'grav_const': 6.67 * 10**-11,
            'earth_mass_kg': 5.98 * 10**24,
            'reflectance_db': reflectance_db,
            'fore_optics_efficiency_db': fore_optics_efficiency_db,
            'grating_efficiency_db': grating_efficiency_db,
            'focusing_optics_efficiency_db': focusing_optics_efficiency_db,
            'sensor_quantum_efficiency_db': sensor_quantum_efficiency_db,
            'read_out_noise_e': read_out_noise_e,
            'pixel_pitch_um': pixel_pitch_um,
            'fwhm_nm': fwhm_nm,
            'gsd_m': gsd_m,
            'gmc': gmc,
            'lambda_nm': lambda_nm,
            'lens_radius_m': lens_radius_m,
            'bits_per_sample': bits_per_sample,
            'spatial_channels': spatial_channels,

            # Calculators
            'incident_power_flux_density_dbw_m2_nm':
            self._incident_power_flux_density_dbw_m2_nm,
            'reflected_power_flux_density_dbw_m2_nm':
            self._reflected_power_flux_density_dbw_m2_nm,
            'reflected_power_density_dbw_nm':
            self._reflected_power_density_dbw_nm,
            'reflected_power_dbw': self._reflected_power_dbw,
            'power_flux_at_lens_dbw_m2': self._power_flux_at_lens_dbw_m2,
            'received_power_dbw': self._received_power_dbw,
            'orbital_velocity_km_per_s': self._orbital_velocity_km_per_s,
            'orbital_period_s': self._orbital_period_s,
            'shutter_time_s': self._shutter_time_s,
            'energy_at_sensor_dbj': self._energy_at_sensor_dbj,
            'signal_electrons_in_well_dbe': self._signal_electrons_in_well_dbe,
            'noise_electrons_dbe': self._noise_electrons_dbe,
            'snr_db': self._snr_db,
            'ground_area_dbm2': self._ground_area_dbm2,
            'optical_loss_db': self._optical_loss_db,
            'atmospheric_loss_db': self._atmospheric_loss_db,
        }
コード例 #12
0
 def _noise_electrons_dbe(self, model):
     N = (0.0 + model.read_out_noise_e +
          pylink.from_db(model.signal_electrons_in_well_dbe / 2))
     return pylink.to_db(N)
コード例 #13
0
 def _reflected_power_dbw(self, model):
     return (1.0 + model.reflected_power_density_dbw_nm +
             pylink.to_db(model.fwhm_nm))
コード例 #14
0
 def _ground_area_dbm2(self, model):
     return pylink.to_db(model.spatial_channels * model.gsd_m**2)
コード例 #15
0
 def _incident_power_flux_density_dbw_m2_nm(self, model):
     PFD = max(
         _interpolate(model.lambda_nm, model.ground_solar_irradiance_w, 1),
         1e-10)
     return pylink.to_db(PFD)