Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ numpy>=1.0
scipy>=1.0
matplotlib>=3.0
netCDF4>=1.4
requests
requests
pytz
89 changes: 65 additions & 24 deletions rocketpy/Environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import bisect
import warnings
import time
import pytz
from datetime import datetime, timedelta
from inspect import signature, getsourcelines
from collections import namedtuple
Expand Down Expand Up @@ -80,7 +81,11 @@ class Environment:
Environment.elevation : float
Launch site elevation.
Environment.date : datetime
Date time of launch.
Date time of launch in UTC.
Environment.localDate : datetime
Date time of launch in the local time zone, defined by Environment.timeZone.
Environment.timeZone : string
Local time zone specification. See pytz for time zone info.

Topographic information:
Environment.elevLonArray: array
Expand Down Expand Up @@ -290,6 +295,7 @@ def __init__(
longitude=0,
elevation=0,
datum="SIRGAS2000",
timeZone="UTC",
):
"""Initialize Environment class, saving launch rail length,
launch date, location coordinates and elevation. Note that
Expand Down Expand Up @@ -326,7 +332,13 @@ def __init__(
'Open-Elevation' which uses the Open-Elevation API to
find elevation data. For this option, latitude and
longitude must also be specified. Default value is 0.
datum:
datum : string
The desired reference ellipsoide model, the following options are
available: "SAD69", "WGS84", "NAD83", and "SIRGAS2000". The default
is "SIRGAS2000", then this model will be used if the user make some
typing mistake.
timeZone : string, optional
Name of the time zone. To see all time zones, import pytz and run

Returns
-------
Expand All @@ -343,9 +355,11 @@ def __init__(

# Save date
if date != None:
self.setDate(date)
self.setDate(date, timeZone)
else:
self.date = None
self.localDate = None
self.timeZone = None

# Initialize constants
self.earthRadius = 6.3781 * (10 ** 6)
Expand Down Expand Up @@ -378,21 +392,30 @@ def __init__(

return None

def setDate(self, date):
def setDate(self, date, timeZone="UTC"):
"""Set date and time of launch and update weather conditions if
date dependent atmospheric model is used.

Parameters
----------
date : Date
Date object specifying launch date and time.
date : Datetime
Datetime object specifying launch date and time.
timeZone : string, optional
Name of the time zone. To see all time zones, import pytz and run
print(pytz.all_timezones). Default time zone is "UTC".

