def read(self):

        # reading canal supply:
        if self.include_canal_system:
            if self.VariableCanalSupply:
                if self.DailyCanalNC:
                    # introduce this test so that we do not ask the model to read
                    # a file from a timestep prior to the current simulation.
                    if not (self._modelTime.isFirstTimestep() &
                            (self.canalTimeLag > 0)):

                        day, month, year = self._modelTime.day, self._modelTime.month, self._modelTime.year
                        canalFileNC = self.canalFileNC.format(day=day,
                                                              month=month,
                                                              year=year)
                        exists = os.path.exists(canalFileNC)
                        max_wait_time = 60
                        wait_time = 0.1
                        total_wait_time = 0
                        while exists is False and total_wait_time <= max_wait_time:
                            time.sleep(wait_time)
                            exists = os.path.exists(canalFileNC)
                            total_wait_time += wait_time

                        if not exists:
                            msg = "canal file doesn't exist and maximum wait time exceeded"
                            raise AQError(msg)

                        CanalSupply = vos.netcdf2PCRobjCloneWithoutTime(
                            canalFileNC,
                            self.canalVarName,
                            cloneMapFileName=self.cloneMap,
                            LatitudeLongitude=True)
                        self.CanalSupply = CanalSupply[self.landmask]

                else:
                    CanalSupply = vos.netcdf2PCRobjClone(
                        self.canalFileNC,
                        self.canalVarName,
                        str(currTimeStep.fulldate),
                        useDoy=method_for_time_index,
                        cloneMapFileName=self.cloneMap,
                        LatitudeLongitude=True)
                    self.CanalSupply = CanalSupply[self.landmask]

            else:
                CanalSupply = vos.netcdf2PCRobjCloneWithoutTime(
                    self.canalFileNC,
                    self.canalVarName,
                    cloneMapFileName=self.cloneMap,
                    LatitudeLongitude=True)
                self.CanalSupply = CanalSupply[self.landmask]
示例#2
0
    def read_root_fraction(self):
        landmask = np.broadcast_to(self.var.landmask,
                                   (2, self.var.nLat, self.var.nLon))
        root_fraction = vos.netcdf2PCRobjCloneWithoutTime(
            self.rootFractionNC,
            self.rootFractionVarName,
            cloneMapFileName=self.var.cloneMap)
        root_fraction = root_fraction[landmask].reshape(2, self.var.nCell)
        root_fraction = np.broadcast_to(
            root_fraction[None, None, :, :],
            (self.var.nFarm, self.var.nCrop, 2, self.var.nCell))

        # scale root fraction - adapted from CWATM
        # landcoverType.py lines 311-319

        # 1 - add top layer to root fraction input data
        root_fraction_adj = np.zeros(
            (self.var.nFarm, self.var.nCrop, self.var.nLayer, self.var.nCell))
        top_layer_fraction = np.divide(
            self.var.root_depth[..., 0, :],
            (self.var.root_depth[..., 0, :] + self.var.root_depth[..., 1, :]))
        root_fraction_adj[...,
                          0, :] = top_layer_fraction * root_fraction[..., 0, :]
        root_fraction_adj[
            ..., 1, :] = (1. - top_layer_fraction) * root_fraction[..., 1, :]
        root_fraction_adj[..., 2, :] = (1. - root_fraction[..., 1, :])

        # 2 - scale so that the total root fraction sums to one
        root_fraction_sum = np.sum(root_fraction_adj, axis=-2)
        root_fraction_adj /= root_fraction_sum[..., None, :]
        self.var.root_fraction = root_fraction_adj.copy()
