Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

revision of SCP implementation for milk and meat alternatives #698

Merged
merged 12 commits into from
Jul 23, 2024

Conversation

flohump
Copy link
Contributor

@flohump flohump commented Jul 12, 2024

🐦 Description of this PR 🐦

  • 15_food revision of MP/SCP implementation for milk and meat alternatives. Added demand for fat and sugar as ingredients for MP-based milk alternatives. Added optional demand for fat as ingredient for MP-based meat alternatives.

🔧 Checklist for PR creator 🔧

  • Label pull request from the label list.

    • Low risk: Simple bugfixes (missing files, updated documentation, typos) or changes in start or output scripts
    • Medium risk: Uncritical changes in the model core (e.g. moderate modifications in non-default realizations)
    • High risk: Critical changes in model core or default settings (e.g. changing a model default or adjusting a core mechanic in the model)
  • Self-review own code

    • No hard coded numbers and cluster/country/region names.
    • The new code doesn't contain declared but unused parameters or variables.
    • magpie4 R library has been updated accordingly and backwards compatible where necessary.
    • scenario_config.csv has been updated accordingly (important if default.cfg has been updated)
  • Document changes

    • Add changes to CHANGELOG.md
    • Where relevant, put In-code documentation comments
    • Properly address updates in interfaces in the module documentations
    • run goxygen::goxygen() and verify the modified code is properly documented
  • Perform test runs

    • Low risk:
      • Run a compilation check via Rscript start.R --> "compilation check"
    • Medium risk:
      • Run test runs via Rscript start.R --> "test runs"
      • Check logs for errors/warnings
    • High risk:
      • Run test runs via Rscript start.R --> "test runs"
      • Check logs for errors/warnings
      • Default run from the PR target branch for comparison
      • Provide relevant comparison plots (land-use, emissions, food prices, land-use intensity,...)

📉 Performance changes 📈

  • Current develop branch default : ** mins
  • This PR's default : ** mins

🚨 Checklist for reviewer 🚨

  • PR is labeled correctly
  • Code changes look reasonable
    • No hard coded numbers and cluster/country/region names.
    • No unnecessary increase in module interfaces
    • model behavior/performance is satisfactory.
  • Changes are properly documented
    • CHANGELOG is updated correctly
    • Updates in interfaces have been properly addressed in the module documentations
    • In-code documentation looks appropriate
  • content review done (at least 1)
  • RSE review done (at least 1)

@flohump flohump added enhancement New feature or request Low risk Low risk labels Jul 12, 2024
@flohump flohump added Medium risk and removed Low risk Low risk labels Jul 12, 2024
s15_scp_protein_per_milk protein needed as ingredient for scp milk (mass per 100g milk) / 3.3 /
s15_scp_fat_to_kcal conversion factor (kcal per gram of fat) / 8.79 /
s15_scp_sugar_to_kcal conversion factor (kcal per gram of sugar) / 3.87 /
s15_scp_protein_to_kcal conversion factor (kcal per gram of protein) / 4.27 /
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s15_scp_fat_to_kcal , s15_scp_sugar_to_kcal, s15_scp_protein_to_kcal these are the specific conversion factors for milk. It would be worth clarifying this in the scalar name. If demand for sugar and oil is also implemented for meat, then this too would have a specific caloric conversion factors that are different from milk.

Copy link
Member

@tscheypidi tscheypidi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one comment concerning the used units where a different unit and/or a better unit description could be helpful

@@ -183,7 +184,12 @@ parameters
;

scalars
s15_year Current year as integer value (yr) / 2000 /
s15_scp_fat_per_milk fat needed as ingredient for scp milk (mass per 100g milk) / 3.3 /
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the unit. Is it g/100g ?! Why not just a mass ratio (1:1)?

Copy link

@slovat slovat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one small comment regarding the naming of s15_scp_fat_to_kcal , s15_scp_sugar_to_kcal and s15_scp_protein_to_kcal, these are specific to milk, it would be worth clarifying this in their names

