6. API reference

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

cycles data for all cycles and utilities to identify them
datamodel
experiment
cycler Cycler
engine
vehicle
vmax
downscale
invariants definitions & idenmpotent formulae for physics/engineering
io The io module provides the Python interfaces to stream handling.
utils software utils unrelated to physics or engineering
cli
plots
idgears (OUTDATED, irrelevant) Detects vehile’s gear-ratios from cycle-data and reconstructs the gears-profile by identifying the actual gears used.

6.1. Module: wltp.cycles

data for all cycles and utilities to identify them

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

Compute the CRC32(V * 10) of a 1Hz velocity trace.

Parameters:
  • V – velocity samples, to be rounded according to wltp.invariants.v_decimals
  • crc – initial CRC value (might be a hex-string)
  • full – print full 32bit number (x8 hex digits), or else, just the highest half (the 1st x4 hex digits)
Returns:

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

  1. The velocity samples are first round to v_decimals;
  2. the samples are then multiplied x10 to convert into integers (assuming v_decimals is 1);
  3. the integer velocity samples are then converted into int16 little-endian bytes (eg 0xC0FE –> (0xFE, 0xC0);
  4. the int16 bytes are then concatanated together, and
  5. fed into ZIP’s CRC32;
  6. the highest 2 bytes of the CRC32 are (usually) kept, formated in hex (x4 leftmost hex-digits).
wltp.cycles.cycle_checksums[source]

Return a big table with cummulative and simple SUM & CRC for all class phases.

Parameters:full – CRCs contain the full 32bit number (x8 hex digits)
wltp.cycles.cycle_phases[source]

Return a textual table with the boundaries of all phaes and cycle phasings

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

Finds which cycle/part/kind matches a CRC.

Parameters:V – Any cycle or parts of it (one of Low/Medium/High/Extra Kigh phases), or concatenated subset of the above phases, but in that order.
Returns:a 3 tuple (class, part, kind), like this:
  • (None,     None,   None): if no match
  • (<class>,  None,  <phasing>): if it matches a full-cycle
  • (<class>, <part>, <phasing>): if it matches a part
  • (<class>, <PART>, <phasing>): (CAPITAL part) if it matches a part cummulatively

where <phasing> is one of

  • V
  • A0 (offset: 0, length: -1)
  • A1 (offset: 1, length: -1)
wltp.cycles.identify_cycle_v_crc(crc: Union[int, str]) → Tuple[Optional[str], Optional[str], Optional[str]][source]

see identify_cycle_v()

6.2. Module: wltp.datamodel

6.3. Module: wltp.experiment

6.4. Module: wltp.cycler

6.5. Module: wltp.engine

6.6. Module: wltp.vehicle

6.7. Module: wltp.vmax

6.8. Module: wltp.downscale

6.9. Module: wltp.invariants

definitions & idenmpotent formulae for physics/engineering

wltp.invariants.nround1(n)

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

wltp.invariants.nround10(n)

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 achive 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.vround(n, *, decimals=1)

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

6.10. Module: wltp.io

6.11. Module: wltp.utils

software utils unrelated to physics or engineering

wltp.utils.memoize(f)[source]

Memoization decorator for functions taking one or more arguments.

wltp.utils.pairwise(t)[source]

From http://stackoverflow.com/questions/4628290/pairs-from-single-list

6.12. Module: wltp.cli

6.13. Module: wltp.plots

6.14. Module: wltp.idgears

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

Note

NOT RELLEVANT to generation of wltp cyles.

The following terms and arguments are used throughout this module:

gear-ratio(s):
the “NoverV”, which is the inverse of the “engine-speed-to-velocity” (“STV”). Conceptually it is the number of engine revolutions required, in RPM, in order for the the vehicle to travel with 1 km/h.
cycle-ratios:
The actual or detected NoverV-ratio on each cycle-point.
cycle-gears:
The actual or identified gear used on each cycle-point.
cycle-data
a pd.DataFrame containing (at the begining) N and V columns with [rpm] and [km/h] as units respectively.

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

  1. Produce a number of different approximate sets of gear-ratios (the “guesses”) by producing histograms of the ratios with different combinations of bins, and then taking the first #gears of peaks.
  2. Feed these “guessed” sets of gear-ratios into a robust (with median) kmeans clustering algorithm, and
  3. pick the gear-ratios with the minimum distortion.

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

  1. On each cycle-point select the Gear with smallest absolute-difference with the respective identified ratio;
  2. Reconstruct engine-speed by dividing velocity-profile with identified gear-ratio on each cycle-point.
class wltp.idgears.Detekt(distort, guess, final, all_peaks_df, hist_X, hist_Y)

Bases: tuple

_asdict()

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

classmethod _make(iterable)

Make a new Detekt object from a sequence or iterable

_replace(**kwds)

Return a new Detekt object replacing specified fields with new values

all_peaks_df

Alias for field number 3

distort

Alias for field number 0

final

Alias for field number 2

guess

Alias for field number 1

hist_X

Alias for field number 4

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._gather_final_Detekts(ngears, cycle_df, guessed_gears)[source]
Parameters:cycle_df (pd.DataFrame) – a dataframe with N and V columns with units [rpm] and [km/h] respectively (or inferred by comparing the means of these 2 columns).
wltp.idgears._gather_guessed_Detekts(ngears, cycle_df)[source]

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

wltp.idgears._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() and plot_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 and V columns (units: [rpm] and [km/h] respectively)
  • gear_ratios (ndarray) – the same as identify_gears_from_ratios()
Returns:

the same as identify_gears_from_ratios()

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

Return arrays will miss NaNs!

Parameters:
  • cycle_ratios (ndarray) – a single column array/list/ndarray of ratios (STVs or inverse).
  • gear_ratios (ndarray) – this list/ndarray of gear-ratios with len equal to the #gears
Returns:

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

wltp.idgears.moving_average(x, window)[source]
Parameters:window (int) – odd windows preserve phase

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

wltp.idgears.plot_idgears_results(cycle_df, detekt, fig=None, axes=None, original_points=None)[source]
Parameters:detekt – A Detekt-namedtuple with the data to plot
wltp.idgears.reconstruct_engine_speed(cycle_df, gear_ratios)[source]

Adds

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

TODO: Class-method

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

Invoke this one if you want to draw the results.

Parameters:cycle_df (pd.DataFrame) – it must contain (at least) N and V columns (units: [rpm] and [km/h] respectively)
Returns:a list of all Detekt tuples sorted with the most probable one at the the head, needed. Its 1st element is the solution

6.15. Validation tests & HDF5 DB

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

test_samples_db
test_wltp_db

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

  • devtools/printwltcclass.py
  • devtools/csvcolumns8to2.py

6.15.1. Module: tests.test_samples_db

(abandoned)

6.15.2. Module: tests.test_wltp_db

(abandoned)

7. Schema

The JSON-schema of the data for this project:

>>> from wltp import datamodel, utils
>>> schema = datamodel._get_model_schema()
>>> print(utils.yaml_dumps(schema))
$schema: http://json-schema.org/draft-07/schema#
$id: /data
title: Json-schema describing the input for a WLTC simulator.
type: object
additionalProperties: false
required:
- test_mass
- p_rated
- n_rated
- n_idle
- gear_ratios
- wot
- driver_mass
- v_stopped_threshold
- f_inertial
- f_safety_margin
- f_n_min
- f_n_min_gear2
- f_n_clutch_gear2
- wltc_data
description: The vehicle attributes required for generating the WLTC velocity-profile
  downscaling and gear-shifts.
properties:
  id:
    title: Any identifier for the object
    type:
    - integer
    - string
  unladen_mass:
    title: vehicle unladen mass
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
    description: The mass (kg) of the vehicle without the driver, used to decide its
      class, as defined in Annex-4
  test_mass:
    title: vehicle test mass
    $ref: '#/definitions/positiveNumber'
    description: The test mass of the vehicle used in all calculations (kg), as defined
      in Annex 4.2.1.3.1, pg 94.
  v_max:
    title: maximum vehicle velocity
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
    description: (OUT) The calculcated maximum velocity, as defined in Annex 2-2.i.
  n_vmax:
    title: engine speed for maximum vehicle velocity
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
    description: (OUT) The engine speed for `v_max`.
  g_vmax:
    title: gear for maximum vehicle velocity
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
    description: (OUT) The gear for achieving `v_max`.
  p_rated:
    title: maximum rated power
    $ref: '#/definitions/positiveNumber'
    description: The maximum rated engine power (kW) as declared by the manufacturer.
  n_rated:
    title: rated engine revolutions
    $ref: '#/definitions/positiveNumber'
    description: |
      The rated engine revolutions at which an engine develops its maximum power.
      If the maximum power is developed over an engine revolutions range,
      it is determined by the mean of this range.
  n_idle:
    title: idling revolutions
    $ref: '#/definitions/positiveNumber'
    description: The idling engine revolutions (Annex 1).
  n_min:
    title: minimum engine revolutions
    type:
    - array
    - number
    - 'null'
    description: |
      Either a number with the minimum engine revolutions for gears > 2 when the vehicle is in motion,
      or an array with the exact `n_min` for each gear (array must have length equal to gears).

      If unspecified, the minimum `n` for gears > 2 is determined by the following equation:

          n_min = n_idle + f_n_min(=0.125) * (n_rated - n_idle)

      Higher values may be used if requested by the manufacturer, by setting this one.
  gear_ratios:
    title: gear ratios
    $ref: '#/definitions/positiveNumbers'
    maxItems: 24
    minItems: 3
    description: An array with the gear-ratios obtained by dividing engine-revolutions
      (1/min) by vehicle-velocity (km/h).
  f0:
    title: driving resistance coefficient f0
    type:
    - number
    description: The driving resistance coefficient f0, in N (Annex 4).
  f1:
    title: driving resistance coefficient f1
    type:
    - number
    description: The driving resistance coefficient f1, in N/(km/h) (Annex 4).
  f2:
    title: driving resistance coefficient f2
    type:
    - number
    description: The driving resistance coefficient f2, in N/(km/h)² (Annex 4).
  n_min_drive1:
    description: see Annex 2-2.k
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
  n_min_drive2_up:
    description: see Annex 2-2.k
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
  n_min_drive2_stopdecel:
    description: see Annex 2-2.k
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
  n_min_drive2:
    description: see Annex 2-2.k
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
  n_min_drive_set:
    description: see Annex 2-2.k
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
  n_min_drive_up:
    description: see Annex 2-2.k
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
  n_min_drive_up_start:
    description: see Annex 2-2.k
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
  n_min_drive_down:
    description: see Annex 2-2.k
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
  n_min_drive_dn_start:
    description: see Annex 2-2.k
    type:
    - number
    - 'null'
    exclusiveMinimum: 0
  t_end_cold:
    description: see Annex 2-2.k about n_mins
    type:
    - number
    - 'null'
    minimum: 0
  wot:
    title: wide open throttle curves
    description: |
      An array/dict/dataframe holding the full load power curves for (at least) 2 columns ('n', 'p')
      or the normalized values ('n_norm', 'p_norm').

      Example:

          np.array([
              [ 600, 1000, ... 7000 ],
              [ 4, 10, ... 30 ]
          ]).T

      * The 1st column or `n` is the engine revolutions in min^-1:
      * The 2nd column or `p` is the full-power load in kW:

      Normalized N/P Example:

          np.array([
              [ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120 ],
              [ 6.11, 21.97, 37.43, 51.05, 62.61, 72.49, 81.13, 88.7, 94.92, 98.99, 100., 96.28, 87.66 ]
          ]).T

      * The 1st column or `n_norm` is the normalized engine revolutions, within [0.0, 1.20]:

                  n_norm = (n - n_idle) / (n_rated  - n_idle)

      * The 2nd column or `p_norm` is the normalised values of the full-power load against the p_rated,
        within [0, 1]:

                  p_norm = p / p_rated
    type:
    - object
    - array
  grid_wots:
    description: |
      A dataframe with 2-level columns (item, gear)
      - `p_avail_stable`: reduced by safety-margin, but not by ASM
      - `p_avail`: reduced by both SM & ASM
      - `p_resist`: road loads power
      - `p_req`: road loads & cycle power
  pmr:
    title: Power to Unladen-Mass
    description: Power/unladen-Mass ratio (W/kg).
    type: number
  wltc_class:
    description: The name of the WLTC-class (found within WLTC-data/classes) as selected
      by the experiment.
    type: string
    enum:
    - class1
    - class2
    - class3a
    - class3b
  resistance_coeffs_regression_curves:
    description: Regression curve factors for calculating vehicle's `resistance_coeffs`
      when missing.
    type: array
    minItems: 3
    maxItems: 3
    items:
      type: array
      minItems: 2
      maxItems: 2
      items:
        type: number
  f_downscale_threshold:
    title: Downscale-factor threshold
    description: The limit for the calculated `f_downscale` below which no downscaling
      happens.
    type:
    - number
    - 'null'
    default: 0.01
  f_downscale_decimals:
    title: Downscale-factor rounding decimals
    type:
    - number
    - 'null'
    default: 3
  driver_mass:
    title: Driver's mass (kg)
    description: |
      The mass (kg) of the vehicle's driver (Annex 1-3.2.6, p9), where:

          Unladen_mass = Test_mass - driver_mass
    type:
    - number
    - 'null'
    default: 75
  v_stopped_threshold:
    description: Velocity (km/h) under which (<=) to idle gear-shift (Annex 2-3.3,
      p71).
    type:
    - number
    - 'null'
    default: 1
  f_inertial:
    description: This is the `kr` inertial-factor used in the 2nd part of the formula
      for calculating required-power (Annex 2-3.1).
    type:
    - number
    - 'null'
    default: 1.03
  f_safety_margin:
    description: |
      Safety-margin(SM) factor for load-curve (Annex 2-3.4).
    type:
    - number
    - 'null'
    default: 0.1
  f_n_min:
    description: For each gear > 2, N :> n_min = n_idle + f_n_min * n_range (unless
      `n_min` overriden by manufacturer)
    type:
    - number
    - 'null'
    default: 0.125
  f_n_min_gear2:
    description: Gear-2 is invalid when N :< f_n_min_gear2 * n_idle.
    type:
    - number
    - 'null'
    default: 0.9
  f_n_clutch_gear2:
    description: |
      A 2-value number-array(f1, f2) controlling when to clutch gear-2:
          N < n_clutch_gear2 := max(f1 * n_idle, f2 * n_range + n_idle),
      unless "clutched"...
    type:
    - array
    - 'null'
    default:
    - 1.15
    - 0.03
  f_downscale:
    description: |
      The downscaling-factor as calculated by the experiment (Annex 1-8.3).

      Set it to 0 to disable downscaling, (or to any other value to force it).
    type: number
  wltc_data:
    $ref: /wltc
  cycle_run:
    description: |
      A dataframe matrix with 2-level columns(item, gear),
      and items, in addition to those of `grid_wots`:
      - `v_cycle`: reduced by safety-margin, but not by ASM
      - `v_dsc`: (optional)
      - `v_target`: road loads power
      - `(ok_..., gN)`: rflags denoting the validty of certainconditions for gear-N
      - `g_max0`: does not include corrections for the `g1-->g2 n_min` rule,
        nor points with insufficient power.
definitions:
  positiveInteger:
    type: integer
    exclusiveMinimum: 0
  positiveNumber:
    type: number
    exclusiveMinimum: 0
  positiveIntegers:
    type: array
    items:
      $ref: '#/definitions/positiveInteger'
  positiveNumbers:
    type: array
    items:
      $ref: '#/definitions/positiveNumber'