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

Upgrade to version 1.7.0 #309

Merged
merged 126 commits into from
Apr 29, 2022
Merged
Changes from 1 commit
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
e4ab5c5
fixing issue rte-france#281
BDonnot Jan 25, 2022
8752708
fixing issue rte-france#282
BDonnot Jan 25, 2022
4befde9
fixing rte-france#283
BDonnot Jan 25, 2022
ffdcbe4
making difference between env_path and grid_path in Environment
BDonnot Jan 26, 2022
b34fc3b
fixing broken tests
BDonnot Jan 26, 2022
6ea4a5b
Merge pull request #147 from BDonnot/bd_dev
BDonnot Jan 27, 2022
1a13dab
Merge pull request #284 from BDonnot/master
BDonnot Jan 27, 2022
53a98c7
fixing rte-france#285
BDonnot Jan 27, 2022
c3af41a
fix a typo in a property definition
BDonnot Jan 27, 2022
415b0c0
fix another typo in a property definition
BDonnot Jan 27, 2022
b698d25
a few modif i need to integrate properly [skip ci]
BDonnot Feb 2, 2022
c7ae389
adding an exception to the error message of the environment
BDonnot Feb 3, 2022
99a9b41
update the changelog [skip ci]
BDonnot Feb 7, 2022
4a70c57
fixing bug rte-france#286
BDonnot Feb 7, 2022
c405668
fixing broken tests
BDonnot Feb 7, 2022
53035a1
Merge pull request #148 from BDonnot/bd_dev
BDonnot Feb 7, 2022
f76069a
Merge pull request #287 from BDonnot/master
BDonnot Feb 7, 2022
9f4d881
adding seeds in the gym compat to make tests reproducible
BDonnot Feb 8, 2022
15d943e
fix a bug of the shunts in the update_from_obs and start to add simul…
BDonnot Feb 8, 2022
316987f
adding attributes to the observation: gen_margin_up and gen_margin_down
BDonnot Feb 9, 2022
149619f
adding icaps env in the doc
BDonnot Feb 9, 2022
79e3833
adding some tests for the simulator, need more tests then documentation
BDonnot Feb 9, 2022
6cdd4e1
adding some tests for the simulator, need more tests then documentation
BDonnot Feb 9, 2022
06cd667
adding an 'automaton' in the enviornment to improve resiliency when h…
BDonnot Feb 10, 2022
70e2ba1
trying to add an option to limit the curtailment to make the redispat…
BDonnot Feb 10, 2022
51b81b8
limit curtailment starts to work on some simple cases
BDonnot Feb 11, 2022
71d477d
passing more tests for the extreme curtailment
BDonnot Feb 11, 2022
19d474f
quite robust tests for the redispatching in extreme cases
BDonnot Feb 11, 2022
64db946
adding some tests for the correct implementation of slack power needed
BDonnot Feb 11, 2022
79ba5dc
identify the possible location of the bug in the tests [skip ci]
BDonnot Feb 11, 2022
526d08c
one more case taken into account when limiting curtailment
BDonnot Feb 15, 2022
f3bd27c
adding new test env, moving _ObsEnv [skip ci]
BDonnot Feb 15, 2022
b3121f0
adding support for max_iter in the pandapowerr backend
BDonnot Feb 16, 2022
8d448a6
progressing in limiting the storage unit actions, some tests does not…
BDonnot Feb 16, 2022
3177b3a
still a weird bug when both storage and curtailment are limited [skip…
BDonnot Feb 16, 2022
f49c9ef
all tests work, will refacto the step functions now
BDonnot Feb 17, 2022
d08d36b
finishing the refactoring of env.step and to code the limit of curtai…
BDonnot Feb 17, 2022
e9a92bc
fixing tests for sonarcloud
BDonnot Feb 18, 2022
3edc78c
fixing broken tests for the environment
BDonnot Feb 18, 2022
43e9304
adding some tests and storage units support in the Simulator
BDonnot Feb 18, 2022
48f5646
adding a utility to plot and possibility to create an env without the…
BDonnot Mar 14, 2022
84da515
Merge branch 'bd_dev' of https://github.com/bdonnot/grid2op into bd_dev
BDonnot Mar 14, 2022
93429cf
update changelog
BDonnot Mar 14, 2022
488b358
Merge branch 'bd_dev' of https://github.com/bdonnot/grid2op into bd_dev
BDonnot Mar 14, 2022
027a183
start to add the method to generate data from grid2op [skipci]
BDonnot Mar 17, 2022
a1299f9
fix a bug in networkx
BDonnot Mar 22, 2022
35b6370
fixing conflict
BDonnot Mar 22, 2022
5a6c4ea
adding a seed to a test that appear random
BDonnot Mar 22, 2022
205f5d9
adding python 3.10 in circleci tests
BDonnot Mar 22, 2022
d4eb4be
adding the start of a doc for the simulator [skip ci]
BDonnot Mar 22, 2022
9a7f1cd
formatting the code with black
BDonnot Mar 23, 2022
e651956
adding documentation to the simulator class
BDonnot Mar 23, 2022
5ee45e3
improving code quality for sonarcloud
BDonnot Mar 23, 2022
754c934
Merge pull request #149 from BDonnot/bd_dev
BDonnot Mar 23, 2022
485c058
Merge pull request #292 from BDonnot/master
BDonnot Mar 24, 2022
cb53b70
fix a bug in runner for max_iter
BDonnot Mar 29, 2022
b45cad6
fix the test grid to silence lightsim2grid warnings
BDonnot Mar 29, 2022
b4967cc
improve the hashing of the environments
BDonnot Mar 29, 2022
0bd5efe
adding explicit action / observation classes for the competition envi…
BDonnot Mar 29, 2022
3f7638e
adding support for changing the opponent space type
BDonnot Mar 29, 2022
41b6a34
silence lightsim2grid warnings for l2rpn_* envs
BDonnot Mar 29, 2022
c98b03f
Merge pull request #150 from BDonnot/bd_dev
BDonnot Mar 30, 2022
aa7221f
Merge pull request #295 from BDonnot/master
BDonnot Mar 30, 2022
b1d86db
adding l2rpn_utils module for dedicated action / observation class fo…
BDonnot Mar 30, 2022
6decea7
Improving error message when environment cannot be updated [skip ci]
BDonnot Mar 30, 2022
a6af965
Merge pull request #151 from BDonnot/bd_dev
BDonnot Mar 30, 2022
7385d88
Merge pull request #296 from BDonnot/master
BDonnot Mar 30, 2022
1580f9c
fix the computation of the reward and scores - bug due to conversion …
BDonnot Mar 30, 2022
ed5931c
adding another thing to do before release [skip ci]
BDonnot Mar 30, 2022
94b5ece
start to add a method to limit the curtailment / storage of an action…
BDonnot Apr 1, 2022
d9f9244
fix two small
Apr 2, 2022
af15164
fix two small malformations
Apr 2, 2022
4b25843
Merge branch 'dev_1.6.6' of github.com:mowang111/Grid2Op into dev_1.6.6
Apr 2, 2022
babb17d
test past for limiting curtailment down [skip ci]
BDonnot Apr 4, 2022
b96f28a
adding functionality to limit the storage / curtailment in the action
BDonnot Apr 4, 2022
0f3d746
Merge pull request #299 from mowang111/dev_1.6.6
BDonnot Apr 4, 2022
819c1d8
improve readme.md [skip ci]
BDonnot Apr 4, 2022
21fcd85
Merge remote-tracking branch 'upstream/dev_1.6.6' into bd_dev
BDonnot Apr 4, 2022
afc83e1
improve readme and notebook on action [skip ci]
BDonnot Apr 5, 2022
82a0a10
adding the doc of act.limit_curtail_storage [skip ci]
BDonnot Apr 5, 2022
43b8ceb
adding some typing for the BaseAction [skip ci]
BDonnot Apr 5, 2022
bcbfd4f
adding a method to compute the chronix 'on the fly' using chronix2gri…
BDonnot Apr 6, 2022
2ddc6df
[skip ci] adding a first dev version of l2rpn 2022, adding some tests…
BDonnot Apr 7, 2022
fb201e4
make sure tests are made for the new functionalities
BDonnot Apr 8, 2022
0a09437
fixing a first bug of config.yaml
BDonnot Apr 8, 2022
d740eff
fixing a second bug of config.yaml
BDonnot Apr 8, 2022
5afa9c5
fixing a second bug of config.yaml 2
BDonnot Apr 8, 2022
a2651ac
fixing a second bug of config.yaml 3
BDonnot Apr 8, 2022
1d7761f
fixing a second bug of config.yaml 4
BDonnot Apr 8, 2022
787811b
fixing a second bug of config.yaml 5
BDonnot Apr 8, 2022
b355e88
fixing a second bug of config.yaml 6
BDonnot Apr 8, 2022
d96b5e1
fixing a second bug of config.yaml 7
BDonnot Apr 8, 2022
5f8ff8a
fixing a second bug of config.yaml 8
BDonnot Apr 8, 2022
abc01f1
fixing a second bug of config.yaml 9
BDonnot Apr 8, 2022
05038d7
fixing a second bug of config.yaml 10
BDonnot Apr 8, 2022
58b9671
fixing a second bug of config.yaml 11
BDonnot Apr 8, 2022
2349042
fixing a second bug of config.yaml 12
BDonnot Apr 8, 2022
6b66609
fixing a second bug of config.yaml 13
BDonnot Apr 8, 2022
ebeda0a
fixing a second bug of config.yaml 14
BDonnot Apr 8, 2022
52009a9
fixing a second bug of config.yaml 15
BDonnot Apr 8, 2022
a310539
fixing a second bug of config.yaml 16
BDonnot Apr 8, 2022
1df8f62
fixing a second bug of config.yaml 17
BDonnot Apr 8, 2022
bb4e74f
fixing a second bug of config.yaml 18
BDonnot Apr 8, 2022
56608b9
fixing broken tests
BDonnot Apr 12, 2022
ba52a7e
fix test and add doc for the new chronix class and improve some docs
BDonnot Apr 12, 2022
d3a6664
updating the changelog [skip ci]
BDonnot Apr 12, 2022
0e171c3
update config of l2rpn_wcci_2022 test env [skip ci]
BDonnot Apr 12, 2022
cbb4fed
resetting the chronix2grid dependency to master instead of bd-dev [sk…
BDonnot Apr 12, 2022
9cca5ba
refactoring the fromChronixGrid class to reduce copy paste
BDonnot Apr 12, 2022
d468241
Merge pull request #152 from BDonnot/bd_dev
BDonnot Apr 12, 2022
06b7848
Merge pull request #300 from BDonnot/master
BDonnot Apr 12, 2022
a07e87b
fix a bug when limiting the action automatically in the env
BDonnot Apr 22, 2022
87f305d
Merge pull request #153 from BDonnot/bd_dev
BDonnot Apr 22, 2022
b9c9fc9
Merge pull request #306 from BDonnot/master
BDonnot Apr 22, 2022
16a9c4e
introducing basic compatibility with 'new' openai reset api [skip ci]
BDonnot Apr 22, 2022
98bc50c
finishing the notebook 4 on the training agent
BDonnot Apr 26, 2022
8431630
adding readme [skip ci]
BDonnot Apr 26, 2022
7e1cd77
adapting the redispatching algorithm, fixing the notebook 4, 5 and 6 …
BDonnot Apr 26, 2022
d5bcc63
updating the last notebooks with more up to date information
BDonnot Apr 27, 2022
02f4026
adapt tests for modification of redispatching algorithm
BDonnot Apr 28, 2022
42797cb
update the changelog [skip ci]
BDonnot Apr 28, 2022
0f2f7a9
Merge pull request #154 from BDonnot/bd_dev
BDonnot Apr 28, 2022
5997b0a
Merge pull request #308 from BDonnot/master
BDonnot Apr 28, 2022
b4a7310
fixing rte-france#310 rte-france#311 and add tests for env.generate_c…
BDonnot Apr 29, 2022
056eb47
Merge pull request #155 from BDonnot/bd_dev
BDonnot Apr 29, 2022
823046f
Merge pull request #312 from BDonnot/master
BDonnot Apr 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix test and add doc for the new chronix class and improve some docs
BDonnot committed Apr 12, 2022
commit ba52a7ef46335219b53082d7b6141f1f6f23d77b
196 changes: 195 additions & 1 deletion docs/environment.rst
Original file line number Diff line number Diff line change
@@ -371,6 +371,61 @@ episode:

(as always added line compared to the base code are highlighted: they are "circle" with `#####`)

Generating chronics that are always new
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. versionadded:: 1.6.6
This functionality is only available for some environments, for example "l2rpn_wcci_2022"

.. warning::
A much better alternative to this class is to have a "process" generate the data, thanks to the
:func:`grid2op.Environment.Environment.generate_data` and then to reload
the data in a (separate) training script.

This is explained in section :ref:`generate_data_flow` of the documentation.

Though it is not recommended at all (for performance reasons), you have, starting from grid2op 1.6.6 (and using
a compatible environment *eg* "l2rpn_wcci_2022") to generate a possibly infinite amount of data thanks to the
:class:`grid2op.Chronics.FromChronix2grid` class.

The data generation process is rather slow for different reasons. The main one is that
the data need to meet a lot of "constraints" to be realistic, some of them are
given in the :ref:`modeled-elements-module` module. On our machines, it takes roughly
40-50 seconds to generate a weekly scenario for the `l2rpn_wcci_2022` environment (usually
an agent will fail in 1 or 2s... This is why we do not recommend to use it)

To generate data "on the fly" you simply need to create the environment with the right
chronics class as follow:

.. code-block:: python

import grid2op
from grid2op.Chronics import FromChronix2grid
env_nm = "l2rpn_wcci_2022" # only compatible environment at time of writing

env = grid2op.make(env_nm,
chronics_class=FromChronix2grid,
data_feeding_kwargs={"env_path": os.path.join(grid2op.get_current_local_dir(), env_nm),
"with_maintenance": True, # whether to include maintenance (optional)
"max_iter": 2 * 288, # duration (in number of steps) of the data generated (optional)
}
)


And this is it. Each time you call `env.reset()` it will internally call `chronix2grid` package to generate
new data for this environment (this is why `env.reset()` will take roughly 50s...).

.. warning::
For this class to be available, you need to have the "chronix2grid" package installed and working.

Please install it with `pip intall grid2op[chronix2grid]` and make sure to have the `coinor-cbc`
solver available on your system (more information at https://github.com/bdonnot/chronix2grid#installation)

.. warning::
Because I know from experience warnings are skipped half of the time: **please consult** :ref:`generate_data_flow` **for
a better way to generate infinite data** !


.. _environment-module-data-pipeline:

Optimize the data pipeline
@@ -529,6 +584,124 @@ This can be achieved with:
Note that by default the `MultifolderWithCache` class will only load the **first** chronics it sees. You need
to filter it and call `env.chronics_handler.real_data.reset()` for it to work properly.

.. _generate_data_flow:

Generate and use an "infinite" data
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. versionadded:: 1.6.6


.. warning::
For this class to be available, you need to have the "chronix2grid" package installed and working.

Please install it with `pip intall grid2op[chronix2grid]` and make sure to have the `coinor-cbc`
solver available on your system (more information at https://github.com/bdonnot/chronix2grid#installation)

In this section we present a new way to generate possibly an infinite amount of data for training your agent (
in case the data shipped with the environment are too limited).

One way to do this is to split the data "generation" process on one python script, and the data "consumption" process
(for example by training an agent) on another one.

This is much more efficient than using the :class:`grid2op.Chronics.FromChronix2grid` because you will not spend 50s
waiting the data to be generated at each call to `env.reset()` after the episode is over.

First, create a script to generate all the data that you want. For example in the script "generation.py":

.. code-block:: python

import grid2op
env_name = "l2rpn_wcci_2022" # only compatible with what comes next (at time of writing)
env = grid2op.make(env_name)
nb_year = 50 # or any "big" number...
env.generate_data(nb_year=nb_year) # generates 50 years of data
# (takes roughly 50s per week, around 45mins per year, in this case 50 * 45 mins = 37.5 hours)

Then create a script to "consume" your data, for example by training an agent (say "train.py")
[we demonstrate it with l2rpn baselines but you can use whatever you want]:

.. code-block:: python

import os
import grid2op
from lightsim2grid import LightSimBackend # highly recommended for speed !

env_name = "l2rpn_wcci_2022" # only compatible with what comes next (at time of writing)
env = grid2op.make(env_name, backend=LightSimBackend())

# now train an agent
# see l2rpn_baselines package for more information, for example
# l2rpn-baselines.readthedocs.io/
from l2rpn_baselines.PPO_SB3 import train
nb_iter = 10000 # train for that many iterations
agent_name = "WhaetverIWant" # or any other name
agent_path = os.path.expand("~") # or anywhere else on your computer
trained_agent = train(env,
iterations=nb_iter,
name=agent_name,
save_path=agent_path)
# this agent will be trained only on the data available at the creation of the environment

# the training loop will take some time, so more data will be generated when it's over
# reload them
env.chronics_handler.init_subpath()
env.chronics_handler.reset()

# and retrain your agent including the data you just generated
trained_agent = train(env,
iterations=nb_iter,
name=agent_name,
save_path=agent_path,
load_path=agent_path
)

# once it's over, more time has passed, and more data are available
# reload them
env.chronics_handler.init_subpath()
env.chronics_handler.reset()

# and retrain your agent
trained_agent = train(env,
iterations=nb_iter,
name=agent_name,
save_path=agent_path,
load_path=agent_path
)

# well you got the idea
# etc. etc.

.. warning::
This way of doing things will always increase the size of the data in your hard drive.
We do recommend to somehow delete some of the data from time to time

Deleting the data you be done before the `env.chronics_handler.init_subpath()` for example:

.. code-block :: python

### delete the folder you want to get rid off
names_folder_to_delete = ...
# To build `names_folder_to_delete`
# you could for examaple:
# - remove the `nth` oldest directories
# see: https://stackoverflow.com/questions/47739262/find-remove-oldest-file-in-directory
# - or keep only the `kth`` most recent directories
# - or keep only `k` folder at random among the one in `grid2op.get_current_local_dir()`
# - or delete all the oldest files and keep your directory at a fixed size
# see: https://gist.github.com/ginz/1ba7de8b911651cfc9c85a82a723f952
# etc.

for nm in names_folder_to_delete:
shutil.rmtree(os.path.join(grid2op.get_current_local_dir(), nm))
####
# reload the remaining data:
env.chronics_handler.init_subpath()
env.chronics_handler.reset()

# continue normally


.. _environment-module-train-val-test:

Splitting into raining, validation, test scenarios
@@ -592,7 +765,28 @@ Environments can be customized in three major ways:
- `Rules`: you can affect the operational constraint that your agent must meet. For example you can affect
more or less powerlines in the same action etc.

TODO
You can do these at creation time:

.. code-block:: python

import grid2op
env_name = "l2rpn_case14_sandbox" # or any other name

# create the regular environment:
env_reg = grid2op.make(env_name)

# to change the backend
# (here using the lightsim2grid faster backend)
from lightsim2grid import LightSimBackend
env_faster = grid2op.make(env_name, backend=LightSimBackend())

# to change the parameters, for example
# to prevent line disconnect when there is overflow
param = env_reg.parameters
param.NO_OVERFLOW_DISCONNECTION = True
env_easier = grid2op.make(env_name, param=param)

Of course you can combine everything. More examples are given in section :ref:`env_cust_makeenv`.

Detailed Documentation by class
--------------------------------
34 changes: 27 additions & 7 deletions docs/makeenv.rst
Original file line number Diff line number Diff line change
@@ -121,6 +121,8 @@ an internet connection)
will not be removed from your local hard drive. This is why we don't recommend to change this folder unless you have a
valid reason to do so.

.. _env_cust_makeenv:

Customize your environment
--------------------------
When you create it, you can change different parameters of the environments. We summarize all parameters
@@ -136,14 +138,17 @@ context of the L2RPN competition, we don't recommend to modify them.
- `reward_class`: change the type of reward you want to use for your agent
- `other_reward`: tell "env.step" to return addition "rewards"
- `difficulty`, `param`: control the difficulty level of the game (might not always be available)
- \* `action_class`: which action class your agent is allowed to use.
- \* `gamerules_class`: the rules that are checked to declare an action legal / illegal
- \* `chronics_path`, `data_feeding`, `chronics_class`, `data_feeding_kwargs`: the path where the data are located
- \* `volagecontroler_class`: how the voltages are set on the grid
- \* `grid_path`: the path where the default powergrid properties are stored
- \* `observation_class`: which type of observation do you use
- `chronics_class`, `data_feeding_kwargs`: further customization to how the data will be generated
- \* `chronics_path`, `data_feeding`, : to overload default path for the data (**not recommended**)
- \* `action_class`: which action class your agent is allowed to use (**not recommended**).
- \* `gamerules_class`: the rules that are checked to declare an action legal / illegal (**not recommended**)
- \* `volagecontroler_class`: how the voltages are set on the grid (**not recommended**)
- \* `grid_path`: the path where the default powergrid properties are stored (**not recommended**)
- \* `observation_class`, `kwargs_observation`: which type of observation do you use (**not recommended**)
- \* `opponent_action_class`, `opponent_class`, `opponent_init_budget`, `opponent_budget_per_ts`,
`opponent_budget_class`: all configuration for the opponent.
`opponent_budget_class`, `opponent_space_type`, `kwargs_opponent`: all configuration for the opponent. (**not recommended**)
- \* `has_attention_budget`, `attention_budget_class`, `kwargs_attention_budget`: all configuration
for the "alarm" / "attention budget" parameters. (**not recommended**)

More information about the "customization" of the environment, especially to optimize the I/O or to manipulate
which data you interact with are available in the :ref:`environment-module` module (:ref:`environment-module-usage` section).
@@ -153,6 +158,21 @@ which data you interact with are available in the :ref:`environment-module` modu

We do not recommend to modify the keyword arguments starting with \*, and especially the action_class.

You can customize an environment with:

.. code-block:: python

import grid2op
env = grid2op.make(dataset_path,
backend=..., # put a compatible backend here
reward_class=..., # change the reward function, see BaseReward
other_reward={key: reward_func}, # with `key` being strings and `reward_func` inheriting from BaseReward
difficulty=..., # str or ints
param=..., # any Parameters (from grid2op.Parameters import Parameters)
etc.
)

See documentation of :func:`grid2op.MakeEnv.make_from_dataset_path` for more information about all these parameters.

Detailed Documentation by class
--------------------------------
55 changes: 55 additions & 0 deletions grid2op/Chronics/fromChronix2grid.py
Original file line number Diff line number Diff line change
@@ -22,6 +22,54 @@


class FromChronix2grid(GridValue):
"""This class of "chronix" allows to use the `chronix2grid` package to generate data "on the fly" rather
than having to read it from the hard drive.

.. versionadded:: 1.6.6


.. warning::
It requires the `chronix2grid` package to be installed, please install it with :

`pip install grid2op[chronix2grid]`

And visit https://github.com/bdonnot/chronix2grid#installation for more installation details (in particular
you need the coinor-cbc software on your machine)

As of writing, this class is really slow compared to reading data from the hard drive. Indeed to generate a week of data
at the 5 mins time resolution (*ie* to generate the data for a "standard" episode) it takes roughly 40/45 s for
the `l2rpn_wcci_2022` environment (based on the IEEE 118).

Notes
------
It requires lots of extra metadata to use this class. As of writing, only the `l2rpn_wcci_2022` is compatible with it.


Examples
----------
To use it (though we do not recommend to use it) you can do:

.. code-block:: python

import grid2op
from grid2op.Chronics import FromChronix2grid
env_nm = "l2rpn_wcci_2022" # only compatible environment at time of writing

env = grid2op.make(env_nm,
chronics_class=FromChronix2grid,
data_feeding_kwargs={"env_path": os.path.join(grid2op.get_current_local_dir(), env_nm),
"with_maintenance": True, # whether to include maintenance (optional)
"max_iter": 2 * 288, # duration (in number of steps) of the data generated (optional)
}
)

Before using it, please consult the :ref:`generate_data_flow` section of the document, that provides a much faster way
to do this.

"""
REQUIRED_FILES = ["loads_charac.csv", "params.json", "params_load.json",
"params_loss.json", "params_opf.json", "params_res.json",
"prods_charac.csv", "scenario_params.json"]
def __init__(self,
env_path: os.PathLike,
with_maintenance: bool,
@@ -44,6 +92,13 @@ def __init__(self,

self._generate_one_episode = generate_one_episode

for el in type(self).REQUIRED_FILES:
tmp_ = os.path.join(env_path, el)
if not (os.path.exists(tmp_) and os.path.isfile(tmp_)):
raise ChronicsError(f"The file \"{el}\" is required but is missing from your environment. "
f"Check data located at \"env_path={env_path}\" and make sure you "
f"can use this environment to generate data.")

GridValue.__init__(
self,
time_interval=time_interval,
126 changes: 114 additions & 12 deletions grid2op/Chronics/multiFolder.py
Original file line number Diff line number Diff line change
@@ -30,6 +30,9 @@ class Multifolder(GridValue):
the data are always loaded in the same order, regardless of the :class:`grid2op.Backend`, :class:`grid2op.BaseAgent` or
:class:`grid2op.Environment`.
.. note::
Most grid2op environments, by default, use this type of "chronix", read from the hard drive.
Attributes
-----------
gridvalueClass: ``type``, optional
@@ -74,18 +77,7 @@ def __init__(
self.data = None
self.path = os.path.abspath(path)
self.sep = sep
try:
self.subpaths = [
os.path.join(self.path, el)
for el in os.listdir(self.path)
if os.path.isdir(os.path.join(self.path, el))
]
self.subpaths.sort()
self.subpaths = np.array(self.subpaths)
except FileNotFoundError:
raise ChronicsError(
'Path "{}" doesn\'t exists.'.format(self.path)
) from None
self.init_subpath()

if len(self.subpaths) == 0:
raise ChronicsNotFoundError(
@@ -116,6 +108,116 @@ def __init__(
self._prev_cache_id = 0
self._order = None

def init_subpath(self):
"""
Read the content of the main directory and initialize the `subpaths`
where the data could be located.
This is usefull, for example, if you generated data and want to be able to use them.
**NB** this has no effect until :attr:`Multifolder.reset` is called.
.. warning::
By default, it will only consider data that are present at creation time. If you add data after, you need
to call this function (and do a reset)
Examples
---------
A "typical" usage of this function can be the following workflow.
Start a script to train an agent (say "train_agent.py"):
.. code-block:: python
import os
import grid2op
from lightsim2grid import LightSimBackend # highly recommended for speed !
env_name = "l2rpn_wcci_2022" # only compatible with what comes next (at time of writing)
env = grid2op.make(env_name, backend=LightSimBackend())
# now train an agent
# see l2rpn_baselines package for more information, for example
# l2rpn-baselines.readthedocs.io/
from l2rpn_baselines.PPO_SB3 import train
nb_iter = 10000 # train for that many iterations
agent_name = "WhaetverIWant" # or any other name
agent_path = os.path.expand("~") # or anywhere else on your computer
trained_agent = train(env,
iterations=nb_iter,
name=agent_name,
save_path=agent_path)
On another script (say "generate_data.py"), you can generate more data:
.. code-block:: python
import grid2op
env_name = "l2rpn_wcci_2022" # only compatible with what comes next (at time of writing)
env = grid2op.make(env_name)
env.generate_data(nb_year=50) # generates 50 years of data
# (takes roughly 50s per week, around 45mins per year, in this case 50 * 45 mins = lots of minutes)
Let the script to generate the data run normally (don't interupt it).
And from time to time, in the script "train_agent.py" you can do:
.. code-block:: python
# reload the generated data
env.chronics_handler.init_subpath()
env.chronics_handler.reset()
# retrain the agent taking into account new data
trained_agent = train(env,
iterations=nb_iter,
name=agent_name,
save_path=agent_path,
load_path=agent_path
)
# the script to generate data is still running, you can reload some data again
env.chronics_handler.init_subpath()
env.chronics_handler.reset()
# retrain the agent
trained_agent = train(env,
iterations=nb_iter,
name=agent_name,
save_path=agent_path,
load_path=agent_path
)
# etc.
Both scripts you run "at the same time" for it to work efficiently.
To recap:
- script "generate_data.py" will... generate data
- these data will be reloaded from time to time by the script "train_agent.py"
.. warning::
Do not delete data between calls to `env.chronics_handler.init_subpath()` and `env.chronics_handler.reset()`,
and even less so during training !
If you want to delete data (for example not to overload your hard drive) you should remove them
right before calling `env.chronics_handler.init_subpath()`.
"""
try:
self.subpaths = [
os.path.join(self.path, el)
for el in os.listdir(self.path)
if os.path.isdir(os.path.join(self.path, el))
]
self.subpaths.sort()
self.subpaths = np.array(self.subpaths)
except FileNotFoundError as exc_:
raise ChronicsError(
'Path "{}" doesn\'t exists.'.format(self.path)
) from exc_
self._order = None # to trigger a "reset" when chronix will next be loaded

def get_kwargs(self, dict_):
if self._filter != self._default_filter:
dict_["filter_func"] = self._filter
4 changes: 2 additions & 2 deletions grid2op/Environment/BaseEnv.py
Original file line number Diff line number Diff line change
@@ -2023,8 +2023,8 @@ def get_obs(self, _update_state=True):
"""
Return the observations of the current environment made by the :class:`grid2op.BaseAgent.BaseAgent`.
.. info::
this function is called twice when the env is reset, otherwise once per step
.. note::
This function is called twice when the env is reset, otherwise once per step
Returns
-------
2 changes: 1 addition & 1 deletion grid2op/MakeEnv/MakeFromPath.py
Original file line number Diff line number Diff line change
@@ -191,7 +191,7 @@ def make_from_dataset_path(
(the "hardest") is the default choice.
opponent_space_type: ``type``, optional
The type of opponent space to use. If provided, it must be a subclass of OpponentSpace.
The type of opponent space to use. If provided, it must be a subclass of `OpponentSpace`.
opponent_action_class: ``type``, optional
The action class used for the opponent. The opponent will not be able to use action that are invalid with
6 changes: 3 additions & 3 deletions grid2op/tests/test_gym_compat.py
Original file line number Diff line number Diff line change
@@ -278,14 +278,14 @@ def test_chain_converter(self):
)
res_tup = (7, 6, 0, 0, 0, 4)
res_disp = np.array(
[1.666666, 1.666666, 0.0, 0.0, 0.0, -2.5], dtype=dt_float
[1.666667, 1.666666, 0.0, 0.0, 0.0, -2.5], dtype=dt_float
)
assert (
act_gym["redispatch"] == res_tup
), f'error. redispatch is {act_gym["redispatch"]}'
act_glop = env_gym.action_space.from_gym(act_gym)
assert np.array_equal(
act_glop._redispatch, res_disp
assert np.allclose(
act_glop._redispatch, res_disp, atol=1e-5
), f"error. redispatch is {act_glop._redispatch}"

def test_all_together(self):