Esempio n. 1
0
def init(pf):
    global fpn,leak,badpx
    
    cursor = coda.Cursor()

    coda.cursor_set_product(cursor, pf)

    # Read wavelengths of detector pixels
    coda.cursor_goto_record_field_by_name(cursor, "spectral_base")
    coda.cursor_goto_array_element_by_index(cursor, 0)
    coda.cursor_goto_record_field_by_name(cursor, "wvlen_det_pix")
    wave_lengths = coda.cursor_read_double_array(cursor)
    coda.cursor_goto_root(cursor)

    # Read fixed pattern noise data
    coda.cursor_goto_record_field_by_name(cursor, "leakage_constant")
    coda.cursor_goto_array_element_by_index(cursor, 0)
    coda.cursor_goto_record_field_by_name(cursor, "fpn_const")
    fpn = coda.cursor_read_double_array(cursor)

    # Read leakage current data
    coda.cursor_goto_parent(cursor)
    coda.cursor_goto_record_field_by_name(cursor, "leak_const")
    leak = coda.cursor_read_double_array(cursor)
    coda.cursor_goto_root(cursor)

    # Read bad pixel map
    coda.cursor_goto_record_field_by_name(cursor, "ppg_etalon")
    coda.cursor_goto_array_element_by_index(cursor, 0)
    coda.cursor_goto_record_field_by_name(cursor, "bad_pix_mask")
    badpx = coda.cursor_read_uint8_array(cursor)
    coda.cursor_goto_root(cursor)
Esempio n. 2
0
if __name__ == "__main__":

    if len(sys.argv) != 2:
        print >> sys.stderr, "Usage: %s <envisat file>" % sys.argv[0]
        sys.exit(1)
        
    coda.set_option_perform_conversions(0)

    pf = coda.open(sys.argv[1])
    product_class = coda.get_product_class(pf)
    if not product_class.startswith("ENVISAT"):
        print >>sys.stderr, "Error: file %s is not an ENVISAT product file (product class = %s)" % (sys.argv[1], product_class)
        sys.exit(1)

    cursor = coda.Cursor()
    coda.cursor_set_product(cursor, pf)

    print "  MPH :"
    coda.cursor_goto_record_field_by_name(cursor, "mph")
    print_record(cursor)
    coda.cursor_goto_parent(cursor)

    print "  SPH :";
    coda.cursor_goto_record_field_by_name(cursor, "sph")
    print_record(cursor);
    coda.cursor_goto_parent(cursor)

    coda.cursor_goto_record_field_by_name(cursor, "dsd")
    num_dsd = coda.cursor_get_num_elements(cursor)
    if num_dsd > 0:
        coda.cursor_goto_first_array_element(cursor)
Esempio n. 3
0
def process_states(pf):
    global fpn,leak,badpx
    
    state_name = [ "no measurement", "nadir", "limb", "occultation", "monitoring" ]

    states_cursor = coda.Cursor()
    mds_cursor = [coda.Cursor() for i in range(0,5)]
    pixel_array = numpy.zeros(shape=(8,1024),dtype=numpy.float64)
#    coda.Cursor mds_cursor[5]  /* 1 dummy + 4x MDS : empty, nadir, limb, occultation, monitoring */


    # Initialize STATES cursor
    coda.cursor_set_product(states_cursor, pf)
    coda.cursor_goto_record_field_by_name(states_cursor, "states")
    num_states = coda.cursor_get_num_elements(states_cursor)
    if (num_states == 0):
        return
    coda.cursor_goto_first_array_element(states_cursor)

    # Initialize MDS cursors
    # Skip #0 (dummy MDS cursor)
    for i in range(1,5):
        coda.cursor_set_product(mds_cursor[i], pf)
        record_type = coda.cursor_get_type(mds_cursor[i])
        field_index = coda.type_get_record_field_index_from_name(record_type, state_name[i])
        available = coda.cursor_get_record_field_available_status(mds_cursor[i], field_index)
        if (available):
            coda.cursor_goto_record_field_by_name(mds_cursor[i], state_name[i])
            coda.cursor_goto_first_array_element(mds_cursor[i])

    # now walk the states
    for stateNr in range(0,num_states):
        # Read mds_type, num_clus, and num_dsr for this state
        coda.cursor_goto_record_field_by_name(states_cursor, "mds_type")
        mds_type = coda.cursor_read_uint8(states_cursor)
        coda.cursor_goto_parent(states_cursor)
        coda.cursor_goto_record_field_by_name(states_cursor, "num_clus")
        num_clus = coda.cursor_read_uint16(states_cursor)
        coda.cursor_goto_parent(states_cursor)
        coda.cursor_goto_record_field_by_name(states_cursor, "num_dsr")
        num_dsr = coda.cursor_read_uint16(states_cursor)
        coda.cursor_goto_parent(states_cursor)

        print "Processing state %d of %d" % (stateNr + 1, num_states)
        print "  mds_type .....: %d (%s)" % (mds_type, state_name[mds_type])
        print "  num_clus .....: %d" % (num_clus,)
        print "  num_dsr ......: %d" % (num_dsr,)

        # traverse the MDSRs for this state */
        for dsrNr in range(0,num_dsr):
