예제 #1
0
def test_cost_func():
        # test cost_func: cost

        # Input
        # stand info
        area = 66.3709
        elevation = 141.034205761
        slope = 21.74728843 
        stand_wkt = u'POLYGON ((-13809080.891332019 5330620.9753014417,-13808943.708174769 5331066.8205624959,-13808393.373740762 5330897.4868904939,-13808530.556898013 5330451.6416294342,-13809080.891332019 5330620.9753014417))'
        # harvest info
        RemovalsCT = 200.0 
        TreeVolCT = 5.0 
        RemovalsSLT = 100.0 
        TreeVolSLT = 70.0 
        RemovalsLLT = 20.0 
        TreeVolLLT = 200.0 
        HdwdFractionCT = 0.15 
        HdwdFractionSLT = 0.0 
        HdwdFractionLLT = 0.0
        PartialCut = 0 
        # routing info
        landing_coords = (-124.04858, 43.12776) 
        haulDist = 8.674960531
        haulTime = 32.92 
        coord_mill = (-124.161246, 43.106512)

        # Expected Output
        cost = {'slope': 21.75, 'skid_distance': 999.69, 'mill_coordinates': (-124.161246, 43.106512), 'elevation': 141.03, 'total_harvest_cost': 314598.0, 'haul_distance_ow': 8.94, 'total_cost': 350309.0, 'haul_cost_min': 0.604, 'total_area': 66.37, 'harvest_cost_ft3': 0.395, 'haul_distance_extension': 0.269, 'total_haul_trips': 898.0, 'haul_time_ow': 32.92, 'total_haul_cost': 35711.0, 'harvest_system': 'GroundBasedMechWT', 'landing_coordinates': (-124.04706351844823, 43.125146208049415), 'total_volume': 796450.8}
        assert(main_model.cost_func(
                # stand info
                area,
                elevation,
                slope,
                stand_wkt,
                # harvest info
                RemovalsCT,
                TreeVolCT,
                RemovalsSLT,
                TreeVolSLT,
                RemovalsLLT,
                TreeVolLLT,
                HdwdFractionCT,
                HdwdFractionSLT,
                HdwdFractionLLT,
                PartialCut,
                # routing info
                landing_coords,
                haulDist,
                haulTime,
                coord_mill
                )) == cost