Return
------
None
"""
# Store date
self.date = datetime(*date)
# Store date and configure time zone
self.timeZone = timeZone
tz = pytz.timezone(self.timeZone)
localDate = datetime(*date)
if localDate.tzinfo == None:
localDate = tz.localize(localDate)
self.localDate = localDate
self.date = self.localDate.astimezone(pytz.UTC)

# Update atmospheric conditions if atmosphere type is Forecast,
# Reanalysis or Ensemble
Expand Down Expand Up @@ -478,7 +501,7 @@ def setElevation(self, elevation="Open-Elevation"):
response = requests.get(requestURL)
results = response.json()["results"]
self.elevation = results[0]["elevation"]
print("Elevation received: ", self.elevation)
print("Elevation received:", self.elevation)
except:
raise RuntimeError("Unabel to reach Open-Elevation API servers.")
else:
Expand Down Expand Up @@ -2820,9 +2843,18 @@ def info(self):
"""
# Print launch site details
print("Launch Site Details")
print("\nLaunch Rail Length: ", self.rL, " m")
if self.date != None:
print("Launch Date: ", self.date, " UTC")
print("\nLaunch Rail Length:", self.rL, " m")
time_format = "%Y-%m-%d %H:%M:%S"
if self.date != None and "UTC" not in self.timeZone:
print(
"Launch Date:",
self.date.strftime(time_format),
"UTC |",
self.localDate.strftime(time_format),
self.timeZone,
)
elif self.date != None:
print("Launch Date:", self.date.strftime(time_format), "UTC")
if self.lat != None and self.lon != None:
print("Launch Site Latitude: {:.5f}°".format(self.lat))
print("Launch Site Longitude: {:.5f}°".format(self.lon))
Expand All @@ -2839,7 +2871,7 @@ def info(self):
# Print atmospheric model details
print("\n\nAtmospheric Model Details")
modelType = self.atmosphericModelType
print("\nAtmospheric Model Type: ", modelType)
print("\nAtmospheric Model Type:", modelType)
print(
modelType
+ " Maximum Height: {:.3f} km".format(self.maxExpectedHeight / 1000)
Expand All @@ -2850,7 +2882,7 @@ def info(self):
endDate = self.atmosphericModelEndDate
interval = self.atmosphericModelInterval
print(modelType + " Time Period: From ", initDate, " to ", endDate, " UTC")
print(modelType + " Hour Interval: ", interval, " hrs")
print(modelType + " Hour Interval:", interval, " hrs")
# Determine latitude and longitude range
initLat = self.atmosphericModelInitLat
endLat = self.atmosphericModelEndLat
Expand All @@ -2859,8 +2891,8 @@ def info(self):
print(modelType + " Latitude Range: From ", initLat, "° To ", endLat, "°")
print(modelType + " Longitude Range: From ", initLon, "° To ", endLon, "°")
if modelType == "Ensemble":
print("Number of Ensemble Members: ", self.numEnsembleMembers)
print("Selected Ensemble Member: ", self.ensembleMember, " (Starts from 0)")
print("Number of Ensemble Members:", self.numEnsembleMembers)
print("Selected Ensemble Member:", self.ensembleMember, " (Starts from 0)")

# Print atmospheric conditions
print("\n\nSurface Atmospheric Conditions")
Expand Down Expand Up @@ -2947,9 +2979,18 @@ def allInfo(self):

# Print launch site details
print("\n\nLaunch Site Details")
print("\nLaunch Rail Length: ", self.rL, " m")
if self.date != None:
print("Launch Date: ", self.date, " UTC")
print("\nLaunch Rail Length:", self.rL, " m")
time_format = "%Y-%m-%d %H:%M:%S"
if self.date != None and "UTC" not in self.timeZone:
print(
"Launch Date:",
self.date.strftime(time_format),
"UTC |",
self.localDate.strftime(time_format),
self.timeZone,
)
elif self.date != None:
print("Launch Date:", self.date.strftime(time_format), "UTC")
if self.lat != None and self.lon != None:
print("Launch Site Latitude: {:.5f}°".format(self.lat))
print("Launch Site Longitude: {:.5f}°".format(self.lon))
Expand All @@ -2958,7 +2999,7 @@ def allInfo(self):
# Print atmospheric model details
print("\n\nAtmospheric Model Details")
modelType = self.atmosphericModelType
print("\nAtmospheric Model Type: ", modelType)
print("\nAtmospheric Model Type:", modelType)
print(
modelType
+ " Maximum Height: {:.3f} km".format(self.maxExpectedHeight / 1000)
Expand All @@ -2969,7 +3010,7 @@ def allInfo(self):
endDate = self.atmosphericModelEndDate
interval = self.atmosphericModelInterval
print(modelType + " Time Period: From ", initDate, " to ", endDate, " UTC")
print(modelType + " Hour Interval: ", interval, " hrs")
print(modelType + " Hour Interval:", interval, " hrs")
# Determine latitude and longitude range
initLat = self.atmosphericModelInitLat
endLat = self.atmosphericModelEndLat
Expand All @@ -2978,8 +3019,8 @@ def allInfo(self):
print(modelType + " Latitude Range: From ", initLat, "° To ", endLat, "°")
print(modelType + " Longitude Range: From ", initLon, "° To ", endLon, "°")
if modelType == "Ensemble":
print("Number of Ensemble Members: ", self.numEnsembleMembers)
print("Selected Ensemble Member: ", self.ensembleMember, " (Starts from 0)")
print("Number of Ensemble Members:", self.numEnsembleMembers)
print("Selected Ensemble Member:", self.ensembleMember, " (Starts from 0)")

# Print atmospheric conditions
print("\n\nSurface Atmospheric Conditions")
Expand Down Expand Up @@ -3506,7 +3547,7 @@ def printEarthDetails(self):
# print("Launch Site UTM coordinates: {:.2f} ".format(self.initialEast)
# + self.initialEW + " {:.2f} ".format(self.initialNorth) + self.initialHemisphere
# )
# print("Launch Site UTM zone number: ", self.initialUtmZone)
# print("Launch Site UTM zone number:", self.initialUtmZone)
# print("Launch Site Surface Elevation: {:.1f} m".format(self.elevation))
print("Earth Radius at Launch site: {:.1f} m".format(self.earthRadius))
print("Gravity acceleration at launch site: Still not implemented :(")
Expand Down
8 changes: 7 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
setuptools.setup(
name="rocketpy",
version="0.9.9",
install_requires=["numpy>=1.0", "scipy>=1.0", "matplotlib>=3.0", "requests"],
install_requires=[
"numpy>=1.0",
"scipy>=1.0",
"matplotlib>=3.0",
"requests",
"pytz",
],
maintainer="RocketPy Developers",
author="Giovani Hidalgo Ceotto",
author_email="ghceotto@gmail.com",
Expand Down
3 changes: 2 additions & 1 deletion tests/test_environment.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import datetime
import pytz
from unittest.mock import patch

import pytest
Expand Down Expand Up @@ -32,7 +33,7 @@ def test_env_set_date(example_env):
tomorrow = datetime.date.today() + datetime.timedelta(days=1)
example_env.setDate((tomorrow.year, tomorrow.month, tomorrow.day, 12))
assert example_env.date == datetime.datetime(
tomorrow.year, tomorrow.month, tomorrow.day, 12
tomorrow.year, tomorrow.month, tomorrow.day, 12, tzinfo=pytz.utc
)


Expand Down