Source code for fmu.tools.rms.zone_mapping

from typing import Any

DEBUG_OFF = 0
DEBUG_ON = 1
DEBUG_VERBOSE = 2
DEBUG_VERY_VERBOSE = 3


[docs] class ZoneMapping: """ Keep info about available zones in modelling grid, its zone numbers in the zone parameter and corresponding zone names. The grid object contains info about zone names for the grid and number of layers per zone as the most important info in this class. The zone parameter (3D parameter with zone number per grid cell) contains a table with corresponding zone name and zone number. """ def __init__( self, grid_model: Any, grid: Any, real_number: int = 0, fmu_mode: bool = False, debug_level: int = DEBUG_OFF, ): assert grid_model assert grid self.grid_model = grid_model self.grid = grid self.real_number = real_number # Key is zone index in the zones in the grid self.grid_zone_dict: dict[int, dict] = {} # Key is zone_number and value is zone name self.zone_code_names: dict[int, str] = {} # Key is zone_number self.grid_zone_index_dict: dict[int, int] = {} if not fmu_mode: # The zone parameter zone_param = get_zone_parameter( self.grid_model, realization_number=self.real_number, debug_level=debug_level, ) self.zone_code_names = zone_param.code_names self.zone_param_name = zone_param.name else: self.zone_code_names = {1: "Zone1"} self.zone_param_name = "Zone1" indexer = self.grid.simbox_indexer zonation = indexer.zonation if debug_level >= DEBUG_VERY_VERBOSE: print(f"--- Zone parameter with zone_code_names: {self.zone_code_names}") print(f"--- Grid with zone names: {self.grid.zone_names}") zone_names_from_grid = self.grid.zone_names for zone_index in zonation: self.grid_zone_dict[zone_index] = {} assert len(zone_names_from_grid) == len(zonation) # same index in zonation and in zone_names corresponds to the same zone for zone_index in zonation: zone_name = zone_names_from_grid[zone_index] self.grid_zone_dict[zone_index]["name_from_grid"] = zone_name layer_ranges = zonation[zone_index] assert ( len(layer_ranges) == 1 ) # No repeated layer numbering for simbox indexer layer_range = layer_ranges[0] start = layer_range[0] end = layer_range[-1] number_of_layers = end + 1 - start self.grid_zone_dict[zone_index]["nlayers"] = number_of_layers self.grid_zone_dict[zone_index]["start_layer"] = start self.grid_zone_dict[zone_index]["end_layer"] = end zone_number = self.get_zone_number(zone_name) self.grid_zone_dict[zone_index]["zone_number"] = zone_number self.grid_zone_index_dict[zone_number] = zone_index
[docs] def validate_zone_number_for_grid(self, zone_number: int) -> None: if zone_number not in self.grid_zone_index_dict: if zone_number in self.zone_code_names: raise ValueError( f"Zone name: {self.zone_code_names[zone_number]} " f"with zone code: {zone_number} in zone parameter " "does not exist in the grid." ) raise ValueError( f"Zone number: {zone_number} is not found in zone parameter." )
[docs] def get_number_of_zones_in_grid(self) -> int: return len(self.grid.simbox_indexer.zonation)
[docs] def get_zone_names_from_grid(self) -> list[str]: """ Zone names got from the grid object. """ return self.grid.zone_names
[docs] def get_zone_names_from_param(self) -> dict[int, str]: """ Zone names corresponding to the grid zones, but the names are got from the zone parameter. """ zone_name_dict = {} nzones = self.get_number_of_zones_in_grid() for zone_index in range(nzones): zone_number = self.get_zone_number_for_zone_index(zone_index) zone_name_dict[zone_number] = self.zone_code_names[zone_number] return zone_name_dict
[docs] def get_zone_numbers(self) -> list[int]: return list(self.zone_code_names.keys())
[docs] def get_zone_numbers_in_grid(self) -> list[int]: nzones = self.get_number_of_zones_in_grid() zone_numbers = [] for zone_index in range(nzones): zone_numbers.append(self.grid_zone_dict[zone_index]["zone_number"]) return zone_numbers
[docs] def get_zone_number(self, zone_name: str) -> int: # Unique zone name for each zone code for code, name in self.zone_code_names.items(): if zone_name == name: return code raise ValueError( f"Unknown zone name: {zone_name}. " f"Check that zone names in grid and zone parameter {self.zone_param_name} " "are consistent." )
[docs] def get_zone_name_for_zone_number(self, zone_number: int) -> str: return self.zone_code_names[zone_number]
[docs] def get_zone_name_for_zone_index( self, zone_index: int, zone_name_from_param: bool = True ) -> str: """ Return zone name in zone_code table in zone parameter or alternatively zone name from grid. """ if not zone_name_from_param: # Zone name from grid return self.grid.zone_names[zone_index] # zone name from param zone_number = self.get_zone_number_for_zone_index(zone_index) return self.zone_code_names[zone_number]
[docs] def get_zone_number_for_zone_index(self, zone_index: int) -> int: return self.grid_zone_dict[zone_index]["zone_number"]
[docs] def get_zone_index_for_zone_number(self, zone_number: int) -> int: self.validate_zone_number_for_grid(zone_number) return self.grid_zone_index_dict[zone_number]
[docs] def is_zone_number_defined(self, zone_number: int) -> bool: zone_numbers_in_grid = self.get_zone_numbers_in_grid() return zone_number in zone_numbers_in_grid
[docs] def number_of_layers_for_zone_number(self, zone_number: int) -> int: self.validate_zone_number_for_grid(zone_number) index = self.grid_zone_index_dict[zone_number] return self.grid_zone_dict[index]["nlayers"]
[docs] def number_of_layers_for_zone_index(self, zone_index: int): return self.grid_zone_dict[zone_index]["nlayers"]
[docs] def get_start_end_layer_for_zone_number(self, zone_number: int) -> tuple[int, int]: self.validate_zone_number_for_grid(zone_number) index = self.grid_zone_index_dict[zone_number] return self.grid_zone_dict[index]["start_layer"], self.grid_zone_dict[index][ "end_layer" ]
[docs] def get_start_end_layer_for_zone_index(self, zone_index: int) -> tuple[int, int]: return self.grid_zone_dict[zone_index]["start_layer"], self.grid_zone_dict[ zone_index ]["end_layer"]
[docs] def get_number_of_layers_per_zone(self) -> list[int]: nzones = self.get_number_of_zones_in_grid() number_of_layers_per_zone = [] for zone_index in range(nzones): number_of_layers_per_zone.append( self.number_of_layers_for_zone_index(zone_index) ) return number_of_layers_per_zone
[docs] def get_zone_parameter( grid_model: Any, name: str = "Zone", realization_number: int = 0, debug_level: int = DEBUG_OFF, ): """Description: Return zone parameter for given grid model. """ properties = grid_model.properties if name in properties: zone_parameter = properties[name] if debug_level >= DEBUG_VERY_VERBOSE: print(f"--- Found existing zone parameter with name {zone_parameter.name}") if zone_parameter.is_empty(realisation=realization_number): raise ValueError(f"Zone parameter: {zone_parameter.name} is empty.") else: raise ValueError(f"Zone parameter {name} does not exists.") return zone_parameter
[docs] def get_zone_mapping( project: Any, grid_model_name: str, debug_level: int = DEBUG_OFF ) -> ZoneMapping: grid_model = project.grid_models[grid_model_name] grid = grid_model.get_grid(project.current_realisation) return ZoneMapping( grid_model, grid, real_number=project.current_realisation, debug_level=debug_level, )