예제 #2
0
def main():

    scenario = Scenario.objects.get(id=122)

    sql = """SELECT
                ss.id AS sstand_id, a.cond, a.rx, a.year, a.offset, ss.acres AS acres,
                a.total_stand_carbon AS total_carbon,
                a.agl AS agl_carbon,
                a.removed_merch_bdft / 1000.0 AS harvested_timber, -- convert to mbf
                a.after_merch_bdft / 1000.0 AS standing_timber, -- convert to mbf
                ST_AsText(ss.geometry_final) AS stand_wkt,
                a.LG_CF             AS LG_CF,
                a.LG_HW             AS LG_HW,
                a.LG_TPA            AS LG_TPA,
                a.SM_CF             AS SM_CF,
                a.SM_HW             AS SM_HW,
                a.SM_TPA            AS SM_TPA,
                a.CH_CF             AS CH_CF,
                a.CH_HW             AS CH_HW,
                a.CH_TPA            AS CH_TPA,
                stand.elevation  AS elev,
                stand.slope      AS slope,
                a.CUT_TYPE       AS CUT_TYPE
            FROM
                trees_fvsaggregate a
            JOIN
                trees_scenariostand ss
              ON  a.cond = ss.cond_id
              AND a.rx = ss.rx_internal_num
              AND a.offset = ss.offset
            JOIN trees_stand stand
              ON ss.stand_id = stand.id
            -- WHERE a.site = 2 -- TODO if we introduce multiple site classes, we need to fix
            WHERE   var = '%s' -- get from current property
            AND   ss.scenario_id = %d -- get from current scenario
            ORDER BY a.year, ss.id;""" % (scenario.input_property.variant.code, scenario.id)

    cursor = connection.cursor()
    cursor.execute(sql)
    data = dictfetchall(cursor)

    # Mill information
    mill_shp = 'Data/mills.shp'

    # Landing Coordinates
    center = scenario.input_property.geometry_final.point_on_surface
    centroid_coords = center.transform(4326, clone=True).tuple
    landing_coords = landing.landing(centroid_coords=centroid_coords)

    haulDist, haulTime, coord_mill = r.routing(
        landing_coords,
        mill_shp=mill_shp
    )

    annual_total_cost = defaultdict(float)
    annual_haul_cost = defaultdict(float)
    annual_heli_harvest_cost = defaultdict(float)
    annual_ground_harvest_cost = defaultdict(float)
    annual_cable_harvest_cost = defaultdict(float)
    used_records = 0
    skip_noharvest = 0
    skip_error = 0

    year = None
    years = []
    for row in data:
        ### GIS Data
        stand_wkt = row['stand_wkt']
        area = row['acres']
        if year != int(row['year']):
            year = int(row['year'])
            print "Calculating cost per stand in year", year
            years.append(year)
            annual_total_cost[year] += 0
            annual_haul_cost[year] += 0
            annual_heli_harvest_cost[year] += 0
            annual_ground_harvest_cost[year] += 0
            annual_cable_harvest_cost[year] += 0

        # NOTE: elevation and slope come directly from stand 
        # if we use spatial contrainsts to chop scenariostands,
        # will need to recalc zonal stats
        elevation = row['elev']
        slope = row['slope']

        ### Tree Data ###
        # Cut type code indicating type of harvest implemented.
        # 0 = no harvest, 1 = pre-commercial thin,
        # 2 = commercial thin, 3 = regeneration harvest
        try:
            cut_type = int(row['cut_type'])
        except:
            # no harvest so don't attempt to calculate
            cut_type = 0

        # PartialCut(clear cut = 0, partial cut = 1)
        if cut_type == 3:
            PartialCut = 0
        elif cut_type in [1, 2]:
            PartialCut = 1
        else:
            # no harvest so don't attempt to calculate
            skip_noharvest += 1
            continue

        # Hardwood Fraction
        # Chip Trees
        RemovalsCT = row['ch_tpa']
        TreeVolCT = row['ch_cf']
        HdwdFractionCT = row['ch_hw']

        # Small Log Trees
        RemovalsSLT = row['sm_tpa']
        TreeVolSLT = row['sm_cf']
        HdwdFractionSLT = row['sm_hw']

        # Large Log Trees
        RemovalsLLT = row['lg_tpa']
        TreeVolLLT = row['lg_cf']
        HdwdFractionLLT = row['lg_hw']

        cost_args = (
            # stand info
            area,
            elevation,
            slope,
            stand_wkt,
            # harvest info
            RemovalsCT,
            TreeVolCT,
            RemovalsSLT,
            TreeVolSLT,
            RemovalsLLT,
            TreeVolLLT,
            HdwdFractionCT,
            HdwdFractionSLT,
            HdwdFractionLLT,
            PartialCut,
            # routing info
            landing_coords,
            haulDist,
            haulTime,
            coord_mill
        )

        try:
            result = m.cost_func(*cost_args)
            annual_haul_cost[year] += result['total_haul_cost']
            annual_total_cost[year] += result['total_cost']

            system = result['harvest_system']
            if system.startswith("Helicopter"):
                annual_heli_harvest_cost[year] += result['total_harvest_cost']
            elif system.startswith("Ground"):
                annual_ground_harvest_cost[year] += result['total_harvest_cost']
            elif system.startswith("Cable"):
                annual_cable_harvest_cost[year] += result['total_harvest_cost']
            else:
                # TODO
                annual_cable_harvest_cost[year] += result['total_harvest_cost']
                #raise ValueError
            used_records += 1
        except (ZeroDivisionError, ValueError):
            skip_error += 1

            # import traceback
            # print cost_args
            # print traceback.format_exc()


    def ordered_costs(x):
        sorted_x = sorted(x.iteritems(), key=operator.itemgetter(0))
        return [-1 * z[1] for z in sorted_x]

    print "--------"
    print "    var heli =", json.dumps(ordered_costs(annual_heli_harvest_cost)), ";"
    print "    var cable =", json.dumps(ordered_costs(annual_cable_harvest_cost)), ";"
    print "    var ground =", json.dumps(ordered_costs(annual_ground_harvest_cost)), ";"
    print "    var haul =", json.dumps(ordered_costs(annual_haul_cost)), ";"
    print "    var years =", json.dumps(sorted(annual_haul_cost.keys())), ";"

    # RANDOMLY determine a revenue w/in % of total cost; HACK
    rev = [-1 * x * (1.0 + (0.35 - (random.random() * 0.5))) for x in ordered_costs(annual_total_cost)]
    #rev = [-1 * x for x in ordered_costs(annual_total_cost)]
    print "    var revenue =", json.dumps(rev), ";"

    # determine profit
    profit = [revenue + cost for revenue, cost in zip(rev, ordered_costs(annual_total_cost))]
    print "    var profit =", json.dumps(profit), ";"

    print "--------"
    print "year, heliHarvestCost, cableHarvestCost, groundHarvestCost, transportationCost"
    for year in sorted(dict(annual_haul_cost).keys()):
        print ", ".join(str(x)
            for x in [
                year,
                annual_heli_harvest_cost[year],
                annual_cable_harvest_cost[year],
                annual_ground_harvest_cost[year],
                annual_haul_cost[year]
            ]
        )

    print "--------"
    print "used records:", used_records
    print "skipped (no harvest):", skip_noharvest
    print "skipped (errors):", skip_error
