def solve_circular(self): from .cycle import simple_cycles from collections import Counter mod, dsp = {}, self.dsp f_nodes, d_nodes, dmap = dsp.function_nodes, dsp.data_nodes, dsp.dmap cycles = list(simple_cycles(dmap.succ)) cycles_nodes = Counter(sum(cycles, [])) for cycle in sorted(map(set, cycles)): cycles_nodes.subtract(cycle) active_nodes = {k for k, v in cycles_nodes.items() if v} for k in sorted(cycle.intersection(f_nodes)): if _check_cycles(dmap, k, f_nodes, cycle, active_nodes, mod): break else: cycles_nodes.update(cycle) dist = sh.inf(len(cycle) + 1, 0) for k in sorted(cycle.intersection(d_nodes)): dsp.set_default_value(k, ERR_CIRCULAR, dist) if mod: # Update dsp. dsp.add_data(CIRCULAR, ERR_CIRCULAR) for k, v in mod.items(): d = f_nodes[k] d['inputs'] = [CIRCULAR if i in v else i for i in d['inputs']] dmap.remove_edges_from(((i, k) for i in v)) dmap.add_edge(CIRCULAR, k) return self
def solve_circular(self): import networkx as nx mod, dsp = {}, self.dsp f_nodes, d_nodes, dmap = dsp.function_nodes, dsp.data_nodes, dsp.dmap for cycle in sorted(map(set, nx.simple_cycles(dmap))): for k in sorted(cycle.intersection(f_nodes)): if _check_cycles(dmap, k, f_nodes, cycle, mod): break else: dist = sh.inf(len(cycle) + 1, 0) for k in sorted(cycle.intersection(d_nodes)): dsp.set_default_value(k, ERR_CIRCULAR, dist) if mod: # Update dsp. dsp.add_data(CIRCULAR, ERR_CIRCULAR) for k, v in mod.items(): d = f_nodes[k] d['inputs'] = [CIRCULAR if i in v else i for i in d['inputs']] dmap.remove_edges_from(((i, k) for i in v)) dmap.add_edge(CIRCULAR, k) return self
Gear box speed vector [RPM]. :type gear_box_speeds_in: numpy.array | float :param motor_p2_speeds: Rotating speed of motor P2 [RPM]. :type motor_p2_speeds: numpy.array | float :return: Motor P2 speed ratio [-]. :rtype: float """ from .p4 import identify_motor_p4_speed_ratio as func return func(gear_box_speeds_in, motor_p2_speeds) dsp.add_data('motor_p2_speed_ratio', 1, sh.inf(10, 1)) @sh.add_function(dsp, outputs=['motor_p2_speeds']) def calculate_motor_p2_speeds(gear_box_speeds_in, motor_p2_speed_ratio): """ Calculates rotating speed of motor P2 [RPM]. :param gear_box_speeds_in: Gear box speed vector [RPM]. :type gear_box_speeds_in: numpy.array | float :param motor_p2_speed_ratio: Ratio between motor P2 speed and gear box speed [-]. :type motor_p2_speed_ratio: float
def test_inf(self): self.assertTrue(sh.inf(1, 2.1) > 3) self.assertTrue(sh.inf(1, 2.1) >= 3) self.assertTrue(sh.inf(2, 2.1) >= sh.inf(1, 2)) self.assertTrue(sh.inf(0, 2.1) <= 2.1) self.assertTrue(sh.inf(0, 2.1) < 3.1) self.assertTrue(sh.inf(0, 2.1) <= sh.inf(0, 3)) self.assertTrue(sh.inf(1, 2.1) != 2.1) self.assertTrue(sh.inf(1, 2.1) != sh.inf(3, 2)) self.assertTrue(sh.inf(0, 2.1) == 2.1) self.assertTrue(sh.inf(1.1, 2.1) == sh.inf(1.1, 2.1)) self.assertTrue(sh.inf(0, 2.1) != (0, 2.1)) self.assertTrue(3 <= sh.inf(1, 2)) self.assertTrue(3 >= sh.inf(0, 2)) self.assertTrue(3 != sh.inf(1, 2)) self.assertTrue(2 == sh.inf(0, 2)) self.assertTrue((0, 2) != sh.inf(0, 2)) self.assertEqual(sh.inf(1.1, 2.1) + 1, sh.inf(1.1, 3.1)) self.assertEqual(1 + sh.inf(1.1, 2.1), sh.inf(1.1, 3.1)) self.assertEqual(sh.inf(1, 2) + sh.inf(1, 0), sh.inf(2, 2)) self.assertEqual(1 - sh.inf(1, 2), sh.inf(-1, -1)) self.assertEqual(sh.inf(1, 2) - 1, sh.inf(1, 1)) self.assertEqual(sh.inf(1, 2) - sh.inf(1, 0), sh.inf(0, 2)) self.assertEqual(sh.inf(2, 2) * 4, sh.inf(8, 8)) self.assertEqual(4 * sh.inf(2, 2), sh.inf(8, 8)) self.assertEqual(sh.inf(2, 2) * sh.inf(2, 0), sh.inf(4, 0)) self.assertEqual(sh.inf(2, 3) ** 2, sh.inf(4, 9)) self.assertEqual(2 ** sh.inf(2, 3), sh.inf(4, 8)) self.assertEqual(sh.inf(3, 2) ** sh.inf(2, 0), sh.inf(9, 1)) self.assertEqual(sh.inf(2, 2) / 2, sh.inf(1, 1)) self.assertEqual(2 / sh.inf(2, 2), sh.inf(1, 1)) self.assertEqual(sh.inf(2, 2) / sh.inf(2, 1), sh.inf(1, 2)) self.assertEqual(3 // sh.inf(2.1, 4.1), sh.inf(1, 0)) self.assertEqual(sh.inf(2.1, 4.1) // 3, sh.inf(0, 1)) self.assertEqual(sh.inf(2, 5.1) // sh.inf(4, 1), sh.inf(0, 5)) self.assertEqual(3 % sh.inf(2, 4.1), sh.inf(1, 3)) self.assertEqual(sh.inf(2, 4) % 3, sh.inf(2, 1)) self.assertEqual(sh.inf(2, 5) % sh.inf(4, 1), sh.inf(2, 0)) self.assertEqual(-sh.inf(1, 2), sh.inf(-1, -2)) self.assertEqual(+sh.inf(-1, 2), sh.inf(-1, 2)) self.assertEqual(abs(sh.inf(-1, 2)), sh.inf(1, 2)) self.assertEqual(round(sh.inf(1.22, 2.62)), sh.inf(1, 3)) self.assertEqual(round(sh.inf(1.22, 2.67), 1), sh.inf(1.2, 2.7)) self.assertEqual(math.trunc(sh.inf(1.2, 2.6)), sh.inf(1, 2)) self.assertEqual(math.ceil(sh.inf(1.2, 2.6)), sh.inf(2, 3)) self.assertEqual(math.floor(sh.inf(1.2, 2.6)), sh.inf(1, 2))
def test_inf(self): self.assertTrue(sh.inf(1, 2.1) > 3) self.assertTrue(sh.inf(1, 2.1) >= 3) self.assertTrue(sh.inf(2, 2.1) >= sh.inf(1, 2)) self.assertTrue(sh.inf(0, 2.1) <= 2.1) self.assertTrue(sh.inf(0, 2.1) < 3.1) self.assertTrue(sh.inf(0, 2.1) <= sh.inf(0, 3)) self.assertTrue(sh.inf(1, 2.1) != 2.1) self.assertTrue(sh.inf(1, 2.1) != sh.inf(3, 2)) self.assertTrue(sh.inf(0, 2.1) == 2.1) self.assertTrue(sh.inf(1.1, 2.1) == sh.inf(1.1, 2.1)) self.assertTrue(sh.inf(0, 2.1) != (0, 2.1)) self.assertTrue(3 != sh.inf(1, 2)) self.assertTrue(2 == sh.inf(0, 2)) self.assertEqual(sh.inf(1.1, 2.1) + 1, sh.inf(1.1, 3.1)) self.assertEqual(1 + sh.inf(1.1, 2.1), sh.inf(1.1, 3.1)) self.assertEqual(sh.inf(1, 2) + sh.inf(1, 0), sh.inf(2, 2)) self.assertEqual(1 - sh.inf(1, 2), sh.inf(-1, -1)) self.assertEqual(sh.inf(1, 2) - 1, sh.inf(1, 1)) self.assertEqual(sh.inf(1, 2) - sh.inf(1, 0), sh.inf(0, 2)) self.assertEqual(sh.inf(2, 2) * 4, sh.inf(8, 8)) self.assertEqual(4 * sh.inf(2, 2), sh.inf(8, 8)) self.assertEqual(sh.inf(2, 2) * sh.inf(2, 0), sh.inf(4, 0)) self.assertEqual(sh.inf(2, 3)**2, sh.inf(4, 9)) self.assertEqual(2**sh.inf(2, 3), sh.inf(4, 8)) self.assertEqual(sh.inf(3, 2)**sh.inf(2, 0), sh.inf(9, 1)) self.assertEqual(sh.inf(2, 2) / 2, sh.inf(1, 1)) self.assertEqual(2 / sh.inf(2, 2), sh.inf(1, 1)) self.assertEqual(sh.inf(2, 2) / sh.inf(2, 1), sh.inf(1, 2)) self.assertEqual(3 // sh.inf(2.1, 4.1), sh.inf(1, 0)) self.assertEqual(sh.inf(2.1, 4.1) // 3, sh.inf(0, 1)) self.assertEqual(sh.inf(2, 5.1) // sh.inf(4, 1), sh.inf(0, 5)) self.assertEqual(3 % sh.inf(2, 4.1), sh.inf(1, 3)) self.assertEqual(sh.inf(2, 4) % 3, sh.inf(2, 1)) self.assertEqual(sh.inf(2, 5) % sh.inf(4, 1), sh.inf(2, 0)) self.assertEqual(-sh.inf(1, 2), sh.inf(-1, -2)) self.assertEqual(+sh.inf(-1, 2), sh.inf(-1, 2)) self.assertEqual(abs(sh.inf(-1, 2)), sh.inf(1, 2)) if EXTRAS != 'micropython': self.assertEqual(str(sh.inf(0, 2.1)), '2.1') self.assertEqual(str(sh.inf(1, 2.1)), 'inf(inf=1, num=2.1)') self.assertTrue((0, 2) != sh.inf(0, 2)) self.assertTrue(3 <= sh.inf(1, 2)) self.assertTrue(3 >= sh.inf(0, 2)) self.assertTrue(3 < sh.inf(1, 2)) self.assertTrue(3 > sh.inf(0, 2)) self.assertEqual(round(sh.inf(1.22, 2.62)), sh.inf(1, 3)) self.assertEqual(round(sh.inf(1.22, 2.67), 1), sh.inf(1.2, 2.7)) self.assertEqual(math.trunc(sh.inf(1.2, 2.6)), sh.inf(1, 2)) self.assertEqual(math.ceil(sh.inf(1.2, 2.6)), sh.inf(2, 3)) self.assertEqual(math.floor(sh.inf(1.2, 2.6)), sh.inf(1, 2))
Gear box type (manual or automatic or cvt). :type gear_box_type: str :return: A flag to impose engine on when there is a gear > 0. :rtype: bool """ return gear_box_type == 'manual' dsp.add_data('min_time_engine_on_after_start', dfl.values.min_time_engine_on_after_start) @sh.add_function(dsp, outputs=['on_engine'], weight=sh.inf(1, 0)) def predict_on_engine(times, velocities, gears, accelerations, start_stop_model, start_stop_activation_time, min_time_engine_on_after_start, correct_start_stop_with_gears, has_start_stop): """ Predicts if the engine is on [-]. :param times: Time vector [s]. :type times: numpy.array :param velocities: Velocity vector [km/h]. :type velocities: numpy.array
Hostname to listen on. :type host: str :param port: Port of the webserver. :type port: int :return: """ import numpy as np np.set_printoptions(threshold=np.inf) site = sitemap.site(cache_folder, host=host, port=port).run() webbrowser.open(site.url) return site @sh.add_function(dsp, outputs=['plot'], weight=sh.inf(101, 0)) def wait_site(site): """ Pause for site shutdown. """ import time try: while True: time.sleep(1) except (KeyboardInterrupt, SystemExit): pass site.shutdown() def _yield_files(
from co2mpas.utils import check_first_arg, check_first_arg_false try: from co2mpas_dice import dsp as _dice except ImportError: _dice = None log = logging.getLogger(__name__) dsp = sh.BlueDispatcher(name='write', description='Write the outputs of the CO2MPAS model.') dsp.add_func(default_start_time, outputs=['start_time']) dsp.add_func(convert2df, outputs=['dfs']) @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),
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))
:type motors_electric_powers: numpy.array :param dcdc_converter_electric_powers_demand: DC/DC converter electric power demand [kW]. :type dcdc_converter_electric_powers_demand: numpy.array :return: Drive battery load vector [kW]. :rtype: numpy.array """ p = drive_battery_electric_powers + motors_electric_powers p -= dcdc_converter_electric_powers_demand return p dsp.add_data('drive_battery_load', 0, sh.inf(11, 0)) @sh.add_function(dsp, outputs=['drive_battery_loads']) def calculate_drive_battery_loads_v1(times, drive_battery_load): """ Calculates drive battery load vector [kW]. :param times: Time vector [s]. :type times: numpy.array :param drive_battery_load: Drive electric load [kW]. :type drive_battery_load: float
inputs=( 'service_battery_state_of_charges', 'service_battery_charging_statuses', 'service_battery_initialization_time', 'alternator_charging_currents', 'accelerations', 'on_engine', 'alternator_currents', 'motive_powers', 'alternator_current_model', 'times', ), outputs=('alternator_current_model', 'alternator_currents')) @sh.add_function(dsp, outputs=['alternator_currents'], weight=sh.inf(10, 3)) def default_alternator_currents(times, is_hybrid): """ Return zero current if the vehicle is hybrid [A]. :param times: Time vector [s]. :type times: numpy.array :param is_hybrid: Is the vehicle hybrid? :type is_hybrid: bool :return: Alternator currents [A]. :rtype: numpy.array
try: if k == 'time_series': raw_data[k] = xl.parse(k).dropna(1).to_dict(orient='list') else: df = xl.parse(k, header=None, index_col=0, usecols=[0, 1]).T raw_data[k] = df.dropna(1).to_dict(orient='records')[0] except IndexError: log.warning('Sheet `%s` is not well formatted!' % k) except xlrd.biffh.XLRDError: log.warning('Missing sheet (`%s`)!' % k) return raw_data dsp.add_data('raw_data', {}, sh.inf(1, 0)) @sh.add_function(dsp, outputs=['vehicle_id']) def get_vehicle_id(raw_data): """ Get vehicle ID from raw data. :param raw_data: Raw data of input file. :type raw_data: dict :return: Vehicle ID. :rtype: int """
@sh.add_function(dsp, outputs=["start_time"]) def default_start_time(): """ Returns the default run start time. :return: Run start time. :rtype: datetime.datetime """ import datetime return datetime.datetime.today() @sh.add_function(dsp, outputs=["done"], weight=sh.inf(100, 0)) def log_done(start_time): """ Logs the overall execution time. :param start_time: Run start time. :type start_time: datetime.datetime :return: Execution time [s]. :rtype: datetime.datetime """ import datetime sec = (datetime.datetime.today() - start_time).total_seconds()
Planetary speed vector [RPM]. :type planetary_speeds_in: numpy.array | float :param motor_p2_planetary_speeds: Rotating speed of planetary motor P2 [RPM]. :type motor_p2_planetary_speeds: numpy.array | float :return: Ratio between planetary motor P2 speed and planetary speed [-]. :rtype: float """ from .p4 import identify_motor_p4_speed_ratio as func return func(planetary_speeds_in, motor_p2_planetary_speeds) dsp.add_data('motor_p2_planetary_speed_ratio', 1, sh.inf(10, 1)) @sh.add_function(dsp, outputs=['motor_p2_planetary_speeds']) def calculate_motor_p2_planetary_speeds(planetary_speeds_in, motor_p2_planetary_speed_ratio): """ Calculates rotating speed of planetary motor P2 [RPM]. :param planetary_speeds_in: Planetary speed vector [RPM]. :type planetary_speeds_in: numpy.array | float :param motor_p2_planetary_speed_ratio: Ratio between planetary motor P2 speed and planetary speed [-]. :type motor_p2_planetary_speed_ratio: float
Engine speed [RPM]. :type engine_speeds_out: numpy.array :param motor_p0_speeds: Rotating speed of motor P0 [RPM]. :type motor_p0_speeds: numpy.array | float :return: Motor P0 speed ratio [-]. :rtype: float """ from .p4 import identify_motor_p4_speed_ratio as func return func(engine_speeds_out, motor_p0_speeds) dsp.add_data('motor_p0_speed_ratio', 3, sh.inf(10, 1)) @sh.add_function(dsp, inputs_kwargs=True, outputs=['motor_p0_speeds']) def calculate_motor_p0_speeds(engine_speeds_out, motor_p0_speed_ratio=3): """ Calculates rotating speed of motor P0 [RPM]. :param engine_speeds_out: Engine speed [RPM]. :type engine_speeds_out: numpy.array :param motor_p0_speed_ratio: Ratio between motor P0 speed and engine speed [-]. :type motor_p0_speed_ratio: float
try: if k == "time_series": raw_data[k] = xl.parse(k).dropna(1).to_dict(orient="list") else: df = xl.parse(k, header=None, index_col=0, usecols=[0, 1]).T raw_data[k] = df.dropna(1).to_dict(orient="records")[0] except IndexError: log.warning("Sheet `%s` is not well formatted!" % k) except xlrd.biffh.XLRDError: log.warning("Missing sheet (`%s`)!" % k) return raw_data dsp.add_data("raw_data", {}, sh.inf(1, 0)) @sh.add_function(dsp, outputs=["vehicle_id"]) def get_vehicle_id(raw_data): """ Get vehicle ID from raw data. :param raw_data: Raw data of input file. :type raw_data: dict :return: Vehicle ID. :rtype: int """
Final drive speed in [RPM]. :type final_drive_speeds_in: numpy.array :param motor_p3_speeds: Rotating speed of motor P3 [RPM]. :type motor_p3_speeds: numpy.array | float :return: Motor P3 speed ratio [-]. :rtype: float """ from .p4 import identify_motor_p4_speed_ratio as func return func(final_drive_speeds_in, motor_p3_speeds) dsp.add_data('motor_p3_front_speed_ratio', 1, sh.inf(10, 1)) dsp.add_data('motor_p3_rear_speed_ratio', 1, sh.inf(10, 1)) @sh.add_function( dsp, inputs_kwargs=True, outputs=['motor_p3_front_speeds'], inputs=['final_drive_speeds_in', 'motor_p3_front_speed_ratio']) @sh.add_function(dsp, inputs_kwargs=True, outputs=['motor_p3_rear_speeds'], inputs=['final_drive_speeds_in', 'motor_p3_rear_speed_ratio']) def calculate_motor_p3_speeds(final_drive_speeds_in, motor_p3_speed_ratio=1): """ Calculates rotating speed of motor P3 [RPM].
if sets_mapping is None: data = raw_data else: data = {} for (i, j), k in sh.stack_nested_keys(sets_mapping): sh.get_nested_dicts(data, i)[j] = raw_data[i][k] parsed_data = {} for (i, j), v in sh.stack_nested_keys(data): if not np.isnan(v).all(): sh.get_nested_dicts(parsed_data, i)[j] = v return parsed_data dsp.add_data('x_label', 'x') dsp.add_data('y_label', 'y') dsp.add_data('labels', None, sh.inf(1, 0)) dsp.add_data('methods', None, sh.inf(1, 0)) dsp.add_data('sets_mapping', None, sh.inf(1, 0)) input_keys = [ 'methods', 'data', 'reference_name', 'labels', 'x_label', 'y_label', 'interpolation_method' ] dsp.add_function( function_id='map_inputs', function=functools.partial(sh.map_list, input_keys), filters=[lambda x: {k: v for k, v in x.items() if v is not None}], inputs=input_keys, outputs=['inputs'])
return sh.map_list(keys, *_compute_shifts(*args)) def _interpolate(x, x_label, data, methods): xp = data[x_label] return { k: methods[k](x, xp=xp, fp=v) for k, v in data.items() if k != x_label } @sh.add_function(dsp, outputs=['methods'], inputs_kwargs=True, inputs_defaults=True, weight=sh.inf(1, 0)) def define_interpolation_methods(interpolation_method='linear'): """ Defines interpolation methods for each variable of each data-set. :param interpolation_method: Default interpolation method. :type interpolation_method: str :return: Interpolation methods for each variable of each data-set. It is like `{"<set-name>": {"<var-name>": "<interp>", ...}, ...}`. :rtype: collections.defaultdict """ import collections
Service battery initialization time delta [s]. :type service_battery_initialization_time: float :return: DC/DC converter currents [A]. :rtype: numpy.array """ return dcdc_current_model.predict( np.column_stack((times, service_battery_state_of_charges, service_battery_charging_statuses)), init_time=service_battery_initialization_time) @sh.add_function(dsp, outputs=['dcdc_converter_currents'], weight=sh.inf(10, 3)) def default_dcdc_converter_currents(times, is_hybrid): """ Return zero current if the vehicle is not hybrid [A]. :param times: Time vector [s]. :type times: numpy.array :param is_hybrid: Is the vehicle hybrid? :type is_hybrid: bool :return: DC/DC converter currents [A]. :rtype: numpy.array