Source code for opendrift.models.openoil.adios.models.oil.sample

"""
Main class that represents an oil record.

This maps to the JSON used in the DB

Having a Python class makes it easier to write importing, validating etc, code.
"""
from dataclasses import dataclass, field

from ..common.utilities import dataclass_to_json, JSON_List

from ..common.measurement import VolumeFraction

from .distillation import Distillation
from .metadata import SampleMetaData
from .physical_properties import PhysicalProperties
from .environmental_behavior import EnvironmentalBehavior
from .sara import Sara
from .ests_fractions import ESTSFractions

# need the namespace for ccme, as using the fieldname the same as the class
# breaks things.
from . import ccme
from .compound import CompoundList
from .industry_property import IndustryPropertyList
from .bulk_composition import BulkCompositionList

from .validation.warnings import WARNINGS
from .validation.errors import ERRORS


[docs]@dataclass_to_json @dataclass class Sample: """ represents the physical and chemical properties of particular sub sample. could be fresh oil, or weathered samples, or distillation cuts, or ... """ metadata: SampleMetaData = field(default_factory=SampleMetaData) cut_volume: VolumeFraction = None # from Exxon data physical_properties: PhysicalProperties = field(default_factory=PhysicalProperties) environmental_behavior: EnvironmentalBehavior = field( default_factory=EnvironmentalBehavior) SARA: Sara = field(default_factory=Sara) distillation_data: Distillation = field(default_factory=Distillation) compounds: CompoundList = field(default_factory=CompoundList) bulk_composition: BulkCompositionList = field(default_factory=BulkCompositionList) industry_properties: IndustryPropertyList = field(default_factory=IndustryPropertyList) headspace_analysis: CompoundList = field(default_factory=CompoundList) CCME: ccme.CCME = field(default_factory=ccme.CCME) ESTS_hydrocarbon_fractions: ESTSFractions = None miscellaneous: CompoundList = field(default_factory=CompoundList) # a place to store arbitrary extra data. extra_data: dict = field(default_factory=dict)
[docs] def __post_init__(self): metadata = self.metadata if metadata.name is not None: if metadata.name.lower() == 'whole crude': metadata.name = 'Fresh Oil Sample' if metadata.short_name is None and metadata.name is not None: if metadata.name.lower() == 'fresh oil sample': metadata.short_name = 'Fresh Oil' else: metadata.short_name = f'{self.name[:12]}...'
def __repr__(self): return f"sample: {self.metadata.name}\n{self.metadata.description}"
[docs]class SampleList(JSON_List): item_type = Sample
[docs] def validate(self): msgs = [] # make sure there's at least one subsample if len(self) == 0: msgs.append(ERRORS["E031"]) else: # check for densities # note: would be good to be smart about the temp densities are at # this is here because only need to check the "fresh" sample if (self[0].physical_properties is None or not self[0].physical_properties.densities): msgs.append(WARNINGS["W006"]) # # check_for_distillation_cuts # try: # if not self[0].distillation_data.cuts: # msgs.append(WARNINGS['W007']) # except AttributeError: # msgs.append(WARNINGS['W007']) # validate all the subsamples for ss in self: msgs.extend(ss.validate()) return msgs