CHANGELOG.md Outdated
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### changed
- **21_trade** refactor equations for enhanced readablility and improve documentation
- **script** rewrite of merge_report.R based on rds files and rbind, which allows for more flexibility when merging reports. Avoid inconsistent use of "GLO" instead of "World" in report.rds files.
- **15_food** revision of SCP implementation for milk. Added demand for plant oil and sugar as ingredients for milk production using single cell protein.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:
"milk production" --> "(animal-free) milk alternative" or similar?

Comment on lines 187 to 193
s15_scp_fat_per_milk fat needed as ingredient for scp milk (g per 100g) / 3.3 /
s15_scp_sugar_per_milk sugar needed as ingredient for scp milk (g per 100g) / 4.7 /
s15_scp_protein_per_milk protein needed as ingredient for scp milk (g per 100g) / 3.3 /
s15_scp_fat_to_kcal_milk conversion factor (kcal per gram of fat) / 8.79 /
s15_scp_sugar_to_kcal_milk conversion factor (kcal per gram of sugar) / 3.87 /
s15_scp_protein_to_kcal_milk conversion factor (kcal per gram of protein) / 4.27 /
;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add information regarding dry or wet matter basis.

Comment on lines 184 to 189
s15_scp_fat_per_milk fat needed as ingredient for scp milk (g per 100g) / 3.3 /
s15_scp_sugar_per_milk sugar needed as ingredient for scp milk (g per 100g) / 4.7 /
s15_scp_protein_per_milk protein needed as ingredient for scp milk (g per 100g) / 3.3 /
s15_scp_fat_to_kcal_milk conversion factor (kcal per gram of fat) / 8.79 /
s15_scp_sugar_to_kcal_milk conversion factor (kcal per gram of sugar) / 3.87 /
s15_scp_protein_to_kcal_milk conversion factor (kcal per gram of protein) / 4.27 /
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add information regarding dry or wet matter basis.

*' Reduction of ruminant meat and dairy products (kfo_rd):
p15_kcal_pc_iso(t,iso,kfo_rd) = p15_kcal_pc_iso(t,iso,kfo_rd) * i15_rumdairy_scp_fadeout(t,iso);
*'
*' Plant oil and sugar demands as ingredients for milk production using single cell protein
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:
"milk production" --> "(animal-free) milk alternative" or similar?

p15_kcal_pc_calibrated(t,i,kfo_rd) = p15_kcal_pc_calibrated(t,i,kfo_rd) * i15_rumdairy_scp_fadeout(t,i);

*'
*' Plant oil and sugar demands as ingredients for milk production using single cell protein
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:
"milk production" --> "(animal-free) milk alternative" or similar?

p15_kcal_pc_calibrated(t,i,kfo_rd) = p15_kcal_pc_calibrated(t,i,kfo_rd) * i15_rumdairy_scp_fadeout(t,i);

*'
*' Plant oil and sugar demands as ingredients for milk production using single cell protein
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion:
"milk production" --> "(animal-free) milk alternative" or similar?

p15_kcal_pc_iso(t,iso,"oils") = p15_kcal_pc_iso(t,iso,"oils")
+ sum(kfo_rd$sameas(kfo_rd,"livst_milk"), p15_kcal_pc_iso_scp(t,iso,kfo_rd))
* (s15_scp_fat_per_milk * s15_scp_fat_to_kcal_milk) / (s15_scp_protein_per_milk * s15_scp_protein_to_kcal_milk);
*'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think '1/s15_scp_protein_to_kcal_milk' has to be replaced by 'i15_protein_to_kcal_ratio(t,"scp")' (the same for line 138 below).
The reference unit for replacement of milk with scp-milk is protein. Based on the estimation of how much scp-protein is needed to replace cow milk, we can calculate here, how much additional sugar and oil is required to create an "scp milk" with similar properties like cow milk.

Furthermore, I don't understand why the conversion factors for kcal per gram of fat and sugar should be specific for milk.

Copy link
Contributor Author

