===================================== HowTo: Assign Average Grade for a Cut ===================================== .. include:: ..\version.h .. include:: howto-reference.h .. contents:: Table of Contents :backlinks: top ------- Preface ------- This document discusses the technique for assigning average grades for a given Interactive Planner cut. Assumptions ----------- It is assumed that you have a working familiarity with, * the MineSightŪ Interactive Planner (MS-IP) * writing Python scripts Furthermore, it is assumed that you have a Custom Attribute defined that is called "Avg_Grade". The value should be defined as a *real*. See the MineSightŪ-Interactive Planner documentation for more information regarding adding custom attributes. ---------- Background ---------- The script we intend to write will walk across all the atomic reserves for a particular cut. The *atomic reserves* are defined as the smallest addressable piece of information after a cut was made on a resource model. These atomic reserves are broken down based on rock type and grade cut-offs. Therefore, our average grades for a cut will walk across each of the possible atomic reserves and compute the average grade for all cut-offs and all rock types within a particular cut. ------------------------ Assigning Average Grades ------------------------ The process of writing the script can be broken down into the following steps, 1. Create the script. 2. Fill in the logic for computing average grades. The following sections discuss the steps required to build a script that assigns average grades. Afterward, we will review the completed script. Create the Script ----------------- In the :file:`$(medexe)\\scripts\\samples` directory there exists a :file:`ip-boilerplate.py` script. This script serves as a quick, ready to use, template, Interactive Planner (IP) script. We will use the :file:`ip-boilerplate.py` script as the basis for creating our own script that will assign average grades. Copy this script to another file, that we will call :file:`averagegrade.py`. Adding the Average Grade Computation ------------------------------------ The next step involves opening the :file:`averagegrade.py` script in your favorite Python editor, and start editing it to assign average grades for cuts. The :f:`run_script()` function is were we will start, and it should look like, .. Python:: def run_script(): hRes = reserves.hGetCurResRef() dRes = reserves.dGetRes(hRes) reslib.ordergrades(dRes) The first order of business is to determine what the control grade is for a given reserve. .. Python:: controlgrade = reslib.getcontrolgrade(dRes) Now it is time to compute the average grade for the control grade, lets start off by creating a separate function that takes a given cut and the control grade and computes the average grade for that cut. .. Python:: def calc_average_grade(cut, grade): total_tons = 0.0 avg_grade = 0.0 for cut_reserve in cut['reserves']: cut_reserve_tons = cut_reserve['tons'] if cut_reserve_tons > 0.0: # avg_grade*total_tons + grade*cut_reserve_tons # avg_grade = ----------------------------------------------- # total_tons + cut_reserve_tons # grade_value = reslib.getgrade(grade, cut_reserve) avg_grade = (avg_grade*total_tons +\ grade_value*cut_reserve_tons) / (total_tons +\ cut_reserve_tons) total_tons = total_tons + cut_reserve_tons return avg_grade The final step is to take the return value for :f:`calc_average_grade` and add it to our database via the geometry view. If we do this for all cuts, then we would get something like, .. Python:: for cut in dRes['cuts']: avggrade = calc_average_grade(cut, controlgrade) geomview.vSetAttr(cut['geomkey'], 'Avg_Grade', avggrade) At this point we have computed the average control grade for all the cuts within a given IP plan. .. Note:: That if you have not defined a custom attribute named "Avg_Grade" then this script will work incorrectly. The Complete Script ------------------- The complete script will appear as follows, .. Python:: """Computes the average control grade for all cuts.""" from grail import gsys from grail.ip import reserves from grail.ip import reslib from grail.ip import geomview def run_script(): hRes = reserves.hGetCurResRef() dRes = reserves.dGetRes(hRes) reslib.ordergrades(dRes) controlgrade = reslib.getcontrolgrade(dRes) for cut in dRes['cuts']: avggrade = calc_average_grade(cut, controlgrade) geomview.vSetAttr(cut['geomkey'], 'Avg_Grade', avggrade) def calc_average_grade(cut, grade): total_tons = 0.0 avg_grade = 0.0 for cut_reserve in cut['reserves']: cut_reserve_tons = cut_reserve['tons'] if cut_reserve_tons > 0.0: # avg_grade*total_tons + grade*cut_reserve_tons # avg_grade = ----------------------------------------------- # total_tons + cut_reserve_tons # grade_value = reslib.getgrade(grade, cut_reserve) avg_grade = (avg_grade*total_tons +\ grade_value*cut_reserve_tons) / (total_tons +\ cut_reserve_tons) total_tons = total_tons + cut_reserve_tons return avg_grade gmain = gsys.GMAIN(run_script, __name__) gmain.run() The script will compute the average control grade for each cut, and store it under the "Avg_Grade" custom attribute for that cut. Our script also has the added bonus of creating a generic function that we can import into other scripts. We could either add the :f:`calc_average_grade()` function to our own Interactive Planner utility module, and import it into other scripts, or we could just import our :file:`averagegrade` script and use the function.