diff --git a/sift/workspace/metadatabase.py b/sift/workspace/metadatabase.py index 4ec7147e8dd6b947a5e0c12098012a2b064b2fe3..5755b6935d77319ff8efa89fa63c028f2c462aef 100644 --- a/sift/workspace/metadatabase.py +++ b/sift/workspace/metadatabase.py @@ -206,7 +206,12 @@ class Product(Base): A StoredProduct's kind determines how its cached data is transformed to different representations for display additional information is stored in a key-value table addressable as product[key:str] """ - __tablename__ = 'products_v0' + __tablename__ = 'products_v1' + + # FAMILY_COLUMNS are used to group products together when assigning color maps + FAMILY_COLUMNS = ('platform', 'instrument', 'name', 'standard_name') + # TRACK_COLUMNS are used to group products together when placing them into a timeline track + TRACK_COLUMNS = FAMILY_COLUMNS + ('scene',) # identity information id = Column(Integer, primary_key=True) @@ -226,14 +231,15 @@ class Product(Base): # kind = Column(PickleType) # class or callable which can perform transformations on this data in workspace atime = Column(DateTime, nullable=False) # last time this file was accessed by application - # cached metadata provided by the file format handler + # cached identifying metadata provided by the file format handler name = Column(String, nullable=False) # product identifier eg "B01", "B02" # resource + shortname should be sufficient to identify the data + standard_name = Column(String, nullable=True) # CF metadata standard_name, or an underscore-prefixed consistent assigned name + instrument = Column(String, nullable=True) # "ABI", "AHI" - physical or virtual instrument + platform = Column(String, nullable=True) # platform or satellite name e.g. "GOES-16", "Himawari-8"; should match PLATFORM enum + scene = Column(String, nullable=True) # "HFD", "EM1", "ECONUS" - # platform = Column(String) # platform or satellite name e.g. "GOES-16", "Himawari-8"; should match PLATFORM enum - # standard_name = Column(String, nullable=True) - # - # times # display_time = Column(DateTime) # normalized instantaneous scheduled observation time e.g. 20170122T2310 + # When placing products into timeline view, TRACK_COLUMNS determine which track to place them in, and obs_time and obs_duration determine breadth/placement obs_time = Column(DateTime, nullable=False) # actual observation time start obs_duration = Column(Interval, nullable=False) # duration of the observation @@ -401,6 +407,10 @@ class Product(Base): INFO.PROJ: 'proj4', INFO.OBS_TIME: 'obs_time', INFO.OBS_DURATION: 'obs_duration', + INFO.PLATFORM: 'platform', + INFO.INSTRUMENT: 'instrument', + INFO.SCENE: 'scene', + INFO.STANDARD_NAME: 'standard_name', INFO.CELL_WIDTH: 'cell_width', INFO.CELL_HEIGHT: 'cell_height', INFO.ORIGIN_X: 'origin_x', @@ -411,6 +421,16 @@ class Product(Base): self.atime = when = when or datetime.utcnow() [x.touch(when) for x in self.resource] + @property + def family(self): + """Products in the same family typically have the same color mapping""" + return tuple(getattr(self, colname) for colname in self.FAMILY_COLUMNS) + + @property + def track(self): + """Products in the same track typically represent a time series of one scene observations""" + return tuple(getattr(self, colname) for colname in self.TRACK_COLUMNS) + class ProductKeyValue(Base): """ key-value pairs associated with a product