@flohump flohump Jul 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your review!
If I understand correctly, we could do the following:
Instead of
p15_kcal_pc_calibrated_scp(t,i,kfo_rd) = p15_kcal_pc_calibrated(t,i,kfo_rd) * (1-i15_rumdairy_scp_fadeout(t,i)) * i15_protein_to_kcal_ratio(t,kfo_rd) / i15_protein_to_kcal_ratio(t,"scp");
we could do
p15_protein_pc_calibrated_scp(t,i,kfo_rd) = p15_kcal_pc_calibrated(t,i,kfo_rd) * (1-i15_rumdairy_scp_fadeout(t,i)) * i15_protein_to_kcal_ratio(t,kfo_rd);
Thus keeping the unit in protein.
This would also change this calculation of p15_kcal_pc_calibrated(t,i,"scp"):
p15_kcal_pc_calibrated(t,i,"scp") = p15_kcal_pc_calibrated(t,i,"scp") + sum(kfo_rd, p15_protein_pc_calibrated_scp(t,i,kfo_rd))/i15_protein_to_kcal_ratio(t,"scp");

This would simplify the addition of oil to:
p15_kcal_pc_calibrated(t,i,"oils") = p15_kcal_pc_calibrated(t,i,"oils") + sum(kfo_rd$sameas(kfo_rd,"livst_milk"), p15_protein_pc_calibrated_scp(t,i,kfo_rd)) / s15_scp_protein_per_milk * s15_scp_fat_per_milk;

For sugar:
p15_kcal_pc_calibrated(t,i,"sugar") = p15_kcal_pc_calibrated(t,i,"sugar") + sum(kfo_rd$sameas(kfo_rd,"livst_milk"), p15_protein_pc_calibrated_scp(t,i,kfo_rd)) / s15_scp_protein_per_milk * s15_scp_sugar_per_milk;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@slovat Do you follow here?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I completely understand. If I get it right, you are saying rather than going through kcal, work with mass of protein. Based on the mass of SCP milk protein produced, calculate the amount of fat and sugar demand then based on their mass ratio with protein in milk? I.e. if I produce 20 Mt milk protein and the mass ratio of protein to fat is 1:1, I would also need 20 Mt fat?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@weindl I'm not sure what's best to use for the conversion factors for kcal per gram of fat and sugar and what level of detail is usually used in MAgPIE. We could use a generic factor of 4 kcal/g protein or sugar and 9 kcal/g fat. But if I'm not mistaken, caloric densities reflect energy available for humans and this includes something about digestability. Because different food products have different digestabilities, a gram of sugar in say milk is different than in wheat and so there is different amounts available depending on the food product. This means there are specific caloric conversion factors for differnet food products (they don't vary hugely between different products), but if this is not normally done in MAgPIE, we can just use generic factors too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @flohump Your suggestion looks good. The only thing I noticed: as long as the meaning of the scalars does not chnage, we still need 's15_scp_fat_to_kcal_milk' and 's15_scp_sugar_to_kcal_milk' to convert mass to kcal, as required by e.g. 'p15_kcal_pc_calibrated(t,i,"oils")'.

Copy link
Contributor

@jansteinhauser jansteinhauser Jul 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@flohump In general, your approach makes sense to me, but the sugar and fat equations need an additional factor at the end translating g sugar / fat to kcal. Right now, equation units would be
kcal = kcal + g protein / (g protein / 100 g milk) * g fat / 100 g milk = kcal + g fat (or g sugar, respectively)

p15_kcal_pc_calibrated(t,i,"oils") = p15_kcal_pc_calibrated(t,i,"oils") + sum(kfo_rd$sameas(kfo_rd,"livst_milk"), p15_protein_pc_calibrated_scp(t,i,kfo_rd)) / s15_scp_protein_per_milk * s15_scp_fat_per_milk * fm_nutrition_attributes(t,"oils", "kcal");

p15_kcal_pc_calibrated(t,i,"sugar") = p15_kcal_pc_calibrated(t,i,"sugar") + sum(kfo_rd$sameas(kfo_rd,"livst_milk"), p15_protein_pc_calibrated_scp(t,i,kfo_rd)) / s15_scp_protein_per_milk * s15_scp_sugar_per_milk * fm_nutrition_attributes(t, "sugar" ,"kcal");

