From 788dd756bcc4756a3c71107f7f5e3349c8fba991 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 17 Feb 2020 00:03:58 +0200 Subject: [PATCH] style(SPELL): fix spelling errors; fix minor doc/indentations --- .travis.yml | 8 +++---- CONTRIBUTING.rst | 14 ++----------- Notebooks/CarsDB-compare.py | 16 +++++++------- Notebooks/Cycler.py | 4 ++-- Notebooks/README.md | 18 ++++++++-------- README.rst | 34 +++++++++++++++--------------- datatree.txt | 2 +- docs/code.rst | 16 +++++++------- docs/faq.rst | 4 ++-- setup.py | 2 +- tests/test_cycler.py | 6 +++--- tests/test_instances.py | 12 +++++------ wltp/autograph.py | 4 ++-- wltp/cli.py | 16 +++++++------- wltp/cycler.py | 42 ++++++++++++++++++------------------- wltp/cycles/__init__.py | 34 +++++++++++++++--------------- wltp/datamodel.py | 14 ++++++------- wltp/downscale.py | 4 ++-- wltp/engine.py | 18 ++++++++-------- wltp/experiment.py | 15 ++++++------- wltp/invariants.py | 4 ++-- wltp/io.py | 10 ++++++--- wltp/vehicle.py | 6 +++--- wltp/vmax.py | 11 +++++----- 24 files changed, 155 insertions(+), 159 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9cfdb7fc..09ed5f38 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,12 @@ ## TravisCI config # git: - depth: 3 + depth: 3 language: python python: - - "3.6" - - "3.7" - # - "3.8-dev" # too slow! + - "3.6" + - "3.7" + # - "3.8-dev" # too slow! # matrix: # allow_failures: # - python: "3.8-dev" diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 8b8d2da7..f487ebcf 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -14,13 +14,7 @@ The typical development procedure is like this: .. code-block:: console - $ python setup.py nosetests --with-coverage --cover-package wltp.model,wltp.experiment --cover-min-percentage=80 - - - .. Tip:: You can enter just: ``python setup.py test_all`` instead of the above cmd-line - since it has been *aliased* in the :file:`setup.cfg` file. - Check this file for more example commands to use during development. - + $ pytest 4. If you made a rather important modification, update also the :doc:`CHANGES` file and/or other documents (i.e. README.rst). To see the rendered results of the documents, @@ -29,8 +23,6 @@ The typical development procedure is like this: .. code-block:: console $ python setup.py build_sphinx # Builds html docs - $ python setup.py build_sphinx -b doctest # Checks if python-code embeded in comments runs ok. - 5. If there are no problems, commit your changes with a descriptive message. @@ -39,7 +31,5 @@ The typical development procedure is like this: You can check whether your merge-request indeed passed the tests by checking its build-status |build-status| on the integration-server's site (TravisCI). - .. Hint:: Skim through the small IPython developer's documentantion on the matter: + .. Hint:: Skim through the small IPython developer's documentation on the matter: `The perfect pull request `_ - - diff --git a/Notebooks/CarsDB-compare.py b/Notebooks/CarsDB-compare.py index 3b27efca..2f18882d 100644 --- a/Notebooks/CarsDB-compare.py +++ b/Notebooks/CarsDB-compare.py @@ -95,7 +95,7 @@ def load_accdb_and_python_datasets(veh_nums=None): v_cols = "v v_orig v_cap v_downscale".split() c1[v_cols] = vround(c1[v_cols]) - ## accdb does not oofer `n_max`.(?) + ## accdb does not offer `n_max`.(?) p1["n_max"] = nround1(p1["n_max1 n_max2 n_max3".split()].max(axis=1)) return p1, c1, p2, c2 @@ -227,7 +227,7 @@ def load_accdb_and_python_datasets(veh_nums=None): # %% [markdown] # ## Compare a vehicle from AccDB <-->PyAlgo *interactively* -# **TODO:** collect and hide all this comprarison GUI code below into a python module. +# **TODO:** collect and hide all this comparison GUI code below into a python module. # %% case_loaded = [None, None] @@ -243,7 +243,7 @@ def _load_interactive_case( cycle = c2.loc[case_name].dropna(how="all", axis=1).copy() - ## Scale each flag into a different value, to plot separatly, and + ## Scale each flag into a different value, to plot separately, and # to plot in the same axis as V # (bc when plotting flags in `secondary_y`, grid is not working) # @@ -295,7 +295,7 @@ def is_velocity(col): return l1, l2 -def define_schenes(): +def define_schemes(): """Predfined case/pan/zooms of the compraison diagram below.""" return [ ## (label, caseno, zoom, pan, *other-UNUSED) @@ -453,7 +453,7 @@ def refresh_tabs(): AxisScenes.options = [ (f"{caseno}: {label}", (caseno, zoom, pan, *other)) - for label, caseno, zoom, pan, *other in define_schenes() + for label, caseno, zoom, pan, *other in define_schemes() ] needs_retabbing = False if out_specs and len(out_specs[0]) < 3: @@ -542,7 +542,7 @@ def recreate_fig(): for i in range(3): fig_nums = plt.get_fignums() fig = plt.figure( - num='Compare AccDB <--> PyAlgo "Inital Gear"', figsize=(20, 12) + num='Compare AccDB <--> PyAlgo "Initial Gear"', figsize=(20, 12) ) if fig.number in set(fig_nums): fig.clear() @@ -650,7 +650,7 @@ def plot_gear_flags( # ax2.grid(True, axis="both", which="both") ax.grid(True, axis="both", which="both") - # Re-tighten if ax3 has (diss)appeared. + # Re-tighten if ax3 has (dis)appeared. # Had to use `rect` or axis-title half-hidden the first time fig is created! fig.tight_layout(rect=[0, 0, 1, 0.985]) @@ -719,7 +719,7 @@ def is_bad_g2_in_decel_to_stop(accdb, cyc, prop): # %% [markdown] -# ### Insufficient power where more than one gears are N-valid: +# ### Insufficient power where more than one gears are N-valid: # %% def is_more_low_powered_gears(cyc): diff --git a/Notebooks/Cycler.py b/Notebooks/Cycler.py index 4b7f9327..c201792e 100644 --- a/Notebooks/Cycler.py +++ b/Notebooks/Cycler.py @@ -218,7 +218,7 @@ def flag_aggregates(ok_flags): max_zoom = 48.0 -## Scale each flag into a different value, to plot separatly, and +## Scale each flag into a different value, to plot separately, and # to plot in the same axis as V # (bc when plotting flags in `secondary_y`, grid is not working) # @@ -298,7 +298,7 @@ def plot_gear(gear="g2", zoom=48, pan=13.8): def phase(cond): - return pm._identify_conjecutive_truths((cycle.v > 1) & cond, True).astype(int) + return pm._identify_consecutive_truths((cycle.v > 1) & cond, True).astype(int) A = (-cycle.v.astype(int)).diff(-1) # GTR's acceleration definition diff --git a/Notebooks/README.md b/Notebooks/README.md index 969a8337..ac1be486 100644 --- a/Notebooks/README.md +++ b/Notebooks/README.md @@ -15,10 +15,10 @@ Notebooks for processing UNECE's WLTP reference implementations in Python and MS RunVehicle.ipynb # sample code to run sample vehicle data Cycler.ipynb # (WIP) run a vehicle from the h5db, step-by-step. - CarsDB-compare.ipynb # compare results stored h5db with AccDb + CarsDB-compare.ipynb # compare results stored h5db with AccDb CarsDB-msaccess.ipynb # populate h5db with AccDB test-car input & output CarsDB-pyalgo.ipynb # populate h5db with results from the old python code - HDF5-APIh-help.ipynb # list usefull HDF5 methods + HDF5-APIh-help.ipynb # list useful HDF5 methods VMax.ipynb # VMax experiments Rounding.ipynb # showcase ROUNDING across MSAccess, Python, Matlab & C# ../tests/vehdb.py # support code for reading & validating vehicles from HD5 files @@ -40,12 +40,12 @@ Notebooks for processing UNECE's WLTP reference implementations in Python and MS ## HDF5 -The 2019 reference implementation is written in `WLTP_GS_calculation_15032019_for_prog_code_subgroup.accdb` +The 2019 reference implementation is written in `WLTP_GS_calculation_15032019_for_prog_code_subgroup.accdb` *MSAccess* MSAccess database, which facilitates the development & execution of the algorithm by storing any and all data needed during those phases. To substitute those facilities i used the *pandas*+*HDF5* file-format to store data, -peristently, across code runs. +persistently, across code runs. - Help on `pandas` HDF5 facilities: https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-hdf5 - Help on the underlying `tables` library: https://www.pytables.org/ @@ -59,16 +59,16 @@ peristently, across code runs. Every `VehData/WltpGS-*.h5` has this structure: vehicles/ - +--v001/ the case (not vehicle_num) + +--v001/ the case (not vehicle_num) | +--prop (INP/OUT, series) all kv-pairs from input-specs & scalar outputs from accdb | +--wot (INPUT, df) the wot for the vehicle of the case, index by n | +--cycle (OUTPUT, df) cycle-run generated by AccDB/Python, etc | +--override (INP, series) pyalgo must also override these kv-pairs +... -Only the `VehData/WltpGS-msaccess.h5` contains all `/vehicles/001/{prop,wot,override}`; -the rest contain just `/vehicles/001/{cycle,ospec}`, since they reuse `prop` & `wot` -from *msaccess to produce their outputs. +Only the `VehData/WltpGS-msaccess.h5` contains all `/vehicles/001/{prop,wot,override}`; +the rest contain just `/vehicles/001/{cycle,ospec}`, since they reuse `prop` & `wot` +from *msaccess to produce their outputs. ## Install and launch the *notebooks* @@ -106,7 +106,7 @@ Reproduce the *exact same* conda-env that will be called *jupyter*:: > pip install blackcellmagic nb-black columnize > > **Note (to the maintainer):** -> Maintain the env-file by running this terminal command after any programm (un)install:: +> Maintain the env-file by running this terminal command after any program (un)install:: > > conda env export -n jupyter | grep -vE 'nodejs|m2-' > conda/environment.yaml diff --git a/README.rst b/README.rst index 37adb819..6531c624 100644 --- a/README.rst +++ b/README.rst @@ -75,7 +75,7 @@ Quick-start Prerequisites: ^^^^^^^^^^^^^^ -**Python-3.6+** is required and **Pytrhon-3.7** recommended. +**Python-3.6+** is required and **Python-3.7** recommended. It requires **numpy/scipy** and **pandas** libraries with native backends. .. Tip:: @@ -122,10 +122,10 @@ From within the project directory, run one of these commands to install it: .. code-block:: bash $ wltp --version - 1.0.0.dev12 + ... $ wltp --help - ... + ... See: :ref:`wltp-usage` @@ -199,10 +199,10 @@ The files and folders of the project are listed below (see also :ref:`architectu | +--datamodel # schemas & defaults for data of algo | +--cycler # code for generating the cycle | +--engine # formulae for engine power & revolutions and gear-box - | +--vehicle # formulae for cyle/vehicle dynamics + | +--vehicle # formulae for cycle/vehicle dynamics | +--vmax # formulae estimating `v_max` from wot | +--downscale # formulae downscaling cycles based on pmr/test_mass ratio - | +--invariants # definitions & idenmpotent formulae for physics/engineering + | +--invariants # definitions & idempotent formulae for physics/engineering | +--io # utilities for starting-up, parsing, naming and spitting data | +--utils # software utils unrelated to physics or engineering | +--cli # (OUTDATED) command-line entry-point for launching this wltp tool @@ -211,7 +211,7 @@ The files and folders of the project are listed below (see also :ref:`architectu +--tests/ # (package) Test-TestCases +--vehdb # Utils for manipulating h5db with accdb & pyalgo cases. +--docs/ # (folder) documentation - | +--pyplots/ # (DEPRECATED by notebooks) scripts plotting the metric diagrams embeded in the README + | +--pyplots/ # (DEPRECATED by notebooks) scripts plotting the metric diagrams embedded in the README +--Notebooks/ # Jupyter notebooks for running & comparing results (see `Notebooks/README.md`) +--AccDB_src/ # AccDB code & queries extracted and stored as text +--setup.py # (script) The entry point for `setuptools`, installing, testing, etc @@ -245,13 +245,13 @@ try to import the project to check its version: .. Tip: - The use :command:`ipython` is preffered over :command:`python` since it offers various user-friendly + The use :command:`ipython` is preferred over :command:`python` since it offers various user-friendly facilities, such as pressing :kbd:`Tab` for completions, or allowing you to suffix commands with ``?`` or ``??`` to get help and read their source-code. Additionally you can copy any python commands starting with ``>>>`` and ``...`` and copy paste them directly into the ipython interpreter; it will remove these prefixes. - But in :command:`python` you have to remove it youself. + But in :command:`python` you have to remove it yourself. If everything works, create the :term:`datamodel` of the experiment. You can assemble the model-tree by the use of: @@ -277,7 +277,7 @@ For instance: ... "p_rated": 100, ... "n_rated": 5450, ... "n_idle": 950, - ... "n_min": None, ## Manufacturers my overridde it + ... "n_min": None, ## Manufacturers my override it ... "gear_ratios": [120.5, 75, 50, 43, 37, 32], ... "f0": 100, ... "f1": 0.5, @@ -474,7 +474,7 @@ All the above commands creates two files: :alt: Screenshot of the `wltp_excel_runner.xlsm` file. After opening it the first tie, enable the macros on the workbook, select the python-code at the left and click - the :menuselection:`Run Selection as Pyhon` button; one sheet per vehicle should be created. + the :menuselection:`Run Selection as Python` button; one sheet per vehicle should be created. The excel-file contains additionally appropriate *VBA* modules allowing you to invoke *Python code* present in *selected cells* with a click of a button, and python-functions declared in the python-script, below, @@ -531,7 +531,7 @@ Data Structures: Computations are vectorial, based on `hierarchical dataframes `_, all of them stored in a single structure, the `datamodel`. -In case the computation breaks, you can still retrive all intermediate results +In case the computation breaks, you can still retrieve all intermediate results till that point. .. TODO:: @@ -689,7 +689,7 @@ identified back by :func:`wltp.cycles.identify_cycle_v_crc`: ======= ========= ===== ====== ==== ==== ==== ==== ======== =========== \ CRC32 SUM ------------------ ------------------------------------- --------------------- -\ by_phase cummulative by_phase cummulative +\ by_phase cumulative by_phase cumulative ------------------ ------------------- ---------------- -------- ----------- *class* *part* *V* *A0* *A1* *V* *A0* *A1* *V* *V* ======= ========= ===== ====== ==== ==== ==== ==== ======== =========== @@ -743,7 +743,7 @@ The typical development procedure is like this: .. code-block:: shell python setup.py build_sphinx # Builds html docs - python setup.py build_sphinx -b doctest # Checks if python-code embeded in comments runs ok. + python setup.py build_sphinx -b doctest # Checks if python-code embedded in comments runs ok. 5. If there are no problems, commit your changes with a descriptive message. @@ -752,7 +752,7 @@ The typical development procedure is like this: You can check whether your merge-request indeed passed the tests by checking its build-status |travis-status| on the integration-server's site (TravisCI). - .. Hint:: Skim through the small IPython developer's documentantion on the matter: + .. Hint:: Skim through the small IPython developer's documentation on the matter: `The perfect pull request `_ @@ -858,7 +858,7 @@ See also :ref:`architecture:Architecture`. sphinx The text-oriented language, a superset of `Restructured Text `_, - used to write the documentation for this project, with simlar capabilities to *LaTeX*, + used to write the documentation for this project, with similar capabilities to *LaTeX*, but for humans, e.g., the Linux kernel adopted this textual format on 2016. http://sphinx-doc.org/ @@ -871,7 +871,7 @@ See also :ref:`architecture:Architecture`. depending on context. A *Jupyter Notebook* document is composed of an ordered list of input/output *cells* - which contain code in variou languages, text (using Markdown), mathematics, plots and + which contain code in various languages, text (using Markdown), mathematics, plots and rich media, usually ending with the ".ipynb" extension. .. _begin-replacements: @@ -904,7 +904,7 @@ See also :ref:`architecture:Architecture`. :target: https://travis-ci.org/JRCSTU/wltp/builds .. |appveyor-status| image:: https://ci.appveyor.com/api/projects/status/0e2dcudyuku1w1gd?svg=true - :alt: Apveyor continuous integration testing ok? (Windows) + :alt: Appveyor continuous integration testing ok? (Windows) :scale: 100% :target: https://ci.appveyor.com/project/JRCSTU/wltp diff --git a/datatree.txt b/datatree.txt index 768d7026..843bf0e8 100644 --- a/datatree.txt +++ b/datatree.txt @@ -83,5 +83,5 @@ /wot/p_resist /wot/sign_p_remain_stable /wot/v -/wot/zero_crosings +/wot/zero_crossings /wots_vmax \ No newline at end of file diff --git a/docs/code.rst b/docs/code.rst index 02421471..cac7d0a9 100644 --- a/docs/code.rst +++ b/docs/code.rst @@ -92,7 +92,7 @@ Module: :mod:`wltp.idgears` :members: -Validation tests & HDF5 DB +Validation tests & HDF5 DB -------------------------- Among the various tests, those running on 'sample' databases for comparing differences with existing tool are the following: @@ -181,7 +181,7 @@ The :term:`JSON-schema` of the data for this project: - number - 'null' exclusiveMinimum: 0 - description: (OUT) The calculcated maximum velocity, as defined in Annex 2-2.i. + description: (OUT) The calculated maximum velocity, as defined in Annex 2-2.i. n_vmax: title: engine speed for maximum vehicle velocity type: @@ -335,7 +335,7 @@ The :term:`JSON-schema` of the data for this project: n_norm = (n - n_idle) / (n_rated - n_idle) - * The 2nd column or `p_norm` is the normalised values of the full-power load against the p_rated, + * The 2nd column or `p_norm` is the normalized values of the full-power load against the p_rated, within [0, 1]: p_norm = p / p_rated @@ -421,7 +421,7 @@ The :term:`JSON-schema` of the data for this project: default: 0.1 f_n_min: description: For each gear > 2, N :> n_min = n_idle + f_n_min * n_range (unless - `n_min` overriden by manufacturer) + `n_min` overridden by manufacturer) type: - number - 'null' @@ -453,14 +453,14 @@ The :term:`JSON-schema` of the data for this project: $ref: /wltc cycle: description: | - A dataframe matrix with 2-level columns(item, gear), + A dataframe matrix with 2-level columns(item, gear), and items, in addition to those of `grid_wots`: - `v_cycle`: reduced by safety-margin, but not by ASM - `v_dsc`: (optional) - `v_target`: road loads power - - `(ok_..., gN)`: rflags denoting the validty of certainconditions for gear-N - - `g_max0`: does not include corrections for the `g1-->g2 n_min` rule, - nor points with insufficient power. + - `(ok_..., gN)`: rflags denoting the validity of certain conditions for gear-N + - `g_max0`: does not include corrections for the `g1-->g2 n_min` rule, + nor points with insufficient power. definitions: positiveInteger: type: integer diff --git a/docs/faq.rst b/docs/faq.rst index 6cf94515..9a01158e 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -32,7 +32,7 @@ In a broad view, the core algorithm of the project is "copylefted" with the *EUPL-1.1+ license*, and it includes files from other "non-copyleft" open source licenses like -MIT MIT License* and *Apache License*, appropriately marked as such. So in an nutshell, you can study it, copy it, or import and use ot from your programs is without any obligation. -You may distrbute & publish a modified version, as long as you always distribute & publish +You may distribute & publish a modified version, as long as you always distribute & publish the sources of your changes. Technical @@ -88,7 +88,7 @@ is a demanding, but manageable, task. Here is a checklist of things that might I do not have python / cannot install it. Is it possible to try a *demo*? -------------------------------------------------------------------------- -Launch it in a binder server byclicking the respective badge at the top of +Launch it in a binder server by clicking the respective badge at the top of the landing of the project. .. image:: docs/_static/BinderLink.png diff --git a/setup.py b/setup.py index 27b2a245..72e7504b 100644 --- a/setup.py +++ b/setup.py @@ -188,7 +188,7 @@ def clean_line(line): "emissions", "fuel-consumption", "gears", - "gearshifs", + "gearshift", "simulator", "driving", "engine", diff --git a/tests/test_cycler.py b/tests/test_cycler.py index 9c55c147..f7196fd8 100644 --- a/tests/test_cycler.py +++ b/tests/test_cycler.py @@ -25,16 +25,16 @@ def gwots(): return pd.DataFrame({("the items", "the gears"): []}) -def test_identify_conjecutive_truths_repeat_threshold_1_is_identical(): +def test_identify_consecutive_truths_repeat_threshold_1_is_identical(): V = datamodel.get_class_v_cycle(0) A = -V.diff(-1) pm = PhaseMarker(phase_repeat_threshold=1) col1 = (V > 1) & (A < 0) - col2 = pm._identify_conjecutive_truths((V > 1) & (A < 0), right_edge=False) + col2 = pm._identify_consecutive_truths((V > 1) & (A < 0), right_edge=False) assert col2.equals(col1) - col2 = pm._identify_conjecutive_truths((V > 1) & (A < 0), right_edge=True) + col2 = pm._identify_consecutive_truths((V > 1) & (A < 0), right_edge=True) assert col2.equals(col1 | col1.shift()) diff --git a/tests/test_instances.py b/tests/test_instances.py index 2cb84a60..d152ef45 100644 --- a/tests/test_instances.py +++ b/tests/test_instances.py @@ -83,20 +83,20 @@ def calc_class_sums(cl): df.columns = ( ("by_phase", "SUM"), ("by_phase", "CRC32"), - ("cummulative", "SUM"), - ("cummulative", "CRC32"), + ("cumulative", "SUM"), + ("cumulative", "CRC32"), ) else: - df.columns = (("by_phase", "CRC32"), ("cummulative", "CRC32")) + df.columns = (("by_phase", "CRC32"), ("cumulative", "CRC32")) return df def test_wltc_checksums(): """ - - ... NOTE:: - The printouts in this TC generate the table + + ... NOTE:: + The printouts in this TC generate the table in :func:`wltp/cycles/cycles.cycle_checksums()`. """ dfs_dict = { diff --git a/wltp/autograph.py b/wltp/autograph.py index 9c06c096..7e3613e7 100644 --- a/wltp/autograph.py +++ b/wltp/autograph.py @@ -59,7 +59,7 @@ def _is_in_my_project(item) -> bool: class Prefkey: - """Index into dicts with a key or a joined(pefix+key), where prefix: tuple""" + """Index into dicts with a key or a joined(prefix+key), where prefix: tuple""" sep = "/" @@ -88,7 +88,7 @@ def _prefkey(self, d, key: _FnKey, default: Union[Callable, Any] = None): class FnHarvester(Prefkey): """ - Collect callables, classes & their methods into ``collected`` atribute. + Collect callables, classes & their methods into ``collected`` attribute. :param collected: a list of 2-tuples:: diff --git a/wltp/cli.py b/wltp/cli.py index c18e3dec..b9b2569d 100644 --- a/wltp/cli.py +++ b/wltp/cli.py @@ -54,7 +54,7 @@ def _init_logging(loglevel, name="%s-cmd" % PROG, skip_root_level=False): def main(argv=None): - """Calculates an engine-map by fitting data-points vectors, use --help for gettting help. + """Calculates an engine-map by fitting data-points vectors, use --help for getting help. REMARKS:: @@ -81,7 +81,7 @@ def main(argv=None): "p_rated": 100, "n_rated": 5450, "n_idle": 950, - "n_min": None, # Can be overriden by manufacturer. + "n_min": None, # Can be overridden by manufacturer. "gear_ratios": [120.5, 75, 50, 43, 37, 32], "f0": 100, "f1": 0.5, @@ -295,7 +295,7 @@ def get_file_format_from_extension(fname): _default_out_file_append = False ## When option `-m MODEL_PATH=VALUE` contains a relative path, # the following is preppended: -_default_model_overridde_path = "/engine/" +_default_model_override_path = "/engine/" _value_parsers = { @@ -506,7 +506,7 @@ def assemble_model(infiles, model_overrides): for (json_path, value) in model_overrides: try: if not json_path.startswith("/"): - json_path = _default_model_overridde_path + json_path + json_path = _default_model_override_path + json_path pandel.set_jsonpointer(mdl, json_path, value) except Exception as ex: raise Exception( @@ -601,7 +601,7 @@ def build_args_parser(program_name, version, desc, epilog): *** JSON: different sub-formats are selected through the 'orient' keyword of Pandas specified with a key-value pair (see: http://pandas.pydata.org/pandas-docs/dev/generated/pandas.io.json.read_json.html). - *** SERIES: uses `pd.Series.from_csv()`. + *** SERIES: uses `pd.Series.read_csv()`. *** Defaults to AUTO, unless reading or , which then is CSV. ** model_path = MODEL_PATH specifies the destination (or source) of the dataframe within the model @@ -645,7 +645,7 @@ def build_args_parser(program_name, version, desc, epilog): FC (g/h) FCnorm (g/h) : normalized against P_MAX PMF (bar) - 4. Irellevant column: + 4. Irrelevant column: X Default when files include headers is 0 (1st row), otherwise it is 'RPM,P,FC'.""" ), @@ -712,7 +712,7 @@ def build_args_parser(program_name, version, desc, epilog): "-M", help=dedent( """\ - get help description for the specfied model path. + get help description for the specified model path. If no path specified, gets the default model-base. """ ), action="append", @@ -725,7 +725,7 @@ def build_args_parser(program_name, version, desc, epilog): help=dedent( """\ specifies output-file(s) to write model-portions into after calculations. - The syntax is indentical to -I, with these differences: + The syntax is identical to -I, with these differences: * Instead of , and write_XXX() methods are used wherever. * One extra key-value pair: ** file_append = [ TRUE | FALSE ] diff --git a/wltp/cycler.py b/wltp/cycler.py index fe662471..4a4cf3e3 100644 --- a/wltp/cycler.py +++ b/wltp/cycler.py @@ -40,7 +40,7 @@ def timelens(cond, shift=1): def calc_acceleration(V: Column) -> np.ndarray: """ - Acordign to formula in Annex 2-3.1 + According to formula in Annex 2-3.1 :return: in m/s^2 @@ -58,15 +58,15 @@ def calc_acceleration(V: Column) -> np.ndarray: @dataclasses.dataclass class PhaseMarker: - """Identifies conjecutive truths in series""" + """Identifies consecutive truths in series""" #: The vehicle is stopped when its velocity is below this number (in kmh), #: by Annex 2-4 this is 1.0 kmh. running_threshold: float = 1.0 - #: (positive) consider *at least* that many conjecutive samples as + #: (positive) consider *at least* that many consecutive samples as #: belonging to a `long_{stop/acc/cruise/dec}` generated column, - #: e.g. for ``phase_repeat_threshold=2`` see the example in :func:`_identify_conjecutive_truths()`. + #: e.g. for ``phase_repeat_threshold=2`` see the example in :func:`_identify_consecutive_truths()`. #: if 0,unspecified (might break) phase_repeat_threshold: int = 2 @@ -74,14 +74,14 @@ class PhaseMarker: #: defined in Annex 2-2.k up_threshold: float = -0.1389 - def _identify_conjecutive_truths( + def _identify_consecutive_truths( self, col: pd.Series, right_edge: bool ) -> pd.Series: """ - Dectect phases with a number of conjecutive trues above some threshold. + Detect phases with a number of consecutive trues above some threshold. :param col: - a bolean series + a boolean series :param right_edge: when true, the `col` includes +1 sample towards the end @@ -102,7 +102,7 @@ def _identify_conjecutive_truths( pm = PhaseMarker() def phase(cond): - return pm._identify_conjecutive_truths((cycle.v > 1) & cond, True).astype(int) + return pm._identify_consecutive_truths((cycle.v > 1) & cond, True).astype(int) RUN = cycle['v'] >= 1 A = (-cycle.v).diff(-1) # GTR's acceleration definition @@ -177,7 +177,7 @@ def add_phase_markers( RUN = cycle[c.run] # def phase(cond): - return self._identify_conjecutive_truths(cond, right_edge=True) + return self._identify_consecutive_truths(cond, right_edge=True) ## Driveability rule phases # @@ -260,7 +260,7 @@ def __init__(self, *velocities: Union[pd.Series, pd.DataFrame], **kwargs): If they are a (dataframe, series, series), they are assigned in :attr:`cycle`, :attr:`V` and :attr:`A` respectively, and - no other procesing happens. + no other processing happens. """ c = wio.pstep_factory.get().cycle @@ -338,7 +338,7 @@ def add_wots(self, gwots: pd.DataFrame): def validate_nims_t_cold_end(self, t_cold_end: int, wltc_parts: Seq[int]): """ - Check `t_cold_end` falls in a gap-stop within the 1st phase. + Check `t_cold_end` falls in a gap-stop within the 1st phase. .. TODO:: Incorporate `validate_nims_t_cold_end()` *properly* in validations pipeline. """ @@ -598,10 +598,10 @@ def _combine_ok_n_gear_flags(self, gflags) -> pd.Series: def combine_ok_n_gear_flags(self, flags: pd.DataFrame): """ - Merge together all N-allowed flags using AND+OR boolean logic. - + Merge together all N-allowed flags using AND+OR boolean logic. + :return: - an int8 dataframe with `1` where where the gear can apply, `0`/`NANFLAG` otherwise. + an int8 dataframe with `1` where where the gear can apply, `0`/`NANFLAG` otherwise. """ c = wio.pstep_factory.get().cycle @@ -654,10 +654,10 @@ def _combine_all_gear_flags(self, gflags) -> pd.Series: def combine_ok_n_p_gear_flags(self, flags: pd.DataFrame): """ - Merge together N+P allowed flags using AND+OR boolean logic. - + Merge together N+P allowed flags using AND+OR boolean logic. + :return: - an int8 dataframe with `1` where where the gear can apply, `0`/`NANFLAG` otherwise. + an int8 dataframe with `1` where where the gear can apply, `0`/`NANFLAG` otherwise. """ c = wio.pstep_factory.get().cycle @@ -685,7 +685,7 @@ def make_gmax0(self, ok_gears: pd.DataFrame): ## +1 for g0 (0-->6 = 7 gears) gids = range(self.gidx.ng + 1) - ## Conver False to NAN to identify samples without any gear + ## Convert False to NAN to identify samples without any gear # (or else, it would be 0, which is used for g0). incrementing_gflags = ok_gears.replace([False, NANFLAG], np.NAN) * gids @@ -701,7 +701,7 @@ def make_gmax0(self, ok_gears: pd.DataFrame): def calc_p_remain(cycle, gidx): """ Return `p_avail - p_req` for all gears > g2 in `gwot` - + TODO: Separate :func:`calc_p_remain` not used yet """ w = wio.pstep_factory.get().wot @@ -722,8 +722,8 @@ def calc_p_remain(cycle, gidx): def calc_ok_p_rule(cycle, gidx): """ - Sufficent power rule for gears > g2, in Annex 2-3.5. - + Sufficient power rule for gears > g2, in Annex 2-3.5. + TODO: Separate :func:`calc_p_remain` not used yet """ c = wio.pstep_factory.get().cycle diff --git a/wltp/cycles/__init__.py b/wltp/cycles/__init__.py index 2aabc66a..8237ec1d 100644 --- a/wltp/cycles/__init__.py +++ b/wltp/cycles/__init__.py @@ -22,7 +22,7 @@ def crc_velocity(V: Iterable, crc: Union[int, str] = 0, full=False) -> str: :param crc: initial CRC value (might be a hex-string) :param full: - print full 32bit number (x8 hex digits), or else, + print full 32bit number (x8 hex digits), or else, just the highest half (the 1st x4 hex digits) :return: the 16 lowest bits of the CRC32 of the trace, as hex-string @@ -34,7 +34,7 @@ def crc_velocity(V: Iterable, crc: Union[int, str] = 0, full=False) -> str: (eg 0xC0FE --> (0xFE, 0xC0); 4. the int16 bytes are then concatanated together, and 5. fed into ZIP's CRC32; - 6. the highest 2 bytes of the CRC32 are (usually) kept, formated in hex + 6. the highest 2 bytes of the CRC32 are (usually) kept, formated in hex (x4 leftmost hex-digits). """ @@ -57,8 +57,8 @@ def crc_velocity(V: Iterable, crc: Union[int, str] = 0, full=False) -> str: @fnt.lru_cache() def cycle_checksums(full=False) -> pd.DataFrame: """ - Return a big table with cummulative and simple SUM & CRC for all class phases. - + Return a big table with cumulative and simple SUM & CRC for all class phases. + :param full: CRCs contain the full 32bit number (x8 hex digits) @@ -71,9 +71,9 @@ def cycle_checksums(full=False) -> pd.DataFrame: table_csv = dedent( """ checksum CRC32 CRC32 CRC32 CRC32 CRC32 CRC32 SUM SUM - accumulation by_phase by_phase by_phase cummulative cummulative cummulative by_phase cummulative + accumulation by_phase by_phase by_phase cumulative cumulative cumulative by_phase cumulative phasing V VA0 VA1 V VA0 VA1 V V - class part + class part class1 part-1 9840D3E9 4438BBA3 97DBE17C 9840D3E9 4438BBA3 97DBE17C 11988.4 11988.4 class1 part-2 8C342DB0 8C8D3B61 D9E87FE5 DCF2D584 90BEA9C 4295031D 17162.8 29151.2 class1 part-3 9840D3E9 9840D3E9 97DBE17C 6D1D7DF5 6D1D7DF5 F523E31C 11988.4 41139.6 @@ -111,7 +111,7 @@ def clip_crc(sr): @fnt.lru_cache() def cycle_phases() -> pd.DataFrame: - """Return a textual table with the boundaries of all phaes and cycle *phasings*""" + """Return a textual table with the boundaries of all phases and cycle *phasings*""" import io from textwrap import dedent from pandas import IndexSlice as idx @@ -120,9 +120,9 @@ def cycle_phases() -> pd.DataFrame: table_csv = dedent( """ class phasing part-1 part-2 part-3 part-4 - class1 V [0, 589] [589, 1022] [1022, 1612] - class1 VA0 [0, 588] [589, 1021] [1022, 1611] - class1 VA1 [1, 589] [590, 1022] [1023, 1612] + class1 V [0, 589] [589, 1022] [1022, 1612] + class1 VA0 [0, 588] [589, 1021] [1022, 1611] + class1 VA1 [1, 589] [590, 1022] [1023, 1612] class2 V [0, 589] [589, 1022] [1022, 1477] [1477, 1801] class2 VA0 [0, 588] [589, 1021] [1022, 1476] [1477, 1800] class2 VA1 [1, 589] [590, 1022] [1023, 1477] [1478, 1801] @@ -158,7 +158,7 @@ def identify_cycle_v_crc( cycle, part = crcs.index[row] accum, phasing = crcs.columns[col] - if accum == "cummulative": + if accum == "cumulative": if row in [2, 6, 10, 14]: # is it a final cycle-part? part = None else: @@ -174,7 +174,7 @@ def identify_cycle_v(V: Iterable): Finds the first left-top CRC matching the cycle/part/kind of the given Velocity. :param V: - Any cycle or parts of it (one of Low/Medium/High/Extra Kigh phases), + Any cycle or parts of it (one of Low/Medium/High/Extra High phases), or concatenated subset of the above phases, but in that order. :return: a 3 tuple (class, part, kind), like this: @@ -182,12 +182,12 @@ def identify_cycle_v(V: Iterable): - ``(None, None, None)``: if no match - ``(, None, )``: if it matches a full-cycle - ``(, , )``: if it matches a part - - ``(, , )``: (CAPITAL part) if it matches a part cummulatively + - ``(, , )``: (CAPITAL part) if it matches a part cumulatively + + where `` is one of - where `` is one of - - - ``V`` - - ``A0`` (offset: 0, length: -1) + - ``V`` + - ``A0`` (offset: 0, length: -1) - ``A1`` (offset: 1, length: -1) """ crc = crc_velocity(V) diff --git a/wltp/datamodel.py b/wltp/datamodel.py index 71b32f86..27ffb8fa 100644 --- a/wltp/datamodel.py +++ b/wltp/datamodel.py @@ -37,7 +37,7 @@ try: from pandas.core.common import PandasError except ImportError: - ## Pandas-0.20.1 dropped this classs. + ## Pandas-0.20.1 dropped this class. # See https://github.com/pydata/pandas-datareader/issues/305 PandasError = ValueError @@ -151,7 +151,7 @@ def get_wltc_data(): :return: a tree """ - ## See schemas for explainations. + ## See schemas for explanations. ## wltc_data = { "classes": { @@ -231,7 +231,7 @@ def _get_model_schema(additional_properties=False): - number - 'null' exclusiveMinimum: 0 - description: (OUT) The calculcated maximum velocity, as defined in Annex 2-2.i. + description: (OUT) The calculated maximum velocity, as defined in Annex 2-2.i. n_vmax: title: engine speed for maximum vehicle velocity type: @@ -387,7 +387,7 @@ def _get_model_schema(additional_properties=False): n_norm = (n - n_idle) / (n_rated - n_idle) - * The 2nd column or `p_norm` is the normalised values of the full-power load against the p_rated, + * The 2nd column or `p_norm` is the normalized values of the full-power load against the p_rated, within [0, 1]: p_norm = p / p_rated @@ -477,7 +477,7 @@ def _get_model_schema(additional_properties=False): f_n_min: description: For each gear > 2, N :> n_min = n_idle + f_n_min * n_range (unless - `n_min` overriden by manufacturer) + `n_min` overridden by manufacturer) type: - number - 'null' @@ -514,7 +514,7 @@ def _get_model_schema(additional_properties=False): - `v_cycle`: reduced by safety-margin, but not by ASM - `v_dsc`: (optional) - `v_target`: road loads power - - `(ok_..., gN)`: rflags denoting the validty of certainconditions for gear-N + - `(ok_..., gN)`: rflags denoting the validity of certain conditions for gear-N - `g_max0`: does not include corrections for the `g1-->g2 n_min` rule, nor points with insufficient power. definitions: @@ -712,7 +712,7 @@ def get_class_parts_limits(class_id: Union[str, int], mdl=None, edges=False): :param class_id: one of 'class1', ..., 'class3b' or its index 0,1, ... 3 - :param mdl: the mdl to parse wltc_data from, if ommited, parses the results of :func:`get_wltc_data()` + :param mdl: the mdl to parse wltc_data from, if omitted, parses the results of :func:`get_wltc_data()` :param edges: when `True`, embeds internal limits inside [0, ..., len] :return: a list of ints with the part-limits, ie for class-3a these are 3 numbers (or 5 if `edge`) diff --git a/wltp/downscale.py b/wltp/downscale.py index df61966a..0ff5159e 100644 --- a/wltp/downscale.py +++ b/wltp/downscale.py @@ -135,7 +135,7 @@ def downscale_by_recursing(V, f_downscale, phases): a = V[t + 1] - V[t] V_DSC[t + 1] = V_DSC[t] + a * (1 - f_downscale) - ## Decelaration phase + ## Deceleration phase # f_corr = (V_DSC[t1] - V[t2]) / (V[t1] - V[t2]) for t in range(t1 + 1, t2): @@ -179,7 +179,7 @@ def downscale_by_scaling(V: pd.Series, f_downscale, phases) -> pd.Series: V_DSC[dn_ix] = dn_offset + f_corr * (V[dn_ix] - dn_offset) assert V_DSC[t2] == V[t2], f"Invariant-end violation {V_DSC[t2]} != {V[t2]}!" - ## FIXME: `f_scale` multipliers should have been on the other side(!) of inequailty, + ## FIXME: `f_scale` multipliers should have been on the other side(!) of inequality, # but then assertion fails frequently. assert f_scale * abs(V_DSC[t1 + 1] - V_DSC[t1]) <= abs(V[t1 + 1] - V[t1]), ( f"Smooth-tip violation diff_V_DSC({abs(V_DSC[t1 + 1] - V_DSC[t1])})" diff --git a/wltp/engine.py b/wltp/engine.py index 61cb9e94..199b109c 100644 --- a/wltp/engine.py +++ b/wltp/engine.py @@ -101,7 +101,7 @@ def parse_wot(wot) -> pd.DataFrame: if wot.shape[0] <= 2 and wot.shape[0] < wot.shape[1]: wot = wot.T - ## Accept a 1-column df if column-names were unamed or one of the p columnns. + ## Accept a 1-column df if column-names were unamed or one of the p columns. # if ( wot.shape[1] == 1 @@ -150,7 +150,7 @@ def parse_wot(wot) -> pd.DataFrame: def validate_wot( wot: pd.DataFrame, n_idle, n_rated, p_rated, n_min_drive_set ) -> pd.DataFrame: - """Higher-level validation of the wot-curves with repect to model.""" + """Higher-level validation of the wot-curves with respect to model.""" w = wio.pstep_factory.get().wot d = wio.pstep_factory.get().wot @@ -218,7 +218,7 @@ def preproc_wot(mdl: Mapping, wot) -> pd.DataFrame: def calc_p_available(P: Column, f_safety_margin, ASM: Optional[Column] = 0) -> Column: """ - Calculate `p_available` acording to Annex 2-3.4. + Calculate `p_available` according to Annex 2-3.4. :param P: power (usually from WOT) @@ -282,7 +282,7 @@ def interpolate_wot_on_v_grid(wot: pd.DataFrame, n2v_ratios) -> pd.DataFrame: because those interpolated values would be highly inaccurate! :return: - the wot interpolated on a v-grid accomodating all gears + the wot interpolated on a v-grid accommodating all gears with 2-level columns (item, gear) """ @@ -346,9 +346,9 @@ def calc_p_avail_in_gwots(gwots, *, SM) -> pd.DataFrame: Must not interpolate along with wot on grid, or great INNACCURACIES. :param gwots: - a df with 2-level multindex columns, having at least (`g1`, 'p'), and + a df with 2-level multiindex columns, having at least (`g1`, 'p'), and optionally ('g1', 'ASM')) for each gears - (as retuned by :func:`interpolate_wot_on_v_grid()`). + (as returned by :func:`interpolate_wot_on_v_grid()`). .. TODO:: Encapsulate GridWots in a class, like Cycler. """ @@ -394,9 +394,9 @@ def interp_n95(label, P, N_norm): raise ValueError( f"BAD wot, too few points {wot_location} n_rated({n_rated})!\n {wot}" ) - n_intep = interpolate.interp1d(P, N_norm, copy=False, assume_sorted=True) + n_interp = interpolate.interp1d(P, N_norm, copy=False, assume_sorted=True) try: - n95 = n_intep(0.95).item() + n95 = n_interp(0.95).item() except Exception as ex: ## Not all WOTs drop again below 95% at top-n. # Accept top-n as `n_max` in such cases (by the GTR); @@ -409,7 +409,7 @@ def interp_n95(label, P, N_norm): ): log.info( "The wot does not drop below 95%% x p_rated(%s) at top n_wot_max(%s);" - " assumng n95_high := n_wot_max-->p(%s).", + " assuming n95_high := n_wot_max-->p(%s).", p_rated, wot[w.n].max(), wot[w.p].iloc[-1], diff --git a/wltp/experiment.py b/wltp/experiment.py index f666b3d5..69567c29 100644 --- a/wltp/experiment.py +++ b/wltp/experiment.py @@ -39,7 +39,8 @@ One row for each gear (starting with 1 to #gears). _N_GEARS: floats (#gears X #cycle_steps) - One row per gear with the Engine-revolutions required to follow the V-profile (unfeasable revs included), + One row per gear with the Engine-revolutions required to follow the V-profile + (unfeasible revs included), produced by multiplying ``V * gear-rations``. _GEARS_YES: boolean (#gears X #cycle_steps) @@ -184,7 +185,7 @@ def run(self): V = cycle.get(forced_v_column) if V is not None: log.info( - "Found forced velocity in %r with %s valus.", forced_v_column, len(V) + "Found forced velocity in %r with %s values.", forced_v_column, len(V) ) V = pd.Series(V, name=c.v_target) @@ -237,7 +238,7 @@ def run(self): V_dsc = vround(V_dsc_raw) V_dsc.name = c.v_dsc - # TODO: separate cokumn due to cap/extend. + # TODO: separate column due to cap/extend. V_target = V_dsc.copy() V_target.name = c.v_target @@ -281,7 +282,7 @@ def run(self): mdl[m.n_max3] = g_max_n2v * mdl[m.v_max] mdl[m.n_max] = engine.calc_n_max(mdl[m.n_max1], mdl[m.n_max2], mdl[m.n_max3]) - # TODO: incorporate `t_colde_env` check in validateion framework. + # TODO: incorporate `t_cold_end` check in validateion framework. if wltc_class: for err in cb.validate_nims_t_cold_end(mdl[m.t_cold_end], wltc_parts): raise err @@ -552,7 +553,7 @@ def step_rule_f(t, pg, g, V, A, GEARS, driveability_issues): if pg < g and GEARS[t - 2] >= g: # NOTE: Nowhere to apply it since rule(b2) would have eliminated 1-sec shifts. Moved before rule(b)! - # NOTE: Applying rule(f) also for i-2, i-3, ... signular-downshifts. + # NOTE: Applying rule(f) also for i-2, i-3, ... singular-downshifts. # FIXME: Rule(f) implement further constraints. # NOTE: Rule(f): What if extra conditions unsatisfied? Allow shifting for 1 sec only?? GEARS[t - 1] = min(g, GEARS[t - 2]) @@ -607,7 +608,7 @@ def apply_step_rules(rules, isStopOnFirstApplied): # for t in range( 2, len(GEARS) - ): # Start from 2nd element to accomodate rule(e)'s backtracking. + ): # Start from 2nd element to accommodate rule(e)'s backtracking. if GEARS[t] < 0: GEARS[t] = GEARS[t - 1] @@ -615,7 +616,7 @@ def apply_step_rules(rules, isStopOnFirstApplied): # t_range = range( 5, len(GEARS) - ) # Start from 5th element to accomodate rule(e)'s backtracking. + ) # Start from 5th element to accommodate rule(e)'s backtracking. for _ in [0, 1]: apply_step_rules( [step_rule_g, step_rule_f], False diff --git a/wltp/invariants.py b/wltp/invariants.py index f6b04a06..64f344bb 100644 --- a/wltp/invariants.py +++ b/wltp/invariants.py @@ -5,7 +5,7 @@ # Licensed under the EUPL (the 'Licence'); # You may not use this work except in compliance with the Licence. # You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl -"""definitions & idenmpotent formulae for physics/engineering""" +"""definitions & idempotent formulae for physics/engineering""" import functools from typing import Union @@ -24,7 +24,7 @@ def round1(n, decimals=0): """ Rounding with the Access DB method (all ties half-up: 0.5 --> 1). - TIP: Double rounding might be needed to achive stability on ties with long decimals + TIP: Double rounding might be needed to achieve stability on ties with long decimals (see downscale scale vs recurse) :param n: diff --git a/wltp/io.py b/wltp/io.py index 8c7fd89e..75bf6d33 100644 --- a/wltp/io.py +++ b/wltp/io.py @@ -22,10 +22,14 @@ #: - call :func:`paths_collected()` at the end of a code run. _root_pstep = mappings.Pstep() -#: The root-path wrapped in a context-var so that cloent code -#: canm redfine paths & column names momentarily with:: +#: The root-path wrapped in a context-var so that client code +#: can redfine paths & column names momentarily with:: #: -#: with wio.pstep_factory.redined(.cols): +#: token = wio.pstep_factory.set(mapping.Pstep()) +#: try: +#: ... +#: finally: +#: wio.pstep_factory.reset(token) #: ... pstep_factory = contextvars.ContextVar("root", default=_root_pstep) diff --git a/wltp/vehicle.py b/wltp/vehicle.py index 629b48a5..e917c493 100644 --- a/wltp/vehicle.py +++ b/wltp/vehicle.py @@ -5,7 +5,7 @@ # Licensed under the EUPL (the 'Licence'); # You may not use this work except in compliance with the Licence. # You may obtain a copy of the Licence at: http://ec.europa.eu/idabc/eupl -"""formulae for cyle/vehicle dynamics""" +"""formulae for cycle/vehicle dynamics""" import logging from typing import Union @@ -32,8 +32,8 @@ def calc_p_m_ratio(p_rated, unladen_mass): def calc_p_resist(V: Column, f0, f1, f2): """ - The `p_resist` required to overcome vehicle-resistances for various velocities, - + The `p_resist` required to overcome vehicle-resistances for various velocities, + as defined in Annex 2-2.i (calculate `V_max_vehicle`). """ VV = V * V diff --git a/wltp/vmax.py b/wltp/vmax.py index 808cfda5..68b91940 100644 --- a/wltp/vmax.py +++ b/wltp/vmax.py @@ -26,8 +26,9 @@ from pandalone import mappings, pandata +from . import engine from . import io as wio -from . import vehicle, engine, utils +from . import utils, vehicle from .invariants import v_decimals, v_step, vround log = logging.getLogger(__name__) @@ -91,15 +92,15 @@ def _find_p_remain_root( # - Apply `fillna()`` bc `diff()` leaves one period at head or tail. # offs = -1 - wot[w.zero_crosings] = offs * wot[w.sign_p_remain_stable].diff( + wot[w.zero_crossings] = offs * wot[w.sign_p_remain_stable].diff( periods=offs ).fillna(0) # ... search for down-crossings only. - # roots_head = wot.index[wot[w.zero_crosings].lt(0, fill_value=0)] # if no `fill_value` all NANs. - roots_head = wot.index[wot[w.zero_crosings] < 0] + # roots_head = wot.index[wot[w.zero_crossings].lt(0, fill_value=0)] # if no `fill_value` all NANs. + roots_head = wot.index[wot[w.zero_crossings] < 0] # ... and capture v @ lowest of them (where p_remain is either 0 or still positive) if roots_head.size > 0: - v_max = roots_head[0] # Plain rounding, alreaydy close to grid. + v_max = roots_head[0] # Plain rounding, already close to grid. n_v_max = wot.loc[v_max, w.n] assert not (np.isnan(v_max) or np.isnan(n_v_max)), locals()