8. API reference

The core of the simulator is composed from the following modules:

cycles

data for all cycles and utilities to identify them

datamodel

Defines schema, defaults and validations for data consumed/produced by Experiment.

experiment

(TO BE DEFUNCT) The core that accepts a vehicle-model and wltc-classes, runs the simulation and updates the model with results.

pipelines

All pipeline definitions for running the WLTP gear-shifting algorithm

cycler

code for generating the cycle

engine

formulae for engine power & revolutions and gear-box

vehicle

formulae for cycle/vehicle dynamics

vmax

formulae estimating v_max from wot

downscale

formulae downscaling cycles based on pmr/test_mass ratio

nmindrive

Calculate/Validate n_min_drive parameters, defined mostly in Annex 2-2.k.

invariants

definitions & idempotent formulae for physics/engineering

autograph

Harvest functions & annotate their dependencies to build pipelines.

io

utilities for starting-up, parsing, naming, indexing and spitting out data

utils

software utils unrelated to physics or engineering

cli

(OUTDATED) command-line entry-point for launching this wltp tool

plots

(OUTDATED) code for plotting diagrams related to wltp cycles & results

idgears

(OUTDATED, irrelevant) Detects vehile's gear-ratios from cycle-data and reconstructs the gears-profile by identifying the actual gears used.

8.1. Module: wltp.cycles

data for all cycles and utilities to identify them

wltp.cycles.calc_wltc_distances(V: pandas.core.series.Series, class_phases_grouper) pandas.core.frame.DataFrame[source]

Return a (phase x (sum, cumsum)) matrix for the v-phasing boundaries of V.

Parameters
  • V – a velocity profile with the standard WLTC length

  • class_phases_grouper – an object to break up a velocity in parts (from make_grouper())

wltp.cycles.crc_velocity(V: Iterable, crc: Union[int, str] = 0, full=False) str[source]

Compute the CRC32(V) of a 1Hz velocity trace, to be compared with Phase boundaries.

Parameters
  • V – velocity samples, to be rounded according to wltp.invariants.v_decimals

  • crc – initial CRC value (might be a hex-string)

  • full – print full 32bit number (x8 hex digits), or else, just the highest half (the 1st x4 hex digits)

Returns