示例#3
0
    def initial(self):
        self.var.irrMgmtParameterFileNC = self.var._configuration.irrMgmtOptions[
            'irrMgmtParameterNC']
        self.var.parameter_names = [
            'IrrMethod', 'IrrInterval', 'SMT1', 'SMT2', 'SMT3', 'SMT4',
            'MaxIrr', 'AppEff', 'NetIrrSMT', 'WetSurf'
        ]
        for param in self.var.parameter_names:
            # nm = '_' + var
            vars(self.var)[param] = vos.netcdf2PCRobjCloneWithoutTime(
                self.var.irrMgmtParameterFileNC,
                param,
                cloneMapFileName=self.var.cloneMap)

        # check if an irrigation schedule file is required
        if np.sum(self.var.IrrMethod == 3) > 0:
            if self.var._configuration.irrMgmtOptions[
                    'irrScheduleNC'] != "None":
                self.var._configuration.irrMgmtOptions[
                    'irrScheduleNC'] = vos.getFullPath(
                        self.var._configuration.irrMgmtOptions[item],
                        self.var._configuration.globalOptions['inputDir'])
                self.var.irrScheduleFileNC = self.var._configuration.irrMgmtOptions[
                    'irrScheduleNC']
            else:
                logger.error(
                    'IrrMethod equals 3 in some or all places, but irrScheduleNC is not set in configuration file'
                )

        else:
            self.var.irrScheduleFileNC = None
    def initial(self):
        self.WaterTable = bool(
            int(self._configuration.GROUNDWATER['WaterTable']))
        self.VariableWaterTable = bool(
            int(self._configuration.GROUNDWATER['VariableWaterTable']))
        self.DailyGroundwaterNC = bool(
            int(self._configuration.GROUNDWATER['DailyGroundwaterInputFile']))

        zGW = np.ones_like(self.landmask) * 999.
        self.zGW = zGW[self.landmask]
        # self.zGW = np.ones((self.nCell)) * 999.

        if self.WaterTable:
            self.gwFileNC = self._configuration.GROUNDWATER[
                'groundwaterInputFile']
            self.gwVarName = self._configuration.GROUNDWATER[
                'groundwaterVariableName']
            self.gwTimeLag = int(self._configuration.GROUNDWATER['timeLag'])

            # if the program is configured to read daily groundwater files and
            # the time lag is positive, we also need to read an initial value
            # file
            if self.DailyGroundwaterNC & (self.gwTimeLag > 0):
                initialGroundwaterLevelNC = str(
                    self._configuration.
                    INITIAL_CONDITIONS['initialGroundwaterLevelInputFile'])
                zGW = vos.netcdf2PCRobjCloneWithoutTime(
                    initialGroundwaterLevelNC,
                    self.gwVarName,
                    cloneMapFileName=self.cloneMap,
                    LatitudeLongitude=True)
                self.zGW = zGW[self.landmask]
    def read(self):
        relative_elevation_var_names = [
            'dzRel0001', 'dzRel0005', 'dzRel0010', 'dzRel0020', 'dzRel0030',
            'dzRel0040', 'dzRel0050', 'dzRel0060', 'dzRel0070', 'dzRel0080',
            'dzRel0090', 'dzRel0100'
        ]

        for var_name in relative_elevation_var_names:
            d = vos.netcdf2PCRobjCloneWithoutTime(
                str(self.lc_configuration['relativeElevationInputFile']),
                var_name,
                cloneMapFileName=self.var.cloneMap)[self.var.landmask]
            vars(self.var)[var_name] = d

        self.var.elevation_standard_deviation = vos.netcdf2PCRobjCloneWithoutTime(
            str(self.lc_configuration['elevationStandardDeviationInputFile']),
            'dem_standard_deviation',
            cloneMapFileName=self.var.cloneMap)[self.var.landmask]
示例#6
0
 def read(self):
     """Function to read crop input parameters"""
     if len(self.var.crop_parameters_to_read) > 0:
         for param in self.var.crop_parameters_to_read:
             # nm = '_' + param
             vars(self.var)[param] = vos.netcdf2PCRobjCloneWithoutTime(
                 self.var.cropParameterFileNC,
                 param,
                 cloneMapFileName=self.var.cloneMap)
 def initial(self):
     self.var.fieldMgmtParameterFileNC = self.var._configuration.fieldMgmtOptions['fieldMgmtParameterNC']
     self.var.parameter_names = ['Mulches','MulchPctGS','MulchPctOS','fMulch','Bunds','zBund','BundWater']
     for var in self.var.parameter_names:
         # nm = '_' + var
         vars(self.var)[var] = vos.netcdf2PCRobjCloneWithoutTime(
             self.var.fieldMgmtParameterFileNC,
             var,
             cloneMapFileName=self.var.cloneMap)
示例#8
0
 def read_max_root_depth(self):
     max_root_depth = vos.netcdf2PCRobjCloneWithoutTime(
         self.maxRootDepthNC,
         self.maxRootDepthVarName,
         cloneMapFileName=self.var.cloneMap)  # nlat, nlon
     max_root_depth = max_root_depth[self.var.landmask]
     max_root_depth *= self.var.soildepth_factor  # CALIBRATION
     self.var.max_root_depth = np.broadcast_to(
         max_root_depth[None, None, :],
         (self.var.nFarm, self.var.nCrop, self.var.nCell))
 def read(self):
     """Function to read crop input parameters"""
     if len(self.crop_parameters_to_read) > 0:
         for param in self.crop_parameters_to_read:
             d = vos.netcdf2PCRobjCloneWithoutTime(
                 self.CropParameterNC,
                 param,
                 cloneMapFileName=self.var.cloneMap)
             d = d[self.var.landmask_crop].reshape(self.var.nCrop,self.var.nCell)
             vars(self.var)[param] = np.broadcast_to(
                 d,
                 (self.var.nFarm, self.var.nCrop, self.var.nCell))