Few fine-tuning question: Are these sugar and fat amounts / 100g the ones that are consumed at the end or the amounts that go into the SCP production process, with different amounts actually consumed?

And is it important for reporting of food profiles that we're splitting a single category (milk) into three distinct ones (SCP, sugar, oils) instead of summing these values to a single SCP kcal value?

Edit: Ah, @weindl was faster. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now

p15_kcal_pc_calibrated(t,i,"sugar") = p15_kcal_pc_calibrated(t,i,"sugar")
+ sum(kfo_rd$sameas(kfo_rd,"livst_milk"), p15_kcal_pc_calibrated_scp(t,i,kfo_rd))
* (s15_scp_sugar_per_milk * s15_scp_sugar_to_kcal_milk) / (s15_scp_protein_per_milk * s15_scp_protein_to_kcal_milk);
*'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same changes necessary as in the other module.

Copy link
Contributor

@jansteinhauser jansteinhauser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment in exodietmacro.gms. Process makes sense to me, but the suggested equations seem to need unit checking.

Copy link
Contributor

@weindl weindl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this version. Looks good!

p15_kcal_pc_iso(t,iso,"oils") = p15_kcal_pc_iso(t,iso,"oils")
+ sum(kfo_rd$sameas(kfo_rd,"livst_milk"), p15_kcal_pc_iso_scp(t,iso,kfo_rd))
* (s15_scp_fat_per_milk * s15_scp_fat_to_kcal_milk) / (s15_scp_protein_per_milk * s15_scp_protein_to_kcal_milk);
*'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now

Copy link
Contributor

@jansteinhauser jansteinhauser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, just one tiny description suggestion.

modules/15_food/anthro_iso_jun22/declarations.gms Outdated Show resolved Hide resolved
modules/15_food/anthropometrics_jan18/declarations.gms Outdated Show resolved Hide resolved
Copy link
Contributor

@jansteinhauser jansteinhauser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please double check units

config/default.cfg Show resolved Hide resolved
modules/15_food/anthro_iso_jun22/exodietmacro.gms Outdated Show resolved Hide resolved
modules/15_food/anthro_iso_jun22/input.gms Show resolved Hide resolved
modules/15_food/anthropometrics_jan18/intersolve.gms Outdated Show resolved Hide resolved
modules/15_food/anthropometrics_jan18/presolve.gms Outdated Show resolved Hide resolved
@flohump flohump changed the title revision of SCP implementation for milk revision of SCP implementation for milk and meat alternatives Jul 19, 2024
@flohump
Copy link
Contributor Author

flohump commented Jul 22, 2024

I added reporting variables for oil and sugar as inredient for scp-based met and milk alternatives in the magpie4 R library: pik-piam/magpie4@0cd8574

Copy link
Contributor

@weindl weindl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addition to the code looks good in general. I have only one comment to the naming of a new scalar.

s15_scp_fat_per_milk Fat needed as ingredient for scp-based milk alternative (g per 100g wet matter) / 3.3 /
s15_scp_sugar_per_milk Sugar needed as ingredient for scp-based milk alternative (g per 100g wet matter) / 4.7 /
s15_scp_protein_per_milk Protein needed as ingredient for scp-based milk alternative (g per 100g wet matter) / 3.3 /
s15_scp_fat_per_meat Fat content of microbial biomass based on Solein from Solar foods (t fat per t DM) / 0.05 /
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to rename the scalar 's15_scp_fat_per_meat' to better reflect its meaning ( ="fat content of microbial biomass).
For me 's15_scp_fat_per_meat' sounds like a scalar indicating how much fat is needed to produce a unit of final scp-meat product in wet matter, which is not the case.

Maybe 's15_scp_fat_content' or similar?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The renaming would also require changes in the magpie4.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. I revised the scalar name in the GAMS code and the magpie4 R library.

@flohump flohump requested a review from weindl July 22, 2024 10:32
@flohump flohump merged commit 92d984c into magpiemodel:develop Jul 23, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Medium risk
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants