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

[Refactor] Rename/define Scenario variables so they make sense when building tiered scenarios #277

Closed
lmz opened this issue Jan 19, 2022 · 11 comments · Fixed by #315
Closed
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@lmz
Copy link
Collaborator

lmz commented Jan 19, 2022

User Story

As a travel modeler who is building networks, I would like to apply projects for a given set of tags without creating a new scenario instance.

Maybe this is already doable using scenario.add_project_cards_from_tags() -- what do these add methods do? Is there a list of cards that are waiting to be applied?

Maybe I'm looking for another layer of cards, like a card set, rather than just the single list in scenario.project_cards?

Right now, our notebook creates new scenario instances over and over just to apply cards for certain tags, which seems unncessary. (Also, this notebook has a huge memory footprint which likely is related...)

Priority

Level of Effort

Resolution Ideas

Project

MTC

Who should be involved?

Implementer: I am happy do this with some guidance
Commenters:
Users:
Reviewers:

Risk

Will this potentially break anything?

Tests

What are relevant tests or what tests need to be created in order to determine that this issue is complete?

@lmz lmz added the enhancement New feature or request label Jan 19, 2022
@lmz lmz changed the title [FEATURE] apply sets of project cards to a single scenario [FEATURE] apply sets of project cards (e.g. by tags) to a single scenario Jan 19, 2022
@e-lo
Copy link
Collaborator

e-lo commented Jan 19, 2022

I think the functionality for tags is already there. Network Wrangler does something similar to git when adding new cards: first they are added and then they are applied (~ committed)

scenario.add_project_cards_from_tags() calls scenario.add_project_cards_from_file() which adds the project cards to scenario.project_cards instance.

Calling scenario.apply_all_proejcts() then applies all the projects in scenario.project_cards.

@e-lo
Copy link
Collaborator

e-lo commented Jan 19, 2022

Maybe I'm looking for another layer of cards, like a card set, rather than just the single list in scenario.project_cards?

Are you thinking similar to the "plans" we had in the og network wrangler 1.0?

@lmz
Copy link
Collaborator Author

lmz commented Jan 19, 2022

Ahh got it. So I think I would like to do something like this
(Reference: https://github.com/BayAreaMetro/NetworkWrangler/blob/master/scripts/net_spec_blueprint.py
)

# Apply base roadway fixes first
scenario.add_project_cards_from_tags(folder=card_path, tags=['Managed Lanes', 'toll review', 'Exclude Trucks'])
scenario.apply_all_projects()
# [do checks or whatever, possibly save it out]
scenario.remove_all_projects()

scenario.add_project_cards_from_tags(folder=card_path, tags=['Major Transit links'])
scenario.apply_all_projects()
# [do checks or whatever, possibly save it out]
scenario.remove_all_projects()

# This is what will be most clear for planners, see net_spec_blueprint.py link above
PLAN_PROJECTS = collections.OrderedDict([
(2020: [
    'proj1',
    'proj2',
    'proj3']),
(2025: [
    'proj4',
    'proj5'])
])
 
for year in PLAN_PROJECTS.keys():
    scenario.add_project_cards_from_list(PLAN_PROJECTS[year])
    scenario.apply_all_projects()
    scenario.write(output_path[year])
    scenario.remove_all_projects()

@e-lo
Copy link
Collaborator

e-lo commented Jan 19, 2022

scenario.remove_all_projects()
--> not sure why this is necessary if you want to layer on?

@e-lo
Copy link
Collaborator

e-lo commented Jan 19, 2022

I think this should work - what is it not happy about?

for year in PLAN_PROJECTS.keys():
    scenario.add_project_cards_from_list(PLAN_PROJECTS[year])
    scenario.apply_all_projects()
    scenario.write(output_path[year])

@lmz
Copy link
Collaborator Author

lmz commented Jan 19, 2022

Ahh... I was under the impression that rerunning scenario.apply_all_projects() without clearing them would apply again? Is it checking for ones already applied? Some projects are made to apply multiple times but most of them are not, so how are they distinguished?

@e-lo
Copy link
Collaborator

e-lo commented Jan 19, 2022

AH - looking at it more I think you are right. I guess we could do either:

  1. add remove to your process
for year in PLAN_PROJECTS.keys():
    scenario.add_project_cards_from_list(PLAN_PROJECTS[year])
    scenario.apply_all_projects()
    scenario.write(output_path[year])
    scenario.remove_all_projects()
  1. remove the project cards as default in apply_project()

