visualdynamics.project¶
project
¶
The project: every object in a test, and how the objects are grouped.
The desktop app's window holds the same things a Project holds: the
named objects, the object groups, which group is the Basis, the project
type and the active geometry. A project built in the app and one built
in a script are therefore the same, and both save to the same .vdyn
file. A script uses the app's own verbs (add, link, set_basis,
rename, save) instead of building dicts and lists by hand.
The functions near the end of this module run a whole workflow in one
call. random_vibration_report, for example, reads a Rattlesnake run
and writes an HTML report, and random_vibration_run builds the project
that report is made from.
Classes:
| Name | Description |
|---|---|
Selection |
Objects reached by type instead of by name. |
Project |
Every object in one test, by name, and how the objects are grouped. |
Functions:
| Name | Description |
|---|---|
type_rank |
The position of an object's type in the order the tree lists types. |
describe |
A few words on what an object holds: its size, not its name. |
holds |
What a file held, in words, from the objects read out of it: for |
holds_of_names |
|
remap_links |
Object groups translated through a {old name: new name} mapping. |
retarget |
Point an object's references at renamed objects. |
holds_forces |
Whether a time history holds a force or modal force channel, or a |
random_vibration_run |
Work a Rattlesnake random vibration run up into a project. |
work_up_system_id |
Work up an imported system identification in place. |
system_id_run |
Work a Rattlesnake system identification up into a project. |
mixed_run |
Work a Rattlesnake random run with a sine sweep under it up into a |
sine_run |
Work a Rattlesnake sine sweep run up into a project. |
sine_report |
Read a Rattlesnake sine sweep run and write an HTML report. |
report_kind |
Which one-call reports a Rattlesnake run gets: 'random', 'mixed', |
run_report |
Read a Rattlesnake run and write the report its type calls for. |
system_id_report |
Read a Rattlesnake system identification and write an HTML |
random_vibration_report |
Read a Rattlesnake random vibration run and write an HTML report. |
Classes¶
Selection
¶
Selection(project: Project, names: Iterable[str] | None = None, label: str = 'project')
Objects reached by type instead of by name.
project.geometry # anywhere in the project
project.basis.frf # in the Basis group
project.basis.psds[0] # one of several
A name is whatever an importer or a user called the object, and importing a second geometry makes 'Geometry' ambiguous without renaming anything. A type does not change, and an editor can complete it.
The singular gives the one object of that kind. When there are
several it raises AttributeError listing their names, except that
when exactly one of them is not on octave bands, that one is
returned. The plural is always a list, so code written for one FRF
still works when a second one is added. A kind leaves out objects
of a narrower kind: time_history does not return a transient
specification, and psds does not return a specification.
Methods:
| Name | Description |
|---|---|
of_type |
The names in scope holding objects of this class. |
Attributes:
| Name | Type | Description |
|---|---|---|
names |
list[str]
|
The names in scope, in the order the tree shows them. |
Source code in src/visualdynamics/project.py
Attributes¶
Methods:¶
of_type
¶
The names in scope holding objects of this class.
Objects of a narrower kind are left out: a transient
specification is not returned for TimeHistory.
Source code in src/visualdynamics/project.py
Project
¶
Project(name: str = 'Project', objects: dict[str, Any] | None = None, active_geometry: str | None = None, project_type: str | None = None, object_groups: Iterable[ObjectGroup] | None = None, provenance: dict[str, dict[str, Any]] | None = None, data_index: DataIndex | Iterable[Mapping[str, Any]] | None = None)
Bases: dict
Every object in one test, by name, and how the objects are grouped.
A Project is a dict from name to object, so project['FRF'],
list(project) and project.items() give what the tree shows.
The desktop app holds one of these: the window's objects,
project_type and active_geometry are properties over it, and its
buttons call the verbs below. A project built in the app and one
built in a script are the same object, and each opens in the other.
Objects are usually reached by type rather than by name, as in
project.geometry, project.basis.frf or project.other.shapes.
The singular gives the one object of that kind and raises an error
when several qualify; the plural is always a list.
Attributes:
object_groups: The groups objects have been linked into, each
{'members': [...], 'role': 'Basis' | None} with an
optional 'name'. Objects are grouped only by link, never
by matching their names.
project_type: The kind of test: 'Modal Test', 'Random
Vibration', 'Transient', 'Shock', 'Sine Sweep', 'Random and
Sine' or 'System ID'. It sets the report template and the
empty slots the tree shows.
active_geometry: The name of the geometry data is drawn on when
nothing else is named.
name: The project's name, used as the title of a saved .vdyn
and of a rendered report.
Methods:
| Name | Description |
|---|---|
grouped_names |
[(group or None, [names])] in the order the tree shows them. |
ordered_names |
Every name, flat, in the order the tree shows them. |
add |
Add an object under a unique name and return the name used. |
duplicate |
Copy objects and add the copies beside them, as Copy and Paste |
import_file |
Import a file into this project and return the names added. |
remove |
Delete objects and take them out of every object group. |
rename |
Rename an object and change every reference to it. |
rename_dof |
Correct a channel's coordinate on an object and on every object |
link |
Link objects into one group, merging any groups they are |
unlink |
Take objects out of their object groups. A group left with one |
relink |
Move one object into the group holding |
name_object_group |
Name the object group an object belongs to, or remove its name. |
object_group_of |
The members linked with |
role_of |
'Basis' for an object in the Basis group, otherwise None. |
placed |
{role: [members]}: the objects in each group that has a role. |
sides |
{side: [object names]} for the project type's slots. |
missing |
The project type's empty slots, the ones the tree shows gray. |
object_group_with_role |
The object group carrying a role, or None. |
place |
Put one object into the Basis or the other group, creating the |
set_channel_role |
Give one channel the role reference, response or monitor, on a |
transformed_rows |
Which of a data object's response DOFs are rows of a response |
set_role |
Set the role of the group an object is in. The Basis is |
set_basis |
Set the Basis for comparisons, the group the other objects are |
modal_basis |
The shape set an object's modal records are coordinates of, |
geometry_for |
(name, geometry) for the geometry an object is drawn on and |
sensors |
The sensors a channel table places on its geometry, and notes on |
channel_table_for |
(name, table) for the channel table linked with an object: |
absorb_links |
Add the object groups of a project being imported. |
verbs |
The processing verbs that apply to an object, each with its |
selection_verbs |
The processing verbs a selection can act on, each with its |
compute_spectra |
Compute spectra from a time history's averages, as Compute |
compute_psds |
Compute PSDs from a time history's averages (Compute PSDs). |
averaging_of |
The |
rms_source |
The name of the time history a computed autospectrum was made |
rms_check |
Check one record of an autospectrum against the time history |
caption_of |
The caption a report plot of a measured record carries, read |
field_limit |
The statistical limit over a set of measured PSDs or SRSs and |
derive_specification |
Write the specification a set of measured PSDs or SRSs gives |
compute_octave |
Integrate a spectrum onto proportional octave bands (Compute |
make_realizable |
Repair a cross-spectral matrix to the nearest realizable one |
compute_frfs |
Compute frequency response functions from a time history |
read_transmissibility |
The ASD-ratio transmissibility behind one record of an FRF, |
read_partial_coherence |
Which drive explains each response, and whether the drives |
compute_multiple_coherence |
Compute the multiple coherence from a time history (Compute |
compute_srs |
Compute shock response spectra from a time history's shocks |
detect_shocks |
Find the events in a time history and mark them on it (Detect |
filter_data |
Filter a time history with its own filter settings (Apply |
resample |
Take a time history to a lower sample rate (Apply Resample in |
truncate_data |
Cut a time history to its truncation span (Apply Truncation in |
integrate |
Integrate a time history once (Integrate): acceleration |
differentiate |
Differentiate a time history once (Differentiate): |
compute_cpsds |
Compute the full cross-spectral matrix from a time history's |
transform |
Transform a record's channels through a shape set to modal |
expand |
Expand modal responses through a shape set back to physical |
author_specification |
Write a specification from a sheet (Make Specification in the |
generate_rigid_body_modes |
Generate the six rigid-body mode shapes of a geometry (Generate |
generate_signal |
Generate a reference signal from a spectrum, a sine |
compute_modal_responses |
Compute how each mode of a shape set answers the forces in a |
merge_coincident_nodes |
Merge each set of a geometry's coincident nodes into one node |
align_meshes |
Move the coarser mesh's nodes onto the finer mesh's nodes where |
new_geometry |
Add an empty geometry to build a model in (the project's + |
new_channel_table |
Add an empty channel table to fill in by hand (the project's |
add_channels |
Add blank channels to a channel table, numbered on from its |
set_view |
Set the view a geometry opens on in 3-D, in the app, the report |
tie_elements |
Tie a patch of a geometry's elements rigidly to the part under |
merge_groups |
Merge a geometry's element groups into one (Merge Element |
add_solid_block |
Add a block to a geometry's solids ( |
add_solid_cylinder |
Add a cylinder to a geometry's solids ( |
add_solid_cone |
Add a cone to a geometry's solids ( |
add_solid_sphere |
Add a sphere to a geometry's solids ( |
add_solid_plate |
Add a plate to a geometry's solids ( |
add_solid_disk |
Add a disk to a geometry's solids ( |
add_solid_section |
Add a structural section to a geometry's solids |
add_solid_hole |
Add a hole to a geometry's solids ( |
delete_elements |
Delete a geometry's elements and the nodes only they used, |
delete_element_groups |
Delete a geometry's element groups with their elements and the |
edit_solid |
Change a solid after it is made ( |
move_solids |
Move whole solids ( |
combine_solids |
Add a boolean of a geometry's solids: 'union', 'subtract' (the |
reorder_solids |
Put a geometry's solids in a new order (a drag in the tree): |
copy_solids |
Copy a geometry's solids, recipe and all, into the same |
pattern_solids |
Pattern a geometry's solids in rows, columns and layers |
mesh_solids |
Mesh a geometry's solids into bricks, tetrahedra or shells |
detect_mated_surfaces |
The patches where element groups' surfaces mate |
add_mated_surfaces |
Join two element groups where their surfaces mate (Mate |
mate_surfaces |
Join every patch where the element groups' surfaces mate, as |
edit_mated_surfaces |
Change a set of mated surfaces: its |
delete_mated_surfaces |
Delete sets of mated surfaces, by id; returns how many went. |
delete_solids |
Delete a geometry's solids, each with every solid it is made |
separate_solids |
Take a geometry's booleans and patterns apart (Take Apart). |
solve_modes |
Solve the normal modes of a geometry whose element groups have |
plan_instrumentation |
Plan a test's accelerometers from finite element modes, by |
convert_to_specification |
Convert a PSD or CPSD to a specification, the requirement |
convert_to_psd |
Convert a specification to a plain PSD or CPSD, under its own |
remembered_spacing |
The frequency spacing the specification's sheet remembers, in |
scale_family |
The measured PSDs that share one comparison scale: the object |
comparison_scale |
The decibels a measured PSD is scaled by when it is compared |
set_comparison_scale |
Hold a comparison scale on a measured PSD and its whole family |
fit_coherence |
The coherence the fitting screen weights a fit of |
fit_modes |
Fit a modal model to an FRF set, as the fitting screen does. |
project_onto_basis |
Sample a shape set at the Basis shape set's DOFs, or at a |
match_modes |
Save matched mode pairs as an object (the comparison screen's + |
comparison_mac |
The MAC between two shape sets, as the comparison screen shows |
plot_mac |
Draw the MAC the comparison screen draws: |
merge |
Combine compatible objects into one (Merge). The merged object |
export |
Write an object to another file format, chosen by the file's |
export_state_space |
Write a shape set at a channel table's channels as a modal |
generate_report |
Build a report from a starter template, bound by type to this |
report_features |
Turn a report's optional features on or off (the report |
report_section |
Write one skeleton section of a report (the report editor's |
report_check_block |
Give a report a check of its own, with what it reads and its |
report_check |
What a report still owes before it is issued, one line per |
report_flash |
Type the parts of a flash report only the author can write. |
report_finding |
Enter, change or remove a finding in a report's findings |
draft_finding_fact |
Offer a finding a draft of its fact, read off a comparison the |
draft_finding_from_requirement |
Offer a finding a draft of its fact, read off a row of a |
draft_findings_from_run_log |
Offer a report the deviations and anomalies a run log extract |
accept_logged_finding |
Accept, or discard, a finding a run log offered a report |
report_test_date |
Set the dates of the test a report covers, which its sensors' |
report_calibration |
Each sensor of a report's channel table against its test |
report_calibration_text |
The equipment list with each sensor's calibration status on |
predict |
Enter one response channel's predicted response, the |
report_prediction |
Add a block reading |
report_requirement |
Bind a test requirement to a run in the report |
index_file |
Add a file to the project's data index (the report editor's |
index_run_log_files |
Add the files a run log extract names to the project's data |
unindex_file |
Take a file out of the data index (the report editor's |
verify_data_index |
Hash every file in the data index again and record whether |
attach_run_log |
Bring one test of a run log into the project, frozen at a stated |
detach_run_log |
Take a run log extract out of the project, and return it. |
refresh_run_log |
Take a run log extract again from its log, to its newest entry |
report_identity |
Enter a report's identification (the report editor's Identity |
export_report_pdf |
Write a report as a paginated PDF, printed from the same page |
issue_report |
Issue a report: print it as a PDF under its number and |
amend_report |
Make an issued report an amendment, to be issued in its turn |
run_identity |
Which run of the test a time history is, as a report reads it. |
set_run_identity |
Enter which run of the test a time history is. |
report_chronology |
Draft the chronology of the project's runs and offer it to a |
accept_chronology |
Accept the drafted chronology as a report's Chronology section, |
report_runs |
Repeat a report's Results for every run (the editor's Results |
work_up |
Compute every missing object the project's type expects from |
export_report |
Write a report as one self-contained HTML file (Export). |
table |
(headers, rows) for an object that can be shown as a table. |
plot_transformation |
Draw one row of a shape set's transformation on its geometry, |
transformation_of |
A rigid set's transformation at a choice of DOFs, as an object |
read_transformation |
What a rigid-body transformation leaves unexplained of the |
plot |
Plot an object the way the app plots it: data as curves, a |
animate |
Animate a mode shape, a complex spectrum's operating |
animate_pair |
Animate two shape sets' modes overlaid on their geometries, as |
name_of |
The name an object is stored under; a string is returned as |
extract_sine |
Read each specification tone's level out of a recording |
stale |
{derived name: reason} for every derived object whose source's |
refresh |
Recompute a derived object in place, under its own name. |
refresh_stale |
Refresh every stale object, sources before the objects derived |
save |
Write the whole project to one file: |
open |
Read a project from a |
journal_as |
Record a stretch of front-end work as the one line that |
record_setting |
Journal a settings write the way a script would make it. |
record_call |
Journal a method call on an object the way a script would make |
session_script |
This session's changes to the project as a runnable Python |
Attributes:
| Name | Type | Description |
|---|---|---|
basis |
Selection
|
The Basis group, reached by type, as in |
object_group_selections |
list[Selection]
|
Every object group, the Basis first, each reached by type. |
other |
Selection
|
The one object group that is not the Basis, usually the model |
names |
list[str]
|
Every object's name, in the order the tree shows them. |
Source code in src/visualdynamics/project.py
Attributes¶
basis
property
¶
basis: Selection
The Basis group, reached by type, as in project.basis.frf.
It is empty, and false, when no group is the Basis, so
if project.basis: works as it reads. Its member names are
project.basis.names.
object_group_selections
property
¶
object_group_selections: list[Selection]
Every object group, the Basis first, each reached by type.
other
property
¶
other: Selection
The one object group that is not the Basis, usually the model side of a correlation.
Empty when there is none. Raises AttributeError when there are
several; use object_group_selections then.
Methods:¶
grouped_names
¶
[(group or None, [names])] in the order the tree shows them.
The Basis group comes first, then the other object groups, then the unlinked objects under None. Within each, objects are in the tree's type order, and objects of one type are in the order they were added.
Source code in src/visualdynamics/project.py
ordered_names
¶
add
¶
Add an object under a unique name and return the name used.
A name that is already taken gets a numbered suffix, the same as importing a file twice in the app; nothing is overwritten. The first geometry added becomes the active geometry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
What to call the object. |
required |
obj
|
object
|
Any object the project can hold. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The name the object was added under, unique within the project. |
Source code in src/visualdynamics/project.py
duplicate
¶
Copy objects and add the copies beside them, as Copy and Paste do in the tree. Returns the names added.
Each copy is named '
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*names
|
str or object
|
The objects to copy, by name or as the objects. |
()
|
Returns:
| Type | Description |
|---|---|
list of str
|
The names the copies were added under, in order. |
Source code in src/visualdynamics/project.py
import_file
¶
Import a file into this project and return the names added.
The file can be anything visualdynamics reads: a geometry, a Rattlesnake run or a saved project. A saved project brings its object groups, which follow the objects even when a name clash renamed them, and when this project is empty it also brings its name, type and active geometry. When a reader returns several objects, each is named by its type the way the tree shows it (a reader's key such as 'Modal_frf' becomes 'FRF'), and if one of them is a channel table they are all linked into one group.
A file that records what kind of test it was sets the project type. A controller's save records which environment ran, and importing it here sets the type the same way importing it in the app does.
options are passed to the format's reader, for example an
Exodus file's steps='time' and nodes=[...] or a geometry's
length_unit='m', so a script can give what the app asks for in
a dialog.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str or PathLike
|
The file to read. The importer is chosen by content and extension. |
required |
**options
|
Any
|
Passed through to the importer. |
{}
|
Returns:
| Type | Description |
|---|---|
list of str
|
The names of every object added, in the order added. |
Source code in src/visualdynamics/project.py
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 | |
remove
¶
Delete objects and take them out of every object group.
A name not in the project is ignored. When the active geometry is removed, the first remaining geometry becomes the active one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*names
|
str
|
The objects to act on, by name. |
()
|
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in src/visualdynamics/project.py
rename
¶
Rename an object and change every reference to it.
Object groups, matched-mode sets, report blocks, provenance
records and the active geometry all refer to objects by name,
and each is updated so that no report figure is left pointing
at the old name. An unknown old raises KeyError; a new that
is empty or already in use raises ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
old
|
str
|
The current name. |
required |
new
|
str
|
The name to give it. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The new name. |
Source code in src/visualdynamics/project.py
rename_dof
¶
Correct a channel's coordinate on an object and on every object derived from it. In the app, double-click a row or reference column of the grid and type.
Only the channel changes, not the point: correcting a force labeled at the wrong node leaves the accelerometer at that node where it is. Spectra computed from a time history carry its channels, so the correction is also applied to every object derived from the source, through any number of steps, instead of leaving each one to be fixed by hand or recomputed. A derived object that does not carry the channel is left alone. An object with no coordinates raises TypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object whose grid row or column was edited. |
required |
old
|
str
|
The coordinate as it is, for example '101Z+'. |
required |
new
|
str
|
The coordinate to give it, normalized the same way as every coordinate. |
required |
quantity
|
str
|
Which channel at |
None
|
Returns:
| Type | Description |
|---|---|
list of str
|
The names of the objects changed, the source first. |
Source code in src/visualdynamics/project.py
link
¶
Link objects into one group, merging any groups they are already in. Returns the group's members.
A group holds at most one geometry, and its members are checked against it. A member that names nodes the geometry does not have is still linked, and the app marks its row red so the mismatch can be seen; a test often has drive points, control coordinates or virtual channels the model does not draw. A modal object with no shape set to be drawn against is refused with ValueError, as are fewer than two names and a second geometry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*names
|
str
|
The objects to link, by name. |
()
|
role
|
str
|
The role to give the group: 'Basis', or None. Left out, a group being merged into keeps the role it had. |
None
|
name
|
str
|
What to call the group. A named group is exported to the Engineering Sciences Common Data Format as an activity with that name. Left out, a group being merged into keeps the name it had. |
None
|
Returns:
| Type | Description |
|---|---|
list of str
|
The group's members after linking. |
Source code in src/visualdynamics/project.py
942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 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 | |
unlink
¶
Take objects out of their object groups. A group left with one member is dissolved unless it has a role.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*names
|
str
|
The objects to act on, by name. |
()
|
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in src/visualdynamics/project.py
relink
¶
Move one object into the group holding target.
link merges the groups of all its arguments, which is right for
saying two objects belong together and wrong for moving one
object: linking a geometry into the other group would bring its
whole group with it. This method takes the object out of its
group first, so only it moves. A target of None only takes it
out.
The group it joins keeps its role, so an object moved into the
Basis becomes part of the Basis. A move that link refuses
leaves the groups as they were and raises the same error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The object to move. |
required |
target
|
str or object
|
An object whose group it should join. None removes it from its current group. |
None
|
Returns:
| Type | Description |
|---|---|
list of str
|
The members of the group the object ends up in, or an empty
list when |
Source code in src/visualdynamics/project.py
name_object_group
¶
Name the object group an object belongs to, or remove its name.
An object in no group raises KeyError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
member
|
str
|
Any member of the group, by name. |
required |
name
|
str or None
|
The group's new name; None removes it. |
required |
Returns:
| Type | Description |
|---|---|
list of str
|
The group's members. |
Source code in src/visualdynamics/project.py
object_group_of
¶
The members linked with name, or None.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The object to look up. |
required |
Returns:
| Type | Description |
|---|---|
list of str, or None
|
The names sharing its object group, or None when it is in no group. |
Source code in src/visualdynamics/project.py
role_of
¶
'Basis' for an object in the Basis group, otherwise None.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The object to look up. |
required |
Returns:
| Type | Description |
|---|---|
str or None
|
Its object group's role, or None if it has none. |
Source code in src/visualdynamics/project.py
placed
¶
{role: [members]}: the objects in each group that has a role.
Nothing is inferred here. An object that has not been placed is in no group with a role, and that is what makes the tree's gray slots meaningful: a slot is filled only by an object in its own group, so a modal test whose only geometry is the model's still shows a slot for the measured one.
Source code in src/visualdynamics/project.py
sides
¶
{side: [object names]} for the project type's slots.
The Basis is listed under its role. Every member of every other
group is listed under OTHER_SIDE, because that side has no role
of its own and is read from the groups instead. The tree's gray
slots and missing are computed from this.
Returns:
| Type | Description |
|---|---|
dict of str to list of str
|
|
Source code in src/visualdynamics/project.py
missing
¶
The project type's empty slots, the ones the tree shows gray.
Each is a tuple (label, class, icon key, ordinal, optional,
side), as project_expectations gives them. A project with no
type expects nothing. Until a Basis is set, every object counts
toward every slot: the app places objects as they arrive, a
script may never place them, and a script's project with
everything in it and no groups should not show every slot empty.
Returns:
| Type | Description |
|---|---|
list of tuple
|
|
Source code in src/visualdynamics/project.py
object_group_with_role
¶
The object group carrying a role, or None.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
role
|
str
|
Which group to fetch. 'Basis' is the only role. |
required |
Returns:
| Type | Description |
|---|---|
ObjectGroup or None
|
That group, or None when no group has the role. |
Source code in src/visualdynamics/project.py
place
¶
Put one object into the Basis or the other group, creating the group if needed. Returns the group's members.
Unlike link, this takes a single object. If a group needed two
members before it could exist, a pair sorted into the wrong
group could not be moved across one object at a time. A move
that is refused leaves the groups as they were.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The object being placed. |
required |
role
|
str or None
|
'Basis', or None for the other group: the one group that is
not the Basis, created if there is none yet. When there are
several groups besides the Basis there is no single other
group, and this raises ValueError; use |
required |
Returns:
| Type | Description |
|---|---|
list of str
|
The group's members. |
Source code in src/visualdynamics/project.py
1252 1253 1254 1255 1256 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 | |
set_channel_role
¶
Give one channel the role reference, response or monitor, on a time history or a channel table and on whatever is linked with it.
The time history's roles are the ones FRFs and multiple coherence use. A channel table linked with a history whose channels it describes shows the history's roles, so a change made on either is made on both. A channel table with no such history keeps its own roles. An unknown role or channel raises ValueError, and an object that is neither raises TypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The time history or channel table, by name or as the object. |
required |
dof
|
str
|
The channel's degree of freedom, for example '101Z+'. |
required |
quantity
|
str
|
What it measures, as a history's |
required |
role
|
str
|
'reference', 'response' or 'monitor'. |
required |
Returns:
| Type | Description |
|---|---|
list of str
|
The objects whose roles changed. |
Source code in src/visualdynamics/project.py
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 1360 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 | |
transformed_rows
¶
Which of a data object's response DOFs are rows of a response transformation in its channel table.
A transformed environment's specification and spectra are over
the matrix's rows, which the controller's file names only by
number, so they import as '1', '2', ... (io.rattlesnake). This
ties such a row back to the matrix: the window's note on the
object, and a script's.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The data object. |
required |
Returns:
| Type | Description |
|---|---|
list of (str, str, list of str)
|
|
Source code in src/visualdynamics/project.py
set_role
¶
Set the role of the group an object is in. The Basis is unique, so giving it to one group takes it from any other.
An object in no group raises ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The object whose group is being labeled. |
required |
role
|
str or None
|
The role, or None to clear it. |
required |
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in src/visualdynamics/project.py
set_basis
¶
Set the Basis for comparisons, the group the other objects are compared against.
Comparisons are made in the Basis group's DOFs, its modes are the rows of the MAC, and its frequencies are the baseline for frequency error. One name marks that object's group as the Basis; several names are linked first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*names
|
str or object
|
The objects that form the basis set. |
()
|
Returns:
| Type | Description |
|---|---|
list of str
|
The basis group's members. |
Source code in src/visualdynamics/project.py
modal_basis
¶
The shape set an object's modal records are coordinates of, by name: the set whose shapes turn them into motion.
Read from where the records came from. Modal responses computed
from forces (compute_modal_responses) name their set in each
comment; a transform's result names it in its provenance; an
object derived from either (filtered, decimated, cropped) keeps
its source's set. None when nothing says, when the records named
come from two sets, or when the set is gone or has fewer modes
than the records.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The object, by name or as the object itself. |
required |
records
|
sequence of int
|
Read only these records; every record at a modal DOF when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
str or None
|
The shape set's name. |
Source code in src/visualdynamics/project.py
1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 | |
geometry_for
¶
geometry_for(name: Any) -> tuple[str, Geometry] | None
(name, geometry) for the geometry an object is drawn on and checked against: the one in its group, otherwise the active one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The object whose geometry is wanted. |
required |
Returns:
| Type | Description |
|---|---|
tuple of (str, Geometry), or None
|
The geometry's name and the geometry itself, or None when there is no geometry in the object's group and no active geometry. |
Source code in src/visualdynamics/project.py
sensors
¶
The sensors a channel table places on its geometry, and notes on
what could not be placed (core.sensors.place): the bodies the
3-D view draws when Sensors is on.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The channel table. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
sensors |
list of Sensor
|
One per physical sensor: its node, model, catalog entry, center and frame. |
notes |
list of str
|
Rows left out and why, models drawn as generic bodies, and triax legs the table gets wrong. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the object is not a channel table. |
ValueError
|
If there is no geometry to place them on. |
Source code in src/visualdynamics/project.py
channel_table_for
¶
channel_table_for(name: Any) -> tuple[str, ChannelTable] | None
(name, table) for the channel table linked with an object: the one lookup the overload check and the shape values share.
For a time history, the first table in its group with a row naming one of its channels: a table in the group that names none of them describes some other recording and is passed over, as the role pairing passes it over. For anything else (a shape set, whose values are read at a table's channels), the first table in its group. A table has none of its own.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The object. |
required |
Returns:
| Type | Description |
|---|---|
tuple of (str, ChannelTable), or None
|
The table's name and the table, or None when no linked table fits. |
Source code in src/visualdynamics/project.py
absorb_links
¶
Add the object groups of a project being imported.
By this point the arriving objects have already been placed in groups one at a time by the project type's rules, without the file's own grouping to go on. The file's groups are added last, and where an object is in two groups the later one is kept, so the file's grouping replaces the earlier placement.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
groups
|
iterable of ObjectGroup
|
Object groups from another project, merged into this one's. |
required |
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in src/visualdynamics/project.py
verbs
¶
The processing verbs that apply to an object, each with its one-line summary, so a script can find what can be done with it.
The table of which verb applies to what is the same one the app's bar reads, so the two always agree. Each summary is the first paragraph of the verb's own docstring, so it also matches the API reference.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to ask about. A name is looked up in the project; an object is checked as it is, whether or not it has been added, so a result can be asked about before it is kept. Omitted, every processing verb is listed. |
None
|
Returns:
| Type | Description |
|---|---|
list of (str, str)
|
|
Source code in src/visualdynamics/project.py
selection_verbs
¶
The processing verbs a selection can act on, each with its one-line summary. This is what the app's bar offers.
For one object, these are its own verbs less the ones that need
a second object (transform needs a shape set beside the
record). For several objects, these are the verbs that apply to
exactly that combination: a record and a shape set can be
transformed or expanded, two shape sets on two geometries can be
projected, and objects of one type can be merged. Verbs that
apply to only one of the objects are not listed. The table is
the same one verbs reads, so the bar and the API agree.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*names
|
str or object
|
The selection, by name or as the objects themselves. |
()
|
Returns:
| Type | Description |
|---|---|
list of (str, str)
|
|
Source code in src/visualdynamics/project.py
compute_spectra
¶
Compute spectra from a time history's averages, as Compute Spectra in the averaging view does.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
compute_psds
¶
Compute PSDs from a time history's averages (Compute PSDs).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
averaging_of
¶
The Averaging a computed spectrum was made with, from its
provenance, or None when it records none (an imported spectrum).
A spectrum computed from a record with no averaging set was each
record whole under a rectangle, and that is what is returned.
A spectrum does not carry its window, and a tone read off it
needs one (Psd.read_tone): the window sets how far the tone leaks
and how tall its spike stands. The provenance holds the
averaging as it was when the spectrum was computed, which is the
one that made it even if the record's own has moved since. An
FRF and a coherence are read the same way: the transmissibility
behind an FRF (read_transmissibility) is read from the frames
the FRF was.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The spectrum, by name or as the object itself. |
required |
Returns:
| Type | Description |
|---|---|
Averaging or None
|
|
Source code in src/visualdynamics/project.py
rms_source
¶
The name of the time history a computed autospectrum was made from, from its provenance, or None when it records none (an imported spectrum) or that record is no longer in the project.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The spectrum, by name or as the object itself. |
required |
Returns:
| Type | Description |
|---|---|
str or None
|
|
Source code in src/visualdynamics/project.py
rms_check
¶
rms_check(spectrum: Any, record: int = 0, *, history: Any = None, threshold_db: float | None = None) -> Any
Check one record of an autospectrum against the time history it came from (the rms check): the rms from the area under the spectrum beside the record's own rms, the gap in dB, and the verdict.
A computed spectrum is checked against the record its
provenance names, over the frames it was averaged with
(averaging_of), so a record whose averaging has moved since
is still read as the spectrum saw it. An imported spectrum, or
one checked against another record, takes history and that
record's own averaging. Psd.rms_check does the reading.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
spectrum
|
str or object
|
The autospectrum, by name or as the object itself. |
required |
record
|
int
|
Which record of the spectrum. |
0
|
history
|
str or object
|
The time history to check against; the one the spectrum was computed from when omitted. |
None
|
threshold_db
|
float
|
The gap, in dB either way, beyond which the two disagree;
|
None
|
Returns:
| Type | Description |
|---|---|
RmsCheck
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When no time history is given and the spectrum records
none, or when |
Source code in src/visualdynamics/project.py
caption_of
¶
caption_of(name: Any, records: int | Sequence[int] = 0, *, specification: Any = None, per_octave: int | None = None, unit_system: Any = None, tone: str | None = None) -> Any
The caption a report plot of a measured record carries, read
off the record and the project around it (core.report_caption):
a spectrum's, a shock response spectrum's, a sine level's or a
time history's (report_caption.caption_kind).
print(project.caption_of('Time History PSDs', 2).text())
A shock response spectrum's run is the time history it was
computed from, with that run's sample rate and the filters
applied in the project on the way to it; against a requirement
each record is judged by the points rule in the polarity drawn
and in each other polarity the project holds of the same events
at the same Q and spacing. A sine level's run is the recording
it was extracted from, its sweep is the tone as the requirement
specifies it, and its distortion is the check the report's check
blocks have already made of the tone (check_blocks.kept); the
check rebuilds every tone and is not made for a caption. A time
history is its own run.
Every row comes from the project, none is typed. The run is the
time history the spectrum was computed from, and the stretch of
it averaged; the window, overlap and frames are the averaging
the spectrum was made with (averaging_of). A banded spectrum
reads these, and its line spacing and degrees of freedom, from
the narrowband spectrum it was banded from. The channel number
and comment come from a channel table that names the channel,
the one linked with the spectrum or its run first, and the
global axis from the geometry linked with them, or the Basis
geometry. An imported spectrum has no run and no averaging the
project knows of, so its run, window and frames read "not
recorded" (a block label, where its records carry one, is the
run): the name an import gave the object is not a run.
per_octave is for a narrowband spectrum drawn on bands without
being stored banded, as a report block that bands its data
draws it: the caption is then of the spectrum on those bands,
compared with the specification on the same bands, and the
comparison's scale is resolved on the narrowband spectrum, as
the report resolves it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The spectrum, by name or as the object itself. |
required |
records
|
int or sequence of int
|
The records the plot draws. |
0
|
specification
|
str or object
|
The requirement drawn with the spectrum, by name or as the object itself. |
None
|
per_octave
|
int
|
Bands per octave the spectrum is drawn on, for one banded only for the plot. |
None
|
unit_system
|
UnitSystem
|
The display units the rms values and ranges are written in. |
None
|
tone
|
str
|
For a sine level set, the tone drawn; its first when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
(RecordCaption, SrsCaption, SineCaption or TimeCaption)
|
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If the object is not a measured record a caption reads. |
Source code in src/visualdynamics/project.py
2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 | |
field_limit
¶
field_limit(sources: Any, records: Sequence[int] | None = None, *, statistic: str = 'tolerance', coverage: float = COVERAGE, confidence: float = CONFIDENCE, k: float | None = None, sigma_db: float | None = None, band: tuple[float, float] | None = None, max_overshoot_db: float = OVERSHOOT_DB, rms: str = 'exceed', max_breakpoints: int | None = MAX_BREAKPOINTS, progress: Any = None) -> Any
The statistical limit over a set of measured PSDs or SRSs and
the straight-line envelope over it (core.field_limit.derive),
without adding anything to the project.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sources
|
str, object, or list
|
One PSD or SRS by name or as the object (its records are the set), a list of them (every record of each), or a list of (name, record) pairs. |
required |
records
|
sequence of int
|
With one source, the records that make the set. |
None
|
statistic
|
str
|
As |
'tolerance'
|
coverage
|
str
|
As |
'tolerance'
|
confidence
|
str
|
As |
'tolerance'
|
k
|
str
|
As |
'tolerance'
|
sigma_db
|
str
|
As |
'tolerance'
|
band
|
str
|
As |
'tolerance'
|
max_overshoot_db
|
float
|
As |
OVERSHOOT_DB
|
rms
|
float
|
As |
OVERSHOOT_DB
|
max_breakpoints
|
float
|
As |
OVERSHOOT_DB
|
progress
|
callable
|
Called with |
None
|
Returns:
| Type | Description |
|---|---|
EnvelopeFit
|
The envelope, its |
Source code in src/visualdynamics/project.py
derive_specification
¶
derive_specification(sources: Any, records: Sequence[int] | None = None, *, statistic: str = 'tolerance', coverage: float = COVERAGE, confidence: float = CONFIDENCE, k: float | None = None, sigma_db: float | None = None, band: tuple[float, float] | None = None, max_overshoot_db: float = OVERSHOOT_DB, rms: str = 'exceed', max_breakpoints: int | None = MAX_BREAKPOINTS, margin_db: float = 0.0, dof: str | None = None, name: str | None = None, progress: Any = None) -> str
Write the specification a set of measured PSDs or SRSs gives
(Derive Specification): the limit over the set, the
straight-line envelope over the limit, and margin_db added,
as a Specification at the breakpoints for PSDs or a
ShockSpecification for SRSs (EnvelopeFit.specification).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sources
|
Any
|
|
required |
records
|
Any
|
|
required |
statistic
|
Any
|
|
required |
coverage
|
Any
|
|
required |
confidence
|
Any
|
|
required |
k
|
Any
|
|
required |
sigma_db
|
Any
|
|
required |
band
|
tuple[float, float] | None
|
As |
None
|
max_overshoot_db
|
tuple[float, float] | None
|
As |
None
|
rms
|
tuple[float, float] | None
|
As |
None
|
max_breakpoints
|
tuple[float, float] | None
|
As |
None
|
margin_db
|
float
|
Decibels added to every breakpoint, on the set's convention (10 log10 for a PSD, 20 log10 for an SRS). |
0
|
dof
|
str
|
The DOF the specification is written at; the set's own when it has one. |
None
|
name
|
str
|
What to call it; the first source's name followed by 'Derived Specification' when omitted. |
None
|
progress
|
callable
|
Called with |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name it was added under, unique within the project (a name already taken gets a numbered suffix). |
Source code in src/visualdynamics/project.py
2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 | |
compute_octave
¶
Integrate a spectrum onto proportional octave bands (Compute Octave Bands). A specification's warning and abort limits are banded the same way.
The total power is unchanged; it is only arranged in bands, the way such a spectrum is usually read.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
per_octave
|
int
|
Bands per octave. Defaults to |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
make_realizable
¶
make_realizable(source: Any, *, name: str | None = None, tolerance: float | None = None, keep_diagonal: bool = True, progress: Any = None) -> str
Repair a cross-spectral matrix to the nearest realizable one (Make Realizable in the Realizability reading), and add the result beside it.
At every line where the matrix is not Hermitian and positive
semi-definite, so that no set of signals has it, the nearest
matrix that is replaces it (Psd.made_realizable); the lines
that pass are unchanged. Holding the diagonal, the default, the
autospectra stay exactly as written and only the cross terms
move. Psd.realizability on the source says what moved and by
how much.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The CSD or specification, by name or as the object itself. |
required |
name
|
str
|
What to call the result. Defaults to the source's name followed by 'Realizable'. |
None
|
tolerance
|
float
|
How far below zero the smallest eigenvalue of the coherence
matrix may lie, as a fraction of the largest;
|
None
|
keep_diagonal
|
bool
|
Hold the autospectra where they are. |
True
|
progress
|
callable
|
Called with |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the object has no cross terms or its matrix is incomplete, if no line could be judged, or if it is realizable already, in which case there is nothing to repair. |
Source code in src/visualdynamics/project.py
2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 | |
compute_frfs
¶
Compute frequency response functions from a time history (Compute FRFs), one for each response and drive, over the frames a PSD uses.
The three estimators differ only in where the noise is assumed to be. The method is put in the result's name, since two FRF sets from one history differ in nothing else a reader can see.
If the history has no averaging set, the frames are detected the same way the coherence detects them, so the FRFs and the coherence come from the same frames. The detected averaging is stored on the history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
method
|
str
|
Which estimator: 'Hv', 'H1' or 'H2'. |
'Hv'
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
read_transmissibility
¶
The ASD-ratio transmissibility behind one record of an FRF, beside its H1, with H1's coherence and random error.
The FRF must have been computed in this project from a time
history (Compute FRFs), against one reference. The reading is
made from that history, for the record's response and reference,
with the averaging the FRF was computed with (averaging_of),
so it is of the frames the FRF was. Its H1 is the H1 of that
pair whichever estimator the FRF used; the ratio, the coherence
and the error are what TimeHistory.read_transmissibility says.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The FRF, by name or as the object itself. |
required |
record
|
int
|
Which record of the FRF. |
0
|
Returns:
| Type | Description |
|---|---|
TransmissibilityReading
|
H1, the ASD ratio and the coherence at every line, in SI, with the frames and the averages. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the object is not an FRF computed from a time history in this project, or it was computed against more than one reference, where a ratio of two autospectra would credit one input with what several caused. |
Source code in src/visualdynamics/project.py
2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 | |
read_partial_coherence
¶
Which drive explains each response, and whether the drives
were independent: the partial, reference and virtual coherence
(core.partial_coherence).
name is a time history, read against its reference channels
with its own averaging, or a multiple coherence computed in this
project (Compute Multiple Coherence), read from its history with
the averaging it was computed with (averaging_of), so the
reading's multiple coherence is that object's.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The time history or the multiple coherence, by name or as the object itself. |
required |
progress
|
callable
|
Called with |
None
|
Returns:
| Type | Description |
|---|---|
PartialCoherence
|
Every response against every reference, at every line. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the object is neither, or the history has no reference or no response channels, or no more averages than references. |
Source code in src/visualdynamics/project.py
compute_multiple_coherence
¶
Compute the multiple coherence from a time history (Compute Multiple Coherence): how much of each response the drives account for.
It is averaged over frames. If the history has no averaging set, the frames are detected and stored on the history. Computed from the whole record as one frame, the drives would fit every response exactly and the coherence would be 1.0 at every line, which says nothing about the measurement.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
compute_srs
¶
compute_srs(source: Any, *, per_octave: int | None = None, q: float | None = None, kind: str = 'maximax') -> str
Compute shock response spectra from a time history's shocks (Compute SRS), one curve per channel per event.
The events are the ones marked on the history. They are detected, and marked on the history, only when it has no shocks marked and no averaging set and is not a transient specification. A record read as frames already says where its events are (in a transient run each playing is one frame), and a specification is one playing by definition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
per_octave
|
int
|
Natural-frequency lines per octave. Defaults to 12. |
None
|
q
|
float
|
The oscillator amplification, Q = 1/(2ζ). Defaults to 10 (5% damping), the usual value for shock tests. |
None
|
kind
|
str
|
Which peak each oscillator reports: 'maximax' (largest magnitude of either sign), 'positive' or 'negative'. |
'maximax'
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
detect_shocks
¶
Find the events in a time history and mark them on it (Detect in the shock view). Returns how many were found.
Any events already marked are replaced. Mark the events on the
recording before filtering it: every object derived from the
recording then carries them, because core.filters copies the
marks onto what it makes. compute_srs detects events only when
a record has none, so if the filtered record were the first to
be detected, the recording itself would be left unmarked.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
Returns:
| Type | Description |
|---|---|
int
|
How many events were found and marked on the record. |
Source code in src/visualdynamics/project.py
filter_data
¶
Filter a time history with its own filter settings (Apply Filter in the filter view), every channel at zero phase so the peaks stay where they are.
The settings are the history's filtering, set in the filter
view as a low-, high- or band-pass. When none is set, the
suggested low-pass (a tenth of the sample rate, order 4) is
stored on the history and used, the way compute_frfs uses a
suggested averaging, so this works before the filter view has
been opened.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
resample
¶
Take a time history to a lower sample rate (Apply Resample in the resample view) and add the result beside it.
Every channel goes through the zero-phase anti-alias low-pass
and then every q-th sample is kept (TimeHistory.resample,
which says what the filter is). The resample view shows what
the resampling does to a channel's spectrum before it is made.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The time history, by name or as the object itself. |
required |
rate
|
float
|
The new sample rate, in Hz, a whole division of the record's. |
required |
anti_alias
|
bool
|
Filter before decimating. |
True
|
order
|
int
|
The anti-alias filter's design order,
|
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
truncate_data
¶
Cut a time history to its truncation span (Apply Truncation in the truncate view): every channel between start and stop, on the record's original clock.
The span is the history's truncation, set in the truncate
view. Unlike filter_data, there is no suggested value to fall
back on, because the only neutral span is the whole record and
keeping all of it changes nothing. With no span set this raises
ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
integrate
¶
Integrate a time history once (Integrate): acceleration channels become velocity, and velocity channels become displacement.
The whole record is integrated, never the shock windows alone;
core.filters gives the reasons. The drift corner is stored in
the result's provenance, so a refresh uses the same one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
drift_corner
|
float or None
|
High-pass corner in Hz applied after integration, so that a
sensor bias does not become a ramp. |
...
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
differentiate
¶
Differentiate a time history once (Differentiate): displacement channels become velocity, and velocity channels become acceleration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
compute_cpsds
¶
Compute the full cross-spectral matrix from a time history's averages (Compute CPSDs), every channel against every channel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The object to read, by name or as the object itself. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
transform
¶
transform(source: Any, shapes: Any, *, records: Sequence[int] | None = None, name: str | None = None) -> str
Transform a record's channels through a shape set to modal
coordinates (Transform to Modal Coordinates), one record per mode
and quantity at M1 … Mn.
The motions are transformed as q = Φ⁺u and the forces as
Φᵀf. It is a change of coordinates only: the set's
frequencies, damping and masses are not used (for the response
a mode makes to forces, see compute_modal_responses). Any shape
set can be used; with the six rigid-body shapes of a
geometry this is the virtual point transformation. The result is
linked into the record's group when a shape set there has every
mode it names, and is otherwise in no group. Its provenance
names both the record and the shape set, and its
transform_report says what was shared, what was dropped and
what was left unexplained. A source that is not a data object,
or shapes that is not a shape set, raises TypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The time history, by name or as the object itself. |
required |
shapes
|
str or object
|
The shape set to transform through, by name or as the object. |
required |
records
|
sequence of int
|
Which of the record's channels to use, the ones picked in the tree. All of them when omitted. |
None
|
name
|
str
|
What to call the result. Defaults to the record's name followed by 'Modal Coordinates'. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
expand
¶
expand(source: Any, shapes: Any, *, records: Sequence[int] | None = None, name: str | None = None) -> str
Expand modal responses through a shape set back to physical
responses (Expand to Physical Responses): u = Φq at every DOF
the shape set covers.
The result is linked into the shape set's group, so it animates on that group's geometry. Expanding some of the modes gives their contribution alone, and the result's name lists them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The modal time history, by name or as the object itself. |
required |
shapes
|
str or object
|
The shape set it was transformed through, by name or as the object. |
required |
records
|
sequence of int
|
Which modal records to expand, the modes picked in the tree. All of them when omitted. |
None
|
name
|
str
|
What to call the result. Defaults to the record's name with 'Modal Coordinates' replaced by 'Physical Responses', and the modes listed in parentheses when not all of them are used. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
author_specification
¶
author_specification(source: Any, draft: Any, *, name: str | None = None, replace: bool = False) -> str
Write a specification from a sheet (Make Specification in the Specification reading) and add it beside the object the sheet was opened on.
The sheet gives autospectra at breakpoints, each cross term as a coherence and phase, and the limit bands in decibels. It can be opened on a shape set (the specification is then at the set's modal coordinates, ready to expand through it), on a channel table (at its control channels) or on a specification. A pair the sheet does not state is left out of the result; nothing is assumed for it.
With replace, the sheet is written into the specification it
was opened from, under that specification's name, so its links
and report slots still hold. A sheet that spans several
specifications is written into each of them. A sheet holding
every channel of a specification replaces it in the sheet's
form, with the sheet's breakpoints or lines. A sheet holding some
of the channels is merged back at the specification's own lines,
and the other channels are unchanged. Replacing an object that
is not a specification raises TypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str, object, or list of str
|
The object the sheet was opened on, by name or as the object, or the specifications' names when the sheet spans several. |
required |
draft
|
SpecificationDraft or dict
|
What the author stated ( |
required |
name
|
str
|
What to call the result. Defaults to the source's name followed by 'Specification'. |
None
|
replace
|
bool
|
Write the sheet into |
False
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the
project (a name already taken gets a numbered suffix). With
|
Source code in src/visualdynamics/project.py
3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 | |
generate_rigid_body_modes
¶
Generate the six rigid-body mode shapes of a geometry (Generate Rigid Body Mode Shapes): three translations and three rotations about its reference point, as a shape set in the geometry's group.
The reference point, and the mass and inertia that
mass-normalize the shapes, are the geometry's mass_properties,
set in the rigid-body view. When none are set, unit shapes about
the centroid are used, which is the case the virtual point
transformation needs most often. Those properties are then
stored on the geometry, so the result's provenance records what
was used. An object that is not a geometry raises TypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
name
|
str
|
What to call the result. Defaults to the geometry's name followed by 'Rigid Body Modes'. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
generate_signal
¶
generate_signal(source: Any, kind: str = 'random', *, name: str | None = None, progress: Any = None, **settings: Any) -> str
Generate a reference signal from a spectrum, a sine specification, a shock specification or a channel table (Generate Signal), as a time history in the source's group.
A spectrum gives random, burst random or periodic random at its
DOFs, drawn to it; a sine specification gives its tone; a shock
specification gives a shock synthesized to its spectrum and
checked against the shaker's shock ratings given
(core.shock_synthesis); a channel table gives the random kinds
at its reference channels, to a typed flat band and level,
or an impulse or a classical pulse (core.signals). The
settings are recorded with the result, and the random seed with
them (one is drawn when none is given), so Recompute makes the
same record again.
project.generate_signal('Requirement', 'srs',
sample_rate=20480.0, stroke=0.0508,
velocity=1.78)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The spectrum, sine specification, shock specification or channel table, by name or as the object itself. |
required |
kind
|
str
|
One of |
'random'
|
name
|
str
|
What to call the result. Defaults to the source's name and the kind. |
None
|
progress
|
callable
|
Called with |
None
|
**settings
|
Any
|
The fields of |
{}
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If a setting is not one |
ValueError
|
If the kind is not one the source makes, or as the signal's generator refuses (a band at or above the Nyquist frequency, units not declared, no reference channel, a shock spectrum no synthesis meets or no synthesis the shaker can hold). |
Source code in src/visualdynamics/project.py
3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 | |
compute_modal_responses
¶
compute_modal_responses(source: Any, shapes: Any, *, quantity: str = 'acceleration', modes: Sequence[int] | None = None, records: Sequence[int] | None = None, name: str | None = None) -> str
Compute how each mode of a shape set answers the forces in a time history or a force CPSD, as a new object (Compute Modal Responses).
The history's force channels are made modal through the set
(pᵣ = Σ φₖᵣ fₖ; channels already holding the set's modal forces
are used as they are), and each mode's equation is solved
exactly for a force linear between samples, from rest
(core.modal_response). The result holds one record per mode,
M1 … Mn, each comment naming the set, on the history's time
axis with its averaging and shock windows. It is linked into the
history's group, and the history itself is not changed; merge
puts the forces and the responses back in one object.
A force CPSD is made modal the same way, S_pp = Φᵀ S_ff Φ, and
each mode answers it through its own frequency response, giving
the modal response CPSD with every picked mode against every
other (core.modal_response.modal_response_density). The CPSD
needs every cross term between the drives, as Transform does;
terms stored as zero, drives that are uncorrelated, are terms.
expand takes the result to the set's DOFs, where it is the
response density the synthesized FRFs give.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The time history or force CPSD, by name or as the object itself. |
required |
shapes
|
str or object
|
The shape set: real modes with frequency, damping and modal mass, by name or as the object itself. |
required |
quantity
|
str
|
'displacement', 'velocity' or 'acceleration' of each modal coordinate. |
'acceleration'
|
modes
|
sequence of int
|
Which modes, by index in the set from zero; all of them when omitted. |
None
|
records
|
sequence of int
|
Which of the source's records are the forces; every force record when omitted. |
None
|
name
|
str
|
What to call the result. Defaults to the source's name followed by 'Modal Responses'. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
As |
Source code in src/visualdynamics/project.py
3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 | |
merge_coincident_nodes
¶
merge_coincident_nodes(source: Any, tolerance: float | None = None, groups: Sequence[int] | None = None, exclude: Sequence[int] | None = None) -> dict
Merge each set of a geometry's coincident nodes into one node (Merge Coincident Nodes). Elements are reconnected to the lowest node id at each point, and the other nodes are removed.
Plates are connected only where they share nodes, so this is what ties together planes meshed separately, along the lines where they meet.
With groups, only the nodes used by those element groups'
elements are merged. The app offers the merge only on element
groups picked in the tree, never on the whole geometry, because
merging every coincident node in a model ties together parts
that were meant to stay separate. With groups left out, the
whole geometry is merged.
While an object linked with the geometry names a node the merge would remove, the merge raises ValueError, since that object's data would refer to a node that no longer exists. Merge first, then measure or solve. An object that is not a geometry raises TypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
tolerance
|
float
|
How close two nodes must be to be merged, in meters (the geometry holds its coordinates in meters). Defaults to a millionth of the diagonal of the geometry's extent. |
None
|
groups
|
sequence of int
|
The element groups whose nodes are merged, by id. Every node of the geometry when omitted. |
None
|
exclude
|
sequence of int
|
Nodes left out of the merge, by id: the places deselected in the app's pane before Merge was pressed. |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
'merged', the nodes removed, 'into', the nodes they became,
'duplicates', the elements removed for filling a cell another
already filled, and 'links', the line elements removed for
joining nodes that became one ( |
Source code in src/visualdynamics/project.py
3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 | |
align_meshes
¶
align_meshes(source: Any, reach: float | None = None, groups: Sequence[int] | None = None, exclude: Sequence[int] | None = None) -> dict
Move the coarser mesh's nodes onto the finer mesh's nodes where parts meshed separately meet or overlap (Align Meshes), so Merge Coincident Nodes can join them next.
Each node of the coarser piece within reach of the finer
piece's surface is moved onto its nearest node there
(Geometry.align_moves). The app offers this on element groups
picked in the tree, as it does the merge. While an object linked
with the geometry names a node that would move, this raises
ValueError, since that object's data was measured or solved
where the node was.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
reach
|
float
|
How far a node may move, in meters (the geometry holds its
coordinates in meters). Defaults to half the coarsest piece's
spacing ( |
None
|
groups
|
sequence of int
|
The element groups whose pieces are aligned, by id. Every element of the geometry when omitted. |
None
|
exclude
|
sequence of int
|
Nodes left out, by id: the moves deselected in the app's pane before Align was pressed, both nodes of each. |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
'moved', how many nodes moved; 'farthest', the longest move, in meters. |
Source code in src/visualdynamics/project.py
new_geometry
¶
Add an empty geometry to build a model in (the project's +
button). Its parts are added as solids (add_solid_plate,
add_solid_block and the rest) and meshed with mesh_solids,
and links in the app's add mode.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
What to call it. |
'Geometry'
|
unit
|
str
|
Its length unit. Coordinates are held in SI either way; the geometry records this as the unit it was built in. |
'm'
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
new_channel_table
¶
Add an empty channel table to fill in by hand (the project's
New Channel Table). Channels are added with add_channels, and
their cells are typed in the app or set with set_cell.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
What to call it. |
'Channel Table'
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
add_channels
¶
Add blank channels to a channel table, numbered on from its highest channel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or ChannelTable
|
The channel table, by name or as the object itself. |
required |
count
|
int
|
How many channels to add. |
1
|
Returns:
| Type | Description |
|---|---|
list of int
|
The new channels' numbers. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the object is not a channel table. |
Source code in src/visualdynamics/project.py
set_view
¶
set_view(source: Any, view: View | None = None) -> None
Set the view a geometry opens on in 3-D, in the app, the report and every exported figure.
In the app, Set Default View captures the view on screen; from a
script the view is given, for example a model built Y-up seen
from the front and above. Everything drawn on the geometry (its
shapes, an ODS, the DOF arrows) opens on this view too, and Reset
View returns to it. The nodes are not rotated; only the viewing
direction changes. An object that is not a geometry, or a view
that is not a View, raises TypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or Geometry
|
The geometry, by name or as the object itself. |
required |
view
|
View
|
Where the eye is, seen from the model's center, and which way is up. None returns to the default isometric view (from +X+Y+Z, Z up). |
None
|
Returns:
| Type | Description |
|---|---|
None
|
|
Examples:
>>> from visualdynamics import View
>>> project.set_view('BARC', View(eye=(1, 1, -1), up=(0, 1, 0)))
Source code in src/visualdynamics/project.py
tie_elements
¶
Tie a patch of a geometry's elements rigidly to the part under it (Tie), as for a bolted joint modeled from the elements its washer covers.
Each node of the patch is joined by a rigid, massless link to the
nearest node of to (mesh.tie).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
elements
|
sequence of int
|
The patch, by element id. |
required |
to
|
str, int or sequence of int
|
An element group, by name or id, or a second patch, by element ids. |
required |
group
|
str
|
The element group the links go into, made rigid if new. Defaults to the geometry's first rigid element group, or a new one named 'ties'. |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
'links', how many were added; 'shared', patch nodes the target already holds; 'group', where the links went. |
Source code in src/visualdynamics/project.py
merge_groups
¶
Merge a geometry's element groups into one (Merge Element Groups). The first group keeps its id, name and properties, and the other groups' elements move into it.
The merge is refused unless the groups hold the same element
types and have the same material and thickness or section
(Geometry.merge_refusal).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
groups
|
sequence of int
|
The element groups, by id; the first is the one kept. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
'into', the element group kept; 'groups', how many merged into it; 'elements', how many elements moved. |
Source code in src/visualdynamics/project.py
add_solid_block
¶
add_solid_block(source: Any, center: Any, widths: Any, angles: Any = (0.0, 0.0, 0.0), name: str = '', *, corner: float = 0.0, unit: str = 'm') -> int
Add a block to a geometry's solids (core.solids). A solid is
a shape to build a part from and mesh later; it adds no elements.
The block is widths across along its own axes, centered at
center and rotated by angles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
center
|
array_like
|
Three numbers each, in |
required |
widths
|
array_like
|
Three numbers each, in |
required |
angles
|
array_like
|
Degrees about the geometry's X, then Y, then Z axes. |
(0, 0, 0)
|
name
|
str
|
What to call it. |
''
|
corner
|
float
|
The radius its four edges along its own Z are rounded to, in
|
0
|
unit
|
str
|
The unit the lengths are in. A geometry whose units are not defined takes them as given. |
'm'
|
Returns:
| Type | Description |
|---|---|
int
|
The solid's id. |
Source code in src/visualdynamics/project.py
add_solid_cylinder
¶
add_solid_cylinder(source: Any, center: Any, radius: float, length: float, angles: Any = (0.0, 0.0, 0.0), name: str = '', *, unit: str = 'm') -> int
Add a cylinder to a geometry's solids (core.solids), of
radius about its own axis and length along it, centered at
center.
With no angles its axis is the geometry's Z. A cylinder
subtracted from a part (combine_solids) makes a hole.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
center
|
array_like
|
Three numbers, in |
required |
radius
|
float
|
In |
required |
length
|
float
|
In |
required |
angles
|
array_like
|
Degrees about the geometry's X, then Y, then Z axes. |
(0, 0, 0)
|
name
|
str
|
What to call it. |
''
|
unit
|
str
|
The unit the lengths are in. A geometry whose units are not defined takes them as given. |
'm'
|
Returns:
| Type | Description |
|---|---|
int
|
The solid's id. |
Source code in src/visualdynamics/project.py
add_solid_cone
¶
add_solid_cone(source: Any, center: Any, base_radius: float, top_radius: float, height: float, angles: Any = (0.0, 0.0, 0.0), name: str = '', *, unit: str = 'm') -> int
Add a cone to a geometry's solids (core.solids.add_cone): a
frustum height along its own axis, base_radius at its base
and top_radius at its top, either zero for a point, centered at
center.
With no angles its axis is the geometry's Z, its base below.
Bricks are fitted to it, since no sweep makes a cone.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
center
|
array_like
|
Three numbers, in |
required |
base_radius
|
float
|
In |
required |
top_radius
|
float
|
In |
required |
height
|
float
|
In |
required |
angles
|
array_like
|
Degrees about the geometry's X, then Y, then Z axes. |
(0, 0, 0)
|
name
|
str
|
What to call it. |
''
|
unit
|
str
|
The unit the lengths are in. A geometry whose units are not defined takes them as given. |
'm'
|
Returns:
| Type | Description |
|---|---|
int
|
The solid's id. |
Source code in src/visualdynamics/project.py
add_solid_sphere
¶
add_solid_sphere(source: Any, center: Any, radius: float, name: str = '', *, unit: str = 'm') -> int
Add a sphere to a geometry's solids (core.solids.add_sphere),
radius about center. Bricks are fitted to it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
center
|
array_like
|
Three numbers, in |
required |
radius
|
float
|
In |
required |
name
|
str
|
What to call it. |
''
|
unit
|
str
|
The unit the lengths are in. A geometry whose units are not defined takes them as given. |
'm'
|
Returns:
| Type | Description |
|---|---|
int
|
The solid's id. |
Source code in src/visualdynamics/project.py
add_solid_plate
¶
add_solid_plate(source: Any, center: Any, widths: Any, angles: Any = (0.0, 0.0, 0.0), name: str = '', *, unit: str = 'm') -> int
Add a plate to a geometry's solids (core.solids.add_plate): a
flat rectangle widths across along its own X and Y, centered at
center.
With no angles it lies in the geometry's XY plane. A plate has
no thickness of its own: it is meshed into plates (mesh_solids
with shells), and their element group takes the thickness. A
cylinder subtracted from it (combine_solids) makes a hole.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
center
|
array_like
|
Three numbers, in |
required |
widths
|
array_like
|
Two numbers, in |
required |
angles
|
array_like
|
Degrees about the geometry's X, then Y, then Z axes. |
(0, 0, 0)
|
name
|
str
|
What to call it. |
''
|
unit
|
str
|
The unit the lengths are in. A geometry whose units are not defined takes them as given. |
'm'
|
Returns:
| Type | Description |
|---|---|
int
|
The solid's id. |
Source code in src/visualdynamics/project.py
add_solid_disk
¶
add_solid_disk(source: Any, center: Any, radius: float, angles: Any = (0.0, 0.0, 0.0), name: str = '', *, unit: str = 'm') -> int
Add a disk to a geometry's solids (core.solids.add_disk): a
flat circle of radius in its own XY plane, centered at
center.
With no angles it lies in the geometry's XY plane. As a
plate's, its thickness is set on the element group it is meshed
into (mesh_solids with shells).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
center
|
array_like
|
Three numbers, in |
required |
radius
|
float
|
In |
required |
angles
|
array_like
|
Degrees about the geometry's X, then Y, then Z axes. |
(0, 0, 0)
|
name
|
str
|
What to call it. |
''
|
unit
|
str
|
The unit the lengths are in. A geometry whose units are not defined takes them as given. |
'm'
|
Returns:
| Type | Description |
|---|---|
int
|
The solid's id. |
Source code in src/visualdynamics/project.py
add_solid_section
¶
add_solid_section(source: Any, shape: str, center: Any, dimensions: Any, length: float, angles: Any = (0.0, 0.0, 0.0), name: str = '', *, unit: str = 'm') -> int
Add a structural section to a geometry's solids
(core.solids.add_section): an I-beam, channel, tee, angle,
rectangular tube or round tube, length along its own axis.
It is sized by its own dimensions, which edit_solid can change
later.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
shape
|
str
|
One of |
required |
center
|
array_like
|
Three numbers, in |
required |
dimensions
|
sequence of float
|
In |
required |
length
|
float
|
In |
required |
angles
|
array_like
|
Degrees about the geometry's X, then Y, then Z axes. With none it runs along Z. |
(0, 0, 0)
|
name
|
str
|
What to call it. |
''
|
unit
|
str
|
The unit the lengths are in. A geometry whose units are not defined takes them as given. |
'm'
|
Returns:
| Type | Description |
|---|---|
int
|
The solid's id. |
Source code in src/visualdynamics/project.py
add_solid_hole
¶
add_solid_hole(source: Any, center: Any, diameter: float, depth: float | None = None, angles: Any = (0.0, 0.0, 0.0), name: str = '', *, counterbore: Any = None, unit: str = 'm') -> int
Add a hole to a geometry's solids (core.solids.add_hole), to
be subtracted from a part with combine_solids.
The hole enters at center and runs depth along its own -Z,
or through the part it is cut from when depth is None. A
counterbore makes it wider at the entry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
center
|
array_like
|
Where it enters, three numbers in |
required |
diameter
|
float
|
In |
required |
depth
|
float
|
In |
None
|
angles
|
array_like
|
Degrees about the geometry's X, then Y, then Z axes. With none it runs down Z. |
(0, 0, 0)
|
name
|
str
|
What to call it. |
''
|
counterbore
|
(float, float)
|
Its diameter and depth, in |
None
|
unit
|
str
|
The unit the lengths are in. A geometry whose units are not defined takes them as given. |
'm'
|
Returns:
| Type | Description |
|---|---|
int
|
The solid's id. |
Source code in src/visualdynamics/project.py
delete_elements
¶
Delete a geometry's elements and the nodes only they used,
except nodes where data in the project is measured or solved
(Geometry.delete_elements).
Deleting a meshed part's bricks removes its nodes, while deleting a test geometry's panels leaves its measurement points.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
ids
|
sequence of int
|
The elements, by id. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
'elements' and 'nodes', how many were deleted. |
Source code in src/visualdynamics/project.py
delete_element_groups
¶
Delete a geometry's element groups with their elements and the
nodes only they used, except nodes where data in the project is
measured or solved (Geometry.delete_groups).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
ids
|
sequence of int
|
The element groups, by id. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
'groups', 'elements' and 'nodes', how many were deleted. |
Source code in src/visualdynamics/project.py
edit_solid
¶
edit_solid(source: Any, solid_id: int, *, center: Any = None, widths: Any = None, angles: Any = None, radius: Any = None, length: Any = None, corner: Any = None, counts: Any = None, spacing: Any = None, dimensions: Any = None, name: Any = None, top_radius: Any = None, unit: str = 'm') -> None
Change a solid after it is made (core.solids.edit). Anything
not given is kept.
The values that can be changed are a block's center, widths, angles and corner; a cylinder's center, radius, length and angles; a cone's center, radius (at its base), top radius, length (its height) and angles; a sphere's center and radius; a plate's center, widths and angles; a disk's center, radius and angles; a section's center, dimensions, length and angles; a hole's center, dimensions and angles; a pattern's counts and spacing; and any solid's name. A boolean the solid is part of changes with it. A mesh made from it does not, until Mesh Solids meshes it again.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
solid_id
|
int
|
Which solid. |
required |
center
|
optional
|
As |
None
|
widths
|
optional
|
As |
None
|
angles
|
optional
|
As |
None
|
radius
|
optional
|
As |
None
|
length
|
optional
|
As |
None
|
corner
|
optional
|
As |
None
|
name
|
optional
|
As |
None
|
counts
|
optional
|
As |
None
|
spacing
|
optional
|
As |
None
|
top_radius
|
float
|
A cone's, in |
None
|
dimensions
|
sequence of float
|
A section's, as |
None
|
unit
|
str
|
The unit the lengths are in. A geometry whose units are not defined takes them as given. |
'm'
|
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in src/visualdynamics/project.py
move_solids
¶
move_solids(source: Any, ids: Any, offset: Any = (0.0, 0.0, 0.0), turn: Any = (0.0, 0.0, 0.0), *, unit: str = 'm') -> int
Move whole solids (core.solids.move): a part and every solid
it is made of, rotated by turn about the center of their extent
and then translated by offset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
ids
|
sequence of int
|
The solids, by id. |
required |
offset
|
array_like
|
The translation, in |
(0, 0, 0)
|
turn
|
array_like
|
Degrees about the geometry's X, then Y, then Z axes. |
(0, 0, 0)
|
unit
|
str
|
The unit the offset is in. A geometry whose units are not defined takes it as given. |
'm'
|
Returns:
| Type | Description |
|---|---|
int
|
How many primitive solids moved (blocks, cylinders, sections and holes). |
Source code in src/visualdynamics/project.py
combine_solids
¶
Add a boolean of a geometry's solids: 'union', 'subtract' (the others subtracted from the first) or 'intersect'.
The solids combined become part of the new solid, and only the new solid is listed as a part. A solid already part of another boolean is refused.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
operation
|
str
|
'union', 'subtract' or 'intersect'. |
required |
ids
|
sequence of int
|
Two or more solids, by id, in order. |
required |
name
|
str
|
What to call it. Defaults to the first solid's name. |
''
|
Returns:
| Type | Description |
|---|---|
int
|
The new solid's id. |
Source code in src/visualdynamics/project.py
reorder_solids
¶
Put a geometry's solids in a new order (a drag in the tree):
its parts, or with within one boolean's own solids. A
subtraction cuts every solid after its first from the first, so
the order decides what is cut (core.solids.reorder).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
ids
|
sequence of int
|
Every one of the solids being ordered, in the new order. |
required |
within
|
int
|
The boolean or pattern whose solids these are; the parts when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
None
|
The geometry is changed in place. |
Source code in src/visualdynamics/project.py
copy_solids
¶
Copy a geometry's solids, recipe and all, into the same geometry or another (Copy and Paste on solid rows). Returns the new top-level ids.
A boolean or a pattern is copied with every solid it is made of
(core.solids.copy), so the copy is edited on its own. A named
solid's copy is '
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry the solids are in, by name or as the object. |
required |
ids
|
sequence of int
|
The solids, by id. |
required |
into
|
str or object
|
The geometry the copies go into; the same one when omitted. Both geometries hold their coordinates the same way, with units defined or not, or the copy is refused. |
None
|
Returns:
| Type | Description |
|---|---|
list of int
|
The new solids' ids, in the order of |
Source code in src/visualdynamics/project.py
pattern_solids
¶
Pattern a geometry's solids in rows, columns and layers
(Pattern): counts along X, Y and Z, the originals included,
spacing apart.
The pattern is one solid made from the originals
(core.solids.pattern), so changing an original changes every
copy. Its counts and spacing are changed with edit_solid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
ids
|
sequence of int
|
The solids to copy, by id. |
required |
counts
|
sequence of int
|
How many along X, Y and Z. |
required |
spacing
|
sequence of float
|
How far apart along X, Y and Z, in |
required |
unit
|
str
|
The unit the spacing is in. A geometry whose units are not defined takes it as given. |
'm'
|
Returns:
| Type | Description |
|---|---|
int
|
The pattern's id. |
Source code in src/visualdynamics/project.py
mesh_solids
¶
mesh_solids(source: Any, ids: Any, size: float | None = None, *, unit: str = 'm', apart: bool = False, parts_apart: bool = False, elements: str = 'hexes', progress: Any = None, sizes: Any = None) -> dict
Mesh a geometry's solids into bricks, tetrahedra or shells (Mesh Solids). Each part becomes an element group named for it.
With elements 'hexes', parts that are an extrusion along X, Y
or Z are meshed on one grid cut at every flat face, with their
holes rounded (core.solids.extrusion_mesh); a union that is
no extrusion in pieces, each operand swept where it is one and
fitted where it is not, at its own size, joined where the
grids meet and tied at the seams where they do not; and any
other shape on a grid fitted to it (core.hexmesh.overlay_mesh);
core.solids.brick_mesh picks. With 'tetras', the parts are
meshed into ten-node tetrahedra from their recipe's signed
distance (core.tetmesh.tet_mesh). With 'quads' or 'triangles'
they are meshed into shells (core.shells.shell_mesh): a plate
or a disk, with what is cut from it, on its plane, and a solid
with a volume on its outer surface, the surface of its bricks
for quads and of its tetrahedra for triangles; the thickness is
set on the element group. A plate or a disk is meshed into
shells only. Parts
meshed together share nodes where they touch. The solids are
kept so they can be meshed again, and a part meshed again
replaces its earlier mesh: the elements in the element group of
its name are deleted, and the group and its material are kept.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
ids
|
sequence of int
|
The parts, by id: solids no other solid uses. |
required |
size
|
float
|
The target element size, in |
None
|
unit
|
str
|
The unit the size is in. A geometry whose units are not defined takes it as given. |
'm'
|
apart
|
bool
|
Join the bricks only to nodes of their own element groups
( |
False
|
parts_apart
|
bool
|
Give each part meshed here its own nodes where the parts touch each other. They are still on one grid, so their nodes coincide and can be merged later where bolts go. Bricks only. |
False
|
elements
|
('hexes', 'tetras', 'quads', 'triangles')
|
The element type, as the tree names the families; 'bricks' and 'tets' are taken to mean the same. 'quads' and 'triangles' are shells. |
'hexes'
|
progress
|
callable
|
Called with |
None
|
sizes
|
mapping of int to float
|
A size per piece of a union meshed in pieces, by solid id,
in |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
For bricks, what |
Source code in src/visualdynamics/project.py
4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 | |
detect_mated_surfaces
¶
detect_mated_surfaces(source: Any, groups: Any = None, tolerance: float | None = None, *, unit: str = 'm') -> list[dict]
The patches where element groups' surfaces mate
(core.mates.detect): the nodes on one group's outer faces that
lie on another's, within tolerance, one patch per connected
piece. The finer side is the first, and follows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
groups
|
sequence of int or str
|
The element groups, by id or name; every group of plates or solids when omitted. |
None
|
tolerance
|
float
|
How far a node may be from the other's faces, in |
None
|
unit
|
str
|
The unit the tolerance is in. |
'm'
|
Returns:
| Type | Description |
|---|---|
list of dict
|
Each patch's 'groups' (first side's and second side's ids), 'nodes_a' and 'nodes_b'. |
Source code in src/visualdynamics/project.py
add_mated_surfaces
¶
add_mated_surfaces(source: Any, groups: Any, nodes_a: Any, nodes_b: Any, *, normal_mode: str = 'rigid', shear_mode: str = 'rigid', normal_stiffness: float = 0.0, shear_stiffness: float = 0.0, name: str | None = None) -> int
Join two element groups where their surfaces mate (Mate
Surfaces): when a model is built, each of nodes_a is tied to the
nearest of nodes_b, along the normal of the surface it lies on
and in that surface's plane, each held rigidly, by a stiffness or
not at all (fem.Model.add_tie). The set is kept on the geometry
(geometry.mates), to be edited or deleted later.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
groups
|
(int or str, int or str)
|
The first side's element group and the second's, by id or name. |
required |
nodes_a
|
sequence of int
|
The first side's nodes, which follow, and the second's. |
required |
nodes_b
|
sequence of int
|
The first side's nodes, which follow, and the second's. |
required |
normal_mode
|
('rigid', 'stiffness', 'free')
|
How the normal and the plane are held. |
'rigid'
|
shear_mode
|
('rigid', 'stiffness', 'free')
|
How the normal and the plane are held. |
'rigid'
|
normal_stiffness
|
float
|
Each node's stiffness along the normal and in the plane, in N/m, where its mode is 'stiffness'. |
0.0
|
shear_stiffness
|
float
|
Each node's stiffness along the normal and in the plane, in N/m, where its mode is 'stiffness'. |
0.0
|
name
|
str
|
What to call the set; "first on second" when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
int
|
The set's id. |
Source code in src/visualdynamics/project.py
mate_surfaces
¶
mate_surfaces(source: Any, groups: Any = None, tolerance: float | None = None, *, unit: str = 'm', normal_mode: str = 'rigid', shear_mode: str = 'rigid', normal_stiffness: float = 0.0, shear_stiffness: float = 0.0) -> list[int]
Join every patch where the element groups' surfaces mate, as
found (detect_mated_surfaces), one set each
(add_mated_surfaces).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
groups
|
sequence of int or str
|
The element groups; every group of plates or solids when omitted. |
None
|
tolerance
|
float
|
As |
None
|
unit
|
str
|
The unit the tolerance is in. |
'm'
|
normal_mode
|
str
|
As |
'rigid'
|
shear_mode
|
str
|
As |
'rigid'
|
normal_stiffness
|
str
|
As |
'rigid'
|
shear_stiffness
|
str
|
As |
'rigid'
|
Returns:
| Type | Description |
|---|---|
list of int
|
The sets' ids. None found raises ValueError. |
Source code in src/visualdynamics/project.py
edit_mated_surfaces
¶
Change a set of mated surfaces: its name, nodes_a,
nodes_b, normal_mode, shear_mode, normal_stiffness or
shear_stiffness
(core.mates.change), refused as add_mated_surfaces refuses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
mate_id
|
int
|
The set. |
required |
**fields
|
Any
|
The fields to change, stiffnesses in N/m. |
{}
|
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in src/visualdynamics/project.py
delete_mated_surfaces
¶
Delete sets of mated surfaces, by id; returns how many went.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
ids
|
sequence of int
|
The sets. |
required |
Returns:
| Type | Description |
|---|---|
int
|
|
Source code in src/visualdynamics/project.py
delete_solids
¶
Delete a geometry's solids, each with every solid it is made
of (core.solids.delete).
A solid that a boolean still uses is refused unless the boolean is deleted with it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
ids
|
sequence of int
|
The solids, by id. |
required |
Returns:
| Type | Description |
|---|---|
int
|
How many solids were deleted, the ones inside included. |
Source code in src/visualdynamics/project.py
separate_solids
¶
Take a geometry's booleans and patterns apart (Take Apart).
Each one is removed, and its operands are parts again
(core.solids.separate).
A primitive solid, or one that is still part of another, is refused.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
ids
|
sequence of int
|
The booleans or patterns, by id. |
required |
Returns:
| Type | Description |
|---|---|
int
|
How many solids are parts again. |
Source code in src/visualdynamics/project.py
solve_modes
¶
solve_modes(source: Any, *, maximum_frequency: float | None = None, num_modes: int | None = None, damping: float = 0.0, name: str | None = None, progress: Any = None) -> str
Solve the normal modes of a geometry whose element groups have properties (Solve Modes). The shapes are added in the geometry's group.
The finite element model is built from the geometry
(fem.Model.from_geometry). Each element group has a material
and a thickness or a section (fem.GroupProperties, set in the
Element Groups table or on geometry.group_properties); each
quad becomes a plate element, each triangle a triangular plate
element and each two-node line a beam. The model is solved
free-free, so the six rigid-body modes come back at 0 Hz,
followed by the elastic modes. A geometry with no element group
properties raises ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The geometry, by name or as the object itself. |
required |
maximum_frequency
|
float
|
Solve for every mode up to this frequency, in Hz. |
None
|
num_modes
|
int
|
Solve for this many modes instead, rigid-body modes included. |
None
|
damping
|
float
|
The fraction of critical damping given to every mode. A finite element model has no damping of its own. |
0.0
|
name
|
str
|
What to call the result. Defaults to the geometry's name with ' Modes' after it. |
None
|
progress
|
callable
|
Called with |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the shape set was added under. |
Source code in src/visualdynamics/project.py
4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 | |
plan_instrumentation
¶
plan_instrumentation(source: Any, triaxial: int, uniaxial: int = 0, *, modes: Any = None, groups: Any = None, surfaces: Any = None, edge_angle: float | None = None, axes: Any = (2,), name: str | None = None, progress: Any = None, edge_distance: float | None = None, unit: str = 'm') -> dict[str, str]
Plan a test's accelerometers from finite element modes, by Effective Independence.
The model's outer surface is split into surfaces at its sharp
edges (core.instrumentation.skin), and every place on the
surfaces kept a sensor can sit is a candidate, measured in its own system with +Z out of the surface
and +X in the plane of a system axis (core.instrumentation.plan).
Tri-axial accelerometers are placed first, then uni-axial ones
along the surface normal. Three objects are added and linked: the
experimental geometry of the chosen places, the channel table, and
the modes at exactly those channels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The shape set, by name or as the object itself. It is read on the geometry in its object group, or the active one. |
required |
triaxial
|
int
|
How many tri-axial accelerometers. |
required |
uniaxial
|
int
|
How many uni-axial accelerometers. |
0
|
modes
|
sequence of int
|
The modes to measure, by index. Every mode above 0 Hz when omitted. |
None
|
groups
|
sequence of int or str
|
The element groups sensors may go on, by id or name. All when omitted. |
None
|
surfaces
|
sequence of int
|
The surfaces sensors may go on, by their number in
|
None
|
edge_angle
|
float
|
Degrees between two neighboring faces' normals beyond which
they are on separate surfaces;
|
None
|
axes
|
sequence of int
|
The directions a uni-axial accelerometer may measure, 0, 1, 2 for X, Y, Z of its place: Z, the surface normal, by default. |
(2,)
|
name
|
str
|
The start of the three names. The shape set's name with ' Plan' after it when omitted. |
None
|
progress
|
callable
|
Called with |
None
|
edge_distance
|
float
|
How near a sensor may be to the edge of its surface, in
|
None
|
unit
|
str
|
The unit |
'm'
|
Returns:
| Type | Description |
|---|---|
dict
|
The names added, under 'geometry', 'channels' and 'shapes'. |
Raises:
| Type | Description |
|---|---|
TypeError
|
When |
ValueError
|
When it has no geometry to plan on, or the plan cannot be made (no sensors, fewer places than sensors, no mode chosen). |
Warns:
| Type | Description |
|---|---|
FewerDirectionsWarning
|
When the sensors measure fewer directions than there are modes: the plan is made for the lowest modes that many, and the shapes kept still hold every mode asked for, so their auto-MAC shows which the sensors cannot tell apart. |
Source code in src/visualdynamics/project.py
4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 | |
convert_to_specification
¶
Convert a PSD or CPSD to a specification, the requirement measurements are judged against, keeping its name, object group and every reference to it.
Some formats have no way to mark a requirement (the ESCDF data types do not), so a file can only suggest one by its name, and a name is not evidence. The person who knows marks it here instead. An object that is not a PSD, or is already a specification, raises TypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or Psd
|
The PSD. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Its name. |
Source code in src/visualdynamics/project.py
convert_to_psd
¶
Convert a specification to a plain PSD or CPSD, under its own
name. This undoes convert_to_specification, and makes a
target written on the Specification sheet a CPSD to drive or
predict with.
A specification on lines converts as it is. One written at
breakpoints is read onto evenly spaced lines at spacing, the
sheet's own reading (core.author.read_onto_lines), since a
density to drive or predict with is read line by line: one
value at each breakpoint would miss everything between them.
A PSD cannot hold warning and abort limits, so a specification's
limits are left out; asking for the conversion is asking for
that (Specification.limit takes one out as a PSD of its own
first). An object that is not a specification raises TypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or Specification
|
The specification. |
required |
spacing
|
float
|
The line spacing in Hz, for a specification at breakpoints.
Defaults to the spacing its sheet remembers
( |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Its name. |
Source code in src/visualdynamics/project.py
remembered_spacing
¶
The frequency spacing the specification's sheet remembers, in Hz: the spacing of its lines form, or of the lines it was opened from. None when it has none, such as a specification imported at breakpoints.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or Specification
|
The specification. |
required |
Returns:
| Type | Description |
|---|---|
float or None
|
The spacing. |
Source code in src/visualdynamics/project.py
scale_family
¶
The measured PSDs that share one comparison scale: the object and every PSD in its object group that is not a specification, such as its source or the octave bands made from it.
The family has one scale because an octave-band PSD is the same measurement on another frequency grid, and two scales for one run would contradict each other.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
measured
|
str or Psd
|
A measured PSD. |
required |
Returns:
| Type | Description |
|---|---|
list of str
|
The family's names, |
Source code in src/visualdynamics/project.py
comparison_scale
¶
The decibels a measured PSD is scaled by when it is compared with a specification. The comparison's plot, bars and report all use this value.
A scale held on any member of the family is used
(set_comparison_scale keeps the family equal). Otherwise it is
detected on the family's narrowband member, so the same data on
octave bands cannot round to a different decibel than the lines
it came from.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
specification
|
str or Specification
|
What is compared against. |
required |
measured
|
str or Psd
|
The measurement. |
required |
Returns:
| Type | Description |
|---|---|
int
|
Whole decibels. |
Source code in src/visualdynamics/project.py
set_comparison_scale
¶
Hold a comparison scale on a measured PSD and its whole family
(scale_family), or with None, go back to detecting it from the
data.
The scale is stored on the objects, not on a view, so the report compares exactly what the screen shows and a saved project keeps the choice. The data itself is never changed. A value that is not a whole number raises ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
measured
|
str or Psd
|
A measured PSD. |
required |
db
|
int or None
|
Whole decibels, or None for automatic. |
required |
Returns:
| Type | Description |
|---|---|
list of str
|
The PSDs the value was set on. |
Source code in src/visualdynamics/project.py
fit_coherence
¶
The coherence the fitting screen weights a fit of source by,
or None when no coherence covers any of the fit's response DOFs.
It is the coherence covering the most of those DOFs, and one in the FRF's own object group is chosen in a tie.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or Frf
|
The FRF set being fitted. |
required |
records
|
sequence of int
|
The records fitted; every record when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
str or None
|
The coherence's name, for |
Source code in src/visualdynamics/project.py
fit_modes
¶
fit_modes(source: str, *, bounds: tuple[float, float] | None = None, limit: int = 30, name: str | None = None, at: Sequence[tuple[float, float]] | None = None, refine: int = 0, records: Sequence[int] | None = None, coherence: Any = None) -> str
Fit a modal model to an FRF set, as the fitting screen does.
This runs the screen's loop: confirm the suggested mode, then
take the next suggestion, limit times. The session's
suggestion logic makes every choice (a peak already confirmed is
not offered again unless a different shape is found there, as
for a repeated pair), and the loop adds no check of its own. On
the screen the person stops the loop; in a script limit does,
and the plate demonstration's cap is a worked example of
choosing it.
On the screen the zoom does the job of bounds: what is on the
plot is what gets searched. A script has no plot, so it gives
bounds instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str
|
The FRF set to fit. |
required |
bounds
|
tuple of float
|
(low, high) frequency limits to fit within, in Hz. Defaults to the whole band. |
None
|
limit
|
int
|
The most modes to accept. |
30
|
name
|
str
|
What to call the shape set. Defaults to the FRF set's name followed by 'Modes'. |
None
|
at
|
sequence of tuple
|
Explicit (frequency, damping) picks, each optionally
(frequency, damping, description), confirmed in the order
given. Each mode is removed from the residual before the
next is fitted, so the order is part of the fit. The fitting
screen journals its confirms as this call, which is how an
interactive session is replayed. |
None
|
refine
|
int
|
How many times to run the joint residue refinement after the confirms (the screen's Refine All). |
0
|
records
|
sequence of int
|
Fit these records only; the screen fits the records picked in the tree. Every record when omitted. |
None
|
coherence
|
str or Coherence
|
Weight each response's least-squares fit by this coherence,
line by line. The screen weights by
|
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 | |
project_onto_basis
¶
project_onto_basis(source: str, *, onto: str | None = None, channels: Iterable[int] | None = None, tolerance: float = 0.02, name: str | None = None) -> str
Sample a shape set at the Basis shape set's DOFs, or at a channel table's (Project onto Basis DOFs). Returns the new shape set's name.
For each target DOF, the nearest node of the source's geometry
is found, and the displacement there is dotted with the DOF's
direction on the target's geometry, its node's coordinate system
and sign included. A DOF with no node within tolerance is
dropped rather than estimated. The result is linked into the
target's group. A channel table as the target puts a model's
modes at a test's sensors and drives before there are test modes
to compare with: its channels' DOFs, on the geometry the table
answers to. channels narrows a channel table to some of its
rows, such as the drives alone; each row's values are the same as
in the projection onto the whole table. With no target, or the
source or the target without a geometry, this raises ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str
|
The shape set to project. |
required |
onto
|
str
|
The shape set or channel table to project onto. Defaults to the shape set in the project's Basis. |
None
|
channels
|
iterable of int
|
Rows of the channel table |
None
|
tolerance
|
float
|
How far the nearest node may be, as a fraction of the Basis geometry's extent (the largest distance of a node from the nodes' mean position). |
0.02
|
name
|
str
|
What to call the result. Defaults to the source's name
followed by '@ Basis DOFs', or by '@' and the table's name,
with the number of channels in parentheses when |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 | |
match_modes
¶
match_modes(first: str, second: str, *, pairs: Iterable[tuple[int, int]] | None = None, macs: Iterable[float] | None = None, threshold: float = 0.7, name: str = 'Matched Modes') -> str
Save matched mode pairs as an object (the comparison screen's + button).
With pairs, exactly those pairs are kept. Otherwise each of
first's modes is paired with the mode in second that has the
highest MAC, when that MAC is at least threshold. Across
geometries the MAC is computed after projection, as the screen
does it (comparison_mac). The result is in no object group,
since it names a shape set in each; it records both geometries
itself.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
first
|
str
|
One shape set, by name. |
required |
second
|
str
|
The other shape set, by name. |
required |
pairs
|
iterable of tuple of int
|
Explicit (first, second) index pairs, overriding the automatic matching. |
None
|
macs
|
iterable of float
|
MAC values for those pairs. Computed from |
None
|
threshold
|
float
|
The lowest MAC an automatic pairing may have. |
0.7
|
name
|
str
|
What to call the result. |
'Matched Modes'
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 | |
comparison_mac
¶
The MAC between two shape sets, as the comparison screen shows it.
When the sets are on different geometries, the second set is projected onto the first set's DOFs, because DOFs with the same name on two geometries need not point in the same direction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
first
|
str
|
One shape set, by name. |
required |
second
|
str
|
The other shape set, by name. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
The MAC matrix, with |
Source code in src/visualdynamics/project.py
plot_mac
¶
Draw the MAC the comparison screen draws: first against
itself, or against second.
Across geometries the second set is projected exactly as
comparison_mac does it. A shape set's own plot_mac compares
by DOF name and has no geometry, so it cannot do this.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
first
|
str or ShapeSet
|
One shape set, by name or as the object. |
required |
second
|
str or ShapeSet
|
The other shape set. Omitted, the auto-MAC of |
None
|
**kwargs
|
Any
|
Passed to the drawing: |
{}
|
Returns:
| Type | Description |
|---|---|
object
|
Whatever the drawing returns: a window or an image. |
Source code in src/visualdynamics/project.py
merge
¶
Combine compatible objects into one (Merge). The merged object replaces its parts.
Only objects of the same type can be merged, and each kind has its own rule: geometries need disjoint node ids, shape sets the same DOFs, and data arrays an identical abscissa. The merged object is linked into the first part's object group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*names
|
str
|
The objects to merge, by name. |
()
|
name
|
str
|
What to call the merged object. Defaults to the first part's name. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
export
¶
Write an object to another file format, chosen by the file's suffix (Export).
Any registered writer can be used: .unv, .exo, .npz,
.bdf, .afu/.ati/.ash, .xlsx, .3mf, .stl,
.vdreport and the rest of io.exporters().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The object to write. |
required |
path
|
str or PathLike
|
Where to write it. The format follows the extension. |
required |
unit_system
|
UnitSystem
|
Units to write in. Omitted, the stored (SI) values are written as they are. |
None
|
**kwargs
|
Any
|
Passed through to the exporter. |
{}
|
Returns:
| Type | Description |
|---|---|
str
|
The path written. |
Source code in src/visualdynamics/project.py
export_state_space
¶
export_state_space(shapes: Any, table: Any, path: str | PathLike, *, maximum_frequency: float | None = None, rigid_frequency: float = 1.0, unit_system: Any = None) -> Any
Write a shape set at a channel table's channels as a modal state-space model, the file Rattlesnake's state-space virtual hardware loads (Export State Space).
The table's reference rows are the inputs, each a force at its
DOF, and every row is an output, in table order, in its own unit
(core.state_space). The file matches that table row for row,
so it is written for the whole table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
shapes
|
str or object
|
The shape set: real, mass-normalized, with a mass unit. |
required |
table
|
str or object
|
The channel table. |
required |
path
|
str or PathLike
|
Where to write the |
required |
maximum_frequency
|
float
|
Modes at or above this frequency, in Hz, are left out. For a controller, its Nyquist frequency, since a mode above it aliases into the band. Every mode is kept when omitted. |
None
|
rigid_frequency
|
float
|
Modes below this frequency, in Hz, are moved up to it, so a rigid-body mode does not drift through a long run. |
1.0
|
unit_system
|
UnitSystem or str
|
The units for a channel whose unit cell is blank, or the
name of one of |
None
|
Returns:
| Type | Description |
|---|---|
StateSpaceModel
|
The model written: its matrices, the rows' DOFs and units, and how many modes were lifted and left out. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
ValueError
|
As |
Source code in src/visualdynamics/project.py
5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 | |
generate_report
¶
generate_report(template: str = 'modal', name: str = 'Report', marking: str | None = None, marking_color: str | None = None) -> str
Build a report from a starter template, bound by type to this project's objects (Generate Report).
An unknown template raises ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
template
|
str
|
Which starter to build: 'modal', 'random', 'shock',
'transient', 'sine', 'sysid', 'mimo' (a multiple-input
random run, judged on its control matrix) or 'empty'. (In
the app, a
Random and Sine project makes 'random' and 'sine', one
report each.) It can also be a saved template, by the name
it was saved under in the templates folder, or the path of a
|
'modal'
|
name
|
str
|
What to call the report object. |
'Report'
|
marking
|
str
|
The banner across the top and bottom of every page. 'UNCLASSIFIED' when omitted. |
None
|
marking_color
|
str
|
'ink' or 'red'. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the result was added under, unique within the project. A name already taken gets a numbered suffix. |
Source code in src/visualdynamics/project.py
5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 | |
report_features
¶
report_features(name: str, *, enable: Sequence[str] = (), disable: Sequence[str] = (), preset: str | None = None) -> FeatureSelection
Turn a report's optional features on or off (the report editor's Report Features panel).
A report feature is an addition to the generated report, off
until it is enabled; with none enabled the report is exactly
what Visual Dynamics writes otherwise. The features, their
groups and what each one needs are listed in
visualdynamics.report.features.FEATURES, and the presets in
PRESETS. The choice is saved with the report and in a
.vdreport template.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
enable
|
sequence of str
|
Feature keys to turn on. A feature that needs another can be enabled in the same call as the one it needs. |
()
|
disable
|
sequence of str
|
Feature keys to turn off. A feature that needs one turned off goes with it, and the notes say so. |
()
|
preset
|
str
|
'default' (no features), 'test_report' or 'flash_report':
the report's features are replaced by the preset's before
|
None
|
Returns:
| Type | Description |
|---|---|
FeatureSelection
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
For an unknown feature or preset, a feature not yet available, or a feature whose requirement is not met. Nothing is changed. |
TypeError
|
When |
Source code in src/visualdynamics/project.py
report_section
¶
report_section(name: str, section: str, text: str | None = None, *, none: bool = False, by: str | None = None) -> None
Write one skeleton section of a report (the report editor's pane on a section's block).
With the report feature skeleton_sections on, the report is
laid out on the sections in
visualdynamics.report.skeleton.SECTIONS, and each section only
the author can write is shown as owed until it says something.
This sets what it says.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
section
|
str
|
The section's key: 'identification', 'summary', 'requirement', 'article', 'setup', 'instrumentation', 'chronology', 'results', 'deviations', 'discussion', 'conclusion' or 'record'. |
required |
text
|
str
|
The section's words, in the report's Markdown, replacing what it said. |
None
|
none
|
bool
|
Write the section's own wording for nothing to report, in
one step ('deviations' and 'discussion' only): "No
deviations. No anomalies. No nonconformances." With the
report feature |
False
|
by
|
str
|
Who made the interpretation ('discussion' only); an empty string clears it. |
None
|
Returns:
| Type | Description |
|---|---|
None
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
For an unknown section, |
TypeError
|
When |
Source code in src/visualdynamics/project.py
5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 | |
report_check_block
¶
report_check_block(name: str, check: str, *, source: str | None = None, measured: str | None = None, specification: str | None = None, shapes: str | None = None, **settings: Any) -> int
Give a report a check of its own, with what it reads and its
settings (report feature check_blocks).
With the feature on, the report carries a block for every check
it can make from what it shows. A check that needs a fact no
object holds is made from a block of its own: the classical
pulse ('pulse', with its nominal shape, peak and duration), the
sweep rate against the modes the test plan names ('sweep_rate',
modes), two signatures before and after the test
('signature', source before and measured after) and a
replicated record's segments ('segments', segments). A check
made from what the report shows, given a block of its own, is
made from the block, so its settings hold. The checks and what
each reads are visualdynamics.report.check_blocks.CHECKS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
check
|
str
|
'time_statistics', 'rms', 'chance', 'shock_validity', 'srs_points', 'pulse', 'distortion', 'frequency', 'sweep_rate', 'signature' or 'segments'. |
required |
source
|
str
|
What the check reads, by object name or symbolic binding ('@basis:TimeHistory'); each field the check takes defaults to its own binding. |
None
|
measured
|
str
|
What the check reads, by object name or symbolic binding ('@basis:TimeHistory'); each field the check takes defaults to its own binding. |
None
|
specification
|
str
|
What the check reads, by object name or symbolic binding ('@basis:TimeHistory'); each field the check takes defaults to its own binding. |
None
|
shapes
|
str
|
What the check reads, by object name or symbolic binding ('@basis:TimeHistory'); each field the check takes defaults to its own binding. |
None
|
**settings
|
Any
|
The keyword arguments of the check's reading in |
{}
|
Returns:
| Type | Description |
|---|---|
int
|
The index of the check's block in the report. |
Raises:
| Type | Description |
|---|---|
ValueError
|
For an unknown check, a field or setting the check does not take, a required setting left out, or settings that cannot be saved. Nothing is changed. |
TypeError
|
When |
Source code in src/visualdynamics/project.py
report_check
¶
What a report still owes before it is issued, one line per section, in order (what Export lists and asks about).
A line names the section and why: not yet written; nothing in
it (Instrumentation or Results with nothing generated or
written); or a discussion that does not say by whom. With the
report feature findings on, section 9 is read off the
register: a kind neither entered nor set to None, a kind both
entered and said to be none, and each finding's blank parts,
such as '9. Deviations, Anomalies and Nonconformances: D-1:
cause not yet written'. An empty list means every section of
the skeleton says something. With the report feature
flash_report on, the lines are what the flash report's one
page still owes (visualdynamics.report.flash.check), such as
'Condition on release: not yet written', since the page draws
none of the skeleton's sections.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
Returns:
| Type | Description |
|---|---|
list of str
|
One line per owed section, such as '4. Test Article: not yet written', in the skeleton's order. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report does not have the report feature
|
TypeError
|
When |
Source code in src/visualdynamics/project.py
report_flash
¶
report_flash(name: str, *, condition: str | None = None, next_steps: str | None = None, report_date: str | None = None, opinions: Sequence[Any] | None = None, opinions_none: bool | None = None) -> None
Type the parts of a flash report only the author can write.
With the report feature flash_report on, the report is one
preliminary page drawn from the identity, the result table and
the findings register (visualdynamics.report.flash). What the
project does not hold is owed on the page until it is typed
here.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
condition
|
str
|
The article's condition on release: the post-test functional and inspection results as far as they go, and who received it ('' clears it). |
None
|
next_steps
|
str
|
What is still to be done before the result is final. |
None
|
report_date
|
str
|
The date the test report will be issued, as the lab writes it. |
None
|
opinions
|
sequence
|
The opinions given at the console, replacing those entered, each (by, text) or a mapping of 'by' and 'text'. Each is drawn marked as an opinion, with who gave it. |
None
|
opinions_none
|
bool
|
True to say no opinion was given; False takes it back. |
None
|
Returns:
| Type | Description |
|---|---|
None
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When the feature is off, for an opinion without its words or without who gave it, and for opinions entered while None is said of them. Nothing is changed. |
TypeError
|
When |
Source code in src/visualdynamics/project.py
report_finding
¶
report_finding(name: str, number: str | None = None, *, kind: str | None = None, run: str | None = None, channel: str | None = None, band: Sequence[float] | None = None, fact: str | None = None, cause: str | None = None, effect: str | None = None, approval: str | None = None, status: str | None = None, accept: bool = False, discard: bool = False, remove: bool = False) -> str
Enter, change or remove a finding in a report's findings
register (report feature findings; the report editor's pane
on section 9).
A finding is a deviation, an anomaly or a nonconformance,
numbered by kind (D-1, A-1, NC-1) and written in four parts:
the fact, the cause, the effect, and the approval (of a
deviation) or disposition (of an anomaly or nonconformance).
Section 9 of the report draws each one, and the summary lists
them by number. A blank part is drawn as owed, and
report_check lists it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
number
|
str
|
The finding to change. Without it a finding of |
None
|
kind
|
str
|
'deviation', 'anomaly' or 'nonconformance', for a new finding only: a finding's kind is its number's. |
None
|
run
|
str
|
The run and the channel the finding concerns. |
None
|
channel
|
str
|
The run and the channel the finding concerns. |
None
|
band
|
(float, float)
|
The band it concerns, low and high in Hz; an empty sequence clears it. |
None
|
fact
|
str
|
The four parts, in the author's words. |
None
|
cause
|
str
|
The four parts, in the author's words. |
None
|
effect
|
str
|
The four parts, in the author's words. |
None
|
approval
|
str
|
The four parts, in the author's words. |
None
|
status
|
str
|
'open', 'closed' or '' (not stated). |
None
|
accept
|
bool
|
Make the fact draft offered on the finding its fact
( |
False
|
discard
|
bool
|
Drop the fact draft offered on the finding. |
False
|
remove
|
bool
|
Take the finding out of the register. Its number is not given again. |
False
|
Returns:
| Type | Description |
|---|---|
str
|
The finding's number. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report does not have the feature enabled; for a
kind on an existing finding or none for a new one, an
unknown number, a band that is not two ordered frequencies,
a status other than open or closed, |
TypeError
|
When |
Source code in src/visualdynamics/project.py
6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 | |
draft_finding_fact
¶
draft_finding_fact(name: str, number: str, measured: str, specification: str, channel: str | None = None, *, band: Sequence[float] | None = None, limits: str = 'abort', progress: Any = None) -> str
Offer a finding a draft of its fact, read off a comparison the project holds.
The draft names the channel, each stretch where measured
went outside specification's limits (its band, its side,
how far beyond at worst in dB, how many lines), the record and
the time history it was computed from, and what was not
judged. It is read on the same cells, at the same scale, as the
comparison figure (visualdynamics.core.findings.excursions).
The draft fills nothing: the author accepts it, edits it or
discards it (report_finding(..., accept=True)). Only the
fact is ever offered; a channel inside its limits gives no
draft.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
number
|
str
|
The finding. |
required |
measured
|
str
|
The measured spectrum and the specification it is compared with. |
required |
specification
|
str
|
The measured spectrum and the specification it is compared with. |
required |
channel
|
str
|
The channel, such as '2Y+'; the finding's own when omitted. |
None
|
band
|
(float, float)
|
The band to read, in Hz; the finding's own when omitted, and the whole comparison when it has none. |
None
|
limits
|
str
|
'abort' or 'warning'. |
'abort'
|
progress
|
callable
|
Accepted so the app can run the reading on its worker; not called. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The draft offered. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report does not have the feature enabled; for an unknown finding, a name that is not a spectrum or a specification of the project, a channel they do not share, no channel, a pair of limits the specification does not carry, a comparison refused (different quantities, units on one side only), nothing judged in the band, an all-zero channel, and a channel inside its limits wherever it was judged. Nothing is changed. |
TypeError
|
When |
Source code in src/visualdynamics/project.py
6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 | |
draft_finding_from_requirement
¶
draft_finding_from_requirement(name: str, number: str, measured: str, specification: str, criterion: int | str) -> str
Offer a finding a draft of its fact, read off a row of a requirement's result table.
A row offers a fact where the run departed from the plan: a
limit channel's notch the plan does not name (its band, its
line count and how far the control fell under the reference),
and a cross-axis channel over its limit (its worst percentage,
the lines over and their reach). The draft names the channel
and the record and the time history it was computed from, and
reaches the finding as draft_finding_fact's does, through the
register's one entry point for drafts
(visualdynamics.report.findings.offer): it fills nothing
until the author accepts it, edits it or discards it
(report_finding(..., accept=True)).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report, with the features |
required |
number
|
str
|
The finding. |
required |
measured
|
str
|
The run and the specification the requirement is bound to
( |
required |
specification
|
str
|
The run and the specification the requirement is bound to
( |
required |
criterion
|
int or str
|
The row: its number in the result table from 1, or its name, such as 'Limit channel 3Z+'. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The draft offered. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report does not have both features enabled; for an unknown finding, no requirement bound to the pair, one that cannot be read, a row number out of range, a name no row has, a name two offering rows share, and a row that offers no finding. Nothing is changed. |
TypeError
|
When |
Source code in src/visualdynamics/project.py
draft_findings_from_run_log
¶
Offer a report the deviations and anomalies a run log extract holds, as drafts beside its findings register.
Each is offered with the log's number, proposed (D-1, A-1), its
kind and its fact as typed at the console, citing the log, test
and entry (with the extract's badge when the log has newer
entries). Nothing enters the register: the deviations section
stays owed, the editing page shows the drafts marked as drafted
from the run log, and the check lists them as waiting. The
author accepts one (accept_logged_finding), which enters the
finding, or discards it. A new offer replaces the drafts
waiting. A finding the register holds with its fact written is
not offered over, one with no fact logged is not offered, and
the cause, effect and approval or disposition are never
offered. A log holding no deviation or anomaly offers nothing:
setting the section to None stays the author's step.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report, with the report feature |
required |
run_log
|
str
|
The run log extract; the project's one extract when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
list of str
|
A line per finding of the log: offered, or left alone and why; or one line saying the log holds none. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report does not have the feature enabled, the
project holds no run log extract, or holds several and
|
TypeError
|
When |
Source code in src/visualdynamics/project.py
accept_logged_finding
¶
accept_logged_finding(name: str, number: str, *, fact: str | None = None, discard: bool = False) -> str | None
Accept, or discard, a finding a run log offered a report
(draft_findings_from_run_log).
Accepting is what enters the finding in the register: under the
log's number when the register has not given it, otherwise under
the next number of its kind (a finding already entered under
that number with its fact blank takes the fact instead). Its
fact, as offered or as edited (fact), reaches it through the
register's one entry point for drafts
(visualdynamics.report.findings.offer) and is accepted; its
cause, effect and approval or disposition stay owed, for the
author to type (report_finding). Discarding drops the draft and
enters nothing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report, with the report feature |
required |
number
|
str
|
The number the log gave it, as offered. |
required |
fact
|
str
|
The fact as the author edited it; the logged fact when omitted. |
None
|
discard
|
bool
|
Drop the draft instead. |
False
|
Returns:
| Type | Description |
|---|---|
str or None
|
The number the finding was entered under; None when discarded. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report does not have the feature enabled, no
finding is offered as |
TypeError
|
When |
Source code in src/visualdynamics/project.py
report_test_date
¶
Set the dates of the test a report covers, which its sensors' calibration is judged against (the dates in the report editor's pane on the channel table).
With the report feature calibration_in_date on, the report's
channel table carries each sensor's calibration status on these
dates: in date, expired before the test, lapsing during it, or
no date given (visualdynamics.core.calibration). The dates are
kept with the report's channel table blocks, and a .vdreport
template leaves them out.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
start
|
str or None
|
The first test day, YYYY-MM-DD. None or '' clears the dates. |
required |
end
|
str
|
The last test day, YYYY-MM-DD, for a test over several days; the first day when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
None
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report does not have |
TypeError
|
When |
Source code in src/visualdynamics/project.py
report_calibration
¶
report_calibration(name: str) -> CalibrationCheck
Each sensor of a report's channel table against its test dates (what the report's Calibration column shows).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
Returns:
| Type | Description |
|---|---|
CalibrationCheck
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report does not have |
TypeError
|
When |
Source code in src/visualdynamics/project.py
report_calibration_text
¶
The equipment list with each sensor's calibration status on the test date, as Markdown offered for the report's Setup and Method section (the section pane's Insert Calibration Status).
The section is the author's, so nothing is written into it
here; put the text in with report_section:
text = project.report_calibration_text('Report')
project.report_section('Report', 'setup', text)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A sentence, a pipe table of the sensors (channel, DOF, quantity, make, model, serial number, expiration and calibration status) and the lines of the check. |
Raises:
| Type | Description |
|---|---|
ValueError
|
As |
TypeError
|
When |
Source code in src/visualdynamics/project.py
predict
¶
predict(name: str, channel: str, quantity: str, peaks: Sequence[Any], *, unit: str | None = None, level_db: float | None = None, curve: tuple[Sequence[float], Sequence[float]] | None = None, reference: str | None = None, source: str = '', customer: bool = False, frequency_uncertainty: float | None = None, level_uncertainty: float | None = None) -> str
Enter one response channel's predicted response, the
analyst's numbers, into the predictions object name, made
when the project has nothing of that name. A prediction already
held for the channel and quantity is replaced.
A report reads a measurement against these with the report
feature prediction (visualdynamics.report.prediction), and
a script with core.prediction.compare.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The predictions object. |
required |
channel
|
str
|
The response DOF, as the records name it ('201Z+'). |
required |
quantity
|
str
|
'asd', 'amplitude' or 'transmissibility'. |
required |
peaks
|
sequence
|
The predicted peaks, each (frequency [Hz], level, Q, band):
the level in |
required |
unit
|
str
|
The unit of the quantity: 'g' for an ASD in g²/Hz or an amplitude in g. A transmissibility has none. |
None
|
level_db
|
float
|
The input level the prediction is stated at, dB relative to full level (0 at full level). A transmissibility has none. |
None
|
curve
|
(frequencies, values)
|
The predicted curve, in |
None
|
reference
|
str
|
The input DOF of a transmissibility. |
None
|
source
|
str
|
The analysis it comes from, with its document and revision. |
''
|
customer
|
bool
|
Whether the customer supplied it. |
False
|
frequency_uncertainty
|
float
|
The model's stated frequency uncertainty, plus or minus, in percent. |
None
|
level_uncertainty
|
float
|
The model's stated level uncertainty, plus or minus, in dB. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name of the predictions object. |
Raises:
| Type | Description |
|---|---|
ValueError
|
For what a prediction cannot hold
( |
TypeError
|
When |
Source code in src/visualdynamics/project.py
6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 | |
report_prediction
¶
report_prediction(name: str, measured: Any, predictions: Any, *, level: float | None = None, caption: str = '') -> int
Add a block reading measured against predictions at the
end of the report name (the report editor's Insert, Responses
Against Prediction), and return its index.
While the report feature prediction is on, the block draws a
figure per response channel, the measurement over its
prediction scaled to the level run, and a table of each
predicted peak against the measured one.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
measured
|
str or object
|
The response: a PSD, an amplitude spectrum or sine level, or a transmissibility (an FRF). |
required |
predictions
|
str or object
|
The predictions object. |
required |
level
|
float
|
The level |
None
|
caption
|
str
|
The table's caption. |
''
|
Returns:
| Type | Description |
|---|---|
int
|
The block's index in the report. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the comparison cannot be read; |
TypeError
|
When |
Source code in src/visualdynamics/project.py
report_requirement
¶
report_requirement(name: str, specification: Any, measured: Any, document: str, composite_bands: Sequence[Any], *, revision: str = '', clause: str = '', strategy: str = 'single', channels: Sequence[str] = (), weights: Sequence[float] | None = None, individual_bands: Sequence[Any] = (), grms_percent: float | None = None, duration: float | None = None, duration_tolerance: Sequence[float] | None = None, min_dof: float | None = None, max_line_spacing: float | None = None, cross_axis: Sequence[Any] = (), cross_axis_channels: Mapping[str, str] | None = None, limit_channels: Sequence[Any] = (), rule: str = 'any_line', combine: int = 1, sources: Mapping[str, Any] | None = None, uncertainty: Mapping[str, Any] | None = None, duration_run: float | None = None, caption: str = '') -> int
Bind a test requirement to a run in the report name, and
return its block's index.
While the report feature test_requirement is on, the block
draws the requirement in words and a result table with one row
per criterion, worded met, not met or not judged, and the
report's pass/fail box for the same specification and run reads
from it (visualdynamics.report.requirement). The requirement's
fields are core.requirement.TestRequirement's; a band is
(low, high, below_db, above_db), low or high None for the
specification's own end.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
specification
|
str or object
|
The specification the run was controlled to; a symbolic binding ('@basis:Specification') is kept as given, so a template carries it. |
required |
measured
|
str or object
|
The run's PSD, likewise. |
required |
document
|
str
|
The governing document. |
required |
composite_bands
|
sequence
|
The control band: the one channel's, or the composite's under a multi-point strategy; one band per frequency range. |
required |
revision
|
str
|
The document's revision, and the tolerance clause as the plan copied it. |
''
|
clause
|
str
|
The document's revision, and the tolerance clause as the plan copied it. |
''
|
strategy
|
str
|
'single', or a multi-point composite: 'average', 'weighted', 'maximum' or 'minimum'. |
'single'
|
channels
|
sequence of str
|
The control channels by response DOF; by default the channel table's Control flags, else the records that pair with the specification. |
()
|
weights
|
sequence of float
|
One per channel, under 'weighted' only. |
None
|
individual_bands
|
sequence
|
Each control channel's band, under a multi-point strategy. |
()
|
grms_percent
|
float
|
The overall rms tolerance, plus or minus, percent. |
None
|
duration
|
float
|
The nominal duration at level, seconds. |
None
|
duration_tolerance
|
(float, float)
|
Its tolerance below and above, percent. |
None
|
min_dof
|
float
|
The fewest degrees of freedom the control may have. |
None
|
max_line_spacing
|
float
|
The widest line spacing the control may have, Hz. |
None
|
cross_axis
|
sequence
|
The cross-axis limits, each (low, high, percent). |
()
|
cross_axis_channels
|
mapping
|
Each cross-axis channel's response DOF, to the in-axis control channel it is read against as a percentage. |
None
|
limit_channels
|
sequence
|
The response channels held under a limit profile, each (channel, profile, notches): the name of the object holding its profile ('' for the specification's own record at the channel) and the notches the plan names for it, each (low, high) Hz. |
()
|
rule
|
str
|
The decision rule: 'any_line' or 'combined'. |
'any_line'
|
combine
|
int
|
How many adjacent lines are combined under 'combined'. |
1
|
sources
|
mapping
|
Where each number came from, by field: (origin, owner), the origin 'laboratory', 'customer' or 'derived'. |
None
|
uncertainty
|
mapping
|
Each control channel's measurement uncertainty, by response DOF: a list of contributions, each (name, percent, coverage, source), an expanded uncertainty in percent on the acceleration with its coverage factor (2 when left out), drawn against one third of the tolerance. |
None
|
duration_run
|
float
|
How long the run was at level, seconds: the controller's counter, which the duration row is judged on. |
None
|
caption
|
str
|
The result table's caption. |
''
|
Returns:
| Type | Description |
|---|---|
int
|
The block's index in the report. |
Raises:
| Type | Description |
|---|---|
ValueError
|
For a requirement |
TypeError
|
When |
Source code in src/visualdynamics/project.py
6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 | |
index_file
¶
index_file(path: str | PathLike, holds: str | None = None, *, role: str = 'referenced', objects: Sequence[str] = (), source: str = 'author', progress: Any | None = None) -> IndexEntry
Add a file to the project's data index (the report editor's Insert, Attached File).
The data index lists every file the project rests on, by name,
what it holds, format, size and SHA-256, and the report feature
data_index prints it in the report's record. A file imported
into the project is indexed by the import; this adds any other
file: a document that goes with the report (the settings list,
the log, the as-run procedure, the flash report), or a data
file kept in the archive that was not imported. Another source
of files adds its entries through this verb as well, naming
itself in source, so the project keeps one index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str or PathLike
|
The file. It is hashed now. |
required |
holds
|
str
|
What the file is or holds, in words ("settings list", "log,
Day 1 and Day 2"). Taken from |
None
|
role
|
str
|
'attached' for a document sent with the report, or 'referenced' for a file named in it and kept in the archive. An attached text file of up to 64 KiB is kept whole, so the report can print it; a CSV prints as a table. |
'referenced'
|
objects
|
sequence of str
|
The project objects read from the file, by name. |
()
|
source
|
str
|
What added the entry, as the index records it. |
'author'
|
progress
|
callable
|
Called as |
None
|
Returns:
| Type | Description |
|---|---|
IndexEntry
|
The file's entry. The same file indexed again with the same checksum is the same entry. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When neither |
(FileNotFoundError, IsADirectoryError)
|
When |
Source code in src/visualdynamics/project.py
6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 | |
index_run_log_files
¶
index_run_log_files(run_log: str | None = None, *, search: Sequence[str | PathLike] = (), progress: Any | None = None) -> list[str]
Add the files a run log extract names to the project's data index, each checked against the SHA-256 the log records.
Each file is looked for by its name in each folder of search,
then beside the log, then beside the project's own file. Found,
it is hashed; when its SHA-256 is the one the log
records it is indexed through the index's own entry point
(DataIndex.add, source 'run log'), saying which entry named
it. A file found but not the one the log records, and a file
not found, are not indexed, and each has a line saying so. The
log itself is never indexed: its checksum changes with every
entry, and the test's head hash, which the report's data index
prints beside the extract, stands for it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run_log
|
str
|
The run log extract; the project's one extract when omitted. |
None
|
search
|
sequence of str
|
Folders to look in first, for example the archive copy. |
()
|
progress
|
callable
|
Called as |
None
|
Returns:
| Type | Description |
|---|---|
list of str
|
One line per file the log names, in the order first named: 'run11.nc4: indexed', or why it was not; or one line saying the log names no file. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the project holds no run log extract, or holds several
and |
TypeError
|
When |
Source code in src/visualdynamics/project.py
6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 | |
unindex_file
¶
unindex_file(name: str) -> IndexEntry
Take a file out of the data index (the report editor's Insert, Remove from Index).
For a document added by mistake, or one that no longer goes with the report. A file imported into the project leaves the index on its own when the last object read from it is removed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The file's name as the index prints it, or its path when two entries share a name. |
required |
Returns:
| Type | Description |
|---|---|
IndexEntry
|
The entry taken out. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When no entry, or more than one, has that name. Nothing is changed. |
Source code in src/visualdynamics/project.py
verify_data_index
¶
Hash every file in the data index again and record whether it matches (what Export does when the report prints the index).
A file is looked for where it was indexed, then by its name in
each folder of search, then beside the project's own file. It
matches when its size and SHA-256 are the ones indexed; it has
changed when they are not; it is not found when it is nowhere.
The result is kept with each entry and printed in the report.
The project's own file, when it has one, is hashed too, and the
report states it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
search
|
sequence of str
|
Folders to look in for files that are not where they were indexed, for example the archive copy. |
()
|
progress
|
callable
|
Called as |
None
|
Returns:
| Type | Description |
|---|---|
list of str
|
One line per file, in the index's order: its name and what the check found, such as 'run11.nc4: matches'. Empty when the index is empty. |
Source code in src/visualdynamics/project.py
attach_run_log
¶
attach_run_log(path: str | PathLike, test: int | None = None, upto: int | None = None, *, name: str | None = None) -> str
Bring one test of a run log into the project, frozen at a stated
entry, as a run log extract (core.run_log_extract).
The extract holds the test's entries as they stood at entry
upto (corrected), with the test's head hash, and reads them as
the run log model does: its runs, interruptions, credited
duration, findings, files and chronology. A report drawing on it
never changes because the log grew; the extract says when the
log holds newer entries (RunLogExtract.status), and
refresh_run_log takes them, as a step of its own. The log's
path is saved relative to the project file when the log is in
the project file's folder or one beneath it, and absolute
otherwise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str or PathLike
|
The |
required |
test
|
int
|
The test, by number; may be left out when the log holds one. |
None
|
upto
|
int
|
The id of the last entry to take; the log's last entry when omitted. |
None
|
name
|
str
|
What to call the extract; 'Run Log, Test N' when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The name the extract was added under. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
When there is no file at |
RunLogError
|
A |
Source code in src/visualdynamics/project.py
detach_run_log
¶
detach_run_log(name: Any) -> RunLogExtract
Take a run log extract out of the project, and return it.
Attaching the same log with the same test and entry
(attach_run_log(path, test=..., upto=...)) brings back the same
entries, since a log is only ever added to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or RunLogExtract
|
The extract. |
required |
Returns:
| Type | Description |
|---|---|
RunLogExtract
|
The extract taken out. |
Raises:
| Type | Description |
|---|---|
TypeError
|
When |
Source code in src/visualdynamics/project.py
refresh_run_log
¶
refresh_run_log(name: Any, upto: int | None = None) -> RunLogExtract
Take a run log extract again from its log, to its newest entry
or to entry upto: the one way an extract changes, and never on
its own.
Refused when the log at the extract's path is another log, or no
longer holds the entries the extract was taken from (cut short or
changed since): attach it again to take it as it is now. Giving
the upto the extract had before takes back its entries.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or RunLogExtract
|
The extract. |
required |
upto
|
int
|
The id of the last entry to take; the log's last entry when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
RunLogExtract
|
The new extract, under the same name. |
Raises:
| Type | Description |
|---|---|
TypeError
|
When |
FileNotFoundError
|
When the log is not at the extract's path. |
RunLogError
|
A |
Source code in src/visualdynamics/project.py
report_identity
¶
Enter a report's identification (the report editor's Identity and Issue fields).
With the report feature report_identity on, every printed page
carries the laboratory, the report number and revision, the
title and page n of N, and the first page the identification
block. Every field is the author's: the program never writes a
number, a date or a name of its own, and a field left blank
shows as not entered.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
**fields
|
Any
|
Any of 'number', 'revision', 'laboratory', 'address', 'location', 'customer', 'contact', 'received', 'tested', 'issued' (the dates as the lab writes them) and 'distribution', each a str ('' clears it); 'authorized', the people authorizing the report, a list of names or one per line ("name, role"), printed each with a blank line for the signature; and 'full_only', whether the first page says the report is not reproduced except in full (True unless turned off). |
{}
|
Returns:
| Type | Description |
|---|---|
None
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
For an unknown field, the status or issue record (changed only by issuing and amending), or the number or revision of a report already issued. Nothing is changed. |
TypeError
|
When |
Source code in src/visualdynamics/project.py
export_report_pdf
¶
export_report_pdf(name: str, path: str | PathLike, unit_system: Any = None, page_size: str = 'letter') -> str
Write a report as a paginated PDF, printed from the same page
export_report writes.
A draft prints as often as wanted and says it is a draft on
every page. An issued report prints again only unchanged: a copy
of what was issued. With the report feature report_identity
on, each page carries the identity and page n of N. With the
report feature data_index on, every indexed file is hashed
again first, as for export_report, so the PDF states what the
check found today.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
path
|
str or PathLike
|
Where to write the PDF. |
required |
unit_system
|
UnitSystem
|
Units to render in; |
None
|
page_size
|
str
|
'letter' or 'a4'. |
'letter'
|
Returns:
| Type | Description |
|---|---|
str
|
The path written. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report was issued and has changed since (a change after issue is an amendment), or for an unknown page size. |
OSError
|
When the page cannot be printed. |
Source code in src/visualdynamics/project.py
issue_report
¶
issue_report(name: str, path: str | PathLike, unit_system: Any = None, page_size: str = 'letter') -> str
Issue a report: print it as a PDF under its number and revision, and record the issue.
The report's status becomes issued (or amended, for an
amendment), and the issue record gains the number, revision,
status and date of issue as entered, with the SHA-256 of the
PDF and of the page it was printed from. From then on the report
is not written again under that identity unless it is
unchanged; a change is an amendment (amend_report). With the
report feature data_index on, every indexed file is hashed
again first, as for export_report, so the issued PDF states
what the check found today.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report, with the report feature |
required |
path
|
str or PathLike
|
Where to write the issued PDF. |
required |
unit_system
|
UnitSystem
|
Units to render in; |
None
|
page_size
|
str
|
'letter' or 'a4'. |
'letter'
|
Returns:
| Type | Description |
|---|---|
str
|
The path written. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the feature is off, the report is already issued, a field the identification needs is not entered, or (with skeleton sections on) a section is still owed; or for an unknown page size. Nothing is changed or written. |
OSError
|
When the PDF cannot be printed; the report stays a draft. |
Source code in src/visualdynamics/project.py
amend_report
¶
amend_report(name: str, changes: Sequence[Mapping[str, str]], *, revision: str, number: str | None = None) -> None
Make an issued report an amendment, to be issued in its turn
(issue_report).
The amendment carries its own revision (and, if given, its own number), refers to the revision it amends by number, revision and date of issue, and prints a table of what it changes. It ends "End of amendment.". The original's record is kept.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
changes
|
sequence of mapping
|
Each change: 'where' (page or section), 'was' (what it said), 'now' (what it says) and, where appropriate, 'reason'. |
required |
revision
|
str
|
The amendment's revision, entered by the author. |
required |
number
|
str
|
The amendment's own report number; the original's when left out. |
None
|
Returns:
| Type | Description |
|---|---|
None
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report has not been issued, a change lacks where, was or now, there are no changes, or the number and revision were already issued. Nothing is changed. |
TypeError
|
When |
Source code in src/visualdynamics/project.py
run_identity
¶
Which run of the test a time history is, as a report reads it.
The axis, run, level against full and start the history carries
(read from its file's name on import, or entered with
set_run_identity), and the level the comparison with its
specification detects when nothing else gives one. A field read
two ways is not read, and refused says why, naming the
record.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
A time history, or an object computed from one (which answers with that run's identity). |
required |
Returns:
| Type | Description |
|---|---|
RunIdentity
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When |
TypeError
|
When |
Source code in src/visualdynamics/project.py
set_run_identity
¶
set_run_identity(name: str, *, axis: str | None = None, run: str | int | None = None, level_db: float | str | None = None, start: Any = None, comment: str | None = None) -> Any
Enter which run of the test a time history is.
An entered field stands over what the file's name or the comparison gave. A field left out (None) is unchanged; an empty string clears it, back to what the record shows. The identity is saved with the history in the project file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The time history: one imported, not one computed from another (that is part of the run it came from). |
required |
axis
|
str
|
The test axis, 'X', 'Y', 'Z' or a lab's own name. |
None
|
run
|
str or int
|
The run's identifier. |
None
|
level_db
|
float
|
The level against full, in decibels: 0 for full level. |
None
|
start
|
(str, datetime or date)
|
When the run started, ISO 8601 text such as '2026-10-11T11:11:05'. |
None
|
comment
|
str
|
A free note on the run. |
None
|
Returns:
| Type | Description |
|---|---|
RunIdentity
|
What the history carries afterwards. |
Raises:
| Type | Description |
|---|---|
ValueError
|
For a history computed from another, a level that is not a finite number, a start that is not a date, or an axis or run on more than one line; the message names the record. Nothing is changed. |
TypeError
|
For an object that is not a time history, or a value of the wrong type. |
Source code in src/visualdynamics/project.py
report_chronology
¶
report_chronology(name: str, *, window_s: float = 0.5, drop_db: float = 6.0, min_s: float = 1.0, progress: Callable[[int, int], None] | None = None) -> str
Draft the chronology of the project's runs and offer it to a report's Chronology section (the editor's Draft from the Runs).
Each run in the order it was run, with its axis, level, start,
the time its record was at level and the interruptions found in
it, as a Markdown table, then how they were read. The chronology
is the author's: the draft is offered beside the section, marked
as drafted on the editing page, and the section stays owed until
the author accepts it (accept_chronology) or writes the
section (report_section). The outcome of each run and the
cause of each interruption are left for the author.
With a run log brought into the project (attach_run_log), the
draft also carries what the log records: each run's outcome,
matched by run number and axis, the cause of each interruption
where the record and the log count the same, and under the table
the log's interruptions with their cause, path and restart and
the time credited on each axis, with which log, test and entry
they come from. A project with an extract and no time history is
offered the log's own chronology. Without an extract, the draft
is the records' alone.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report, with the report feature |
required |
window_s
|
float
|
The running-RMS window, in seconds. |
0.5
|
drop_db
|
float
|
How far below the run's level an interruption reaches. |
6.0
|
min_s
|
float
|
How long an interruption lasts at least, in seconds. |
1.0
|
progress
|
callable
|
Called with (runs read, runs) as each record is read. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The draft offered, in the report's Markdown. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report does not have |
TypeError
|
When |
Source code in src/visualdynamics/project.py
7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 | |
accept_chronology
¶
Accept the drafted chronology as a report's Chronology section, as it was drafted or as the author edited it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report. |
required |
text
|
str
|
The draft as the author edited it; the draft on offer when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
None
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When no draft is on offer and no |
TypeError
|
When |
Source code in src/visualdynamics/project.py
report_runs
¶
Repeat a report's Results for every run (the editor's Results for Every Run).
The report's generated Results sections drawn from its first run are added again for each run it does not draw on yet, each figure bound by name to the object computed from that run the same way, its caption naming the run. A section whose figure has nothing computed from a run is not added for that run, and the line for the run says what to compute. A second call adds nothing for a run already drawn on.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report, with the report feature |
required |
Returns:
| Type | Description |
|---|---|
list of str
|
A line per run: the figures added, and what was not added and why. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the report does not have |
TypeError
|
When |
Source code in src/visualdynamics/project.py
work_up
¶
Compute every missing object the project's type expects from what is loaded, with the report last (Automatic on the tree's bar).
The empty slots are filled in their own order, each from the objects already there, the way the workflow guide makes them: PSDs from the time data, octave bands from the PSDs and the specification, and the coherence from the time data; the FRFs, a fitted shape set and the matched modes for a modal test; the levels for a sine sweep; the filtered record, its SRS and the integrated motion for a shock; the two streams' PSDs on shared frames and the H1 FRFs for a system identification; and then the type's report. A slot the loaded data cannot fill (a geometry, the photographs, a specification) is left gray. A computation the data refuses (no drive channel for a coherence) is skipped, and the rest still run. Nothing already present is made again, so calling this twice adds nothing the second time.
It is journaled as one line, project.work_up(), the way
merge is. The verbs it calls are the ones the guide describes,
and a script that wants them one at a time can call them.
Returns:
| Type | Description |
|---|---|
list of str
|
The names added, in the order made; empty when the skeleton was already full. |
Raises:
| Type | Description |
|---|---|
ValueError
|
When the project has no type, so there are no slots to fill. |
Source code in src/visualdynamics/project.py
7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 | |
export_report
¶
Write a report as one self-contained HTML file (Export).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The report object to render. |
required |
path
|
str or PathLike
|
Where to write the self-contained HTML file. |
required |
unit_system
|
UnitSystem
|
Units to render in. Defaults to |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The path written. |
Raises:
| Type | Description |
|---|---|
ValueError
|
With the report feature |
Source code in src/visualdynamics/project.py
table
¶
table(name: Any, *, values: bool = False, dofs: Any = None, form: str = 'shapes', environment: str | None = None) -> tuple[list[str], list[list[str]]]
(headers, rows) for an object that can be shown as a table.
The rows are a channel table's instrumentation, a shape set's
identified parameters, or a matched-modes object's pairs beside
both sets' parameters. They are the same rows the report prints,
so a script and a report always agree. With values, a shape
set gives its shape values instead, as the app's Shape Values
table shows them: at every DOF of the set, or at dofs, and as
the shapes or one of the transformations through them
(core.transform.matrix_at). With environment, a channel
table's Control column is that control loop's, and with form
'response' or 'reference' as well the rows are that loop's
transformation instead, as the app shows it with the
environment and the view picked on the table's bar. An object
with no table raises ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The object to tabulate. |
required |
values
|
bool
|
For a shape set, its values rather than its modes. |
False
|
dofs
|
str or sequence of str
|
With |
None
|
form
|
str
|
With |
'shapes'
|
environment
|
str
|
For a channel table, one of its environments
( |
None
|
Returns:
| Type | Description |
|---|---|
tuple of (list of str, list of list of str)
|
The column headings and the rows, both as text. |
Source code in src/visualdynamics/project.py
7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 | |
plot_transformation
¶
plot_transformation(name: Any, *, dofs: Any = None, form: str = 'reference', row: int = 0, **kwargs: Any) -> Any
Draw one row of a shape set's transformation on its geometry, as arrows scaled per DOF, as the app's Shape Values view does with a transformation picked.
The row is a mode; each arrow is at one of dofs, along it, its
length the row's value there as a share of the row's largest
(viz.geometry.transformation_arrows), pointing the other way
for a negative value. The geometry is the one in the set's
object group (geometry_for). A set with no geometry, or the
'shapes' form, whose rows are DOFs rather than modes, raises
ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or ShapeSet
|
The shape set. |
required |
dofs
|
str or sequence of str
|
Where, as for |
None
|
form
|
str
|
'reference' ( |
'reference'
|
row
|
int
|
Which mode's row, from 0. |
0
|
**kwargs
|
Any
|
Passed to |
{}
|
Returns:
| Type | Description |
|---|---|
object
|
The plotter, or the image when rendered to |
Source code in src/visualdynamics/project.py
transformation_of
¶
A rigid set's transformation at a choice of DOFs, as an object
(core.transformation.Transformation.from_shapes): the matrix
from motions at the DOFs to the set's six coordinates, with its
conditioning, its residual projector and its table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or ShapeSet
|
Six unscaled rigid-body shapes. |
required |
dofs
|
str or sequence of str
|
Where, as for |
None
|
max_condition
|
float
|
The conditioning past which it is refused; the package's
limit ( |
None
|
Returns:
| Type | Description |
|---|---|
Transformation
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the set is not unscaled rigid shapes, a DOF is not in it, or the DOFs resolve too little or too poorly. |
TypeError
|
If the object is not a shape set. |
Source code in src/visualdynamics/project.py
read_transformation
¶
What a rigid-body transformation leaves unexplained of the
density it was applied to, line by line
(core.transformation.read_residual).
name is a density transformed in this project (Transform to
Modal Responses) from a cross-spectral density through six
unscaled rigid-body shapes. The transformation is rebuilt from
the set at the channels the transform used, and the source's
measured power at those channels is split into the part the six
motions explain and the residual, with the frequency up to which
the residual stays under threshold of it. The conditioning is
reported, not refused: a reading of a poor layout is the point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The transformed density, by name or as the object itself. |
required |
threshold
|
float
|
The residual's share of the measured power at which the
rigid-body assumption is said to stop holding; a tenth when
left out ( |
None
|
progress
|
callable
|
Called with |
None
|
Returns:
| Type | Description |
|---|---|
TransformationResidual
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the object was not transformed in this project from a cross-spectral density through rigid shapes, or no motion channel of the source is in the set. |
Source code in src/visualdynamics/project.py
8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 | |
plot
¶
Plot an object the way the app plots it: data as curves, a geometry as its scene, a shape set as its auto-MAC.
An object with no plot raises TypeError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The object to draw. |
required |
**kwargs
|
Any
|
Passed through to the object's own plot method. |
{}
|
Returns:
| Type | Description |
|---|---|
object
|
Whatever the underlying plot call returns. |
Source code in src/visualdynamics/project.py
animate
¶
Animate a mode shape, a complex spectrum's operating deflection shape, or a time history, on the object's geometry.
The geometry is the one geometry_for gives; with none, this
raises ValueError. A spectrum's line is picked with
frequency= in kwargs. A time history whose modal records
have a shape set behind them (modal_basis) plays those records
through the set's shapes on the set's geometry, unless
quantity= picks one of its physical measurements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The shape set or spectrum to animate. |
required |
mode
|
int
|
Which mode, by index. Not used for a spectrum. |
0
|
**kwargs
|
Any
|
Passed through to the scene. |
{}
|
Returns:
| Type | Description |
|---|---|
object
|
The plotter the animation is running in. |
Source code in src/visualdynamics/project.py
animate_pair
¶
Animate two shape sets' modes overlaid on their geometries, as the app does for a picked cell of their cross-MAC.
Each set is drawn on its own geometry (geometry_for), or on
the first set's when the second has none; the first must have
one, or this raises ValueError. The Basis set is drawn solid and
the other partly transparent over it (theme.overlay_alphas),
whichever order they are given in; with no Basis between them,
the first is drawn solid. The caption gives both names.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
first
|
str or ShapeSet
|
The two shape sets. |
required |
second
|
str or ShapeSet
|
The two shape sets. |
required |
mode
|
int
|
Their modes, by index. |
required |
other_mode
|
int
|
Their modes, by index. |
required |
**kwargs
|
Any
|
Passed through to |
{}
|
Returns:
| Type | Description |
|---|---|
object
|
The plotter, the still, or the movie's path. |
Source code in src/visualdynamics/project.py
name_of
¶
The name an object is stored under; a string is returned as it is.
Every verb accepts either, so project.compute_psds('Time
History') and project.compute_psds(project.basis.time_history)
are the same call. An object not in the project raises
ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str or object
|
A name, or an object the project holds. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The name it is stored under. |
Source code in src/visualdynamics/project.py
extract_sine
¶
Read each specification tone's level out of a recording (Extract Sine Levels), as one sine level set holding every tone.
Each tone is read against its own sweep, since each sweeps its
own frequencies on its own clock. When no specification is
named, the project's one sine sweep specification is used. The
settings are the recording's sine_extraction; when none is
set, the suggested setting is used, as filter_data uses its
suggested filter, and the setting with the smoothing chosen is
stored on the recording. The result is linked to the recording.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
str or object
|
The recording (a time history) to read. |
required |
specification
|
str or object
|
The sweep specification to extract against. Defaults to the project's own, when it holds exactly one. |
None
|
progress
|
callable
|
Called with |
None
|
Returns:
| Type | Description |
|---|---|
list of str
|
A list holding the name of the sine level set added. |
Source code in src/visualdynamics/project.py
8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 | |
stale
¶
{derived name: reason} for every derived object whose source's settings have changed since it was computed.
An object whose source is gone, or whose provenance records no state to compare, is not reported.
Source code in src/visualdynamics/project.py
refresh
¶
Recompute a derived object in place, under its own name.
Links, the report's figures and the grids all refer to the
object by name, so replacing the value under that name keeps
every reference correct. Objects derived from this one then
become stale by content, and are refreshed one at a time or all
together with refresh_stale, never automatically. An object
with no recorded derivation, or whose source is gone, raises
ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str or object
|
The derived object to recompute, in place and under its own name. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The name refreshed. |
Source code in src/visualdynamics/project.py
refresh_stale
¶
Refresh every stale object, sources before the objects derived from them, until nothing is stale. Returns the names refreshed.
This is the refresh on the project's row in the tree.
Source code in src/visualdynamics/project.py
save
¶
Write the whole project to one file: .vdyn, .mat for the
same layout in a MATLAB file, or .h5 for the Engineering
Sciences Common Data Format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str or PathLike
|
Where to write the file. A |
required |
**options
|
Any
|
Passed to the MATLAB or ESCDF writer, for example an ESCDF
file's |
{}
|
Returns:
| Type | Description |
|---|---|
str
|
The path written. |
Source code in src/visualdynamics/project.py
open
classmethod
¶
open(path: str | PathLike) -> Project
Read a project from a .vdyn, .mat or ESCDF .h5 (.hdf5,
.escdf) file.
The journal starts over with the one line that opens the file. A file holding a single object rather than a project raises ValueError.
Source code in src/visualdynamics/project.py
journal_as
¶
Record a stretch of front-end work as the one line that replays it.
The app imports a file by building the objects itself and
adding them one at a time. Journaled verb by verb, that stretch
would be lines that do not replay, when the accurate record is
the single import_file call a script would make. Inside the
stretch, verbs record nothing, the same as verbs called from
other verbs, and the line is added only when the stretch
finishes without an error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
line
|
str or None
|
The line that replays the stretch, or None to record nothing. |
required |
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in src/visualdynamics/project.py
record_setting
¶
Journal a settings write the way a script would make it.
The app stores analysis settings by assignment (a dragged averaging span, a filter corner, the shock windows), and those writes are part of the session as much as any verb. A repeated write to the same attribute replaces its own last line, so a setting adjusted many times leaves one assignment, not a line for each change. An object not in the project is ignored.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str or object
|
The object written to, by name or as the object. |
required |
attribute
|
str
|
Which settings attribute was stored. |
required |
value
|
Any
|
What was stored. Its repr must rebuild it, as every settings dataclass in visualdynamics does. |
required |
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in src/visualdynamics/project.py
record_call
¶
Journal a method call on an object the way a script would make it.
This is for object methods that are not Project verbs, such as a line added to a geometry or a photo renamed, so the console shows every change made in the session. An object not in the project is ignored.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target
|
str or object
|
The object acted on, by name or as the object. |
required |
method
|
str
|
The method a script would call. |
required |
*args
|
Any
|
The call's arguments. Their reprs must rebuild them. |
()
|
settle
|
bool
|
Replace the last line when it was the same call (the same object, method, positional arguments and keyword names, with only the keyword values different), so a gesture adjusted again leaves one line, not one per adjustment. |
False
|
**kwargs
|
Any
|
Keyword arguments, under the same rule as |
{}
|
Returns:
| Type | Description |
|---|---|
None
|
|
Source code in src/visualdynamics/project.py
session_script
¶
This session's changes to the project as a runnable Python script.
It is the journal under the imports it needs: every verb that ran and every setting stored, whether clicked in the app or called from a script, as the line that reproduces it. A session worked up by hand can then be replayed, adapted or kept. Reads and refused calls are left out, because the script records what changed the project, and a verb that raised changed nothing.
Returns:
| Type | Description |
|---|---|
str
|
A Python script; running it rebuilds this session's project from the same inputs. |
Source code in src/visualdynamics/project.py
Functions:¶
type_rank
¶
The position of an object's type in the order the tree lists types.
describe
¶
A few words on what an object holds: its size, not its name.
A count of zero is left out of the text.
Source code in src/visualdynamics/project.py
holds
¶
What a file held, in words, from the objects read out of it: for
each, its kind and size (describe), and for records the channels
they span and a time history's sample rate. The data index prints
this as the file's holdings, so a reader can ask for the file that
holds a channel.
Source code in src/visualdynamics/project.py
holds_of_names
¶
holds for the objects of project called names; refuses an
empty selection, since an index entry has to say what it holds.
Source code in src/visualdynamics/project.py
remap_links
¶
remap_links(object_groups: Iterable[ObjectGroup], mapping: dict[str, str], roles_taken: Iterable[str] = ()) -> list[ObjectGroup]
Object groups translated through a {old name: new name} mapping.
When a project is imported into one that already holds objects,
the names that clash are renamed, and the groups have to be renamed
with them or the file's grouping is lost. A member missing from the
mapping is dropped, and a group left with fewer than two members is
dropped. A role in roles_taken stays with the group that already
has it, because the Basis belongs to the project, not to the file.
Source code in src/visualdynamics/project.py
retarget
¶
Point an object's references at renamed objects.
Matched modes name their two shape sets, and a report's blocks name the objects they draw from. When one of those objects is renamed, the reference has to be changed with it, or the report figure has nothing to draw. The object is changed in place.
Source code in src/visualdynamics/project.py
holds_forces
¶
Whether a time history holds a force or modal force channel, or a CPSD a force or modal force density: what Compute Modal Responses answers.
Source code in src/visualdynamics/project.py
random_vibration_run
¶
random_vibration_run(run: str | PathLike, per_octave: int | None = None, *, last: float | None = None, geometry: str | PathLike | None = None, length_unit: str | None = None, photos: Any = None) -> Project
Work a Rattlesnake random vibration run up into a project.
project = visualdynamics.random_vibration_run('run.nc4')
project = visualdynamics.random_vibration_run(
'run.nc4', last=100.0, geometry='article.stp', length_unit='mm',
photos='setup_photos/')
These are the steps the app takes from a controller file to a finished project, in the same order: import the run, average PSDs from the control time histories, put those on proportional bands, put the specification on the same bands with its limits (the report compares the banded measurement with the banded requirement), and compute how much of each response the drives account for. The run records that it is a random vibration test, so the project's type is set to Random Vibration.
The averaging is what Detect finds: the controller's own frame length, window and overlap from the file, with the start and the number of frames worked out from the record (where the run is at level and how many frames that stretch holds). A script, an import and a click on Detect therefore give the same numbers.
The other arguments are what the app's tree asks for after the run
is imported, so a script never has to open the app: the article's
geometry, with its length unit given when the file does not carry
one; the setup photographs, as a folder of png or jpeg files, one
file, or a list of files in the order they should appear; and, for
a run too long to hold in memory, last, the number of seconds
before the end to import. last is the same window the import
dialog's Last field sets, and a run shorter than that is imported
whole. The geometry and the photographs are linked into the run's
own group, so the report can read them against the channel table.
A run with no time data raises ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
str or PathLike
|
The controller's |
required |
per_octave
|
int
|
Bands per octave for the banded PSD and specification. Defaults to 6. |
None
|
last
|
float
|
Import only the last |
None
|
geometry
|
str or PathLike
|
A geometry file to import and link to the run. |
None
|
length_unit
|
str
|
The geometry's length unit, for a file that does not say. |
None
|
photos
|
str, os.PathLike or sequence of them
|
A folder of photographs, one photograph, or several. |
None
|
Returns:
| Type | Description |
|---|---|
Project
|
The worked-up project, of type Random Vibration. |
Source code in src/visualdynamics/project.py
9666 9667 9668 9669 9670 9671 9672 9673 9674 9675 9676 9677 9678 9679 9680 9681 9682 9683 9684 9685 9686 9687 9688 9689 9690 9691 9692 9693 9694 9695 9696 9697 9698 9699 9700 9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711 9712 9713 9714 9715 9716 9717 9718 9719 9720 9721 9722 9723 9724 9725 9726 9727 9728 9729 9730 9731 9732 9733 9734 9735 9736 9737 9738 9739 9740 9741 9742 9743 9744 9745 9746 9747 9748 9749 9750 9751 9752 9753 9754 9755 | |
work_up_system_id
¶
work_up_system_id(project: Project) -> tuple[str | None, str]
Work up an imported system identification in place.
The project type is set to System ID, the driven stream is renamed 'Excitation Time History' and the ambient one 'Noise Time History', and the H1 FRFs, the multiple coherence and both streams' PSDs (on the excitation's frames) are computed. Returns the two stream names, with the ambient one None when the recording holds only the driven stream.
Source code in src/visualdynamics/project.py
system_id_run
¶
system_id_run(run: str | PathLike, *, last: float | None = None, geometry: str | PathLike | None = None, length_unit: str | None = None, photos: Any = None) -> Project
Work a Rattlesnake system identification up into a project.
project = visualdynamics.system_id_run('sysid.nc4')
These are the steps the app takes, in the same order: import the recording, name the two streams (the ambient and the driven), and compute the FRFs from the driven stream by H1, the controller's own estimator, since the excitation is known and the noise is on the response. Then compute the multiple coherence, and average a PSD from each stream on the same frames, since the signal-to-noise ratio is a ratio of densities and is only defined on lines both hold. The project's type is set to System ID. A recording with no time data raises ValueError.
last, geometry, length_unit and photos mean the same as in
random_vibration_run. The ambient stream, the geometry and the
photographs are linked into the driven stream's group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
str or PathLike
|
The controller's |
required |
last
|
float
|
Import only the last |
None
|
geometry
|
str or PathLike
|
A geometry file to import and link to the run. |
None
|
length_unit
|
str
|
The geometry's length unit, for a file that does not say. |
None
|
photos
|
str, os.PathLike or sequence of them
|
A folder of photographs, one photograph, or several in order. |
None
|
Returns:
| Type | Description |
|---|---|
Project
|
The worked-up project, of type System ID. |
Source code in src/visualdynamics/project.py
mixed_run
¶
mixed_run(run: str | PathLike, per_octave: int | None = None, *, last: float | None = None, geometry: str | PathLike | None = None, length_unit: str | None = None, photos: Any = None) -> Project
Work a Rattlesnake random run with a sine sweep under it up into a project, both halves.
project = visualdynamics.mixed_run('run.nc4')
This does everything random_vibration_run does (imports the run,
averages and bands the PSDs, bands the specification, computes the
coherence, and brings in the geometry and photographs), and then the
sine half: each tone's level is extracted from the same recording
against the sweep specification the file carries. The run records
that it is both, so the project's type is set to Random and Sine. A
run with no sine sweep specification raises ValueError instead of
being worked up as half of what was asked for; use
random_vibration_run for it. The keyword arguments are the same
as random_vibration_run's.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
str or PathLike
|
The controller's |
required |
per_octave
|
int
|
Bands per octave for the banded PSD and specification. Defaults to 6. |
None
|
last
|
float
|
Import only the last |
None
|
geometry
|
str or PathLike
|
A geometry file to import and link to the run. |
None
|
length_unit
|
str
|
The geometry's length unit, for a file that does not say. |
None
|
photos
|
str, os.PathLike or sequence of them
|
A folder of photographs, one photograph, or several in order. |
None
|
Returns:
| Type | Description |
|---|---|
Project
|
The worked-up project, of type Random and Sine. |
Source code in src/visualdynamics/project.py
9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020 10021 10022 10023 10024 10025 10026 10027 | |
sine_run
¶
sine_run(run: str | PathLike, *, last: float | None = None, geometry: str | PathLike | None = None, length_unit: str | None = None, photos: Any = None) -> Project
Work a Rattlesnake sine sweep run up into a project.
project = visualdynamics.sine_run('sweep.nc4')
The run is imported, each tone's level is extracted from the
control channels against the sweep specification the file carries,
and the geometry and photographs are imported and linked the way
random_vibration_run does it. The run records that it is a sine
sweep, so the project's type is set to Sine Sweep. A run with no
sine sweep specification, or no time data, raises ValueError; use
random_vibration_run or mixed_run for a run without a sweep. The
keyword arguments are random_vibration_run's except per_octave,
which a sweep does not use.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
str or PathLike
|
The controller's |
required |
last
|
float
|
Import only the last |
None
|
geometry
|
str or PathLike
|
A geometry file to import and link to the run. |
None
|
length_unit
|
str
|
The geometry's length unit, for a file that does not say. |
None
|
photos
|
str, os.PathLike or sequence of them
|
A folder of photographs, one photograph, or several in order. |
None
|
Returns:
| Type | Description |
|---|---|
Project
|
The worked-up project, of type Sine Sweep. |
Source code in src/visualdynamics/project.py
10030 10031 10032 10033 10034 10035 10036 10037 10038 10039 10040 10041 10042 10043 10044 10045 10046 10047 10048 10049 10050 10051 10052 10053 10054 10055 10056 10057 10058 10059 10060 10061 10062 10063 10064 10065 10066 10067 10068 10069 10070 10071 10072 10073 10074 10075 10076 10077 10078 10079 10080 10081 10082 10083 10084 10085 10086 10087 10088 10089 10090 10091 | |
sine_report
¶
sine_report(run: Any = ASK, path: str | PathLike | None = None, *, last: float | None = None, geometry: Any = None, photos: Any = None, unit_system: Any = None, marking: str | None = None) -> Any
Read a Rattlesnake sine sweep run and write an HTML report.
visualdynamics.sine_report('sweep.nc4', 'report.html')
visualdynamics.sine_report() # ask for both
visualdynamics.sine_report('sweep.nc4', 'reports/')
This is random_vibration_report for a sweep: a run left out is
asked for, the batch and folder rules are the same, the project is
worked up by sine_run, and the Sine Sweep report is written as one
self-contained HTML file. Returns the path written, or the list of
them when several runs were chosen. marking is the banner across
every page of the report, 'UNCLASSIFIED' when omitted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
str, os.PathLike, sequence of them, or `visualdynamics.ASK`
|
The controller's |
ASK
|
path
|
(str, PathLike or None)
|
The file to write, or a folder (one that exists, or a name ending in a separator) the report is written into under the run's own name. Beside the run when omitted. Several runs need a folder or None. |
None
|
last
|
float
|
Import only the last |
None
|
geometry
|
str, os.PathLike, `visualdynamics.ASK` or None
|
A geometry file to import and link to the run. Asked for once for
the whole batch when the run was asked for, with Cancel meaning
none; |
None
|
photos
|
str, os.PathLike or sequence of them
|
A folder of photographs, one photograph, or several in order. |
None
|
unit_system
|
UnitSystem
|
The units the report is written in. Defaults to the package default, 'in-slinch-lbf-s (g)'. |
None
|
marking
|
str
|
The banner across the top and bottom of every page. 'UNCLASSIFIED' when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
str or list of str
|
The path written, or a list of them when several runs were chosen or a list of runs was given. |
Source code in src/visualdynamics/project.py
10094 10095 10096 10097 10098 10099 10100 10101 10102 10103 10104 10105 10106 10107 10108 10109 10110 10111 10112 10113 10114 10115 10116 10117 10118 10119 10120 10121 10122 10123 10124 10125 10126 10127 10128 10129 10130 10131 10132 10133 10134 10135 10136 10137 10138 10139 10140 10141 10142 10143 10144 10145 10146 10147 10148 10149 10150 10151 | |
report_kind
¶
Which one-call reports a Rattlesnake run gets: 'random', 'mixed', 'sine' or 'sysid', from the project type the file records.
'mixed' is a random run with a sweep under it, which gets both a
random report and a sine report (run_report). 'sysid' is also
given for a streamed save shaped like a system identification (two
streams, a quiet one and then a loud one); the app asks in that
case, and this function chooses 'sysid'. A run of a type with no
one-call report, such as a modal or transient run, raises
ValueError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
str or PathLike
|
The controller's |
required |
Returns:
| Type | Description |
|---|---|
str
|
'random', 'mixed', 'sine' or 'sysid'. |
Source code in src/visualdynamics/project.py
run_report
¶
run_report(run: Any = ASK, path: str | PathLike | None = None, *, last: Any = None, kinds: Any = None, geometry: Any = None, photos: Any = None, per_octave: int | None = None, unit_system: Any = None, marking: str | None = None, progress: Any = None) -> Any
Read a Rattlesnake run and write the report its type calls for.
visualdynamics.run_report('run.nc4', 'report.html')
visualdynamics.run_report() # ask for the runs and the geometry
visualdynamics.run_report('run.nc4', 'reports/')
visualdynamics.run_report(['a.nc4', 'b.nc4'], 'reports/',
geometry='article.stp')
This one-call report reads the run's own type (report_kind) and
writes that report. A random run gets random_vibration_report's
report, a sweep sine_report's, a system identification
system_id_report's, and a random and sine run gets both a random
and a sine report, as <name>_random.html and <name>_sine.html.
For that run the random report reads only the last last seconds
when they are given, and the sine report always reads the whole
run, since a sweep cut short loses tones. A streamed save that
looks like a system identification (two streams, quiet and then
loud) is treated as one without asking. The function is named for
what it takes, since visualdynamics.report is the rendering
package.
The asking, the batch and the folder follow the same rules as the
typed functions, and a batch may mix kinds. The keyword arguments
are the union of theirs, and per_octave is used only for the
random reports.
Every run's kind is read before any report is written, so a batch
holding a run with no one-call report raises ValueError before
writing anything instead of stopping partway through. kinds
overrides the reading run by run, for example for a restarted
random run that was taken for a system identification or a file
that records no type, and last can be given run by run too.
progress(done, total) is called after each run, which is what the
app's progress bar and Cancel use; a run is the smallest step, so a
cancel takes effect between runs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
str, os.PathLike, sequence of them, or `visualdynamics.ASK`
|
The controller's |
ASK
|
path
|
(str, PathLike or None)
|
The file to write, or a folder (one that exists, or a name ending in a separator) the report is written into under the run's own name. Beside the run when omitted. Several runs need a folder or None. |
None
|
last
|
float or Mapping
|
Import only the last |
None
|
kinds
|
Mapping
|
The report each run gets, by path: 'random', 'mixed' (a random
and a sine report), 'sine' or 'sysid'. Any other value raises
ValueError. A run it leaves out gets the report its file
records ( |
None
|
geometry
|
str, os.PathLike, `visualdynamics.ASK` or None
|
A geometry file to import and link to the run. Asked for once for
the whole batch when the run was asked for, with Cancel meaning
none; |
None
|
photos
|
str, os.PathLike or sequence of them
|
A folder of photographs, one photograph, or several in order. |
None
|
per_octave
|
int
|
Bands per octave for the banded PSD and specification. Defaults to 6. Only the random reports use it. |
None
|
unit_system
|
UnitSystem
|
The units the report is written in. Defaults to the package default, 'in-slinch-lbf-s (g)'. |
None
|
marking
|
str
|
The banner across the top and bottom of every page. 'UNCLASSIFIED' when omitted. |
None
|
progress
|
callable
|
Called as |
None
|
Returns:
| Type | Description |
|---|---|
str or list of str
|
The path written, or a list of them when several runs were chosen, a list of runs was given, or a run was random and sine (two reports). |
Source code in src/visualdynamics/project.py
10202 10203 10204 10205 10206 10207 10208 10209 10210 10211 10212 10213 10214 10215 10216 10217 10218 10219 10220 10221 10222 10223 10224 10225 10226 10227 10228 10229 10230 10231 10232 10233 10234 10235 10236 10237 10238 10239 10240 10241 10242 10243 10244 10245 10246 10247 10248 10249 10250 10251 10252 10253 10254 10255 10256 10257 10258 10259 10260 10261 10262 10263 10264 10265 10266 10267 10268 10269 10270 10271 10272 10273 10274 10275 10276 10277 10278 10279 10280 10281 10282 10283 10284 10285 10286 10287 10288 10289 10290 10291 10292 10293 10294 10295 10296 10297 10298 10299 10300 10301 10302 10303 10304 10305 10306 10307 10308 10309 10310 10311 10312 10313 10314 10315 10316 10317 10318 10319 10320 10321 10322 10323 10324 10325 10326 10327 10328 10329 10330 10331 10332 10333 10334 10335 10336 10337 10338 10339 10340 10341 10342 10343 10344 10345 10346 10347 10348 10349 10350 10351 10352 10353 10354 10355 | |
system_id_report
¶
system_id_report(run: Any = ASK, path: str | PathLike | None = None, *, last: float | None = None, geometry: Any = None, photos: Any = None, unit_system: Any = None, marking: str | None = None) -> Any
Read a Rattlesnake system identification and write an HTML report.
visualdynamics.system_id_report('sysid.nc4', 'sysid.html')
visualdynamics.system_id_report() # ask for both
This is system_id_run followed by the System ID report: the
measured FRFs, the coherence map, and the signal-to-noise ratio of
the measurement at each line and for each channel. Where the ratio
falls to zero decibels, the measurement is of the ambient noise,
not of the structure.
Asking, batches and folders work as in random_vibration_report.
When the run is left out it is asked for, and as many runs may be
chosen as there are reports wanted; the geometry is asked for once
for the whole batch when the run was asked for, with Cancel meaning
none; visualdynamics.ASK forces either question; and path may
be the file to write or the folder to write into.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
str, os.PathLike, sequence of them, or `visualdynamics.ASK`
|
The controller's |
ASK
|
path
|
(str, PathLike or None)
|
The file to write, or a folder (one that exists, or a name ending in a separator) the report is written into under the run's own name. Beside the run when omitted. Several runs need a folder or None. |
None
|
last
|
float
|
Import only the last |
None
|
geometry
|
str, os.PathLike, `visualdynamics.ASK` or None
|
A geometry file to import and link to the run. Asked for once for
the whole batch when the run was asked for, with Cancel meaning
none; |
None
|
photos
|
str, os.PathLike or sequence of them
|
A folder of photographs, one photograph, or several in order. |
None
|
unit_system
|
UnitSystem
|
The units the report is written in. Defaults to the package default, 'in-slinch-lbf-s (g)'. |
None
|
marking
|
str
|
The banner across the top and bottom of every page. 'UNCLASSIFIED' when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
str or list of str
|
The path written, or a list of them when several runs were chosen or a list of runs was given. |
Source code in src/visualdynamics/project.py
10358 10359 10360 10361 10362 10363 10364 10365 10366 10367 10368 10369 10370 10371 10372 10373 10374 10375 10376 10377 10378 10379 10380 10381 10382 10383 10384 10385 10386 10387 10388 10389 10390 10391 10392 10393 10394 10395 10396 10397 10398 10399 10400 10401 10402 10403 10404 10405 10406 10407 10408 10409 10410 10411 10412 10413 10414 10415 10416 10417 10418 10419 10420 | |
random_vibration_report
¶
random_vibration_report(run: Any = ASK, path: str | PathLike | None = None, *, last: float | None = None, geometry: Any = None, photos: Any = None, per_octave: int | None = None, unit_system: Any = None, marking: str | None = None) -> Any
Read a Rattlesnake random vibration run and write an HTML report.
visualdynamics.random_vibration_report('run.nc4', 'report.html')
visualdynamics.random_vibration_report(
'run.nc4', 'report.html', last=100.0,
geometry='article.stp', photos='setup_photos/')
visualdynamics.random_vibration_report() # ask for both
visualdynamics.random_vibration_report('run.nc4', 'reports/')
Called with no run, it opens a file dialog and takes as many runs as
are chosen, writes one report for each and returns the list. A run
chosen that way is asked about its geometry too, with Cancel meaning
none. visualdynamics.ASK in either place forces the question, so a
script with a run in hand can still be asked for the geometry. A
run given without a geometry argument means no geometry, and no
dialog opens.
path may be the file to write, or a folder the report is written
into under the run's own name with an .html extension. Without a
path the report is written beside the run. Several runs need a
folder or no path; a single file name raises ValueError.
The whole workflow runs in one call: import the run (or only its
last last seconds; a shorter run is imported whole), detect the
averaging, compute the PSDs, put them and the specification on
octave bands, compute the multiple coherence, bring in the geometry
and the photographs when they are given, generate the Random
Vibration report, and write it as one self-contained HTML file. The
keyword arguments are random_vibration_run's except length_unit,
plus unit_system and marking for the report.
It is random_vibration_run followed by generate_report and
export_report. Use those instead when the project is wanted
afterwards, to write the test summary or to save it as .vdyn.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
run
|
str, os.PathLike, sequence of them, or `visualdynamics.ASK`
|
The controller's |
ASK
|
path
|
(str, PathLike or None)
|
The file to write, or a folder (one that exists, or a name ending in a separator) the report is written into under the run's own name. Beside the run when omitted. Several runs need a folder or None. |
None
|
last
|
float
|
Import only the last |
None
|
geometry
|
str, os.PathLike, `visualdynamics.ASK` or None
|
A geometry file to import and link to the run. Asked for once for
the whole batch when the run was asked for, with Cancel meaning
none; |
None
|
photos
|
str, os.PathLike or sequence of them
|
A folder of photographs, one photograph, or several in order. |
None
|
per_octave
|
int
|
Bands per octave for the banded PSD and specification. Defaults to 6. |
None
|
unit_system
|
UnitSystem
|
The units the report is written in. Defaults to the package default, 'in-slinch-lbf-s (g)'. |
None
|
marking
|
str
|
The banner across the top and bottom of every page. 'UNCLASSIFIED' when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
str or list of str
|
The path written, or a list of them when several runs were chosen or a list of runs was given. |
Source code in src/visualdynamics/project.py
10423 10424 10425 10426 10427 10428 10429 10430 10431 10432 10433 10434 10435 10436 10437 10438 10439 10440 10441 10442 10443 10444 10445 10446 10447 10448 10449 10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 10464 10465 10466 10467 10468 10469 10470 10471 10472 10473 10474 10475 10476 10477 10478 10479 10480 10481 10482 10483 10484 10485 10486 10487 10488 10489 10490 10491 10492 10493 10494 10495 10496 10497 10498 10499 10500 10501 10502 10503 10504 10505 10506 10507 10508 10509 10510 10511 10512 10513 | |