示例#10
0
    def initial(self):

        # Define initial water contents
        self.var.initialConditionFileNC = self.var._configuration.globalOptions[
            'initialConditionNC']
        th = vos.netcdf2PCRobjCloneWithoutTime(
            self.var.initialConditionFileNC,
            'th',
            cloneMapFileName=self.var.cloneMap)
        init_cond_interp_method = self.var._configuration.globalOptions[
            'InterpMethod']
        # init_cond_type = self.var._configuration.globalOptions['initialConditionType']

        if init_cond_interp_method.lower() == 'depth':
            depths = vos.netcdfDim2NumPy(self.var.initialConditionFileNC,
                                         'depth')

            zBot = np.cumsum(self.var.dz)
            zTop = zBot - self.var.dz
            zMid = (zTop + zBot) / 2

            # add zero point
            if depths[0] > 0:
                depths = np.concatenate([[0.], depths])
                th = np.concatenate([th[0, ...][None, :], th], axis=0)

            if depths[-1] < zBot[-1]:
                depths = np.concatenate([depths, [zBot[-1]]])
                th = np.concatenate([th, th[-1, ...][None, :]], axis=0)

            # now interpolate to compartments
            f_thini = interpolate.interp1d(depths,
                                           th,
                                           axis=0,
                                           bounds_error=False,
                                           fill_value=(th[0, ...], th[-1,
                                                                      ...]))
            th = f_thini(zMid)
        else:
            th = th[self.var.layerIndex, :, :]

        # NB original Matlab code also allows users to supply initial condition
        # as field capacity, wilting point or saturation. We do not explicitly
        # include this option but of course it is possible to do this by
        # supplying a netCDF file containing the values. However, note that in
        # the original version if field capacity is specified and groundwater
        # table is present the initial water content is set to th_fc_adj once
        # this variable has been computed.

        th = np.broadcast_to(
            th, (self.var.nCrop, self.var.nComp, self.var.nLat, self.var.nLon))
        self.var.th = np.copy(th)
示例#11
0
    def initial_tubewell_capacity(self):

        # TODO - this is where initial tubewell ownership is read to the model

        initialTubewellCapacityNC = str(
            self.configuration['initialTubewellOwnershipInputFile'])
        tubewell_capacity_varname = str(
            self.configuration['initialTubewellOwnershipVariableName'])
        tubewell_count = vos.netcdf2PCRobjCloneWithoutTime(
            initialTubewellCapacityNC,
            tubewell_capacity_varname,
            cloneMapFileName=self.var.cloneMap,
            LatitudeLongitude=True)
        mask = np.broadcast_to(self.var.landmask, tubewell_count.shape)
        tubewell_count = np.reshape(tubewell_count[mask],
                                    (self.var.nFarm, self.var.nCell))
        self.var.TubewellCount = tubewell_count.copy()
示例#12
0
 def read_potential_crop_yield(self):
     if self.var.AnnualChangeInPotYield:
         if self.var._modelTime.timeStepPCR == 1 or self.var._modelTime.doy == 1:
             date = '%04i-%02i-%02i' % (self.var._modelTime.year, 1, 1)
             self.var.Yx = vos.netcdf2PCRobjClone(
                 self.var.PotYieldFileNC,
                 self.var.PotYieldVarName,
                 date,
                 useDoy=None,
                 cloneMapFileName=self.var.cloneMap,
                 LatitudeLongitude=True)
     else:
         if self.var._modelTime.timeStepPCR == 1:
             self.var.Yx = vos.netcdf2PCRobjCloneWithoutTime(
                 self.var.PotYieldFileNC,
                 self.var.PotYieldVarName,
                 cloneMapFileName=self.var.cloneMap)
    def initial_water_content(self):
        landmask = np.broadcast_to(
            self.var.landmask, (self.var.nLayer, self.var.nLat, self.var.nLon))
        self.var.initialConditionFileNC = str(
            self.var._configuration.
            INITIAL_CONDITIONS['initialConditionInputFile'])
        self.var.initialConditionVarName = str(
            self.var._configuration.
            INITIAL_CONDITIONS['initialConditionVariableName'])
        th = vos.netcdf2PCRobjCloneWithoutTime(
            self.var.initialConditionFileNC,
            self.var.initialConditionVarName,
            cloneMapFileName=self.var.cloneMap)

        th = th[landmask].reshape(self.var.nLayer, self.var.nCell)
        self.var.th = np.broadcast_to(
            th[None, None, ...], (self.var.nFarm, self.var.nCrop,
                                  self.var.nLayer, self.var.nCell)).copy()
        self.var.wc = (self.var.th * self.var.root_depth)
