def test_diet_intermediates(herb_class): """Scraps of the function calc_diet_intermediates.""" diet = forage.Diet() diet.If = 10. diet.DMDf = 0.64 diet.CPIf = 1. # copied from calc_diet_intermediates() supp = forage.Supplement(FreerParam.FreerParamCattle('indicus'), 0, 0, 0, 0, 0, 0) site = forage.SiteInfo(1, 0) diet_interm = forage.DietIntermediates() MEIf = (17.0 * diet.DMDf - 2) * diet.If # eq 31: herbage MEIs = (13.3 * supp.DMD + 23.4 * supp.EE + 1.32) * diet.Is # eq 32 FMEIs = (13.3 * supp.DMD + 1.32) * diet.Is # eq 32, supp.EE = 0 MEItotal = MEIf + MEIs # assuming no intake of milk M_per_Dforage = MEIf / diet.If kl = herb_class.FParam.CK5 + herb_class.FParam.CK6 * M_per_Dforage # eq 34 km = (herb_class.FParam.CK1 + herb_class.FParam.CK2 * M_per_Dforage ) # eq 33 efficiency of energy use for maintenance Emove = herb_class.FParam.CM16 * herb_class.D * herb_class.W Egraze = herb_class.FParam.CM6 * herb_class.W * diet.If * \ (herb_class.FParam.CM7 - diet.DMDf) + Emove Emetab = herb_class.FParam.CM2 * herb_class.W**0.75 * max( math.exp(-herb_class.FParam.CM3 * herb_class.A), herb_class.FParam.CM4) # eq 41, energy req for maintenance: MEm = (Emetab + Egraze) / km + herb_class.FParam.CM1 * MEItotal if herb_class.sex == 'castrate' or herb_class.sex == 'entire_m': MEm = MEm * 1.15 if herb_class.sex == 'herd_average': MEm = MEm * 1.055 if herb_class.sex == 'NA': MEm = (MEm + MEm * 1.15) / 2 diet_interm.L = (MEItotal / MEm) - 1. # new calculations to test --- copy any corrections from here A_foet = 30. # assumed days since conception RA = A_foet / herb_class.FParam.CP1 BW = (1 - herb_class.FParam.CP4 + herb_class.FParam.CP4 * herb_class.Z) * herb_class.FParam.CP15 * herb_class.SRW BC_foet = 1 # assume condition of foetus is 1, ignoring weight # assume she is pregnant with one foetus MEc_num1 = (herb_class.FParam.CP8 * (herb_class.FParam.CP5 * BW) * BC_foet) MEc_num2 = ((herb_class.FParam.CP9 * herb_class.FParam.CP10) / herb_class.FParam.CP1) MEc_num3 = math.exp(herb_class.FParam.CP10 * (1 - RA) + herb_class.FParam.CP9 * (1 - math.exp(herb_class.FParam.CP10 * (1 - RA)))) MEc = (MEc_num1 * MEc_num2 * MEc_num3) / herb_class.FParam.CK8 Pc_1 = herb_class.FParam.CP11 * (herb_class.FParam.CP5 * BW) * BC_foet Pc_2 = ((herb_class.FParam.CP12 * herb_class.FParam.CP13) / herb_class.FParam.CP1) Pc_3 = herb_class.FParam.CP13 * (1 - RA) Pc_4 = (herb_class.FParam.CP12 * (1 - math.exp(herb_class.FParam.CP13 * (1 - RA)))) Pc_5 = math.exp(Pc_3 + Pc_4) Pc = Pc_1 * Pc_2 * Pc_5
import numpy as np grass1 = { 'label': 'grass1', 'type': 'C4', # 'C3' or 'C4' 'DMD_green': 0.541, 'DMD_dead': 0.541, 'cprotein_green': 0.023, 'cprotein_dead': 0.023, 'green_gm2': 2000., 'dead_gm2': 2000., 'percent_biomass': 1., } grass_list = [grass1] total_SD = 1. site = forage.SiteInfo(total_SD, 1., -3.5) prop_legume = 0.0 breed = 'Brahman' # see documentation for allowable breeds; assumed to apply to all animal classes sex = 'castrate' # right now, we only deal with steers A = 225. # initial age (days) W = 161. # initial weight (Rubanza et al 2005) herd_size = 1 DOY_start = 213 outdir = 'C:\Users\Ginger\Dropbox\NatCap_backup\Forage_model\Forage_model\Verification_calculations\Sensitivity\SRW' time_step = 'day' force_supp = False forage.set_time_step(time_step) steps = 10 FParam = FreerParam.FreerParam(forage.get_general_breed(breed))
def different_diets(available_forage, herbivore_csv, weight_1): """Create different diets for two hypothetical animal types. The weight ratio describes the ratio of """ time_step = 'month' forage_u.set_time_step(time_step) total_SD = 2 prop_legume = 0 DOY = 100 supp_available = 0 site = forage_u.SiteInfo(1., -3.25) supp_csv = "C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/Forage_model/model_inputs/Shem_et_al_1995_supp.csv" supp_list = (pandas.read_csv(supp_csv)).to_dict(orient='records') supp_info = supp_list[0] supp = forage_u.Supplement(FreerParam.FreerParamCattle('indicus'), supp_info['digestibility'], supp_info['kg_per_day'], supp_info['M_per_d'], supp_info['ether_extract'], supp_info['crude_protein'], supp_info['rumen_degradability']) herbivore_input = (pandas.read_csv(herbivore_csv)).to_dict( orient='records') herbivore_list = [] for h_class in herbivore_input: herd = forage_u.HerbivoreClass(h_class) herd.update() herbivore_list.append(herd) avail_weights = [weight_1, 0] qual_weights = [0, weight_1] diet_dict = {} for idx in xrange(len(herbivore_list)): herb_class = herbivore_list[idx] f_w = avail_weights[idx] rq_w = qual_weights[idx] herb_class.calc_distance_walked(total_SD, site.S, available_forage) max_intake = herb_class.calc_max_intake() ZF = herb_class.calc_ZF() HR = forage_u.calc_relative_height(available_forage) diet = diet_selection_t2(ZF, HR, prop_legume, supp_available, supp, max_intake, herb_class.FParam, available_forage, idx, f_w, rq_w) diet_interm = forage_u.calc_diet_intermediates(diet, supp, herb_class, site, prop_legume, DOY) # if herb_class.type != 'hindgut_fermenter': # reduced_max_intake = forage_u.check_max_intake(diet, # diet_interm, # herb_class, # max_intake) # if reduced_max_intake < max_intake: # diet = forage_u.diet_selection_t2(ZF, HR, # args[u'prop_legume'], # supp_available, supp, # reduced_max_intake, # herb_class.FParam, # available_forage) diet_dict[herb_class.label] = diet return diet_dict # forage_u.reduce_demand(diet_dict, stocking_density_dict, # available_forage) diet_interm = forage_u.calc_diet_intermediates(diet, supp, herb_class, site, prop_legume, DOY) delta_W = forage_u.calc_delta_weight(diet_interm, herb_class) delta_W_step = forage_u.convert_daily_to_step(delta_W) herb_class.update(delta_weight=delta_W_step, delta_time=forage_u.find_days_per_step())
def run_test(): SRW_list = np.linspace(160, 600, 9).tolist() total_SD = 1. site = forage.SiteInfo(1., -3.25) prop_legume = 0.0 supp_available = 0 breed = 'Ayrshire' sex = 'entire_m' herd_size = 1 DOY_start = 1 outdir = r'C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/Forage_model/Verification_calculations/Shem_et_al_1995/revisions_10_12/summary_unsupplemented' if not os.path.exists(outdir): os.makedirs(outdir) time_step = 'day' forage.set_time_step(time_step) supp_csv = "C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/Forage_model/model_inputs/Shem_et_al_1995_supp.csv" herbivore_csv = "C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/Forage_model/model_inputs/herbivore_Shem_et_al.csv" grass_csv = "C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/Forage_model/model_inputs/grasses_Shem_et_al_1995.csv" grass_list = (pandas.read_csv(grass_csv)).to_dict(orient='records') out_name = os.path.join(outdir, "summary.csv") supp_list = (pandas.read_csv(supp_csv)).to_dict(orient='records') supp_info = supp_list[0] supp = forage.Supplement(FreerParam.FreerParamCattle('indicus_x_taurus'), supp_info['digestibility'], supp_info['kg_per_day'], supp_info['M_per_d'], supp_info['ether_extract'], supp_info['crude_protein'], supp_info['rumen_degradability']) if supp.DMO > 0.: supp_available = 1 supp_available = 0 # change to allow supplementation with open(out_name, 'wb') as out: writer = csv.writer(out, delimiter=',') header = ['red_max_intake', 'max_intake', 'intake_forage', 'intake_supp', 'daily_gain', 'grass_label', 'step', 'study', 'SRW'] writer.writerow(header) for SRW in SRW_list: modify_SRW(herbivore_csv, SRW) herbivore_input = (pandas.read_csv(herbivore_csv)).to_dict(orient='records') for grass in grass_list: one_grass = [grass] available_forage = forage.calc_feed_types(one_grass) herbivore_list = [] for h_class in herbivore_input: herd = forage.HerbivoreClass(h_class) herd.update() herbivore_list.append(herd) print "beginning weight: " + str(herd.W) print "beginning BC: " + str(herd.BC) print "SRW: " + str(herd.SRW) for step in xrange(60): DOY = DOY_start + step row = forage.one_step(site, DOY, herd, available_forage, prop_legume, supp_available, supp) row.append(grass['label']) row.append(step) row.append('Schem_et_al') row.append(SRW) writer.writerow(row)
def launch_model(herb_csv, grass_list, outdir): f_args = { 'latitude': 0.02759, 'prop_legume': 0.0, 'steepness': 1., 'DOY': 1, 'start_year': 2015, 'start_month': 1, 'num_months': 1, 'mgmt_threshold': 0., 'century_dir': 'C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/CENTURY4.6/Century46_PC_Jan-2014', 'outdir': outdir, 'template_level': 'GH', 'fix_file': 'drytrpfi.100', 'user_define_protein': 1, 'user_define_digestibility': 0, 'herbivore_csv': herb_csv, 'supp_csv': "C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/Forage_model/model_inputs/Rubanza_et_al_2005_supp.csv", 'restart_yearly': 0, 'diet_verbose': 1, } now_str = datetime.now().strftime("%Y-%m-%d--%H_%M_%S") if not os.path.exists(f_args['outdir']): os.makedirs(f_args['outdir']) forage.write_inputs_log(f_args, now_str) forage.set_time_step('month') # current default, enforced by CENTURY add_event = 1 # TODO should this ever be 0? steps_per_year = forage.find_steps_per_year() if f_args['diet_verbose']: master_diet_dict = {} diet_segregation_dict = {'step': [], 'segregation': []} herbivore_list = [] if f_args[u'herbivore_csv'] is not None: herbivore_input = (pandas.read_csv( f_args[u'herbivore_csv'])).to_dict(orient='records') for h_class in herbivore_input: herd = forage.HerbivoreClass(h_class) herd.update() BC = 1 # TODO get optional BC from user # if BC: # herd.check_BC(BC) herbivore_list.append(herd) results_dict = {'step': [], 'year': [], 'month': []} for h_class in herbivore_list: results_dict[h_class.label + '_kg'] = [] results_dict[h_class.label + '_gain_kg'] = [] results_dict[h_class.label + '_intake_forage_per_indiv_kg'] = [] if h_class.sex == 'lac_female': results_dict['milk_prod_kg'] = [] results_dict['total_offtake'] = [] supp_available = 0 if 'supp_csv' in f_args.keys(): supp_list = (pandas.read_csv( f_args[u'supp_csv'])).to_dict(orient='records') assert len(supp_list) == 1, "Only one supplement type is allowed" supp_info = supp_list[0] supp = forage.Supplement(FreerParam.FreerParamCattle('indicus'), supp_info['digestibility'], supp_info['kg_per_day'], supp_info['M_per_d'], supp_info['ether_extract'], supp_info['crude_protein'], supp_info['rumen_degradability']) if supp.DMO > 0.: supp_available = 1 stocking_density_dict = forage.populate_sd_dict(herbivore_list) total_SD = forage.calc_total_stocking_density(herbivore_list) site = forage.SiteInfo(f_args[u'steepness'], f_args[u'latitude']) threshold_exceeded = 0 try: for step in xrange(f_args[u'num_months']): step_month = f_args[u'start_month'] + step if step_month > 12: mod = step_month % 12 if mod == 0: month = 12 else: month = mod else: month = step_month year = (step / 12) + f_args[u'start_year'] if month == 1 and f_args['restart_yearly'] and \ f_args[u'herbivore_csv'] is not None: threshold_exceeded = 0 herbivore_list = [] for h_class in herbivore_input: herd = forage.HerbivoreClass(h_class) herd.update() herbivore_list.append(herd) # get biomass and crude protein for each grass type available_forage = forage.calc_feed_types(grass_list) results_dict['step'].append(step) results_dict['year'].append(year) results_dict['month'].append(month) if not f_args[u'user_define_digestibility']: for feed_type in available_forage: feed_type.calc_digestibility_from_protein() total_biomass = forage.calc_total_biomass(available_forage) if step == 0: # threshold biomass, amount of biomass required to be left # standing (kg per ha) threshold_biomass = total_biomass * float( f_args[u'mgmt_threshold']) diet_dict = {} for herb_class in herbivore_list: herb_class.calc_distance_walked(total_SD, site.S, available_forage) max_intake = herb_class.calc_max_intake() ZF = herb_class.calc_ZF() HR = forage.calc_relative_height(available_forage) diet = forage.diet_selection_t2(ZF, HR, f_args[u'prop_legume'], supp_available, supp, max_intake, herb_class.FParam, available_forage, herb_class.f_w, herb_class.q_w) diet_interm = forage.calc_diet_intermediates( diet, supp, herb_class, site, f_args[u'prop_legume'], f_args[u'DOY']) if herb_class.type != 'hindgut_fermenter': reduced_max_intake = forage.check_max_intake( diet, diet_interm, herb_class, max_intake) if reduced_max_intake < max_intake: diet = forage.diet_selection_t2( ZF, HR, f_args[u'prop_legume'], supp_available, supp, reduced_max_intake, herb_class.FParam, available_forage) diet_dict[herb_class.label] = diet forage.reduce_demand(diet_dict, stocking_density_dict, available_forage) if f_args['diet_verbose']: # save diet_dict across steps to be written out later master_diet_dict[step] = diet_dict # diet_segregation = forage.calc_diet_segregation(diet_dict) # diet_segregation_dict['step'].append(step) # diet_segregation_dict['segregation'].append(diet_segregation) total_intake_step = forage.calc_total_intake( diet_dict, stocking_density_dict) if (total_biomass - total_intake_step) < threshold_biomass: print "Forage consumed violates management threshold" threshold_exceeded = 1 total_intake_step = 0 for herb_class in herbivore_list: if threshold_exceeded: diet_dict[herb_class.label] = forage.Diet() diet = diet_dict[herb_class.label] # if herb_class.type != 'hindgut_fermenter': diet_interm = forage.calc_diet_intermediates( diet, supp, herb_class, site, f_args[u'prop_legume'], f_args[u'DOY']) if herb_class.sex == 'lac_female': milk_production = forage.check_milk_production( herb_class.FParam, diet_interm) milk_kg_day = herb_class.calc_milk_yield(milk_production) if threshold_exceeded: delta_W = -(forage.convert_step_to_daily(herb_class.W)) else: delta_W = forage.calc_delta_weight(diet_interm, herb_class) delta_W_step = forage.convert_daily_to_step(delta_W) herb_class.update(delta_weight=delta_W_step, delta_time=forage.find_days_per_step()) results_dict[herb_class.label + '_kg'].append(herb_class.W) results_dict[herb_class.label + '_gain_kg'].append(delta_W_step) results_dict[herb_class.label + '_intake_forage_per_indiv_kg'].append( forage.convert_daily_to_step(diet.If)) if herb_class.sex == 'lac_female': results_dict['milk_prod_kg'].append( forage.convert_daily_to_step(milk_kg_day)) results_dict['total_offtake'].append(total_intake_step) finally: if f_args['diet_verbose']: # df = pandas.DataFrame(diet_segregation_dict) # save_as = os.path.join(f_args['outdir'], 'diet_segregation.csv') # df.to_csv(save_as, index=False) for h_label in master_diet_dict[0].keys(): new_dict = {} new_dict['step'] = master_diet_dict.keys() new_dict['DMDf'] = [ master_diet_dict[step][h_label].DMDf for step in master_diet_dict.keys() ] new_dict['CPIf'] = [ master_diet_dict[step][h_label].CPIf for step in master_diet_dict.keys() ] grass_labels = master_diet_dict[0][h_label].intake.keys() for g_label in grass_labels: new_dict['intake_' + g_label] = \ [master_diet_dict[step][h_label].intake[g_label] for step in master_diet_dict.keys()] df = pandas.DataFrame(new_dict) save_as = os.path.join(f_args['outdir'], h_label + '_diet.csv') df.to_csv(save_as, index=False) filled_dict = forage.fill_dict(results_dict, 'NA') df = pandas.DataFrame(filled_dict) df.to_csv(os.path.join(f_args['outdir'], 'summary_results.csv'))
def run_simulations(): century_dir = 'C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/CENTURY4.6/Century46_PC_Jan-2014' fix_file = 'drytrpfi.100' graz_file = os.path.join(century_dir, "graz.100") site_list = ['Research', 'Loidien'] #, 'Rongai', 'Kamok'] input_dir = "C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/CENTURY4.6/Kenya/input" outer_dir = "C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/CENTURY4.6/Output/Stocking_density_test" prop_legume = 0 template_level = 'GL' herb_class_weights = "C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/CENTURY4.6/Kenya/Boran_weights.csv" sd_dir = 'C:/Users/Ginger/Dropbox/NatCap_backup/Forage_model/CENTURY4.6/Kenya/OPC_stocking_density' breed = 'Boran' steepness = 1. latitude = 0 supp_available = 0 FParam = FreerParam.FreerParam(forage.get_general_breed(breed)) supp = forage.Supplement(FParam, 0, 0, 0, 0, 0, 0) forage.set_time_step('month') add_event = 1 grass_file = "C:/Users/ginge/Dropbox/NatCap_backup/Forage_model/Forage_model/model_inputs/grass.csv" grass = (pandas.read_csv(grass_file)).to_dict(orient='records')[0] grass['DMD_green'] = 0.64 grass['DMD_dead'] = 0.64 grass['cprotein_green'] = 0.1 grass['cprotein_dead'] = 0.1 for site in site_list: spin_up_outputs = [site + '_hist_log.txt', site + '_hist.lis'] century_outputs = [site + '_log.txt', site + '.lis', site + '.bin'] filename = 'average_animals_%s_2km_per_ha.csv' % site stocking_density_file = os.path.join(sd_dir, filename) sd_df = pandas.read_table(stocking_density_file, sep=',') outdir = os.path.join(outer_dir, site) if not os.path.exists(outdir): os.makedirs(outdir) # write CENTURY bat for spin-up simulation hist_bat = os.path.join(input_dir, (site + '_hist.bat')) hist_schedule = site + '_hist.sch' hist_output = site + '_hist' cent.write_century_bat(input_dir, hist_bat, hist_schedule, hist_output, fix_file, 'outvars.txt') # write CENTURY bat for extend simulation extend_bat = os.path.join(input_dir, site + '.bat') schedule = site + '.sch' output = site extend = site + '_hist' cent.write_century_bat(century_dir, extend_bat, schedule, output, fix_file, 'outvars.txt', extend) # move CENTURY run files to CENTURY dir site_file = os.path.join(input_dir, site + '.100') weather_file = os.path.join(input_dir, site + '.wth') e_schedule = os.path.join(input_dir, site + '.sch') h_schedule = os.path.join(input_dir, site + '_hist.sch') file_list = [ hist_bat, extend_bat, e_schedule, h_schedule, site_file, weather_file ] for file in file_list: shutil.copyfile(file, os.path.join(century_dir, os.path.basename(file))) # make a copy of the original graz params and schedule file shutil.copyfile(graz_file, os.path.join(century_dir, 'graz_orig.100')) label = os.path.basename(e_schedule)[:-4] copy_name = label + '_orig.sch' shutil.copyfile(e_schedule, os.path.join(input_dir, copy_name)) # run CENTURY for spin-up up to start_year and start_month hist_bat = os.path.join(century_dir, site + '_hist.bat') century_bat = os.path.join(century_dir, site + '.bat') p = Popen(["cmd.exe", "/c " + hist_bat], cwd=century_dir) stdout, stderr = p.communicate() p = Popen(["cmd.exe", "/c " + century_bat], cwd=century_dir) stdout, stderr = p.communicate() # save copies of CENTURY outputs, but remove from CENTURY dir intermediate_dir = os.path.join(outdir, 'CENTURY_outputs_spin_up') if not os.path.exists(intermediate_dir): os.makedirs(intermediate_dir) to_move = century_outputs + spin_up_outputs for file in to_move: shutil.copyfile(os.path.join(century_dir, file), os.path.join(intermediate_dir, file)) os.remove(os.path.join(century_dir, file)) grass_list = [grass] results_dict = {'year': [], 'month': []} herbivore_input = (pandas.read_csv(herb_class_weights).to_dict( orient='records')) herbivore_list = [] for h_class in herbivore_input: results_dict[h_class['label'] + '_gain_kg'] = [] results_dict[h_class['label'] + '_offtake'] = [] results_dict['milk_prod_kg'] = [] for grass in grass_list: results_dict[grass['label'] + '_green_kgha'] = [] results_dict[grass['label'] + '_dead_kgha'] = [] results_dict['total_offtake'] = [] results_dict['stocking_density'] = [] try: for row in xrange(len(sd_df)): herbivore_list = [] for h_class in herbivore_input: herd = forage.HerbivoreClass(FParam, breed, h_class['weight'], h_class['sex'], h_class['age'], h_class['stocking_density'], h_class['label'], Wbirth=24) herd.update(FParam, 0, 0) herbivore_list.append(herd) for h_class in herbivore_list: h_class.stocking_density = sd_df.iloc[row][h_class.label] total_SD = forage.calc_total_stocking_density(herbivore_list) results_dict['stocking_density'].append(total_SD) siteinfo = forage.SiteInfo(total_SD, steepness, latitude) month = sd_df.iloc[row].month year = sd_df.iloc[row].year suf = '%d-%d' % (month, year) DOY = month * 30 # get biomass and crude protein for each grass type from CENTURY output_file = os.path.join(intermediate_dir, site + '.lis') outputs = cent.read_CENTURY_outputs(output_file, year, year + 2) target_month = cent.find_prev_month(year, month) grass['prev_g_gm2'] = grass['green_gm2'] grass['prev_d_gm2'] = grass['dead_gm2'] grass['green_gm2'] = outputs.loc[target_month, 'aglivc'] grass['dead_gm2'] = outputs.loc[target_month, 'stdedc'] grass['cprotein_green'] = ( outputs.loc[target_month, 'aglive1'] / outputs.loc[target_month, 'aglivc']) grass['cprotein_dead'] = ( outputs.loc[target_month, 'stdede1'] / outputs.loc[target_month, 'stdedc']) if row == 0: available_forage = forage.calc_feed_types(grass_list) else: available_forage = forage.update_feed_types( grass_list, available_forage) results_dict['year'].append(year) results_dict['month'].append(month) for feed_type in available_forage: results_dict[feed_type.label + '_' + feed_type.green_or_dead + '_kgha'].append( feed_type.biomass) siteinfo.calc_distance_walked(FParam, available_forage) for feed_type in available_forage: feed_type.calc_digestibility_from_protein() total_biomass = forage.calc_total_biomass(available_forage) # Initialize containers to track forage consumed across herbivore # classes total_intake_step = 0. total_consumed = {} for feed_type in available_forage: label_string = ';'.join( [feed_type.label, feed_type.green_or_dead]) total_consumed[label_string] = 0. for herb_class in herbivore_list: max_intake = herb_class.calc_max_intake(FParam) if herb_class.Z < FParam.CR7: ZF = 1. + (FParam.CR7 - herb_class.Z) else: ZF = 1. if herb_class.stocking_density > 0: adj_forage = forage.calc_adj_availability( available_forage, herb_class.stocking_density) else: adj_forage = list(available_forage) diet = forage.diet_selection_t2(ZF, prop_legume, supp_available, supp, max_intake, FParam, adj_forage) diet_interm = forage.calc_diet_intermediates( FParam, diet, supp, herb_class, siteinfo, prop_legume, DOY) reduced_max_intake = forage.check_max_intake( FParam, diet, diet_interm, herb_class, max_intake) if reduced_max_intake < max_intake: diet = forage.diet_selection_t2( ZF, prop_legume, supp_available, supp, reduced_max_intake, FParam, adj_forage) diet_interm = forage.calc_diet_intermediates( FParam, diet, supp, herb_class, siteinfo, prop_legume, DOY) total_intake_step += ( forage.convert_daily_to_step(diet.If) * herb_class.stocking_density) if herb_class.sex == 'lac_female': milk_production = forage.check_milk_production( FParam, diet_interm) milk_kg_day = forage.calc_milk_yield( FParam, milk_production) delta_W = forage.calc_delta_weight(FParam, diet, diet_interm, supp, herb_class) delta_W_step = forage.convert_daily_to_step(delta_W) herb_class.update(FParam, delta_W_step, forage.find_days_per_step()) if herb_class.stocking_density > 0: results_dict[herb_class.label + '_gain_kg'].append(delta_W_step) results_dict[herb_class.label + '_offtake'].append( diet.If) else: results_dict[herb_class.label + '_gain_kg'].append('NA') results_dict[herb_class.label + '_offtake'].append('NA') if herb_class.sex == 'lac_female': results_dict['milk_prod_kg'].append(milk_kg_day * 30.) # after have performed max intake check, we have the final diet # selected # calculate percent live and dead removed for each grass type consumed_by_class = forage.calc_percent_consumed( available_forage, diet, herb_class.stocking_density) forage.sum_percent_consumed(total_consumed, consumed_by_class) results_dict['total_offtake'].append(total_intake_step) # send to CENTURY for this month's scheduled grazing event date = year + float('%.2f' % (month / 12.)) schedule = os.path.join(century_dir, site + '.sch') target_dict = cent.find_target_month(add_event, schedule, date, 1) if target_dict == 0: er = "Error: no opportunities exist to add grazing event" raise Exception(er) new_code = cent.add_new_graz_level(grass, total_consumed, graz_file, template_level, outdir, suf) cent.modify_schedule(schedule, add_event, target_dict, new_code, outdir, suf) # call CENTURY from the batch file century_bat = os.path.join(century_dir, site + '.bat') p = Popen(["cmd.exe", "/c " + century_bat], cwd=century_dir) stdout, stderr = p.communicate() # save copies of CENTURY outputs, but remove from CENTURY dir intermediate_dir = os.path.join( outdir, 'CENTURY_outputs_m%d_y%d' % (month, year)) if not os.path.exists(intermediate_dir): os.makedirs(intermediate_dir) for file in century_outputs: shutil.copyfile(os.path.join(century_dir, file), os.path.join(intermediate_dir, file)) os.remove(os.path.join(century_dir, file)) # remove files from CENTURY directory finally: # replace graz params used by CENTURY with original file os.remove(graz_file) shutil.copyfile(os.path.join(century_dir, 'graz_orig.100'), graz_file) os.remove(os.path.join(century_dir, 'graz_orig.100')) files_to_remove = [ os.path.join(century_dir, os.path.basename(f)) for f in file_list ] for file in files_to_remove: os.remove(file) os.remove(os.path.join(century_dir, site + '_hist.bin')) filled_dict = forage.fill_dict(results_dict, 'NA') df = pandas.DataFrame(filled_dict) df.to_csv(os.path.join(outdir, 'summary_results.csv'))
import csv grass1 = { 'label': 'grass1', 'type': 'C4', # 'C3' or 'C4' 'DMD_green': 0.541, 'DMD_dead': 0.541, 'cprotein_green': 0.023, 'cprotein_dead': 0.023, 'green_gm2': 2000., 'dead_gm2': 2000., 'percent_biomass': 1., } grass_list = [grass1] total_SD = 1. site = forage.SiteInfo(1., -3.5) prop_legume = 0.0 breed = 'Brahman' # see documentation for allowable breeds; assumed to apply to all animal classes sex = 'castrate' # right now, we only deal with steers A = 225. # initial age (days) W = 161. # initial weight (Rubanza et al 2005) herd_size = 1 Wbirth = 34.7 SRW = 297 DOY_start = 213 outdir = r'C:\Users\Ginger\Dropbox\NatCap_backup\Forage_model\Forage_model\Verification_calculations\Rubanza_et_al_2005' time_step = 'day' force_supp = False forage.set_time_step(time_step) available_forage = forage.calc_feed_types(grass_list)
def calc_equivalent_intake(): """Calculate the approximately equivalent amount of one feed type that would need to be eaten to replace another. For example, how much hay would be nutritionally equivalent to a given amount of forage, in terms of liveweight gain?""" def calc_liveweight(site, herb_class, available_forage): supp_available = 0 DOY = 150 prop_legume = 0 herb_class.calc_distance_walked(site.S, herb_class.stocking_density, available_forage) max_intake = herb_class.calc_max_intake() ZF = herb_class.calc_ZF() HR = forage_u.calc_relative_height(available_forage) diet = forage_u.diet_selection_t2(ZF, HR, prop_legume, supp_available, max_intake, herb_class.FParam, available_forage) diet_interm = forage_u.calc_diet_intermediates(diet, herb_class, prop_legume, DOY, site) reduced_max_intake = forage_u.check_max_intake(diet, diet_interm, herb_class, max_intake) if reduced_max_intake < max_intake: diet = forage_u.diet_selection_t2(ZF, HR, prop_legume, supp_available, reduced_max_intake, herb_class.FParam, available_forage) diet_interm = forage_u.calc_diet_intermediates( diet, herb_class, prop_legume, DOY, site) delta_W = forage_u.calc_delta_weight(diet_interm, herb_class) return delta_W grass_gm2 = 87. # does it matter? forage_args = default_forage_args() site = forage_u.SiteInfo(1., 44.6) grass_csv = r"C:\Users\ginge\Dropbox\NatCap_backup\WitW\model_inputs\Ucross\grass_high_quality_only.csv" hay_csv = r"C:\Users\ginge\Dropbox\NatCap_backup\WitW\model_inputs\Ucross\Merlin_hay.csv" herb_csv = forage_args['herbivore_csv'] h_class = (pd.read_csv( forage_args[u'herbivore_csv'])).to_dict(orient='records')[0] herd = forage_u.HerbivoreClass(h_class) herd.update() # get liveweight from grass grass_list = (pd.read_csv(grass_csv)).to_dict(orient='records') for grass in grass_list: grass['green_gm2'] = grass_gm2 grass['dead_gm2'] = grass_gm2 * 0.5 available_forage = forage_u.calc_feed_types(grass_list) for feed_type in available_forage: feed_type.calc_digestibility_from_protein( forage_args['digestibility_flag']) grass_liveweight = calc_liveweight(site, herd, available_forage) # try n times to match liveweight with hay, given a tolerance, and changing # the amount of hay supplied hay_list = (pd.read_csv(hay_csv)).to_dict(orient='records') tolerance = 10. hay_liveweight = 0 upper_bound = grass_gm2 * 2. lower_bound = grass_gm2 / 2. n = 1 while n < 15: for hay in hay_list: hay['green_gm2'] = upper_bound hay['dead_gm2'] = upper_bound * 0.5 available_forage = forage_u.calc_feed_types(hay_list) for feed_type in available_forage: feed_type.calc_digestibility_from_protein( forage_args['digestibility_flag']) hay_upper_lw = calc_liveweight(site, herd, available_forage) if (grass_liveweight - hay_upper_lw) > tolerance: raise Exception, "upper bound hay gm2 is too low" for hay in hay_list: hay['green_gm2'] = lower_bound hay['dead_gm2'] = lower_bound * 0.5 available_forage = forage_u.calc_feed_types(hay_list) for feed_type in available_forage: feed_type.calc_digestibility_from_protein( forage_args['digestibility_flag']) hay_lower_lw = calc_liveweight(site, herd, available_forage) if (hay_lower_lw - grass_liveweight) > tolerance: raise Exception, "lower bound hay gm2 is too high" if (hay_upper_lw - grass_liveweight) > (grass_liveweight - hay_lower_lw): upper_bound = lower_bound + ((upper_bound - lower_bound) / 2.) else: lower_bound = lower_bound + ((upper_bound - lower_bound) / 2.) n = n + 1 print "Hay biomass: between {} and {}".format(lower_bound, upper_bound) print """liveweight gain: {0:.3f} (grass), {0:.3f} (hay upper bound), {0:.3f} (hay lower bound)""".format(grass_liveweight, hay_upper_lw, hay_lower_lw)