allfed / allfed-integrated-model

Integrated model to calculate the effects of resilient foods in catastrophic events
https://allfed.github.io/allfed-integrated-model/
GNU General Public License v3.0
11 stars 10 forks source link

unsure if CalculateAnimalOutputs is being used properly #106

Closed k-r-a-s-s closed 1 year ago

k-r-a-s-s commented 1 year ago

I can only find CalculateAnimalOutputs referenced in: /allfed-integrated-model/src/food_system/calculate_animals_and_feed_over_time.py and in the parameters.py

but the parameters only calls: feed_dairy_meat_results = ( coa.calculate_feed_and_animals_using_baseline_feed_usage( reduction_in_beef_calves=90, reduction_in_dairy_calves=reduction_in_dairy_calves, reduction_in_pig_breeding=90, reduction_in_poultry_breeding=90, increase_in_slaughter=110, months=constants_inputs["NMONTHS"], discount_rate=30, mother_slaughter=0, use_grass_and_residues_for_dairy=use_grass_and_residues_for_dairy, baseline_kcals_per_month_feed=feed_per_month_baseline, ) ) I don’t understand what this baseline thing is, and how this compares to the 'normal' , 'non baseline' function. I also don’t see any other call to calculate_feed_and_animals And the weirdest thing: if I comment out the feed_dairy_meat_results lines, the model still runs. It’s as if it’s not even using the slaughter stuff!

Is there a reference I am missing? If not, it seems that Calculate Animal feeds is not being called, but this doesn't seem right either.

morganrivers commented 1 year ago

feed_per_month_baseline is the feed in billions of kcals that animals in the US consume per month before there is a nuclear winter. The idea with this was that it could be used to calculate the tons feed to kcals feed conversion (kcals / ton for feed, the caloric density). But, the code is no longer doing that it seems. I got rid of that part, because tons_to_kcals_first_try =((3560 + 3350) / 2 * 1000 ) was close enough to the correct answer that I didn't want to add the additional complication of running the function twice. So feed_per_month_baseline is no longer used.

If you were to comment out feed_dairy_meat_results = ( coa.calculate_feed_and_animals_using_baseline_feed_usage( reduction_in_beef_calves=90, reduction_in_dairy_calves=reduction_in_dairy_calves, reduction_in_pig_breeding=90, reduction_in_poultry_breeding=90, increase_in_slaughter=110, months=constants_inputs["NMONTHS"], discount_rate=30, mother_slaughter=0, use_grass_and_residues_for_dairy=use_grass_and_residues_for_dairy, baseline_kcals_per_month_feed=feed_per_month_baseline, ) )

then feed_dairy_meat_results will not be assigned anything, and when it is called to determine the meat and dairy, it should throw an error. The most likely problem is that you are running a scenario that does not call the slaughter stuff. I suggest running the run_USA_with_improved_numbers.py and adding some print statements to be sure the init_meat_and_dairy_and_feed_from_breeding function is being run.

In summary, you can remove the baseline line and put this code in, it will work fine (it will having a slight difference between feed usage before and at the start of the nuclear winter due to a slightly different baseline kcals per month).

def calculate_feed_and_animals_using_baseline_feed_usage(
    self,
    reduction_in_beef_calves,
    reduction_in_dairy_calves,
    increase_in_slaughter,
    reduction_in_pig_breeding,
    reduction_in_poultry_breeding,
    months,
    discount_rate,
    mother_slaughter,
    use_grass_and_residues_for_dairy,
):
    """
    assign the caloric density to a reasonable value then call the rest of the function to calculate animal and dairy outputs.
    The baseline calculation for continuity purposes has been fully removed from this function.
    """

    tons_to_kcals = (
        (3560 + 3350) / 2 * 1000
    )  # convert tons to kcals (ASSUME CALORIC DENSITY IS HALF MAIZE, HALF SOYBEAN)

    feed_over_time_final = self.calculate_feed_and_animals(
        reduction_in_beef_calves=reduction_in_beef_calves,
        reduction_in_dairy_calves=reduction_in_dairy_calves,
        reduction_in_pig_breeding=reduction_in_pig_breeding,
        reduction_in_poultry_breeding=reduction_in_poultry_breeding,
        increase_in_slaughter=increase_in_slaughter,
        months=months,
        discount_rate=discount_rate,
        mother_slaughter=mother_slaughter,
        use_grass_and_residues_for_dairy=use_grass_and_residues_for_dairy,
        tons_to_kcals=tons_to_kcals,
    )
    return feed_over_time_final
morganrivers commented 1 year ago

The equation that was happening before was something like this: baseline_kcals_per_month_feed was passed in from FAOSTAT data. call calculate_feed_and_animals once and obtain feed usage in tons, this was assigned to a variable with a name like calibration_feed_tons_first_month then, the function was doing a calculation like

tons_to_kcals = baseline_kcals_per_month_feed[0]/calibration_feed_tons_first_month

in order to have a more accurate number than tons_to_kcals = ((3560 + 3350) / 2 * 1000) which is just a guess based on the caloric density of maize and soybean

however, running through this process I found ((3560 + 3350) / 2 * 1000) was actually pretty close to the right answer after all, and removed that first call to calculate_feed_and_animals for calibration at some point.

hopefully that makes more sense why the code is like how it is now

morganrivers commented 1 year ago

we figured it out. running the wrong scenario was the main problem

had to run run_USA_with_improved_numbers.py