8. API reference¶
The core of the simulator is composed from the following modules:
data for all cycles and utilities to identify them |
|
Defines schema, defaults and validations for data consumed/produced by |
|
(TO BE DEFUNCT) The core that accepts a vehicle-model and wltc-classes, runs the simulation and updates the model with results. |
|
All pipeline definitions for running the WLTP gear-shifting algorithm |
|
code for generating the cycle |
|
formulae for engine power & revolutions and gear-box |
|
formulae for cycle/vehicle dynamics |
|
formulae estimating |
|
formulae downscaling cycles based on pmr/test_mass ratio |
|
Calculate/Validate n_min_drive parameters, defined mostly in Annex 2-2.k. |
|
definitions & idempotent formulae for physics/engineering |
|
Harvest functions & annotate their dependencies to build pipelines. |
|
utilities for starting-up, parsing, naming, indexing and spitting out data |
|
software utils unrelated to physics or engineering |
|
(OUTDATED) command-line entry-point for launching this wltp tool |
|
|
(OUTDATED) code for plotting diagrams related to wltp cycles & results |
(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
ofV
.- 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
The velocity samples are first round to
v_decimals
;the samples are then multiplied x10 to convert into integers (assuming
v_decimals
is 1);the integer velocity samples are then converted into int16 little-endian bytes (eg 0xC0FE –> (0xFE, 0xC0);
the int16 bytes are then concatanated together, and
fed into ZIP’s CRC32;
formated as 0-padded, 8-digit, HEXes;
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()
withedges=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 ofV
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
asVA1
phasing.- Parameters
class_phase_boundaries – a list of
[low, high]
boundary pairs (fromget_class_phase_boundaries()
)
Onbviously, it cannot produce overlapping split-times belonging to 2 phases.
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_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 propert
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
, wherelength
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 fromdatamodel['wltc_data']
,- Returns
a tree
- 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.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) []
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
- property model¶
- wltp.experiment.applyDriveabilityRules(V, A, GEARS, CLUTCH, driveability_issues)[source]¶
@note: Modifies GEARS & CLUTCH. @see: Annex 2-4, p 72
- 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.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.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.
8.4. Module: wltp.pipelines
¶
All pipeline definitions for running the WLTP gear-shifting algorithm
- wltp.pipelines.compensate_capped_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline [source]¶
Pipeline to provide
V_compensated
fromV_capped
trace (Annex 1, 9).
- wltp.pipelines.cycler_pipeline(aug: wltp.autograph.Autograph = None, domain=('cycle', None), **pipeline_kw) graphtik.pipeline.Pipeline [source]¶
Main pipeline to “run” the cycle.
- 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).
- 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).
- wltp.pipelines.n_max_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline [source]¶
Pipeline to provide
n_max
s (Annex 2, 2.g).
- 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).
- wltp.pipelines.scale_trace_pipeline(aug: wltp.autograph.Autograph = None, **pipeline_kw) graphtik.pipeline.Pipeline [source]¶
Main pipeline to scale the Velocity trace:
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
.
- 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).
- 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).
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
andA
respectively, and no other processing happens.
- A: pandas.core.series.Series[source]¶
A column derived from
V
, also withincycle
, populated on construction, and used in subsequent calculations.
- V: pandas.core.series.Series[source]¶
A column within
cycle
populated from the lastvelocity
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 thev_cap
column of thecycle
.- Parameters
gwots – a dataframe of wot columns indexed by a grid of rounded velocities, as generated by
interpolate_wot_on_v_grid()
, and augmented byattach_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]¶
- flat_cycle() pandas.core.frame.DataFrame [source]¶
return a copy of
cycle
passed throughflatten_columns()
- 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
cycle – assumes indexed by time
wltc_parts – must include edges (see
get_class_parts_limits()
)
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 byemerge_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. forphase_repeat_threshold=2
see the example in_identify_consecutive_truths()
. if 0,unspecified (might break)
- 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
cycle – must be indexed by time
class_phase_boundaries – a list of
[low, high]
boundary pairs (fromget_class_phase_boundaries()
)
- 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, withNANFLAG`(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 ingwot
.
- 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
andstop
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 thev_cap
column of thecycle
.- Parameters
gwots – a dataframe of wot columns indexed by a grid of rounded velocities, as generated by
interpolate_wot_on_v_grid()
, and augmented byattach_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
8.6. Module: wltp.engine
¶
formulae for engine power & revolutions and gear-box
- wltp.engine._make_v_grid(v_wot_min: float, v_wot_max: float) numpy.ndarray [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
andp_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 byinterpolate_wot_on_v_grid()
).
- 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 aroundn_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_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 fromv_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.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.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
, andn
,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()
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_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
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 foundn_vmax
: the engine speed producing v_max; np.NAN if not foundg_vmax
: the number of the gear producing v_maxis_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
- _field_defaults = {}¶
- _fields = ('v_max', 'n_vmax', 'g_vmax', 'is_n_lim', 'wot')¶
- _fields_defaults = {}¶
- 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”) crossesp_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, ifp_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
andp_avail_stable
columns for all gears, as generated byinterpolate_wot_on_v_grid()
, and augmented byattach_p_avail_in_gwots()
(in kW) andcalc_p_resist()
.- Returns
a
VMaxRec
namedtuple.
8.9. Module: wltp.downscale
¶
formulae downscaling cycles based on pmr/test_mass ratio
- 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 amplesV_capped – compensated with extra
v_cap
samples as defined bycompensate_phases_t_extra
.v_cap – needed just for verification,
- Returns
the compensated
V_capped
, same name & indexNote
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 equalizeV_capped
distance withV_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} \]
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.- _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 = {}¶
- 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._compose_mdl_2_n_min_drives(aug: wltp.autograph.Autograph = None, **pipeline_kw) Pipeline [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)
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_start_V1(n_min_drive_up_start_R: int, n_min_drive_set_R: int)[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]¶
- wltp.invariants.OR_columns_with_NANFLAGs(df: pandas.core.frame.DataFrame, nan_val: int = 0, NANFLAG=- 1) pandas.core.series.Series [source]¶
- 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 valuesop – one of
pd.Series.__or__()
,__and__
, etcnan_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.
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):dict from overrides keyed by
name
decorated with
autographed()
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 inrename_maps
.
- _collect_rest_op_args(decors: dict)[source]¶
Collect the rest operation arguments from
autographed
decoration.
- _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 decideprovides
by the the 1st one matching (unlessprovides
are specified in theoverrides
):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 ontoneeds
&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 givenfn-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
), thename-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
forautographed()
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 wasautographed()
).
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 ... ]
- harvest(*items: Any, base_modules=Ellipsis) List[Tuple[str, Callable]] [source]¶
Collect any callable
items
and children, respectingbase_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 fromitems
.- Returns
the
collected
- class wltp.autograph.Prefkey(sep=None)[source]¶
Bases:
object
Index into dicts with a key or a joined(prefix+key), where prefix: tuple
- _prefkey(d, key: Union[str, Pattern, Iterable[Union[str, Pattern]]], default: Optional[Union[Callable, Any]] = None)[source]¶
- sep = '.'¶
- 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 forAutograph
.- Parameters
name –
the name of the operation.
If the same
name
has already been defined for the samedomain
, it is overwritten; otherwise, a new decoration is appended, so thatAutograph.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 asfxed
out_sideffects – appended into
provides
; if a tuple, makes it asfxed
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'
- wltp.autograph.get_autograph_decors(fn, default=None, domain: Optional[Union[str, int, Collection]] = None) dict [source]¶
Get the 1st match in
domain
of thefn
autographed()
special attribute.- Parameters
default – return this if
fn
non-autographed, or domain don’t matchdomain – list-ified if a single str
- Returns
the decors that will override
Autograph
attributes, as found from the givenfn
, and for the 1st matching domain indomain
:<fn>(): _autograph (function-attribute) <domain> (dict) <name> (dict) <decors> (dict)
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-bracketgear
.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 fromg1
(e.g. when constructed withfrom_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']
- 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 fromg1
.
- 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', ...}
- property ng¶
The number of gears extracted from 2-level dataframe.
- property shape¶
- property size¶
- 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.flatten_columns(columns, sep='/')[source]¶
Use
inflate_columns()
to inverse it
- 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) ...
8.14. Module: wltp.utils
¶
software utils unrelated to physics or engineering
- 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. IfNone
, 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. IfNone
, wraps non-iterables in a single-item tuple, and no exception is ever raised.
- 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.pwd_changed(path: os.PathLike)[source]¶
Temporarily change working-dir to (and yield) given
path
.
8.15. Module: wltp.cli
¶
(OUTDATED) command-line entry-point for launching this wltp tool
See also
- 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)
- _field_defaults = {}¶
- _fields = ('io_method', 'fname', 'file', 'frmt', 'path', 'append', 'renames', 'kws')¶
- _fields_defaults = {}¶
- 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.
- 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)].
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
andV
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:
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.
Feed these “guessed” sets of gear-ratios into a robust (with median) kmeans clustering algorithm, and
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:
On each cycle-point select the Gear with smallest absolute-difference with the respective identified ratio;
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)
- _field_defaults = {}¶
- _fields = ('distort', 'guess', 'final', 'all_peaks_df', 'hist_X', 'hist_Y')¶
- _fields_defaults = {}¶
- 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
andV
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._norm1_1d_vq(obs, guess, is_robust=False)[source]¶
Simplified from scipy.cluster.vq.py_vq2()
- 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()
andplot_idgears_results()
separately.- Returns
a
ndarray
with the detected gear-ratios (for the STVs, inverse them)
- 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
andV
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.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
andV
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)
- _field_types = {'df': <class 'pandas.core.frame.DataFrame'>, 'items': <class 'list'>, 'props': <class 'pandas.core.series.Series'>}¶
- _fields = ('props', 'df', 'items')¶
- 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)
- _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 indatasets
,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 byself.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
- 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.accdb_renames()[source]¶
Renames to use accdb inputs (props, wots) into pyalgo to be used like:
props.unstack().rename(accdb_prop_renames())
- 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.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) containingvehicles/v001/{subgroups}
groupsvehicle_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.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.
8.18.1.1. (abandoned)¶
(DEPRECATED) Compares the results of synthetic vehicles from JRC against pre-phase-1b Heinz's tool. |
|
(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.
- 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._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.plot_diffs_with_heinz(heinz_dir, experiment_num=None, transplant_original_gears=False, force_rerun_experiments=False)[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.
- 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._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._plotResults(veh_fname, df_g, df_h, res, ax, plot_diffs_gears_only=True, plot_original_gears=False)[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.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