Skip to content
dataset.py 8.56 KiB
Newer Older
Christoph.Knote's avatar
sdf
Christoph.Knote committed
import datetime
import sys

class Variable:
    @property
    def desc(self):
        return ", ".join( [self.name, self.units, self.units ] )
    def __init__(self, name, units, scale, miss):
        self.name = name
        self.units = units
        self.scale = scale
        self.miss = miss

class Dataset:
    @property
    def nheader(self):
Christoph.Knote's avatar
kj  
Christoph.Knote committed
        total = 12 + self.ndvar + 1 + self.nscom + 1 + self.nncom
Christoph.Knote's avatar
sdf
Christoph.Knote committed
        if self.format == 2110:
            total += self.nauxvar + 5
        return total
    @property
    def ndvar(self):
        return len(self.DVAR)
    @property
    def nauxvar(self):
        return len(self.AUXVAR)
    @property
    def nvar(self):
        return self.ndvar + 1
    @property
    def nscom(self):
        return len(self.SCOM)
    @property
    def nncom(self):
        return len(self.NCOM)

    def write(self, f=sys.stdout):
        def prnt(txt):
            f.write(str(txt) + "\n")

        # Number of lines in header, file format index (most files use 1001) - comma delimited.
        prnt("{:d}, {:d}".format(self.nheader, self.format))
        # PI last name, first name/initial.
        prnt(self.PI)
        # Organization/affiliation of PI.
        prnt(self.organization)
        # Data source description (e.g., instrument name, platform name, model name, etc.).
        prnt(self.dataSource)
        # Mission name (usually the mission acronym).
        prnt(self.mission)
        # File volume number, number of file volumes (these integer values are used when the data require more than one file per day; for data that require only one file these values are set to 1, 1) - comma delimited.
        prnt("1, 1")
        # UTC date when data begin, UTC date of data reduction or revision - comma delimited (yyyy, mm, dd, yyyy, mm, dd).
        prnt(", ".join([ datetime.datetime.strftime(x, "%Y, %m, %d") for x in [ self.dateValid, self.dateRevised ] ]))
        # Data Interval (This value describes the time spacing (in seconds) between consecutive data records. It is the (constant) interval between values of the independent variable. For 1 Hz data the data interval value is 1 and for 10 Hz data the value is 0.1. All intervals longer than 1 second must be reported as Start and Stop times, and the Data Interval value is set to 0. The Mid-point time is required when it is not at the average of Start and Stop times. For additional information see Section 2.5 below.).
        prnt("0")
        # Description or name of independent variable (This is the name chosen for the start time. It always refers to the number of seconds UTC from the start of the day on which measurements began. It should be noted here that the independent variable should monotonically increase even when crossing over to a second day.).
        prnt(self.IVAR.desc)
        if self.format == 2110:
            # Description or name of independent (bound) variable (This is the name chosen for the start time. It always refers to the number of seconds UTC from the start of the day on which measurements began. It should be noted here that the independent variable should monotonically increase even when crossing over to a second day.).
            prnt(self.IBVAR.desc)
        # Number of variables (Integer value showing the number of dependent variables: the total number of columns of data is this value plus one.).
        prnt(self.ndvar)
        # Scale factors (1 for most cases, except where grossly inconvenient) - comma delimited.
        prnt(", ".join( [ "{:6.3f}".format(x.scale) for x in self.DVAR ]))
        # Missing data indicators (This is -9999 (or -99999, etc.) for any missing data condition, except for the main time (independent) variable which is never missing) - comma delimited.
        prnt(", ".join( [ "{:d}".format(x.miss) for x in self.DVAR ]))
        # Variable names and units (Short variable name and units are required, and optional long descriptive name, in that order, and separated by commas. If the variable is unitless, enter the keyword "none" for its units. Each short variable name and units (and optional long name) are entered on one line. The short variable name must correspond exactly to the name used for that variable as a column header, i.e., the last header line prior to start of data.).
        nul = [ prnt(x.desc) for x in self.DVAR ]
        if self.format == 2110:
            # Number of variables (Integer value showing the number of dependent variables: the total number of columns of data is this value plus one.).
            prnt(self.nauxvar)
            # Scale factors (1 for most cases, except where grossly inconvenient) - comma delimited.
            prnt(", ".join( [ "{:6.3f}".format(x.scale) for x in self.AUXVAR ]))
            # Missing data indicators (This is -9999 (or -99999, etc.) for any missing data condition, except for the main time (independent) variable which is never missing) - comma delimited.
            prnt(", ".join( [ "{:d}".format(x.miss) for x in self.AUXVAR ]))
            # Variable names and units (Short variable name and units are required, and optional long descriptive name, in that order, and separated by commas. If the variable is unitless, enter the keyword "none" for its units. Each short variable name and units (and optional long name) are entered on one line. The short variable name must correspond exactly to the name used for that variable as a column header, i.e., the last header line prior to start of data.).
            nul = [ prnt(x.desc) for x in self.AUXVAR ]

        # Number of SPECIAL comment lines (Integer value indicating the number of lines of special comments, NOT including this line.).
        prnt("{:d}".format(self.nscom))
        # Special comments (Notes of problems or special circumstances unique to this file. An example would be comments/problems associated with a particular flight.).
        nul = [ prnt(x) for x in self.SCOM ]
        # Number of Normal comments (i.e., number of additional lines of SUPPORTING information: Integer value indicating the number of lines of additional information, NOT including this line.).
        prnt("{:d}".format(self.nncom))
        # Normal comments (SUPPORTING information: This is the place for investigators to more completely describe the data and measurement parameters. The supporting information structure is described below as a list of key word: value pairs. Specifically include here information on the platform used, the geo-location of data, measurement technique, and data revision comments. Note the non-optional information regarding uncertainty, the upper limit of detection (ULOD) and the lower limit of detection (LLOD) for each measured variable. The ULOD and LLOD are the values, in the same units as the measurements that correspond to the flags -7777s and -8888s within the data, respectively. The last line of this section should contain all the short variable names on one line. The key words in this section are written in BOLD below and must appear in this section of the header along with the relevant data listed after the colon. For key words where information is not needed or applicable, simply enter N/A.).
        nul = [ prnt(x) for x in self.NCOM ]