示例#14
0
    def initial(self):
        initialCanalAccessNC = str(
            self.configuration['initialCanalAccessInputFile'])
        canal_access_varname = str(
            self.configuration['initialCanalAccessVariableName'])
        try:
            canal_access = vos.netcdf2PCRobjCloneWithoutTime(
                initialCanalAccessNC,
                canal_access_varname,
                cloneMapFileName=self.var.cloneMap,
                LatitudeLongitude=True)
        except:
            canal_access = np.ones(
                (self.var.nFarm, self.var.nLat, self.var.nLon))

        mask = np.broadcast_to(self.var.landmask, canal_access.shape)
        canal_access = np.reshape(canal_access[mask],
                                  (self.var.nFarm, self.var.nCell))
        self.var.CanalAccess = canal_access.copy()
 def read_crop_area(self, date = None):
     if date is None:
         crop_area = vos.netcdf2PCRobjCloneWithoutTime(
             self.CropAreaFileNC,
             self.CropAreaVarName,
             cloneMapFileName = self.var.cloneMap,
             LatitudeLongitude = True)
     else:
         crop_area = vos.netcdf2PCRobjClone(
             self.CropAreaFileNC,
             self.CropAreaVarName,
             date,
             useDoy = None,
             cloneMapFileName = self.var.cloneMap,
             LatitudeLongitude = True)
     crop_area = np.reshape(
         crop_area[self.var.landmask_crop],
         (self.var.nCrop, self.var.nCell))
     crop_area = np.float64(crop_area)
     return crop_area
 def read_potential_crop_yield(self):        
     start_of_model_run = (self.var._modelTime.timeStepPCR == 1)
     start_of_year = (self.var._modelTime.doy == 1)
     if self.AnnualChangeInPotYield:
         if start_of_model_run or start_of_year:
             date = datetime.datetime(self.var._modelTime.year, 1, 1, 0, 0, 0)
             Yx = vos.netcdf2PCRobjClone(
                 self.PotYieldNC,
                 self.PotYieldVarName,
                 date,
                 useDoy = None,
                 cloneMapFileName = self.var.cloneMap,
                 LatitudeLongitude = True)
             self.var.Yx = Yx[self.var.landmask_crop].reshape(self.var.nCrop, self.var.nCell)
     else:
         if start_of_model_run:
             # date = datetime.datetime(self.staticLandCoverYear, 1, 1, 0, 0, 0) # ***TODO***
             Yx = vos.netcdf2PCRobjCloneWithoutTime(
                 self.PotYieldNC,
                 self.PotYieldVarName,
                 cloneMapFileName = self.var.cloneMap)
             self.var.Yx = Yx[self.var.landmask_crop].reshape(self.var.nCrop, self.var.nCell)
示例#17
0
    def set_farm_category(self):
        if not self.FarmCategoryFileNC == "None":
            start_of_model_run = (self.var._modelTime.timeStepPCR == 1)
            start_of_year = (self.var._modelTime.doy == 1)
            if self.AnnualChangeInFarmCategory:
                if start_of_model_run or start_of_year:
                    date = datetime.datetime(self.var._modelTime.year, 1, 1, 0,
                                             0, 0)
                    farm_category_new = vos.netcdf2PCRobjClone(
                        self.FarmCategoryFileNC,
                        self.FarmCategoryVarName,
                        date,
                        useDoy=None,
                        cloneMapFileName=self.var.cloneMap,
                        LatitudeLongitude=True)
                    mask = np.broadcast_to(
                        self.var.landmask,
                        (self.var.nFarm, self.var.nLat, self.var.nLon))
                    farm_category_new = np.reshape(
                        farm_category_new[mask],
                        (self.var.nFarm, self.var.nCell))

                if np.any(self.var.GrowingSeasonDayOne):
                    self.var.FarmCategory[self.var.GrowingSeasonDayOne[
                        0, :, :]] = (farm_category_new[
                            self.var.GrowingSeasonDayOne[0, :, :]])
            else:
                if start_of_model_run:
                    farm_category = vos.netcdf2PCRobjCloneWithoutTime(
                        self.FarmCategoryFileNC,
                        self.FarmCategoryVarName,
                        cloneMapFileName=self.var.cloneMap)
                    mask = np.broadcast_to(
                        self.var.landmask,
                        (self.var.nFarm, self.var.nLat, self.var.nLon))
                    farm_category = np.reshape(
                        farm_category[mask], (self.var.nFarm, self.var.nCell))
                    self.var.FarmCategory = farm_category.copy()
    def read(self):

        # method for finding time indexes in the groundwater netdf file:
        # - the default one
        method_for_time_index = None
        # - based on the ini/configuration file (if given)
        # if 'time_index_method_for_groundwater_netcdf' in self._configuration.GROUNDWATER.keys() and\
        #                                                    self._configuration.GROUNDWATER['time_index_method_for_groundwater_netcdf'] != "None":
        #     method_for_time_index = self._configuration.GROUNDWATER['time_index_method_for_groundwater_netcdf']

        # reading groundwater:
        if self.WaterTable:
            if self.VariableWaterTable:

                # DailyGroundwaterNC is a logical indicating whether a separate
                # netCDF is used for each time step - use this for coupling
                if self.DailyGroundwaterNC:

                    # introduce this test so that we do not ask the model to read
                    # a file from a timestep prior to the current simulation.
                    if not (self._modelTime.isFirstTimestep() &
                            (self.gwTimeLag > 0)):

                        tm = self._modelTime.currTime - datetime.timedelta(
                            self.gwTimeLag)
                        day, month, year = tm.day, tm.month, tm.year

                        # Fill named placeholders (NB we have already checked that
                        # the specified filename contains these placeholders)
                        gwFileNC = self.gwFileNC.format(day=day,
                                                        month=month,
                                                        year=year)

                        # Check whether the file is present in the filesystem; if
                        # it doesn't, enter a while loop which periodically checks
                        # whether the file exists. We specify a maximum wait time
                        # in order to prevent the model hanging if the file never
                        # materialises.
                        exists = os.path.exists(gwFileNC)
                        max_wait_time = 60
                        wait_time = 0.1
                        total_wait_time = 0
                        while exists is False and total_wait_time <= max_wait_time:
                            time.sleep(wait_time)
                            exists = os.path.exists(gwFileNC)
                            total_wait_time += wait_time

                        if not exists:
                            msg = "groundwater file doesn't exist and maximum wait time exceeded"
                            raise AQError(msg)

                        zGW = vos.netcdf2PCRobjCloneWithoutTime(
                            gwFileNC,
                            self.gwVarName,
                            cloneMapFileName=self.cloneMap,
                            LatitudeLongitude=True)
                        self.zGW = zGW[self.landmask]

                else:
                    zGW = vos.netcdf2PCRobjClone(
                        self.gwFileNC,
                        self.gwVarName,
                        str(currTimeStep.fulldate),
                        useDoy=method_for_time_index,
                        cloneMapFileName=self.cloneMap,
                        LatitudeLongitude=True)
                    self.zGW = zGW[self.landmask]

            else:
                zGW = vos.netcdf2PCRobjCloneWithoutTime(
                    self.gwFileNC,
                    self.gwVarName,
                    cloneMapFileName=self.cloneMap,
                    LatitudeLongitude=True)
                self.zGW = zGW[self.landmask]
示例#19
0
    def read(self):

        # method for finding time indexes in the groundwater netdf file:
        # - the default one
        method_for_time_index = None
        # - based on the ini/configuration file (if given)
        # if 'time_index_method_for_groundwater_netcdf' in self.var._configuration.groundwaterOptions.keys() and\
        #                                                    self.var._configuration.groundwaterOptions['time_index_method_for_groundwater_netcdf'] != "None":
        #     method_for_time_index = self.var._configuration.groundwaterOptions['time_index_method_for_groundwater_netcdf']
        
        # reading groundwater:
        if self.var.WaterTable:
            if self.var.VariableWaterTable:

                # DailyForcingData is a logical indicating whether a separate
                # netCDF is used for each time step - use this for coupling
                if self.var.DailyForcingData:

                    day, month, year = self.var._modelTime.day, self.var._modelTime.month, self.var._modelTime.year

                    # Fill named placeholders (NB we have already checked that
                    # the specified filename contains these placeholders)
                    gwFileNC = self.var.gwFileNC.format(day=day, month=month, year=year)

                    # Check whether the file is present in the filesystem; if
                    # it doesn't, enter a while loop which periodically checks
                    # whether the file exists. We specify a maximum wait time
                    # in order to prevent the model hanging if the file never
                    # materialises.
                    
                    exists = os.path.exists(gwFileNC)
                    max_wait_time = 60
                    wait_time = 0.1
                    total_wait_time = 0
                    while exists is False and total_wait_time <= max_wait_time:
                        time.sleep(wait_time)
                        exists = os.path.exists(gwFileNC)
                        total_wait_time += wait_time

                    if not exists:
                        print "groundwater file doesn't exist and maximum wait time exceeded"
                        raise   # TODO: make error class

                    self.var.zGW = vos.netcdf2PCRobjCloneWithoutTime(gwFileNC,
                                                                     self.var.gwVarName,
                                                                     cloneMapFileName = self.var.cloneMap,
                                                                     LatitudeLongitude = True)
                        
                else:
                    self.var.zGW = vos.netcdf2PCRobjClone(self.var.gwFileNC,
                                                          self.var.gwVarName,
                                                          str(currTimeStep.fulldate),
                                                          useDoy = method_for_time_index,
                                                          cloneMapFileName = self.var.cloneMap,
                                                          LatitudeLongitude = True)
                    
            else:
                self.var.zGW = vos.netcdf2PCRobjCloneWithoutTime(self.var.gwFileNC,
                                                                 self.var.gwVarName,
                                                                 cloneMapFileName = self.var.cloneMap,
                                                                 LatitudeLongitude = True)
                
        else:
            self.var.zGW = None
    def readSoil(self):

        # Get layer and compartment thickness (zLayer and dz) from dimensions
        # Layers:
        zlayermid = vos.netcdfDim2NumPy(self.var.soilAndTopoFileNC, 'layer')
        nlayer = zlayermid.size
        zlayer = np.zeros((nlayer))
        runtot = 0
        for layer in range(nlayer):
            zlayer[layer] = (zlayermid[layer] - runtot) * 2
            runtot = np.sum(zlayer[:(layer + 1)])
        self.var.nLayer = nlayer
        self.var.zLayer = zlayer

        # Compartments:
        zmid = vos.netcdfDim2NumPy(self.var.soilAndTopoFileNC, 'compartment')
        ncomp = zmid.size
        dz = np.zeros((ncomp))
        runtot = 0
        for comp in range(ncomp):
            dz[comp] = (zmid[comp] - runtot) * 2
            runtot = np.sum(dz[:(comp + 1)])
        self.var.nComp = ncomp
        self.var.dz = dz
        self.var.dzsum = np.cumsum(dz)

        # These parameters have dimensions depth,lat,lon
        soilParams1 = ['ksat', 'th_s', 'th_fc', 'th_wp']
        for var in soilParams1:
            d = vos.netcdf2PCRobjCloneWithoutTime(
                self.var.soilAndTopoFileNC,
                var,
                cloneMapFileName=self.var.cloneMap)
            vars(self.var)[var] = np.broadcast_to(
                d, (self.var.nCrop, self.var.nLayer, self.var.nLat,
                    self.var.nLon))

        # These parameters have dimensions lat,lon
        soilParams2 = [
            'CalcSHP', 'EvapZsurf', 'EvapZmin', 'EvapZmax', 'Kex', 'fevap',
            'fWrelExp', 'fwcc', 'AdjREW', 'REW', 'AdjCN', 'CN', 'zCN', 'zGerm',
            'zRes', 'fshape_cr'
        ]
        for var in soilParams2:
            d = vos.netcdf2PCRobjCloneWithoutTime(
                self.var.soilAndTopoFileNC,
                var,
                cloneMapFileName=self.var.cloneMap)
            d = np.broadcast_to(d,
                                (self.var.nCrop, self.var.nLat, self.var.nLon))
            vars(self.var)[var] = np.copy(
                d
            )  #np.broadcast_to(d, (self.var.nCrop, self.var.nLat, self.var.nLon))

        # map layers to compartments - the result is a 1D array with length
        # equal to nComp where the value of each element is the index of the
        # corresponding layer. For the time being we use the layer in which
        # the midpoint of each compartment is located.
        #
        # some data to try the command yourself.var:
        #
        # from numpy import np
        # zMid = np.array((0.05,0.15,0.25,0.375,0.525,0.7,0.9,1.125,1.375,1.625,1.875,2.15))
        # zLayerTop = np.array((0,0.5))
        # nLayer = 2
        zBot = np.cumsum(self.var.dz)
        zTop = zBot - self.var.dz
        zMid = (zTop + zBot) / 2
        zLayerBot = np.cumsum(self.var.zLayer)
        zLayerTop = zLayerBot - self.var.zLayer
        self.var.layerIndex = np.sum(((zMid[:, None] * np.ones(
            (self.var.nLayer))[None, :]) > zLayerTop),
                                     axis=1) - 1

        # The following is adapted from AOS_ComputeVariables.m, lines 129-139
        # "Calculate drainage characteristic (tau)
        self.var.tau = 0.0866 * (self.var.ksat**0.35)
        self.var.tau = np.round(self.var.tau * 100) / 100
        self.var.tau[self.var.tau > 1] = 1
        self.var.tau[self.var.tau < 0] = 0

        # The following is adapted from AOS_ComputeVariables.m, lines 25
        self.var.th_dry = self.var.th_wp / 2

        cond = (self.var.AdjREW == 0)
        self.var.REW[cond] = (np.round(
            (1000 * (self.var.th_fc[:, 0, ...] - self.var.th_dry[:, 0, ...]) *
             self.var.EvapZsurf)))[cond]
        # The following is adapted from AOS_ComputeVariables.m, lines 147-151
        # "Calculate upper and lower curve numbers"
        self.var.CNbot = np.round(1.4 * (np.exp(-14 * np.log(10))) +
                                  (0.507 * self.var.CN) -
                                  (0.00374 * self.var.CN**2) +
                                  (0.0000867 * self.var.CN**3))
        self.var.CNtop = np.round(5.6 * (np.exp(-14 * np.log(10))) +
                                  (2.33 * self.var.CN) -
                                  (0.0209 * self.var.CN**2) +
                                  (0.000076 * self.var.CN**3))

        # transform certain soil properties to (ncrop, ncomp, nlat, nlon)
        soil_params = ['th_s', 'th_fc', 'th_wp', 'th_dry', 'ksat', 'tau']
        # soil_params = ['th_s','th_fc','th_wp','th_dry','ksat','tau','fshape_cr']
        for nm in soil_params:
            newnm = nm + '_comp'
            vars(self.var)[newnm] = vars(self.var)[nm][:, self.var.layerIndex,
                                                       ...]
    def read(self):
        self.var.nLayer = 3

        # soil depths
        soildepth0 = np.full((self.var.nLat, self.var.nLon),
                             0.05)[self.var.landmask]
        soildepth1 = vos.netcdf2PCRobjCloneWithoutTime(
            str(self.var._configuration.SOIL['soilDepthOneInputFile']),
            str(self.var._configuration.SOIL['soilDepthOneVariableName']),
            cloneMapFileName=self.var.cloneMap)[self.var.landmask]
        soildepth1 = np.maximum(0.05, soildepth1 - soildepth0)

        soildepth2 = vos.netcdf2PCRobjCloneWithoutTime(
            str(self.var._configuration.SOIL['soilDepthTwoInputFile']),
            str(self.var._configuration.SOIL['soilDepthTwoVariableName']),
            cloneMapFileName=self.var.cloneMap)[self.var.landmask]
        soildepth2 = np.maximum(0.05, soildepth2)
        soil_depth = np.stack([soildepth0, soildepth1, soildepth2])

        # CALIBRATION
        self.var.soildepth_factor = 1.  # TODO: read from configuration
        soil_depth[1] *= self.var.soildepth_factor
        soil_depth[2] *= self.var.soildepth_factor
        self.var.soil_depth = np.broadcast_to(
            soil_depth[None, None, :, :],
            (self.var.nFarm, self.var.nCrop, self.var.nLayer, self.var.nCell))

        # crop group number
        # TODO: would it make more sense to have this per crop?
        self.var.crop_group_number = vos.netcdf2PCRobjCloneWithoutTime(
            str(self.var._configuration.SOIL['cropGroupNumberInputFile']),
            str(self.var._configuration.SOIL['cropGroupNumberVariableName']),
            cloneMapFileName=self.var.cloneMap)[self.var.landmask]

        # These parameters have dimensions depth,lat,lon
        landmask = np.broadcast_to(
            self.var.landmask, (self.var.nLayer, self.var.nLat, self.var.nLon))
        ksat = vos.netcdf2PCRobjCloneWithoutTime(
            str(self.lc_configuration['KsatInputFile']),
            str(self.lc_configuration['KsatVariableName']),
            cloneMapFileName=self.var.cloneMap)
        ksat = ksat[landmask].reshape(self.var.nLayer, self.var.nCell)
        self.var.ksat = np.broadcast_to(
            ksat[None, None, :, :], (self.var.nFarm, self.var.nCrop,
                                     self.var.nLayer, self.var.nCell)).copy()
        self.var.ksat /= 100.  # cm d-1 -> m d-1 ***TODO*** put factor in config

        # Saturated water content
        th_s = vos.netcdf2PCRobjCloneWithoutTime(
            self.lc_configuration['saturatedWaterContentInputFile'],
            self.lc_configuration['saturatedWaterContentVariableName'],
            cloneMapFileName=self.var.cloneMap)
        th_s = th_s[landmask].reshape(self.var.nLayer, self.var.nCell)
        self.var.th_s = np.broadcast_to(
            th_s[None, None, :, :],
            (self.var.nFarm, self.var.nCrop, self.var.nLayer, self.var.nCell))

        # # Field capacity
        # th_fc = vos.netcdf2PCRobjCloneWithoutTime(
        #     self.lc_configuration['fieldCapacityInputFile'],
        #     self.lc_configuration['fieldCapacityVariableName'],
        #     cloneMapFileName=self.var.cloneMap)
        # th_fc = th_fc[landmask].reshape(self.var.nLayer,self.var.nCell)
        # self.var.th_fc = np.broadcast_to(th_fc[None,None,:,:], (self.var.nFarm, self.var.nCrop, self.var.nLayer, self.var.nCell))

        # # Wilting point
        # th_wp = vos.netcdf2PCRobjCloneWithoutTime(
        #     self.lc_configuration['wiltingPointInputFile'],
        #     self.lc_configuration['wiltingPointVariableName'],
        #     cloneMapFileName=self.var.cloneMap)
        # th_wp = th_wp[landmask].reshape(self.var.nLayer,self.var.nCell)
        # self.var.th_wp = np.broadcast_to(th_wp[None,None,:,:], (self.var.nFarm, self.var.nCrop, self.var.nLayer, self.var.nCell))

        # Residual water content
        th_res = vos.netcdf2PCRobjCloneWithoutTime(
            self.lc_configuration['residualWaterContentInputFile'],
            self.lc_configuration['residualWaterContentVariableName'],
            cloneMapFileName=self.var.cloneMap)
        th_res = th_res[landmask].reshape(self.var.nLayer, self.var.nCell)
        self.var.th_res = np.broadcast_to(
            th_res[None, None, :, :],
            (self.var.nFarm, self.var.nCrop, self.var.nLayer, self.var.nCell))

        # # The following is adapted from AOS_ComputeVariables.m, lines 25
        # self.var.th_dry = self.var.th_wp / 2

        # Van Genuchten alpha shape parameter
        van_genuchten_alpha = vos.netcdf2PCRobjCloneWithoutTime(
            self.lc_configuration['alphaInputFile'],
            self.lc_configuration['alphaVariableName'],
            cloneMapFileName=self.var.cloneMap)
        van_genuchten_alpha = van_genuchten_alpha[landmask].reshape(
            self.var.nLayer, self.var.nCell)
        self.var.van_genuchten_alpha = np.broadcast_to(
            van_genuchten_alpha[None, None, :, :],
            (self.var.nFarm, self.var.nCrop, self.var.nLayer, self.var.nCell))

        # Van Genuchten lambda shape parameter
        van_genuchten_lambda = vos.netcdf2PCRobjCloneWithoutTime(
            self.lc_configuration['lambdaInputFile'],
            self.lc_configuration['lambdaVariableName'],
            cloneMapFileName=self.var.cloneMap)
        van_genuchten_lambda = van_genuchten_lambda[landmask].reshape(
            self.var.nLayer, self.var.nCell)
        self.var.van_genuchten_lambda = np.broadcast_to(
            van_genuchten_lambda[None, None, :, :],
            (self.var.nFarm, self.var.nCrop, self.var.nLayer, self.var.nCell))
示例#22
0
 def set_grid_cell_area(self):
     grid_cell_area = vos.netcdf2PCRobjCloneWithoutTime(
         str(self._configuration.MASK_OUTLET['gridCellAreaInputFile']),
         str(self._configuration.MASK_OUTLET['gridCellAreaVariableName']),
         cloneMapFileName = self.cloneMap)
     self.grid_cell_area = grid_cell_area[self.landmask]