예제 #3
0
def main():

    scenario = Scenario.objects.get(id=122)

    sql = """SELECT
                ss.id AS sstand_id, a.cond, a.rx, a.year, a.offset, ss.acres AS acres,
                a.total_stand_carbon AS total_carbon,
                a.agl AS agl_carbon,
                a.removed_merch_bdft / 1000.0 AS harvested_timber, -- convert to mbf
                a.after_merch_bdft / 1000.0 AS standing_timber, -- convert to mbf
                ST_AsText(ss.geometry_final) AS stand_wkt,
                a.LG_CF             AS LG_CF,
                a.LG_HW             AS LG_HW,
                a.LG_TPA            AS LG_TPA,
                a.SM_CF             AS SM_CF,
                a.SM_HW             AS SM_HW,
                a.SM_TPA            AS SM_TPA,
                a.CH_CF             AS CH_CF,
                a.CH_HW             AS CH_HW,
                a.CH_TPA            AS CH_TPA,
                stand.elevation  AS elev,
                stand.slope      AS slope,
                a.CUT_TYPE       AS CUT_TYPE
            FROM
                trees_fvsaggregate a
            JOIN
                trees_scenariostand ss
              ON  a.cond = ss.cond_id
              AND a.rx = ss.rx_internal_num
              AND a.offset = ss.offset
            JOIN trees_stand stand
              ON ss.stand_id = stand.id
            -- WHERE a.site = 2 -- TODO if we introduce multiple site classes, we need to fix
            WHERE   var = '%s' -- get from current property
            AND   ss.scenario_id = %d -- get from current scenario
            ORDER BY a.year, ss.id;""" % (scenario.input_property.variant.code,
                                          scenario.id)

    cursor = connection.cursor()
    cursor.execute(sql)
    data = dictfetchall(cursor)

    # Mill information
    mill_shp = 'Data/mills.shp'

    # Landing Coordinates
    center = scenario.input_property.geometry_final.point_on_surface
    centroid_coords = center.transform(4326, clone=True).tuple
    landing_coords = landing.landing(centroid_coords=centroid_coords)

    haulDist, haulTime, coord_mill = r.routing(landing_coords,
                                               mill_shp=mill_shp)

    annual_total_cost = defaultdict(float)
    annual_haul_cost = defaultdict(float)
    annual_heli_harvest_cost = defaultdict(float)
    annual_ground_harvest_cost = defaultdict(float)
    annual_cable_harvest_cost = defaultdict(float)
    used_records = 0
    skip_noharvest = 0
    skip_error = 0

    year = None
    years = []
    for row in data:
        ### GIS Data
        stand_wkt = row['stand_wkt']
        area = row['acres']
        if year != int(row['year']):
            year = int(row['year'])
            print "Calculating cost per stand in year", year
            years.append(year)
            annual_total_cost[year] += 0
            annual_haul_cost[year] += 0
            annual_heli_harvest_cost[year] += 0
            annual_ground_harvest_cost[year] += 0
            annual_cable_harvest_cost[year] += 0

        # NOTE: elevation and slope come directly from stand
        # if we use spatial contrainsts to chop scenariostands,
        # will need to recalc zonal stats
        elevation = row['elev']
        slope = row['slope']

        ### Tree Data ###
        # Cut type code indicating type of harvest implemented.
        # 0 = no harvest, 1 = pre-commercial thin,
        # 2 = commercial thin, 3 = regeneration harvest
        try:
            cut_type = int(row['cut_type'])
        except:
            # no harvest so don't attempt to calculate
            cut_type = 0

        # PartialCut(clear cut = 0, partial cut = 1)
        if cut_type == 3:
            PartialCut = 0
        elif cut_type in [1, 2]:
            PartialCut = 1
        else:
            # no harvest so don't attempt to calculate
            skip_noharvest += 1
            continue

        # Hardwood Fraction
        # Chip Trees
        RemovalsCT = row['ch_tpa']
        TreeVolCT = row['ch_cf']
        HdwdFractionCT = row['ch_hw']

        # Small Log Trees
        RemovalsSLT = row['sm_tpa']
        TreeVolSLT = row['sm_cf']
        HdwdFractionSLT = row['sm_hw']

        # Large Log Trees
        RemovalsLLT = row['lg_tpa']
        TreeVolLLT = row['lg_cf']
        HdwdFractionLLT = row['lg_hw']

        cost_args = (
            # stand info
            area,
            elevation,
            slope,
            stand_wkt,
            # harvest info
            RemovalsCT,
            TreeVolCT,
            RemovalsSLT,
            TreeVolSLT,
            RemovalsLLT,
            TreeVolLLT,
            HdwdFractionCT,
            HdwdFractionSLT,
            HdwdFractionLLT,
            PartialCut,
            # routing info
            landing_coords,
            haulDist,
            haulTime,
            coord_mill)

        try:
            result = m.cost_func(*cost_args)
            annual_haul_cost[year] += result['total_haul_cost']
            annual_total_cost[year] += result['total_cost']

            system = result['harvest_system']
            if system.startswith("Helicopter"):
                annual_heli_harvest_cost[year] += result['total_harvest_cost']
            elif system.startswith("Ground"):
                annual_ground_harvest_cost[year] += result[
                    'total_harvest_cost']
            elif system.startswith("Cable"):
                annual_cable_harvest_cost[year] += result['total_harvest_cost']
            else:
                # TODO
                annual_cable_harvest_cost[year] += result['total_harvest_cost']
                #raise ValueError
            used_records += 1
        except (ZeroDivisionError, ValueError):
            skip_error += 1

            # import traceback
            # print cost_args
            # print traceback.format_exc()

    def ordered_costs(x):
        sorted_x = sorted(x.iteritems(), key=operator.itemgetter(0))
        return [-1 * z[1] for z in sorted_x]

    print "--------"
    print "    var heli =", json.dumps(
        ordered_costs(annual_heli_harvest_cost)), ";"
    print "    var cable =", json.dumps(
        ordered_costs(annual_cable_harvest_cost)), ";"
    print "    var ground =", json.dumps(
        ordered_costs(annual_ground_harvest_cost)), ";"
    print "    var haul =", json.dumps(ordered_costs(annual_haul_cost)), ";"
    print "    var years =", json.dumps(sorted(annual_haul_cost.keys())), ";"

    # RANDOMLY determine a revenue w/in % of total cost; HACK
    rev = [
        -1 * x * (1.0 + (0.35 - (random.random() * 0.5)))
        for x in ordered_costs(annual_total_cost)
    ]
    #rev = [-1 * x for x in ordered_costs(annual_total_cost)]
    print "    var revenue =", json.dumps(rev), ";"

    # determine profit
    profit = [
        revenue + cost
        for revenue, cost in zip(rev, ordered_costs(annual_total_cost))
    ]
    print "    var profit =", json.dumps(profit), ";"

    print "--------"
    print "year, heliHarvestCost, cableHarvestCost, groundHarvestCost, transportationCost"
    for year in sorted(dict(annual_haul_cost).keys()):
        print ", ".join(
            str(x) for x in [
                year, annual_heli_harvest_cost[year],
                annual_cable_harvest_cost[year],
                annual_ground_harvest_cost[year], annual_haul_cost[year]
            ])

    print "--------"
    print "used records:", used_records
    print "skipped (no harvest):", skip_noharvest
    print "skipped (errors):", skip_error
