Module snowpat.pysmet.MetaData
Expand source code
from typing import Optional, List
import pandas as pd
from ..msgs import *
class MetaData:
"""A class used to represent the metadata of a SMET file.
Attributes:
station_id (str): The ID of the station.
location (Location): The location of the station, which includes:
latitude (float): The latitude of the location.
longitude (float): The longitude of the location.
altitude (float): The altitude of the location.
easting (float): The easting of the location.
northing (float): The northing of the location.
epsg (int): The EPSG code of the location.
nodata (float): The value representing no data.
fields (List[str]): The list of fields in the SMET file.
"""
def __init__(self) -> None:
self.station_id: str = ""
self.location: Location = Location()
self.nodata: Optional[float] = None
self.fields: Optional[List[str]] = []
def __eq__(self, __value: object) -> bool:
if not isinstance(__value, MetaData):
return False
isEqual = True
if self.station_id != __value.station_id:
isEqual = False
elif self.location != __value.location:
isEqual = False
elif self.nodata != __value.nodata:
isEqual = False
elif self.fields != __value.fields:
isEqual = False
return isEqual
def __str__(self):
return (
f"MetaData:\n"
f"Station ID: {self.station_id}\n"
f"{self.location}\n"
f"No Data: {self.nodata}\n"
f"Fields: {self.fields}"
)
@property
def combined_dict(self):
d = self.__dict__.copy()
d.update(self.location.adjusted_dict)
del d["location"]
if d.get('fields') is not None:
d['fields'] = ' '.join(d['fields'])
return d
def checkValidity(self, fun:bool=False) -> bool:
nodata_set = self.nodata is not None
valid = self.station_id and self.location.checkValidity() and nodata_set and self.fields
if not valid:
if not self.station_id:
print("Station ID is missing")
if not self.location.checkValidity():
print("Location is invalid. Needs Lat, Lon and Altitude!")
if not nodata_set:
print("No Data is missing")
if not self.fields:
print("Fields are missing")
if fun:
print(bad())
print(empire())
raise Exception(f"Invalid metadata: {self}")
else :
if fun:
print(way())
print(mando())
return valid
class Location:
def __init__(self) -> None:
self.latitude: Optional[float] = None
self.longitude: Optional[float] = None
self.altitude: Optional[float] = None
self.easting: Optional[float] = None
self.northing: Optional[float] = None
self.epsg: Optional[int] = None
def __eq__(self, __value: object) -> bool:
if not isinstance(__value, Location):
return False
isEqual = True
for k,v in self.adjusted_dict.items():
if v != getattr(__value, k):
isEqual = False
break
return isEqual
def __ne__(self, __value: object) -> bool:
return not self.__eq__(__value)
def is_latlon(self):
return self.latitude is not None and self.longitude is not None
@property
def adjusted_dict(self):
return {k: v for k, v in self.__dict__.items() if v is not None}
def __str__(self):
attributes = [
("Latitude", self.latitude),
("Longitude", self.longitude),
("Altitude", self.altitude),
("Easting", self.easting),
("Northing", self.northing),
("EPSG", self.epsg),
]
attributes_str = ", ".join(
f"{name}: {value}" for name, value in attributes if value is not None
)
return f"Location: ({attributes_str})"
def checkValidity(self) -> bool:
lat_long_alt_set = (
self.latitude is not None
and self.longitude is not None
and self.altitude is not None
)
east_north_alt_set = (
self.easting is not None
and self.northing is not None
and self.altitude is not None
)
return lat_long_alt_set or east_north_alt_set
class OptionalMetaData:
"""A class used to store optional metadata of a SMET file.
Attributes:
station_name (str): The name of the station.
tz (float): The timezone of the station.
slope_angle (float): The slope angle of the station.
slope_azi (float): The slope azimuth of the station.
creation (str): The creation date/time of the SMET file.
source (str): The source of the SMET file.
units_offset (List[float]): The list of unit offsets in the SMET file.
units_multiplier (List[float]): The list of unit multipliers in the SMET file.
comment (str): Any additional comments.
"""
def __init__(self) -> None:
self.station_name: Optional[str] = None
self.tz: Optional[float] = None
self.slope_angle: Optional[float] = None
self.slope_azi: Optional[float] = None
self.creation: Optional[str] = None
self.source: Optional[str] = None
self.units_offset: Optional[List[float]] = None
self.units_multiplier: Optional[List[float]] = None
self.comment: Optional[str] = None
@property
def adjusted_dict(self):
d = self.__dict__.copy()
if d.get('units_offset') is not None:
d['units_offset'] = ' '.join(map(str, d['units_offset']))
if d.get('units_multiplier') is not None:
d['units_multiplier'] = ' '.join(map(str, d['units_multiplier']))
return {k: v for k, v in d.items() if v is not None}
def __str__(self):
attributes = [
("Station Name", self.station_name),
("Timezone", self.tz),
("Slope Angle", self.slope_angle),
("Slope Azi", self.slope_azi),
("Creation", self.creation),
("Source", self.source),
("Units Offset", self.units_offset),
("Units Multiplier", self.units_multiplier),
("Comment", self.comment),
]
attributes_str = "\n".join(
f"{name}: {value}" for name, value in attributes if value is not None
)
return f"OptionalMetaData:\n{attributes_str}"
def join(self, other: 'OptionalMetaData'):
attributes = ['station_name', 'tz', 'slope_angle', 'slope_azi', 'creation', 'source',
'units_offset', 'units_multiplier', 'comment']
for attr in attributes:
self_value = getattr(self, attr)
other_value = getattr(other, attr)
if not self_value and other_value:
setattr(self, attr, other_value)
elif self_value and other_value and self_value != other_value:
print(f"Warning: {attr} mismatch: {self_value} != {other_value}")
Classes
class Location-
Expand source code
class Location: def __init__(self) -> None: self.latitude: Optional[float] = None self.longitude: Optional[float] = None self.altitude: Optional[float] = None self.easting: Optional[float] = None self.northing: Optional[float] = None self.epsg: Optional[int] = None def __eq__(self, __value: object) -> bool: if not isinstance(__value, Location): return False isEqual = True for k,v in self.adjusted_dict.items(): if v != getattr(__value, k): isEqual = False break return isEqual def __ne__(self, __value: object) -> bool: return not self.__eq__(__value) def is_latlon(self): return self.latitude is not None and self.longitude is not None @property def adjusted_dict(self): return {k: v for k, v in self.__dict__.items() if v is not None} def __str__(self): attributes = [ ("Latitude", self.latitude), ("Longitude", self.longitude), ("Altitude", self.altitude), ("Easting", self.easting), ("Northing", self.northing), ("EPSG", self.epsg), ] attributes_str = ", ".join( f"{name}: {value}" for name, value in attributes if value is not None ) return f"Location: ({attributes_str})" def checkValidity(self) -> bool: lat_long_alt_set = ( self.latitude is not None and self.longitude is not None and self.altitude is not None ) east_north_alt_set = ( self.easting is not None and self.northing is not None and self.altitude is not None ) return lat_long_alt_set or east_north_alt_setInstance variables
var adjusted_dict-
Expand source code
@property def adjusted_dict(self): return {k: v for k, v in self.__dict__.items() if v is not None}
Methods
def checkValidity(self) ‑> bool-
Expand source code
def checkValidity(self) -> bool: lat_long_alt_set = ( self.latitude is not None and self.longitude is not None and self.altitude is not None ) east_north_alt_set = ( self.easting is not None and self.northing is not None and self.altitude is not None ) return lat_long_alt_set or east_north_alt_set def is_latlon(self)-
Expand source code
def is_latlon(self): return self.latitude is not None and self.longitude is not None
class MetaData-
A class used to represent the metadata of a SMET file.
Attributes
station_id:str- The ID of the station.
location:Location- The location of the station, which includes: latitude (float): The latitude of the location. longitude (float): The longitude of the location. altitude (float): The altitude of the location. easting (float): The easting of the location. northing (float): The northing of the location. epsg (int): The EPSG code of the location.
nodata:float- The value representing no data.
fields:List[str]- The list of fields in the SMET file.
Expand source code
class MetaData: """A class used to represent the metadata of a SMET file. Attributes: station_id (str): The ID of the station. location (Location): The location of the station, which includes: latitude (float): The latitude of the location. longitude (float): The longitude of the location. altitude (float): The altitude of the location. easting (float): The easting of the location. northing (float): The northing of the location. epsg (int): The EPSG code of the location. nodata (float): The value representing no data. fields (List[str]): The list of fields in the SMET file. """ def __init__(self) -> None: self.station_id: str = "" self.location: Location = Location() self.nodata: Optional[float] = None self.fields: Optional[List[str]] = [] def __eq__(self, __value: object) -> bool: if not isinstance(__value, MetaData): return False isEqual = True if self.station_id != __value.station_id: isEqual = False elif self.location != __value.location: isEqual = False elif self.nodata != __value.nodata: isEqual = False elif self.fields != __value.fields: isEqual = False return isEqual def __str__(self): return ( f"MetaData:\n" f"Station ID: {self.station_id}\n" f"{self.location}\n" f"No Data: {self.nodata}\n" f"Fields: {self.fields}" ) @property def combined_dict(self): d = self.__dict__.copy() d.update(self.location.adjusted_dict) del d["location"] if d.get('fields') is not None: d['fields'] = ' '.join(d['fields']) return d def checkValidity(self, fun:bool=False) -> bool: nodata_set = self.nodata is not None valid = self.station_id and self.location.checkValidity() and nodata_set and self.fields if not valid: if not self.station_id: print("Station ID is missing") if not self.location.checkValidity(): print("Location is invalid. Needs Lat, Lon and Altitude!") if not nodata_set: print("No Data is missing") if not self.fields: print("Fields are missing") if fun: print(bad()) print(empire()) raise Exception(f"Invalid metadata: {self}") else : if fun: print(way()) print(mando()) return validInstance variables
var combined_dict-
Expand source code
@property def combined_dict(self): d = self.__dict__.copy() d.update(self.location.adjusted_dict) del d["location"] if d.get('fields') is not None: d['fields'] = ' '.join(d['fields']) return d
Methods
def checkValidity(self, fun: bool = False) ‑> bool-
Expand source code
def checkValidity(self, fun:bool=False) -> bool: nodata_set = self.nodata is not None valid = self.station_id and self.location.checkValidity() and nodata_set and self.fields if not valid: if not self.station_id: print("Station ID is missing") if not self.location.checkValidity(): print("Location is invalid. Needs Lat, Lon and Altitude!") if not nodata_set: print("No Data is missing") if not self.fields: print("Fields are missing") if fun: print(bad()) print(empire()) raise Exception(f"Invalid metadata: {self}") else : if fun: print(way()) print(mando()) return valid
class OptionalMetaData-
A class used to store optional metadata of a SMET file.
Attributes
station_name:str- The name of the station.
tz:float- The timezone of the station.
slope_angle:float- The slope angle of the station.
slope_azi:float- The slope azimuth of the station.
creation:str- The creation date/time of the SMET file.
source:str- The source of the SMET file.
units_offset:List[float]- The list of unit offsets in the SMET file.
units_multiplier:List[float]- The list of unit multipliers in the SMET file.
comment:str- Any additional comments.
Expand source code
class OptionalMetaData: """A class used to store optional metadata of a SMET file. Attributes: station_name (str): The name of the station. tz (float): The timezone of the station. slope_angle (float): The slope angle of the station. slope_azi (float): The slope azimuth of the station. creation (str): The creation date/time of the SMET file. source (str): The source of the SMET file. units_offset (List[float]): The list of unit offsets in the SMET file. units_multiplier (List[float]): The list of unit multipliers in the SMET file. comment (str): Any additional comments. """ def __init__(self) -> None: self.station_name: Optional[str] = None self.tz: Optional[float] = None self.slope_angle: Optional[float] = None self.slope_azi: Optional[float] = None self.creation: Optional[str] = None self.source: Optional[str] = None self.units_offset: Optional[List[float]] = None self.units_multiplier: Optional[List[float]] = None self.comment: Optional[str] = None @property def adjusted_dict(self): d = self.__dict__.copy() if d.get('units_offset') is not None: d['units_offset'] = ' '.join(map(str, d['units_offset'])) if d.get('units_multiplier') is not None: d['units_multiplier'] = ' '.join(map(str, d['units_multiplier'])) return {k: v for k, v in d.items() if v is not None} def __str__(self): attributes = [ ("Station Name", self.station_name), ("Timezone", self.tz), ("Slope Angle", self.slope_angle), ("Slope Azi", self.slope_azi), ("Creation", self.creation), ("Source", self.source), ("Units Offset", self.units_offset), ("Units Multiplier", self.units_multiplier), ("Comment", self.comment), ] attributes_str = "\n".join( f"{name}: {value}" for name, value in attributes if value is not None ) return f"OptionalMetaData:\n{attributes_str}" def join(self, other: 'OptionalMetaData'): attributes = ['station_name', 'tz', 'slope_angle', 'slope_azi', 'creation', 'source', 'units_offset', 'units_multiplier', 'comment'] for attr in attributes: self_value = getattr(self, attr) other_value = getattr(other, attr) if not self_value and other_value: setattr(self, attr, other_value) elif self_value and other_value and self_value != other_value: print(f"Warning: {attr} mismatch: {self_value} != {other_value}")Instance variables
var adjusted_dict-
Expand source code
@property def adjusted_dict(self): d = self.__dict__.copy() if d.get('units_offset') is not None: d['units_offset'] = ' '.join(map(str, d['units_offset'])) if d.get('units_multiplier') is not None: d['units_multiplier'] = ' '.join(map(str, d['units_multiplier'])) return {k: v for k, v in d.items() if v is not None}
Methods
def join(self, other: OptionalMetaData)-
Expand source code
def join(self, other: 'OptionalMetaData'): attributes = ['station_name', 'tz', 'slope_angle', 'slope_azi', 'creation', 'source', 'units_offset', 'units_multiplier', 'comment'] for attr in attributes: self_value = getattr(self, attr) other_value = getattr(other, attr) if not self_value and other_value: setattr(self, attr, other_value) elif self_value and other_value and self_value != other_value: print(f"Warning: {attr} mismatch: {self_value} != {other_value}")