Block model manipulation
Block models can be manipulated without Vulcan being opened. The following examples illustrate how to do this.
Topics:
Modules to import
Import the following libraries:
import pandas as pd import numpy as np import matplotlib.pyplot as plt from maptek import vulcan
Open a block model
from maptek import vulcan bm = vulcan.block_model() bm.open('small.bmf')
Get a list of all variables
from maptek import vulcan bm = vulcan.block_model('small.bmf') bm.field_list()
Block model information
Extract some common information about the block model.
from maptek import vulcan bm = vulcan.block_model('small.bmf') nblocks = bm.n_blocks() extent = bm.model_extent() origin = bm.model_origin() orientation = bm.model_orientation() print("nblocks: {}".format(nblocks)) print("extents: {}".format(extent)) print("origin: {}".format(origin)) print("orientation: {}".format(orientation))
Get the value of a block
from maptek import vulcan bm = vulcan.block_model('small.bmf') grade = bm.get('au') print("First block au value: {:.3f}".format(grade))
Get all values using a loop
Loop through the block model and extract all values for a particular variable.
from maptek import vulcan def get_all_values(bm,variable): bm.rewind() # Go to start of block model data=[] # Empty list nblocks = bm.n_blocks() # Get number of blocks in model for block in bm: value = bm.get(variable) # Get value of block data.append(value) # Append to list bm.next() # Go to next block return data bm = vulcan.block_model('small.bmf') au_vals = get_all_values(bm, 'au') au_vals
All values as a numpy array
Read all values in a variable into a numpy array. Need to have enough physical memory to read in all the data.
from maptek import vulcan bm = vulcan.block_model('small.bmf') au = bm.get_data('au')
All values in a Pandas dataframe
Read all values in a variable into a pandas dataframe. Need to have enough physical memory to read in all the data.
from maptek import vulcan bm = vulcan.block_model('small.bmf') data = bm.get_pandas() data.head()
Calculate statistics on a dataframe
Calculate statistics of the Pandas dataframe using the method describe.
from maptek import vulcan bm = vulcan.block_model('small.bmf') data = bm.get_pandas() data.describe()
Close the block model
from maptek import vulcan bm = vulcan.block_model('small.bmf') bm.close()
Modify a block selection
from maptek import vulcan # open the block model bm = vulcan.block_model('small.bmf') # get all au and cu data inside the given solid i.e. a selection data = bm.get_pandas(['au','cu'], '-t tq1.00t') # change the values for the data inside the selection data.au = 100 data.cu = 50 # write the modified data back to the block model # the selection is maintained from the previous operation # so the values are written into the correct locationsa bm.put_pandas(data, ['au','cu']) # close the block model bm.close() # statistics on dataframe data.describe()
Sub-block model creation
An example of creating a sub-blocked model.
- The coordinates are in model coordinates not block.
- No blocks are created unless they are explicitly defined.
- The block model needs to be translated and rotated into the required world coordinates.
from maptek import vulcan bm = vulcan.block_model() xbegin = 0 ybegin = 0 zbegin = 0 xend = 50 yend = 50 zend = 50 x_num_pblock = 5 y_num_pblock = 5 z_num_pblock = 5 x_num_subblock=10 y_num_subblock=10 z_num_subblock=10 bm.create_irregular('subblock.bmf', xbegin, ybegin, zbegin, xend, yend, zend, x_num_pblock, y_num_pblock , z_num_pblock, x_num_subblock, y_num_subblock, z_num_subblock) # Add variables to block model bm.add_variable('au','integer','-99','gold') bm.add_variable('cu','float','-99','copper') bm.add_variable('lith','name','NA','lith') # Check number of blocks, there should be none print('Number of blocks: {0}'.format(bm.n_blocks())) # move the origin of the block model to 100,100,50 bm.translate(100,100,50) # actual rotation is bearing=23 but have to subtract standard vulcancan 90 degrees # mod 360 constrains the answer to 360 degrees bearing = (23 - 90)%360 dip = -5 plunge = -20 bm.rotate(dip, plunge, bearing) # block length = 50/5 = 10 xlen = 10 ylen = 10 zlen = 10 # blocks are added in model space NOT world space the block is defined # from the lower left of the 3d cube to the upper right of the 3d cube. for i in range(0, xend, xlen): for j in range(0, yend, ylen): for k in range(0, zend, zlen): # calculate the min/max block xmin = i ymin = j zmin = k xmax = i+xlen ymax = j+ylen zmax = k+zlen # add block to block model bm.add_block(xmin,ymin,zmin,xmax,ymax,zmax) # Check number of blocks after adding them all print('Number of blocks: {0}'.format(bm.n_blocks())) bm.close()
Reset a variable to default
from maptek import vulcan ''' This script will reset a block model to the variable default using the NumPy interface. The var_data variable is a NumPy array with the values of all the blocks in the block model. The .fill function populates all values of that array with the variable default. The data is then placed back in the model after being updated with the new values. ''' with vulcan.block_model('small.bmf', 'w') as bm: var_default = bm.field_default('au') var_data = bm['au'] var_data.fill(var_default) bm['au'] = var_data print('Default value for au : {}'.format(var_default))
Block model calculation using NumPy
from maptek import vulcan ''' The code below is an example of using NumPy to calculate the entire models values within a single set of statements. NumPy uses large arrays of data to make the calculations faster (~4x). Code with # ** after it means it is syntax for the NumPy package in Python ''' au_price = 1320 cu_price = 3.02 with vulcan.block_model('small.bmf', "w") as bm: # Reset the calculated variable au_eq = bm["au_eq"] au_eq.fill(0) # ** # Get the data to work with au = bm["au"] cu = bm["cu"] # Set anything with values less than zero to zero (-99 or -9) au[au < 0] = 0 # ** cu[cu < 0] = 0 # ** # Calculate the new values au_oz = au * (1/31.1035) cu_lb = cu * 2240 # Calculate the new equivalent au_eq = (au_oz * au_price + cu_lb * cu_price) / au_price # Update the values bm["au_eq"] = au_eq print('Average au : {:.3f}'.format(au.mean())) print('Average cu : {:.3f}'.format(cu.mean())) print('Average au_eq : {:.3f}'.format(au_eq.mean()))
Block model calculation
from maptek import vulcan ''' The code below does calculation one block at a time and can be slower but is generally simpler to use. ''' au_price = 1320 cu_price = 3.02 with vulcan.block_model('small.bmf', "w") as bm: for block in bm: # Get the data to work with au = block["au"] cu = block["cu"] # Set anything with values less than zero to zero (-99 or -9) if au < 0: au = 0 if cu < 0: cu = 0 # Calculate the new values au_oz = au * (1/31.1035) cu_lb = cu * 2240 # Calculate the new equivalent au_eq = (au_oz * au_price + cu_lb * cu_price) / au_price # Update the values block["au_eq"] = au_eq au_eq = bm["au_eq"] print('Average au_eq : {:.3f}'.format(au_eq.mean()))
Looping through a model on a single block basis
from maptek import vulcan with vulcan.block_model('small.bmf') as bm: au_sum = 0.0 for block in bm: if(block['au'] > 0): au_sum += block['au'] ave_au = au_sum / bm.n_blocks() print('Average au : {:.3f}'.format(ave_au))