API Reference¶
Backend¶
ml4cps.automata
¶
Automaton
¶
Bases: CPSComponent
Automaton class is the main class for modeling various kinds of hybrid systems.
Source code in ml4cps/automata/base.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 | |
num_modes
property
¶
Returns the number of modes in the automaton. :return: number of states.
num_transitions
property
¶
Returns the number of transitions in the automaton. :return: number of transitions.
state
property
writable
¶
Automata discrete state is uni-variate. :return:
__init__(states=None, transitions=None, unknown_state='raise', id='', initial_q=(), initial_r=None, final_q=(), super_states=(), decision_states=(), **kwargs)
¶
Class initialization from lists of elements. :param states: Discrete states / modes of continuous behavior. :param events: The events that trigger state transitions. :param transitions: The transition information. If a collection of dicts then dict should contain "source", "dest" and "event". The other attributes will be added as data of that transition. Alternatively, a collection of tuples can be used of the form (source, event, dest, *). :param unknown_state: The name of unknown states during "play in", if "raise", an exception will be raised.
Source code in ml4cps/automata/base.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | |
__str__()
¶
String representation of the automaton. :return:
Source code in ml4cps/automata/base.py
653 654 655 656 657 658 659 660 661 662 | |
add_final_state(states)
¶
Add final state(s) of the automaton. :param states: States to add.
Source code in ml4cps/automata/base.py
468 469 470 471 472 473 474 475 476 477 478 | |
add_initial_state(states)
¶
Add initial state(s) of the automaton. :param states: States to add.
Source code in ml4cps/automata/base.py
456 457 458 459 460 461 462 463 464 465 466 | |
add_state(new_state, **kwargs)
¶
Add state to the automaton. :param new_state: State to be added.
Source code in ml4cps/automata/base.py
428 429 430 431 432 433 | |
add_state_data(s, d)
¶
Add state data to a state s the automaton. :param s: state :param d: data to be added to s :return:
Source code in ml4cps/automata/base.py
419 420 421 422 423 424 425 426 | |
add_states_from(new_state, **kwargs)
¶
Add multiple states to the automaton. :param new_state: States to be added.
Source code in ml4cps/automata/base.py
435 436 437 438 439 440 | |
add_transition(s, d, e, **other)
¶
Add multiple transition.
:param list_of_tuples: List of transitions in the form (source_state, destination_state, event, ...
Source code in ml4cps/automata/base.py
449 450 451 452 453 454 | |
add_transitions_from(list_of_tuples, **other)
¶
Add multiple transition.
:param list_of_tuples: List of transitions in the form (source_state, destination_state, event, ...
Source code in ml4cps/automata/base.py
442 443 444 445 446 447 | |
flow(q, p, x, u)
¶
Flow equation gives derivative of the continuous variables. :param q: Current discrete state of the model. :param p: Stochastic parameters generated on entry to state current_q. :param x: Current continuous state of the model. :param u: Calculated internal i signals. :return: Derivative of the continuous state x.
Source code in ml4cps/automata/base.py
664 665 666 667 668 669 670 671 672 673 | |
get_num_in(q)
¶
Returns the number of in transitions of state q in the automaton. :return: number of transitions.
Source code in ml4cps/automata/base.py
507 508 509 510 511 512 513 514 515 | |
get_num_out(q)
¶
Returns the number of out transitions of state q in the automaton. :return: number of transitions.
Source code in ml4cps/automata/base.py
517 518 519 520 521 522 523 524 525 | |
get_transition(s, d=None, e=None, if_more_than_one='raise')
¶
Get all transitions with source state s, destination state __d. In case when e is provided, the returned list contains transitions where event is e. :param if_more_than_one: :param s: Source state. :param d: Destination state. :param e: Event. :return:
Source code in ml4cps/automata/base.py
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 | |
in_transitions(s, event=None)
¶
Get all incoming transitions of state s. :param s: :return:
Source code in ml4cps/automata/base.py
535 536 537 538 539 540 541 542 543 544 | |
inv(t, q, x, y, z, p)
¶
Invariants. :param t: :param q: :param x: :param y: :param z: :param p:
Source code in ml4cps/automata/base.py
675 676 677 678 679 680 681 682 683 684 685 | |
is_transition(s, d, e)
¶
Check if a transition (s,d,e) exists in the automaton. :param s: Source. :param d: Destination. :param e: Event. :return:
Source code in ml4cps/automata/base.py
480 481 482 483 484 485 486 487 488 489 490 491 492 | |
merge(q1, q2)
¶
If two states are compatible, they are merged with the function merge. The transitions of the automaton, the in- and outdegree of the states and the number of transitions happening are adjusted.
Source code in ml4cps/automata/base.py
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | |
out_transitions(s, event=None)
¶
Get all outgoing transitions of state s. :param event: :param s: :return:
Source code in ml4cps/automata/base.py
546 547 548 549 550 551 552 553 554 555 556 | |
print_state(v)
¶
Prints outgoing transitions of a state v.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
v
|
state
|
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
String |
Description of the outgoing transitions of the state. |
Source code in ml4cps/automata/base.py
690 691 692 693 694 695 696 697 698 699 700 701 702 | |
remove_transition(source, dest)
¶
Remove the transition(s) from source to dest. :param source: :param dest: :return:
Source code in ml4cps/automata/base.py
320 321 322 323 324 325 326 327 | |
rename_events(prefix='e_')
¶
Rename events to become e_0, e_1... The old id is stored in the field 'old_symbol' of the state data.
Source code in ml4cps/automata/base.py
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | |
step(q, x0, t, u)
¶
Simulates one time step of continuous behavior from t to t+dt. Underlying function is solve_ivp with method is 'RK23'. :param x0: Initial state vector. :param t: Time at start of the step simulation. :param u: Arguments passed..... :return: Time t+dt, value of state at t+dt
Source code in ml4cps/automata/base.py
638 639 640 641 642 643 644 645 646 647 648 649 650 651 | |
try_merge_states(state1, state2, try_fun=None)
¶
Merge state2 into state1 and update transitions.
Source code in ml4cps/automata/base.py
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | |
CPSComponent
¶
Bases: PythonModel, Simulator
General hybrid system class based on scipy and simpy.
Source code in ml4cps/cps/base.py
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 | |
state
property
writable
¶
System state is a vector of all state variables. :return:
__step_continuous(clock_start, clock_finish)
¶
Simulates one time step of continuous behavior from t to t+dt. Underlying function is solve_ivp with method is 'RK23'. :param x0: Initial state vector. :param t: Time at start of the step simulation. :param u: Arguments passed..... :return: Time t+dt, value of state at t+dt
Source code in ml4cps/cps/base.py
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | |
apply_sim_event(e, env=None)
¶
The event e is applied in this component's simpy execution, this means that the process must wait for an event. :param e: Event to apply. :return:
Source code in ml4cps/cps/base.py
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 | |
simulate(finish_time, verbose=False, save_choices=False)
¶
Simulates behaviour of the system until the finish_time is reached.
Parameters¶
finish_time : Time when simulation finishes. verbose : Should the execution log be printed in detail (default is False). save_choices : Should the choices for each component be saved to json files after the simulation is finished (default is False).
Source code in ml4cps/cps/base.py
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 | |
simulation_process_simpy(env, max_time, verbose=False)
¶
The function simulates single concurrent thread of one component (CPSComponent). Parameters
env : simpy.Environment It is simpy environment used to synchronize multiple parallel threads during simulation. max_time : float It is the maximum time that the simulation will perform. verbose : bool Should the function print execution logs (default is False).
Source code in ml4cps/cps/base.py
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | |
timed_event(q, xc, xd)
¶
Calculates if and when the next time event will happen and the new state values. :param t: Current time. :param q: Discrete-event part of the state. :param xc: Time-continuous part of the state. :param xd: Time-discrete part of the state. :return: Time delay of the timed event, new state value.
Source code in ml4cps/cps/base.py
704 705 706 707 708 709 710 711 712 713 | |
automata¶
The module provides learning algorithms for creation of different kinds of automata.
Authors: - Nemanja Hranisavljevic, hranisan@hsu-hh.de, nemanja@ai4cps.com - Tom Westermann, tom.westermann@hsu-hh.de, tom@ai4cps.com
FnDetectChangePoints(xout, udout, xout_shifts)
¶
Detects change points in output and input variables, filters them, and constructs a trace structure.
This function analyzes the provided output (xout) and input (udout) data to detect change points
using the findChangePoints function. It processes both output and input variables, aggregates and filters
the detected change points, and returns a structured trace dictionary containing the processed data and
change point information.
Args:
xout (np.ndarray): Output data array of shape (n_samples, n_outputs).
udout (np.ndarray): Input data array of shape (n_samples, n_inputs).
xout_shifts (np.ndarray): Shifted output data array, used for further processing.
Returns:
dict: A dictionary with the following keys:
- 'x': Filtered output data array.
- 'xs': Filtered shifted output data array.
- 'chpoints': Array of global change points detected across all variables.
- 'chpoints_per_var': List of arrays, each containing change points for a specific variable.
- 'ud': Filtered input data array.
- 'labels_num': Empty list (reserved for numeric labels).
- 'labels_trace': Empty list (reserved for trace labels).
Notes:
- Relies on global variables: num_var, num_ud, max_deriv, and chp_depths.
- Uses external functions: findChangePoints and filterChangePoints.
- The function is intended for use in time-series or sequential data analysis where detecting
significant changes in variable values is required.
Source code in ml4cps/automata/learn.py
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | |
FnShiftAndDiff(xout, udout, norm_coeff, num_var, num_ud, max_deriv, Ts)
¶
Normalizes and processes state and input data by generating shifted versions and computing derivatives.
This function performs the following operations:
1. Normalizes the state output xout using the provided normalization coefficients.
2. Generates shifted duplicates of xout up to the specified maximum derivative order.
3. Computes numerical derivatives of xout up to max_deriv order and appends them to the state data.
4. Strips the initial entries from xout and the shifted data to account for the derivative computation.
5. Normalizes the input data udout (if present) and strips initial entries to match the processed state data.
Args:
xout (np.ndarray): State output data of shape (n_samples, num_var).
udout (np.ndarray): Input data of shape (n_samples, num_ud).
norm_coeff (np.ndarray): Normalization coefficients of shape (num_var + num_ud, 1).
num_var (int): Number of state variables.
num_ud (int): Number of input variables.
max_deriv (int): Maximum order of derivatives to compute.
Ts (float): Sampling time interval.
Returns:
Tuple[np.ndarray, np.ndarray, pd.DataFrame]:
- xout (np.ndarray): Processed and augmented state data with derivatives, shape (n_samples - max_deriv, ...).
- udout (np.ndarray): Normalized input data, shape (n_samples - max_deriv, num_ud).
- xout_shifts (pd.DataFrame): Shifted duplicates of the normalized state data, shape (n_samples - max_deriv, ...).
Notes:
- The function assumes that xout and udout are NumPy arrays and that xout has at least max_deriv rows.
- The normalization coefficients should be provided for both state and input variables.
- The function uses zero-padding for shifted and derivative computations.
Source code in ml4cps/automata/learn.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | |
FnTraceToTrainingData(trace, num_var, num_ud, useTime)
¶
Converts a trace dictionary into training data suitable for machine learning models. Parameters: trace (dict): A dictionary containing the following keys: - 'x' (np.ndarray): Array of system variables over time (shape: [timesteps, num_var]). - 'ud' (np.ndarray): Array of user-defined variables over time (shape: [timesteps, num_ud]). - 'labels_trace' (np.ndarray): Array of state labels for each segment. - 'chpoints' (list or np.ndarray): Indices indicating change points (state switches) in the trace. num_var (int): Number of system variables to include in the feature vector. num_ud (int): Number of user-defined variables to include in the feature vector. useTime (bool): If True, includes the time since the last state switch as a feature. Returns: X (np.ndarray): Feature matrix where each row corresponds to a time step and contains: - Current state label - System variables - User-defined variables (if num_ud > 0) - Time since last state switch (if useTime is True) Y (np.ndarray): Array of next state labels (class labels) for each feature vector in X. states (np.ndarray): Array of state labels for each time step in the trace. Notes: - The function skips the last time step in the trace for feature construction, as it cannot form a (X, Y) pair. - The function assumes that the trace data is properly aligned and that 'chpoints' and 'labels_trace' are consistent.
Source code in ml4cps/automata/learn.py
588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | |
build_pta(data, event_col='event', boundaries=1)
¶
Builds a Prefix Tree Acceptor (PTA) from a collection of event sequences.
This function constructs a PTA by iterating through each sequence of events in the provided data.
It adds states and transitions to the automaton based on the observed event sequences,
and sets the depth, in-degree, and out-degree of the states. The PTA is useful for learning
automata from positive examples.
Args:
data (iterable): An iterable of event sequences. Each sequence can be a pandas DataFrame,
pandas Series, or string. If a DataFrame, it should contain at least a time column and
an event column.
event_col (str, optional): The name of the column containing event labels in the input
DataFrame or Series. Defaults to 'event'.
boundaries (int or dict, optional): Not currently used in the function, but intended for
handling event boundaries or timing constraints. Defaults to 1.
Returns:
Automaton: The constructed Prefix Tree Acceptor representing the input event sequences.
Notes:
- The function expects the presence of an Automaton class with methods for adding states,
transitions, and final states.
- If a sequence is a string, it is converted to a pandas Series of characters.
- Timing information (dt) is calculated as the difference between consecutive time steps.
- The function skips empty sequences.
Source code in ml4cps/automata/learn.py
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | |
computeDistance(der)
¶
Computes a distance metric over a sliding window for a given derivative array.
For each position in the input array der, the function calculates the sum of absolute differences
between two windows of size windowSize before and after the current position, after normalizing
each window by subtracting its first element. The result is an array of distances.
Parameters:
der (np.ndarray): The input array (e.g., derivative values) over which to compute the distance.
Returns:
np.ndarray: An array containing the computed distances for each valid position.
Source code in ml4cps/automata/learn.py
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | |
filterChangePoints(xout, udout, xout_shifts, chpoints, chp_var)
¶
Filters and synchronizes detected changepoints in time series data across multiple variables. This function processes global and local changepoint indices to ensure consistency and remove redundant or closely spaced changepoints. It updates the provided data arrays and changepoint lists accordingly. Args: xout (np.ndarray): Output variable time series data (samples x variables). udout (np.ndarray): Input variable time series data (samples x variables), or an empty array if not used. xout_shifts (np.ndarray): Shifted output variable data (samples x variables). chpoints (list or np.ndarray): List of global changepoint indices. chp_var (list of np.ndarray): List containing arrays of changepoint indices for each variable. Returns: tuple: - xout (np.ndarray): Filtered output variable data. - udout (np.ndarray): Filtered input variable data. - xout_shifts (np.ndarray): Filtered shifted output variable data. - chpoints (np.ndarray): Filtered and synchronized global changepoint indices. - chp_var (list of np.ndarray): Updated list of changepoint indices for each variable. Notes: - Uses global variables: windowSize, num_var, num_ud. - Assumes that changepoints are sorted and that there are at least two changepoints. - The function modifies chp_var in place.
Source code in ml4cps/automata/learn.py
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 | |
filterindx(indx, windw)
¶
Filters out indices from the input array that are within a specified window of each other.
Given a sorted array of indices, this function removes any index that is within windw distance
from its predecessor, keeping only the first occurrence in each window.
Parameters:
indx (array-like): A sorted array or list of integer indices.
windw (int): The minimum allowed distance between consecutive indices.
Returns:
numpy.ndarray: The filtered array of indices, where no two indices are within windw of each other.
Example:
>>> filterindx(np.array([1, 2, 3, 10, 12]), 2)
array([ 1, 10, 12])
Source code in ml4cps/automata/learn.py
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 | |
findChangePoints(xout, depth, starting, ending, max_depth)
¶
Recursively detects change points in a multi-dimensional signal using a hierarchical approach.
This function analyzes a segment of the input array xout at a given depth (dimension),
computes a distance metric to identify potential change points (peaks), and then recursively
searches for further change points in subsegments at deeper levels. The recursion stops when
the maximum depth is reached or the segment is too small.
Parameters
xout : np.ndarray The input array containing the signal or features to analyze. Expected shape is (n_samples, n_features). depth : int The current depth (dimension) being analyzed. starting : int The starting index of the segment to analyze. ending : int The ending index (exclusive) of the segment to analyze. max_depth : int The maximum depth (dimension) to analyze. Returns
np.ndarray An array of indices representing detected change points within the specified segment. Notes
- Uses global variables
windowSizeandchp_depthsfor windowing and tracking change points per depth. - Utilizes
computeDistance,find_peaks, andfilterindxhelper functions. - At the top level (depth == 0), prepends and appends boundary indices to the result.
Source code in ml4cps/automata/learn.py
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 | |
rpni(positive_samples, negative_samples)
¶
Implements the RPNI (Regular Positive and Negative Inference) algorithm for learning a DFA from positive and negative samples. Args: positive_samples (Iterable[str]): A collection of strings that should be accepted by the learned DFA. negative_samples (Iterable[str]): A collection of strings that should be rejected by the learned DFA. Returns: DFA: A deterministic finite automaton (DFA) that accepts all positive samples and rejects all negative samples. Notes: - The function first constructs a Prefix Tree Acceptor (PTA) from the positive samples. - It then attempts to merge states in the DFA, ensuring that no negative sample is accepted after each merge. - The merging process is guided by the constraint that all negative samples must be rejected.
Source code in ml4cps/automata/learn.py
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 | |
simple_learn_from_event_logs(data, initial=True, count_repetition=True, verbose=False)
¶
Simple algorithm to learn a timed automaton from event log data.
This function constructs a timed automaton by iterating over sequences of timestamped events.
Each event sequence is treated as a trace, and transitions are created between states based on event occurrences and their timing.
States are determined by the emitted events, optionally including repetition counts.
The automaton can be initialized with an explicit initial state, and transitions can account for repeated events.
Args:
data (list or pandas.Series): A list of event sequences, where each sequence is a pandas Series with timestamps as indices and event labels as values.
initial (bool, optional): If True, adds an explicit 'initial' state to the automaton. Defaults to True.
count_repetition (bool, optional): If True, distinguishes states and transitions by counting consecutive repetitions of the same event. Defaults to True.
verbose (bool, optional): If True, prints detailed information about the learning process. Defaults to False.
Returns:
Automaton: The learned timed automaton object.
Notes:
- Each sequence in data should be a pandas Series indexed by timestamps.
- If a sequence contains fewer than two events, it is skipped.
- The function assumes the existence of an Automaton class with add_initial_state and add_single_transition methods.
Source code in ml4cps/automata/learn.py
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | |
simple_learn_from_signal_updates(data, sig_names, initial=True, verbose=False)
¶
Learns a timed automaton from sequences of signal updates.
This function processes a list of dataframes, each representing a sequence of signal updates over time.
For each sequence, it constructs states based on the values of the specified signals and adds transitions
to an Automaton object whenever a signal value changes.
Args:
data (list of pandas.DataFrame): List of dataframes, each containing time-stamped signal updates.
The first column is assumed to be the time column, and subsequent columns correspond to signal names.
sig_names (list of str): List of signal names to track and use for state construction.
initial (bool, optional): If True, adds an initial state to the automaton for each sequence. Defaults to True.
verbose (bool, optional): If True, prints detailed information about the learning process. Defaults to False.
Returns:
Automaton: The learned automaton with states and transitions based on the observed signal updates.
Notes:
- Each state is represented as a dictionary mapping signal names to their current values.
- Transitions are added only when all signal values are set (i.e., not None).
- The event label for each transition is formatted as '
Source code in ml4cps/automata/learn.py
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | |
simple_learn_from_signal_vectors(data, drop_no_changes=False, verbose=False)
¶
Learns a timed automaton from a list of signal vector dataframes. This function processes sequences of signal vectors (as pandas DataFrames), detects changes in the specified signal columns, and constructs a timed automaton by adding transitions for each detected event. Args: data (list of pandas.DataFrame): List of DataFrames, each representing a sequence of signal vectors. The first column is assumed to be the time column, and the remaining columns are signal values. sig_names (list of str): List of column names in the DataFrame that correspond to the signals to be considered for state transitions. drop_no_changes (bool, optional): If True, rows where no signal changes occur are dropped before processing. Default is False. verbose (bool, optional): If True, prints detailed information about the learning process. Default is False. Returns: Automaton: An Automaton object constructed from the observed transitions in the input data. Notes: - Each transition in the automaton corresponds to a change in the signal vector, with the event label representing the difference between consecutive signal vectors and the transition time as the time delta. - The function assumes that the Automaton class and its add_single_transition method are defined elsewhere.
Source code in ml4cps/automata/learn.py
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | |
The module provides a class Automaton which inherits CPSComponent and implements the dynamics of different kinds of automata.
Authors: - Nemanja Hranisavljevic, hranisan@hsu-hh.de, nemanja@ai4cps.com - Tom Westermann, tom.westermann@hsu-hh.de, tom@ai4cps.com
Automaton
¶
Bases: CPSComponent
Automaton class is the main class for modeling various kinds of hybrid systems.
Source code in ml4cps/automata/base.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 | |
num_modes
property
¶
Returns the number of modes in the automaton. :return: number of states.
num_transitions
property
¶
Returns the number of transitions in the automaton. :return: number of transitions.
state
property
writable
¶
Automata discrete state is uni-variate. :return:
__init__(states=None, transitions=None, unknown_state='raise', id='', initial_q=(), initial_r=None, final_q=(), super_states=(), decision_states=(), **kwargs)
¶
Class initialization from lists of elements. :param states: Discrete states / modes of continuous behavior. :param events: The events that trigger state transitions. :param transitions: The transition information. If a collection of dicts then dict should contain "source", "dest" and "event". The other attributes will be added as data of that transition. Alternatively, a collection of tuples can be used of the form (source, event, dest, *). :param unknown_state: The name of unknown states during "play in", if "raise", an exception will be raised.
Source code in ml4cps/automata/base.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | |
__str__()
¶
String representation of the automaton. :return:
Source code in ml4cps/automata/base.py
653 654 655 656 657 658 659 660 661 662 | |
add_final_state(states)
¶
Add final state(s) of the automaton. :param states: States to add.
Source code in ml4cps/automata/base.py
468 469 470 471 472 473 474 475 476 477 478 | |
add_initial_state(states)
¶
Add initial state(s) of the automaton. :param states: States to add.
Source code in ml4cps/automata/base.py
456 457 458 459 460 461 462 463 464 465 466 | |
add_state(new_state, **kwargs)
¶
Add state to the automaton. :param new_state: State to be added.
Source code in ml4cps/automata/base.py
428 429 430 431 432 433 | |
add_state_data(s, d)
¶
Add state data to a state s the automaton. :param s: state :param d: data to be added to s :return:
Source code in ml4cps/automata/base.py
419 420 421 422 423 424 425 426 | |
add_states_from(new_state, **kwargs)
¶
Add multiple states to the automaton. :param new_state: States to be added.
Source code in ml4cps/automata/base.py
435 436 437 438 439 440 | |
add_transition(s, d, e, **other)
¶
Add multiple transition.
:param list_of_tuples: List of transitions in the form (source_state, destination_state, event, ...
Source code in ml4cps/automata/base.py
449 450 451 452 453 454 | |
add_transitions_from(list_of_tuples, **other)
¶
Add multiple transition.
:param list_of_tuples: List of transitions in the form (source_state, destination_state, event, ...
Source code in ml4cps/automata/base.py
442 443 444 445 446 447 | |
flow(q, p, x, u)
¶
Flow equation gives derivative of the continuous variables. :param q: Current discrete state of the model. :param p: Stochastic parameters generated on entry to state current_q. :param x: Current continuous state of the model. :param u: Calculated internal i signals. :return: Derivative of the continuous state x.
Source code in ml4cps/automata/base.py
664 665 666 667 668 669 670 671 672 673 | |
get_num_in(q)
¶
Returns the number of in transitions of state q in the automaton. :return: number of transitions.
Source code in ml4cps/automata/base.py
507 508 509 510 511 512 513 514 515 | |
get_num_out(q)
¶
Returns the number of out transitions of state q in the automaton. :return: number of transitions.
Source code in ml4cps/automata/base.py
517 518 519 520 521 522 523 524 525 | |
get_transition(s, d=None, e=None, if_more_than_one='raise')
¶
Get all transitions with source state s, destination state __d. In case when e is provided, the returned list contains transitions where event is e. :param if_more_than_one: :param s: Source state. :param d: Destination state. :param e: Event. :return:
Source code in ml4cps/automata/base.py
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 | |
in_transitions(s, event=None)
¶
Get all incoming transitions of state s. :param s: :return:
Source code in ml4cps/automata/base.py
535 536 537 538 539 540 541 542 543 544 | |
inv(t, q, x, y, z, p)
¶
Invariants. :param t: :param q: :param x: :param y: :param z: :param p:
Source code in ml4cps/automata/base.py
675 676 677 678 679 680 681 682 683 684 685 | |
is_transition(s, d, e)
¶
Check if a transition (s,d,e) exists in the automaton. :param s: Source. :param d: Destination. :param e: Event. :return:
Source code in ml4cps/automata/base.py
480 481 482 483 484 485 486 487 488 489 490 491 492 | |
merge(q1, q2)
¶
If two states are compatible, they are merged with the function merge. The transitions of the automaton, the in- and outdegree of the states and the number of transitions happening are adjusted.
Source code in ml4cps/automata/base.py
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | |
out_transitions(s, event=None)
¶
Get all outgoing transitions of state s. :param event: :param s: :return:
Source code in ml4cps/automata/base.py
546 547 548 549 550 551 552 553 554 555 556 | |
print_state(v)
¶
Prints outgoing transitions of a state v.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
v
|
state
|
|
required |
Returns:
| Name | Type | Description |
|---|---|---|
String |
Description of the outgoing transitions of the state. |
Source code in ml4cps/automata/base.py
690 691 692 693 694 695 696 697 698 699 700 701 702 | |
remove_transition(source, dest)
¶
Remove the transition(s) from source to dest. :param source: :param dest: :return:
Source code in ml4cps/automata/base.py
320 321 322 323 324 325 326 327 | |
rename_events(prefix='e_')
¶
Rename events to become e_0, e_1... The old id is stored in the field 'old_symbol' of the state data.
Source code in ml4cps/automata/base.py
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | |
step(q, x0, t, u)
¶
Simulates one time step of continuous behavior from t to t+dt. Underlying function is solve_ivp with method is 'RK23'. :param x0: Initial state vector. :param t: Time at start of the step simulation. :param u: Arguments passed..... :return: Time t+dt, value of state at t+dt
Source code in ml4cps/automata/base.py
638 639 640 641 642 643 644 645 646 647 648 649 650 651 | |
try_merge_states(state1, state2, try_fun=None)
¶
Merge state2 into state1 and update transitions.
Source code in ml4cps/automata/base.py
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 | |
cps¶
The module provides base classes to represent the dynamics of cyber-physical systems (CPS): - CPS, and, - CPSComponent.
Author: Nemanja Hranisavljevic, hranisan@hsu-hh.de
CPS
¶
CPS class represents a cyber-physical system. It is used to model the hierarchy in the system as each CPS can contain a mixture of other CPS and CPS components. The leaves of the hierarchy are only CPS component objects which define their dynamics and communication with other components.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Identifier of the object. |
com |
OrderedDict
|
Property. A collection of components. |
Source code in ml4cps/cps/base.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | |
parent_system
property
writable
¶
Gets the parent system by accessing _parent_system private attribute.
Returns:
| Type | Description |
|---|---|
CPS
|
The parent system. |
__getitem__(key)
¶
Gets the component with the given key in the collection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
string
|
The key where the value will be stored. Must be a hashable type (e.g., int, str). |
required |
Return: (CPS, CPSComponent): Returned component or subsystem.
Source code in ml4cps/cps/base.py
87 88 89 90 91 92 93 94 95 96 97 | |
__init__(sys_id, components)
¶
Initializes CPS with the given attributes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sys_id
|
str
|
ID of the system. |
required |
components
|
iterable
|
Child components of the system. |
required |
Source code in ml4cps/cps/base.py
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | |
get_all_components(exclude=None)
¶
Returns a list of all child components (not only direct) except those with ids possibly provided in exclude.
Parameters¶
exclude : iterable A list of component ids to exclude in the returned list.
Source code in ml4cps/cps/base.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | |
get_components(exclude=None)
¶
Returns a list of all direct child components except those with ids possibly provided in exclude.
Parameters¶
exclude : iterable A list of component ids to exclude in the returned list (default is None).
Source code in ml4cps/cps/base.py
123 124 125 126 127 128 129 130 131 132 133 | |
reinitialize(t=0, state=None)
¶
The function re-initializes the CPS components of this CPS with the given state values. :param t: Current time to set to the components. :param state: State of the CPS (it's components) given as a dictionary of dictionaries ... of tuples (according to the CPS hierarchy). The tuplus are created as values concatenated values of discrete-event state variables, time-continuous state variables and time-discrete state variables.
:return:
Source code in ml4cps/cps/base.py
192 193 194 195 196 197 198 199 200 201 202 203 204 205 | |
set_child_component(id, com)
¶
Set component with the id.
Parameters¶
id : str ID of the component to add. com : (CPS, CPSComponent) Component of subsystem to add.
Source code in ml4cps/cps/base.py
135 136 137 138 139 140 141 142 143 144 145 146 | |
simulate(finish_time, verbose=False, save_choices=False)
¶
Simulates behaviour of the system until the finish_time is reached.
Parameters¶
finish_time : Time when simulation finishes. verbose : Should the execution log be printed in detail (default is False). save_choices : Should the choices for each component be saved to json files after the simulation is finished (default is False).
Source code in ml4cps/cps/base.py
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | |
CPSComponent
¶
Bases: PythonModel, Simulator
General hybrid system class based on scipy and simpy.
Source code in ml4cps/cps/base.py
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 | |
state
property
writable
¶
System state is a vector of all state variables. :return:
__step_continuous(clock_start, clock_finish)
¶
Simulates one time step of continuous behavior from t to t+dt. Underlying function is solve_ivp with method is 'RK23'. :param x0: Initial state vector. :param t: Time at start of the step simulation. :param u: Arguments passed..... :return: Time t+dt, value of state at t+dt
Source code in ml4cps/cps/base.py
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | |
apply_sim_event(e, env=None)
¶
The event e is applied in this component's simpy execution, this means that the process must wait for an event. :param e: Event to apply. :return:
Source code in ml4cps/cps/base.py
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 | |
simulate(finish_time, verbose=False, save_choices=False)
¶
Simulates behaviour of the system until the finish_time is reached.
Parameters¶
finish_time : Time when simulation finishes. verbose : Should the execution log be printed in detail (default is False). save_choices : Should the choices for each component be saved to json files after the simulation is finished (default is False).
Source code in ml4cps/cps/base.py
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 | |
simulation_process_simpy(env, max_time, verbose=False)
¶
The function simulates single concurrent thread of one component (CPSComponent). Parameters
env : simpy.Environment It is simpy environment used to synchronize multiple parallel threads during simulation. max_time : float It is the maximum time that the simulation will perform. verbose : bool Should the function print execution logs (default is False).
Source code in ml4cps/cps/base.py
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | |
timed_event(q, xc, xd)
¶
Calculates if and when the next time event will happen and the new state values. :param t: Current time. :param q: Discrete-event part of the state. :param xc: Time-continuous part of the state. :param xd: Time-discrete part of the state. :return: Time delay of the timed event, new state value.
Source code in ml4cps/cps/base.py
704 705 706 707 708 709 710 711 712 713 | |
Simulation.
Author: - Nemanja Hranisavljevic, hranisan@hsu-hh.de, nemanja@ai4cps.com
Simulator
¶
Source code in ml4cps/cps/sim.py
12 13 14 15 16 17 18 19 20 21 22 23 | |
stop_condition(t)
¶
Simulation stop condition which can be overridden by the subclasses.
Source code in ml4cps/cps/sim.py
19 20 21 22 23 | |
discretization¶
The module provides base classes to represent the dynamics of cyber-physical systems (CPS): CPS and CPSComponent.
Author: Nemanja Hranisavljevic, hranisan@hsu-hh.de
EqualFrequencyDiscretizer
¶
Bases: TimeSeriesDiscretizer
A class that implements the equal-frequency interval (EFI) discretization method. It divides each variable (column) into intervals such that each interval contains approximately the same number of data points.
Source code in ml4cps/discretization/discretization.py
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | |
discretize(df, return_str=False, append_discr=None)
¶
Discretize data into equal-frequency intervals. :param df: Data to discretize. :param return_str: Whether to return discretized data as a concatenated string per row. :return: Discretized data.
Source code in ml4cps/discretization/discretization.py
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | |
train(data, number_of_intervals=10)
¶
Estimate model parameters, thresholds that divide each variable into equal-frequency intervals. :param data: Data to calculate model parameters from. :param number_of_intervals: Number of equal-frequency intervals per variable. :return:
Source code in ml4cps/discretization/discretization.py
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | |
EqualWidthDiscretizer
¶
Bases: TimeSeriesDiscretizer
A class that implements equal-width interval (EWI) discretization method. It calculates range of every variable (column) of the input data into a predefined number of equal-width intervals.
Source code in ml4cps/discretization/discretization.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | |
discretize(df, return_str=False, append_discr=None)
¶
Discretize data into equal width intervals. :param data: Data to discretize. :return: Discretized data.
Source code in ml4cps/discretization/discretization.py
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | |
train(data, number_of_intervals=10)
¶
Estimate model parameters, thresholds that divide each variable into equal-width intervals. :param data: Data to calculate model parameters from. :param number_of_intervals: Number of equal-width intervals per variable. :return:
Source code in ml4cps/discretization/discretization.py
33 34 35 36 37 38 39 40 41 42 43 44 45 | |
KMeansDiscretizer
¶
Bases: TimeSeriesDiscretizer
A class that implements K-means discretization. It clusters the data values of each variable into a predefined number of clusters using the K-means algorithm.
Source code in ml4cps/discretization/discretization.py
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | |
discretize(df, return_str=False, append_discr=None)
¶
Discretize data into clusters determined by K-means. :param df: DataFrame to discretize. :param return_str: Whether to return discretized data as concatenated strings. :return: Discretized data.
Source code in ml4cps/discretization/discretization.py
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | |
train(data, number_of_clusters_per_var=10)
¶
Train the K-means discretizer by fitting K-means models for each variable (column) in the data. :param data: List of DataFrames to calculate model parameters from. :param number_of_clusters_per_var: Number of clusters (intervals) per variable.
Source code in ml4cps/discretization/discretization.py
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | |
MultivariateKMeansDiscretizer
¶
Bases: TimeSeriesDiscretizer
A class that implements multivariate K-means discretization. It clusters the data based on all variables (columns) together into a predefined number of clusters.
Source code in ml4cps/discretization/discretization.py
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | |
discretize(df, return_str=False, append_discr=None)
¶
Discretize data into clusters determined by K-means. :param df: DataFrame to discretize. :param return_str: Whether to return discretized data as concatenated strings. :return: Discretized data (cluster labels).
Source code in ml4cps/discretization/discretization.py
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | |
train(data, number_of_clusters=10)
¶
Train the K-means discretizer by fitting a single K-means model for all variables. :param data: List of DataFrames to calculate model parameters from. :param number_of_clusters: Number of clusters.
Source code in ml4cps/discretization/discretization.py
225 226 227 228 229 230 231 232 233 234 235 | |
TimeSeriesDiscretizer
¶
Abstract class that encapsulates methods used for the discretization of time series.
Source code in ml4cps/discretization/discretization.py
12 13 14 15 16 17 18 19 20 | |
vis¶
The module provides methods to visualize various kinds of data, such as time series or automata graphs.
Authors: - Nemanja Hranisavljevic, hranisan@hsu-hh.de, nemanja@ai4cps.com - Tom Westermann, tom.westermann@hsu-hh.de, tom@ai4cps.com
plot2d(df, x=None, y=None, mode='markers', hovercolumns=None, figure=False, **args)
¶
Creates a 2D scatter or line plot using Plotly based on the provided DataFrame columns. Parameters: df (pd.DataFrame): The input DataFrame containing the data to plot. x (str, optional): The column name to use for the x-axis. y (str, optional): The column name to use for the y-axis. mode (str, optional): The Plotly scatter mode (e.g., 'markers', 'lines'). Defaults to 'markers'. hovercolumns (list of str, optional): List of column names to include in the hover tooltip. figure (bool, optional): If True, returns a Plotly Figure object; otherwise, returns a Scatter trace. Defaults to False. **args: Additional keyword arguments passed to the Plotly Scatter constructor. Returns: plotly.graph_objs._scatter.Scatter or plotly.graph_objs._figure.Figure: The generated Plotly Scatter trace or Figure, depending on the 'figure' parameter. Example: plot2d(df, x='feature1', y='feature2', hovercolumns=['label'], mode='markers', figure=True)
Source code in ml4cps/vis.py
1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 | |
plot3d(df, x=None, y=None, z=None, mode='markers', hovercolumns=None, **args)
¶
Creates a 3D scatter plot using Plotly's Scatter3d, with customizable axes, hover information, and additional plot arguments.
Parameters:
df (pandas.DataFrame): The data source containing columns for x, y, z, and optional hover data.
x (str, optional): The column name in df to use for the x-axis.
y (str, optional): The column name in df to use for the y-axis.
z (str, optional): The column name in df to use for the z-axis.
mode (str, optional): Plotly scatter mode (e.g., 'markers', 'lines'). Defaults to 'markers'.
hovercolumns (list of str, optional): List of column names in df to include in the hover tooltip.
**args: Additional keyword arguments passed to go.Scatter3d.
Returns:
plotly.graph_objs._scatter3d.Scatter3d: A Plotly 3D scatter plot object configured with the specified data and options.
Source code in ml4cps/vis.py
1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 | |
plot_2d_contour_from_fun(fun, rangex=None, rangey=None, th=50, **kwargs)
¶
Plots a 2D contour of a function over a specified range. Parameters: fun (callable): A function that takes a 2D array of shape (n_points, 2) and returns a 1D array of function values. rangex (tuple, optional): The range for the x-axis as (min, max). Defaults to (-5, 5) if not provided. rangey (tuple, optional): The range for the y-axis as (min, max). Defaults to (-5, 5) if not provided. th (int, optional): Unused parameter, kept for compatibility. Defaults to 50. **kwargs: Additional keyword arguments passed to the plotly.graph_objs.Contour constructor. Returns: plotly.graph_objs.Contour: A Plotly contour plot object representing the function values over the specified range.
Source code in ml4cps/vis.py
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 | |
plot_cps(cps, dash_id=None, node_labels=False, edge_labels=True, node_size=40, node_font_size=20, edge_font_size=16, edge_text_max_width=None, output='cyto', dash_port=8050, height='100%', minZoom=0.5, maxZoom=2, **kwargs)
¶
Plots all the components of a CPS in the same figure. :param cps: CPS to plot. :param node_labels: Should node labels be plotted. :param edge_labels: Should edge labels be plotted. :param node_size: What is the size of the nodes in the figure. :param node_font_size: The font size of the node labels. :param edge_font_size: The font size of the edge labels. :param edge_text_max_width: Max width of the edge labels. :param output: Should output be plotted as a dash.Cytoscape component ("cyto"), or should dash server be run ("dash"). :param dash_port: If temporary dash server is run, what port to use. :param kwargs: Other paramters are forwarded to the Cytoscape component. :return:
Source code in ml4cps/vis.py
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 | |
plot_cps_component(cps, id=None, node_labels=False, center_node_labels=False, event_label=True, show_transition_freq=False, show_transition_timing=False, font_size=6, edge_font_size=6, edge_text_max_width=None, init_label=False, limit_interval_precision=None, show_transition_data=False, transition_data_keys=True, node_size=20, output='cyto', dash_port=8050, min_zoom=0.5, split_edges_diff_event=False, max_zoom=1, min_edge_thickness=0.1, max_edge_thickness=4, freq_as_edge_thickness=False, color='black', title_text=None, layout_name='breadthfirst', layout_spacingFactor=1, hide_nodes=None)
¶
Visualizes a component of a Cyber-Physical System (CPS) as a graph using Dash Cytoscape.
This function generates a graphical representation of the discrete states and transitions of a CPS,
with various customization options for node and edge appearance, labels, and output format.
The visualization can be rendered as Dash Cytoscape elements, in a Dash app, or as a notebook widget.
Parameters:
cps: object
The CPS object containing discrete states, transitions, and related data.
id: str, optional
The unique identifier for the Cytoscape component (default: "graph").
node_labels: bool, optional
Whether to display labels on nodes (default: False).
center_node_labels: bool, optional
Whether to center node labels (default: False).
edge_labels: bool, optional
Whether to display labels on edges (default: True).
show_transition_freq: bool, optional
Whether to show transition frequency on edge labels (default: False).
edge_font_size: int, optional
Font size for edge labels (default: 6).
edge_text_max_width: int or None, optional
Maximum width for edge label text wrapping (default: None).
init_label: bool, optional
Whether to label initial state transitions as 'init' (default: False).
show_transition_data: bool or list, optional
Whether to display additional transition data on edge labels. If a list, only specified keys are shown (default: False).
node_size: int, optional
Size of the nodes (default: 20).
output: str, optional
Output format: "cyto" (Dash Cytoscape Div), "elements" (raw elements), "notebook" (inline Dash app), or "dash" (Dash app in browser) (default: "cyto").
dash_port: int, optional
Port for running the Dash app (default: 8050).
min_zoom: float, optional
Minimum zoom level for the Cytoscape component (default: 0.5).
max_zoom: float, optional
Maximum zoom level for the Cytoscape component (default: 1).
min_edge_thickness: float, optional
Minimum edge thickness for frequency-based scaling (default: 0.1).
max_edge_thickness: float, optional
Maximum edge thickness for frequency-based scaling (default: 4).
freq_as_edge_thickness: bool, optional
Whether to scale edge thickness based on transition frequency (default: False).
color: str, optional
Color for nodes and edges (default: "black"). If "hsu", uses a preset color.
title_text: str or Dash component, optional
Title text or component to display above the graph (default: None).
Returns:
Dash component, dict, or Dash app:
- If output == "cyto": returns a Dash html.Div containing the Cytoscape graph.
- If output == "elements": returns a dict with 'nodes' and 'edges'.
- If output == "notebook": runs and displays a Dash app inline (for Jupyter).
- If output == "dash": runs a Dash app in the browser and returns the app instance.
Notes:
- Requires Dash, dash_cytoscape, dash_bootstrap_components, and pandas.
- The function supports interactive modals for displaying timing data on states and transitions.
- Threading is used to launch the Dash app in browser mode without blocking the main program.
# 1. 'grid' → Places nodes in a simple rectangular grid.
2. 'random' → Randomly positions nodes; useful for testing.¶
3. 'circle' → Arranges nodes evenly around a circle.¶
4. 'concentric' → Places nodes in concentric circles, often by degree or weight.¶
5. 'breadthfirst' → Hierarchical layout (tree-like), good for state machines or DAGs.¶
Optional params: directed=True, padding=¶
6. 'cose' → Force-directed layout (spring simulation). Great for organic graphs.¶
Optional params: idealEdgeLength, nodeRepulsion, gravity, numIter¶
7. 'cose-bilkent' → Improved force-directed layout with better stability and aesthetics.¶
(Requires: cyto.load_extra_layouts())¶
8. 'cola' → Constraint-based force-directed layout; handles larger graphs well.¶
(Requires: cyto.load_extra_layouts())¶
9. 'euler' → Physically simulated layout; looks natural and dynamic.¶
(Requires: cyto.load_extra_layouts())¶
10. 'avsdf' → Circular layout optimized to reduce edge crossings.¶
(Requires: cyto.load_extra_layouts())¶
11. 'spread' → Distributes disconnected components evenly across space.¶
(Requires: cyto.load_extra_layouts())¶
12. 'klay' → Layered (hierarchical) layout, excellent for flowcharts or process models.¶
(Requires: cyto.load_extra_layouts())¶
13. 'dagre' → Directed acyclic graph layout, ideal for workflows and automata.¶
(Requires: cyto.load_extra_layouts())¶
Optional params: rankDir='TB' (top-bottom), 'LR' (left-right), etc.¶
Source code in ml4cps/vis.py
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 | |
plot_cps_plotly(cps, layout='dot', marker_size=20, node_positions=None, show_events=True, show_num_occur=False, show_state_label=True, font_size=10, plot_self_transitions=True, use_previos_node_positions=False, **kwargs)
¶
Visualizes a Cyber-Physical System (CPS) state-transition graph using Plotly.
This function generates an interactive Plotly figure representing the states and transitions of a CPS.
Nodes represent system states, and edges represent transitions. Various layout algorithms and display options
are supported.
Args:
cps: The CPS object containing the state-transition graph. Must have attributes _G (networkx graph),
get_transitions(), print_state(), num_occur(), and previous_node_positions.
layout (str, optional): Layout algorithm for node positioning. Options are "dot" (default), "spectral",
"kamada_kawai", or "fruchterman_reingold".
marker_size (int, optional): Size of the node markers. Default is 20.
node_positions (dict, optional): Precomputed node positions as a dictionary {node: (x, y)}. If None,
positions are computed using the selected layout.
show_events (bool, optional): Whether to display event labels on transitions. Default is True.
show_num_occur (bool, optional): Whether to display the number of occurrences for each transition. Default is False.
show_state_label (bool, optional): Whether to display state labels on nodes. Default is True.
font_size (int, optional): Font size for transition/event labels. Default is 10.
plot_self_transitions (bool, optional): Whether to plot self-loop transitions. Default is True.
use_previos_node_positions (bool, optional): If True and node_positions is None, reuse positions from
cps.previous_node_positions. Default is False.
**kwargs: Additional keyword arguments passed to the layout function (e.g., for networkx layouts).
Returns:
plotly.graph_objs.Figure: A Plotly figure object representing the CPS state-transition graph.
Notes:
- Requires Plotly, NetworkX, and pydotplus (for "dot" layout).
- The CPS object must provide the required methods and attributes as described above.
- Edge and node styling can be further customized by modifying the function.
Source code in ml4cps/vis.py
798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 | |
plot_dash_frames(graph_frames, dash_port=8050)
¶
Launches an interactive Dash web application to visualize a sequence of graph frames with a slider for manual frame selection. Args: graph_frames (list): A list of Dash components (e.g., Cytoscape graphs) representing different frames to display. dash_port (int, optional): The port number on which to run the Dash server. Defaults to 8050. Returns: dash.Dash: The Dash application instance. Side Effects: - Starts a Dash server in a separate thread. - Opens the default web browser to display the Dash app. - Waits for user input before returning. Notes: - The app displays the first frame by default and allows users to select other frames using a slider. - The function blocks until the user presses Enter in the console.
Source code in ml4cps/vis.py
1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 | |
plot_execution_tree(graph, nodes_to_color, color, font_size=30)
¶
Plots a system execution tree as a graph, where the horizontal position of nodes corresponds to their timestamps and the tree branches vertically.
Args:
graph (networkx.DiGraph): A directed graph where each node represents a system state, and edges represent transitions.
Each node should have a 'label' (str) and 'weight' (int) attribute. Node names must be timestamp strings in the format "%d/%m/%Y, %H:%M:%S".
nodes_to_color (list): List of node identifiers (timestamp strings) to be highlighted with a specific color.
color (str): The color to use for highlighting nodes in nodes_to_color.
font_size (int, optional): Font size for node labels in the visualization. Defaults to 30.
Returns:
cyto.Cytoscape: A Dash Cytoscape object representing the execution tree visualization, with nodes positioned by timestamp and colored as specified.
Notes:
- The function assumes the first node in graph.nodes is the starting node.
- Node positions are determined by the time difference from the start node (x-axis) and their 'weight' attribute (y-axis).
- Nodes in nodes_to_color are colored with the specified color; all others are gray.
- Requires the cyto (Dash Cytoscape) library and datetime module.
Source code in ml4cps/vis.py
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 | |
plot_state_transitions(ta, state, obs=None)
¶
Visualizes the outgoing state transitions from a given state in a timed automaton, along with associated observation data.
Parameters:
ta: An object representing the timed automaton, expected to have an out_transitions(state) method that returns transitions from the given state.
state: The current state for which outgoing transitions and associated observations are to be visualized.
obs (optional): A pandas DataFrame containing observation data. Must include at least the columns 'Mode', 'q_next', 'Duration', 'Time', and optionally 'Vergussgruppe', 'HID', 'ChipID', 'Order', and 'ArtNr'. If None, the function raises NotImplemented.
Returns:
fig: A Plotly figure object containing subplots for each outgoing transition. For each transition, the function displays:
- A scatter plot of observation durations over time, grouped by 'Vergussgruppe'.
- A histogram of durations for each 'Vergussgruppe'.
The subplots are arranged with shared axes and appropriate titles for each transition.
Raises:
NotImplemented: If obs is None.
Notes:
- The function expects certain columns to exist in the obs DataFrame. If missing, default values are assigned.
- Colors for different 'Vergussgruppe' groups are assigned from DEFAULT_PLOTLY_COLORS.
- The function uses Plotly's make_subplots, go.Scatter, and go.Histogram for visualization.
Source code in ml4cps/vis.py
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 | |
plot_stateflow(stateflow, color_mapping=None, state_col='State', task_col='Task', bar_height=12, start_column='Start', finish_column='Finish', return_figure=False, description_col='Description', idle_states=None)
¶
Visualizes state transitions over time for one or more tasks/stations as a Gantt-like interactive timeline.
Parameters: - stateflow (DataFrame or dict): DataFrame with state transitions, or a dictionary of DataFrames per station. - color_mapping (dict, optional): Mapping of state names to colors. If None, default colors are used. - state_col (str): Column name indicating the state (default: 'State'). - bar_height (int): Height of the timeline bars (default: 12). - start_column (str): Column name with start timestamps (default: 'Start'). - finish_column (str): Column name with end timestamps (default: 'Finish'). - return_figure (bool): If True, returns a Plotly Figure. Otherwise, returns a list of Plotly traces. - description_col (str or list): Column(s) to include in the hover tooltip (default: 'Description'). - idle_states (str or list): State(s) to exclude from the plot (e.g., 'IDLE').
Returns:
- Plotly Figure or list of traces, depending on return_figure.
Example
fig = plot_stateflow(df, state_col='Mode', start_column='StartTime', finish_column='EndTime', return_figure=True) fig.show()
This function is ideal for visualizing process flows, machine states, or event-based logs with time intervals.
Source code in ml4cps/vis.py
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | |
plot_timeseries(data, timestamp=None, mode_data=None, discrete=False, title=None, use_columns=None, height=None, limit_num_points=None, names=None, xaxis_title=None, customdata=None, iterate_colors=True, y_title_font_size=14, opacity=1, vertical_spacing=0.005, sharey=False, bounds=None, plot_only_changes=False, yAxisLabelOffset=False, marker_size=4, showlegend=False, mode='lines+markers', mode_height=0.2, x_title=None, **kwargs)
¶
Using plotly library, plots each variable (column) in a collection of dataframe as subplots, one after another.
Arguments: yAxisLabelOffset (bool): if True, adds an offset to the plots y-axis labels. Improves readability on long subplot names.
Returns:
| Name | Type | Description |
|---|---|---|
fig |
Figure
|
|
Source code in ml4cps/vis.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | |
plot_transition(self, s, d)
¶
Plots the transition histogram between two states.
Retrieves the transition data between the source state s and destination state d,
and generates a Plotly figure visualizing the timing distribution of the transition.
The plot includes a title, an annotation indicating the transition, and a histogram
of the transition timings.
Args:
s: The source state identifier.
d: The destination state identifier.
Returns:
plotly.graph_objs._figure.Figure: A Plotly Figure object containing the histogram
of transition timings.
Source code in ml4cps/vis.py
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 | |
view_graphviz(self, layout='dot', marker_size=20, node_positions=None, show_events=True, show_num_occur=False, show_state_label=True, font_size=10, plot_self_transitions=True, use_previos_node_positions=False, **kwargs)
¶
Visualizes the internal graph structure using Graphviz and returns a pydot graph object. Parameters: layout (str): The layout algorithm to use for node positioning (default: "dot"). marker_size (int): Size of the node markers in the visualization (default: 20). node_positions (dict or None): Optional dictionary mapping node names to (x, y) positions. If None, positions are computed. show_events (bool): Whether to display event labels on transitions (default: True). show_num_occur (bool): Whether to display the number of occurrences for each transition (default: False). show_state_label (bool): Whether to display state labels on nodes (default: True). font_size (int): Font size for labels and annotations (default: 10). plot_self_transitions (bool): Whether to plot self-loop transitions (default: True). use_previos_node_positions (bool): Whether to reuse previously computed node positions (default: False). **kwargs: Additional keyword arguments for customization. Returns: pdp.Dot: A pydot graph object representing the visualized graph. Notes: - Node positions are either computed using Graphviz or taken from the provided/previous positions. - Annotations for transitions can include event names and/or occurrence counts. - The function prepares the graph for further rendering or export, but does not display it directly.
Source code in ml4cps/vis.py
957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 | |
tools¶
Various methods to transform data.
binary_ordinal_encode(column, order)
¶
Encodes a pandas Series with binary ordinal encoding based on the specified order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
column
|
Series
|
The column to encode. |
required |
order
|
list
|
The ordered list of unique values in the column. |
required |
Returns:
| Type | Description |
|---|---|
|
pd.DataFrame: The binary ordinal encoded DataFrame for the given column. |
Source code in ml4cps/tools.py
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | |
generate_random_walk(start_values, steps=100)
¶
Generates a random walk process for multiple variables.
Parameters: - start_values (list): A list of starting values for each variable. - steps (int): Number of steps in the random walk.
Returns: - pd.DataFrame: DataFrame containing the random walk process for each variable.
Source code in ml4cps/tools.py
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 | |
remove_timestamps_without_change(data, sig_names=None)
¶
Removes timestamps where no values changed in comparison to the previous timestamp.
Source code in ml4cps/tools.py
96 97 98 99 100 101 102 103 104 105 106 107 108 109 | |