========================== ``grail.ip.reslib`` module ========================== .. include:: ../../version.h .. contents:: Table of Contents :backlinks: top -------- Overview -------- This library provides a set of functions for making working with the reserves dictionary easier (see grail.ip.reserves_). Throughout this module there is a reference to the `Reserves Dictionary`. The dictionary is returned when working with the grail.ip.reserves_ module. Specifically it is the dictionary returned by the following two function calls, .. _grail.ip.reserves: lib-grail-ip-reserves.html .. Python:: hres = reserves.hGetCurResRef() dres = reserves.dGetRes(hres) When working with the Reserves Dictionary, in your typical IP script you should also make a call to :f:`ordergrades` as in, .. Python:: hres = reserves.hGetCurResRef() dres = reserves.dGetRes(hres) reslib.ordergrades(dres) that ensures the control grade is set and the grade lists between different cuts and areas match in their respective binning within the Reserves Dictionary. -------------------------- Using reslib Get Functions -------------------------- Some of the :f:`get` functions within reslib return reference to the contents of the Reserves Dictionary. What does this mean? This means that if you modify a reference to a Dictionary or List retrieved by a :f:`get` function, you are in fact modifying the Reserves Dictionary directly. However, if your :f:`get` function only returns a string, real, or integer value, then do not need to worry about references. Sometimes modifying the Reserves Dictionary directly is useful and efficient; however, sometimes it will lead to unintentional side-effects. An example of an unintentional side-effect is the illustrated below, .. Python:: hres = reserves.hGetCurResRef() dRes = reserves.dGetRes(hRes) Unordered_Grade_List = reslib.getgradelist(dRes) print Unordered_Grade_List # (1) reslib.ordergrades(dRes) print Unordered_Grade_List # (2) When you request the unordered grade list via :f:`getgradelist`, you get a *reference* to the grade list within the Reserves Dictionary. When your print the grade list at **(1)** you will see an unordered grade list. After you order the Reserves Dictionary grade list with :f:`ordergrades`, you will have an ordered grade list. The new ordered grade list in the Reserves Dictionary is the same grade list as the one you referenced with :f:`getgradelist`. This means that your :d:`Unordered_Grade_List` in **(2)** will now be ordered. If your intention was to get a copy and not a reference to the grade list, then you should use Python's ``copy`` module [#python-lib-copy]_. The above code snippet could be re-written as, .. Python:: import copy # ... later ... hres = reserves.hGetCurResRef() dRes = reserves.dGetRes(hRes) Unordered_Grade_List = copy.copy(reslib.getgradelist(dRes)) print Unordered_Grade_List # (1) reslib.ordergrades(dRes) print Unordered_Grade_List # (2) Now your :d:`Unordered_Grade_List` at step **(2)** will be the same as the copy of the grade list you got with your call to :f:`getgradelist`. This is because the :d:`Unordered_Grade_List` is not a reference to the Reserves Dictionary internal grade list, but a new list onto itself. In practice, if you intend to quickly read data from the Reserves Dictionary, you do not need to worry about the reference mechanics. If you intend to read and do work with the results, then you need to worry about references with Python's List and Dictionary objects returned by the reslib :f:`get` functions. If you intend to read/write to the reserves dictionary, then you will need to continue to operate with the same reference to a Python List or Dictionary object. If your :f:`get` function returns an string, real or integer, then you do not need to worry about references. --------- Functions --------- The functions defined in reslib can be broken down into the following broad categories, * `General Functions`_ Functions that are useful for all purpose reserves work with the Reserves Dictionary. * `Attribute Functions`_ Functions that work with the attributes defined within the Reserves Dictionary. * `Area Functions`_ Functions used to work with the Areas within a Reserves Dictionary. * `Bin (Cutoff) Functions`_ Functions used to work with the cutoff bins within the Reserves Dictionary. When you divide a grade into a set of cutoff, the range between cutoffs is considered a bin. * `Calculation Functions`_ Simple functions that perform simple calculations based on the contents of the Reserves Dictionary. * `Cut Functions`_ Functions dedicated to working with the cuts within the Reserves Dictionary. * `Grade Functions`_ Functions dedicated to working with the grades within the Reserves Dictionary. * `Material Functions`_ Functions dedicated to working with the materials within the Reserves Dictionary. * `Material Set Functions`_ Functions that work with material sets within the Reserves Dictionary. * `ODBC Functions`_ Functions relating to the Open Database Connectivity interface with MineSightŪ Interactive Planner. * `Path Functions`_ Functions relating to pathing information with the active Interactive Planner object. General Functions ----------------- Functions that are useful for all purpose reserves work with the Reserves Dictionary. :df:`get_cuts_except_current(dRes)` *New in version 4.70* Scans through :d:`dRes` and returns a list of cut dictionaries for all the cuts, except the current cut. :df:`get_current_cut_idx(dRes)`: *New in version 4.70* Returns the current cut within the :d:`dRes`. If there is no current cut it will return -1. :df:`is_current_cut(dRes)`: *New in version 4.70* Returns :d:`True` if there is a current cut. This is the same as checking that :f:`get_current_cut_idx` does not return -1. :df:`getcontrolgrade(dRes[, areaidx])` Returns the controlling grade, if an area index is not specified it is assumed that there is only one area. .. Note:: The results of this function call are *undefined* if :f:`reslib.ordergrades` has not be called prior to calling this function. :df:`getreslibversion()` Returns the version for the reslib module. :df:`getunitsflag(dRes)` Returns 0 if the metric, 1 if imperial. The value is based on the value of the flag stored within the Interactive Plan database *only*, not the units used for you MineSightŪ 3D project. The grail.ms3d.project_ module provides details about the MineSightŪ 3D project and its units. .. _grail.ms3d.project: ../grail.ms3d/lib-grail-ms3d-project.html :df:`getplanname(dRes)` Returns the plan name. :df:`olddict(dRes)` Returns 1 if old style dictionary else returns None. :df:`ordergrades(dRes)` Sets control grade and ensures grade lists are in proper order. In a typical IP script, this will be your third function call, .. Python:: hres = reserves.hGetCurResRef() dres = reserves.dGetRes(hres) reslib.ordergrades(dres) :df:`ordergradescut(res)` For *internal usage only*. :df:`ordergradesitems(glist)` For *internal use only*. :df:`preprints(msg[, fname])` Default file writing logger. Will append a messages, :a:`msg`, to the the file, :a:`fname`, or if desired, another filename. Default file name is :file:`scripterr.txt`. Attribute Functions ------------------- :df:`attrexists(cut, attributeName)` Returns a one if custom attribute exists otherwise returns none. Takes a cut and the custom attribute name as an argument. Takes a cut and the custom :a:`attributeName` as an argument. :df:`getcustomattr(cut, attrname)` Returns custom attribute value if it exists in the given :a:`cut`. The `attrname` is case sensitive. The :a:`cut` should be a cut dictionary as retrieved from :d:`dRes`. For example, to print all custom attribute for all cuts given :d:`dRes` you would do the following, .. Python:: for cut in dRes['cuts']: print reslib.attr_value(cut, 'MyCustomAttr') :df:`getcustomattrname(dRes, index)` Returns custom attribute name given dRes and attribute index. :df:`getnumcustomattr(dRes)` Returns number of custom attributes given Reserves Dictionary, :a:`dRes`. Area Functions -------------- :df:`getnumareas(dRes)` Return number of areas in plan. :df:`getarea(dRes, cut)` Returns reference to an area for a given Reserves Dictionary and cut. See also `Using reslib Get Functions`_. :df:`getdefarea(dRes)` Returns a default reference to an area for a given Reserves Dictionary, :a:`dRes`. See also `Using reslib Get Functions`_. :df:`getareabyindex(dRes, index)` Returns a reference to an area given the Reserves Dictionary, :a:`dRes`, and the area :a:`index`. See also `Using reslib Get Functions`_. :df:`getareaindexfrommatsetname(dRes, materialname)` Returns an area index for a :a:`materialname` within the Reserves Dictionary, :a:`dRes`. Bin (Cutoff) Functions ---------------------- Functions used to work with the cutoff bins within the Reserves Dictionary. When you divide a grade into a set of cutoff, the range between cutoffs is considered a bin. :df:`getbingrade(dRes, bin, gradename)` Returns a grade for a given :a:`bin` and :a:`gradename` within the Reserves Dictionary, :a:`dRes`. :df:`getbingradematset(dRes, materialset, bin, gradename)` Returns a grade for a :a:`bin` within a :a:`materialset` with the given :a:`gradename`, within the Reserves Dictionary, :a:`dRes`. :df:`getbingradematseti(dRes, materialset, bin, gradename, gidx)` Returns a grade for a :a:`bin` within a :a:`materialset` with the given :a:`gradename` and :a:`gradeiindex` within the Reserves Dictionary, :a:`dRes`. :df:`getbingradeperiod(dRes, period, bin, gradename)` Returns a grade for a :a:`gradename` within a given :a:`period` and :a`bin` within the Reserves Dictionary, :a:`dRes`. :df:`getbintonsmatset(dRes, materialset, bin)` Returns the total tons for a given :a:`materialset` and :a:`bin` index for the Reserves Dictionary, :a:`dRes`. This is the tons as reported across all periods. :df:`getbintonsperiodmatset(dRes, period, materialset, bin)` Returns the tons for a :a:`period` and `materialset` with the given :a:`bin` index within the Reserves Dictionary, :a:`dRes`. :df:`getbinvol(dRes, bin)` Returns the volume for a given :a:`bin` within the Reserves Dictionary, :a:`dRes`. :df:`getbinvolmatset(dRes, materialset, bin)` Returns the volume for a :a:`materialset`'s :a`bin` within the Reserves Dictionary, :a:`dRes`. :df:`getbinvolperiod(dRes, period, bin)` Returns the volume for a given :a:`period` and :a:`bin` index within the Reserves Dictionary, :a:`dRes`. :df:`getbinvolperiodmatset(dRes, period, materialset, bin)` Returns the volume for a given :a:`period`, :a:`materialset` and :a:`bin` index within the Reserves Dictionary, :a:`dRes`. :df:`getmaxbinsbycut(dRes, cut)` Returns the maximum number of bins represented across all the materials for a given :a:`cut` within the Reserves Dictionary, :a:`dRes`. :df:`getnumbinsbycut(dRes, cut)` Returns the number of bins for the :a:`cut` within the Reserves Dictionary, :a:`dRes`. :df:`getnumbinsbymaterial(dRes, area, materialset, material)` Return number of bins for a :a:`material` within :a:`materialset` inside a given :a:`area` as defined by the Reserves Dictionary, :a:`dRes`. :df:`getnumbinsmaterial(dRes, materialindex [, areaindex])` Returns the number of bins for a :a:`materialindex`. The :a:`areaindex` will default to 0. .. Note:: That this only works if your IP plan only has one material set. :df:`getnumbins(dRes[, areaidx])` Returns the number of bins within the Reserves Dictionary, :a:`dRes`, for the :a:`areaindex`. The :a:`areaindex` defaults to 0. .. Note:: That this only works if your IP plan only has one material set. :df:`getnumbinsmaterialbycut(dRes, cut, materialindex [, areaindex])` Returns the number of bins given the Reserves Dictionary, :a:`dRes`, for the :a:`cut`, :a:`materialindex`, and optional :a:`areaindex`. The area index defaults to 0. Calculation Functions --------------------- Simple functions that perform simple calculations based on the contents of the Reserves Dictionary. :df:`gettonscutbin(cut, bin)` Returns the tons given a :a:`cut` and :a:`bin`. :df:`getvolcutbin(cut, bin)` Returns the volume given a :a:`cut` and :a:`bin`. Cut Functions ------------- :df:`getcutcontrolgrade(dRes, cut)` Returns control grade given a cut. :df:`getcutgradematerialbin(cut, gname, matname, bin)` Return the grade for a cut given the materials and grade name and bin number. :df:`getcutgradematerialbini(cut, gidx, matname, bin)` Return the grade for a cut given the materials and grade name and bin number. :df:`getcutmaterialnumblocks(cut, matname, bin)` Returns the number of blocks given material and bin number. See also `Using reslib Get Functions`_ :df:`getcuttons(cut)` Returns the total tons for a given :a:`cut`. :df:`getcuttonsmaterial(dRes, cut, matname)` Return the total tons for a :a:`cut` with the given material name, :a:`matname`. :df:`getcuttonsmaterialbin(cut, matname, bin)` Return the tons for a cut given the materials name and bin number. :df:`getcutvolmaterial(dRes, cut, matname)` Return the total volume for a cut for a material given the material name. :df:`getcutvolmaterialbin(cut, matname, bin)` Return the volume for a cut given the materials name and bin number. :df:`getcutvolume(cut)` Returns total volume for a given :a:`cut`. :df:`get_cut_segid(cut)` *New in version 4.70* Returns the segment id for the given :a:`cut`. This ID can be used with the plan ID to look back into the MSPD. A currently active, new cut, will not have a segement id until that cut is saved to the MSPD. :df:`get_cut_geominfo(cut)` *New in version 4.70* Returns the field "Geom Info" field for a given cut. This is also known as "geometry creation info", or "geomcreation". Grade Functions --------------- :df:`getgrade(gname, res)` Return grade given reserve dictionary and grade name. :df:`getgradei(gidx, res)` Return grade given reserve dictionary and grade index. :df:`getgradelist(dRes[, areaidx])` Return list of grade dictionaries, which includes name, and accumulation flag. See also `Using reslib Get Functions`_. .. Note:: You are working with a reference to the grade list within the Reserves Dictionary. If you intend to operate with a entirely new structure use Python's ``copy`` module instead [#python-lib-copy]_. :df:`getgradename(dRes, i[, areaidx])` Returns a grade name given an index into the reserves dictionary. The area index is optional. :df:`getgradeperiod(dRes, period, gradename)` Return grade for period given Reserves Dictionary and grade name. :df:`getgradeperiodmatset(dRes, period, materialset, gradename)` Return grade for period given Reserves Dictionary and grade name. :df:`getgradeperiodmatseti(dRes, period, materialset, gradename, gidx)` Return grade for period given Reserves Dictionary and grade name. :df:`getgradeplan(dRes, gradename)` Return grade for plan given Reserves Dictionary and grade name. :df:`getgradeplanmatset(dRes, materialset, gradename)` Return grade for plan given Reserves Dictionary and grade name. :df:`getgradeplanmatseti(dRes, materialset, gname, gidx)` Return grade for plan given Reserves Dictionary and grade name. :df:`getgrades(dRes[, areaidx])` Returns a list of grade dictionaries. If no area index specified, there is assumed to be only 1. See also `Using reslib Get Functions`_. :df:`getnumgrades(dRes[, areaidx])` Return number of grades, area index is optional. :df:`getnumgradescut(cut)` Returns number of grades for a given cut. :df:`isgradeaccum(dRes, grade[, areaindex])` Returns 1 if the grade is an accumulated grade; otherwise, returns 0. :df:`isgradethick(dRes, grade[, areaindexi])` Returns 1 if the accumulation are performed with the special thickness case. The thickness case is a special case on how to average. In MineSightŪ Interactive Planner we can sum up our grades in two ways, 1. We can do a weighted average based on the specific gravity. For example with copper grades. 2. We can do a straight accumulation. For example with dollar values of barrels of oil. Thickness is the exception to the above to methods. If one wants to the know the average thickness of a the cut, you can not sum and you can not do a weighted average based on the specific gravity. You have to do a weighted average based on how many blocks were considered. In other words, how much area the average considers. Material Functions ------------------ :df:`getmat(dRes, matsetname, matname)` Return material given materialset name and material name. See also `Using reslib Get Functions`_. :df:`getmatreserves(cut, matname)` Returns reserves structure given a cut structure and material name. See also `Using reslib Get Functions`_. :df:`getmaterial(dRes, material)` Return material given Reserves Dictionary and material name only works with single material set. See also `Using reslib Get Functions`_. :df:`getmaterialbycut(dRes, cut, material[, areaindex])` Return material given Reserves Dictionary and material name. The :a:`areaindex` defaults to 0. See also `Using reslib Get Functions`_. :df:`getmaterials(dRes[, areaidx])` Return default material given Reserves Dictionary only works with single material set. See also `Using reslib Get Functions`_. :df:`getmaterialsbycut(dRes, cut[, areaidx])` Return material given Reserves Dictionary and a cut, which gives you the material set. See also `Using reslib Get Functions`_. :df:`getmaterialsetbycut(dRes, cut)` Returns the materialset for the given cut only works for the new dictionary structure. :df:`getnummaterialsbycut(dRes, cut)` Return number of materials given Reserve Dictionary and a cut, which gives you the material set. Material Set Functions ---------------------- :df:`getmaterialsetbyindex(dRes, areaindex, materialsetindex)` Return material set given area and materialset index. See also `Using reslib Get Functions`_. :df:`getmatsetindexfromcut(dRes, cut[, areaidx])` Return index to a material set, given a cut. See also `Using reslib Get Functions`_. :df:`getmatsets(dRes[, areaidx])` Return the materials sets dictionary given Reserves Dictionary. See also `Using reslib Get Functions`_. :df:`getnummaterialsets(dRes, areaindex)` Return number of material sets given area index. :df:`getnummatsets(dRes)` Return number of material sets Reserve Dictionary. :df:`matincut(material, cut)` Return reserves for a given cut and material. See also `Using reslib Get Functions`_. ODBC Functions -------------- Functions related to the Open Database Connectivity (ODBC) interface. :df:`db_odbc_str(dRes)` This returns a string for use with the python `odbc` module. It can be used to open a connection to a database with a properly defined ODBC name. As an example, this function will convert the following result of a call to :f:`db_odbc_connection_str`, .. Python:: ('ODBC;DSN=test;DBQ=C:\\tmp\\projects\\IPSingleOrePercent\\' 'attrib_database\\test.mdb;DriverId=25;FIL=MS Access;' MaxBufferSize=2048;PageTimeout=5;') to the following value for use in the python `odbc` module, .. Python:: test// notice, that if there was a username and password you would have gotten the following, .. Python:: test/username/password See the warning in :f:`db_odbc_obj` for issues regarding using the python `odbc` module directly. :df:`db_odbc_obj(dRes)` This returns the results of calling the python `odbc` module with the :f:`db_odbc_str` function. The :c:`odbc` Object returned can let you make queries against the underlying database. .. Python:: import pprint from grail.ip import reslib sql = "SELECT OBJECTID FROM GEOMOBJECT" odbc = reslib.db_odbc_obj(dRes) cursor = odbc.cursor() cursor.execute(sql) resultList = cursor.fetchall() print "Results of SQL Query: " + sql pprint.pprint(resultList) where the resulting message window would have something like this, .. Python:: Results of SQL Query: SELECT OBJECTID FROM GEOMOBJECT [('test-2007',), ('test_plan',), ('test-2007_OPENIP',), ('test-2007_BLASTVECS',)] .. Warning:: Extreme caution should be taken when using this Database connection and issuing SQL statements against the DB. By circumnavigating the standard interfaces you are risking corrupting your data. Furthermore, we can not guarantee that the underlying definitions will remain consistent from release to release. :df:`db_odbc_connection_str(dRes)` Returns the connection string used for the current database. Deprecated alias :f:`getODBCconnection` since v4.00. :df:`db_query(dRes)` Returns the query used for the currently active view into the database. The active view is defined by open 'plan'. Specifically this returns the contents of the WHERE clause within a SQL SELECT statement. For instance, with the following SQL statement, .. code-block:: SQL SELECT * FROM GEOMOBJECT WHERE OBJECTID = "PLAN23" this function would return "OBJECTID = 'PLAN23'". Deprecated alias :f:`getODBCquery` since v4.00. Path Functions -------------- Functions used to returning pathing information for a given Interactive Plan. All paths are returned as absolute paths. :df:`getplanfilepath(dRes)` Returns the absolute path to the Interactive Planner MineSightŪ Resource file. :df:`getmodelpath(dRes[, area])` Alias: :df:`get_model_path` starting in 4.60. Returns the absolute path to the model for the given :a:`area` index. Default area index is 0. The model path will only have a value if the :a:`area` type is a :d:`AREATYPE_MODEL`. See :f:`get_area_type` for more details. :df:`getpcfpath(dRes[, area])` Alias: :df:`get_pcf_path` starting in 4.60. Returns the absolute path to the Project Control File (PCF) for a given :a:`area`. Default area index is 0. :df:`get_area_type(dRes[,area])` *New in version 4.60.* Returns the either :d:`AREATYPE_DH` or :d:`AREATYPE_MODEL` depending on what type of model is used for the underlying :a:`area`. A :d:`AREATYPE_DH` corresponds to drillhole data, and the :d:`AREATYPE_MODEL` corresponds to modeling data. The default :a:`area` is 0. :df:`get_dh_survey_path(dRes[,area])` *New in version 4.60.* Returns the absolute path for the survey file if the area type for :a:`area` is :d:`AREATYPE_DH` (drillhole). See :f:`get_area_type` for more details. If the :d:`area` is not a drillhole area, this will return a blank string. The default :a:`area` is 0. Call :f:`get_survey_type`, to get its file number in the MineSight(r) system. :df:`get_dh_assay_path(dRes[,area])` *New in version 4.60.* Returns the absolute path for the assay file if the area type for :a:`area` is :d:`AREATYPE_DH` (drillhole). See :f:`get_area_type` for more details.If the :d:`area` is not a drillhole area, this will return a blank string. The default :a:`area` is 0. Call :f:`get_survey_type`, to get its file number in the MineSight(r) system. :df:`get_dh_survey_type(dRes[,area])` *New in version 4.60.* Returns the file number in the MineSight(r) system as an integer for the survey file define for the :a:`area`. If the :d:`area` is not a drillhole area, this will return 0. The default :a:`area` is 0. :df:`get_dh_assay_type(dRes[,area])` *New in version 4.60.* Returns the file number in the MineSight(r) system as an integer for the assay file define for the :a:`area`. If the :d:`area` is not a drillhole area, this will return 0. The default :a:`area` is 0. --------- Constants --------- :dd:`AREATYPE_DH` *New in version 4.60*. When querying :d:`get_area_type` it will return this if the area is a drill hole type. :dd:`AREATYPE_MODEL`: *New in version 4.60*. When querying :d:`get_area_type` it will return this if the area is a model type. :dd:`AREATYPE_TORQUE`: *New in version 6.10*. When querying :d:`get_area_type` it will return this if the area is a MSTorque drill hole type. --------- Reference --------- .. [#python-lib-copy] "copy -- Shallow and deep copy operations". 21 December 2001. 6 June 2005.