Skip to content
Snippets Groups Projects
convert_cvi_colloc.py 3.27 KiB

import os
import shutil
import sys
import numpy as np
from pyhdf import SD

class ConvertCviColloc(object):

    def main(self):

        colloc_file, out_file = sys.argv[1:]
        if not os.stat(colloc_file).st_size:
            print 'Zero collocations'
            empty_file = os.path.join(os.path.dirname(__file__), 'cris_viiri.empty.hdf')
            shutil.copy(empty_file, out_file)
            sys.exit(0)
        explicit_idxs = ExplicitCollocationIndexSet.from_file(
                            colloc_file,
                            ['Master_Index_3', 'Master_Index_2', 'Master_Index_1'],
                            ['Follower_Index_2', 'Follower_Index_1'])
        implicit_idxs = ImplicitCollocationIndexSet.from_explicit(
                            explicit_idxs, master_dimensions=[60, 30, 9])
        implicit_idxs.to_file(out_file,
                              ['VIIRS_Along_Track_IDX', 'VIIRS_Across_Track_IDX'],
                              'Number_Of_VIIRS_FOV')

class ExplicitCollocationIndexSet(object):

    @classmethod
    def from_file(cls, path, master_idx_sdss, follower_idx_sdss):

        sd = SD.SD(path)
        return cls([sd.select(n)[:] - 1 for n in master_idx_sdss],
                   [sd.select(n)[:] - 1 for n in follower_idx_sdss])

    def __init__(self, master_indexes, follower_indexes):

        self.master_indexes = np.array(master_indexes)
        self.follower_indexes = np.array(follower_indexes)

    @property
    def num_master_fovs(self):

        return self.master_indexes.shape[1]

    @property
    def max_follower_fovs(self):

        return self.follower_indexes.shape[2]

    @property
    def num_follower_dimensions(self):

        return self.follower_indexes.shape[0]

    def by_master_fov(self):

        for i in range(self.num_master_fovs):
            yield self.master_indexes[:,i], self.follower_indexes[:,i,:]

class ImplicitCollocationIndexSet(object):

    @classmethod
    def from_explicit(cls, explicit_idxs, master_dimensions):

        shape = ([explicit_idxs.num_follower_dimensions] + list(master_dimensions) +
                     [explicit_idxs.max_follower_fovs])
        implicit_follower_idxs = np.zeros(shape, np.int) - 1
        for master_idx, collocated_follower_idxs in explicit_idxs.by_master_fov():
            k = tuple([slice(None)] + list(master_idx) + [slice(None)])
            implicit_follower_idxs[k] = collocated_follower_idxs
        return cls(implicit_follower_idxs)

    def __init__(self, follower_idxs):

        self.follower_idxs = np.array(follower_idxs)

    @property
    def master_shape(self):

        return self.follower_idxs.shape[1:-1]

    @property
    def num_follower_fovs(self):

        return (self.follower_idxs[0] != -1).sum(axis=-1)

    def to_file(self, path, idx_sdss, count_sds):

        sd = SD.SD(path, SD.SDC.WRITE | SD.SDC.CREATE | SD.SDC.TRUNC)
        for i, sds_name in enumerate(idx_sdss):
            a = self.follower_idxs[i,...] + 1
            sds = sd.create(sds_name, SD.SDC.INT32, a.shape)
            sds[:] = a.astype(np.int32)
            sds.endaccess()
        sds = sd.create(count_sds, SD.SDC.INT32, self.master_shape)
        sds[:] = self.num_follower_fovs.astype(np.int32)
        sds.endaccess()
        sd.end()

if __name__ == '__main__':
    ConvertCviColloc().main()