the 16 lowest bits of the CRC32 of the trace, as hex-string

  1. The velocity samples are first round to v_decimals;

  2. the samples are then multiplied x10 to convert into integers (assuming v_decimals is 1);

  3. the integer velocity samples are then converted into int16 little-endian bytes (eg 0xC0FE –> (0xFE, 0xC0);

  4. the int16 bytes are then concatanated together, and

  5. fed into ZIP’s CRC32;

  6. formated as 0-padded, 8-digit, HEXes;

  7. keeping (usually) the highest 2 bytes of the CRC32 (4 leftmost hex-digits).

See also identify_cycle_v_crc() & cycle_checksums().

wltp.cycles.cycle_checksums(full=False) pandas.core.frame.DataFrame[source]

Return a big table with by-phase/cumulative CRC/SUM for all class phases.

Parameters

full – CRCs contain the full 32bit number (x8 hex digits)

wltp.cycles.cycle_phases() pandas.core.frame.DataFrame[source]

Return a textual table with the boundaries of all cycle Phases (the problem).

wltp.cycles.get_class_phase_boundaries(part_lengths: tuple, V_cycle) Tuple[Tuple[int, int], ...][source]

Serve [low, high) boundaries from class-data, as Dijkstra demands it.

Returns

a tuple of tuple-pairs of time indices (low/hight) part-boundaries (ie for class-3a these are 5 pairs of numbers, see example below), that may be used as Series.loc[slice(*pair)].

Like datamodel.get_class_parts_limits() with edges=true, suited for pipelines.

Example:

>>> from wltp import datamodel, cycles
>>> wcd = datamodel.get_wltc_data()
>>> cd = cycles.get_wltc_class_data(wcd["classes"], "class3b")
>>> cycles.get_class_phase_boundaries(cd["lengths"], cd["V_cycle"])
((0, 589), (589, 1022), (1022, 1477), (1477, 1800))
wltp.cycles.get_wltc_class_data(wltc_classes: Mapping, wltc_class: Union[str, int]) dict[source]

Fetch the wltc-data for a specific class.

Parameters
  • wltc_data – same-named item in datamodel

  • wltc_class – one of ‘class1’, …, ‘class3b’ or its index 0,1, … 3

Like datamodel.get_class() suited for pipelines.

wltp.cycles.identify_cycle_v(V: Iterable)[source]

Finds the first left-top CRC matching the given Velocity-trace.

Parameters

V – Any cycle or phases of it (one of Low/Medium/High/Extra High phases), or concatenated subset of the above phases, but in that order.

Returns

a 3tuple (class, phase, kind), like this:

  • (None,     None,   None): if no match

  • (<class>,  None,  <phasing>): if it matches a full-cycle

  • (<class>, <phase>, <phasing>): if it matches a phase

  • (<class>, <PHASE>, <phasing>): (CAPITAL phase) if it matches a phase, cumulatively

where <phasing> is one of

  • V

  • A0 (offset: 0, length: -1, lissing -last sample)

  • A1 (offset: 1, length: -1, missing first sample)

wltp.cycles.identify_cycle_v_crc(crc: Union[int, str]) Tuple[Optional[str], Optional[str], Optional[str]][source]

The opposite of identify_cycle_v()

wltp.cycles.make_class_phases_grouper(class_phase_boundaries: Sequence[tuple]) pandas.core.arrays.categorical.Categorical[source]

Return a pandas group-BY for the given boundaries as VA1 phasing.

Parameters

class_phase_boundaries – a list of [low, high] boundary pairs (from get_class_phase_boundaries())

Onbviously, it cannot produce overlapping split-times belonging to 2 phases.

wltp.cycles.read_V_file(fname) Tuple[float, ...][source]

Parse textual files with cycle velocities.

8.2. Module: wltp.datamodel

Defines schema, defaults and validations for data consumed/produced by Experiment.

The datamodel-instance is managed by pandel.Pandel.

>>> from wltp.datamodel import *
>>> __name__ = "wltp.datamodel"
wltp.datamodel._get_model_schema(additional_properties=False) dict[source]
Parameters

additional_properties (bool) – when False, 4rd-step(validation) will scream on any non-schema property found. The json-schema(dict) for input/output of the WLTC experiment.

Warning

Do not modify, or they will affect all future operations

wltp.datamodel._get_wltc_schema() dict[source]

The json-schema for the WLTC-data required to run a WLTC experiment.

Warning

Do not modify, or they will affect all future operations

wltp.datamodel.get_class(wltc_class: Union[str, int], mdl=None) dict[source]

Fetch the wltc-data for a specific class.

Parameters

wltc_class – one of ‘class1’, …, ‘class3b’ or its index 0,1, … 3

Note

For pipeline use cycles.get_wltc_class_data().

wltp.datamodel.get_class_names(mdl=None) pandas.core.frame.DataFrame[source]
wltp.datamodel.get_class_part_names(cls_name=None)[source]
Parameters

cls_name (str) – one of ‘class1’, …, ‘class3b’, if missing, returns all 4 part-names

wltp.datamodel.get_class_parts_limits(wltc_class: Union[str, int], edges=False) Tuple[Tuple[int, int], ...][source]

Parses the supplied in wltc_data and extracts the part-limits for the specified class-name.

Parameters
  • wltc_class – one of ‘class1’, …, ‘class3b’ or its index 0,1, … 3

  • edges – when True, internal limits are wrapped within [0, …, len]

Returns

a list of ints with the part-limits, ie for class-3a these are 3 numbers (or 5 if edge)

Note

For pipeline use cycles.get_class_phase_boundaries().

Example:

>>> from wltp import datamodel
>>> import pandas as pd
>>> cls = 'class2'
>>> part_limits = datamodel.get_class_parts_limits(cls)
>>> part_limits
(589, 1022, 1477)
>>> part_limits = datamodel.get_class_parts_limits(cls, edges=True)
>>> part_limits
(0,  589, 1022, 1477, 1800)

And these are the limits for acceleration-dependent items:

>>> cls_data = datamodel.get_wltc_data()['classes'][cls]
>>> V = pd.DataFrame(cls_data['V_cycle'])
>>> V.groupby(pd.cut(V.index, part_limits)).sum()
              V_cycle
(0, 589]      11162.2
(589, 1022]   17054.3
(1022, 1477]  24450.6
(1477, 1800]  28869.8
wltp.datamodel.get_class_pmr_limits(edges=False) list[source]

Parses the supplied in wltc_data and extracts the part-limits for the specified class-name.

Parameters

edges – when True, embeds internal limits into (0, len)

Returns

a list with the pmr-limits (2 numbers)

Note

For pipeline use jsonp dependencies into wltc_class_data.

wltp.datamodel.get_class_v_cycle(wltc_class: Union[str, int]) pandas.core.series.Series[source]

Fetch the v-cycle for a class with the proper t in index.

Parameters

wltc_class – one of ‘class1’, …, ‘class3b’ or its index 0,1, … 3

Returns

a series containing \(length + 1\) samples, numbered from 0 to length, where length is the duration of the cycle in seconds.

wltp.datamodel.get_model_base() dict[source]

The base model for running a WLTC experiment.

It contains some default values for the experiment but this model is not valid - you need to override its attributes.

Returns

a tree with the default values for the experiment.

wltp.datamodel.get_model_schema(additional_properties=False)[source]

Schema of the input data; you may freely modify them.

wltp.datamodel.get_wltc_data()[source]

The WLTC-data required to run an experiment (the class-cycles and their attributes)..

Prefer to access wltc-data through get_class(), or from datamodel['wltc_data'],

Returns

a tree

wltp.datamodel.get_wltc_schema()[source]

Schema of the wLTC data; you may freely modify them.

wltp.datamodel.merge(a, b, path=[])[source]

‘merges b into a

wltp.datamodel.model_validator(additional_properties=False, validate_wltc_data=False, validate_schema=False) pandalone.pandata.PandelVisitor[source]
wltp.datamodel.upd_default_load_curve(mdl, engine_type='petrol')[source]

Some default ‘full-load-curve’ for the vehicles

wltp.datamodel.upd_resistance_coeffs_regression_curves(mdl)[source]
wltp.datamodel.validate_model(mdl, additional_properties=False, iter_errors=False, validate_wltc_data=False, validate_schema=False)[source]
Parameters

iter_errors (bool) – does not fail, but returns a generator of ValidationErrors

>>> validate_model(None)
Traceback (most recent call last):
jsonschema.exceptions.ValidationError: None is not of type 'object'
...
>>> mdl = get_model_base()
>>> err_generator = validate_model(mdl, iter_errors=True)
>>> sorted(err_generator, key=hash)
[<ValidationError:
...
>>> mdl = get_model_base()
>>> mdl.update({
...     "unladen_mass":1230,
...     "test_mass":   1300,
...     "p_rated": 110.625,
...     "n_rated": 5450,
...     "n_idle":  950,
...     "n_min":   500,
...     "n2v_ratios":[120.5, 75, 50, 43, 33, 28],
...     "f0": 100,
...     "f1": 0.5,
...     "f2": 0.04,
... })
>>> mdl = upd_default_load_curve(mdl);
>>> err_generator = validate_model(mdl, iter_errors=True)
>>> list(err_generator)
[]
wltp.datamodel.yield_load_curve_errors(mdl)[source]
wltp.datamodel.yield_n_min_errors(mdl)[source]

8.3. Module: wltp.experiment

(TO BE DEFUNCT) The core that accepts a vehicle-model and wltc-classes, runs the simulation and updates the model with results.

Attention

The documentation of this core module has several issues and needs work.

8.3.1. Notation

  • ALL_CAPITAL variables denote vectors over the velocity-profile (the cycle),

  • ALL_CAPITAL starting with underscore (_) denote matrices (gears x time).

For instance, GEARS is like that:

[0, 0, 1, 1, 1, 2, 2, ... 1, 0, 0]
 <----   cycle time-steps   ---->

and _GEARS is like that:

 t:||: 0  1  2  3
---+-------------
g1:|[[ 1, 1, 1, 1, ... 1, 1
g2:|   2, 2, 2, 2, ... 2, 2
g3:|   3, 3, 3, 3, ... 3, 3
g4:|   4, 4, 4, 4, ... 4, 4 ]]

8.3.2. Major vectors & matrices

V: floats (#cycle_steps)

The wltp-class velocity profile.

_GEARS: integers (#gears X #cycle_steps)

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 (unfeasible revs included), produced by multiplying V * gear-rations.

_GEARS_YES: boolean (#gears X #cycle_steps)

One row per gear having True wherever gear is possible for each step.

See also

,datamodel for in/out schemas

class wltp.experiment.Experiment(mdl, skip_model_validation=False, validate_wltc_data=False, additional_properties=True)[source]

Bases: object

Runs the vehicle and cycle data describing a WLTC experiment.

See wltp.experiment for documentation.

Parameters
  • mdl – trees (formed by dicts & lists) holding the experiment data.

  • skip_model_validation – when true, does not validate the model.

  • additional_properties – when false; strict checks screams if unknown props in model

_set_model(mdl, skip_validation, validate_wltc_data, additional_properties)[source]
driveability_report()[source]
property model
run()[source]

Invokes the main-calculations and extracts/update Model values!

@see: Annex 2, p 70

wltp.experiment.addDriveabilityMessage(time_step, msg, driveability_issues)[source]
wltp.experiment.addDriveabilityProblems(_GEARS_BAD, reason, driveability_issues)[source]
wltp.experiment.applyDriveabilityRules(V, A, GEARS, CLUTCH, driveability_issues)[source]

@note: Modifies GEARS & CLUTCH. @see: Annex 2-4, p 72

wltp.experiment.assert_regexp_unmatched(regex, string, msg)[source]
wltp.experiment.bytes2np(bytesarr)[source]
wltp.experiment.dec_byte_repl(m)[source]
wltp.experiment.gearsregex(gearspattern)[source]
Parameters

gearspattern

regular-expression or substitution that escapes decimal-bytes written as: \g\d+ with adding +128, eg:

\g124|\g7 --> unicode(128+124=252)|unicode(128+7=135)

wltp.experiment.np2bytes(NUMS)[source]
wltp.experiment.rule_a(bV, GEARS, CLUTCH, driveability_issues, re_zeros)[source]

Rule (a): Clutch & set to 1st-gear before accelerating from standstill.

Implemented with a regex, outside rules-loop: Also ensures gear-0 always followed by gear-1.

NOTE: Rule(A) not inside x2 loop, and last to run.

wltp.experiment.rule_c2(bV, A, GEARS, CLUTCH, driveability_issues, re_zeros)[source]

Rule (c2): Skip 1st-gear while decelerating to standstill.

Implemented with a regex, outside rules-loop: Search for zeros in _reversed_ V & GEAR profiles, for as long Accel is negative. NOTE: Rule(c2) is the last rule to run.

wltp.experiment.rule_checkSingletons(bV, GEARS, CLUTCH, driveability_issues, re_zeros)[source]
wltp.experiment.step_rule_b1(t, pg, g, V, A, GEARS, driveability_issues)[source]

Rule (b1): Do not skip gears while accelerating.

wltp.experiment.step_rule_b2(t, pg, g, V, A, GEARS, driveability_issues)[source]

Rule (b2): Hold gears for at least 2sec when accelerating.

wltp.experiment.step_rule_c1(t, pg, g, V, A, GEARS, driveability_issues)[source]

Rule (c1): Skip gears <3sec when decelerating.

wltp.experiment.step_rule_d(t, pg, g, V, A, GEARS, driveability_issues)[source]

Rule (d): Cancel shifts after peak velocity.

wltp.experiment.step_rule_e(t, pg, g, V, A, GEARS, driveability_issues)[source]

Rule (e): Cancel shifts lasting 5secs or less.

wltp.experiment.step_rule_f(t, pg, g, V, A, GEARS, driveability_issues)[source]

Rule(f): Cancel 1sec downshifts (under certain circumstances).

wltp.experiment.step_rule_g(t, pg, g, V, A, GEARS, driveability_issues)[source]

Rule(g): Cancel upshift during acceleration if later downshifted for at least 2sec.

8.4. Module: wltp.pipelines

All pipeline definitions for running the WLTP gear-shifting algorithm

wltp.pipelines.check_dupe_cols(op_cb)[source]

Utility to validate solution from callbacks.

wltp.pipelines.compensate_capped_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline[source]

Pipeline to provide V_compensated from V_capped trace (Annex 1, 9).

compensate_capped_pipeline

wltp.pipelines.cycler_pipeline(aug: wltp.autograph.Autograph = None, domain=('cycle', None), **pipeline_kw) graphtik.pipeline.Pipeline[source]

Main pipeline to “run” the cycle.

cycler_pipeline

wltp.pipelines.downscale_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline[source]

Pipeline to provide V_dsc & V_capped traces (Annex 1, 8.2 & 8.3).

downscale_pipeline

wltp.pipelines.gwots_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline[source]

Pipeline to provide P_avail for each gear (Annex 2, 3.4).

gwots_pipeline

wltp.pipelines.n_max_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline[source]

Pipeline to provide n_maxs (Annex 2, 2.g).

n_max_pipeline

wltp.pipelines.p_req_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline[source]

Pipeline to provide P_req traces (Annex 2, 9).

p_req_pipeline

wltp.pipelines.scale_trace_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline[source]

Main pipeline to scale the Velocity trace:

scale_trace_pipeline

Example:

>>> mdl = {"n_idle": 500, "n_rated": 3000, "p_rated": 80, "t_cold_end": 470}
wltp.pipelines.v_distances_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline[source]

Pipeline to provide per-phase & total distances for V_cycle, V_dsc, V_capped & V_compensated.

v_distances_pipeline

wltp.pipelines.vmax_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline[source]

Pipeline to provide vehicle’s v_max (Annex 2, 2.i).

vmax_pipeline

wltp.pipelines.wltc_class_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline[source]

Pipeline to provide p_m_ratio (Annex 1, 2).

wltc_class_pipeline

8.5. Module: wltp.cycler

code for generating the cycle

class wltp.cycler.CycleBuilder(*velocities: Union[pandas.core.series.Series, pandas.core.frame.DataFrame], **kwargs)[source]

Bases: object

Specific choreography of method-calls required, see TCs & notebooks.

Initialize cycle with the given velocities and acceleration of the last one.

Parameters

velocities

named series, e.g. from get_class_v_cycle(), all sharing the same time-index The last one is assumed to be the “target” velocity for the rest of the cycle methods.

If they are a (dataframe, series, series), they are assigned in cycle, V and A respectively, and no other processing happens.

A: pandas.core.series.Series[source]

A column derived from V, also within cycle, populated on construction, and used in subsequent calculations.

V: pandas.core.series.Series[source]

A column within cycle populated from the last velocity given in the cstor. to use in subsequent calculations.

add_columns(*columns: Union[pandas.core.frame.DataFrame, pandas.core.series.Series])[source]

Concatenate more columns into cycle.

Parameters

columns – must have appropriate columns, ie. 2-level (item, gear).

add_wots(gwots: pandas.core.frame.DataFrame)[source]

Adds the gwots joined on the v_cap column of the cycle.

Parameters

gwots – a dataframe of wot columns indexed by a grid of rounded velocities, as generated by interpolate_wot_on_v_grid(), and augmented by attach_p_avail_in_gwots().

calc_initial_gear_flags(*, g_vmax: int, n95_high: float, n_max_cycle: float, nmins: wltp.nmindrive.NMinDrives) pandas.core.frame.DataFrame[source]
combine_ok_n_gear_flags(flags: pandas.core.frame.DataFrame)[source]
cycle: pandas.core.frame.DataFrame[source]

The instance that is built.

derrive_ok_gears(flags: pandas.core.frame.DataFrame)[source]
flat_cycle() pandas.core.frame.DataFrame[source]

return a copy of cycle passed through flatten_columns()

gidx: wltp.io.GearMultiIndexer[source]
make_gmax0(ok_gears: pandas.core.frame.DataFrame)[source]
validate_nims_t_cold_end(t_cold_end: int, wltc_parts: Sequence[int])[source]

Check t_cold_end falls in a gap-stop within the 1st phase.

Todo

Incorporate validate_nims_t_cold_end() properly in validations pipeline.

wltp.cycler.NANFLAG = -1

The value representing NANs in “bool” int8 arrays (Int8 cannot write in HDF5 by tables lib)

class wltp.cycler.PhaseMarker(running_threshold: float = 1.0, phase_repeat_threshold: int = 2, up_threshold: float = - 0.1389)[source]

Bases: object

Identifies consecutive truths in series

_autograph = {None: {None: {'provides': 'phase_marker'}}}
_identify_consecutive_truths(col: pandas.core.series.Series, right_edge=True) pandas.core.series.Series[source]

Detect phases with a number of consecutive trues above some threshold.

Parameters
  • col – a boolean series

  • right_edge – when true, the col includes +1 sample towards the end

Example:

from cycler import PhaseMarker
cycle = pd.DataFrame({
            'v': [0,0,3,3,5,8,8,8,6,4,5,6,6,5,0,0],
        'accel': [0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0],
       'cruise': [0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0],
        'decel': [0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,0],
           'up': [0,0,1,1,1,1,1,1,0,1,1,1,1,0,0,0],
    'initaccel': [1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
    'stopdecel': [0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0],
})
pm = PhaseMarker()

def phase(cond):
    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
assert (phase(RUN & (A > 0)) == cycle.accel).all()
assert (phase(RUN & (A == 0)) == cycle.cruise).all()
assert (phase(RUN & (A < 0)) == cycle.decel).all()

Adapted from: https://datascience.stackexchange.com/a/22105/79324

add_class_phase_markers(cycle: pandas.core.frame.DataFrame, wltc_parts: Iterable[int], *, right_edge=True) pandas.core.frame.DataFrame[source]

Adds low/mid/hight/extra high boolean index into cycle, named as p1, …

Parameters

TODO: DEL after graphtiked

add_transition_markers(cycle: pandas.core.frame.DataFrame, V: pandas.core.series.Series, A: pandas.core.series.Series) pandas.core.frame.DataFrame[source]

Adds accel/cruise/decel/up phase markers into the given cycle,

based V & A columns of a cycle generated by emerge_cycle().

TODO: DEL after graphtiked

calc_phase_accel(run: pandas.core.series.Series, accel_raw: pandas.core.series.Series) pandas.core.series.Series[source]

Driveability rule for acceleration/constant phase in Annex 2-2.k for the determination of the initial gear, according to Annex 2-3.5.

Parameters

f_up_threshold

The acceleration/constant<–>deceleration threshold for n_mins_up/down (Annex 2-2.k) for the determination of the initial gear & n_mins, according to Annex 2-3.5.

type

number

default

-0.1389

units

m/s²

tags

input, constant

calc_phase_decel(run: pandas.core.series.Series, accel_raw: pandas.core.series.Series) pandas.core.series.Series[source]

Driveability rule for acceleration/constant phase in Annex 2-2.k for the determination of the initial gear, according to Annex 2-3.5.

Parameters

f_up_threshold

The acceleration/constant<–>deceleration threshold for n_mins_up/down (Annex 2-2.k) for the determination of the initial gear & n_mins, according to Annex 2-3.5.

type

number

default

-0.1389

units

m/s²

tags

input, constant

calc_phase_initaccel(V, accel)[source]

Driveability rule phase for the initial accelerating phase of a short trip.

tags

input, output

#/definitions/booleans

calc_phase_stopdecel(decel, stop)[source]

Driveability rule phase for the final decelerating phase of a short trip.

tags

input, output

#/definitions/booleans

calc_phase_up(run: pandas.core.series.Series, A: pandas.core.series.Series, f_up_threshold) pandas.core.series.Series[source]

Driveability rule for acceleration/constant phase in Annex 2-2.k for the determination of the initial gear, according to Annex 2-3.5. for Annex 2-4.

tags

input, output

#/definitions/booleans

Parameters

f_up_threshold

The acceleration/constant<–>deceleration threshold for n_mins_up/down (Annex 2-2.k) for the determination of the initial gear & n_mins, according to Annex 2-3.5.

type

number

default

-0.1389

units

m/s²

tags

input, constant

phase_repeat_threshold: int = 2

(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 _identify_consecutive_truths(). if 0,unspecified (might break)

running_threshold: float = 1.0

The vehicle is stopped when its velocity is below this number (in kmh), by Annex 2-4 this is 1.0 kmh.

up_threshold: float = -0.1389

the acceleration threshold(-0.1389) for identifying n_min_drive_up/down phases, defined in Annex 2-2.k

wltp.cycler._combine_all_gear_flags(gflags) pandas.core.series.Series[source]
Parameters

gflags – the initial-gear rule flags grouped for one specific gear

Returns

(must return) a boolean series, or else, groupby does nothing!!

wltp.cycler._derrive_ok_n_flags(initial_gear_flags) pandas.core.series.Series[source]
Parameters

initial_gear_flags – the initial-gear rule flags grouped for each gear (except g0)

Returns

(must return) a boolean series, or else, groupby does nothing!!

wltp.cycler.attach_class_phase_markers(cycle, class_phase_boundaries: Sequence[tuple]) pandas.core.frame.DataFrame[source]

Append class-phase indexes as separate boolean columns, named as “phase_1”, …

Parameters
wltp.cycler.calc_OK_g0(N: pandas.core.frame.DataFrame, stop_phase: pandas.core.series.Series, initaccel: pandas.core.series.Series, stopdecel: pandas.core.series.Series, n_min_drive2_stopdecel: pandas.core.series.Series, gidx: wltp.io.GearMultiIndexer)[source]

Gear-0 rule.

wltp.cycler.calc_OK_max_n(N, n95_high, n_max_cycle, g_vmax, gidx: wltp.io.GearMultiIndexer)[source]

(MAXn-1) , (MAXn-a) and (MAXn-b) rules.

wltp.cycler.calc_OK_min_n(cycle, gidx: wltp.io.GearMultiIndexer, t: pandas.core.series.Series, run_phase: pandas.core.series.Series, stop_phase: pandas.core.series.Series, initaccel_phase: pandas.core.series.Series, stopdecel_phase: pandas.core.series.Series, up_phase: pandas.core.series.Series, g_vmax: int, n95_high: float, n_max_cycle: float, n_min_drive1: int, n_min_drive2_up: int, n_min_drive2_stopdecel: int, n_min_drive2: int, n_min_drive_set: int, n_min_drive_up: int, n_min_drive_up_start: int, n_min_drive_down: int, n_min_drive_down_start: int, t_cold_end: int) pandas.core.frame.DataFrame[source]

Heavy lifting calculations for “initial gear” rules of Annex 2: 2.k, 3.2, 3.3 & 3.5.

Returns

a dataframe with nullable dtype int8 with -1 for NANs (for storage efficiency) and hierarchical columns, with NANFLAG`(1) wherever a gear is allowed, for a specific rule (different sets of rules per gear). Push it to :meth:`derrive_ok_n_flags() & derrive_ok_gears().

Conditions consolidated & ordered like that:

0  RULE      CONDITION                ALLOWED GEAR           COMMENTS
==========  =======================  =====================  ============================================
ok-p               p_avail >= p_req  g > 2                  # 3.5

                            ... AND ...

MAXn-a                  n ≤ n95_high  g < g_vmax            # 3.3
MAXn-b              n ≤ n_max_cycle  g_vmax ≤ g             # 3.3
                                                            see `calc_OK_max_n`()

                            ... AND ...

MINn-ud/hc      n_mid_drive_set ≤ n  g > 2                  # 3.3 & 2k (up/dn on A ≷ -0.1389, hot/cold)
MINn-2ii      n_idle ≤ n, stopdecel  g = 2                  # 3.3 & 2k (stopdecel)
MINn-2iii          0.9 * n_idle ≤ n  g = 2 + clutch         # 3.3 & 2k
c_initacell               initaccel  g = 1                  # 3.2 & 3.3c (also n ≤ n95_high apply)
c_a            1.0 ≤ v & !initaccel  g = 1                  # 3.3c (also n ≤ n95_high apply)

                            ... AND ...

stop              !initaccel, v < 1  g = 0, n = n_idle      # 3.2 (`see calc_OK_g0()`)

                                NOT HERE:

min-2i          1.15 * n_idle  ≤  n  g = 2 <-- 1            # 3.3 & 2k, driveabilty (needs init-gear)
c_b                      n < n_idle  n/clutch modifs        # 3.3 & 2k1, driveability!
too_low_p                                                   # Annex 1-8.4 (full throttle)
wltp.cycler.calc_OK_p(P_remain: pandas.core.frame.DataFrame, gidx: wltp.io.GearMultiIndexer)[source]

Sufficient power rule for gears > g2, in Annex 2-3.5.

TODO: Separate calc_ok_p() not used yet

wltp.cycler.calc_P_remain(P_avail: pandas.core.frame.DataFrame, P_req: pandas.core.series.Series, gidx: wltp.io.GearMultiIndexer)[source]

Return p_avail - p_req for all gears > g2 in gwot.

wltp.cycler.calc_acceleration(V: Union[pandas.core.generic.NDFrame, numpy.ndarray, int, float]) numpy.ndarray[source]

According to formula in Annex 2-3.1

Returns

in m/s^2

Attention

the result in the last sample is NAN!

wltp.cycler.calc_ok_gears(**flags)[source]

Merge together N+P allowed flags using AND+OR boolean logic.

Returns

an int8 dataframe with 1 where where the gear can apply, 0/NANFLAG otherwise.

wltp.cycler.calc_phase_accel_raw(A: pandas.core.series.Series) pandas.core.series.Series[source]

Init phase (start from standstill, Annex 2-3.2) starts for any v > 0 (not v > 0.1 kmh), so must not use the pre-calculated accel/stop phases below.

wltp.cycler.calc_phase_run_stop(V: pandas.core.series.Series, f_running_threshold: float) Tuple[pandas.core.series.Series, pandas.core.series.Series][source]

Return the run and stop phase flags:

Driveability rule phase for where V is above(>=) f_running_threshold, for Annex 2-4.

tags

input, output

#/definitions/booleans

Driveability rule phase for where V is strictly below(<) f_running_threshold, for Annex 2-4.

tags

input, output

#/definitions/booleans

Parameters

f_running_threshold

Τhe velocity threshold above which the vehicle is considered as “running”, from drivability rules of Annex 2-4.

type

number

default

1

units

km/h

tags

input, constant

wltp.cycler.concat_frame_columns(*frames: Union[pandas.core.frame.DataFrame, pandas.core.series.Series]) pandas.core.frame.DataFrame[source]
wltp.cycler.derrive_ok_n_flags(**ok_n_flags: Mapping[str, pandas.core.frame.DataFrame])[source]

Merge together all N-allowed flags using AND+OR boolean logic.

Returns

an int8 dataframe with 1 where where the gear can apply, 0/NANFLAG otherwise.

wltp.cycler.fill_insufficient_power(cycle)[source]

TODOFIXME: fill_insufficient_power() not calced yet!

wltp.cycler.init_cycle_velocity(*velocities: Union[pandas.core.series.Series, pandas.core.frame.DataFrame]) pandas.core.frame.DataFrame[source]

Concatenate velocities(series)/cycle(dataframe), cloning the last column as V.

Parameters

velocities – one or more velocity (same) time-indexed series & datarames (properly named), with the last one becoming the V, unless it already exists

Returns

the concatenated cycle with 2-level columns (item, gear)

wltp.cycler.join_gwots_with_cycle(cycle: pandas.core.frame.DataFrame, V: pandas.core.series.Series, gwots: pandas.core.frame.DataFrame, gidx: wltp.io.GearMultiIndexer)[source]

Adds the gwots joined on the v_cap column of the cycle.

Parameters

gwots – a dataframe of wot columns indexed by a grid of rounded velocities, as generated by interpolate_wot_on_v_grid(), and augmented by attach_p_avail_in_gwots().

wltp.cycler.make_G_max0(incrementing_gflags)[source]

The first estimation of gear to use for every sample.

Not exactly like AccDB’s g_max:

  • no g1–>g2 limit.

wltp.cycler.make_G_min(incrementing_gflags)[source]

The minimum gear satisfying power & N limits for every sample.

wltp.cycler.make_incrementing_gflags(gidx2: wltp.io.GearMultiIndexer, ok_gear: pandas.core.frame.DataFrame)[source]
Parameters

gidx2 – needed due to g0 flags, not originally in gwots

wltp.cycler.timelens(cond, shift=1)[source]

Include earlier + later values for some condition index.

Utility for when reviewing cycle trace “events”, to look at them in context.

8.6. Module: wltp.engine

formulae for engine power & revolutions and gear-box

wltp.engine._denormalize_n(wot_df: pandas.core.frame.DataFrame, n_idle, n_rated)[source]
wltp.engine._denormalize_p(wot_df: pandas.core.frame.DataFrame, p_rated)[source]
wltp.engine._make_v_grid(v_wot_min: float, v_wot_max: float) numpy.ndarray[source]
wltp.engine._normalize_n(wot_df: pandas.core.frame.DataFrame, n_idle, n_rated)[source]
wltp.engine._normalize_p(wot_df: pandas.core.frame.DataFrame, p_rated)[source]
wltp.engine.attach_p_avail_in_gwots(gwots: pandas.core.frame.DataFrame, *, f_safety_margin) pandas.core.frame.DataFrame[source]

Attaches both p_avail and p_avail_stable for all gears.

Parameters

gwots – a df with 2-level multiindex columns, having at least (g1, ‘p’), and optionally (‘g1’, ‘ASM’)) for each gears (as returned by interpolate_wot_on_v_grid()).

wltp.engine.calc_n2v_g_vmax(g_vmax, n2v_ratios)[source]
wltp.engine.calc_n95(wot: pandas.core.frame.DataFrame, n_rated: int, p_rated: float) Tuple[float, float][source]

Find wot’s high (& low) n where 95% of power is produced (n_max1 of Annex 2-2.g).

TODO: accept n_lim

Split P_norm in 2 sections around n_rated, and interpolate separately each section.

Wot

Must contain n & p_norm.

Returns

a tuple with (low, hgh); both can be np.NAN if failed to find (error info-logged)

wltp.engine.calc_n_max(n95_high, n_max_cycle, n_max_vehicle)[source]
wltp.engine.calc_n_max_cycle(n2v_g_vmax, V: pandas.core.series.Series)[source]

Calc n_max2 of Annex 2-2.g based on max(V) of “base cycle” (Annex 1-9.1).

wltp.engine.calc_n_max_vehicle(n2v_g_vmax, v_max)[source]

Calc n_max3 of Annex 2-2.g from v_max (Annex 2-2.i).

wltp.engine.calc_p_available(P: Union[pandas.core.generic.NDFrame, numpy.ndarray, int, float], f_safety_margin, ASM: Optional[Union[pandas.core.generic.NDFrame, numpy.ndarray, int, float]] = 0) Union[pandas.core.generic.NDFrame, numpy.ndarray, int, float][source]

Calculate p_available according to Annex 2-3.4.

Parameters
  • P – power (usually from WOT)

  • f_safety_margin – usually 0.1

  • ASM – in % (e.g. 0.10, 0.35), not enforcing any of GTR’s restrictions (e.g. <= 50%)

Returns

same units as P

wltp.engine.denorm_wot(wot_df: pandas.core.frame.DataFrame, n_idle, n_rated, p_rated)[source]
wltp.engine.interpolate_wot_on_v_grid(wot: pandas.core.frame.DataFrame, n2v_ratios) pandas.core.frame.DataFrame[source]

Return a new linearly interpolated df on v with inv.v_decimals.

Parameters

df

A df containing at least n (in RPM); any other column gets interpolated.

Attention

Do not include non-linear columns (e.g. p_resistances(v^2)) because those interpolated values would be highly inaccurate!

Returns

the wot interpolated on a v-grid accommodating all gears with 2-level columns (item, gear)

wltp.engine.norm_wot(wot_df: pandas.core.frame.DataFrame, n_idle, n_rated, p_rated)[source]
wltp.engine.parse_wot(wot) pandas.core.frame.DataFrame[source]

Make a wot-df from 2D-matrix(lists/numpy), dict, df(1-or-2 cols) or series,

ensuring the result wot contains one of p, p_norm, and n, n_norm columns.

Use if from interactive code to quickly feed algo with some tabular wot.

wltp.engine.preproc_wot(mdl: collections.abc.Mapping, wot) pandas.core.frame.DataFrame[source]

Parses & validates wot from string or other matrix format

see parse_wot()

wltp.engine.validate_n_max(wot: pandas.core.frame.DataFrame, n_max: int) None[source]

Simply check the last N wot point is >= n_max.

wltp.engine.validate_wot(wot: pandas.core.frame.DataFrame, n_idle, n_rated, p_rated, n_min_drive_set) pandas.core.frame.DataFrame[source]

Higher-level validation of the wot-curves with respect to model.

8.7. Module: wltp.vehicle

formulae for cycle/vehicle dynamics

>>> from wltp.vehicle import *
>>> __name__ = "wltp.vehicle"
wltp.vehicle.calc_default_resistance_coeffs(test_mass, regression_curves)[source]

Approximating typical P_resistance based on vehicle test-mass.

The regression-curves are in the model resistance_coeffs_regression_curves. Use it for rough results if you are missing the real vehicle data.

wltp.vehicle.calc_inertial_power(V, A, test_mass, f_inertial)[source]

Power demands of the cycle accelerations, Annex 2-3.1.

Parameters
  • test_mass

    The test mass of the vehicle used in all calculations, as defined in Annex 4.2.1.3.1, pg 94.

    units

    kg

    tags

    input

    #/definitions/positiveNumber

  • f_inertial

    This is the kr inertial-factor used in the 2nd part of the formula for calculating required-power (Annex 2-3.1).

    type

    number

    default

    1.03

    tags

    input, constant

wltp.vehicle.calc_mro(unladen_mass, driver_mass)[source]
wltp.vehicle.calc_p_m_ratio(p_rated, unladen_mass)[source]
wltp.vehicle.calc_p_resist(V: Union[pandas.core.generic.NDFrame, numpy.ndarray, int, float], f0, f1, f2)[source]

The p_resist required to overcome vehicle-resistances for various velocities,

as defined in Annex m-2.i (calculate V_max_vehicle).

wltp.vehicle.calc_required_power(p_resist: Union[pandas.core.generic.NDFrame, numpy.ndarray, int, float], p_inert: Union[pandas.core.generic.NDFrame, numpy.ndarray, int, float]) Union[pandas.core.generic.NDFrame, numpy.ndarray, int, float][source]

Equals \(road_loads + inertial_power\)

@see: Annex 2-3.1

wltp.vehicle.calc_unladen_mass(mro, driver_mass)[source]
wltp.vehicle.decide_wltc_class(wltc_classes_data: Mapping[str, dict], p_m_ratio, v_max)[source]

Vehicle classification according to Annex 1-2.

8.8. Module: wltp.vmax

formulae estimating v_max from wot

The v_max is found by the maximum gear where p_avail_stable intersects p_resist (Annex 2-fig A2).

Note

On Aug 2019 Mr Heinz confirmed a shortcut of the vmax discovery procedure, implemented here: scan 3 gear from top, and stop on first having v_max less-or-equal than previous, and accept v_max from that previous gear.

class wltp.vmax.VMaxRec(v_max, n_vmax, g_vmax, is_n_lim, wot)

Bases: tuple

Solution results of the equation finding the v-max of each gear:

  • v_max: in kmh; np.NAN if not found

  • n_vmax: the engine speed producing v_max; np.NAN if not found

  • g_vmax: the number of the gear producing v_max

  • is_n_lim: true if max-WOT(n) reached for VMax (ie. p_avail_stable always > p_resist)

  • wot: df with intermediate curves on grid-V used to solve the equation

_asdict()[source]

Return a new OrderedDict which maps field names to their values.

_field_defaults = {}
_fields = ('v_max', 'n_vmax', 'g_vmax', 'is_n_lim', 'wot')
_fields_defaults = {}
classmethod _make(iterable)[source]

Make a new VMaxRec object from a sequence or iterable

_replace(**kwds)[source]

Return a new VMaxRec object replacing specified fields with new values

property g_vmax

Alias for field number 2

property is_n_lim

Alias for field number 3

property n_vmax

Alias for field number 1

property v_max

Alias for field number 0

property wot

Alias for field number 4

wltp.vmax._find_p_remain_root(gid: int, wot: pandas.core.frame.DataFrame, p_resist: Union[pandas.core.series.Series, numpy.ndarray]) wltp.vmax.VMaxRec[source]

Find the velocity (the “x”) where p_avail (the “y”) crosses p_resist,

rounded towards the part of wot where p_remain > 0 (like MSAccess in e.g. F new vehicle.form.vbs#L3273) or v @ max p_wot, if p_remain_stable is always positive.

Parameters

gear_gwot – A df indexed by grid v with (at least) p_remain_stable column.

Returns

a VMaxRec with v_max in kmh or np.NAN

wltp.vmax.calc_v_max(gwots: Union[pandas.core.series.Series, pandas.core.frame.DataFrame]) wltp.vmax.VMaxRec[source]

Finds maximum velocity by scanning gears from the top.

TODO: accept n_lim

Parameters

gwots – a dataframe indexed by a grid of rounded velocities, containing (at least) p_resist and p_avail_stable columns for all gears, as generated by interpolate_wot_on_v_grid(), and augmented by attach_p_avail_in_gwots() (in kW) and calc_p_resist().

Returns

a VMaxRec namedtuple.

8.9. Module: wltp.downscale

formulae downscaling cycles based on pmr/test_mass ratio

wltp.downscale.calc_V_capped(V_dsc, v_cap)[source]

Clip all values of V_dsc above v_cap.

wltp.downscale.calc_V_compensated(v_cap, V_dsc: pandas.core.series.Series, V_capped: pandas.core.series.Series, compensate_phases_t_extra, class_phases_grouper) pandas.core.series.Series[source]

Equalize capped-cycle distance to downscaled one.

Parameters
  • V_dsc – compared against V_capped to discover capped amples

  • V_capped – compensated with extra v_cap samples as defined by compensate_phases_t_extra.

  • v_cap – needed just for verification,

Returns

the compensated V_capped, same name & index

Note

Cutting corners by grouping phases like VA0, so an extra 0 needed at the end when constructing the compensated trace.

wltp.downscale.calc_V_dsc_raw(v_class: pandas.core.series.Series, f_dsc, dsc_phases) pandas.core.series.Series[source]

Downscale velocity profile by f_dsc.

Returns

the downscaled velocity profile, not-rounded (by the Spec should have 1 decimal only)

  • The Spec demarks 2 UP/DOWN phases with 3 time-points in dsc_phases, eg. for class3:

    • 1533: the “start” of downscaling

    • 1724: the “tip”

    • 1763: the “end”

  • V @ start & end (1533, 1763) must remain unchanged (by the Spec & asserted).

  • The “tip” is scaled with the UP-phase (by the Spec).

  • Those numbers are recorded in the model @ <class>/downscale/phases/

  • The code asserts that the scaled V remains as smooth at tip as originally (and a bit more, due to the downscaling).

Compare v075(class-3a) with AccDB:

V_accdb V_python diff% 45.1636 45.1637 -0.000224059 # middle on tip(eg. 1724), both scale & recurse 45.1636 45.1637 -0.000122941 # on tip, scale & recurse, round(1) 45.1636 45.1637 -5.39439e-05 # on tip-1 45.1636 45.1636 0 # on tip-1, scale & recurse, round(1) 45.1636 45.1637 -6.48634e-05 # on tip+1 45.1636 45.1636 0 # on tip+1, scale & recurse, round(1)

@see: Annex 1-8, p 64-68

wltp.downscale.calc_compensate_phases_t_extra_raw(v_cap: Optional[float], dsc_distances, capped_distances, class_phase_boundaries) pandas.core.series.Series[source]

Extra time each phase needs to run at v_cap to equalize V_capped distance with V_dsc.

Parameters

v_cap – Compensation applies only if v_cap > 0.

Returns

a series with the # of extra secs for each phase (which may be full of 0s)

This functions checks zero/null v_cap condition.

wltp.downscale.calc_f_dsc(f_dsc_raw: float, f_dsc_threshold: float, f_dsc_decimals) float[source]

ATTENTION: by the spec, f_dsc MUST be > 0.01 to apply, but in F_new_vehicle.form.txt:(3537, 3563, 3589) a +0.5 is ADDED! (see CHANGES.rst)

wltp.downscale.calc_f_dsc_raw(wltc_dsc_p_max_values, wltc_dsc_coeffs, p_rated, test_mass, f0, f1, f2, f_inertial)[source]

Check if downscaling required, and apply it.

Returns

(float) the factor

@see: Annex 1-7, p 68

wltp.downscale.downscale_by_recursing(V, f_dsc, phases)[source]

Downscale by recursing (according to the Spec).

wltp.downscale.downscale_by_scaling(V: pandas.core.series.Series, f_dsc, phases) pandas.core.series.Series[source]

Multiply the UP/DOWN phases with 2 factors (no recurse, against the Spec).

Example, for class-3:

\[ \begin{align}\begin{aligned}V_{dsc}[1520:1725] = V[1520] + (V[1520:1725] - V[1520]) imes (1 - f_{dsc})\\V_{dsc}[1526:1743] = V[1743] + (V[1526:1743] - V[1743]) imes f_{corr}\end{aligned}\end{align} \]
wltp.downscale.make_compensated_phase_boundaries(class_phase_boundaries, compensate_phases_t_extra) List[Tuple[int, int]][source]
wltp.downscale.round_compensate_phases_t_extra(compensate_phases_t_extra_raw: pandas.core.series.Series) pandas.core.series.Series[source]

8.10. Module: wltp.nmindrive

Calculate/Validate n_min_drive parameters, defined mostly in Annex 2-2.k.

>>> from wltp.nmindrive import *
>>> __name__ = "wltp.nmindrive"
class wltp.nmindrive.NMinDrives(n_min_drive1, n_min_drive2_up, n_min_drive2_stopdecel, n_min_drive2, n_min_drive_set, n_min_drive_up, n_min_drive_up_start, n_min_drive_down, n_min_drive_down_start, t_cold_end)

Bases: tuple

Consume (R)ounded values to construct a _NMinDrives instance.

_asdict()[source]

Return a new OrderedDict which maps field names to their values.

_autograph = {None: {None: {'inp_sideffects': 'valid: n_min_drives', 'needs': ['n_min_drive1_R'(>'n_min_drive1'), 'n_min_drive2_up_R'(>'n_min_drive2_up'), 'n_min_drive2_stopdecel_R'(>'n_min_drive2_stopdecel'), 'n_min_drive2_R'(>'n_min_drive2'), 'n_min_drive_set_R'(>'n_min_drive_set'), 'n_min_drive_up_R'(>'n_min_drive_up'), 'n_min_drive_up_start_R'(>'n_min_drive_up_start'), 'n_min_drive_down_R'(>'n_min_drive_down'), 'n_min_drive_down_start_R'(>'n_min_drive_down_start'), 't_cold_end'(>), sfx('valid: n_min_drives')], 'provides': 'n_min_drives'}}}
_field_defaults = {}
_fields = ('n_min_drive1', 'n_min_drive2_up', 'n_min_drive2_stopdecel', 'n_min_drive2', 'n_min_drive_set', 'n_min_drive_up', 'n_min_drive_up_start', 'n_min_drive_down', 'n_min_drive_down_start', 't_cold_end')
_fields_defaults = {}
classmethod _make(iterable)[source]

Make a new NMinDrives object from a sequence or iterable

_replace(**kwds)[source]

Return a new NMinDrives object replacing specified fields with new values

property n_min_drive1

Alias for field number 0

property n_min_drive2

Alias for field number 3

property n_min_drive2_stopdecel

Alias for field number 2

property n_min_drive2_up

Alias for field number 1

property n_min_drive_down

Alias for field number 7

property n_min_drive_down_start

Alias for field number 8

property n_min_drive_set

Alias for field number 4

property n_min_drive_up

Alias for field number 5

property n_min_drive_up_start

Alias for field number 6

property t_cold_end

Alias for field number 9

wltp.nmindrive._NMinDrives

alias of wltp.nmindrive.NMinDrives

wltp.nmindrive._check_higher_from_n_min_drive_set(n, n_min_drive_set)[source]
wltp.nmindrive._check_lower_than_2x_n_min_drive_set(n, n_min_drive_set)[source]
wltp.nmindrive._compose_mdl_2_n_min_drives(aug: wltp.autograph.Autograph = None, **pipeline_kw) Pipeline[source]
wltp.nmindrive.calc_n_idle_R(n_idle: float) int[source]
wltp.nmindrive.calc_n_min_drive1(n_idle_R: int) int[source]
wltp.nmindrive.calc_n_min_drive1_R(n_min_drive1: float) int[source]
wltp.nmindrive.calc_n_min_drive2(n_idle_R: int) float[source]
wltp.nmindrive.calc_n_min_drive2_R(n_min_drive2: float) int[source]
wltp.nmindrive.calc_n_min_drive2_stopdecel(n_idle_R: int) int[source]
wltp.nmindrive.calc_n_min_drive2_stopdecel_R(n_min_drive2_stopdecel: float) int[source]
wltp.nmindrive.calc_n_min_drive2_up(n_idle_R: int) float[source]
wltp.nmindrive.calc_n_min_drive2_up_R(n_min_drive2_up: float) int[source]
wltp.nmindrive.calc_n_min_drive_down(n_min_drive_set: int) int[source]
wltp.nmindrive.calc_n_min_drive_down_R(n_min_drive_down: float) int[source]
wltp.nmindrive.calc_n_min_drive_down_start(n_min_drive_down: int) int[source]
wltp.nmindrive.calc_n_min_drive_down_start_R(n_min_drive_down_start: float) int[source]
wltp.nmindrive.calc_n_min_drive_set(n_idle_R: int, n_rated_R: float) float[source]
wltp.nmindrive.calc_n_min_drive_set_R(n_min_drive_set: float) int[source]
wltp.nmindrive.calc_n_min_drive_up(n_min_drive_set: int) int[source]
wltp.nmindrive.calc_n_min_drive_up_R(n_min_drive_up: float) int[source]
wltp.nmindrive.calc_n_min_drive_up_start(n_min_drive_up: int) int[source]
wltp.nmindrive.calc_n_min_drive_up_start_R(n_min_drive_up_start: float) int[source]
wltp.nmindrive.calc_n_rated_R(n_rated: float) int[source]
wltp.nmindrive.mdl_2_n_min_drives = Pipeline('mdl_2_n_min_drives', needs=['n_min_drive1_R', 'n_min_drive2_up_R', 'n_min_drive2_stopdecel_R', 'n_min_drive2_R', 'n_min_drive_set_R', 'n_min_drive_up_R', 'n_min_drive_up_start_R', 'n_min_drive_down_R', 'n_min_drive_down_start_R', 't_cold_end', sfx('valid: n_min_drives'), 'n_idle', 'n_idle_R', 'n_min_drive1', 'n_min_drive2', 'n_min_drive2_stopdecel', 'n_min_drive2_up', 'n_min_drive_set', 'n_min_drive_down', 'n_min_drive_down_start', 'n_rated_R', 'n_min_drive_up', 'n_min_drive_up_start', 'n_rated', sfx('valid: n_idle'), sfx('valid: n_rated'), sfx('valid: n_min_drive_up'), sfx('valid: n_min_drive_down'), sfx('valid: n_min_drive_up_start'), sfx('valid: n_min_drive_down_start')], provides=['n_min_drives', 'n_idle_R', 'n_min_drive1', 'n_min_drive1_R', 'n_min_drive2', 'n_min_drive2_R', 'n_min_drive2_stopdecel', 'n_min_drive2_stopdecel_R', 'n_min_drive2_up', 'n_min_drive2_up_R', 'n_min_drive_down', 'n_min_drive_down_R', 'n_min_drive_down_start', 'n_min_drive_down_start_R', 'n_min_drive_set', 'n_min_drive_set_R', 'n_min_drive_up', 'n_min_drive_up_R', 'n_min_drive_up_start', 'n_min_drive_up_start_R', 'n_rated_R', sfx('valid: n_min_drive_down'), sfx('valid: n_min_drive_down_start'), sfx('valid: n_min_drive_up'), sfx('valid: n_min_drive_up_start'), sfx('valid: n_min_drives'), sfx('valid: n_rated'), sfx('valid: n_idle')], x31 ops: NMinDrives, calc_n_idle_R, calc_n_min_drive1, calc_n_min_drive1_R, calc_n_min_drive2, calc_n_min_drive2_R, calc_n_min_drive2_stopdecel, calc_n_min_drive2_stopdecel_R, calc_n_min_drive2_up, calc_n_min_drive2_up_R, calc_n_min_drive_down, calc_n_min_drive_down_R, calc_n_min_drive_down_start, calc_n_min_drive_down_start_R, calc_n_min_drive_set, calc_n_min_drive_set_R, calc_n_min_drive_up, calc_n_min_drive_up_R, calc_n_min_drive_up_start, calc_n_min_drive_up_start_R, calc_n_rated_R, validate_n_min_drive_down_V1, validate_n_min_drive_down_V2, validate_n_min_drive_down_start_V1, validate_n_min_drive_down_start_V2, validate_n_min_drive_up_V1, validate_n_min_drive_up_V2, validate_n_min_drive_up_start_V1, validate_n_min_drive_up_start_V2, validate_n_min_drives, validate_n_rated_above_n_idle)

A pipeline to pre-process n_min_drives values. (the validation nodes in the plot below are hidden, not to clutter the diagram):

>>> import networkx as nx
>>> netop = mdl_2_n_min_drives
>>> hidden = netop.net.find_ops(lambda n, _: not n.name.startswith("validate_"))
>>> g = nx.DiGraph()
>>> node_attrs = {"_no_plot": True}
>>> g.add_nodes_from((n, node_attrs) for n in hidden)
>>> hidden = [n for n in netop.net.graph.nodes if str(n).startswith("sideffect(")]
>>> g.add_nodes_from((n, node_attrs) for n in hidden)

nmindrives

Example:

>>> from wltp.nmindrive import mdl_2_n_min_drives
>>> mdl = {"n_idle": 500, "n_rated": 3000, "p_rated": 80, "t_cold_end": 470}
>>> n_min_drives = mdl_2_n_min_drives.compute(mdl, "n_min_drives")
>>> n_min_drives
{'n_min_drives': NMinDrives(n_min_drive1=500, n_min_drive2_up=575, n_min_drive2_stopdecel=500,
 n_min_drive2=450, n_min_drive_set=813, n_min_drive_up=813, n_min_drive_up_start=813,
 n_min_drive_down=813, n_min_drive_down_start=813, t_cold_end=470)}
wltp.nmindrive.validate_n_min_drive_down_V1(n_min_drive_down_R: int, n_min_drive_set_R: int)[source]
wltp.nmindrive.validate_n_min_drive_down_V2(n_min_drive_down_R: int, n_min_drive_set_R: int)[source]
wltp.nmindrive.validate_n_min_drive_down_start_V1(n_min_drive_down_start_R: int, n_min_drive_set_R: int)[source]
wltp.nmindrive.validate_n_min_drive_down_start_V2(n_min_drive_down_start_R: int, n_min_drive_set_R: int)[source]
wltp.nmindrive.validate_n_min_drive_up_V1(n_min_drive_up_R: int, n_min_drive_set_R: int)[source]
wltp.nmindrive.validate_n_min_drive_up_V2(n_min_drive_up_R: int, n_min_drive_set_R: int)[source]
wltp.nmindrive.validate_n_min_drive_up_start_V1(n_min_drive_up_start_R: int, n_min_drive_set_R: int)[source]
wltp.nmindrive.validate_n_min_drive_up_start_V2(n_min_drive_up_start_R: int, n_min_drive_set_R: int)[source]
wltp.nmindrive.validate_n_min_drives()[source]

Ensure all no-sideffect validations run.

wltp.nmindrive.validate_n_rated_above_n_idle(n_idle_R, n_rated_R)[source]

8.11. Module: wltp.invariants

definitions & idempotent formulae for physics/engineering

wltp.invariants.AND_columns_with_NANFLAGs(df: pandas.core.frame.DataFrame, nan_val: int = 1, NANFLAG=- 1) pandas.core.series.Series[source]

see apply_bool_op_on_columns_with_NANFLAGs()

wltp.invariants.OR_columns_with_NANFLAGs(df: pandas.core.frame.DataFrame, nan_val: int = 0, NANFLAG=- 1) pandas.core.series.Series[source]

see apply_bool_op_on_columns_with_NANFLAGs()

wltp.invariants.apply_bool_op_on_columns_with_NANFLAGs(df: pandas.core.frame.DataFrame, op, nan_val: int, NANFLAG=- 1) pandas.core.series.Series[source]

NANs assumed nan_val`, rows with all NANs are skipped.

Parameters
  • df – a preferably dtype=int8 dataframe with NANFLAGs denoting missing values

  • op – one of pd.Series.__or__(), __and__, etc

  • nan_val – replace NANs with this value (typically 0 or 1, to cleanly convert to astype(bool)). Applied only on rows that are not all NANs.

Returns

A series(dtype=int8) with NANFLAG elements where all columns were NANFLAGs.

Example:

>>> df0 = pd.DataFrame({'a': [-1, 0, 1], 'b': [-1, -1, -1]})
>>> df0
   a  b
0 -1 -1
1  0 -1
2  1 -1
>>> df = df0.copy()
>>> apply_bool_op_on_columns_with_NANFLAGs(df0, pd.Series.__or__, 0)
0   -1
1    0
2    1
dtype: int8
>>> apply_bool_op_on_columns_with_NANFLAGs(df0, pd.Series.__and__, 1)
0   -1
1    0
2    1
dtype: int8
wltp.invariants.asint(n)[source]

Convert numbers or arrays to integers, only when not containing NAN/INFs.

Parameters

n – number/sequence of numbers

Returns

number/ndarray, or the unrounded(!) n if it contained NAN/INFs

Examples:

>>> asint(3.14)
3
>>> type(_)
<class 'int'>
>>> asint(float('inf'))
inf
>>> type(_)
<class 'float'>
>>> asint([1, 3.14])
array([1, 3])
>>> _.dtype             # doctest: +SKIP
'int64'
>>> asint([np.NAN, 3.14, -np.inf])  # input untouched!!
array([ nan, 3.14, -inf])
>>> _.dtype
dtype('float64')
wltp.invariants.nround1(n)[source]

The GTR rounding for N (RPM) to integer precision, e.g. for n_min_drive_set.

wltp.invariants.nround10(n)[source]

The GTR rounding for N (RPM) to the nearest 10 RPMs precision, e.g. for n_idle.

wltp.invariants.round1(n, decimals=0)[source]

Rounding with the Access DB method (all ties half-up: 0.5 –> 1).

TIP: Double rounding might be needed to achieve stability on ties with long decimals (see downscale scale vs recurse)

Parameters
  • n – number/array to round

  • decimals – Number of decimal places to round to (default: 0). If decimals is negative, it specifies the number of positions to the left of the decimal point. None means keep it as it is.

>>> round1(2.5, None)
2.5
>>> round1(2.5)
3.0
>>> round1(np.arange(-6.55, 7), 1)
array([-6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5,
       0.5,  1.5,  2.5,  3.5, 4.5,  5.5,  6.5])
>>> round1(np.arange(-6.65, 7), 1)
array([-6.6, -5.6, -4.6, -3.6, -2.7, -1.7, -0.7,
       0.3,  1.3,  2.3,  3.4, 4.4,  5.4,  6.4])
>>> round1([0.49999999999999994, 5000000000000001.0, -2.4, 2.4])
 array([ 1.e+00,  5.e+15, -2.e+00,  2.e+00])
wltp.invariants.v_decimals = 1

The number of digits for Velocity traces used in WLTC.

wltp.invariants.v_step = 0.1

The number of V-grid steps required for covering Velocity traces.

wltp.invariants.vround(n, *, decimals=1)[source]

The rounding of the GTR, used for Vs already close to grid, e.g. to index with results from operations on the grid.

8.12. Module: wltp.autograph

Harvest functions & annotate their dependencies to build pipelines.

>>> from wltp.autograph import *
>>> __name__ = "wltp.autograph"
class wltp.autograph.Autograph(out_patterns: Optional[Union[str, Pattern, Iterable[Union[str, Pattern]]]] = None, overrides: Optional[Mapping[Union[str, Pattern, Iterable[Union[str, Pattern]]], Mapping]] = None, renames: Optional[Mapping] = None, full_path_names: bool = False, domain: Optional[Union[str, int, Collection]] = None, sep=None)[source]

Bases: wltp.autograph.Prefkey

Make a graphtik operation by inspecting a function

The params below (except full_path_names) are merged in this order (1st takes precendance):

  1. dict from overrides keyed by name

  2. decorated with autographed()

  3. inspected from the callable

Example:

>>> def calc_sum_ab(a, b=0):
...     return a + b
>>> aug = Autograph(out_patterns=['calc_', 'upd_'], renames={"a": "A"})
>>> aug.wrap_funcs([calc_sum_ab])
[FnOp(name='calc_sum_ab',
                    needs=['A', 'b'(?)],
                    provides=['sum_ab'],
                    fn='calc_sum_ab')]
_apply_renames(rename_maps: Iterable[Union[Mapping, unset]], word_lists: Iterable)[source]

Rename words in all word_lists matching keys in rename_maps.

_collect_rest_op_args(decors: dict)[source]

Collect the rest operation arguments from autographed decoration.

_deduce_provides_from_fn_name(fn_name)[source]
_from_overrides(key)[source]
_match_fn_name_pattern(fn_name, pattern) Optional[Union[str, Tuple[str, str]]][source]

return matched group or groups, callable results or after matched prefix string

domain: Collection[source]

the autographed() domains to search when wrapping functions, in-order; if undefined, only the default domain (None) is included, otherwise, the default, None, must be appended explicitely (usually at the end). List-ified if a single str, autographed() decors for the 1st one matching are used;

full_path_names[source]

Whether operation-nodes would be named after the fully qualified name (separated with by default)

out_patterns[source]

Autodeduce provides by parsing function-names against a collection of these items, and decide provides by the the 1st one matching (unless provides are specified in the overrides):

  • regex: may contain 1 or 2 groups:

    • 1 group: the name of a single provides

    • 2 groups: 2nd is the name of a single sideffected dependency, the 1st is the sideffect acting upon the former;

  • str: matched as a prefix of the function-name, which is trimmed by the first one matching to derrive a single provides;

Note that any out_sideffects in overrides, alone, do not block the rule above.

overrides[source]

a mapping of fn-keys --> dicts with keys:

name, needs, provides, renames, inp_sideffects, out_sideffects

An fn-key may be a string-tuple of names like:

[module, [class, ...] callable
renames[source]

global from --> to renamings applied both onto needs & provides. They are applied after merging has been completed, so they can rename even “inspected” names.

wrap_func(func, domain: Optional[Union[str, int, Collection]] = None) graphtik.fnop.FnOp[source]
wrap_funcs(funcs: Collection[Union[Callable, Tuple[Union[str, Collection[str]], Union[Callable, Collection[Callable]]]]], exclude=(), domain: Optional[Union[str, int, Collection]] = None) List[graphtik.fnop.FnOp][source]

Convert a (possibly @autographed) function into one (or more) operations.

Parameters

fn – a list of funcs (or 2-tuples (name-path, fn-path)

See also

yield_wrapped_ops() for the rest arguments.

yield_wrapped_ops(fn: Union[Callable, Tuple[Union[str, Collection[str]], Union[Callable, Collection[Callable]]]], exclude=(), domain: Optional[Union[str, int, Collection]] = None) Iterable[graphtik.fnop.FnOp][source]

Convert a (possibly @autographed) function into an graphtik FnOperations,

respecting any configured overrides

Parameters
  • fn

    either a callable, or a 2-tuple(name-path, fn-path) for:

    [module[, class, ...]] callable
    
    • If fn is an operation, yielded as is (found also in 2-tuple).

    • Both tuple elements may be singulars, and are auto-tuple-zed.

    • The name-path may (or may not) correspond to the given fn-path, and is used to derrive the operation-name; If not given, the function name is inspected.

    • The last elements of the name-path are overridden by names in decorations; if the decor-name is the “default” (None), the name-path becomes the op-name.

    • The name-path is not used when matching overrides.

  • exclude – a list of decor-names to exclude, as stored in decors. Ignored if fn already an operation.

  • domain – if given, overrides domain for autographed() decorators to search. List-ified if a single str, autographed() decors for the 1st one matching are used.

Returns

one or more FnOp instances (if more than one name is defined when the given function was autographed()).

Overriddes order: my-args, self.overrides, autograph-decorator, inspection

See also: David Brubeck Quartet, “40 days”

class wltp.autograph.FnHarvester(*, excludes: Optional[Iterable[Union[str, Pattern, Iterable[Union[str, Pattern]]]]] = None, base_modules: Optional[Iterable[Union[module, str]]] = None, predicate: Optional[Callable[[Any], bool]] = None, include_methods=False, sep=None)[source]

Bases: wltp.autograph.Prefkey

Collect public ops, routines, classes & their methods, partials into collected.

Parameters
  • collected

    a list of 2-tuples:

    (name_path, item_path)
    

    where the 2 paths correspond to the same items; the last path element is always a callable, and the previous items may be modules and/or classes, in case non-modules are given directly in harvest():

    [module, [class, ...] callable
    

    E.g. the path of a class constructor is (module_name, class_name).

    For operations, the name-part is None.

  • excludes – names to exclude; they can.be.prefixed or not

  • base_modules – skip function/classes not in these modules; if not given, include all items. If string, they are searched in sys.modules.

  • predicate – any user callable accepting a single argument returning falsy to exclude the visited item

  • include_methods – Whether to collect methods from classes

Example:

>>> from wltp import cycler, downscale, engine, vehicle, vmax
>>> modules = ('os', 'sys')
>>> funcs = FnHarvester(
...     base_modules=modules,
...     include_methods=False,
... ).harvest()
>>> len(funcs) > 50
True
>>> funcs
[(('os', 'PathLike'),
...

Use this pattern when iterating, to account for any operation instances:

>>> funcs = [
...         (name, fn if isinstance(fn, Operation) else fn)
...         for name, fn
...         in funcs
...        ]
_collect(name_path, item_path)[source]

Obey decorated name

_harvest(name_path, item_path)[source]

Recursively collect modules, routines & classes,.

collected: List[Tuple[Tuple[str, ...], Tuple[Callable, ...]]][source]
harvest(*items: Any, base_modules=Ellipsis) List[Tuple[str, Callable]][source]

Collect any callable items and children, respecting base_modules, excludes etc.

Parameters

items

module fqdn (if already imported), items with __name__, like modules, classes, functions, or partials (without __name__).

If nothing is given, attr:`baseModules is used in its place.

Note

This parameter works differently from base_modules, that is, harvesting is not limited to those modules only, recursing to any imported ones from items.

Returns

the collected

include_methods: bool = True
is_harvestable(name_path, item)[source]

Exclude already-seen, private, user-excluded objects(by name or path).

paths()[source]

returns the paths only (no callables), sorted

class wltp.autograph.Prefkey(sep=None)[source]

Bases: object

Index into dicts with a key or a joined(prefix+key), where prefix: tuple

_join_path_names(*names)[source]
_prefkey(d, key: Union[str, Pattern, Iterable[Union[str, Pattern]]], default: Optional[Union[Callable, Any]] = None)[source]
sep = '.'
wltp.autograph._is_in_my_project(item) bool[source]

UNUSED

wltp.autograph.autographed(fn=T(unset), *, name=None, needs=T(unset), provides=T(unset), renames=T(unset), returns_dict=T(unset), aliases=T(unset), inp_sideffects=T(unset), out_sideffects=T(unset), domain: Optional[Union[str, int, Collection]] = None, **kws)[source]

Decorator adding _autograph func-attribute with overrides for Autograph.

Parameters
  • name

    the name of the operation.

    • If the same name has already been defined for the same domain, it is overwritten; otherwise, a new decoration is appended, so that Autograph.yield_wrapped_ops() will produce more than one operations.

    • if not given, it will be derrived from the fn on wrap-time.

  • domain – one or more list-ified domains to assign decors into (instead of the “default” domain); it allows to reuse the same function to build different operation, when later wrapped into an operation by Autograph.

  • renames – mappings to rename both any matching the final needs & provides

  • inp_sideffects – appended into needs; if a tuple, makes it a sfxed

  • out_sideffects – appended into provides; if a tuple, makes it a sfxed

  • kws

    the rest arguments of graphtik.operation, such as:

    kwd, endured, parallel, marshalled, node_props
    

wltp.autograph.camel_2_snake_case(word)[source]
>>> camel_2_snake_case("HTTPResponseCodeXYZ")
'http_response_code_xyz'

From https://stackoverflow.com/a/1176023/548792

wltp.autograph.get_autograph_decors(fn, default=None, domain: Optional[Union[str, int, Collection]] = None) dict[source]

Get the 1st match in domain of the fn autographed() special attribute.

Parameters
  • default – return this if fn non-autographed, or domain don’t match

  • domain – list-ified if a single str

Returns

the decors that will override Autograph attributes, as found from the given fn, and for the 1st matching domain in domain:

<fn>():
  _autograph        (function-attribute)
    <domain>        (dict)
      <name>        (dict)
        <decors>    (dict)

wltp.autograph.is_regular_class(name, item)[source]

8.13. Module: wltp.io

utilities for starting-up, parsing, naming, indexing and spitting out data

class wltp.io.GearMultiIndexer(items: Optional[Sequence[str]], gnames: pandas.core.series.Series, top_gear: int, gear_namer: Callable[[int], str], level_names: Sequence[str] = ('item', 'gear'))[source]

Bases: object

Multi-indexer for 2-level df columns like (item, gear) with 1-based & closed-bracket gear.

Example 2-level grid_wots columns:

p_avail  p_avail  ... n_foo  n_foo
   g1       g2    ...   g1      g2

df.columns = gidx[:]

… Warning::

negative indices might not work as expected if gnames do not start from g1 (e.g. when constructed with from_df() static method)

Examples:

  • Without items you get simple gear-indexing:

    >>> G = GearMultiIndexer.from_ngears(5)
    >>> G.gnames
    1    g1
    2    g2
    3    g3
    4    g4
    5    g5
    dtype: object
    >>> G[1:3]
    ['g1', 'g2', 'g3']
    >>> G[::-1]
    ['g5', 'g4', 'g3', 'g2', 'g1']
    >>> G[3:2:-1]
    ['g3', 'g2']
    >>> G[3:]
    ['g3', 'g4', 'g5']
    >>> G[3:-1]
    ['g3', 'g4', 'g5']
    >>> G[-1:-2:-1]
    ['g5', 'g4']
    
    >>> G[[1, 3, 2]]
    ['g1', 'g3', 'g2']
    
    >>> G[-1]
    'g5'
    
  • When items are given, you get a “product” MultiIndex:

    >>> G = G.with_item("foo")
    >>> G[1:3]
    MultiIndex([('foo', 'g1'),
                ('foo', 'g2'),
                ('foo', 'g3')],
                names=['item', 'gear'])
    
    >>> len(G)
    5
    >>> G.shape
    (5, 2)
    >>> G.size
    10
    

    Use no items to reset them:

    >>> G = G.with_item()
    >>> G[:]
    ['g1', 'g2', 'g3', 'g4', 'g5']
    >>> G.shape
    (5,)
    
  • Notice that G0 changes “negative” indices:

    >>> G[[-5, -6, -7]]
    ['g1', 'g5', 'g4']
    >>> G = GearMultiIndexer.from_ngears(5, gear0=True)
    >>> G[:]
    ['g0', 'g1', 'g2', 'g3', 'g4', 'g5']
    >>> G[[-5, -6, -7]]
    ['g1', 'g0', 'g5']
    
_level_names(items=None) Optional[Sequence[str]][source]
colidx_pairs(item: Union[str, Iterable[str]], gnames: Optional[Iterable[str]] = None)[source]
classmethod from_df(df, items: Optional[Sequence[str]] = None, gear_namer: Callable[[int], str] = <function gear_name>)[source]

Derive gears from the deepest level columns, sorted, and the last one becomes ngear

Parameters

df – the regular or multilevel-level df, not stored, just to get gear-names.

… Warning::

Negative indices might not work as expected if gnames does not start from g1.

classmethod from_gids(gids: Iterable[int], items: Optional[Sequence[str]] = None, gear_namer: Callable[[int], str] = <function gear_name>)[source]
classmethod from_ngears(ngears: int, items: Optional[Sequence[str]] = None, gear_namer: Callable[[int], str] = <function gear_name>, gear0=False)[source]
gear_namer: Callable[[int], str][source]

a function returns the string representation of a gear, like 1 --> 'g1'

gnames: pandas.core.series.Series[source]

2-level columns; use a gear_namer like gear_names() (default)

to make a pd.Series like:

{1: 'g1', 2: 'g2', ...}
items: Optional[Sequence[str]][source]

1st level column(s)

level_names: Sequence[str] = ('item', 'gear')
property ng

The number of gears extracted from 2-level dataframe.

It equals top_gear if gnames are from 1–>top_gear.

property shape
property size
top_gear: int[source]

Setting it to a gear not in gnames, indexing with negatives may not always work.

with_item(*items: str)[source]

Makes a gear-indexer producing tuple of (items x gears).

Example:

>>> GearMultiIndexer.from_ngears(2, gear0=True).with_item("foo", "bar")[:]
MultiIndex([('foo', 'g0'),
            ('foo', 'g1'),
            ('foo', 'g2'),
            ('bar', 'g0'),
            ('bar', 'g1'),
            ('bar', 'g2')], )
wltp.io._root_pstep = ``[source]

Contains all path/column names used, after code has run code. Don’t use it directly, but either - through context-vars to allow for redefinitions, or - call paths_collected() at the end of a code run.

wltp.io.class_part_name(part_index)[source]
wltp.io.flatten_columns(columns, sep='/')[source]

Use inflate_columns() to inverse it

wltp.io.gear_name(g: int) str[source]
wltp.io.gear_names(glist)[source]
wltp.io.getdval(mdl, key, default)[source]

Returns default if key not in mdl or value is None/NAN

wltp.io.inflate_columns(columns, levels=2, sep='/')[source]

Use flatten_columns() to inverse it

wltp.io.make_autograph(out_patterns=None, *args, **kw) wltp.autograph.Autograph[source]

Configures a new Autograph with func-name patterns for this project.

wltp.io.paths_collected(with_orig=False, tag=None) List[str][source]

Return path/column names used, after code has run code.

See mappings.Pstep._paths().

wltp.io.pstep_factory = <ContextVar name='root' default=``>

The root-path wrapped in a context-var so that client code can redfine paths & column names momentarily with:

token = wio.pstep_factory.set(mapping.Pstep(<mappings>))
try:
    ...
finally:
    wio.pstep_factory.reset(token)
   ...
wltp.io.veh_name(v)[source]
wltp.io.veh_names(vlist)[source]

8.14. Module: wltp.utils

software utils unrelated to physics or engineering

class wltp.utils.Lazy(func)[source]

Bases: object

class wltp.utils.Token[source]

Bases: str

class wltp.utils._NoOp[source]

Bases: object

wltp.utils.asdict(i, argname: str)[source]

Converts iterables-of-pairs or just a pair-tuple into a dict.

Parameters

argname – Used in the exception raised when i not an iterable.

wltp.utils.aslist(i, argname: Optional[str], allowed_types=<class 'list'>)[source]

Converts iterables (except strings) into a list.

Parameters

argname – If string, it’s used in the exception raised when i not an iterable. If None, wraps non-iterables in a single-item list.

wltp.utils.astuple(i, argname: Optional[str]) tuple[source]

Converts iterables (except strings) into a tuple.

Parameters

argname – If string, it’s used in the exception raised when i not an iterable. If None, wraps non-iterables in a single-item tuple, and no exception is ever raised.

wltp.utils.ctxtvar_redefined(var: ContextVar, value)[source]
wltp.utils.generate_filenames(filename)[source]
wltp.utils.json_dump(obj, fp, pd_method=None, **kwargs)[source]
wltp.utils.json_dumps(obj, pd_method=None, **kwargs)[source]
wltp.utils.make_json_defaulter(pd_method)[source]
wltp.utils.matlab_pwd_changed(path: os.PathLike, oc: oct2py.octave)[source]

Temporarily change Matlab’s Oct2Pyc session’s working-dir to (and yield) given path.

Returns

yields the given path as a pathlib.Path instance

wltp.utils.open_file_with_os(fpath)[source]
wltp.utils.pwd_changed(path: os.PathLike)[source]

Temporarily change working-dir to (and yield) given path.

wltp.utils.str2bool(v)[source]
wltp.utils.yaml_dump(o, fp)[source]
wltp.utils.yaml_dumps(o) str[source]
wltp.utils.yaml_load(fp) Union[dict, list][source]
wltp.utils.yaml_loads(txt: str) Union[dict, list][source]

8.15. Module: wltp.cli

(OUTDATED) command-line entry-point for launching this wltp tool

See also

main()

class wltp.cli.FileSpec(io_method, fname, file, frmt, path, append, renames, kws)

Bases: tuple

Create new instance of FileSpec(io_method, fname, file, frmt, path, append, renames, kws)

_asdict()[source]

Return a new OrderedDict which maps field names to their values.

_field_defaults = {}
_fields = ('io_method', 'fname', 'file', 'frmt', 'path', 'append', 'renames', 'kws')
_fields_defaults = {}
classmethod _make(iterable)[source]

Make a new FileSpec object from a sequence or iterable

_replace(**kwds)[source]

Return a new FileSpec object replacing specified fields with new values

property append

Alias for field number 5

property file

Alias for field number 2

property fname

Alias for field number 1

property frmt

Alias for field number 3

property io_method

Alias for field number 0

property kws

Alias for field number 7

property path

Alias for field number 4

property renames

Alias for field number 6

class wltp.cli.RawTextHelpFormatter(prog, indent_increment=2, max_help_position=24, width=None)[source]

Bases: argparse.RawDescriptionHelpFormatter

Help message formatter which retains formatting of all help text.

Only the name of this class is considered a public API. All the methods provided by the class are considered an implementation detail.

_split_lines(text, width)[source]
wltp.cli._init_logging(loglevel, name='wltp-cmd', skip_root_level=False)[source]
wltp.cli.assemble_model(infiles, model_overrides)[source]
wltp.cli.build_args_parser(program_name, version, desc, epilog)[source]
wltp.cli.copy_excel_template_files(dest_dir=None)[source]
wltp.cli.get_file_format_from_extension(fname)[source]
wltp.cli.load_file_as_df(filespec)[source]
wltp.cli.load_model_part(mdl, filespec)[source]
wltp.cli.main(argv=None)[source]

Calculates an engine-map by fitting data-points vectors, use –help for getting help.

REMARKS:

* All string-values are case-sensitive.
* Boolean string-values are case insensitive:
    False  : false, off, no,  == 0
    True   : true,  on,  yes, != 0
* In KEY=VALUE pairs, the values are passed as string.  For other types,
  substitute '=' with:.
    +=     : integer
    *=     : float
    ?=     : boolean
    :=     : parsed as json
    @=     : parsed as python (with eval())

EXAMPLES:

Assuming a ‘vehicle.json’ file like this:

{
    "unladen_mass":1230,
    "test_mass":   1300,
    "v_max":    195,
    "p_rated":  100,
    "n_rated":  5450,
    "n_idle":   950,
    "n_min":    None, # Can be overridden by manufacturer.
    "n2v_ratios":      [120.5, 75, 50, 43, 37, 32],
    "f0": 100,
    "f1": 0.5,
    "f2": 0.04,
}

then the following examples:

## Calculate and print fitted engine map's parameters
#     for a petrol vehicle with the above engine-point's CSV-table:
>> %(prog)s -I vehicle.csv file_model_path=/vehicle
-I vehicle.csv file_frmt=SERIES model_path=/params header@=None 
## ...and if no header existed:
>> %(prog)s -m /vehicle:=n_idle -I engine.csv header@=None

## Assume PME column contained normalized-Power in Watts,
#    instead of P in kW:
>> %(prog)s -m fuel=petrol -I engine.csv  -irenames X X 'Pnorm (w)'

## Read the same table above but without header-row and
#    store results into Excel file, 1st sheet:
>> %(prog)s -m fuel=petrol -I engine.csv --icolumns CM PME PMF -I engine_map.xlsx sheetname+=0

## Supply as inline-json more model-values required for columns [RPM, P, FC]
#    read from <stdin> as json 2D-array of values (no headers).
#    and store results in UTF-8 regardless of platform's default encoding:
>> %(prog)s -m '/engine:={"fuel":"petrol", "stroke":15, "capacity":1359}' \
        -I - file_frmt=JSON orient=values -c RPM P FC \
        -O engine_map.txt encoding=UTF-8

Now, if input vectors are in 2 separate files, the 1st, ‘engine_1.xlsx’, having 5 columns with different headers than expected, like this:

OTHER1   OTHER2       N        "Fuel waste"   OTHER3
0       -1            12       0.14           "some text"
...

and the 2nd having 2 columns with no headers at all and the 1st column being ‘Pnorm’, then it, then use the following command:

>> %(prog)s -O engine_map -m fuel=petrol \
        -I=engine_1.xlsx sheetname+=0 \
        -c X   X   N   'Fuel consumption'  X \
        -r X   X   RPM 'FC(g/s)'           X \
        -I=engine_2.csv header@=None \
        -c Pnorm X
wltp.cli.parse_column_specifier(arg)[source]

Argument-type for –icolumns, syntaxed like: COL_NAME [(UNITS)].

wltp.cli.parse_key_value_pair(arg)[source]

Argument-type for syntax like: KEY [+*?:]= VALUE.

wltp.cli.parse_many_file_args(many_file_args, filemode, col_renames=None)[source]
wltp.cli.store_model_parts(mdl, outfiles)[source]
wltp.cli.store_part_as_df(filespec, part)[source]

If part is Pandas, store it as it is, else, store it as json recursively.

Parameters
  • filespec (FileSpec) – named_tuple

  • part – what to store, originating from model(filespec.path))

wltp.cli.validate_file_opts(opts)[source]

8.16. Module: wltp.plots

(docs disabled, breaks travis)

8.17. Module: wltp.idgears

(OUTDATED, irrelevant) Detects vehile’s gear-ratios from cycle-data and reconstructs the gears-profile by identifying the actual gears used.

Note

NOT RELLEVANT to generation of wltp cyles.

The following terms and arguments are used throughout this module:

gear-ratio(s):

the “NoverV”, which is the inverse of the “engine-speed-to-velocity” (“STV”). Conceptually it is the number of engine revolutions required, in RPM, in order for the the vehicle to travel with 1 km/h.

cycle-ratios:

The actual or detected NoverV-ratio on each cycle-point.

cycle-gears:

The actual or identified gear used on each cycle-point.

cycle-data

a pd.DataFrame containing (at the begining) N and V columns with [rpm] and [km/h] as units respectively.

The detection of the gear-ratios happens in a 3 steps, approximation or guessing, estimation and selection:

  1. Produce a number of different approximate sets of gear-ratios (the “guesses”) by producing histograms of the ratios with different combinations of bins, and then taking the first #gears of peaks.

  2. Feed these “guessed” sets of gear-ratios into a robust (with median) kmeans clustering algorithm, and

  3. pick the gear-ratios with the minimum distortion.

The identification of the actual gear on each cycle-data point (reconstructing the gear-profile) happens in 2 steps:

  1. On each cycle-point select the Gear with smallest absolute-difference with the respective identified ratio;

  2. Reconstruct engine-speed by dividing velocity-profile with identified gear-ratio on each cycle-point.

class wltp.idgears.Detekt(distort, guess, final, all_peaks_df, hist_X, hist_Y)

Bases: tuple

Create new instance of Detekt(distort, guess, final, all_peaks_df, hist_X, hist_Y)

_asdict()[source]

Return a new OrderedDict which maps field names to their values.

_field_defaults = {}
_fields = ('distort', 'guess', 'final', 'all_peaks_df', 'hist_X', 'hist_Y')
_fields_defaults = {}
classmethod _make(iterable)[source]

Make a new Detekt object from a sequence or iterable

_replace(**kwds)[source]

Return a new Detekt object replacing specified fields with new values

property all_peaks_df

Alias for field number 3

property distort

Alias for field number 0

property final

Alias for field number 2

property guess

Alias for field number 1

property hist_X

Alias for field number 4

property hist_Y

Alias for field number 5

wltp.idgears._append_aproximate_Detekt(ngears, cases, ratios, all_peaks_df, hist_X, hist_Y)[source]

Appends 2 sets of ratios for each one specified as input, the 2nd one being a linspace between the min-max.

wltp.idgears._approximate_ratios_by_binning(ratios, bins, ngears)[source]
Returns

3 sets of ratios: 1. all peaks detected with bins specified 2. the first #gears peaks 3. the first #gears peaks detected by binning the space between the previous #gears identified

wltp.idgears._estimate_ratios_by_kmeans(obs, guess, **kmeans_kws)[source]

Adapted kmeans to use norm1 distances (identical to euclidean-norm2 for 1D) and using median() for each guess, to ignore outliers and identify “gear-lines”.

wltp.idgears._filter_cycle_and_derive_ratios(df, filter_outliers=None, filter_transient=True)[source]
wltp.idgears._gather_final_Detekts(ngears, cycle_df, guessed_gears)[source]
Parameters

cycle_df (pd.DataFrame) – a dataframe with N and V columns with units [rpm] and [km/h] respectively (or inferred by comparing the means of these 2 columns).

wltp.idgears._gather_guessed_Detekts(ngears, cycle_df)[source]

Makes a number gear-ratios guesses based on histograms with different bin combinations.

wltp.idgears._n_idle_filter_df(df, col, n_idle_threshold=1.05)[source]
wltp.idgears._new_Detekt_approximation(guess_ratios, all_peaks_df, hist_X, hist_Y)[source]
wltp.idgears._norm1_1d_vq(obs, guess, is_robust=False)[source]

Simplified from scipy.cluster.vq.py_vq2()

wltp.idgears._outliers_filter_df(df, cols)[source]
wltp.idgears._outliers_filter_df2(df, cols)[source]
wltp.idgears._set_Detekt_final(gears, final_ratios, distortion)[source]
wltp.idgears._transient_filter_df(df, col, std_threshold=0.2, apply_dequantize=True)[source]
wltp.idgears.dequantize(df, method='linear')[source]

Tries to undo results of a non-constant sampling rate (ie due to indeterministic buffering).

Parameters

method (str) – see pd.DataFrame.interpolate() that is used to fill-in column-values that are held constant

Note

The results wil never have a flat section, so checking for some value (ie 0) must always apply for some margin (ie (-e-4, e-4).

wltp.idgears.dequantize_unstabbleMean(df, method='linear')[source]
Parameters

method (str) – see pd.DataFrame.interpolate() that is used to fill-in column-values that are held constant

wltp.idgears.detect_gear_ratios_from_cycle_data(ngears, cycle_df)[source]

Use a 2 step procedure if you want to plot the results, by invoking run_gear_ratios_detections_on_cycle_data() and plot_idgears_results() separately.

Returns

a ndarray with the detected gear-ratios (for the STVs, inverse them)

wltp.idgears.find_histogram_peaks(df, bins, smooth_window=None)[source]
wltp.idgears.identify_gears_from_cycle_data(cycle_df, gear_ratios)[source]

Like identify_gears_from_ratios() but with more sane filtering (ie v above 1 km/h).

Parameters
  • cycle_df (pd.DataFrame) – it must contain (at least) N and V columns (units: [rpm] and [km/h] respectively)

  • gear_ratios (ndarray) – the same as identify_gears_from_ratios()

Returns

the same as identify_gears_from_ratios()

wltp.idgears.identify_gears_from_ratios(cycle_ratios, gear_ratios)[source]

Return arrays will miss NaNs!

Parameters
  • cycle_ratios (ndarray) – a single column array/list/ndarray of ratios (STVs or inverse).

  • gear_ratios (ndarray) – this list/ndarray of gear-ratios with len equal to the #gears

Returns

a 2-tuple, where [0] is the 0-based identified-gears, and [1] the distortion for each cycle-point.

wltp.idgears.identify_n_idle(N)[source]
wltp.idgears.moving_average(x, window)[source]
Parameters

window (int) – odd windows preserve phase

From http://nbviewer.ipython.org/github/demotu/BMC/blob/master/notebooks/DataFiltering.ipynb

wltp.idgears.plot_idgears_results(cycle_df, detekt, fig=None, axes=None, original_points=None)[source]
Parameters

detekt – A Detekt-namedtuple with the data to plot

wltp.idgears.reconstruct_engine_speed(cycle_df, gear_ratios)[source]

Adds

Parameters

gear_ratios (ndarray) – this list/ndarray of gear-ratios with len equal to the #gears

TODO: Class-method

wltp.idgears.run_gear_ratios_detections_on_cycle_data(ngears, cycle_df)[source]

Invoke this one if you want to draw the results.

Parameters

cycle_df (pd.DataFrame) – it must contain (at least) N and V columns (units: [rpm] and [km/h] respectively)

Returns

a list of all Detekt tuples sorted with the most probable one at the the head, needed. Its 1st element is the solution

8.18. Validation tests & HDF5 DB

Among the various tests, those running on ‘sample’ databases for comparing differences with existing tool are the following:

8.18.1. Module: tests.vehdb

Utils for manipulating h5db with accdb & pyalgo cases.

used by many tests & notebooks.

  • load_vehicle_accdb(vehnum=1): load inps & outs for AccDB

  • load_vehicle_pyalgo(vehnum=1): load outs for AccDB

class tests.vehdb.CaseData(props: pandas.core.series.Series, df: pandas.core.frame.DataFrame, items: list)[source]

Bases: tuple

Typical case data stored in vehicle DBs.

Create new instance of CaseData(props, df, items)

_asdict()[source]

Return a new OrderedDict which maps field names to their values.

_field_defaults = {}[source]
_field_types = {'df': <class 'pandas.core.frame.DataFrame'>, 'items': <class 'list'>, 'props': <class 'pandas.core.series.Series'>}
_fields = ('props', 'df', 'items')
_fields_defaults = {}[source]
classmethod _make(iterable)[source]

Make a new CaseData object from a sequence or iterable

_replace(**kwds)[source]

Return a new CaseData object replacing specified fields with new values

property df

Alias for field number 1

property items

Alias for field number 2

property props

Alias for field number 0

class tests.vehdb.Comparator(col_accessor: Callable[[pandas.core.generic.NDFrame, str], pandas.core.generic.NDFrame], *, no_diff_percent=False, diff_colname='diff', diff_bar_kw={'align': 'mid', 'color': ['#d65f5f', '#5fba7d']}, no_styling=False)[source]

Bases: object

Pick and concat side-by-side differently-named columns from multiple dataframe.

Parameters
  • col_accessor – how to pick a column from an NDFrame

  • no_diff_percent – if this is falsy, the result dataframe contains an extra diff percent column if the respective equivalent-columns are numerics.

  • diff_colname` – how to name the extra diff column (does nothing for when not generated)

  • diff_bar_kw – if given, apply styling bars at the diff[%] columns, with these as extra styling (see https://pandas.pydata.org/pandas-docs/stable/user_guide/style.html#Bar-charts)

_col_0(equiv_colnames)[source]
_concat_datasets(datasets, equiv_colnames: Sequence[Sequence[str]], dataset_names: Sequence[str], keys: Sequence[str])[source]
_pick_n_diff_columns(datasets: Sequence[pandas.core.generic.NDFrame], col_names: Sequence[str], dataset_names: Sequence[str]) pandas.core.generic.NDFrame[source]

Pick and concatenate the respective col_names from each dataframe in datasets,

and (optionally) diff against the 1st dataset.

Parameters
  • datasets – a list of N x dataframes. Each one must contain the respective column from col_names, when access by self.col_accessor( df[i], col_name[i] ) ∀ i ∈ [0, N).

  • col_names – a list o N x column-names; Nones omit the respective dataset

Returns

_styled_with_diff_bars(df, col_level_0)[source]
compare(datasets: Sequence, equiv_colnames: Sequence[Sequence[str]], dataset_names: Sequence[str], *, no_styling=None, describe=False)[source]

List side-by-side same-kind columns (with different names) from many datasets,

optionally diffing them against the 1st dataset.

Parameters
  • datasets – a list of N x NDFrames, each one containing the respective columns in equiv_colnames.

  • equiv_colnames

    a matrix of M x N column-names, like:

    [(“p_downscale”, “f_dsc”), (“cycle”, “wltc_class”), …]

    All columns in the N dimension must exist in the respective dataframe in datasets list. The 1st columns in the M-dimension are used a axis-1, level-0 labels on the concatanated NDFrame.

  • dataset_names – used as hierarchical labels to distinguish from which dataset each column comes from

tests.vehdb._cmd(*args)[source]
tests.vehdb._file_hashed(fpath, algo='md5') Tuple[str, str][source]
tests.vehdb._git_describe(basedir='.')[source]
tests.vehdb._human_time(unixtime: Optional[int] = None) str[source]
tests.vehdb._provenir_fpath(fpath, algos=('md5', 'sha256')) Dict[str, str][source]
tests.vehdb._python_describe()[source]
tests.vehdb._root_provenance = None[source]

Lazily instanciated

tests.vehdb.accdb_renames()[source]

Renames to use accdb inputs (props, wots) into pyalgo to be used like:

props.unstack().rename(accdb_prop_renames())
tests.vehdb.all_vehnums(h5) List[int][source]
tests.vehdb.collect_nodes(h5: Union[str, pathlib.Path, pandas.io.pytables.HDFStore], predicate: Callable[[str], Any], start_in='/') List[str][source]

feed all groups into predicate and collect its truthy output

tests.vehdb.do_h5(h5: Union[str, pathlib.Path, pandas.io.pytables.HDFStore], func: callable, *args, **kw)[source]

Open & close if h5 is fname (string), do nothing if an opened db

tests.vehdb.drop_scalar_columns(df, scalar_columns) Tuple[pandas.core.frame.DataFrame, dict][source]
tests.vehdb.get_scalar_column(df, column)[source]

Extract the single scalar value if column contains it.

tests.vehdb.grid(df, fitcols=True, cwidth=None)[source]
tests.vehdb.load_n2v_gear_ratios(vehicle_iprops: Union[dict, pandas.core.series.Series])[source]

Reads all valid ndv_X values from AccDB input-properties in HD5

tests.vehdb.load_vehicle_accdb(h5: Union[str, pathlib.Path, pandas.io.pytables.HDFStore] = PosixPath('/home/docs/checkouts/readthedocs.org/user_builds/wltp/checkouts/latest/tests/../Notebooks/VehData/WltpGS-msaccess.h5'), vehnum=None) tests.vehdb.CaseData[source]

return the typical inputs data (not outs) for a vehicle in accdc: props, wot, n2vs

tests.vehdb.load_vehicle_nodes(h5: Union[str, pathlib.Path, pandas.io.pytables.HDFStore], vehnum, *subnodes) list[source]

return vehicle’s groups listed in subnodes

tests.vehdb.load_vehicle_pyalgo(h5: Union[str, pathlib.Path, pandas.io.pytables.HDFStore] = PosixPath('/home/docs/checkouts/readthedocs.org/user_builds/wltp/checkouts/latest/tests/../Notebooks/VehData/WltpGS-pyalgo.h5'), vehnum=None, nodes=('oprop', 'cycle', 'wots_vmax')) tests.vehdb.CaseData[source]

return the typical output data for a vehicle in pyalgo (see node defaults).

tests.vehdb.mdl_from_accdb(props, wot, n2vs: List[float]) dict[source]
Parameters

props – may have been renamed with accdb_renames()

tests.vehdb.merge_db_vehicle_subgroups(h5: Union[str, pathlib.Path, pandas.io.pytables.HDFStore], *vehicle_subgroups: str, veh_nums=None) Union[pandas.core.generic.NDFrame, List[pandas.core.generic.NDFrame]][source]

Merge HDF-subgroup(s) from all vehicles into an Indexed-DataFrame(s)

Parameters
  • h5 – any WltpGs-*.h5 file (path or h5db) containing vehicles/v001/{subgroups} groups

  • vehicle_subgroups – the name of a sub-group in the h5 file (or a list of such names). If a list given, returns a list

Returns

as many vertically concatenated dataframes as vehicle_subgroups given

tests.vehdb.oneliner(s) str[source]

Collapse any whitespace in stringified s into a single space.

tests.vehdb.openh5(h5: Union[str, pathlib.Path, pandas.io.pytables.HDFStore], mode='r')[source]

Open h5-fpath or reuse existing h5db instance.

tests.vehdb.print_nodes(h5: Union[str, pathlib.Path, pandas.io.pytables.HDFStore], displaywidth=160)[source]
tests.vehdb.provenance_h5node(h5: Union[str, pathlib.Path, pandas.io.pytables.HDFStore], node)[source]

Get provenance-infos from some existing H5 node.

tests.vehdb.provenance_info(*, files=(), repos=(), base=None) Dict[str, str][source]

Build a provenance record, examining environment if no base given.

Parameters

base – if given, reused (cloned first), and any fpaths & git-repos appended in it.

tests.vehdb.provenir_h5node(h5: Union[str, pathlib.Path, pandas.io.pytables.HDFStore], node, *, title=None, files=(), repos=(), base=None)[source]

Add provenance-infos to some existing H5 node.

For its API, see provenance_info().

tests.vehdb.read_matlab_csv(fpath, **csv_kw)[source]

Matlab data-files have spaces columns and are humanly indented.

tests.vehdb.run_pyalgo_on_accdb_vehicle(h5, vehnum, additional_properties=False, props_group_suffix='prop', pwot_group_suffix='wot') Tuple[dict, pandas.core.frame.DataFrame, pandas.core.frame.DataFrame][source]

Quick ‘n dirty way to invoke python-algo (bc model will change).

Parameters

h5 – the WltpGs-msaccess.h5 file (path or h5db) to read input from

Returns

the out-props key-values, the cycle data-frame, and the grid-wots constructed to solve v_max.

tests.vehdb.setup_octave()[source]

Setup oct2py library to execute wltp’s MATLAB sources.

tests.vehdb.vehnode(vehnum=None, *suffix)[source]

8.18.1.1. (abandoned)

tests.test_samples_db

(DEPRECATED) Compares the results of synthetic vehicles from JRC against pre-phase-1b Heinz's tool.

tests.test_wltp_db

(DEPRECATED) Compares the results of a batch of wltp_db vehicles against phase-1b-alpha Heinz's tool.

The following scripts in the sources maybe used to preprocess various wltc data:

  • devtools/printwltcclass.py

  • devtools/csvcolumns8to2.py

(DEPRECATED) Compares the results of synthetic vehicles from JRC against pre-phase-1b Heinz’s tool.

  • Run as Test-case to generate results for sample-vehicles.

  • Run it as cmd-line to compare with Heinz’s results.

class tests.test_samples_db.ExperimentSampleVehs(methodName='runTest')[source]

Bases: unittest.case.TestCase

Compares a batch of vehicles with results obtained from “Official” implementation.

Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.

setUp()[source]

Hook method for setting up the test fixture before exercising it.

test0_runExperiments(plot_results=False, encoding='ISO-8859-1')[source]
test1_AvgRPMs()[source]

Check mean-engine-speed diff with Heinz within some percent.

Results:

                   mean         std          min          max
python      1876.555626  146.755857  1652.457262  2220.657166
heinz       1892.048584  148.248303  1660.710716  2223.772904
diff_prcnt     0.008256    0.010170     0.004995     0.001403

Keeping idle engine revs:

                   mean         std          min          max
python      1898.453462  146.889032  1674.151741  2239.621701
heinz       1892.048584  148.248303  1660.710716  2223.772904
diff_prcnt    -0.003385    0.009254    -0.008094    -0.007127
test1_PMRatio()[source]

Check mean-engine-speed diff with Heinz within some percent for all PMRs.

Results:

                    gened_mean_rpm  heinz_mean_rpm  diff_prcnt  count
pmr
(40.759, 49.936]       1814.752308     1822.011660    0.004000      4
(49.936, 59.00401]     1861.137208     1879.822876    0.010040      4
(59.00401, 68.072]     2015.693195     2031.240237    0.007713      3
(68.072, 77.14]        1848.735584     1859.116047    0.005615      5
(77.14, 86.208]                NaN             NaN         NaN      0
(86.208, 95.276]       1786.879366     1807.764020    0.011688      5
(95.276, 104.344]      1956.288657     1980.523043    0.012388      3
(104.344, 113.412]     1929.718933     1947.787155    0.009363      3
(113.412, 122.48]      2033.321183     2051.602998    0.008991      1
(122.48, 131.548]      1781.487338     1781.591893    0.000059      1
(131.548, 140.616]             NaN             NaN         NaN      0
(140.616, 149.684]     1895.125082     1907.872848    0.006727      1

Keeping idle engine revs:

                    gened_mean_rpm  heinz_mean_rpm  diff_prcnt  count
pmr
(40.759, 49.936]       2079.060852     2071.114936   -0.003837      4
(49.936, 59.00401]     1915.715680     1911.017351   -0.002459      4
(59.00401, 68.072]     1941.701195     1930.170461   -0.005974      3
(68.072, 77.14]        1867.228321     1863.086063   -0.002223      5
(77.14, 86.208]                NaN             NaN         NaN      0
(86.208, 95.276]       1803.169294     1795.347029   -0.004357      5
(95.276, 104.344]      1813.784185     1807.303905   -0.003586      3
(104.344, 113.412]     1929.050124     1929.524894    0.000246      3
(113.412, 122.48]      1716.185416     1704.537479   -0.006833      1
(122.48, 131.548]      1769.131368     1750.813992   -0.010462      1
(131.548, 140.616]             NaN             NaN         NaN      0
(140.616, 149.684]     2083.586370     2084.413659    0.000397      1
tests.test_samples_db._compare_exp_results(tabular, outfname, run_comparison)[source]
tests.test_samples_db._plotResults(veh_fname, df_g, df_h, g_diff, ax, plot_diffs_gears_only=True, plot_original_gears=False)[source]
tests.test_samples_db._run_the_experiments(transplant_original_gears=False, plot_results=False, compare_results=False, encoding='ISO-8859-1')[source]
tests.test_samples_db.driver_weight = 70

For calculating unladen_mass.

tests.test_samples_db.init_logging(loglevel=10)[source]
tests.test_samples_db.make_heinz_fname(veh_num)[source]
tests.test_samples_db.plot_diffs_with_heinz(heinz_dir, experiment_num=None, transplant_original_gears=False, force_rerun_experiments=False)[source]
tests.test_samples_db.read_heinz_file(veh_num, heinz_dir=None)[source]
tests.test_samples_db.read_sample_file(inpfname)[source]
tests.test_samples_db.read_vehicle_data()[source]

(DEPRECATED) Compares the results of a batch of wltp_db vehicles against phase-1b-alpha Heinz’s tool.

  • Run as Test-case to generate results for sample-vehicles.

  • Run it as cmd-line to compare with Heinz’s results.

class tests.test_wltp_db.WltpDbTests(methodName='runTest')[source]

Bases: unittest.case.TestCase

Compares a batch of vehicles with results obtained from “official” implementation.

Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.

_check_gear_diffs(fname_glob)[source]
_check_n_mean(fname_glob)[source]
_check_n_mean__gear(fname_glob)[source]
_check_n_mean__pmr(fname_glob)[source]
setUp()[source]

Hook method for setting up the test fixture before exercising it.

test0_runExperiment(plot_results=False, encoding='UTF-8')[source]
test0_runExperimentTransplant(plot_results=False, encoding='UTF-8')[source]
test1_Downscale()[source]

Check mean-downscaled-velocity diff with Heinz within some percent.

### Comparison history ###

Force class3b, Phase-1b-beta(ver <= 0.0.8, Aug-2014) with Heinz maxt gear-time=2sec:

           python       heinz    diff_prcnt
count  378.000000  378.000000  0.000000e+00
mean    45.973545   46.189082  4.688300e-01
std      1.642335    1.126555 -4.578377e+01
min     35.866421   36.659117  2.210133e+00
25%     46.506718   46.504909 -3.892020e-03
50%     46.506718   46.506504 -4.620879e-04
75%     46.506718   46.506719  4.116024e-08
max     46.506718   46.506719  4.116024e-08

Not forcing class3b, honoring declared v_max & unladen_mass:

           python       heinz    diff_prcnt
count  382.000000  382.000000  0.000000e+00
mean    44.821337   44.846671  5.652189e-02
std      5.054214    5.050208 -7.933394e-02
min     28.091672   28.388418  1.056347e+00
25%     46.506718   46.504868 -3.978244e-03
50%     46.506718   46.506478 -5.162230e-04
75%     46.506718   46.506719  4.116033e-08
max     46.506718   46.506719  4.116033e-08
test2a_gear_diffs()[source]

Check diff-gears with Heinz stays within some percent.

### Comparison history ###

Class3b-Vehicles, Phase-1b-beta(ver <= 0.0.8, Aug-2014) with Heinz maxt gear-time=2sec:

             count       MEAN        STD  min  max
gears        23387  75.931818  56.921729    6  279
accell       19146  62.162338  48.831155    4  238
senza rules  16133  52.379870  35.858415   11  170

Separated test/unladen masses:

         diff_gears    diff_accel     diff_orig
count    378.000000    378.000000    378.000000
mean     104.965608     86.171958     90.235450
std      100.439783     82.613475    109.283901
min        6.000000      4.000000     11.000000
25%       36.250000     25.250000     23.000000
50%       69.000000     57.500000     51.000000
75%      142.000000    119.750000    104.750000
max      524.000000    404.000000    600.000000
sum    39677.000000  32573.000000  34109.000000
mean%      5.831423      4.787331      5.013081

Not forcing class3b, honoring declared v_max & unladen_mass:

         diff_gears    diff_accel     diff_orig
count    382.000000    382.000000    382.000000
mean      75.994764     63.633508     54.083770
std       58.290971     51.885162     38.762326
min        2.000000      2.000000      6.000000
25%       29.000000     22.000000     19.000000
50%       57.000000     48.500000     45.000000
75%      111.000000     97.000000     78.750000
max      279.000000    243.000000    173.000000
sum    29030.000000  24308.000000  20660.000000
mean%      4.221931      3.535195      3.004654
test2b_gear_diffs_transplanted()[source]

Check driveability-only diff-gears with Heinz stays within some percent.

### Comparison history ###

Force class3b, Phase-1b-beta(ver <= 0.0.8, Aug-2014) with Heinz maxt gear-time=2sec:

        diff_gears   diff_accel  diff_orig
count   378.000000   378.000000        378
mean     15.566138     5.634921          0
std      16.554295     8.136700          0
min       0.000000     0.000000          0
25%       5.000000     1.000000          0
50%      11.000000     3.000000          0
75%      19.750000     7.000000          0
max     123.000000    78.000000          0
sum    5884.000000  2130.000000          0
mean%     0.864785     0.313051          0

Not forcing class3b, honoring declared v_max & unladen_mass:

        diff_gears   diff_accel  diff_orig
count   382.000000   382.000000        382
mean     12.599476     4.651832          0
std      15.375930     7.566103          0
min       0.000000     0.000000          0
25%       4.000000     0.000000          0
50%       9.000000     2.000000          0
75%      15.000000     6.000000          0
max     123.000000    78.000000          0
sum    4813.000000  1777.000000          0
mean%     0.699971     0.258435          0
test3a_n_mean()[source]

Check mean-rpm diff with Heinz stays within some percent.

### Comparison history ###

Class3b-Vehicles, Phase-1b-beta(ver <= 0.0.8, Aug-2014) with Heinz maxt gear-time=2sec:

                   mean         std          min          max
python      1766.707825  410.762478  1135.458463  3217.428423
heinz       1759.851498  397.343498  1185.905053  3171.826208
diff_prcnt    -0.3896     -3.3772       4.4428      -1.4377

Separated test/unladen masses:

            python        heinz  diff_prcnt
count   378.000000   378.000000    0.000000
mean   1923.908119  1899.366431   -1.292099
std     628.998854   593.126296   -6.048047
min    1135.458463  1185.905053    4.442839
25%    1497.544940  1495.699889   -0.123357
50%    1740.927971  1752.668517    0.674384
75%    2121.459309  2111.876041   -0.453780
max    4965.206982  4897.154914   -1.389625

Not forcing class3b, honoring declared v_max & unladen_mass:

            python        heinz  diff_prcnt
count   382.000000   382.000000    0.000000
mean   1835.393402  1827.572965   -0.427914
std     476.687485   464.264779   -2.675781
min    1135.458463  1185.905053    4.442839
25%    1486.886555  1482.789006   -0.276341
50%    1731.983662  1739.781233    0.450210
75%    2024.534101  2018.716963   -0.288160
max    3741.849187  3750.927263    0.242609

Keeping idle engine revs:

            python        heinz  diff_prcnt
count   382.000000   382.000000    0.000000
mean   1852.183403  1827.572965   -1.346619
std     473.142045   464.264779   -1.912113
min    1168.757027  1185.905053    1.467202
25%    1507.030779  1482.789006   -1.634877
50%    1749.246014  1739.781233   -0.544021
75%    2043.861777  2018.716963   -1.245584
max    3747.026551  3750.927263    0.104102
test3b_n_mean_transplanted()[source]

Check driveability-only mean-rpm diff with Heinz stays within some percent.

### Comparison history ###

Force class3b, Phase-1b-beta(ver <= 0.0.8, Aug-2014) with Heinz maxt gear-time=2sec:

            python        heinz  diff_prcnt
count   378.000000   378.000000    0.000000
mean   1880.045112  1899.366431    1.027705
std     572.842493   593.126296    3.540904
min    1150.940393  1185.905053    3.037921
25%    1477.913404  1495.699889    1.203486
50%    1739.882957  1752.668517    0.734852
75%    2073.715015  2111.876041    1.840225
max    4647.136063  4897.154914    5.380063

Not forcing class3b, honoring declared v_max & unladen_mass:

            python        heinz  diff_prcnt
count   382.000000   382.000000    0.000000
mean   1818.519842  1827.572965    0.497829
std     469.276397   464.264779   -1.079474
min    1150.940393  1185.905053    3.037921
25%    1467.153958  1482.789006    1.065672
50%    1730.051632  1739.781233    0.562388
75%    2010.264758  2018.716963    0.420452
max    3704.999890  3750.927263    1.239605
test4a_n_mean__PMR()[source]

Check mean-rpm diff with Heinz stays within some percent for all PMRs.

### Comparison history ###

Force class3b, Phase-1b-beta(ver <= 0.0.8, Aug-2014) with Heinz maxt gear-time=2sec:

                    gened_mean_rpm  heinz_mean_rpm  diff_ratio  count
pmr
(9.973, 24.823]        1566.018469     1568.360963    0.001496     32
(24.823, 39.496]       1701.176128     1702.739797    0.000919     32
(39.496, 54.17]        1731.541637     1724.959671   -0.003816    106
(54.17, 68.843]        1894.477475     1877.786294   -0.008889     61
(68.843, 83.517]       1828.518522     1818.720627   -0.005387     40
(83.517, 98.191]       1824.060716     1830.482140    0.003520      3
(98.191, 112.864]      1794.673461     1792.693611   -0.001104     31
(112.864, 127.538]     3217.428423     3171.826208   -0.014377      1
(127.538, 142.211]     1627.952896     1597.571904   -0.019017      1
(142.211, 156.885]             NaN             NaN         NaN      0
(156.885, 171.558]             NaN             NaN         NaN      0
(171.558, 186.232]     1396.061758     1385.176569   -0.007858      1

Separated test/unladen masses:

                     gened_mean_rpm  heinz_mean_rpm  diff_prcnt  count
pmr
(11.504, 26.225]        1579.612698     1585.721306    0.386716     28
(26.225, 40.771]        1706.865069     1700.689983   -0.363093     41
(40.771, 55.317]        1866.150857     1841.779091   -1.323273    119
(55.317, 69.863]        2122.662626     2085.262950   -1.793523    122
(69.863, 84.409]        2228.282795     2171.952804   -2.593518     29
(84.409, 98.955]        1783.316413     1787.378401    0.227777      4
(98.955, 113.501]       1718.157828     1718.516147    0.020855     31
(113.501, 128.0475]     2005.415058     1954.763742   -2.591173      2
(128.0475, 142.594]     1566.601860     1553.383676   -0.850928      1
(142.594, 157.14]               NaN             NaN         NaN      0
(157.14, 171.686]               NaN             NaN         NaN      0
(171.686, 186.232]      1396.061758     1385.176569   -0.785834      1

Not forcing class3b, honoring declared v_max & unladen_mass:

                    gened_mean_rpm  heinz_mean_rpm  diff_prcnt  count
pmr
(9.973, 24.823]        1560.010258     1563.836656    0.245280     33
(24.823, 39.496]       1725.209986     1725.004638   -0.011904     34
(39.496, 54.17]        1737.811065     1730.770088   -0.406812    123
(54.17, 68.843]        1996.999520     1983.753219   -0.667739     94
(68.843, 83.517]       2051.088434     2034.594136   -0.810692     59
(83.517, 98.191]       1964.832555     1958.081066   -0.344801      4
(98.191, 112.864]      1682.122484     1684.443875    0.138004     31
(112.864, 127.538]     2718.877009     2687.055802   -1.184241      2
(127.538, 142.211]     1660.925042     1668.155469    0.435325      1
(142.211, 156.885]             NaN             NaN         NaN      0
(156.885, 171.558]             NaN             NaN         NaN      0
(171.558, 186.232]     1396.061758     1385.176569   -0.785834      1
Mean: 0.419219429398

pandas 0.15.1:

                    gened_mean_rpm  heinz_mean_rpm  diff_prcnt  count
pmr
(9.973, 24.823]        2037.027221     2038.842442    0.089111     33
(24.823, 39.496]       2257.302959     2229.999526   -1.224369     34
(39.496, 54.17]        1912.075914     1885.792807   -1.393743    123
(54.17, 68.843]        1716.720028     1717.808457    0.063402     94
(68.843, 83.517]       1677.882399     1683.916224    0.359610     59
(83.517, 98.191]       1535.881170     1551.609661    1.024070      4
(98.191, 112.864]      1571.290286     1589.997331    1.190553     31
(112.864, 127.538]     1409.308426     1425.965019    1.181898      2
(127.538, 142.211]     1975.481368     1967.808440   -0.389923      1
(142.211, 156.885]             NaN             NaN         NaN      0
(156.885, 171.558]             NaN             NaN         NaN      0
(171.558, 186.232]     1950.377512     1937.426430   -0.668468      1
Mean diff_prcnt: 0.632095580562
                    gened_mean_rpm  heinz_mean_rpm  diff_prcnt  count
Keeping idle engine revs::

pmr (9.973, 24.823] 2058.624153 2038.842442 -0.970242 33 (24.823, 39.496] 2271.419763 2229.999526 -1.857410 34 (39.496, 54.17] 1927.898841 1885.792807 -2.232803 123 (54.17, 68.843] 1733.545963 1717.808457 -0.916139 94 (68.843, 83.517] 1694.461857 1683.916224 -0.626256 59 (83.517, 98.191] 1553.854990 1551.609661 -0.144710 4 (98.191, 112.864] 1590.081566 1589.997331 -0.005298 31 (112.864, 127.538] 1427.367629 1425.965019 -0.098362 2 (127.538, 142.211] 1989.461646 1967.808440 -1.100372 1 (142.211, 156.885] NaN NaN NaN 0 (156.885, 171.558] NaN NaN NaN 0 (171.558, 186.232] 1960.918157 1937.426430 -1.212522 1 Mean diff_prcnt: 0.76367613389

test4b_n_mean__PMR_transplanted()[source]

Check driveability-only mean-rpm diff with Heinz stays within some percent for all PMRs.

### Comparison history ###

Force class3b, Phase-1b-beta(ver <= 0.0.8, Aug-2014) with Heinz maxt gear-time=2sec:

                    gened_mean_rpm  heinz_mean_rpm  diff_prcnt  count
pmr
(9.973, 24.823]        1557.225037     1568.360963    0.715113     32
(24.823, 39.496]       1686.859826     1696.482640    0.570457     34
(39.496, 54.17]        1771.670097     1789.409819    1.001299    120
(54.17, 68.843]        2133.400050     2165.214662    1.491263     94
(68.843, 83.517]       2020.903728     2043.741660    1.130085     59
(83.517, 98.191]       1886.836446     1890.040533    0.169813      4
(98.191, 112.864]      1788.434592     1792.693611    0.238142     31
(112.864, 127.538]     2580.884314     2568.011660   -0.501269      2
(127.538, 142.211]     1581.625191     1597.571904    1.008249      1
(142.211, 156.885]             NaN             NaN         NaN      0
(156.885, 171.558]             NaN             NaN         NaN      0
(171.558, 186.232]     1367.068837     1385.176569    1.324566      1

Separated test/unladen masses:

                     gened_mean_rpm  heinz_mean_rpm  diff_prcnt  count
pmr
(11.504, 26.225]        1572.733597     1585.721306    0.825805     28
(26.225, 40.771]        1690.081663     1700.689983    0.627681     41
(40.771, 55.317]        1821.319706     1841.779091    1.123327    119
(55.317, 69.863]        2060.507029     2085.262950    1.201448    122
(69.863, 84.409]        2142.964427     2171.952804    1.352723     29
(84.409, 98.955]        1783.214173     1787.378401    0.233524      4
(98.955, 113.501]       1713.473617     1718.516147    0.294287     31
(113.501, 128.0475]     1950.373771     1954.763742    0.225084      2
(128.0475, 142.594]     1543.937285     1553.383676    0.611838      1
(142.594, 157.14]               NaN             NaN         NaN      0
(157.14, 171.686]               NaN             NaN         NaN      0
(171.686, 186.232]      1367.068837     1385.176569    1.324566      1

Not forcing class3b, honoring declared v_max & unladen_mass:

                    gened_mean_rpm  heinz_mean_rpm  diff_prcnt  count
pmr
(9.973, 24.823]        1551.901645     1563.836656    0.769057     33
(24.823, 39.496]       1713.382835     1725.004638    0.678296     34
(39.496, 54.17]        1722.174466     1730.770088    0.499114    123
(54.17, 68.843]        1974.768859     1983.753219    0.454958     94
(68.843, 83.517]       2026.630271     2034.594136    0.392961     59
(83.517, 98.191]       1954.817179     1958.081066    0.166966      4
(98.191, 112.864]      1676.678357     1684.443875    0.463149     31
(112.864, 127.538]     2678.973439     2687.055802    0.301696      2
(127.538, 142.211]     1658.577318     1668.155469    0.577492      1
(142.211, 156.885]             NaN             NaN         NaN      0
(156.885, 171.558]             NaN             NaN         NaN      0
(171.558, 186.232]     1367.068837     1385.176569    1.324566      1
Mean diff_prcnt: 0.469021296461

pandas 0.15.1:

                    gened_mean_rpm  heinz_mean_rpm  diff_prcnt  count
pmr
(9.973, 24.823]        2021.882193     2038.842442    0.838835     33
(24.823, 39.496]       2204.136804     2229.999526    1.173372     34
(39.496, 54.17]        1880.733341     1885.792807    0.269016    123
(54.17, 68.843]        1710.819917     1717.808457    0.408491     94
(68.843, 83.517]       1677.846860     1683.916224    0.361735     59
(83.517, 98.191]       1541.587174     1551.609661    0.650141      4
(98.191, 112.864]      1579.049392     1589.997331    0.693325     31
(112.864, 127.538]     1411.921405     1425.965019    0.994646      2
(127.538, 142.211]     1976.193317     1967.808440   -0.426102      1
(142.211, 156.885]             NaN             NaN         NaN      0
(156.885, 171.558]             NaN             NaN         NaN      0
(171.558, 186.232]     1954.662077     1937.426430   -0.889616      1
Mean diff_prcnt: 0.558773102894
test5a_n_mean__gear()[source]

Check mean-rpm diff% with Heinz stays within some percent for all gears.

### Comparison history ###

Force class3b, Phase-1b-beta(ver <= 0.0.8, Aug-2014) with Heinz maxt gear-time=2sec:

n_mean      python        heinz      diff%
gear
0       732.358286   804.656085  -9.925769
1       870.080494  1177.547512 -44.450903
2      1789.787609  1650.383967   6.520319
3      1921.271483  1761.172027   7.804359
4      1990.286402  1886.563262   5.401895
5      2138.445024  2112.552162   1.892950
6      2030.970322  1987.865039   2.228276

Not forcing class3b, honoring declared v_max & unladen_mass:

gear
0        735.143823   808.795812 -10.052865
1        799.834530  1139.979330 -47.027383
2       1598.773915  1582.431975   1.119054
3       1793.617644  1691.589756   5.768020
4       1883.863510  1796.957457   5.024360
5       2095.211754  2052.059948   2.430360
6       2033.663975  1990.344346   2.238421
test5b_n_mean__gear_transplanted()[source]

Check mean-rpm diff% with Heinz stays within some percent for all gears.

### Comparison history ###

Force class3b, Phase-1b-beta(ver <= 0.0.8, Aug-2014) with Heinz maxt gear-time=2sec:

n_mean      python        heinz      diff%
gear
0       732.357001   804.656085  -9.926855
1       966.022039  1177.547512 -24.409425
2      1678.578373  1650.383967   1.616768
3      1791.644768  1761.172027   1.700642
4      1883.504933  1886.563262   0.119165
5      2099.218160  2112.552162  -0.320293
6      1985.732086  1987.865039  -0.096754

Not forcing class3b, honoring declared v_max & unladen_mass:

n_mean       python        heinz      diff%
gear
0        735.077116   808.795812 -10.065886
1        932.586982  1139.979330 -24.285307
2       1606.040896  1582.431975   1.379144
3       1721.141364  1691.589756   1.686708
4       1803.212699  1796.957457   0.370703
5       2053.822313  2052.059948   0.142138
6       1988.195381  1990.344346  -0.097482
tests.test_wltp_db._compare_exp_results(tabular, outfname, run_comparison)[source]
tests.test_wltp_db._file_pairs(fname_glob)[source]

Generates pairs of files to compare, skipping non-existent and those with mismatching #_of_rows.

Example:

for (veh_num, df_g, df_h) in _file_pairs(‘wltp_db_vehicles-00*.csv’):

pass

tests.test_wltp_db._init_logging(loglevel=10)[source]
tests.test_wltp_db._is_file_up_to_date(result_file, other_dependency_files=())[source]
tests.test_wltp_db._make_gened_fname(transplant_original_gears, veh_num)[source]
tests.test_wltp_db._make_heinz_fname(veh_num)[source]
tests.test_wltp_db._plotResults(veh_fname, df_g, df_h, res, ax, plot_diffs_gears_only=True, plot_original_gears=False)[source]
tests.test_wltp_db._read_gened_file(inpfname)[source]
tests.test_wltp_db._read_heinz_file(veh_num)[source]
tests.test_wltp_db._read_vehicles_inp()[source]
tests.test_wltp_db._read_vehicles_out()[source]
tests.test_wltp_db._read_wots()[source]
tests.test_wltp_db._run_the_experiments(transplant_original_gears=False, plot_results=False, compare_results=False, encoding='UTF-8')[source]
tests.test_wltp_db._select_wot(wots, isDiesel)[source]
tests.test_wltp_db._write_vehicle_data(df)[source]
tests.test_wltp_db.aggregate_single_columns_means(gened_column, heinz_column)[source]

Runs experiments and aggregates mean-values from one column of each (gened, heinz) file-sets.

tests.test_wltp_db.driver_weight = 70

For calculating unladen_mass.

tests.test_wltp_db.plot_diffs_with_heinz(diff_results, res, transplant_original_gears=False)[source]
tests.test_wltp_db.vehicles_applicator(fname_glob, pair_func)[source]

Applies the fun onto a pair of (generated, heinz) files for each tested-vehicle in the glob and appends results to list, preffixed by veh_num.

Parameters

pair_func – signature: func(veh_no, gened_df, heinz_df)–>sequence_of_numbers

Returns

a dataframe with the columns returned from the pair_func, row_indexed by veh_num