obsreconmanager.py 10.4 KB
Newer Older
# coding=utf-8
import os

from earthdiagnostics.datamanager import DataManager
from earthdiagnostics.variable_type import VariableType


class ObsReconManager(DataManager):
    """
    Data manager class for CMORized experiments
    """
    def __init__(self, config):
        super(ObsReconManager, self).__init__(config)
        data_folders = self.config.data_dir.split(':')
        self.config.data_dir = None
        for data_folder in data_folders:
            if os.path.isdir(os.path.join(data_folder, self.config.data_type,  self.experiment.institute.lower(),
                                          self.experiment.model.lower())):
                self.config.data_dir = data_folder
                break

        if not self.config.data_dir:
            raise Exception('Can not find model data')

        if self.config.data_type in ('obs', 'recon') and self.experiment.chunk_size != 1:
            raise Exception('For obs and recon data chunk_size must be always 1')

    # noinspection PyUnusedLocal
Javier Vegas-Regidor's avatar
Javier Vegas-Regidor committed
    def request_leadtimes(self, domain, variable, startdate, member, leadtimes, frequency=None,
                          vartype=VariableType.MEAN):
        filepath = self.get_file_path(startdate, domain, variable, frequency, vartype)
        return self._get_file_from_storage(filepath)

    def create_link(self, domain, filepath, frequency, var, grid, move_old, vartype):
        pass

    # noinspection PyUnusedLocal
    def file_exists(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None,
                    vartype=VariableType.MEAN):
        """
        Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy

        :param domain: CMOR domain
        :type domain: str
        :param var: variable name
        :type var: str
        :param startdate: file's startdate
        :type startdate: str
        :param member: file's member
        :type member: int
        :param chunk: file's chunk
        :type chunk: int
        :param grid: file's grid (only needed if it is not the original)
        :type grid: str
        :param box: file's box (only needed to retrieve sections or averages)
        :type box: Box
        :param frequency: file's frequency (only needed if it is different from the default)
        :type frequency: Frequency
        :param vartype: Variable type (mean, statistic)
        :type vartype: VariableType
        :return: path to the copy created on the scratch folder
        :rtype: str
        """
        return NotImplementedError

    def get_file_path(self, startdate, domain, var, frequency, vartype,
                      box=None, grid=None):
        """
        Returns the path to a concrete file
        :param startdate: file's startdate
        :type startdate: str
        :param domain: file's domain
        :type domain: str
        :param var: file's var
        :type var: str
        :param frequency: file's frequency
        :type frequency: Frequency
        :param box: file's box
        :type box: Box
        :param grid: file's grid
        :type grid: str
        :return: path to the file
        :rtype: str
        :param vartype: Variable type (mean, statistic)
        :type vartype: VariableType
        """
        if not frequency:
            frequency = self.config.frequency
        var = self._get_final_var_name(box, var)

        folder_path = self._get_folder_path(frequency, domain, var, grid, vartype)
        file_name = self._get_file_name(var, startdate)

        filepath = os.path.join(folder_path, file_name)
        return filepath

    def _get_folder_path(self, frequency, domain, variable, grid, vartype):

        if self.config.data_type == 'exp' and not frequency.frequency.endswith('hr'):
            var_folder = self.get_varfolder(domain, variable, grid)
        else:
            var_folder = variable

        folder_path = os.path.join(self.config.data_dir, self.config.data_type,
                                   self.experiment.institute.lower(),
                                   self.experiment.model.lower(),
                                   frequency.folder_name(vartype),
                                   var_folder)
        return folder_path

    def get_year(self, domain, var, startdate, member, year, grid=None, box=None, vartype=VariableType.MEAN):
        """
        Ge a file containing all the data for one year for one variable
        :param domain: variable's domain
        :type domain: str
        :param var: variable's name
        :type var: str
        :param startdate: startdate to retrieve
        :type startdate: str
        :param member: member to retrieve
        :type member: int
        :param year: year to retrieve
        :type year: int
        :param grid: variable's grid
        :type grid: str
        :param box: variable's box
        :type box: Box
        :param vartype: Variable type (mean, statistic)
        :type vartype: VariableType
        :return:
        """
        raise NotImplementedError()

    def get_var_url(self, var, startdate, frequency, box, vartype):
        """
        Get url for dataset
        :param var: variable to retrieve
        :type var: str
        :param startdate: startdate to retrieve
        :type startdate: str
        :param frequency: frequency to get:
        :type frequency: Frequency | None
        :param box: box to get
        :type box: Box
        :param vartype: type of variable
        :type vartype: VariableType
        :return:
        """
        if not frequency:
            frequency = self.config.frequency
        var = self._get_final_var_name(box, var)
        full_path = os.path.join(self.config.data_dir, self.config.data_type, self.experiment.institute,
                                 self.experiment.model, frequency.folder_name(vartype))
        full_path = os.path.join(full_path, var, self._get_file_name(var, startdate))
        return full_path

    def _get_file_name(self, var, startdate):
        if startdate:
            if self.config.data_type != 'exp':
                startdate = startdate[0:6]
            return '{0}_{1}.nc'.format(var, startdate)
        else:
            return '{0}.nc'.format(var)

    def link_file(self, domain, var, cmor_var, startdate, member, chunk=None, grid=None,
                  frequency=None, year=None, date_str=None, move_old=False, vartype=VariableType.MEAN):
        """
        Creates the link of a given file from the CMOR repository.

        :param cmor_var: 
        :param move_old:
        :param date_str:
        :param year: if frequency is yearly, this parameter is used to give the corresponding year
        :type year: int
        :param domain: CMOR domain
        :type domain: str
        :param var: variable name
        :type var: str
        :param startdate: file's startdate
        :type startdate: str
        :param member: file's member
        :type member: int
        :param chunk: file's chunk
        :type chunk: int
        :param grid: file's grid (only needed if it is not the original)
        :type grid: str
        :param frequency: file's frequency (only needed if it is different from the default)
        :type frequency: str
        :param vartype: Variable type (mean, statistic)
        :type vartype: VariableType
        :return: path to the copy created on the scratch folder
        :rtype: str
        """
        # THREDDSManager does not require links
        pass

    def request_chunk(self, domain, var, startdate, member, chunk, grid=None, box=None, frequency=None,
                      vartype=VariableType.MEAN):
        """
        Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy

        :param vartype: 
        :param domain: CMOR domain
        :type domain: Domain
        :param var: variable name
        :type var: str
        :param startdate: file's startdate
        :type startdate: str
        :param member: file's member
        :type member: int
        :param chunk: file's chunk
        :type chunk: int
        :param grid: file's grid (only needed if it is not the original)
        :type grid: str|NoneType
        :param box: file's box (only needed to retrieve sections or averages)
        :type box: Box
        :param frequency: file's frequency (only needed if it is different from the default)
        :type frequency: Frequency|NoneType
        :return: path to the copy created on the scratch folder
        :rtype: str
        """
        var = self._get_final_var_name(box, var)
        filepath = self.get_file_path(startdate, domain, var, frequency, vartype, grid, box)
        return self._get_file_from_storage(filepath)

    def declare_chunk(self, domain, var, startdate, member, chunk, grid=None, region=None, box=None, frequency=None,
                      vartype=VariableType.MEAN, diagnostic=None):
        """
        Copies a given file from the CMOR repository to the scratch folder and returns the path to the scratch's copy

        :param diagnostic: 
        :param region: 
        :param domain: CMOR domain
        :type domain: Domain
        :param var: variable name
        :type var: str
        :param startdate: file's startdate
        :type startdate: str
        :param member: file's member
        :type member: int
        :param chunk: file's chunk
        :type chunk: int
        :param grid: file's grid (only needed if it is not the original)
        :type grid: str|NoneType
        :param box: file's box (only needed to retrieve sections or averages)
        :type box: Box
        :param frequency: file's frequency (only needed if it is different from the default)
        :type frequency: Frequency|NoneType
        :param vartype: Variable type (mean, statistic)
        :type vartype: VariableType
        :return: path to the copy created on the scratch folder
        :rtype: str
        """
        if not frequency:
            frequency = self.config.frequency
        original_name = var
        cmor_var = self.variable_list.get_variable(var)
        if cmor_var:
            var = cmor_var.short_name
        final_name = var

        filepath = self.get_file_path(startdate, domain, final_name, frequency, vartype, box, grid)
        netcdf_file = self._declare_generated_file(filepath, domain, final_name, cmor_var, self.config.data_convention,
                                                   region, diagnostic, grid, vartype, original_name)
        netcdf_file.frequency = frequency
        return netcdf_file