예제 #4
0
def test_cost_func():
    # test cost_func: cost

    # Input
    # stand info
    area = 66.3709
    elevation = 141.034205761
    slope = 21.74728843
    stand_wkt = u'POLYGON ((-13809080.891332019 5330620.9753014417,-13808943.708174769 5331066.8205624959,-13808393.373740762 5330897.4868904939,-13808530.556898013 5330451.6416294342,-13809080.891332019 5330620.9753014417))'
    # harvest info
    RemovalsCT = 200.0
    TreeVolCT = 5.0
    RemovalsSLT = 100.0
    TreeVolSLT = 70.0
    RemovalsLLT = 20.0
    TreeVolLLT = 200.0
    HdwdFractionCT = 0.15
    HdwdFractionSLT = 0.0
    HdwdFractionLLT = 0.0
    PartialCut = 0
    # routing info
    landing_coords = (-124.04858, 43.12776)
    haulDist = 8.674960531
    haulTime = 32.92
    coord_mill = (-124.161246, 43.106512)

    # Expected Output
    cost = {
        'slope': 21.75,
        'skid_distance': 999.69,
        'mill_coordinates': (-124.161246, 43.106512),
        'elevation': 141.03,
        'total_harvest_cost': 314598.0,
        'haul_distance_ow': 8.94,
        'total_cost': 350309.0,
        'haul_cost_min': 0.604,
        'total_area': 66.37,
        'harvest_cost_ft3': 0.395,
        'haul_distance_extension': 0.269,
        'total_haul_trips': 898.0,
        'haul_time_ow': 32.92,
        'total_haul_cost': 35711.0,
        'harvest_system': 'GroundBasedMechWT',
        'landing_coordinates': (-124.04706351844823, 43.125146208049415),
        'total_volume': 796450.8
    }
    assert (main_model.cost_func(
        # stand info
        area,
        elevation,
        slope,
        stand_wkt,
        # harvest info
        RemovalsCT,
        TreeVolCT,
        RemovalsSLT,
        TreeVolSLT,
        RemovalsLLT,
        TreeVolLLT,
        HdwdFractionCT,
        HdwdFractionSLT,
        HdwdFractionLLT,
        PartialCut,
        # routing info
        landing_coords,
        haulDist,
        haulTime,
        coord_mill)) == cost
