Modules
cli
Functions and definitions useful when working with ArgumentParser.
Attributes:
-
ArgumentCmdParser(TypeAlias) –generic type of a subparser of the ArgumentParser class.
Attributes
ArgumentCmdParser
module-attribute
ArgumentCmdParser: TypeAlias = _SubParsersAction
Functions:
existing_dir
existing_dir(path: str | Path)
Check if path points to an existing directory.
Example:
from argparse import ArgumentParser
from ipsl_common.cli import existing_dir
parser = ArgumentParser()
parser.add_argument("file", type=existing_dir)
Parameters:
-
(pathstr | Path) –path to a directory
Source code in ipsl_common/cli.py
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | |
existing_file
existing_file(path: str | Path)
Check if path points to an existing file.
Example:
from argparse import ArgumentParser
from ipsl_common.cli import existing_file
parser = ArgumentParser()
parser.add_argument("file", type=existing_file)
Parameters:
-
(pathstr | Path) –path to a file
Source code in ipsl_common/cli.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | |
collections
Custom data structures and related functions.
Classes
FlattenKeyDictView
FlattenKeyDictView(
*args, flat_key_separator: str = ".", **kwargs
)
Bases: dict
Dictionary view which works with flatten keys.
This class allows accessing values of a normal Python nested dictionary
using flatten keys, e.g. a.b.c, parent.child. The dictionary view
implements getting, setting, deleting and checking existance of keys.
Example usage:
from ipsl_common.collections import FlattenKeyDictView
d = {
"a": {
"k1": 1,
"k2": 2
}
}
fd = FlattenKeyDictView(d)
fd["a.k1"] = 17
del fd["a.k2"]
fd["b.k1"] = 34
print(fd)
Which prints the following result:
{'a': {'k1': 17}, 'b': {'k1': 34}}
Create flatten-key dict view class.
Parameters:
-
–*argspositional arguments passed to the dict() constructor
-
(flat_key_separatorstr, default:'.') –separator of keys in the flat key (default:
.) -
–**kwargskeyword arguments passed to the dict() constructor
Source code in ipsl_common/collections.py
63 64 65 66 67 68 69 70 71 72 | |
Attributes
flat_key_separator
instance-attribute
flat_key_separator = flat_key_separator
Methods:
__contains__
__contains__(flat_key: object) -> bool
Check if flat key exists
Source code in ipsl_common/collections.py
97 98 99 100 101 102 103 104 105 | |
__delitem__
__delitem__(flat_key: str) -> None
Delete key-value pairs using flat key
Source code in ipsl_common/collections.py
92 93 94 95 | |
__getitem__
__getitem__(flat_key: str) -> Any
Retrieve value using flat key
Source code in ipsl_common/collections.py
82 83 84 85 | |
__setitem__
__setitem__(flat_key: str, value: Any) -> None
Set new value using flat key
Source code in ipsl_common/collections.py
87 88 89 90 | |
ordered_keys
ordered_keys() -> list[str]
Ordered list of all flatten keys (including all parent keys)
Source code in ipsl_common/collections.py
74 75 76 | |
ordered_leaf_keys
ordered_leaf_keys() -> list[str]
Ordered list of flatten leaf keys (excluding all parent keys)
Source code in ipsl_common/collections.py
78 79 80 | |
Functions:
deep_update
deep_update(target: dict, update: dict) -> dict
Deep update of a dictionary.
Update the target dictionary in a nested manner. The standard dict.update() method performs only a shallow update, meaning that only the top-level dictionary keys are updated. This function will recursively inspect the dict values, so that the nested values are correctly updated.
This function doesn't perform any deep copy before updating the target dictionary.
Hence, all the updates on the target variable are performed in-place.
Parameters:
-
(targetdict) –the dictionary to update
-
(updatedict) –modifications to apply
Returns:
-
dict(dict) –returned updated dictionary (the same as the
targetargument reference)
Source code in ipsl_common/collections.py
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | |
environment
Environment utility functions.
Functions:
has_command
has_command(cmd: str) -> bool
Test if given command exists in the environment.
This function is mostly a convenience alias.
Parameters:
-
(cmdstr) –command to test
Returns:
-
bool–True if the command exists, False otherwise
Source code in ipsl_common/environment.py
5 6 7 8 9 10 11 12 13 14 15 16 | |
envmodules
Python interface to EnvModules.
Better Python interface to EnvModules which doesn't pollute
the global environment with the module() function.
Examples:
em = EnvModules()
em.load("gcc", "cdo")
print(em.list_loaded())
Classes
EnvModules
EnvModules(modulehome: str | Path | None = None)
Modern interface to EnvModules.
This class encapsulate the module() function of EnvModules inside
a local environment.
Attributes:
-
envmodule–Reference to the
module()function of EnvModules.
Initialize EnvModules found on specified path (or default).
Parameters:
-
(modulehomestr or Path, default:None) –Path to the EnvModules installation directory.
Source code in ipsl_common/envmodules.py
30 31 32 33 34 35 36 37 38 39 40 41 | |
Attributes
envmodule
instance-attribute
envmodule = self.locals['module']
locals
instance-attribute
locals: dict = {}
Methods:
get_available
get_available(
flatten=True,
) -> list[str] | dict[str, list[str]]
Return available EnvModules.
This method depends on the /usr/bin/modulecmd binary being present.
The classical module() function won't work here, because we need to
capture and then parse the output of the module avail function
which normally is directly passed onto stderr stream.
Parameters:
-
(flattenbool, default:True) –If true (default), the result will be a flat list of modules. Otherwise, a dictionary is returned with keys representing a named-group of modules.
Returns:
Source code in ipsl_common/envmodules.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | |
get_loaded
get_loaded() -> list[str]
Return loaded EnvModules.
Returns:
-
list[str]–list[str]: List of loaded EnvModules.
Source code in ipsl_common/envmodules.py
59 60 61 62 63 64 65 66 67 | |
load
load(*modules) -> bool
Load passed EnvModules.
Returns:
-
bool(bool) –True if loading was successful.
Source code in ipsl_common/envmodules.py
51 52 53 54 55 56 57 | |
purge
purge() -> bool
Purge all loaded EnvModules.
Returns:
-
bool(bool) –True if purging was successful.
Source code in ipsl_common/envmodules.py
43 44 45 46 47 48 49 | |
machine
Functions:
is_espri_spirit
is_espri_spirit() -> bool
Check if this is ESPRI/Spirit machine (1 or 2)
Source code in ipsl_common/machine.py
17 18 19 | |
is_espri_spiritx
is_espri_spiritx() -> bool
Check if this is ESPRI/SpiritX machine (1 or 2)
Source code in ipsl_common/machine.py
22 23 24 | |
is_idris_jean_zay
is_idris_jean_zay() -> bool
Check if this is IDRIS/JeanZay machine (also pp, visu)
Source code in ipsl_common/machine.py
7 8 9 | |
is_idris_jean_zay_pp
is_idris_jean_zay_pp() -> bool
Check if this is IDRIS/JeanZay post-processing machine
Source code in ipsl_common/machine.py
12 13 14 | |
is_tgcc_irene
is_tgcc_irene() -> bool
Check if this is TGCC/Irene machine
Source code in ipsl_common/machine.py
27 28 29 | |
modipsl
Modules
card_file
Classes
CardFileDecoder
CardFileDecoder(include_positions: bool = False)
Bases: Transformer
Decoder performs translation from *.card file to a dictionary.
The translation rules are:
*.card |
Python | Comment |
|---|---|---|
| section | dict[str, dict] |
Top-level dicts are sections |
| key-value | dict |
Each item is a sigle kv pair |
| list | list |
Empty or with elements |
| nested list | list[list] |
List of lists |
| range | tuple[int] |
Integer range in the form: START:STEP:END |
| string | str |
Unquoted (with chars: -./${}*) and double quoted |
| integer number | int |
--- |
| real number | float |
Including scientific notation |
true/y |
True |
Case insensitive |
false/n |
False |
Case insensitive |
Empty/NONE |
None |
Empty value that acts like null |
Warning
CardFileDecoder works on items not belonging to any section, e.g. top-level key-value pairs. However, the load(s) functions require that a valid *.card file contains all keys inside some section.
Initialize CardFileDecoder.
Parameters:
-
(include_positionsbool, default:False) –include textual positions of keys and values (offset from the start)
Source code in ipsl_common/modipsl/card_file.py
275 276 277 278 279 280 281 | |
decode
decode(text: str) -> dict[str, Any]
Decode *.card text into dictionary.
Parameters:
-
(textstr) –content of the
*.cardfile
Returns:
-
dict(dict[str, Any]) –Decoded
*.cardfile
Source code in ipsl_common/modipsl/card_file.py
283 284 285 286 287 288 289 290 291 292 293 | |
CardFileEncoder
CardFileEncoder(
truthy_value: str = "true",
falsey_value: str = "false",
encode_none_in_kv: bool = False,
)
Encoder translates Python dictionary to *.card file.
The translation rules are:
| Python | *.card |
Comment |
|---|---|---|
dict[str, dict] |
section | Top-level keys with dicts are sections |
dict |
key-value | Each item is a sigle kv pair |
list |
list | Empty or with elements |
list[list] |
nested list | List of lists |
tuple[int] |
range | Integer range in the form: START:STEP:END |
str |
string | Unquoted (with chars: -./${}*) and double quoted |
int |
integer number | --- |
float |
real number | Including scientific notation |
bool |
true/false |
Case insensitive |
None |
Empty/NONE |
Empty value that acts like null |
The translation is straightforward, based on Python type a specific conversion is performed.
No grammar, nor parse tree is used during this step. A null value, NONE in lists
is always encoded as NONE, so that the number of list elements is preserved. However,
a single key with NONE is encoded as a= by default. See :encode_none_in_kv
argument for more information.
Example:
from ipsl_common.modipsl.card_file import CardFileEncoder
text = CardFileEncoder().encode(dictionary)
If dictionary contains:
{
"UserChoices": {
"LMDZ_Physics": "NPv6.2"
},
"BoundaryFiles": {
"ListNonDel": [
["${R_IN}/ATM/INPUT_CE0L/Albedo4_deg.nc", "Albedo.nc"],
["${R_IN}/ATM/INPUT_CE0L/ECDYN4.nc", "ECDYN.nc"]
]
}
}
Then, the encoded *.card file would look as follows:
[UserChoices]
LMDZ_Physics = NPv6.2
[BoundaryFiles]
ListNonDel = (${R_IN}/ATM/INPUT_CE0L/Albedo4_deg.nc, Albedo.nc), (${R_IN}/ATM/INPUT_CE0L/ECDYN4.nc, ECDYN.nc)
Tip
Python representation of the *.card file doesn't contain any textual position of
particular elements (keys, values, comments, whitespaces, etc.), thus, re-encoding of
the exact input *.card file is impossible. In order to recreate the original file,
or modify a file while keeping the original comments, whitespaces, and order of elements,
use the designated modify functions.
Initialize CardFileEncoder.
Parameters:
-
(truthy_valuestr, default:'true') –label used to encode True
-
(falsey_valuestr, default:'false') –label used to encode False
-
(encode_none_in_kvbool, default:False) –encode null
NONEwith single key-values (e.g. a=NONE)
Source code in ipsl_common/modipsl/card_file.py
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | |
encode
encode(obj: Any, _nested_list_indent=None) -> str
Encode dictionary or other Python object into *.card file.
Parameters:
-
(objAny) –dictionary or Python object
-
–_nested_list_indentinternal parameter used to indent nested lists, so that each sublist starts at the same position.
Returns:
-
str–Encoded text of a
*.deffile
Info
_nested_list_indent parameter is internal, even if set by the user,
it will be set again during the encoding to match the length of a key
with a nested list as its value.
Source code in ipsl_common/modipsl/card_file.py
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 | |
Functions:
dump
dump(obj: dict, buffer: TextIOBase) -> None
Dump dictionary into *.card text/file buffer.
Parameters:
-
(objdict) –dictionary to dump to a file
-
(bufferTextIOBase) –text or file buffer for storing *.card file
Source code in ipsl_common/modipsl/card_file.py
53 54 55 56 57 58 59 60 61 62 | |
dumps
dumps(obj: dict) -> str
Dump dictionary into *.card string.
Parameters:
-
(objdict) –dictionary to dump to a file
Source code in ipsl_common/modipsl/card_file.py
65 66 67 68 69 70 71 | |
load
load(
buffer: TextIOBase, include_positions: bool = False
) -> dict
Load *.card text/file buffer into dictionary.
Parameters:
-
(bufferTextIOBase) –text or file buffer with the
*.cardfile -
(include_positionsbool, default:False) –include textual positions of elements (section, key, value)
Returns:
-
dict(dict) –Loaded
*.cardfile
Source code in ipsl_common/modipsl/card_file.py
16 17 18 19 20 21 22 23 24 25 26 27 28 | |
loads
loads(text: str, include_positions: bool = False) -> dict
Load *.card file string into dictionary.
Parameters:
-
(textstr) –content of the
*.cardfile -
(include_positionsbool, default:False) –include textual positions of elements (section, key, value)
Returns:
-
dict(dict) –Loaded
*.cardfile
Source code in ipsl_common/modipsl/card_file.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | |
modify
modify(
buffer: TextIOBase,
new_obj: dict,
buffer_out: TextIOBase | None = None,
insert_header: str = "",
) -> None
Modify *.card text/file buffer with minimal amount of changes.
The output text/file buffer follows changes made to new_obj representation of *.card file.
The modifications are performed, so that the minimal amount of changes is applied.
As a result, the diff between the old and new file content is minimal and no comments
or whitespaces are lost beyond what is neccessary. The new_obj can remove, modify,
and/or add new key-value pairs.
Parameters:
-
(bufferTextIOBase) –text or file buffer for reading the file (optionally to write to the file)
-
(new_objdict) –modified representation of the *.card file content
-
(buffer_outTextIOBase | None, default:None) –optional output buffer for writing the modified file content
-
(insert_headerstr, default:'') –optional header inserted before appended key-value pairs
Source code in ipsl_common/modipsl/card_file.py
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
modifys
modifys(
text: str, new_obj: dict, insert_header: str = ""
) -> str
Modify *.card file string with minimal amount of changes.
The output text follows changes made to new_obj representation of *.card file.
The modifications are performed, so that the minimal amount of changes is applied.
As a result, the diff between the old and new file content is minimal and no comments
or whitespaces are lost beyond what is neccessary. The new_obj can remove, modify,
and/or add new key-value pairs.
Parameters:
-
(textstr) –input text with *.card content to modify
-
(new_objdict) –modified representation of the *.card file content
-
(insert_headerstr, default:'') –optional header inserted before appended key-value pairs
Returns:
-
str(str) –Modified text
Source code in ipsl_common/modipsl/card_file.py
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | |
common
Functions:
index_after_newline
index_after_newline(text: str, position: int) -> int
Return new position with the newline eaten at the input position
Source code in ipsl_common/modipsl/common.py
7 8 9 10 11 12 | |
inject_value_position
inject_value_position(func: Callable) -> Callable
Retrieve in-text position of values from their token(s).
This decorator works with grammar generated methods of the lark.Transformer.
It works well on scalar (e.g. 1, 3.14, True) and compound
(e.g. (1, 2, 3)) values, because those are represented using only
lark.Tokens, each with a start_pos/end_pos attributes.
The decorator converts the normal parsing method into the one
that takes those position attributes and transform the parsed value to
a dictionary comining the original value with its positions.
Parameters:
-
(funcCallable) –lark.Transformer based method to decorate
Returns:
-
Callable(Callable) –decorated method returning dictionary with the parsed value and its positions in the text
Source code in ipsl_common/modipsl/common.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | |
is_empty_rule_branch
is_empty_rule_branch(
entity: Any, rule_name: str | None = None
) -> bool
Check if entity is an empty rule branch of an AST with an empty Token.
Such empty branch is created when an optional sub-rule
(e.g. rule: optional? required) is not present.
Parameters:
-
(entityAny) –potential empty rule branch to check
-
(rule_namestr | None, default:None) –optional grammar rule name to validate in the empty rule branch
Returns:
-
bool(bool) –True, if entity is an empty rule branch
Source code in ipsl_common/modipsl/common.py
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | |
retrieve_values
retrieve_values(obj: Any) -> dict | list
Retrieve only values from a nested structure with position attributes.
The .def/.card decoding with inserting value/key/section positions
convert those files into Python dictionaries which, apart from values,
contains additional keys such as start_pos, end_pos, key_start_pos,
section_start_pos and section_end_pos. Those keys encode the start/end
positions of various elements of those file formats. This function removes
them and it keeps only the original values from the files.
Example input dictionary:
{
'section': {
'b': {
'value': 2,
'start_pos': 16,
'end_pos': 17,
'key_start_pos': 14
}
}
}
And the result:
{
'section': {
'b': 2
}
}
Parameters:
-
(objAny) –object with values to retrive
Returns:
-
dict(dict | list) –a new object with only values
Source code in ipsl_common/modipsl/common.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | |
def_file
Read, write, and modify *.def file from the IPSL/modipsl project.
The *.def file contains model parameters in the key-value format. The format
is extremely simple in comparison to similar formats, like *.ini or *.toml, as
it doesn't provide sections, nor standarized datatypes.
Usually, model configuration files contain dozens or hundred of parameters
with scalars (int, float, str), arrays, or special _AUTO_/_AUTOBLOCK_ values.
The special "auto" values are used by the IPSL/modipsl/libIGCM projects to mark place where an external script, called component driver, should inject configuration values.
Examples usage:
// Follows Python convention of the JSON module with load(), dump(), etc. functions
from ipsl_common.modipsl.def_file import load, dump
with open("run_dynamico.def", "r") as f:
parameters = load(f)
// Modify loaded parameters
parameters["start_file_name"] = "start2024.nc"
with open("new_run_dynamico.def", "w") as g:
dump(parameters, g)
Loading an example *.def file:
INCLUDEDEF=run_lmdz.def
INCLUDEDEF=run_dynamico.def
use_forcing=y
g=_AUTO_: DEFAULT=9.8
start_file_name=start2023
physics="always"
Gives the following dictionary:
{
'INCLUDEDEF': ['run_lmdz.def', 'run_dynamico.def'],
'g': ('_AUTO_', 9.8),
'physics': '"always"',
'start_file_name': 'start2023',
'use_forcing': True
}
Loaded configuration can be altered and subsequently dumped onto a file or into
a string. The configuration is easy to view and modify, because it is directly
decoded into a Python dictionary. The decoding and encoding process is managed
internally by DefFileDecoder and DefFileEncoder classes with decode() and
encode() methods.
Classes
DefFileDecoder
DefFileDecoder(include_positions: bool = False)
Bases: Transformer
Decoder performs translation from *.def file to a dictionary.
The translation rules are:
*.def |
Python | Comment |
|---|---|---|
| key-value | dict |
Including many key-value pairs and INCLUDEDEF |
| array | list |
Collection of at least 2 elements |
| string | str |
Unquoted and quoted (single or double) strings |
| integer number | int |
Standard integer values |
| real number | float |
Including scientific notation |
true/y |
True |
Case insensitive |
false/n |
False |
Case insensitive |
_AUTO_ |
tuple |
With optional default value |
_AUTOBLOCKER_ |
tuple |
With optional default value |
The first step of the decoder is parsing of *.def file. For this task Lark Earley
parser is used with a simple grammar expressed with EBNF notation. The *.def
grammer doesn't parse well with LALR(1) parser. The parsing produces a parse tree.
The second step transforms the parse tree into Python dictionary using translation rules mentioned in the above table. This transformation is based on a automated visitor pattern called Transformer, which produces the dictionary in a bottom-up manner.
Examples:
from ipsl_common.modipsl.def_file import DefFileDecoder
dictionary = DefFileDecoder().decode(text)
If text contains this *.def file:
radius=6.371229E6
g=9.80665
omega=_AUTO_: DEFAULT=7.292E-5
Then, Python dictionary would look as follows:
{
"radius": 6.371229e6,
"g": 9.80665,
"omega": ("_AUTO_", 7.292e-05),
}
Tip
By default, the result dictionary contains no information about textual
layout of the file. However, by using the argument include_positions=True,
it is possible to refine the dictionary with exact start/end positions of
each value as follows:
{
"radius": {"value": 6371229.0, "start_pos": 50, "end_pos": 60},
"g": {"value": 9.80665, "start_pos": 99, "end_pos": 106},
"omega": {"value": ("_AUTO_", 7.292e-05), "start_pos": 158, "end_pos": 182},
}
Initialize DefFileDecoder.
Parameters:
-
(include_positionsbool, default:False) –include textual positions of keys and values (offset from the start)
Source code in ipsl_common/modipsl/def_file.py
349 350 351 352 353 354 355 | |
decode
decode(content: str) -> dict
Decode *.def content into dictionary.
Parameters:
-
(contentstr) –content of the
*.deffile
Returns:
-
dict(dict) –Decoded
*.deffile
Source code in ipsl_common/modipsl/def_file.py
357 358 359 360 361 362 363 364 365 366 367 | |
DefFileEncoder
DefFileEncoder(
truthy_value: str = "true", falsey_value: str = "false"
)
Encoder performs translation from a dictionary to *.def file.
The translation rules are:
| Python | *.def |
Comment |
|---|---|---|
dict |
key-value | Each INCLUDEDEF value translates to a single key-value |
list |
array | Of at least 2 elements |
str |
string | Quoted strings will contain explicit quote characters |
int |
integer number | --- |
float |
real number | Including scientific notation |
bool |
true/false |
Can be specified with encode arguments |
tuple |
_AUTO_/_AUTOBLOCKER_ |
With optional default value at second position in tuple |
The translation is straightforward, based on Python type a specific conversion is performed. No grammar, nor parse tree is used during this step.
Example:
from ipsl_common.modipsl.def_file import DefFileEncoder
text = DefFileEncoder().encode(dictionary)
If dictionary contains:
{
"radius": 6.371229e6,
"g": 9.80665,
"omega": ("_AUTO_", 7.292e-05),
}
Then, the encoded *.def file would look as follows:
radius = 6371229.0
g = 9.80665
omega = _AUTO_: DEFAULT=7.292e-05
Tip
Python representation of the *.def file doesn't contain any textual position of
particular elements (keys, values, comments, whitespaces, etc.), thus, re-encoding of
the exact input *.def file is impossible. In order to recreate the original file,
or modify a file while keeping the original comments, whitespaces, and order of elements,
use the designated modify functions.
Initialize DefFileEncoder.
Parameters:
-
(truthy_valuestr, default:'true') –label used to encode True
-
(falsey_valuestr, default:'false') –label used to encode False
Source code in ipsl_common/modipsl/def_file.py
510 511 512 513 514 515 516 517 518 519 520 521 522 | |
encode
encode(obj: Any) -> str
Encode dictionary or other Python object into *.def file.
This function works not only on full decoded *.def files,
but it also work on particular Python object such as a list,
or a tuple. In such case, it will take the given object and apply
one of the encoding rules mentioned before.
Parameters:
-
(objAny) –dictionary or Python object
Returns:
-
str–Encoded text of a
*.deffile
Source code in ipsl_common/modipsl/def_file.py
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 | |
Functions:
dump
dump(obj: dict, buffer: TextIOBase) -> None
Dump dictionary into *.def text/file buffer.
Parameters:
-
(objdict) –dictionary to dump to a file
-
(bufferTextIOBase) –text or file buffer for storing *.def file
Source code in ipsl_common/modipsl/def_file.py
103 104 105 106 107 108 109 110 111 112 | |
dumps
dumps(obj: dict) -> str
Dump dictionary into *.def string.
Parameters:
-
(objdict) –dictionary to dump to a file
Source code in ipsl_common/modipsl/def_file.py
115 116 117 118 119 120 121 | |
load
load(
buffer: TextIOBase,
include_positions: bool = False,
return_text: bool = False,
) -> dict | tuple[dict, str]
Load *.def text/file buffer into dictionary.
Parameters:
-
(bufferTextIOBase) –text or file buffer with the
*.deffile -
(include_positionsbool, default:False) –include textual positions of values
Returns:
-
dict(dict | tuple[dict, str]) –Loaded
*.deffile
Source code in ipsl_common/modipsl/def_file.py
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | |
loads
loads(text: str, include_positions: bool = False) -> dict
Load *.def file string into dictionary.
Parameters:
-
(textstr) –content of the
*.deffile -
(include_positionsbool, default:False) –include textual positions of values
Returns:
-
dict(dict) –Loaded
*.deffile
Source code in ipsl_common/modipsl/def_file.py
90 91 92 93 94 95 96 97 98 99 100 | |
modify
modify(
buffer: TextIOBase,
new_obj: dict,
buffer_out: TextIOBase | None = None,
insert_header: str = "",
) -> None
Modify *.def text/file buffer with minimal amount of changes.
The output text/file buffer follows changes made to new_obj representation of *.def file.
The modifications are performed, so that the minimal amount of changes is applied.
As a result, the diff between the old and new file content is minimal and no comments
or whitespaces are lost beyond what is neccessary. The new_obj can remove, modify,
and/or add new key-value pairs.
Parameters:
-
(bufferTextIOBase) –text or file buffer for reading the file (optionally to write to the file)
-
(new_objdict) –modified representation of the *.def file content
-
(buffer_outTextIOBase | None, default:None) –optional output buffer for writing the modified file content
-
(insert_headerstr, default:'') –optional header inserted before appended key-value pairs
Source code in ipsl_common/modipsl/def_file.py
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | |
modifys
modifys(
text: str, new_obj: dict, insert_header: str = ""
) -> str
Modify *.def file string with minimal amount of changes.
The output text follows changes made to new_obj representation of *.def file.
The modifications are performed, so that the minimal amount of changes is applied.
As a result, the diff between the old and new file content is minimal and no comments
or whitespaces are lost beyond what is neccessary. The new_obj can remove, modify,
and/or add new key-value pairs.
Parameters:
-
(textstr) –input text with *.def content to modify
-
(new_objdict) –modified representation of the *.def file content
-
(insert_headerstr, default:'') –optional header inserted before appended key-value pairs
Returns:
-
str(str) –Modified text
Source code in ipsl_common/modipsl/def_file.py
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | |
mod_file
Read mod.def file from the IPSL/modipsl project.
The mod.def file contains definitions of coupled model configurations. A single configuration consists of one or more components (e.g. athmospheric model, dynamics, I/O system, experiments).
Examples:
from ipsl_common.modipsl.mod_file import load
with open("mod.def", "r") as f:
configs = load(f)
The loaded dictionary has a fixed schema. Using the following input:
#-H- GRISLI GRISLI stand-alone for Antarctica icesheets (prototype)
#-C- GRISLI trunk/libIGCM HEAD 10 libIGCM .
#-C- GRISLI branches/xios HEAD 26 GRISLI modeles
...
#-S- 7 git https://gitlab.in2p3.fr/ipsl/projets/nemogcm/nemo.git
#-S- 8 svn --username icmc_users https://forge.ipsl.fr/igcmg/svn
the output looks as follows:
{
'configuration': {
'GRISLI': {
'description': ['GRISLI stand-alone for Antarctica icesheets (prototype)']
'components': [
{
'modipsl_dir': '.',
'name': 'libIGCM',
'repository': 10,
'revision': 'HEAD',
'variant': 'trunk/libIGCM'
},
{
'modipsl_dir': 'modeles',
'name': 'GRISLI',
'repository': 26,
'revision': 'HEAD',
'variant': 'branches/xios'
},
(...)
],
},
(...)
},
'repository': {
7: {
'clone_url': 'https://gitlab.in2p3.fr/ipsl/projets/nemogcm/nemo.git',
'type': 'git'
},
8: {
'clone_url': '--username icmc_users https://forge.ipsl.fr/igcmg/svn',
'type': 'svn'
},
(...)
}
}
Warning
Because this module uses iterative matching to patterns (with re.finditer),
it doesn't have a capability to tell, when the *.mod file is not well
formatted, nor invalid. It will siliently skip non-matched lines and move on!
Functions:
load
load(buffer: TextIOBase) -> dict
Load mod.def file from a text/file buffer.
Parameters:
-
(bufferTextIOBase) –text or file buffer with the mod.def file
Returns:
-
dict(dict) –Loaded mod.def file
Source code in ipsl_common/modipsl/mod_file.py
151 152 153 154 155 156 157 158 159 160 | |
loads
loads(content: str) -> dict
Load mod.def file from a string.
Parameters:
-
(contentstr) –content of the mod.def file
Returns:
-
dict(dict) –Loaded mod.def file
Source code in ipsl_common/modipsl/mod_file.py
163 164 165 166 167 168 169 170 171 172 173 174 175 176 | |
path
Utility path/pathlib functions.
Functions:
try_joinpath
try_joinpath(
path: Path, *others: str | Path
) -> Path | None
Test and return joined path if it exists.
This function is especially useful when used with walrus operator (:=).
Example:
if p := try_joinpath(some_dir, "subdir", "file.txt"):
with open(p, "r") as f:
...
Parameters:
-
(pathPath) –path to test
-
(othersstr | Path, default:()) –other paths to join
Returns:
-
Path | None–full joined path if it exists or None
Source code in ipsl_common/path.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
try_path
try_path(path: Path) -> Path | None
Test and return path if it exists.
This function is especially useful when used with walrus operator (:=).
Example:
if p := try_path(some_file):
with open(p, "r") as f:
...
Parameters:
-
(pathPath) –path to test
Returns:
-
Path | None–path if it exists or None
Source code in ipsl_common/path.py
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
python
Python-related functions, such as: checking Python version.
Functions:
check_minimal_version
check_minimal_version(
major: int,
minor: int,
reason: str = "",
exit_on_fail: bool = False,
) -> None
Check if minimal Python version is present. If not, print warning (default) or exit program entirely. The passed major.minor version is not validated and it can have any value, e.g. even non-existing Python versions like 4.24.
Source code in ipsl_common/python.py
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
scripts
Modules
slurm_logs
Process slurm logs from the command-line.
Examples:
ipsl_slurm_logs slurm.log --output-dir output_test/ --remove-trailing-whitespaces
The above command separates slurm.log containing model execution using 4 MPI processes into
distinct files inside the output_test/ directory:
output_test/
├── output_0.log
├── output_10.log
├── output_11.log
├── output_12.log
JSON example:
ipsl_slurm_logs slurm.log --json > slurm.json
Will separate the slurm.log into a JSON format.
Functions:
main
main()
Source code in ipsl_common/scripts/slurm_logs.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | |
slurm
Improved interaction with the SLURM ecosystem.
This module includes: functions to separate labelled SLURM logs.
Functions:
separate_labelled_log
separate_labelled_log(
fp: TextIO, remove_trailing_whitespaces: bool = False
) -> dict[int | str, list[str]]
Seperate SLURM labelled log by process IDs.
Almost each line in the SLURM labelled log starts with the process number followed by a colon:
22: USING DEFAULTS : area_radius1 = 3360.00000000000
26: USING DEFAULTS : area_radius1 = 3360.00000000000
0: USING DEFAULTS : area_radius1 = 3360.00000000000
0: GETIN area_radius1 = 3360.00000000000
12: USING DEFAULTS : area_rotation_pre = 0.000000000000000E+000
12: USING DEFAULTS : area_rotation = 0.000000000000000E+000
This function reads such log file and groups lines coming from the same process.
If a line doesn't have the label, which can happen when it is an error coming
from srun or sbatch, it is placed under the slurm key.
This function might take a lot of memory for big logs, because it loads all
the processed lines into one dictionary. Consider using
separate_labelled_log_to_files() to separate files into files on-the-fly.
Parameters:
-
(fpTextIO) –text I/O stream with the log's content
-
(remove_trailing_whitespacesbool, default:False) –remove trailing whitespaces and empty lines
Returns: dict: labelled log lines grouped by processes.
Source code in ipsl_common/slurm.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | |
separate_labelled_log_to_files
separate_labelled_log_to_files(
fp: TextIO,
output_dir: Path,
output_name: str,
remove_trailing_whitespaces: bool = False,
) -> None
Seperate SLURM labelled log by process IDs, on-the-fly, into dedicated log files.
This function will not load the log content into memory like separate_labelled_log() does.
Instead, it will process it line-by-line and write to dedicated log files.
Use this function for big logs.
Parameters:
-
(fpTextIO) –text I/O stream with the log's content
-
(output_dirPath) –directory where dedicated logs will be placed (must exist)
-
(output_namestr) –the name of the output file (must contain
{process_id}as a placeholder of the process ID) -
(remove_trailing_whitespacesbool, default:False) –remove trailing whitespaces and empty lines
Source code in ipsl_common/slurm.py
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | |
str
Collection of string related functions
Functions:
contains
contains(text: str, *args) -> bool
Check if text contains all given substrings.
Parameters:
Returns:
-
bool(bool) –True if all substrings are found in the text.
Source code in ipsl_common/str.py
6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
contains_any
contains_any(text: str, *args) -> bool
Check if text contains any of given substrings.
Parameters:
Returns:
-
bool(bool) –True if any of substrings is found in the text.
Source code in ipsl_common/str.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
is_float
is_float(text: str) -> bool
Check if text represents floating value.
Parameters:
-
(textstr) –Text to verify
Returns:
-
bool(bool) –True if text represents a floating value.
Source code in ipsl_common/str.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | |
is_int
is_int(text: str) -> bool
Check if text represents integer value.
Parameters:
-
(textstr) –Text to verify
Returns:
-
bool(bool) –True if text represents an integer value.
Source code in ipsl_common/str.py
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | |
replace_text
replace_text(
text: str,
replacements: list[tuple[int, int, str]],
sort_replacements: bool = True,
) -> str
Replace given text by a collection of replacements. Each replacement defines starting and ending positions with a new text value to replace. If the start and end positions of a replacements are the same, the text will be inject at given position. Using an empty replacement text "" will remove text between start and end positions.
Parameters:
-
(textstr) –Text to replace
-
(replacementslist[tuple[int, int, str]]) –Collection of replacements of the form (start position, end position, new value).
-
(sort_replacementsbool, default:True) –Sort replacements by their start/end positions.
Returns: str: New text with applied replacements.
Source code in ipsl_common/str.py
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | |