Skip to content
Snippets Groups Projects
Commit 50bd572a authored by tomrink's avatar tomrink
Browse files

initial commit

parents
No related branches found
No related tags found
No related merge requests found
files.py 0 → 100644
import datetime, os
from datetime import timezone
import glob
class Files:
"""
Provides a time-ordered view of a set of files of identical structure and contents but separated by time.
"""
def __init__(self, files_path, file_time_span, pattern):
"""
:param files_path: Location of target files, can have wildcard characters.
:param file_time_span: Duration of a file (minutes). For example, an 8-minute polar orbiting granule or the
time between successive geostationary CONUS products. Assumed to be fixed.
:param pattern: The glob pattern that matches the files: concatenated with files_path.
"""
self.flist = []
self.ftimes = []
self.dto_s = []
for path in glob.glob(files_path + pattern, recursive=True):
self.flist.append(path)
if len(self.flist) == 0:
raise GenericException('no matching files found in: ' + files_path + ' matching: ' + pattern)
self.span_seconds = datetime.timedelta(minutes=file_time_span).seconds
for pname in self.flist:
dto = self.get_datetime(pname)
dto_start = dto
dto_end = dto + datetime.timedelta(minutes=file_time_span)
self.ftimes.append((dto_start.timestamp(), dto_end.timestamp()))
self.dto_s.append(dto)
self.ftimes = np.array(self.ftimes)
self.flist = np.array(self.flist)
self.dto_s = np.array(self.dto_s)
sidxs = np.argsort(self.ftimes[:, 0]) # sort on start time
self.ftimes = self.ftimes[sidxs, :]
self.flist = self.flist[sidxs]
self.dto_s = self.dto_s[sidxs]
self._current_index = 0
self.number_of_files = len(self.flist)
def get_number_of_files(self):
"""
:return: The number of files self managers
"""
return self.number_of_files
def get_datetime(self, pathname):
"""
:param pathname: The full-path of the file.
:return: The file's time label as a datetime object.
"""
pass
def get_file_containing_time(self, timestamp):
"""
:param timestamp: seconds since the epoch
:return: the file whose time range contains timestamp.
"""
k = -1
for i in range(self.ftimes.shape[0]):
if (timestamp >= self.ftimes[i, 0]) and (timestamp < self.ftimes[i, 1]):
k = i
break
if k < 0:
return None, None, None
return self.flist[k], self.ftimes[k, 0], k
def get_file(self, timestamp, window=None):
"""
:param timestamp: seconds since the epoch.
:param window: the duration (minutes) of files in this object. Defaults to the constructor time span.
:return: the file whose start time is closest to timestamp.
"""
if window is None:
window = self.span_seconds
else:
window = datetime.timedelta(minutes=window).seconds
diff = self.ftimes[:, 0] - timestamp
midx = np.argmin(np.abs(diff))
if np.abs(self.ftimes[midx, 0] - timestamp) < window:
return self.flist[midx], self.ftimes[midx, 0], midx
else:
return None, None, None
def get_file_in_range(self, timestamp, t_lo_minutes, t_hi_minutes):
"""
:param timestamp:
:param t_lo_minutes: can be negative or positive
:param t_hi_minutes: can be negative or positive, but must be greater than t_lo_minutes.
:return: the file whose time label is within the range (timestamp + t_lo_minutes, timestamp + t_hi_minutes).
If more than one, return the first occurrence.
"""
if t_hi_minutes <= t_lo_minutes:
raise ValueError('t_hi_minutes must be greater than t_lo_minutes')
t_lo = timestamp + datetime.timedelta(minutes=t_lo_minutes).seconds
t_hi = timestamp + datetime.timedelta(minutes=t_hi_minutes).seconds
m_idx = np.where(np.logical_and(self.ftimes[:, 0] >= t_lo, self.ftimes[:, 0] < t_hi))[0]
if len(m_idx) > 0:
m_idx = m_idx[0] # the first occurrence
return self.flist[m_idx], self.ftimes[m_idx, 0], m_idx
else:
return None, None, None
def get_parameters(self):
pass
def __iter__(self):
return self
def __next__(self):
if self._current_index < len(self.flist):
fname = self.flist[self._current_index]
t_start = self.ftimes[self._current_index, 0]
t_stop = self.ftimes[self._current_index, 1]
dto = self.dto_s[self._current_index]
self._current_index += 1
return fname, t_start, t_stop, dto
self._current_index = 0
raise StopIteration
util.py 0 → 100644
class MyGenericException(Exception):
def __init__(self, message):
self.message = message
# Return index of nda closest to value. nda (numpy.ndarray) must be 1d. If multiple occurrences should arise,
# the first is returned according to NumPy's argmin/max function.
def value_to_index(nda, value):
diff = np.abs(nda - value)
idx = np.argmin(diff)
return idx
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment