Source code for s2d2.unit_conversion

#! /usr/bin/env python3
# -*- coding: utf-8 -*-

import numpy as np

from datetime import datetime, timedelta

# time conversions
[docs] def datetime2doy(dt): """ Convert array of datetime64 to a day of year. Parameters ---------- dt : np.datetime64 times of interest Returns ------- year : integer, {x ∈ ℕ} calender year doy : integer, {x ∈ ℕ} day of year """ year = dt.astype('datetime64[Y]').astype(int)+1970 doy = (dt.astype('datetime64[D]') - dt.astype('datetime64[Y]') + 1).astype('float64') return year, doy
[docs] def doy2dmy(doy,year): """ given day of years, calculate the day and month Parameters ---------- year : integer, {x ∈ ℕ} calender year doy : integer, {x ∈ ℕ} day of year Returns ------- day, month, year """ if year.size < doy.size: year = year*np.ones_like(doy) # sometimes the doy is longer than 365, than put this to the year counter xtra_years = np.floor(doy / 365).astype(int) year += xtra_years doy = doy % 365 dates = (year-1970).astype('datetime64[Y]') + doy.astype('timedelta64[D]') month = dates.astype('datetime64[M]').astype(int) % 12 + 1 day = dates - dates.astype('datetime64[M]') + 1 day = day.astype(int) if day.size==1: return day[0], month[0], year[0] else: return day, month, year
[docs] def datetime2calender(dt): """ Convert array of datetime64 to a calendar year, month, day. Parameters ---------- dt : np.datetime64 times of interest Returns ------- cal : numpy array calendar array with last axis representing year, month, day """ # decompose calendar floors Y, M, D = [dt.astype(f"M8[{x}]") for x in "YMD"] year = (Y + 1970).astype('timedelta64[Y]').astype(int) month = ((M - Y) + 1).astype('timedelta64[M]').astype(int) day = ((D - M) + 1).astype('timedelta64[D]').astype(int) return year, month, day
[docs] def datenum2datetime(t): """ some write a date as a number "YYYYMMDD" conver this to numpy.datetime Parameters ---------- t : {int,numpy.array} time, in format YYYYMMD Returns ------- dt : {numpy.datetime64, numpy.array}, type=numpy.datetime64[D] times in numpy time format See Also -------- datetime2datenum """ if type(t) in (np.ndarray, ): dt = np.array([np.datetime64(str(e)[:4]+'-'+str(e)[4:6]+'-'+str(e)[-2:]) for e in t.astype(str)]) else: dt = np.datetime64(str(t)[:4] + '-' + str(t)[4:6] + '-' + str(t)[-2:]) return dt
[docs] def datetime2datenum(dt): """ convert numpy.datetime to a date as a number "YYYYMMDD" Parameters ---------- dt : {numpy.datetime64, numpy.array}, type=numpy.datetime64[D] times in numpy time format Returns ------- t : {int, numpy.array} time, in format YYYYMMD See Also -------- datenum2datetime """ if type(dt) in (np.ndarray, ): t = np.array([int(e.astype(str)[:4] + e.astype(str)[5:7]+ e.astype(str)[-2:]) for e in dt.astype(str)], dtype=np.int64) else: dt = int(dt.astype(str)[:4]+dt.astype(str)[5:7]+dt.astype(str)[-2:]) return t
# geometric and angular scales and formats
[docs] def deg2dms(ang): """ convert decimal degrees to degree minutes seconds format Parameters ---------- ang : {float,np.array}, unit=decimal degrees angle(s) of interest Returns ------- deg : {integer,np.array} degrees min : {integer,np.array}, range=0...60 angular minutes sec : {float,np.array}, range=0...60 angular seconds """ min,sec = np.divmod(ang*3600, 60) deg,min = np.divmod(min, 60) deg,min = deg.astype(int), min.astype(int) return deg,min,sec
[docs] def dms2deg(deg, min, sec): """ convert degree minutes seconds format to decimal degrees Parameters ---------- deg : {integer,np.array} degrees min : {integer,np.array}, range=0...60 angular minutes sec : {float,np.array}, range=0...60 angular seconds Returns ------- ang : {float,np.array}, unit=decimal degrees angle(s) of interest """ ang = deg.astype(float) + (min.astype(float)/60) + (sec.astype(float)/3600) return ang
[docs] def deg2compass(θ): """ adjust angle to be in bounds of a positive argument angle,like a compass Parameters ---------- θ : unit=degrees Returns ------- θ : unit=degrees, range=0...+360 See Also -------- deg2arg Notes ----- The angle is declared in the following coordinate frame: .. code-block:: text ^ North & y | - <--|--> + | +----> East & x """ return θ % 360
[docs] def deg2arg(θ): """ adjust angle to be in bounds of an argument angle Parameters ---------- θ : unit=degrees Returns ------- θ : unit=degrees, range=-180...+180 See Also -------- deg2compass Notes ----- The angle is declared in the following coordinate frame: .. code-block:: text ^ North & y | - <--|--> + | +----> East & x """ return ((θ + 180) % 360) -180