-
Notifications
You must be signed in to change notification settings - Fork 3
Better Scenario class
#32
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
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
b11a351
initial class and tests
RemDelaporteMathurin 3575686
ported existing tests
RemDelaporteMathurin d417424
one final test
RemDelaporteMathurin 9e7d754
added temporary warning for RISP
RemDelaporteMathurin aab1449
Use the new scenario class
RemDelaporteMathurin c0050e8
removed class
RemDelaporteMathurin 7029ed6
black formatting
RemDelaporteMathurin b73566c
docs
RemDelaporteMathurin 75f61a6
black + removed txt files
RemDelaporteMathurin 0836e1e
added tests for Pulse + better handling of RISP
RemDelaporteMathurin c2e3d6f
added one test for no waiting
RemDelaporteMathurin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| from .helpers import PulsedSource, Scenario | ||
| from .helpers import PulsedSource | ||
|
|
||
| from .h_transport_class import CustomProblem | ||
| from .scenario import Scenario, Pulse |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,229 @@ | ||
| import pandas as pd | ||
| from typing import List | ||
| import warnings | ||
|
|
||
|
|
||
| class Pulse: | ||
| pulse_type: str | ||
| nb_pulses: int | ||
| ramp_up: float | ||
| steady_state: float | ||
| ramp_down: float | ||
| waiting: float | ||
|
|
||
| def __init__( | ||
| self, | ||
| pulse_type: str, | ||
| nb_pulses: int, | ||
| ramp_up: float, | ||
| steady_state: float, | ||
| ramp_down: float, | ||
| waiting: float, | ||
| ): | ||
| self.pulse_type = pulse_type | ||
| self.nb_pulses = nb_pulses | ||
| self.ramp_up = ramp_up | ||
| self.steady_state = steady_state | ||
| self.ramp_down = ramp_down | ||
| self.waiting = waiting | ||
|
|
||
| @property | ||
| def total_duration(self) -> float: | ||
| all_zeros = ( | ||
| self.ramp_up == 0 | ||
| and self.steady_state == 0 | ||
| and self.ramp_down == 0 | ||
| and self.waiting == 0 | ||
| ) | ||
| if self.pulse_type == "RISP" and all_zeros: | ||
| msg = "RISP pulse has all zeros for ramp_up, steady_state, ramp_down, waiting. " | ||
| msg += "Setting hardcoded values. Please check the values in the scenario file." | ||
| warnings.warn(msg, UserWarning) | ||
|
|
||
| self.ramp_up = 10 | ||
| self.steady_state = 250 | ||
| self.ramp_down = 10 | ||
| self.waiting = 1530 | ||
|
|
||
| return self.ramp_up + self.steady_state + self.ramp_down + self.waiting | ||
|
|
||
| @property | ||
| def duration_no_waiting(self) -> float: | ||
| return self.total_duration - self.waiting | ||
|
|
||
|
|
||
| class Scenario: | ||
| def __init__(self, pulses: List[Pulse] = None): | ||
| """Initializes a Scenario object containing several pulses. | ||
|
|
||
| Args: | ||
| pulses: The list of pulses in the scenario. Each pulse is a Pulse object. | ||
| """ | ||
| self._pulses = pulses if pulses is not None else [] | ||
|
|
||
| @property | ||
| def pulses(self) -> List[Pulse]: | ||
| return self._pulses | ||
|
|
||
| def to_txt_file(self, filename: str): | ||
| df = pd.DataFrame( | ||
| [ | ||
| { | ||
| "pulse_type": pulse.pulse_type, | ||
| "nb_pulses": pulse.nb_pulses, | ||
| "ramp_up": pulse.ramp_up, | ||
| "steady_state": pulse.steady_state, | ||
| "ramp_down": pulse.ramp_down, | ||
| "waiting": pulse.waiting, | ||
| } | ||
| for pulse in self.pulses | ||
| ] | ||
| ) | ||
| df.to_csv(filename, index=False) | ||
|
|
||
| @staticmethod | ||
| def from_txt_file(filename: str, old_format=False) -> "Scenario": | ||
| if old_format: | ||
| pulses = [] | ||
| with open(filename, "r") as f: | ||
| for line in f: | ||
| # skip first line | ||
| if line.startswith("#"): | ||
| continue | ||
|
|
||
| # assume this is the format | ||
| pulse_type, nb_pulses, ramp_up, steady_state, ramp_down, waiting = ( | ||
| line.split() | ||
| ) | ||
| pulses.append( | ||
| Pulse( | ||
| pulse_type=pulse_type, | ||
| nb_pulses=int(nb_pulses), | ||
| ramp_up=float(ramp_up), | ||
| steady_state=float(steady_state), | ||
| ramp_down=float(ramp_down), | ||
| waiting=float(waiting), | ||
| ) | ||
| ) | ||
| return Scenario(pulses) | ||
| df = pd.read_csv(filename) | ||
| pulses = [ | ||
| Pulse( | ||
| pulse_type=row["pulse_type"], | ||
| nb_pulses=int(row["nb_pulses"]), | ||
| ramp_up=float(row["ramp_up"]), | ||
| steady_state=float(row["steady_state"]), | ||
| ramp_down=float(row["ramp_down"]), | ||
| waiting=float(row["waiting"]), | ||
| ) | ||
| for _, row in df.iterrows() | ||
| ] | ||
| return Scenario(pulses) | ||
|
|
||
| def get_row(self, t: float) -> int: | ||
| """Returns the row of the scenario file that corresponds to the time t. | ||
|
|
||
| Args: | ||
| t: the time in seconds | ||
|
|
||
| Returns: | ||
| int: the row index of the scenario file corresponding to the time t | ||
| """ | ||
| current_time = 0 | ||
| for i, pulse in enumerate(self.pulses): | ||
| phase_duration = pulse.nb_pulses * pulse.total_duration | ||
| if t <= current_time + phase_duration: | ||
| return i | ||
| else: | ||
| current_time += phase_duration | ||
|
|
||
| raise ValueError( | ||
| f"Time t {t} is out of bounds of the scenario file. Maximum time is {self.get_maximum_time()}" | ||
| ) | ||
|
|
||
| def get_pulse(self, t: float) -> Pulse: | ||
| """Returns the pulse at time t. | ||
|
|
||
| Args: | ||
| t: the time in seconds | ||
|
|
||
| Returns: | ||
| Pulse: the pulse at time t | ||
| """ | ||
| row_idx = self.get_row(t) | ||
| return self.pulses[row_idx] | ||
|
|
||
| def get_pulse_type(self, t: float) -> str: | ||
| """Returns the pulse type as a string at time t. | ||
|
|
||
| Args: | ||
| t: time in seconds | ||
|
|
||
| Returns: | ||
| pulse type (eg. FP, ICWC, RISP, GDC, BAKE) | ||
| """ | ||
| return self.get_pulse(t).pulse_type | ||
|
|
||
| def get_maximum_time(self) -> float: | ||
| """Returns the maximum time of the scenario in seconds. | ||
|
|
||
| Returns: | ||
| the maximum time of the scenario in seconds | ||
| """ | ||
| return sum([pulse.nb_pulses * pulse.total_duration for pulse in self.pulses]) | ||
|
|
||
| def get_time_start_current_pulse(self, t: float): | ||
| """Returns the time (s) at which the current pulse started. | ||
|
|
||
| Args: | ||
| t: the time in seconds | ||
|
|
||
| Returns: | ||
| the time at which the current pulse started | ||
| """ | ||
| current_pulse = self.get_pulse(t) | ||
| pulse_index = self.pulses.index(current_pulse) | ||
| return sum( | ||
| [ | ||
| pulse.nb_pulses * pulse.total_duration | ||
| for pulse in self.pulses[:pulse_index] | ||
| ] | ||
| ) | ||
|
|
||
| # TODO this is the same as get_time_start_current_pulse, remove | ||
| def get_time_till_row(self, row: int) -> float: | ||
| """Returns the time (s) until the row in the scenario file. | ||
|
|
||
| Args: | ||
| row: the row index in the scenario file | ||
|
|
||
| Returns: | ||
| the time until the row in the scenario file | ||
| """ | ||
| return sum( | ||
| [pulse.nb_pulses * pulse.total_duration for pulse in self.pulses[:row]] | ||
| ) | ||
|
|
||
| # TODO remove | ||
| def get_pulse_duration_no_waiting(self, row: int) -> float: | ||
| """Returns the total duration (without the waiting time) of a pulse in seconds for a given row in the file. | ||
|
|
||
| Args: | ||
| row: the row index in the scenario file | ||
|
|
||
| Returns: | ||
| the total duration of the pulse in seconds | ||
| """ | ||
| return self.pulses[row].duration_no_waiting | ||
|
|
||
| # TODO remove | ||
| def get_pulse_duration(self, row: int) -> float: | ||
| """Returns the total duration of a pulse in seconds for a given row in the file. | ||
|
|
||
| Args: | ||
| row: the row index in the scenario file | ||
|
|
||
| Returns: | ||
| the total duration of the pulse in seconds | ||
| """ | ||
| return self.pulses[row].total_duration | ||
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hopefully this will become obsolete when we expand to new users
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!