#            clus_config_cursor = coda.Cursor()
#            clus_dat_cursor = coda.Cursor()

            # Initialize pixel_array with zeros
            for chan_num in range(0,8):
                for pixelNr in range(0,1024):
                    pixel_array[chan_num][pixelNr] = 0.0

            clus_config_cursor = copy.deepcopy(states_cursor)
            coda.cursor_goto_record_field_by_name(clus_config_cursor, "clus_config")
            coda.cursor_goto_first_array_element(clus_config_cursor)
            
            
            clus_dat_cursor = copy.deepcopy(mds_cursor[mds_type])
            coda.cursor_goto_record_field_by_name(clus_dat_cursor, "clus_dat")
            coda.cursor_goto_first_array_element(clus_dat_cursor)

            # traverse the clusters in this MDSR
            for cluster in range(0,num_clus):
                # Read clus_config
                coda.cursor_goto_record_field_by_name(clus_config_cursor, "chan_num")
                chan_num = coda.cursor_read_uint8(clus_config_cursor)
                coda.cursor_goto_parent(clus_config_cursor)
                chan_num -= 1
                coda.cursor_goto_record_field_by_name(clus_config_cursor, "start_pix")
                start_pix = coda.cursor_read_uint16(clus_config_cursor)
                coda.cursor_goto_parent(clus_config_cursor)
                coda.cursor_goto_record_field_by_name(clus_config_cursor, "clus_len")
                clus_len = coda.cursor_read_uint16(clus_config_cursor)
                coda.cursor_goto_parent(clus_config_cursor)
                coda.cursor_goto_record_field_by_name(clus_config_cursor, "pet")
                pet = coda.cursor_read_double(clus_config_cursor)
                coda.cursor_goto_parent(clus_config_cursor)
                coda.cursor_goto_record_field_by_name(clus_config_cursor, "intgr_time")
                intgr_time = coda.cursor_read_double(clus_config_cursor)
                coda.cursor_goto_parent(clus_config_cursor)
                coda.cursor_goto_record_field_by_name(clus_config_cursor, "coadd_factor")
                coadd_factor = coda.cursor_read_uint16(clus_config_cursor)
                coda.cursor_goto_parent(clus_config_cursor)
                coda.cursor_goto_record_field_by_name(clus_config_cursor, "num_readouts")
                num_readouts = coda.cursor_read_uint16(clus_config_cursor)
                coda.cursor_goto_parent(clus_config_cursor)
                coda.cursor_goto_record_field_by_name(clus_config_cursor, "clus_data_type")
                clus_data_type = coda.cursor_read_uint8(clus_config_cursor)
                coda.cursor_goto_parent(clus_config_cursor)

                # The integration time is not allways equal to intgr_time/16
                # since the integration time is sometimes equal to 1/32 which
                # can not be expressed with the intgr_time field. So always use
                # 'coadd_factor * pet' to calculate the integration time.

                it = coadd_factor * pet

                # Read clus_dat
                if (clus_data_type == 1):
                    coda.cursor_goto_record_field_by_name(clus_dat_cursor, "sig")
                else:
                    coda.cursor_goto_record_field_by_name(clus_dat_cursor, "sigc")

                coda.cursor_goto_first_array_element(clus_dat_cursor)
                for readoutNr in range(0,num_readouts):
                    for pixelNr in range(start_pix,start_pix + clus_len):
                        # Read signal
                        coda.cursor_goto_record_field_by_name(clus_dat_cursor, "signal")

                        signal = coda.cursor_read_double(clus_dat_cursor)
                        pixel_array[chan_num][pixelNr] += signal

                        coda.cursor_goto_parent(clus_dat_cursor)

                        if ((readoutNr < num_readouts - 1) or (pixelNr < start_pix + clus_len - 1)):
                            coda.cursor_goto_next_array_element(clus_dat_cursor)

                coda.cursor_goto_parent(clus_dat_cursor)      # back to array
                coda.cursor_goto_parent(clus_dat_cursor)      # back to record

                for pixelNr in range(start_pix,start_pix + clus_len):
                    # Take average
                    pixel_array[chan_num][pixelNr] /= num_readouts

                    # Perform correction for fixed pattern noise and leakage current
                    pixel_array[chan_num][pixelNr] = pixel_array[chan_num][pixelNr] / it - fpn[chan_num][pixelNr] / pet - leak[chan_num][pixelNr]

                if (cluster < num_clus - 1):
                    coda.cursor_goto_next_array_element(clus_config_cursor)
                    coda.cursor_goto_next_array_element(clus_dat_cursor)

            # Apply bad pixel map
            for chan_num in range(0,8):
                for pixelNr in range(0,1024):
                    if (badpx[chan_num][pixelNr]):
                        pixel_array[chan_num][pixelNr] = NO_VALUE

            coda.cursor_goto_next_array_element(mds_cursor[mds_type])

        if (stateNr < num_states - 1):
            coda.cursor_goto_next_array_element(states_cursor)
def extract_grib_metadata(gribfile):
    """
      this will return a tuple containing:
        - ecmwfmars properties struct
        - levtype_options struct (see set_remote_url())
    """
    import coda

    @contextlib.contextmanager
    def coda_open(filename):
        coda_handle = coda.open(filename)
        try:
            yield coda_handle
        finally:
            coda.close(coda_handle)

    ecmwfmars = Struct()
    levtype_options = {}  # TODO: add extraction of levtype_options

    with coda_open(gribfile) as coda_handle:
        cursor = coda.Cursor()
        coda.cursor_set_product(cursor, coda_handle)
        num_messages = coda.cursor_get_num_elements(cursor)
        coda.cursor_goto_first_array_element(cursor)
        for i in range(num_messages):
            index = coda.cursor_get_available_union_field_index(cursor)
            coda.cursor_goto_record_field_by_index(cursor, index)
            step = 0
            if index == 0:
                # grib1
                centuryOfReferenceTimeOfData = coda.fetch(
                    cursor, "centuryOfReferenceTimeOfData")
                yearOfCentury = coda.fetch(cursor, "yearOfCentury")
                month = coda.fetch(cursor, "month")
                day = coda.fetch(cursor, "day")
                date = "%02d%02d-%02d-%02d" % (centuryOfReferenceTimeOfData -
                                               1, yearOfCentury, month, day)
                hour = coda.fetch(cursor, "hour")
                minute = coda.fetch(cursor, "minute")
                time = "%02d:%02d:00" % (hour, minute)
                unitOfTimeRange = coda.fetch(cursor, "unitOfTimeRange")
                if unitOfTimeRange != 0:
                    P1 = coda.fetch(cursor, "P1")
                    if unitOfTimeRange == 1:
                        step = P1
                    elif unitOfTimeRange == 2:
                        step = 24 * P1
                    elif unitOfTimeRange == 10:
                        step = 3 * P1
                    elif unitOfTimeRange == 11:
                        step = 6 * P1
                    elif unitOfTimeRange == 13:
                        step = 12 * P1
                    else:
                        raise Error("unsupported unitOfTimeRange: %d" %
                                    (unitOfTimeRange, ))
                local = coda.fetch(cursor, "local")
                try:
                    local = local[1:9].tobytes()
                except AttributeError:
                    # workaround for older numpy versions
                    local = local[1:9].tostring()
                marsclass, marstype, stream, expver = struct.unpack(
                    '>BBH4s', local)
            else:
                # grib2
                year = coda.fetch(cursor, "year")
                month = coda.fetch(cursor, "month")
                day = coda.fetch(cursor, "day")
                date = "%04d-%02d-%02d" % (year, month, day)
                hour = coda.fetch(cursor, "hour")
                minute = coda.fetch(cursor, "minute")
                second = coda.fetch(cursor, "second")
                time = "%02d:%02d:%02d" % (hour, minute, second)
                significanceOfReferenceTime = coda.fetch(
                    cursor, "significanceOfReferenceTime")
                local = coda.fetch(cursor, "local[0]")
                try:
                    local = local[2:12].tobytes()
                except AttributeError:
                    # workaround for older numpy versions
                    local = local[2:12].tostring()
                marsclass, marstype, stream, expver = struct.unpack(
                    '>HHH4s', local)
                coda.cursor_goto_record_field_by_name(cursor, "data")
                num_data = coda.cursor_get_num_elements(cursor)
                coda.cursor_goto_first_array_element(cursor)
                prev_step = None
                for j in range(num_data):
                    forecastTime = coda.fetch(cursor, "forecastTime")
                    if forecastTime != 0:
                        indicatorOfUnitOfTimeRange = coda.fetch(
                            cursor, "indicatorOfUnitOfTimeRange")
                        if indicatorOfUnitOfTimeRange == 0:
                            # minutes
                            step = 60 * forecastTime
                        elif indicatorOfUnitOfTimeRange == 1:
                            # hours
                            step = 60 * 60 * forecastTime
                        elif indicatorOfUnitOfTimeRange == 2:
                            # days
                            step = 24 * 60 * 60 * forecastTime
                        elif indicatorOfUnitOfTimeRange == 10:
                            # 3 hours
                            step = 3 * 60 * 60 * forecastTime
                        elif indicatorOfUnitOfTimeRange == 11:
                            # 6 hours
                            step = 6 * 60 * 60 * forecastTime
                        elif indicatorOfUnitOfTimeRange == 12:
                            # 12 hours
                            step = 12 * 60 * 60 * forecastTime
                        elif indicatorOfUnitOfTimeRange == 13:
                            # seconds
                            step = forecastTime
                        step = int(step / 3600.)  # convert seconds to hours
                        if prev_step is None:
                            prev_step = step
                        elif step != prev_step:
                            raise Error(
                                "not all data has the same 'step' time (%d) (%d)"
                                % (step, prev_step))
                    if j < num_data - 1:
                        coda.cursor_goto_next_array_element(cursor)
                coda.cursor_goto_parent(cursor)
                coda.cursor_goto_parent(cursor)
            if marsclass not in MARSCLASSES:
                raise Error("unsupported MARS class (%d)" % (marsclass, ))
            marsclass = MARSCLASSES[marsclass]
            if marstype not in MARSTYPES:
                raise Error("unsupported MARS type (%d)" % (marstype, ))
            marstype = MARSTYPES[marstype]
            if stream not in MARSSTREAMS:
                raise Error("unsupported MARS stream (%d)" % (stream, ))
            stream = MARSSTREAMS[stream]
            if 'date' in ecmwfmars:
                if date != ecmwfmars.date:
                    raise Error("not all data is for the same date (%s) (%s)" %
                                (date, ecmwfmars.date))
                if time != ecmwfmars.time:
                    raise Error("not all data is for the same time (%s) (%s)" %
                                (time, ecmwfmars.time))
                if step != 0:
                    if 'step' in ecmwfmars:
                        if step != ecmwfmars.step:
                            raise Error(
                                "not all data has the same 'step' time (%d) (%d)"
                                % (step, ecmwfmars.step))
                    else:
                        raise Error("not all data has the same 'step' time")
                else:
                    if 'step' in ecmwfmars and ecmwfmars.step != 0:
                        raise Error("not all data has the same 'step' time")
                if marsclass != ecmwfmars.marsclass:
                    raise Error(
                        "not all data has the same MARS class (%s) (%s)" %
                        (marsclass, ecmwfmars.marsclass))
                if marstype != ecmwfmars.type:
                    raise Error(
                        "not all data has the same MARS type (%s) (%s)" %
                        (marstype, ecmwfmars.type))
                if stream != ecmwfmars.stream:
                    raise Error(
                        "not all data has the same MARS stream (%s) (%s)" %
                        (stream, ecmwfmars.stream))
                if expver != ecmwfmars.expver:
                    raise Error(
                        "not all data has the same MARS experiment version (%s) (%s)"
                        % (expver, ecmwfmars.expver))
            else:
                ecmwfmars.date = date
                ecmwfmars.time = time
                if step != 0:
                    ecmwfmars.step = step
                ecmwfmars.marsclass = marsclass
                ecmwfmars.type = marstype
                ecmwfmars.stream = stream
                ecmwfmars.expver = expver
                if (marsclass, stream, expver, marstype) in PUBLIC_DATASETS:
                    ecmwfmars.dataset = PUBLIC_DATASETS[(marsclass, stream,
                                                         expver, marstype)]
            coda.cursor_goto_parent(cursor)
            if i < num_messages - 1:
                coda.cursor_goto_next_array_element(cursor)

    return ecmwfmars, levtype_options