def wltp_cycle(): """ Defines the wltp cycle model. .. dispatcher:: d >>> d = wltp_cycle() :return: The wltp cycle model. :rtype: schedula.Dispatcher """ d = sh.Dispatcher( name='WLTP cycle model', description='Returns the theoretical times, velocities, and gears of ' 'WLTP.') from ..defaults import dfl d.add_data(data_id='initial_temperature', default_value=dfl.values.initial_temperature_WLTP, description='Initial temperature of the test cell [°C].') d.add_data(data_id='max_time', default_value=dfl.values.max_time_WLTP, description='Maximum time [s].', initial_dist=5) d.add_data(data_id='wltp_base_model', default_value=copy.deepcopy(dfl.values.wltp_base_model)) d.add_function(function=define_wltp_base_model, inputs=['wltp_base_model'], outputs=['base_model']) d.add_dispatcher( dsp=calculate_wltp_velocities(), inputs=('times', 'base_model', 'velocities', 'speed_velocity_ratios', 'inertial_factor', 'downscale_phases', 'climbing_force', 'downscale_factor', 'downscale_factor_threshold', 'vehicle_mass', 'unladen_mass', 'road_loads', 'engine_max_power', 'engine_speed_at_max_power', 'max_velocity', 'wltp_class', 'max_speed_velocity_ratio'), outputs=('velocities', )) d.add_function(function=sh.add_args(wltp_gears), inputs=[ 'gear_box_type', 'full_load_curve', 'velocities', 'accelerations', 'motive_powers', 'speed_velocity_ratios', 'idle_engine_speed', 'engine_speed_at_max_power', 'engine_max_power', 'engine_max_speed', 'base_model' ], outputs=['gears'], input_domain=lambda *args: args[0] == 'manual', weight=10) return d
def test_add_args_parent_func(self): class original_func: __name__ = 'original_func' def __call__(self, a, b, *c, d=0, e=0): """Doc""" return list((a, b) + c) fo = original_func() func = sh.add_args(sh.partial(fo, 1, 2), 2) self.assertEqual(func.__name__, 'original_func') self.assertEqual(func.__doc__, None) self.assertEqual(func((1, 2, 3), 2, 4), [1, 2, 4]) func = sh.add_args(sh.partial(sh.partial(func, 1), 1, 2), 2, callback=lambda res, *args, **kwargs: res.pop()) self.assertEqual(func.__name__, 'original_func') self.assertEqual(func.__doc__, None) self.assertEqual(func((1, 2, 3), 6, 5, 7), [1, 2, 2, 5]) func = sh.parent_func(func) self.assertEqual(func, fo)
def test_add_args_parent_func(self): class original_func: __name__ = 'original_func' def __call__(self, a, b, *c, d=0, e=0): """Doc""" return list((a, b) + c) fo = original_func() func = sh.add_args(functools.partial(fo, 1, 2), 2) self.assertEqual(func.__name__, 'original_func') self.assertEqual(func.__doc__, None) self.assertEqual(func((1, 2, 3), 2, 4), [1, 2, 4]) func = sh.add_args( functools.partial(functools.partial(func, 1), 1, 2), 2, callback=lambda res, *args, **kwargs: res.pop() ) self.assertEqual(func.__name__, 'original_func') self.assertEqual(func.__doc__, None) self.assertEqual(func((1, 2, 3), 6, 5, 7), [1, 2, 2, 5]) func = sh.parent_func(func) self.assertEqual(func, fo)
def setUp(self): import functools ss_dsp = sh.Dispatcher() def fun(a, c): """ :param a: Nice a. :type a: float :param c: Nice c. :type c: float :return: Something. :rtype: tuple """ return a + 1, c, a - 1 ss_dsp.add_function('fun', fun, ['a', 'e'], ['b', 'c', 'd']) ss_dsp_func = sh.DispatchPipe(ss_dsp, 'func', ['e', 'a'], ['c', 'd', 'b']) sub_disfun = sh.add_args(functools.partial(ss_dsp_func, 5)) s_dsp = sh.Dispatcher() s_dsp.add_data('a', 1) s_dsp.add_data('d', 4) s_dsp.add_function('sub_dispatch', sub_disfun, ['d', 'a'], ['b', 'c', sh.SINK]) dispatch = sh.SubDispatch(s_dsp, ['b', 'c', 'a'], output_type='list') self.dsp = dsp = sh.Dispatcher() dsp.add_data('input', default_value={'a': 3}) dsp.add_function('dispatch', dispatch, ['input'], [sh.SINK, 'h', 'i'], inp_weight={'input': 4}, out_weight={ 'h': 3, 'i': 6 }) dsp.add_function('fun', lambda: None, None, ['j']) dsp.add_dispatcher(s_dsp, inputs=('a', ), outputs=('b', 'c'), include_defaults=True)
def run_plan(): """ Defines the plan model. .. dispatcher:: d >>> d = run_plan() :return: The plan model. :rtype: Dispatcher """ d = sh.Dispatcher(name='run_plan', description='Processes a vehicle plan.') d.add_data(data_id='engineering_mode', default_value=False) d.add_data(data_id='use_selector', default_value=False) d.add_data(data_id='soft_validation', default_value=False) d.add_function(function=sh.add_args(schema.validate_plan), inputs=[ 'run_plan', 'data', 'engineering_mode', 'soft_validation', 'use_selector' ], outputs=['validated_plan'], input_domain=check_first_arg) d.add_function(function=default_start_time, outputs=['start_time']) d.add_function(function=default_timestamp, inputs=['start_time'], outputs=['timestamp']) from .plan import make_simulation_plan d.add_function(function=make_simulation_plan, inputs=['validated_plan', 'timestamp', 'variation', 'flag'], outputs=['summary']) return sh.SubDispatch(d)
def final_drive(): """ Defines the final drive model. .. dispatcher:: d >>> d = final_drive() :return: The final drive model. :rtype: schedula.Dispatcher """ d = sh.Dispatcher(name='Final drive', description='Models the final drive.') from .defaults import dfl d.add_data(data_id='final_drive_ratio', default_value=dfl.values.final_drive_ratio) d.add_function(function=calculate_final_drive_ratios, inputs=['final_drive_ratio', 'n_gears'], outputs=['final_drive_ratios']) d.add_function(function=sh.add_args(calculate_final_drive_ratios), inputs=['gear_box_type', 'final_drive_ratio'], outputs=['final_drive_ratios'], input_domain=is_cvt) d.add_function(function=calculate_final_drive_ratio_vector, inputs=['final_drive_ratios', 'gears'], outputs=['final_drive_ratio_vector']) d.add_function( function=calculate_final_drive_speeds_in, inputs=['final_drive_speeds_out', 'final_drive_ratio_vector'], outputs=['final_drive_speeds_in']) d.add_data(data_id='final_drive_efficiency', default_value=dfl.values.final_drive_efficiency) d.add_data(data_id='n_wheel_drive', default_value=dfl.values.n_wheel_drive) d.add_data(data_id='final_drive_torque_loss', default_value=sh.EMPTY) d.add_function( function=calculate_final_drive_torque_losses, inputs=['final_drive_torques_out', 'final_drive_torque_loss'], outputs=['final_drive_torque_losses'], input_domain=lambda *args: args[1] is not sh.EMPTY) d.add_function( function=sh.add_args(calculate_final_drive_torque_losses_v1), inputs=[ 'n_dyno_axes', 'n_wheel_drive', 'final_drive_torques_out', 'final_drive_ratio_vector', 'final_drive_efficiency' ], outputs=['final_drive_torque_losses'], weight=5, input_domain=domain_final_drive_torque_losses_v1) d.add_function(function=calculate_final_drive_torques_in, inputs=[ 'final_drive_torques_out', 'final_drive_ratio_vector', 'final_drive_torque_losses' ], outputs=['final_drive_torques_in']) d.add_function(function=calculate_final_drive_efficiencies, inputs=[ 'final_drive_torques_out', 'final_drive_ratio_vector', 'final_drive_torques_in' ], outputs=['final_drive_efficiencies']) d.add_function( function=calculate_final_drive_powers_in, inputs=['final_drive_powers_out', 'final_drive_efficiencies'], outputs=['final_drive_powers_in']) d.add_function(function=define_fake_final_drive_prediction_model, inputs=[ 'final_drive_ratio_vector', 'final_drive_speeds_in', 'final_drive_torque_losses', 'final_drive_torques_in', 'final_drive_efficiencies', 'final_drive_powers_in' ], outputs=['final_drive_prediction_model']) d.add_function(function=define_final_drive_prediction_model, inputs=[ 'final_drive_ratios', 'final_drive_torque_loss', 'n_wheel_drive', 'final_drive_efficiency' ], outputs=['final_drive_prediction_model'], weight=4000) return d
""" Load inputs from .dill file. :param input_file: Input file. :type input_file: io.BytesIO :return: Raw input data. :rtype: dict """ import dill return dill.load(input_file) dsp.add_function(function=sh.add_args(load_from_dill), inputs=['input_file_name', 'input_file'], outputs=['raw_data'], input_domain=functools.partial(check_file_format, ext=('.dill', ))) dsp.add_function(function=parse_excel_file, inputs=['input_file_name', 'input_file'], outputs=['raw_data'], input_domain=check_file_format) if _dice is not None: _out, _inp = ['base', 'meta', 'dice'], [ 'input_file_name', 'input_file', 'encryption_keys', 'encryption_keys_passwords' ]
mvl = _upgrade_gsm(mvl, velocity_speed_ratios, cycle_type) mvl.plateau_acceleration = plateau_acceleration correct_gear = CorrectGear(velocity_speed_ratios, idle_engine_speed) correct_gear.fit_correct_gear_mvl(mvl) correct_gear.fit_correct_gear_full_load(full_load_curve, max_velocity_full_load_correction) correct_gear.fit_basic_correct_gear() return correct_gear dsp.add_data(data_id='max_velocity_full_load_correction', default_value=dfl.values.max_velocity_full_load_correction) dsp.add_function(function=sh.add_args(correct_gear_v0), inputs=[ 'fuel_saving_at_strategy', 'cycle_type', 'velocity_speed_ratios', 'MVL', 'idle_engine_speed', 'full_load_curve', 'max_velocity_full_load_correction', 'plateau_acceleration' ], outputs=['correct_gear'], input_domain=co2_utl.check_first_arg) def correct_gear_v1(cycle_type, velocity_speed_ratios, mvl, idle_engine_speed, plateau_acceleration=float('inf')):
def run_base(): """ Defines the vehicle-processing model. .. dispatcher:: d >>> d = run_base() :return: The vehicle-processing model. :rtype: Dispatcher """ d = sh.Dispatcher( name='run_base', description='Processes a vehicle from the file path to the write of its' ' outputs.') d.add_data(data_id='engineering_mode', default_value=False) d.add_data(data_id='output_folder', default_value='.') d.add_data(data_id='use_selector', default_value=False) d.add_data(data_id='soft_validation', default_value=False) d.add_function(function=schema.validate_meta, inputs=['meta', 'soft_validation'], outputs=['validated_meta']) d.add_function(function=sh.add_args(schema.validate_base), inputs=[ 'run_base', 'data', 'engineering_mode', 'soft_validation', 'use_selector' ], outputs=['validated_base'], input_domain=check_first_arg, weight=10) d.add_data(data_id='only_summary', default_value=False) d.add_function(function=default_vehicle_name, inputs=['input_file_name'], outputs=['vehicle_name']) d.add_function(function=default_start_time, outputs=['start_time']) d.add_function(function=default_timestamp, inputs=['start_time'], outputs=['timestamp']) d.add_function(function=default_output_file_name, inputs=['output_folder', 'vehicle_name', 'timestamp'], outputs=['output_file_name']) from .model import model d.add_function(function=sh.add_args(sh.SubDispatch(model())), inputs=['validated_meta', 'validated_base'], outputs=['dsp_solution']) d.add_function(function=parse_dsp_solution, inputs=['dsp_solution'], outputs=['output_data']) from .report import report d.add_function( function=report(), inputs=['output_data', 'vehicle_name'], outputs=['report', 'summary'], ) from .io.ta import write_ta_output from .conf import defaults dfl = defaults.io_constants_dfl d.add_data('encrypt_inputs', dfl.ENCRYPT_INPUTS) d.add_data('encryption_keys', dfl.ENCRYPTION_KEYS_PATH) d.add_function(function=sh.add_args(write_ta_output()), inputs=[ 'type_approval_mode', 'encrypt_inputs', 'encryption_keys', 'vehicle_family_id', 'start_time', 'timestamp', 'data', 'meta', 'report', 'output_folder' ], outputs=['output_ta_file'], input_domain=check_first_arg) d.add_function(function=get_template_file_name, inputs=['output_template', 'input_file_name'], outputs=['template_file_name']) d.add_data(data_id='output_template', default_value=_get_co2mpas_output_template_fpath(), initial_dist=10) from .io import write_outputs d.add_function(function=sh.add_args(write_outputs()), inputs=[ 'only_summary', 'output_file_name', 'template_file_name', 'report', 'start_time', 'flag' ], outputs=[sh.SINK], input_domain=lambda *args: not args[0]) d.add_function( function=sh.add_args(plot_model_workflow), inputs=['plot_workflow', 'output_file_name', 'vehicle_name'], outputs=[sh.PLOT], weight=30, input_domain=check_first_arg) return sh.SubDispatch(d)
if initial_gears: gears = initial_gears.copy() else: # noinspection PyUnresolvedReferences gears = res[0] # Apply Driveability-rules. # noinspection PyUnresolvedReferences wltp_exp.applyDriveabilityRules(v, accelerations, gears, res[1], res[-1]) gears[gears < 0] = 0 log.warning( 'The WLTP gear-shift profile generation is for engineering ' 'purposes and the results are by no means valid according to ' 'the legislation.\nActually they are calculated based on a pre ' 'phase-1a version of the GTR spec.\n ' 'Please provide the gear-shifting profile ' 'within `prediction.WLTP` sheet.') return gears dsp.add_function(function=sh.add_args(wltp_gears), inputs=('gear_box_type', 'full_load_curve', 'velocities', 'accelerations', 'motive_powers', 'speed_velocity_ratios', 'idle_engine_speed', 'engine_speed_at_max_power', 'engine_max_power', 'engine_max_speed', 'base_model'), outputs=['gears'], input_domain=is_manual, weight=sh.inf(2, 10))
:param atct_family_correction_factor: Family correction factor for representative regional temperatures [-]. :type atct_family_correction_factor: float :return: Corrected CO2 emission value of the cycle [CO2g/km]. :rtype: float """ v = rcb_corrected_co2_emission_value * ki_multiplicative + ki_additive return v * atct_family_correction_factor dsp.add_data('is_plugin', dfl.values.is_plugin) dsp.add_function( function=sh.add_args(calculate_corrected_co2_emission), inputs=[ 'is_plugin', 'rcb_corrected_co2_emission_value', 'ki_multiplicative', 'ki_additive', 'atct_family_correction_factor' ], outputs=['corrected_co2_emission_value'], input_domain=co2_utl.check_first_arg_false ) dsp.add_function( function=sh.add_args(calculate_corrected_co2_emission), inputs=[ 'is_plugin', 'rcb_corrected_co2_emission_value', 'ki_multiplicative', 'ki_additive', 'atct_family_correction_factor' ], outputs=['corrected_sustaining_co2_emission_value'], input_domain=co2_utl.check_first_arg
(380, k5), (380, 0), (400, 0)) tg = _repeat_parts(times, parts).T s = interp1d(*tg, kind='nearest', assume_sorted=True)(times) s[s > max_gear] = max_gear return s # noinspection PyUnusedLocal, PyMissingOrEmptyDocstring def is_manual(gear_box_type, *args): return gear_box_type == 'manual' dsp.add_function( function_id='nedc_gears', function=sh.add_args(nedc_gears), inputs=['gear_box_type', 'times', 'max_gear', 'k1', 'k2', 'k5'], outputs=['gears'], input_domain=is_manual) def _repeat_parts(times, parts): import numpy as np from functools import reduce it = [v[1] for v in sorted(parts.items())] def _func(x, y): y = np.array(y) y[:, 0] += x[-1][-1][0] return x + (y, )
def setUp(self): ss_dsp = sh.Dispatcher(name='Ciao.') def fun(b, c, d=0): """ Fun description. :param b: Second param. :param int c: Third param. :return: Out param. :rtype: float """ return b + c + d def dom(a, *args): """ :param a: First param. """ return a ss_dsp.add_function( function=sh.add_args(fun), inputs=['a', 'b', 'c', 'd'], outputs=['e'], input_domain=dom ) ss_dsp.add_function( function=sh.bypass, inputs=['e'], outputs=['f'] ) ss_dsp.add_function( function=sh.replicate_value, inputs=['f'], outputs=['g', 'h'] ) sdspfunc = sh.SubDispatchFunction( ss_dsp, 'SubDispatchFunction', ['a', 'b', 'c', 'd'], ['g', 'h'] ) sdsp = sh.SubDispatch(ss_dsp, ['e', 'f'], output_type='list') def fun1(): """""" return sdspfunci = sh.SubDispatchFunction( ss_dsp, 'SubDispatchFunction', ['a', 'b', 'c', 'd'] ) s_dsp = sh.Dispatcher(name='Sub-Dispatcher') s_dsp.add_function('3', sdspfunc, ['a', 'b', 'c', 'd'], ['g', 'h']) s_dsp.add_function('8', sdspfunci, ['a', 'b', 'c', 'd'], ['o']) s_dsp.add_function('2', sdsp, ['I'], ['e', 'f']) s_dsp.add_function('4', max, ['e', 'f', 'l'], ['i']) s_dsp.add_function('5', inputs=['i'], outputs=['n']) s_dsp.add_function('6', fun1) s_dsp.add_function('7', sh.bypass, inputs=['p'], input_domain=sh.add_args(lambda p: None)) s_dsp.add_data('i', description='max.') self.dsp = dsp = sh.Dispatcher() dsp.add_dispatcher( dsp_id='1', dsp=s_dsp, inputs=('n', 'd', 'I', 'l', {'m': ('b', 'c'), ('a', 'a1'): 'a'}), outputs=['g', 'i', {'f': ('h', 'f')}, {('e', 'h'): ('e', 'e1')}] )
@sh.add_function(dsp, outputs=['output_template'], weight=sh.inf(1, 0)) def default_output_template(): """ Returns the default template output. :return: Template output. :rtype: str """ from pkg_resources import resource_filename return resource_filename('co2mpas', 'templates/output_template.xlsx') dsp.add_func(write_to_excel, outputs=['excel_output']) dsp.add_function(function=sh.add_args(sh.bypass), inputs=['type_approval_mode', 'excel_output'], outputs=['output_file'], input_domain=check_first_arg_false) dsp.add_func(default_timestamp, outputs=['timestamp']) def default_output_file_name(output_folder, vehicle_name, timestamp, ext='xlsx'): """ Returns the output file name. :param output_folder:
def setUp(self): ss_dsp = sh.Dispatcher(name='Ciao.') def fun(b, c, d=0): """ Fun description. :param b: Second param. :param int c: Third param. :return: Out param. :rtype: float """ return b + c + d def dom(a, *args): """ :param a: First param. """ return a ss_dsp.add_function(function=sh.add_args(fun), inputs=['a', 'b', 'c', 'd'], outputs=['e'], input_domain=dom) ss_dsp.add_function(function=sh.bypass, inputs=['e'], outputs=['f']) ss_dsp.add_function(function=sh.replicate_value, inputs=['f'], outputs=['g', 'h']) sdspfunc = sh.SubDispatchFunction(ss_dsp, 'SubDispatchFunction', ['a', 'b', 'c', 'd'], ['g', 'h']) sdsp = sh.SubDispatch(ss_dsp, ['e', 'f'], output_type='list') def fun1(): """""" return sdspfunci = sh.SubDispatchFunction(ss_dsp, 'SubDispatchFunction', ['a', 'b', 'c', 'd']) s_dsp = sh.Dispatcher(name='Sub-Dispatcher') s_dsp.add_function('3', sdspfunc, ['a', 'b', 'c', 'd'], ['g', 'h']) s_dsp.add_function('8', sdspfunci, ['a', 'b', 'c', 'd'], ['o']) s_dsp.add_function('2', sdsp, ['I'], ['e', 'f']) s_dsp.add_function('4', max, ['e', 'f', 'l'], ['i']) s_dsp.add_function('5', inputs=['i'], outputs=['n']) s_dsp.add_function('6', fun1) s_dsp.add_function('7', sh.bypass, inputs=['p'], input_domain=sh.add_args(lambda p: None)) s_dsp.add_data('i', description='max.') self.dsp = dsp = sh.Dispatcher() dsp.add_dispatcher( dsp_id='1', dsp=s_dsp, inputs=('n', 'd', 'I', 'l', { 'm': ('b', 'c'), ('a', 'a1'): 'a' }), outputs=['g', 'i', { 'f': ('h', 'f') }, { ('e', 'h'): ('e', 'e1') }])
def load_inputs(): """ Defines a module to load the input file of the CO2MPAS model. .. dispatcher:: d >>> d = load_inputs() :return: The load input module. :rtype: SubDispatchFunction """ d = sh.Dispatcher( name='load_inputs', description='Loads from files the inputs for the CO2MPAS model.' ) d.add_function( function=get_cache_fpath, inputs=['input_file_name'], outputs=['cache_file_name'] ) d.add_data( data_id='overwrite_cache', default_value=False ) d.add_function( function_id='load_data_from_cache', function=sh.add_args(dill.load_from_dill, n=2), inputs=['overwrite_cache', 'input_file_name', 'cache_file_name'], outputs=['raw_data'], input_domain=check_cache_fpath_exists ) d.add_function( function=excel.parse_excel_file, inputs=['input_file_name'], outputs=['raw_data'], input_domain=functools.partial(check_file_format, extensions=('.xlsx', '.xls')), weight=5 ) d.add_function( function=dill.load_from_dill, inputs=['input_file_name'], outputs=['raw_data'], input_domain=functools.partial(check_file_format, extensions=('.dill',)), weight=5 ) import pandalone.xleash as xleash d.add_function( function_id='load_from_xlasso', function=xleash.lasso, inputs=['input_file_name'], outputs=['raw_data'], input_domain=check_xlasso, weight=5 ) d.add_function( function_id='cache_parsed_data', function=dill.save_dill, inputs=['raw_data', 'cache_file_name'] ) return d
:return: Final drive ratios [-]. :rtype: dict """ d = collections.defaultdict(lambda: final_drive_ratio) d.update(dict.fromkeys(range(0, int(n_gears + 1)), final_drive_ratio)) return d # noinspection PyUnusedLocal,PyMissingOrEmptyDocstring def is_not_manual_or_automatic(gear_box_type, *args): return gear_box_type not in ('manual', 'automatic') dsp.add_function(function=sh.add_args(calculate_final_drive_ratios), inputs=['gear_box_type', 'final_drive_ratio'], outputs=['final_drive_ratios'], input_domain=is_not_manual_or_automatic) @sh.add_function(dsp, outputs=['final_drive_ratio_vector']) def calculate_final_drive_ratio_vector(final_drive_ratios, gears): """ Calculates the final drive ratio vector [-]. :param final_drive_ratios: Final drive ratios [-]. :type final_drive_ratios: dict[int, float | int] :param gears:
def nedc_cycle(): """ Defines the wltp cycle model. .. dispatcher:: d >>> d = nedc_cycle() :return: The wltp cycle model. :rtype: schedula.Dispatcher """ d = sh.Dispatcher( name='NEDC cycle model', description='Returns the theoretical times, velocities, and gears of ' 'NEDC.' ) from ..defaults import dfl d.add_data( data_id='initial_temperature', default_value=dfl.values.initial_temperature_NEDC, description='Initial temperature of the test cell [°C].' ) d.add_data( data_id='max_time', default_value=dfl.values.max_time_NEDC, description='Maximum time [s].', initial_dist=5 ) d.add_data( data_id='k1', default_value=dfl.values.k1 ) d.add_data( data_id='k2', default_value=dfl.values.k2 ) d.add_function( function_id='set_max_gear_as_default_k5', function=sh.bypass, inputs=['max_gear'], outputs=['k5'] ) d.add_data( data_id='k5', default_value=dfl.values.k5, initial_dist=10 ) d.add_function( function_id='nedc_gears', function=sh.add_args(nedc_gears), inputs=['gear_box_type', 'times', 'max_gear', 'k1', 'k2', 'k5'], outputs=['gears'], input_domain=lambda *args: args[0] == 'manual' ) d.add_function( function=nedc_velocities, inputs=['times', 'gear_box_type'], outputs=['velocities'] ) return d