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
def one_step(FParam, DOY, herd, available_forage, prop_legume, supp_available, supp, intake=None): """One step of the forage model, if available forage does not change.""" row = [] max_intake = herd.calc_max_intake(FParam) if herd.Z < FParam.CR7: ZF = 1. + (FParam.CR7 - herd.Z) else: ZF = 1. if intake is not None: # if forage intake should be forced diet = forage.Diet() diet.If = intake diet.DMDf = available_forage[0].digestibility # this is super hack-y diet.CPIf = intake * available_forage[ 0].crude_protein # and only works with one type of available forage diet.Is = supp.DMO # also force intake of all supplement offered diet_interm = forage.calc_diet_intermediates(FParam, diet, supp, herd, site, prop_legume, DOY) else: diet = forage.diet_selection_t2(ZF, prop_legume, supp_available, supp, max_intake, FParam, available_forage, force_supp) diet_interm = forage.calc_diet_intermediates(FParam, diet, supp, herd, site, prop_legume, DOY) reduced_max_intake = forage.check_max_intake(FParam, diet, diet_interm, herd, max_intake) if reduced_max_intake < max_intake: diet = forage.diet_selection_t2(ZF, prop_legume, supp_available, supp, reduced_max_intake, FParam, available_forage, force_supp) diet_interm = forage.calc_diet_intermediates( FParam, diet, supp, herd, site, prop_legume, DOY) delta_W = forage.calc_delta_weight(FParam, diet, diet_interm, supp, herd) #delta_W_step = forage.convert_daily_to_step(delta_W) herd.update(FParam, delta_W, forage.find_days_per_step()) row.append(max_intake) row.append(diet.If) row.append(diet.Is) row.append(diet.CPIf) row.append(diet_interm.MEItotal) row.append(delta_W) return row
def one_step(FParam, DOY, herd, available_forage, prop_legume, supp_available, supp): """One step of the forage model, if available forage does not change.""" row = [] row.append(available_forage[0].label) max_intake = herd.calc_max_intake(FParam) if herd.Z < FParam.CR7: ZF = 1. + (FParam.CR7 - herd.Z) else: ZF = 1. diet = forage.diet_selection_t2(ZF, prop_legume, supp_available, supp, max_intake, FParam, available_forage) diet_interm = forage.calc_diet_intermediates(FParam, diet, supp, herd, site, prop_legume, DOY) reduced_max_intake = forage.check_max_intake(FParam, diet, diet_interm, herd, max_intake) if reduced_max_intake < max_intake: diet = forage.diet_selection_t2(ZF, prop_legume, supp_available, supp, reduced_max_intake, FParam, available_forage) diet_interm = forage.calc_diet_intermediates(FParam, diet, supp, herd, site, prop_legume, DOY) delta_W = forage.calc_delta_weight(FParam, diet, diet_interm, supp, herd) row.append(herd.W) row.append(max_intake) row.append(reduced_max_intake) row.append(diet.If) row.append(diet.CPIf) row.append(diet_interm.MEItotal) row.append(delta_W) #delta_W_step = forage.convert_daily_to_step(delta_W) herd.update(FParam, delta_W, forage.find_days_per_step()) return row
def diet_selection(forage_args, live_gm2, dead_gm2): """Perform diet selection on forage, as a metric of forage quality. Return diet selected by an individual animal from the forage available as described by live_gm2 and dead_gm2. Assume that digestibility of forage is calculated from crude protein, and crude protein is specified in the grass csv (i.e. fixed).""" forage_u.set_time_step('month') herbivore_list = [] herbivore_input = (pd.read_csv(forage_args['herbivore_csv']).to_dict( orient='records')) for h_class in herbivore_input: herd = forage_u.HerbivoreClass(h_class) herd.update() herbivore_list.append(herd) stocking_density_dict = forage_u.populate_sd_dict(herbivore_list) total_SD = forage_u.calc_total_stocking_density(herbivore_list) grass_list = (pd.read_csv(forage_args['grass_csv'])).to_dict(orient='records') assert len(grass_list) == 1, "Must be one grass type" grass_list[0]['green_gm2'] = live_gm2 grass_list[0]['dead_gm2'] = dead_gm2 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']) # TODO n_mult?? assert len(herbivore_list) == 1, "must be one herbivore type" herb_class = herbivore_list[0] herb_class.calc_distance_walked(1., total_SD, 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, 0., 0, max_intake, herb_class.FParam, available_forage, herb_class.f_w, herb_class.q_w) diet_interm = forage_u.calc_diet_intermediates(diet, herb_class, 0., 150) 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, 0., 0, max_intake, herb_class.FParam, available_forage, herb_class.f_w, herb_class.q_w) return diet
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 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'))
def one_step(site, DOY, herb_class, available_forage, prop_legume, supp_available, supp, intake=None, force_supp=None): """One step of the forage model, if available forage does not change.""" row = [] row.append(supp.DMO) herb_class.calc_distance_walked(herb_class.stocking_density, site.S, available_forage) max_intake = herb_class.calc_max_intake() ZF = herb_class.calc_ZF() HR = forage.calc_relative_height(available_forage) if intake is not None: # if forage intake should be forced diet = forage.Diet() diet.If = intake diet.DMDf = available_forage[0].digestibility # this is super hack-y diet.CPIf = intake * available_forage[ 0].crude_protein # and only works with one type of available forage diet.Is = supp.DMO # also force intake of all supplement offered diet_interm = forage.calc_diet_intermediates(diet, supp, herb_class, site, prop_legume, DOY) row.append('NA') else: diet = forage.diet_selection_t2(ZF, HR, prop_legume, supp_available, supp, max_intake, herb_class.FParam, available_forage, force_supp) diet_interm = forage.calc_diet_intermediates(diet, supp, herb_class, site, prop_legume, DOY) if herb_class.type != 'hindgut_fermenter': reduced_max_intake = forage.check_max_intake( diet, diet_interm, herb_class, max_intake) row.append(reduced_max_intake) if reduced_max_intake < max_intake: diet = forage.diet_selection_t2(ZF, HR, prop_legume, supp_available, supp, reduced_max_intake, herb_class.FParam, available_forage, force_supp) diet_interm = forage.calc_diet_intermediates( diet, supp, herb_class, site, prop_legume, DOY) delta_W = forage.calc_delta_weight(diet_interm, herb_class) delta_W_step = forage.convert_daily_to_step(delta_W) herd_t1 = forage.HerdT1(herb_class.W, 297) maint_t1 = herd_t1.e_maintenance() delta_W_t1 = herd_t1.e_allocate(diet_interm.MEItotal, maint_t1, 'moderate') herb_class.update(delta_weight=delta_W_step, delta_time=forage.find_days_per_step()) row.append(max_intake) row.append(diet.If) row.append(diet.Is) row.append(diet.CPIf) row.append(diet_interm.MEItotal) row.append(delta_W) row.append(delta_W_t1) return row