Make Process commission year a RangeInclusive#1010
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #1010 +/- ##
==========================================
- Coverage 81.13% 80.99% -0.14%
==========================================
Files 52 52
Lines 6287 6299 +12
Branches 6287 6299 +12
==========================================
+ Hits 5101 5102 +1
- Misses 932 942 +10
- Partials 254 255 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
tsmbland
left a comment
There was a problem hiding this comment.
I think this seems like a cleaner approach overall
There will be a performance cost to this, because now any time you provide "all" as the year, you're going to end up cloning the data over all years in the process range, whereas before it would just be the milestone years. I don't know how significant this will be.
This is one reason to go ahead with #874, but as you've mentioned it's debatable whether this is worth it
| let record_years = | ||
| parse_year_str(&record.commission_years, process_years).with_context(|| { | ||
| parse_year_str(&record.commission_years, &process_years).with_context(|| { | ||
| format!("Invalid year for process {id}. Valid years are {process_years:?}") |
There was a problem hiding this comment.
Probably fine, although this could be a lot of years which will make for a long message. Maybe better to give the range of years rather than the full list?
I also wonder if parse_year_str could be simplified by taking a range instead of a list of years?
There was a problem hiding this comment.
I thought about this, but parse_year_str is used in other places passing the milestone years as valid years, which is a discrete vector. In python handling this two possible inputs would be a piece of cake, but I don't see a clear way forward here but by duplicating the function, one taking a vector as input and another a range, updating the internal logic internally as needed.
There was a problem hiding this comment.
Hmm good point. I'd say it's best as it is then
src/input/process/availability.rs
Outdated
| .iter() | ||
| .copied() | ||
| .filter(|&year| year >= base_year); | ||
| let process_milestone_years = process.years.clone().filter(|&year| year >= base_year); |
There was a problem hiding this comment.
I think this is wrong. We need to filter this to just include milestone years. Currently it includes all years after the first milestone year
You'll need to pass the list of milestone years into the function to do this
| asset.process_id, | ||
| asset.commission_year, | ||
| asset.agent_id, | ||
| ); |
There was a problem hiding this comment.
I like this block a lot, but aren't we already doing these checks elsewhere?
There was a problem hiding this comment.
Yes, sort of, when building the commodity graph for the model. I just thought it made sense to catch issues even earlier, when processing the file. Happy to remove it if you think it is redundant, but I don't think it does any harm.
src/input/process.rs
Outdated
| .filter(|year| (start_year..=end_year).contains(year)), | ||
| ) | ||
| .collect(); | ||
| // simulation's time horizon, so assume that all years >=start_year are valid too. |
There was a problem hiding this comment.
I don't think we need this comment any more
|
@tsmbland Wait to re-review. I've made the changes to the wrong branch... :( |
|
Done, now. |
src/input/process/availability.rs
Outdated
| let process_milestone_years = process.years.clone().filter(|&year| year >= base_year); | ||
| let mut missing = Vec::new(); | ||
| for (region_id, year) in iproduct!(&process.regions, process_milestone_years) { | ||
| for (region_id, &year) in iproduct!(&process.regions, milestone_years) { |
There was a problem hiding this comment.
I think this still isn't right. This needs to be just the milestone years within the year range of the process
|
Now. Hopefully |
Description
This is the first of a series of modifications aimed at refactoring how process maps are represented and used. See #880 for more details on the purpose of this refactoring.
This particular PR changes the code so the process valid commission years are stored as a
RangeInclusiveinstead of a discrete vector of years. The direct consequence of this is that input assets can be commissioned in any year where the process can be commissioned, and not just the milestone years or years before the base year.As a consequence of this change, the following also had to be made:
Finally, a validation step has been added when reading assets where the commission year is checked against the range of valid commission years and the years available in the parameters and flows.
No change has been made to how the parameters and flow maps are handled (suggested to use
rangemap) as that requires significant refactoring and needs to be well thought.Fixes #859
Fixes #770
Type of change
Key checklist
$ cargo test$ cargo docFurther checks