Christoph.Knote's avatar
Christoph.Knote committed
        # data!
Christoph.Knote's avatar
Christoph.Knote committed
        nul = [ prnt(",".join( [ str(y) for y in x ] )) for x in self.data ]
Christoph.Knote's avatar
sdf
Christoph.Knote committed

Christoph.Knote's avatar
Christoph.Knote committed
    def make_filename(self):
        return self.dataID + "_" +self.locationID + "_" +datetime.datetime.strftime(self.dateValid, '%Y%m%d') + "_" +"R" + self.revision + ".ict"
Christoph.Knote's avatar
sdf
Christoph.Knote committed

    def __init__(self):
        self.format       = 1001
Christoph.Knote's avatar
Christoph.Knote committed

        self.revision     = '0'
        self.dataID       = 'dataID'
        self.locationID   = 'locationID'

Christoph.Knote's avatar
sdf
Christoph.Knote committed
        self.PI           = 'Mustermann, Martin'
        self.organization = 'Musterinstitut'
        self.dataSource   = 'Musterdatenprodukt'
        self.mission      = 'MUSTEREX'
        self.dateValid    = datetime.datetime.today()
        self.dateRevised  = datetime.datetime.today()
        self.dataInterval = 0
        self.IVAR         = Variable('Time_Start',
                                     'seconds_from_0_hours_on_valid_date',
                                     1.0, -9999999)
        self.DVAR         = [
                            Variable('Time_Stop',
                                     'seconds_from_0_hours_on_valid_date',
Christoph.Knote's avatar
Christoph.Knote committed
                                     1.0, -9999999),
                            Variable('Some_Variable',
                                     'ppbv',
Christoph.Knote's avatar
sdf
Christoph.Knote committed
                                     1.0, -9999999)
                            ]
        self.SCOM         = []
        self.NCOM         = []
Christoph.Knote's avatar
Christoph.Knote committed

        self.data         = [ [1.0, 2.0, 45.0], [2.0, 3.0, 36.0] ]

Christoph.Knote's avatar
sdf
Christoph.Knote committed
        # for 2210
        self.IBVAR        = None
        self.AUXVAR       = []