예제 #5
0
        TreeVolLLT = 100.00

        cost = m.cost_func(
            # stand info
            area,
            elevation,
            slope,
            stand_wkt,
            # harvest info
            RemovalsCT,
            TreeVolCT,
            RemovalsSLT,
            TreeVolSLT,
            RemovalsLLT,
            TreeVolLLT,
            HdwdFractionCT,
            HdwdFractionSLT,
            HdwdFractionLLT,
            PartialCut,
            # road construction info
            lengthNewRoad,
            totaltravelCostNewRoad,
            standCount,
            # routing info
            coords_landing_stand,
            coords_landing_road,
            haulDist,
            haulTime,
            coord_mill,
        )

        pprint(cost)
예제 #6
0
        mill_shp=mill_shp
    )

    cost = m.cost_func(
        # stand info
        area,
        elevation,
        slope,
        stand_wkt,
        # harvest info
        RemovalsCT,
        TreeVolCT,
        RemovalsSLT,
        TreeVolSLT,
        RemovalsLLT,
        TreeVolLLT,
        HdwdFractionCT,
        HdwdFractionSLT,
        HdwdFractionLLT,
        PartialCut,
        # routing info
        landing_coords,
        haulDist,
        haulTime,
        coord_mill,
        # options
        True,
        0.5
    )

    pprint(cost)
예제 #7
0
    haulDist, haulTime, coord_mill = r.routing(landing_coords,
                                               mill_shp=mill_shp)

    cost = m.cost_func(
        # stand info
        area,
        elevation,
        slope,
        stand_wkt,
        # harvest info
        RemovalsCT,
        TreeVolCT,
        RemovalsSLT,
        TreeVolSLT,
        RemovalsLLT,
        TreeVolLLT,
        HdwdFractionCT,
        HdwdFractionSLT,
        HdwdFractionLLT,
        PartialCut,
        # routing info
        landing_coords,
        haulDist,
        haulTime,
        coord_mill,
        # options
        True,
        0.5)

    pprint(cost)
예제 #8
0
        for field in fields:
            val = row[field]
            try:
                val = float(val)
            except ValueError:
                if "|" in val:
                    # randomly sample from uniform distribution
                    low, high = [float(x) for x in val.split("|")]
                    val = random.uniform(low, high)

            args.append(val)

        if row['PartialCut'] == 1:
            haulprop = 0.5
        else:
            haulprop = 1.0

        val = row['skid_distance']
        try:
            skid_distance = float(val)
        except ValueError:
            if "|" in val:
                # randomly sample from uniform distribution
                low, high = [float(x) for x in val.split("|")]
                skid_distance = random.uniform(low, high)

        #print args
        results = main_model.cost_func(*args, Helicopter=False, HaulProportion=haulprop, skid_distance=skid_distance)
        print ",".join(str(x) for x in [row['name'], row['actual_cost'], results['total_cost']])
        print "\n"
예제 #9
0
import traceback
import glob
import shutil

#from IPython.core import ultratb
#sys.excepthook = ultratb.FormattedTB(mode='Verbose', color_scheme='Linux', call_pdb=1)

good = bad = 0

for txt in glob.glob("*.txt"):
    moveit = False
    with open(txt, 'r') as fh:
        lines = fh.readlines()
        args = eval(lines[6])
        try:
            print main_model.cost_func(*args)
            good += 1
            #moveit = True
        except:
            bad += 1
            print "-----"
            print txt
            print
            print traceback.format_exc()
    if moveit:
        shutil.move(txt, "good/" + txt)

print "##### GOOD", good
print "##### BAD", bad