=============================== ``grail.data.model_rex`` module =============================== .. include:: ..\..\version.h .. contents:: Table of Contents :backlinks: top --------- Overview --------- Pyrex is python with C data types. It allows you to mix code that uses python values and C values. This helps in reducing block model access times since it allows direct referencing of the model access library (written in C). The biggest bottleneck in grail.data.model is the translation of data from python to C and back again. This document outlines the C functions that are available for accessing a block model, and provides some examples. .. Note:: Pyrex requires Python version 2.5 or higher. ------------------ Choice of Compiler ------------------ The choice of compiler you will use will be a function of the platform you are building against (32 bit vs. 64 bit), and the python version you are working with. The table below highlights the recommendations, ====== ======== ==================== Python Platform Recommended Compiler ====== ======== ==================== 2.5 32 BIT MinGW32 GCC 2.5 64 BIT n/a - not available in MPYTHON. 2.7 32 BIT n/a - not available in MPYTHON. 2.7 64 BIT Visual Studio 2008 Express ====== ======== ==================== For 32 Bit Python 2.5, you can either use the free MinGW32 GCC or pay for an old version of Visual Studio 2003. Since there is good 32 bit support for GCC, and since GCC is free, we often recommened this compiler when working with Python 2.5 and 32 bit code. For 64 Bit Python 2.7, you have a choice of 64 Bit GCC or a Visual Studio 2008 Express. With the Express edition, you now have access to a Microsoft Visual Studio compiler that is free. With 64 Bit GCC we have found that that state of the compiler on Microsoft platforms is in a state of flux at the moment. Since Visual Studio 2008 Express is free, and since it is operational, and since GCC 64 bit support is limited, we recommend using Visual Studio 2008. --------- Functions --------- :df:`MODEL* ciMODELDefine(char* pcfpath, char* modelname)` Loads a model structure. Specify the path (relative or absolute) to the pcf and the name (not path) of the model file. :df:`void ciMODELFree(MODEL* model)` Releases the model contents from the system's memory. :df:`int ciMODELLoadSlab(MODEL* model, int l0, int ln, int r0, int rn, int c0, int cn, int nitem, int* items)` Loads a slab (a contiguous set of blocks comprising a subset of the model). You must specify the number of model items to load and provide an array of model item indices to load. .. Warning:: Block model indices are offset from zero. This is in contrast to grail.data.model in which the indices begin at 1. :df:`int ciMODELGetSlabSize(MODEL* model)` Returns the number of cells in the Slab. :df:`int ciMODELGetSlabItemIndexByItemName_Raw(MODEL* model, char *itemName)` Returns the slab index for the given item name. Returns -1 if no slab index is found for the given itemName. .. Warning:: ciMODELGetSlabItemIndexByItemName_Raw is an "expensive” function and should not be called repeatedly within the processing loop. The function assumes the parameters are not NULL, and that a slab has been loaded from the model. :df:`float ciMODELGetSlabValueAt(MODEL* model, int lev, int row, int col, int idx)` Returns the value of the item for the given cell. The item index is relative to the Slab item indices (only the items that were loaded when the Slab was loaded) not the model item indices. :df:`int ciMODELGetSlabValueAtAsInt(MODEL* model, int lev, int row, int col, int idx)` Returns the integer value of the item for the given cell. The item index is relative to the Slab item indices (only the items that were loaded when the Slab was loaded) not the model item indices. :df:`int ciMODELSetSlabValueAt(MODEL* model, int lev, int row, int col, int idx, float value)` Sets the value for an item. The item index is relative to the Slab item indices (only the items that were loaded when the Slab was loaded) not the model item indices. Any values set on the Slab object will not be committed to the model file until you "store" the Slab. :df:`int ciMODELStoreSlab(MODEL* model)` Commits the contents of the defined slab to file. :df:`void ciMODELFreeSlab(MODEL* model)` Releases the slab contents from the system's memory. :df:`char* ciGetError()` Used to access an error message in the event that an error has occurred. .. Note:: Most functions return either a flag or some kind of pointer. By testing the return value of a function you can determine if an error has occurred. An error message can be accessed using the `ciGetError()` function. ----------- Example pyx ----------- .. Python:: cimport model_rex from grail.data import pcf import os def run(FILE_10, FILE_15, minlvl, maxlvl, minrow, maxrow, mincol, maxcol): #ensure that file15 is a basename (as opposed to an absolute path) FILE_15 = os.path.basename(FILE_15) cdef model_rex.MODEL* model model = model_rex.ciMODELDefine(FILE_10, FILE_15) if not model: print "\nError loading model: %s" % model_rex.ciGetError() return 0 #convert 1-based indices to 0-based indices. cdef int cminlvl, cmaxlvl, cminrow, cmaxrow, cmincol, cmaxcol cminlvl = minlvl-1 cmaxlvl = maxlvl-1 cminrow = minrow-1 cmaxrow = maxrow-1 cmincol = mincol-1 cmaxcol = maxcol-1 #Create an array to hold model item indices cdef int numitems, itemidx[3] #get a list of model items from the PCF and fill array p = pcf.Pcf(FILE_10) allitems = p.itemlist(FILE_15) itemidx[0] = allitems.index('TCU') itemidx[1] = allitems.index('AU') itemidx[2] = allitems.index('EQCU') numitems = 3 cdef int row, col, lvl cdef float tcu, au, eqcu for cminlvl <= lvl <= cmaxlvl: model_rex.ciMODELLoadSlab(model, lvl, lvl, cminrow, cmaxrow, cmincol, cmaxcol, numitems, itemidx) #get slab item indices by name tcu_idx = model_rex.ciMODELGetSlabItemIndexByItemName_Raw(model, "TCU") au_idx = model_rex.ciMODELGetSlabItemIndexByItemName_Raw(model, "AU") eqcu_idx = model_rex.ciMODELGetSlabItemIndexByItemName_Raw(model, "EQCU") for cminrow <= row <= cmaxrow: for cmincol <= col <= cmaxcol: #get values tcu = model_rex.ciMODELGetSlabValueAt(model, lvl, row, col, tcu_idx) au = model_rex.ciMODELGetSlabValueAt(model, lvl, row, col, au_idx) #perform calculation eqcu = tcu + au/1.44 #set value model_rex.ciMODELSetSlabValueAt(model, lvl, row, col, eqcu_idx, eqcu) model_rex.ciMODELStoreSlab(model) model_rex.ciMODELFreeSlab(model) model_rex.ciMODELFree(model) return 1 ------------------ Build Instructions ------------------ 1. **For 32 Bit, Python 2.5**: install MinGW32 GCC compiler suite (ensure 'gcc.exe' is on %PATH%). **For 64 bit, Python 2.7**: Install Visual Studio 2008 Express (ensure that 'cl.exe' is on the %PATH%). Typically done by using an installed short cut "Visual Studio 2008 x64 Win64 Command Prompt". 2. Write Pyrex function (save as 'model_rex.pyx'). Refer to "model_rex_boilerplate.pyx" in the script samples as a guide. 3. Compile to pyd using "build_model_rex.cmd" (found in %MEDEXE% folder). Pass the full filepath to your model_rex.pyx file as a command-line argument. 4. In main python script, import :d:`grail.data.pyrex_config` before importing your new model_rex extension.