Either would be straightforward to implement...

@lmz
Copy link
Collaborator Author

lmz commented Jan 19, 2022

I think it would be intuitive to have scenario.apply_all_projects() remove the project from the project_cards list once it's applied.

scenario.apply_project() is a little trickier since it's taking the project card as an arg

(In the meantime, I am invoking scenario.remove_all_projects() after applying as a workaround.

@e-lo e-lo added this to the v1.0 milestone Apr 8, 2022
@e-lo
Copy link
Collaborator

e-lo commented Apr 8, 2022

@lmz @DavidOry @i-am-sijia @kulshresthaa Thinking about this some more, I'd like to propose changing some attribute definitions 😨 😬 so we are:

  • (A) super explicit about what wrangler is doing with each function/stage of network building and
  • (B) can have the functionality that MTC (and likely other agencies) want without having to use confusing terminology (e.g. "remove_all projects" seems like it is "reversing" them from the network scenario)

Current Definitions

  • Scenario.project_cards: Collection of Project card instances that have been either queued or applied; in proposed implementation order .
  • Scenario.projects: projects that have been queued for
  • Scenario.ordered_project_cards: filled when project
  • Scenario.applied_projects :
  • There are also two "state" variables: requisites_checked and conflicts_checked

Issues

  1. There are meaningful changes to the definitions of what is in the variables above which can vary not only on the state variables, but also other activities.
  2. Difficult to understand what each means
  3. A lot of the "state" variable situations could be more easily taken care of in a @Property based variable definition.

Proposed Definitions

  • Scenario.project_cards: Mapping[ProjectCard.name,ProjectCard] Storage of all project cards by name; helps prevent naming conflicts.
  • Scenario._planned_projects: Collection[ProjectCard.name] Initial ordering of project cards which are awaiting to be queued for adding. Similar to a git working directory, project cards aren't recognized in this collection once they are moved to staging
  • Scenario._queued_projects: Collection[ProjectCard.name] Projects which are "shovel ready": have had pre-requistes checked and done any required re-ordering. Similar to a git staging, project cards aren't recognized in this collection once they are moved to applied
  • Scenario.queued_projects: @Property wrapper on _queued_projects which lazily queues (checks requirements/conflicts and orders) anything already in Scenario._queued_projects and anything in Scenario.planned_projects (and removes queued projects from planned_projects)
  • Scenario.applied_projects: Collection[ProjectCard.name] Projects which have been applied to the network.
  • No more "state" variables: requisites_checked and conflicts_checked: as this is the definitional difference between planned and queued
  • Scenario.projects: Sum of applied, queued.

Corresponding function definitions would be:

  • create_scenario(project_cards_list=project_cards_list) : adds project card instances to Scenario.project_cards and project card names to Scenario.planned_projects
  • my_scenario.apply_all_projects(): applies Scenario.queued_projects, removing from queue once they have been applied and adding project name to Scenario.applied_projects`

Considerations:

  • This makes the queuing implicit, not explicit...would we want to change that or is that an ok expected behavior?

@e-lo e-lo changed the title [FEATURE] apply sets of project cards (e.g. by tags) to a single scenario [Refactor] Rename/define Scenario variables so they make sense when building tiered scenarios Apr 8, 2022
@e-lo e-lo self-assigned this Apr 8, 2022
@DavidOry
Copy link
Member

I like it. Agree that Scenario.projects is ambiguous and @lmz's use case seems common. The fact that it wasn't obvious to her how to do this (apply projects, look at things, and then apply some more) is compelling motivation to change.

e-lo added a commit that referenced this issue Mar 7, 2023
Changes how scenarios works per description in #277 and updates relevant documentation about API changes.

Also:
- various efficiencies and consistency fixes
e-lo added a commit that referenced this issue Apr 26, 2023
Changes how scenarios works per description in #277 and updates relevant documentation about API changes.

Also:
- various efficiencies and consistency fixes
- Update example notebooks for tiny API changes
- Fix default project_card_list to be [] not None
- Require minimum variables in base_scenario: applied_projects and conflicts
- Varia fixes from Sijia! (thx!)
- Scenario tests now use fixtures + are consistently formatted
- added specific Exception types for better error catching in testing
- black

Remaining:
- project card handling

Co-authored-by: Sijia Wang and Lisa Zorn
@e-lo
Copy link
Collaborator

e-lo commented Aug 27, 2024

Implemented.

@e-lo e-lo closed this as completed Aug 27, 2024
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants