Core API¶
This page describes the core functions in MiningPy
ijk¶
- miningpy.core.ijk(blockmodel: DataFrame, method: str = 'ijk', indexing: int = 0, xyz_cols: Optional[Tuple[str, str, str]] = None, origin: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, dims: Optional[Tuple[Union[int, float, str], Union[int, float, str], Union[int, float, str]]] = None, rotation: Tuple[Union[int, float], Union[int, float], Union[int, float]] = (0, 0, 0), ijk_cols: Tuple[str, str, str] = ('i', 'j', 'k'), print_warnings: bool = True, inplace: bool = False) DataFrame ¶
Calculate block ijk indexes from their xyz cartesian coordinates
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- method: str, default ‘ijk’
can be used to only calculate i, or j, or k
- indexing: int, default 0
controls whether origin block has coordinates 0,0,0 or 1,1,1
- xyz_cols: tuple of strings
names of x,y,z columns in model
- origin: tuple of floats or ints
x,y,z origin of model - this is the corner of the bottom block (not the centroid)
- dims: tuple of floats, ints or str
x,y,z dimension of regular parent blocks can either be a number or the columns names of the x,y,z columns in the dataframe
- rotation: tuple of floats or ints, default (0,0,0)
rotation of block model grid around x,y,z axis, -180 to 180 degrees
- ijk_cols: tuple of strings, default (‘i’, ‘j’, ‘k’)
name of the i,j,k columns added to the model
- print_warnings: bool, default True
if True then will check if blocks are on a regular grid before the IJK calculation and print a warning to the user if the blocks are not regular (i.e. could get funky IJK values).
- inplace: bool, default False
whether to do calculation inplace on pandas.DataFrame
- Returns
- pandas.DataFrame
indexed block model
Examples
>>> import pandas as pd >>> import miningpy ... >>> # block model data and framework >>> data = {'x': [5, 5, 15], ... 'y': [5, 15, 25], ... 'z': [5, 5, 5]} >>> xdim, ydim, zdim = 5, 5, 5 # regular block dimensions >>> xorg, yorg, zorg = 2.5, 2.5, 2.5 # model origin (corner of first block) ... >>> # Create block model from data >>> blockmodel = pd.DataFrame(data) >>> print(blockmodel) x y z 0 5 5 5 1 5 15 5 2 15 25 5 >>> # calculate i, j, k indexes >>> blockmodel.ijk(indexing=1, # use ijk function just like any other Pandas function ... xyz_cols=('x', 'y', 'z'), # input the x, y, z column names as a tuple ... origin=(xorg, yorg, zorg), ... dims=(xdim, ydim, zdim), ... inplace=True) # can do inplace True/False like other standard Pandas functions >>> # print results of ijk calculation >>> print(blockmodel) x y z i j k 0 5 5 5 1 1 1 1 5 15 5 1 3 1 2 15 25 5 3 5 1
xyz¶
- miningpy.core.xyz(blockmodel: DataFrame, method: str = 'xyz', indexing: int = 0, ijk_cols: Tuple[str, str, str] = ('i', 'j', 'k'), origin: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, dims: Optional[Tuple[Union[int, float, str], Union[int, float, str], Union[int, float, str]]] = None, rotation: Tuple[Union[int, float], Union[int, float], Union[int, float]] = (0, 0, 0), xyz_cols: Tuple[str, str, str] = ('x', 'y', 'z'), inplace: bool = False) DataFrame ¶
Calculate xyz cartesian cooridinates of blocks from their ijk indexes
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- method: str, default ‘xyz’
can be used to only calculate i, or j, or k
- indexing: int, default 0
controls whether origin block has coordinates 0,0,0 or 1,1,1
- ijk_cols: tuple of strings, default (‘i’, ‘j’, ‘k’)
name of the i,j,k columns added to the model
- origin: tuple of floats or ints
x,y,z origin of model - this is the corner of the bottom block (not the centroid)
- dims: tuple of floats, ints or str
x,y,z dimension of regular parent blocks can either be a number or the columns names of the x,y,z columns in the dataframe
- rotation: tuple of floats or ints, default (0,0,0)
rotation of block model grid around x,y,z axis, -180 to 180 degrees
- xyz_cols: tuple of strings, default (‘x’, ‘y’, ‘z’)
names of x,y,z columns in model
- inplace: bool, default False
whether to do calculation inplace on pandas.DataFrame
- Returns
- pandas.DataFrame
indexed block model
rotate_grid¶
- miningpy.core.rotate_grid(blockmodel: DataFrame, xyz_cols: Tuple[str, str, str] = ('x', 'y', 'z'), origin: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, rotation: Tuple[Union[int, float], Union[int, float], Union[int, float]] = (0, 0, 0), return_full_model: bool = True, derotate: bool = False, inplace: bool = False) Union[DataFrame, dict] ¶
Rotate block model relative to cartesian grid This method uses a rotation matrix method Rotation is done using the right hand rule
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- xyz_cols: tuple of strings, default (‘x’, ‘y’, ‘z’)
names of x,y,z columns in model
- origin: tuple of floats or ints
x,y,z origin of model - this is the corner of the bottom block (not the centroid)
- rotation: tuple of floats or ints, default (0,0,0)
rotation of block model grid around x,y,z axis, -180 to 180 degrees
- return_full_model: bool, default True
whether to return the full block model or just a dict of the rotated x,y,z coordinates
- derotate: bool
whether to rotate a model or derotate it back to it’s normal orthogonal coordinate system this parameter exists because using the reverse angles in more than one dimension will not derotate a model
- inplace: bool, default False
whether to do calculation inplace on pandas.DataFrame
- Returns
- pandas.DataFrame
rotated block model or dict of rotated x,y,z coordinates
group_weighted_average¶
- miningpy.core.group_weighted_average(blockmodel: DataFrame, avg_cols: Union[str, List[str]], weight_col: str, group_cols: Optional[Union[str, List[str]]] = None) DataFrame ¶
weighted average of block model attribute(s)
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- avg_cols: str or list of str
column(s) to take the weighted average
- weight_col: str
column to weight on. Example the tonnes column
- group_cols: str or list of str
the columns you want to group on. Either single column or list of columns
- Returns
- pandas.DataFrame
block model
nblocks_xyz¶
- miningpy.core.nblocks_xyz(blockmodel: DataFrame, xyz_cols: Optional[Tuple[str, str, str]] = None, dims: Optional[Tuple[Union[int, float, str], Union[int, float, str], Union[int, float, str]]] = None, origin: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, rotation: Tuple[Union[int, float], Union[int, float], Union[int, float]] = (0, 0, 0)) Tuple[Union[int, float], Union[int, float], Union[int, float]] ¶
Number of blocks along the x,y,z axis. If the model is rotated, it is unrotated and then the number of blocks in the x,y,z axis is calculated.
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- xyz_cols: tuple of strings
names of x,y,z columns in model
- dims: tuple of floats, ints or str
x,y,z dimension of regular parent blocks can either be a number or the columns names of the x,y,z columns in the dataframe
- origin: tuple of floats or ints
x,y,z origin of model - this is the corner of the bottom block (not the centroid)
- rotation: tuple of floats or ints, default (0,0,0)
rotation of block model grid around x,y,z axis, -180 to 180 degrees
- Returns
- tuple of floats
Number of blocks along the x,y,z axis.
model_origin¶
- miningpy.core.model_origin(blockmodel: DataFrame, xyz_cols: Optional[Tuple[str, str, str]] = None, dims: Optional[Tuple[Union[int, float, str], Union[int, float, str], Union[int, float, str]]] = None) Tuple[float, float, float] ¶
calculate the origin of a block model grid relative to its current xyz grid origin is the corner of the block with min xyz coordinates
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- xyz_cols: tuple of strings
names of x,y,z columns in model
- dims: tuple of floats, ints or str
x,y,z dimension of regular parent blocks can either be a number or the columns names of the x,y,z columns in the dataframe
- Returns
- tuple of floats
origin of a block model for each axis (x,y,z)
block_dims¶
- miningpy.core.block_dims(blockmodel: DataFrame, xyz_cols: Optional[Tuple[str, str, str]] = None, origin: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, rotation: Tuple[Union[int, float], Union[int, float], Union[int, float]] = (0, 0, 0)) Tuple[float, float, float] ¶
estimate the x, y, z dimensions of blocks if the blocks are rotated then they are unrotated first then the x, y, z dimensions are estimated
note that this function just estimates the dimensions of the blocks it may not always get the perfectly correct answer if there are alot of blocks missing in the grid (i.e. a sparse array of blocks) the estimation is less likely to be correct
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- xyz_cols: tuple of strings
names of x,y,z columns in model
- origin: tuple of floats or ints
x,y,z origin of model - this is the corner of the bottom block (not the centroid)
- rotation: tuple of floats or ints, default (0,0,0)
rotation of block model grid around x,y,z axis, -180 to 180 degrees
- Returns
- tuple of floats (xdim, ydim, zdim)
check_regular¶
- miningpy.core.check_regular(blockmodel: DataFrame, xyz_cols: Optional[Tuple[str, str, str]] = None, origin: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, dims: Optional[Tuple[Union[int, float, str], Union[int, float, str], Union[int, float, str]]] = None, rotation: Tuple[Union[int, float], Union[int, float], Union[int, float]] = (0, 0, 0), tolerance: Union[int, float] = 1e-05) bool ¶
check if the blocks in a block model are actually on a regular grid (including a rotated grid). note this is just an estimation of regularity, it is not perfect
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- xyz_cols: tuple of strings
names of x,y,z columns in model
- origin: tuple of floats or ints
x,y,z origin of model - this is the corner of the bottom block (not the centroid)
- dims: tuple of floats, ints or str
x,y,z dimension of regular parent blocks can either be a number or the columns names of the x,y,z columns in the dataframe
- rotation: tuple of floats or ints, default (0,0,0)
rotation of block model grid around x,y,z axis, -180 to 180 degrees
- tolerance: float or int, default 0.00001
the difference of a blocks centroid from the point on a grid it should be located generally in the range of 0.1 to 0.000001
- Returns
- bool
whether block model is regular or not. True if regular.
check_internal_blocks_missing¶
- miningpy.core.check_internal_blocks_missing(blockmodel: DataFrame, xyz_cols: Optional[Tuple[str, str, str]] = None, dims: Optional[Tuple[Union[int, float, str], Union[int, float, str], Union[int, float, str]]] = None, rotation: Tuple[Union[int, float], Union[int, float], Union[int, float]] = (0, 0, 0), origin: Tuple[Union[int, float], Union[int, float], Union[int, float]] = (0, 0, 0)) bool ¶
check if there are missing internal blocks (not side blocks) within a regular block model
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- xyz_cols: tuple of strings
names of x,y,z columns in model
- dims: tuple of floats, ints or str
x,y,z dimension of regular parent blocks can either be a number or the columns names of the x,y,z columns in the dataframe
- rotation: tuple of floats or ints, default (0,0,0)
rotation of block model grid around x,y,z axis, -180 to 180 degrees
- origin: tuple of floats or ints, default (0,0,0)
ONLY NEEDED IF MODEL IS ROTATED x,y,z origin of model - this is the corner of the bottom block (not the centroid)
- Returns
- bool
whether block model contains missing internal blocks returns True if so
vulcan_csv¶
- miningpy.core.vulcan_csv(blockmodel: DataFrame, path: Optional[str] = None, var_path: Optional[str] = None, xyz_cols: Optional[Tuple[str, str, str]] = None, dims: Optional[Tuple[Union[int, float, str], Union[int, float, str], Union[int, float, str]]] = None, inplace: bool = False) DataFrame ¶
transform pandas.Dataframe block model into Vulcan import compatible CSV format.
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- path: str
filename for vulcan csv block model file
- var_path: {optional} str
filename for csv that lists the Vulcan dtype of each column in block model (used if manually creating bdf)
- xyz_cols: tuple of strings
names of x,y,z columns in model
- dims: tuple of floats, ints or str
x,y,z dimension of regular parent blocks can either be a number or the columns names of the x,y,z columns in the dataframe
- inplace: bool, default False
whether to do calculation inplace (i.e. add Vulcan headers inplace) or return pandas.DataFrame with Vulcan headers
- Returns
- pandas.DataFrame
block model in Vulcan import CSV format
vulcan_bdf¶
- miningpy.core.vulcan_bdf(blockmodel: DataFrame, path: Optional[str] = None, origin: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, dims: Optional[Tuple[Union[int, float, str], Union[int, float, str], Union[int, float, str]]] = None, start_offset: Tuple[Union[int, float], Union[int, float], Union[int, float]] = (0.0, 0.0, 0.0), end_offset: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, format: str = 'T') bool ¶
Create a Vulcan block definition file from a vulcan block model. This script creates a BDF from a vulcan block model csv that can be imported into Vulcan. It assumes that bearing, dip and plunge are the default. values for the block model. Variables are given a default value of -99.0, a blank description and type ‘double’. This script will define the parent schema. All of these values can be edited within Vulcan once the script has been run and bdf imported.
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model in Vulcan CSV import compatible format (use funtion: “vulcan_csv”)
- path: str
filename for vulcan bdf file
- origin: tuple of floats or ints
x,y,z origin of model - this is the corner of the bottom block (not the centroid)
- dims: tuple of floats, ints or str
x,y,z dimension of regular parent blocks can either be a number or the columns names of the x,y,z columns in the dataframe
- start_offset: tuple of floats or ints, default (0.0, 0.0, 0.0)
minimum offset along the x,y,z axes
- end_offset: tuple of floats or ints
maximum offset along the x,y,z axes
- format: {‘C’, ‘T’}, default ‘T’
block model file format (classic = C, extended = T)
- Returns
- True if Vulcan .bdf file is exported with no errors
geometric_reblock¶
- miningpy.core.geometric_reblock(blockmodel: DataFrame, xyz_cols: Optional[Tuple[str, str, str]] = None, origin: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, dims: Optional[Tuple[Union[int, float, str], Union[int, float, str], Union[int, float, str]]] = None, reblock_multiplier: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, varlist_agg: Optional[dict] = None, min_cols: Optional[list] = None, max_cols: Optional[list] = None)¶
Reblock a regular block model into larger or smaller blocks (aggregate or split blocks). Aggregating multiple small blocks into big blocks will be referred to as “superblocking” and splitting big blocks into smaller children will be referred to as “subblocking”. This tool can be used as a tool for geometrically aggregating blocks in bench-phases.
This function utilises a
reblock_multiplier
in (x, y, z) dimensions to define the reblock. The function will either superblock or subblock but not both in the same call. The reblock_multiplier must be a multiple of the parent dimension. To superblock in one dimension and subblock in another, subblock to the smallest dimensions required and then superblock to the required size.Weighting of blocks, is handled by argument
varlist_agg
. This dictionary must have the block model attribute to weight by as the key and the attributes to be weighted as a list in the key.- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- xyz_cols: tuple of strings
names of x,y,z columns in model
- dims: tuple of floats, ints or str
x,y,z dimension of regular parent blocks
- origin: tuple of floats or ints
x,y,z origin of model - this is the corner of the bottom block (not the centroid)
- reblock_multiplier: tuple of floats or ints
the scalar to change dimensions of blocks. E.g., (2, 2, 1) will double the blocks in the x and y dimension and keep the z dimension the same.
- varlist_agg: dictionary
used to weight attributes. Key is the attribute to weight by, value is a list of attributes to weight. All attributes that are required to be carried through the reblock must be a key in the dictionary even if they are not weighting anything. Keys with empty lists will be divided or summed accordingly E.g., to carry through ore tonnes, volume and energy with ore grades, varlist_agg = {‘ore_tonnes’: [‘au_grade’, ‘cu_grade’], ‘volume’:[‘density’], ‘energy’:[]}
- min_cols: {optional} list of model attributes
attributes that require the min value e.g., pit_number
- max_cols: {optional} list of model attributes
attributes that require the max value e.g., resource category
- Returns
- pandas.DataFrame
reblocked block model
Examples
>>> import pandas as pd >>> import miningpy
>>> # block model example (zuck small - MineLib) >>> url = "https://drive.google.com/uc?export=download&id=1SOrYhqiu5Tg8Zjb7be4fUWhbFDTU1sEk"
>>> # read in block model from link >>> data = pd.read_csv(url, compression='zip')
>>> # listing attributes to carry through (n.b. dropping ID column) >>> # keys are what to weight by and values are lists of attributes to be weighted >>> varlist_agg = { >>> 'rock_tonnes': ['cost', 'value'], >>> 'ore_tonnes': [], >>> }
>>> # take the max or min value of reblock >>> min_cols = ['final_pit'] >>> max_cols = ['period']
>>> # reblock function >>> reblock = data.geometric_reblock( >>> dims=(1, 1, 1), # original dims of model >>> xyz_cols=('x', 'y', 'z'), >>> origin=(-0.5, -0.5, -0.5), # bottom left corner >>> reblock_multiplier=(2, 2, 1), # doubling x and y dim and keeping z dim the same >>> varlist_agg=varlist_agg, >>> min_cols=min_cols, >>> max_cols=max_cols, >>> )
>>> reblock.plot3D(dims=(2, 2, 1), xyz_cols=('x', 'y', 'z'), col='value', widget='section') # reblocked plot >>> data.plot3D(dims=(1, 1, 1), xyz_cols=('x', 'y', 'z'), col='value', widget='section') # original plot
index_3Dto1D¶
- miningpy.core.index_3Dto1D(blockmodel: DataFrame, indexing: int = 0, xyz_cols: Optional[Tuple[str, str, str]] = None, origin: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, dims: Optional[Tuple[Union[int, float, str], Union[int, float, str], Union[int, float, str]]] = None, rotation: Tuple[Union[int, float], Union[int, float], Union[int, float]] = (0, 0, 0), nblocks_xyz: Optional[Tuple[int, int, int]] = None, idxcol: str = 'ijk', inplace: bool = False) DataFrame ¶
Convert 3D array of xyz block centroids to 1D index that is reversible. Opposite of the function index_1Dto3D()
This is identical to the “ijk” parameter in Datamine block models. Note that “ijk” value from this function and from Datamine may be different, depending on which axis Datamine uses as the major indexing axis. Bot “ijk” indexing values are still valid.
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- indexing: int, default 0
controls whether origin block has coordinates 0,0,0 or 1,1,1
- xyz_cols: tuple of strings
names of x,y,z columns in model
- origin: tuple of floats or ints
x,y,z origin of model - this is the corner of the bottom block (not the centroid)
- dims: tuple of floats, ints or str
x,y,z dimension of regular parent blocks can either be a number or the columns names of the x,y,z columns in the dataframe
- rotation: tuple of floats or ints, default (0,0,0)
rotation of block model grid around x,y,z axis, -180 to 180 degrees
- nblocks_xyz: tuple of ints or None
number of blocks along the x,y,z axis. If the model is rotated, it is unrotated and then the number of blocks in the x,y,z axis is calculated. If “None” (default value) then the nx,ny,nz is automatically estimated
- idxcol: str, default ‘ijk’
name of the 1D index column added to the model
- inplace: bool
whether to do calculation inplace on pandas.DataFrame
- Returns
- pandas.DataFrame
block model with 1D indexed column
index_1Dto3D¶
- miningpy.core.index_1Dto3D(blockmodel: DataFrame, indexing: int = 0, idxcol: str = 'ijk', origin: Optional[Tuple[Union[int, float], Union[int, float], Union[int, float]]] = None, dims: Optional[Tuple[Union[int, float, str], Union[int, float, str], Union[int, float, str]]] = None, rotation: Tuple[Union[int, float], Union[int, float], Union[int, float]] = (0, 0, 0), nblocks_xyz: Optional[Tuple[int, int, int]] = None, xyz_cols: Tuple[str, str, str] = ('x', 'y', 'z'), inplace: bool = False) DataFrame ¶
Convert IJK index back to xyz block centroids. Opposite of the function index_3Dto1D()
This is identical to the “ijk” parameter in Datamine block models. Note that “ijk” value from this function and from Datamine may be different, depending on which axis Datamine uses as the major indexing axis. Bot “ijk” indexing values are still valid.
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- indexing: int, default 0
controls whether origin block has coordinates 0,0,0 or 1,1,1
- idxcol: str, default ‘ijk’
name of the 1D index column added to the model
- origin: tuple of floats or ints
x,y,z origin of model - this is the corner of the bottom block (not the centroid)
- dims: tuple of floats, ints or str
x,y,z dimension of regular parent blocks can either be a number or the columns names of the x,y,z columns in the dataframe
- rotation: tuple of floats or ints, default (0,0,0)
rotation of block model grid around x,y,z axis, -180 to 180 degrees
- nblocks_xyz: tuple of ints or None
number of blocks along the x,y,z axis. If the model is rotated, it is unrotated and then the number of blocks in the x,y,z axis is calculated.
- xyz_cols: tuple of strings, default (‘x’, ‘y’, ‘z’)
names of x,y,z columns in model
- inplace: bool
whether to do calculation inplace on pandas.DataFrame
- Returns
- pandas.DataFrame
block model with 1D indexed column
grade_tonnage_plot¶
- miningpy.core.grade_tonnage_plot(blockmodel: DataFrame, grade_col: str, ton_col: str, cog_grades: Optional[List] = None, cog_grade_points: Optional[int] = None, plot_path: Optional[str] = None, show_plot: bool = False)¶
Create and return grade-tonnage table and optional export plot as a .png and save image. Grade-Tonnage curves are a visual representation of the impact of cut-off grades on mineral reserves. Grades to plot can be specified, else grades to plot will be generated based on the range of grades in the model.
- Parameters
- blockmodel: pd.DataFrame
pandas dataframe of block model
- grade_col: str
name of grade to plot, typically ‘ore’ grade
- ton_col: str
name of tonnage column in the model
- cog_grades: {optional} ints, floats
list of cut off grades to plot
- cog_grade_points: {optional} int, default 10
number of cut off grades to plot between min and max grade
- plot_path: {optional} str
path to save plot .png
- show_plot: {optional} bool
if running in interactive console, show plot, default False
- Returns
- pandas.DataFrame
dataframe of grade-tonnage
- matplotlib.pyplot
Grade-Tonnage plot