====== Advanced Pipeline Commands ======
==== Introduction ====
This section provides a tutorial for advanced pipeline commands and proper pipeline development. A set of standards is also laid out for scripts and meta commands. Several commands are discussed with options that may be helpful with your script development. It is not meant to be a comprehensive discussion of each pipeline command. For a more detailed discussion go to the command wiki page. This tutorial is meant as a "sampler" to show the variety of ways the commands can be implemented.
=== Word of Caution ===
It is tempting for some labs to create elaborate pipelines that control all of the data processing. In other words, they try to create a "push-button" approach to data processing. Removing the user from the process limits the Quality Assurance process inherent in looking at and evaluating your data. 3D Motion capture data is challenging and when force platforms are included in the mix, even more challenging. We caution users from omitting this basic Quality Assurance.
Equally important is that these same labs often have the pipelines and templates created by a lab director, and not by students or other members of the lab. This article cautions against [[http://www.wsj.com/articles/automation-makes-us-dumb-1416589342?KEYWORDS=robots|over-automation]]
==== Prerequisites ====
This tutorial assumes that you already know how to use pipeline commands within Visual 3D. To review the tutorial on command pipeline click on [[Visual3D:Tutorials:Pipeline:Command_Pipeline_|Tutorial: Command Pipeline]]. After completion return to this tutorial for discussion on advanced scripting and standards.
==== Sample Data ====
- Download the standing calibration file from the website: [[https://www.has-motion.com/download/examples/Lower%20Body%20Static%20Trial.c3d|Lower Body Static Trial.c3d]]
- Download the movement trial file [[https://www.has-motion.com/download/examples/Walking%20Trial%201.c3d|Walking Trial 1.c3d]]
- Download the full body gait [[[https://www.has-motion.com/download/examples/FullBodyGait.zip|Download Example1 Here]]]
- Save these files in the folder where you plan to save your motion capture files.
==== Pipeline Editor ====
To review, the pipeline editor or pipeline workshop can be accessed via:
* the command menu
* the "Pipeline" button on the toolbar
* or by selecting "Workshop" from the Pipeline Menu.
The pipeline workshop will open. To orient you, commands are located in the left column. The commands are organized into folders for:
* File Import/Export and Management
* Event/Creation and Management
* Force
* Metric Creation
* Model Building
* Computing Model Based Data
* Realtime Biofeedback
* Signal Processing and Math
* Reports
* Other (for miscellaneous commands)
* MetaCommands
=== Select commands ===
Commands can be moved over into the main pipeline (middle column) by using the **ADD>>** (double arrow) buttons and can be reordered in any sequence. The right most column will show a preview of the command when the command is highlighted. Any command editing can be done here. Open, Save and other execution buttons are on the top.
=== Debugging ===
The Workshop has many debugging features that will assist you in developing your scripts. You can step through commands, halt on the first error, play a sound, and clear command parameters.
== Step ==
The workshop has a feature that will allow you to "step" through the commands to debug your script. This can be extremely useful especially if you have a script with several commands. When you "step" through the commands, the "Pipeline Processing Results" window will open and show the command with the parameters and the results. Any errors will be stated in this window.
To step through the commands:
* Start with a series of commands in the Main Pipeline.
* Highlight the command you wish to begin stepping through. It does not have to be the first command in the list. You can start anywhere in the Pipeline.
* Click the "Step" button.
* Only the highlighted command will execute.
* The "Pipeline Processing Results" window will open and show the command with the parameters and the results. Any errors will be stated in this window. Look at the bottom of this window for the number of errors and warnings.
* Continue to click the "Step" button to execute each command.
== Halt on First Error ==
Another debugging feature of the Pipeline Workshop is the ability to halt execution of commands on the "first error". In a long series of commands it can be time consuming to "step" through the commands for debugging purposes. Another way to debug a series of commands is to setup a "halt on first error".
In the Pipeline Workshop select the "halt on first error" and click on the Execute button. The Processing Results window will open and the series of commands will execute. When the first error occurs, commands will stop executing and the errors and warnings will appear in this window.
== Play Sound ==
A sound (.wav file) can be setup to play upon completion of the commands in the Pipeline. To setup the sound file click on "Play Sound" and click the browse button (to the right) to find your *.wav file preference. The sound will play upon completion of every command if you "step" through the commands and will play at the end if you execute the whole pipeline. This can be a nice auditory cue for when your commands have completed executing.
=== Main vs Recalc ===
There are two pipelines that can be edited in the Pipeline Dialog
This tutorial is about the main processing pipeline.
The [[Visual3D:Documentation:Pipeline:General_Information:RECALC_Pipeline|Recalc Pipeline]] is a special pipeline that gets executed every time the Visual3D Workspace is updated; on opening the cmo file, when a report template is opened, by the user selected the RECALC button, or when Visual3D determines that it needs to update the workspace in order to be able to perform some specific processing requirements.
it is important to note that the RECALC pipeline is part of the [[Visual3D:Documentation:Reports:Reports_Overview|Report Template]]. When a Report Template is opened, the RECALC pipeline is deleted a replaced with the RECALC pipeline in the Report Template.
Both the main processing pipeline and the [[Visual3D:Documentation:Pipeline:General_Information:RECALC_Pipeline#Saving_the_Recalc_Pipeline|Recalc pipeline]] can be saved as ASCII files.
==== Notepad++ ====
The Visual 3D pipeline command scripts are text files that can be edited in any text editor such as notepad. The resulting [[Visual3D:Documentation:Definitions:File_Formats:V3S_File|V3S File]] is then opened in the pipeline workshop and executed.
On the C-Motion Software Exchange page (https://www.c-motion.com/products/free-downloads/), there is a free software download for Notepad++. This is an XML language file for Notepad++ that offers editing visibility features like highlighting and indenting for Visual3D script development.
==== Pipeline Favorites ====
Pipeline Favorites is a very powerful way for you to list your pipeline scripts as a Table of Contents. Your list of pipeline scripts can be viewed or run from the Pipeline Favorites list box. The [[Visual3D:Documentation:Pipeline:General_Information:Pipeline_Favorites|Tutorial: Pipeline Favorites]] will walk you through how to create your pipeline favorites.
==== Standards ====
We recommend the following standards for pipeline development.
=== Why standards? ===
* Script migration: Standardizing your pipeline scripts allows you to easily migrate scripts to different types of analyses. In addition should C-Motion enhance a Visual 3D command, this command can easily be found within your pipeline script and edited to reflect the new command parameters.
* Debugging: Standardizing your pipeline scripts makes debugging easier.
* Script management: Standards will aide in good script management.
* Sharing scripts: When you share scripts with collaborators, they can easily review and or edit the script as needed.
* Proper V3D implementation of scripts:
* If you want C-Motion to build you a customized application, standards are required.
=== Include comments ===
Including comments in your scripts will allow you to easily review your commands for processing settings. This can be very helpful if it has been a while since you constructed the script. In addition, including comments will allow you to easily debug your scripts while you are developing them or make changes later on down the road. It is good practice and well worth the effort!
=== Develop your script by sections ===
We recommend developing your script in section form with comments added for documentation and clarification. Open the example script "?.v3s" in pipeline.
* The first section in your script should include your lab name, date of revision, the model used, and the purpose of the script. Lines starting with ! are comment lines.
* To split the sections use ! ====================
Below is an example of the first section of the script.
!=====================================================
! Advanced Pipeline Processing Tutorial Example
! Date: 2012
! Need: The Standing Trial - Filename is cal.c3d
! The Model Template - Filename is model.mdh
! The Movement Trials
! TAG names for the Movement Trials
! The Report Template
! Purpose: Example script to be used in advanced pipeline tutorial
!=======================================================
Continue to make sections for file import/export (more here)
==== Define global parameters ====
Always start by defining global parameters to identify key locations, directories, values, etc. This can be accomplished using one of the "Pipeline Parameter" commands found in the "Pipeline Control" folder. It is similar to specifying a global variable that could be used in computations across all files. Once this parameter is defined you use the parameter name in the script. There are many pipeline parameter commands to chose from (i.e setting folder paths, data values).
=== Folder paths ===
We recommend starting with setting folder paths and directories. The following script is an example of how you might set folder paths.
! ==========================
! Initialize Global Scripting Parameters
! ==========================
File_New
! Clear Workspace. The previous workspace will not be saved
;
! Set Data path
Set_Pipeline_Parameter_To_Folder_Path
/PARAMETER_NAME=DATA_PATH
/PARAMETER_VALUE=C:\Program Files\Visual3D\data\
! /PARAMETER_VALUE_SEARCH_FOR=
! /PARAMETER_VALUE_REPLACE_WITH=
! /PARAMETER_VALUE_APPEND=
;
! Set Template path
Set_Pipeline_Parameter_To_Folder_Path
/PARAMETER_NAME=TEMPLATE_PATH
/PARAMETER_VALUE=C:\Program Files\Visual3D\templates\
! /PARAMETER_VALUE_SEARCH_FOR=
! /PARAMETER_VALUE_REPLACE_WITH=
! /PARAMETER_VALUE_APPEND=
;
=== Signal names ===
You can also set signal names to one global parameter name. This can be helpful when you want to process all the signals the same way and not have to actually designate each signal name in subsequent commands. The following example is for setting a parameter name for a group of muscle signals. In future commands, the parameter name will be "MUSCLES".
!=================================================
!Set a pipeline parameter for the muscle signals
!=================================================
Set_Pipeline_Parameter
/PARAMETER_NAME=MUSCLES
/PARAMETER_VALUE=RECTFEM+VASTLAT+VASTMED+MEDHAMS+TIBANT+GASTROC
! /PARAMETER_VALUE_SEARCH_FOR=
! /PARAMETER_VALUE_REPLACE_WITH=
! /PARAMETER_VALUE_PREFIX=
! /PARAMETER_VALUE_APPEND=
;
=== User prompts ===
The pipeline has several interactive commands. Users can be prompted for input by either entering the value directly or by using a pulldown menu to select the value. The prompting commands can be found in the "Pipeline control" folder.
== Direct input prompts ==
To input a value directly into a parameter, use the [[Visual3D:Documentation:Pipeline:Pipeline_Commands:Prompt_For_Pipeline_Parameter_Value|Prompt For Pipeline Parameter Value]] or [[Visual3D:Documentation:Pipeline:Pipeline_Commands:Prompt_For_Multiple_Pipeline_Parameter_Values|Prompt For Multiple Pipeline Parameter Values]] commands. These can be found in the "Pipeline Control" command folder. A default value can be set for both of these commands.
Below is an example of how to prompt for multiple values with defaults. This example prompts for height and weight and gives default values. When a user is prompted using the [[Visual3D:Documentation:Pipeline:Pipeline_Commands:Prompt_For_Multiple_Pipeline_Parameter_Values|Prompt For Multiple Pipeline Parameter Values]] a dialog table will open up and the user will enter values through the table.
! --------------------------------------------------------------
! Prompt for parameters mass and height
! --------------------------------------------------------------
Prompt_For_Multiple_Pipeline_Parameter_Values
/GLOBAL_PARAMETER_NAME=Mass+Height
/DATATYPE=float+float
/DEFAULT_VALUE=0+0
;
! --------------------------------------------------------------
! Setting subject weight parameter
! --------------------------------------------------------------
Set_Subject_Weight
! /CALIBRATION_FILE=::CALIBRATION_FILE
/WEIGHT=::MASS
;
! --------------------------------------------------------------
! Setting subject height parameter
! --------------------------------------------------------------
Set_Subject_Height
! /CALIBRATION_FILE=::CALIBRATION_FILE
/HEIGHT=::HEIGHT
;
== Pulldown prompts ==
A user can be prompted to select a value via a pulldown menu of predefined values. Instructions can be added to the top of the pulldown dialog menu to assist the user in their selection. Below is an example of a prompt with a pulldown menu that will ask the user to select 1 for the right side and -1 for the left side. This can be used to negate (multiply by -1) a signal that may depend on side such as output from a Biodex torque signal.
Prompt_For_Pipeline_Parameter_Value
/GLOBAL_PARAMETER_NAME=SIDE
/PROMPT=Which side was tested? Choose 1.0 for right, -1.0 for left.
/DATA_TYPE=float+float
/DEFAULT_VALUE=1.0 + -1.0
;
Below is what the user would see when the command is executed. {{:prompt_pulldown.jpg}}
In the previous section, we entered in values via a multiple prompt dialog but we could have also used the pulldown prompts to enter in these values. The example below shows how we would set this up.
==== Advanced Tagging ====
Tagging files can be very useful to identify a group of files for specific analyses and for looping processes (which will be discussed in the next section). In the basic pipeline command tutorial, we covered tagging files via the workspace tag and the Assign_Tags_To_Files command. In this section, we will discuss advanced techniques to tag files: tagging files based on the name of the file, user prompts for tags, and querying tags.
=== Tagging based on filename convention ===
This technique can be useful to tag files based on their naming convention. Let's say that you have collected MVIC EMG data and have also collected walking trials. MVIC data and the walking trials would need to be processed differently. We can assign tags based on the naming convention of your files. For example, you may have files named MedGastMVIC.C3D, RectFemMVIC.C3D, Walk1.C3D, and Walk2.C3D. We can tag these files by using * as a wildcard.
!Open files
File_Open
! /FILE_NAME=
;
!--------------------------------------------------------------
! Automatically assign tag to motion files for walking and MVIC trials
! --------------------------------------------------------------
!Assign Tags to walking files
Assign_Tags_To_Files
/MOTION_FILE_NAMES=*MVIC*.C3D
! /QUERY=
/TAGS=MVIC
;
!Assign Tags to walking files
Assign_Tags_To_Files
/MOTION_FILE_NAMES=*walk*.C3D
! /QUERY=
/TAGS=Walk
;
! --------------------------------------------------------------
! This command will make active all of the files with the tag name
! --------------------------------------------------------------
Select_Active_File
/File_Name=MVIC
;
Another example can be found on [[Visual3D:Documentation:Pipeline:Pipeline_Commands:Pipeline_Example_Assigning_Tags|Pipeline Processing Example 4]].
=== Tagging based on user prompts ===
Another nice way to tag files is based on user prompts. For example, you can open a group of files and prompt the user for the tag name of the files that were opened.
!Open files
File_Open
! /FILE_NAME=
;
!Prompt_For_Pipeline_Parameter_Value
/GLOBAL_PARAMETER_NAME=TAG
/PROMPT=Enter The Name of the Tag for this Workspace
! /DATA_TYPE=
! /DEFAULT_VALUE=
;
!Assign_Tags_To_Files
! Assign the TAG to all files in the Workspace
/MOTION_FILE_NAMES=ALL_FILES
/TAGS=::TAG
;
! --------------------------------------------------------------
! This command will make active all of the files with the tag name
! --------------------------------------------------------------
Select_Active_File
/File_Name=TAG
;
=== Tagging Query ===
Another tagging option is to use a query when assiging tags to file. There are a few options based on logical operators and the use of parameters in your query.
Here is an example of an **OR** tagging query:
!******************************
! OR option for tagging query
!******************************
!TAGS can be assigned to files based on a Query. The following example assigns the TAG "Processed"
!to files tagged "Walk" OR "Barefoot"
Assign_Tags_To_Files
/MOTION_FILE_NAMES=ALL_FILES
/QUERY=Walk | Barefoot
/TAGS=Processed
;
Here is an example of an **AND** tagging query:
!******************************
! AND option for tagging query
!******************************
!TAGS can be assigned to files based on a Query. The following example assigns the TAG "Processed"
!to files tagged "Walk" AND "Barefoot"
Assign_Tags_To_Files
/MOTION_FILE_NAMES=ALL_FILES
/QUERY=Walk & Barefoot
/TAGS=Processed
;
Here is an example of an **OR** tagging query using parameters:
!************************************************
! OR option for tagging query using parameters - + needs to used in this case
!************************************************
!Set_Pipeline_Parameters for tags
Set_Pipeline_Parameter
/PARAMETER_NAME=TAG1
/PARAMETER_VALUE=Walk
;
Set_Pipeline_Parameter
/PARAMETER_NAME=TAG2
/PARAMETER_VALUE=Barefoot
;
Assign_Tags_To_Files
/MOTION_FILE_NAMES=ALL_FILES
/QUERY=::TAG1+::TAG2
/TAGS=Processed
;
Here is an example of an **AND** tagging query using parameters. The ::AMP operator is used:
!************************************************
! AND option for tagging query using parameters - ::AMP needs to used in this case
!************************************************
!Set_Pipeline_Parameters for tags
Set_Pipeline_Parameter
/PARAMETER_NAME=TAG1
/PARAMETER_VALUE=Walk
;
Set_Pipeline_Parameter
/PARAMETER_NAME=TAG2
/PARAMETER_VALUE=Barefoot
;
Assign_Tags_To_Files
/MOTION_FILE_NAMES=ALL_FILES
/QUERY=::TAG1&::AMP&::TAG2
/TAGS=Processed
;
Here is an example of an **NOT** operator:
!************************************************
! Tagging query using a logical NOT operator
!************************************************
!From ALL_FILES select files that are NOT "Barefoot"
Assign_Tags_To_Files
/MOTION_FILE_NAMES=ALL_FILES
/QUERY=NOT(Barefoot)
/TAGS=Processed
;
Here is an example of using both **AND** and **NOT** operators:
!************************************************
! Tagging query using both logical AND and NOT operators
!************************************************
!From ALL_FILES select files that are NOT "Barefoot" AND are tagged "Run"
Assign_Tags_To_Files
/MOTION_FILE_NAMES=ALL_FILES
/QUERY=NOT(Barefoot) & Run
/TAGS=Processed
;
==== Loops and Nesting ====
You may want to loop processing commands and may even want to nest loops within loops. Visual 3D can loop via the [[Visual3D:Documentation:Pipeline:Pipeline_Commands:For_Each_and_End_For_Each|For Each]] command. Tags are often used to identify the files that will be processed in the loop. In addition, Visual 3D has the ability to call scripts within scripts.
=== For Each ===
The [[Visual3D:Documentation:Pipeline:Pipeline_Commands:For_Each_and_End_For_Each|For Each]] command executes pipeline commands multiple times for each item in a list of items. It is not identical with a "for loop" or "do loop" in a programming language because the items must be explicitly defined as ITEMS in the command. The [[Visual3D:Documentation:Pipeline:Pipeline_Commands:For_Each_and_End_For_Each|For Each]] command can be iterated by a series of numbers, filenames, tags, signal names, or parameter values.
== Iterating the For Each by numbers ==
You may wish to iterate the loop by a set of numbers. Three examples are illustrated: 2 iteration based on repetitions examples and 1 iteration based of filename.
This example shows how one would loop based on repetition of a motion (i.e. 5 squat movements within one trial). This loop will calculate an event at the maximum position for each repetition and name the event Rep_1 for rep 1, Rep_2 for rep 2, etc.
!=================================================
!Loop for Reps - Finds Max Event for 5 reps
!=================================================
For_Each
/Iteration_Parameter_Name=INDEX1
/Items=1+2+3+4+5
;
!Find the event at Max POSITION and name it Rep_#
Event_Minimum
/SIGNAL_TYPES=DERIVED
/SIGNAL_NAMES=POSITION
/SIGNAL_FOLDER=PROCESSED
/EVENT_NAME=Rep_&::INDEX1
/SELECT_X=TRUE
! /SELECT_Y=FALSE
! /SELECT_Z=FALSE
/FRAME_WINDOW=1000
/START_AT_EVENT=REP_0
/END_AT_EVENT=END
/EVENT_INSTANCE=::INDEX1
;
End_For_Each
/Iteration_Parameter_Name=INDEX1
;
The following example is a variation on the previous example. But this time we will use the command **Set_Pipeline_Parameter_From_For_Loop** to create a pipeline parameter to mimic the indexing that is traditional in a For loop.
!=================================================
!Loop for Reps - Finds Max Event for 5 reps
!=================================================
! Create a pipeline parameter to mimic a traditional For loop
Set_Pipeline_Parameter_From_For_Loop
/PARAMETER_NAME=INTEGER_ITERATION
/PARAMETER_INDEX_START=1
/PARAMETER_INDEX_END=5
/PARAMETER_INDEX_STEP=1
/PARAMETER_INDEX_TYPE=INTEGER
;
For_Each
/Iteration_Parameter_Name=INDEX1
/Items=::INTEGER_ITERATION
;
!Find the event at Max POSITION and name it Rep_#
Event_Minimum
/SIGNAL_TYPES=DERIVED
/SIGNAL_NAMES=POSITION
/SIGNAL_FOLDER=PROCESSED
/EVENT_NAME=Rep_&::INDEX1
/SELECT_X=TRUE
! /SELECT_Y=FALSE
! /SELECT_Z=FALSE
/FRAME_WINDOW=1000
/START_AT_EVENT=REP_0
/END_AT_EVENT=END
/EVENT_INSTANCE=::INDEX1
;
End_For_Each
/Iteration_Parameter_Name=INDEX1
;
This example shows how one would loop on filename iterations (i.e. if you have the files Walk01.c3d, Walk02.c3d, and Walk03.c3d)
!=================================================
Loop for setting the active file
!=================================================
For_Each
/ITERATION_PARAMETER_NAME=FileNo
/ITEMS=01+02+03
;
!Set the active file
Select_Active_File
/FILE_NAME=C:\DataFile\Walk&::FileNo&.c3d
;
End_For_Each
/Iteration_Parameter_Name=FileNo
;
== Using Tags in Loops ==
Tags can be used to iterate the [[Visual3D:Documentation:Pipeline:Pipeline_Commands:For_Each_and_End_For_Each|For Each]] loop or the loop could be used to tag filenames. The first example shows how one would iterate the [[Visual3D:Documentation:Pipeline:Pipeline_Commands:For_Each_and_End_For_Each|For Each]] based on fienames and tag based on those filenames.
!==============================================================
! The pipeline assumes that there are 3 sets of trials
! It loads and TAGS the files according to the filenames
!==============================================================
For_Each
/ITERATION_PARAMETER_NAME=FILE
/ITEMS=jump+run+walk
;
Open_File
/FILE_NAME=::FOLDER&*&::FILE&*.c3d
;
Assign_Tags_To_Files
/MOTION_FILE_NAMES=*&::FILE&*.c3d
! /QUERY=
/TAGS=::FILE
;
End_For_Each
/ITERATION_PARAMETER_NAME=FILE
;
This example shows how one would loop using tag names.
!===============================================================
! Below starts a loop that will perform calculations based on tag names run, jump, & walk
!===============================================================
For_Each
/Iteration_Parameter_Name=TagName
/Items= Run+Jump+Walk
;
! --------------------------------------------------------------
! This command will make active all of the files with the Indexed tag name
! --------------------------------------------------------------
Select_Active_File
/File_Name=::TagName
;
End_For_Each
/ITERATION_PARAMETER_NAME=TagName
;
== Nesting Loops ==
Loops can be nested within each other. This example shows how one would select files to process based on tagnames and signal names. The first loop selects the tag name as the active files to process and the parameter **EMG_SIGNALS** represents the signals that will be processed. Before the loop begins you would set the **EMG_SIGNALS** values using Set_Pipeline_Parameter (i.e. Rect_Fem, Gastroc).
!================================================
! This example normalizes the EMG signal.
!================================================
!------------------------------------------------
!Loop to select files with tag names
!------------------------------------------------
For_Each
/Iteration_Parameter_Name=TagName
/Items= Run+Jump+Walk
;
! --------------------------------------------------------------
! This command will make active all of the files with the Indexed tag name
! --------------------------------------------------------------
Select_Active_File
/File_Name=::TagName
;
!---------------------------------------------------------------
! Normalize EMG Loop - each signal in EMG_SIGNALS will be processed in the loop
!---------------------------------------------------------------
For_Each
/ITERATION_PARAMETER_NAME=INDEX
/ITEMS=::EMG_SIGNALS
;
Divide_Signals
/SIGNAL_TYPES=ANALOG+METRIC
/SIGNAL_NAMES=::INDEX+GLOBAL:&:&::INDEX&_MAX
/SIGNAL_FOLDER=EMG+EMG
/RESULT_NAME=::INDEX
/RESULT_FOLDER=EMG_NORM
;
Evaluate_Expression
/EXPRESSION=ANALOG::EMG:&:&::INDEX& / GLOBAL::METRIC::EMG:&:&::INDEX&_MAX
/RESULT_NAME=::INDEX
/RESULT_TYPE=ANALOG
/RESULT_FOLDER=EMG_NORM
;
End_For_Each
/ITERATION_PARAMETER_NAME=INDEX
;
End_For_Each
/Iteration_Parameter_Name=TagName
;
The following is an example of a 4 nested loop pipeline using tagnames, signal names, link based model names, and events.
!======================================================================================
! This example will calculate metrics for COP-COM, EMG Signals, and link based model at
! events for the selected tag named files.
!======================================================================================
!------------------------------------------------
!Loop to select files with tag names
!------------------------------------------------
For_Each
/Iteration_Parameter_Name=TagName
/Items= Run+Jump+Walk
;
Set_Pipeline_Parameter
/PARAMETER_NAME=EVENTS
/PARAMETER_VALUE=START+END
! /PARAMETER_VALUE_SEARCH_FOR=
! /PARAMETER_VALUE_REPLACE_WITH=
! /PARAMETER_VALUE_PREFIX=
! /PARAMETER_VALUE_APPEND=
;
! --------------------------------------------------------------
! This command will make active all of the files with the Indexed tag name
! --------------------------------------------------------------
Select_Active_File
/File_Name=::TagName
;
! --------------------------------------------------------------
! Start of COM-COP at Events Loop
! --------------------------------------------------------------
For_Each
/Iteration_Parameter_Name=INDEX
/Items= ::EVENTS
;
! --------------------------------------------------------------
! This command will calculate the metric at events for COM-COP
! --------------------------------------------------------------
Metric_Signal_Value_At_Event
/RESULT_METRIC_NAME=COM-COP&_&::INDEX
/RESULT_METRIC_FOLDER=VALUES_AT_EVENTS
/SIGNAL_TYPES=DERIVED
/SIGNAL_NAMES=COM-COP
/SIGNAL_FOLDER=PROCESSED
/EVENT_NAME=::INDEX
/GENERATE_MEAN_AND_STDDEV=TRUE
! /APPEND_TO_EXISTING_VALUES=FALSE
! /GENERATE_VECTOR_LENGTH_METRIC=FALSE
! /RETAIN_NO_DATA_VALUES=FALSE
;
! --------------------------------------------------------------
! Start of EMG at Events Loop
! --------------------------------------------------------------
For_Each
/Iteration_Parameter_Name=EINDEX
/Items= ::EMG_SIGNALS
;
! --------------------------------------------------------------
! This command will calculate the metric at events for EMG
! --------------------------------------------------------------
Metric_Signal_Value_At_Event
/RESULT_METRIC_NAME=::EINDEX&_&::INDEX
/RESULT_METRIC_FOLDER=VALUES_AT_EVENTS
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=::EINDEX
/SIGNAL_FOLDER=EMG_NORM
/EVENT_NAME=::INDEX
/GENERATE_MEAN_AND_STDDEV=TRUE
! /APPEND_TO_EXISTING_VALUES=FALSE
! /GENERATE_VECTOR_LENGTH_METRIC=FALSE
! /RETAIN_NO_DATA_VALUES=FALSE
;
End_For_Each
/Iteration_Parameter_Name=EINDEX
;
! --------------------------------------------------------------
! Start of Link Based Model at Events Loop
! --------------------------------------------------------------
For_Each
/Iteration_Parameter_Name=LBMINDEX
/Items= ::LINK_BASED_SIGNALS
;
! --------------------------------------------------------------
! This command will calculate the metric at events for all Link Based Model signals
! --------------------------------------------------------------
Metric_Signal_Value_At_Event
/RESULT_METRIC_NAME=::LBMINDEX&_&::INDEX
/RESULT_METRIC_FOLDER=VALUES_AT_EVENTS
/SIGNAL_TYPES=LINK_MODEL_BASED
/SIGNAL_NAMES=::LBMINDEX
/SIGNAL_FOLDER=ORIGINAL
/EVENT_NAME=::INDEX
/GENERATE_MEAN_AND_STDDEV=TRUE
! /APPEND_TO_EXISTING_VALUES=FALSE
! /GENERATE_VECTOR_LENGTH_METRIC=FALSE
! /RETAIN_NO_DATA_VALUES=FALSE
;
End_For_Each
/Iteration_Parameter_Name=LBMINDEX
;
End_For_Each
/Iteration_Parameter_Name=INDEX
;
=== While Loop ===
Visual3D doesn't have a WHILE command, so there is no option but to use a kludge. Refer to [[|Example: Implementing a //while// loop]] for details of an example work around.
=== Scripts calling scripts ===
Visual 3D scripts can call other scripts by using the [[Visual3D:Documentation:Pipeline:Other_Commands:Call_Script|Call_Script]] command. This can be used to smoothly link multiple scripts together for efficiency. For an example, refer to the [[Visual3D:Documentation:Pipeline:Other_Commands:Call_Script|Call_Script]] page.
=== If Then or other conditional loops ===
There is no IF...THEN command, but often there are workarounds that accomplish the same thing. The use of logical operators and expressions can be used in place of an IF... THEN... Else command to setup a conditional expression. An example can be found on [[#Conditional_Expressions|Pipeline_Script_examples#Conditional_Expressions]] and another example can be found on [[Visual3D:Documentation:Pipeline:Expressions:Expressions_Overview#Example:_Conditional_Statement|Expressions#Example:_Conditional_Statement]].
To illustrate, the example below uses a logical operator to find out if a signal is negative (below zero). The result is used in an expression to calculate a constant variable (either -1 or 1) that is multiplied to the signal.
! Prompt the user for the FOLDER containing the data files
Set_Pipeline_Parameter_To_Folder_Path
/PARAMETER_NAME=FOLDER
/PARAMETER_VALUE=
! /PARAMETER_VALUE_SEARCH_FOR=
! /PARAMETER_VALUE_REPLACE_WITH=
! /PARAMETER_VALUE_APPEND=
;
! For_Each loop for 3 files
For_Each
/ITERATION_PARAMETER_NAME=INDEX
/ITEMS=01+02+03
;
Set_Pipeline_Parameter
/PARAMETER_NAME=FILE
/PARAMETER_VALUE=::FOLDER&task&::INDEX&.c3d
;
Select_Active_File
/FILE_NAME=::FILE
;
! Use the Boolean operator < to identify when ::METRIC::PROCESSED::POSITION_MEAN is less than 0
! The output signal will be 1 when ::METRIC::PROCESSED::POSITION_MEAN
! is less than 0 (negative) and 0 otherwise.
! The Metric POSITION_NEGATIVE will be -1 or 1.
Evaluate_Expression
/EXPRESSION= 1-(METRIC::PROCESSED::POSITION_MEAN < 0)*2
/RESULT_NAME=POSITION_NEGATIVE
/RESULT_TYPE=METRIC
/RESULT_FOLDER=PROCESSED
;
!POSITION is multiplied by POSITION_NEGATIVE which is 1 or -1 for the side.
Multiply_Signals_By_Constant
/SIGNAL_TYPES=ANALOG
/SIGNAL_NAMES=POSITION
/SIGNAL_FOLDER=PROCESSED
/RESULT_NAMES=POSITION_CORRECTED
!/RESULT_TYPES=
!/RESULT_FOLDER=PROCESSED
! /RESULT_SUFFIX=
! /SIGNAL_COMPONENTS=
/CONSTANT=METRIC::PROCESSED::POSITION_NEGATIVE
;
! End File Loop
End_For_Each
/ITERATION_PARAMETER_NAME=INDEX
;
==== Signal Processing ====
There are several pipeline commands related to interpolating, filtering, and signal math.
=== Filtering ===
Visual3D has many commands related to signal processing. The previous command pipeline tutorial touched on interpolation and lowpass filtering commands. The [[Visual3D:Tutorials:EMG:Typical_EMG_Processing|Tutorial EMG]] page lays out how one would process EMG with MVC trials using pipeline commands. This tutorial processes the EMG signals with a highpass filter command, then a lowpass filter command, and creates a linear envelope with a moving RMS window command. In addition, a normalizing scale factor is applied to the EMG signals.
=== Signal Math ===
There are many pipeline commands for signal math. One of the most powerful and useful commands is **Evaluate_Expression**. Rather than repeat content here, please go to the [[Visual3D:Documentation:Pipeline:Expressions:Expressions_Overview|Expressions]] page for more details on this command and several very good examples. Another great example can be found here https://www.c-motion.com/v3dwiki/index.php?title=Pipeline_Script_examples#Example_Script
==== Model Creation ====
Model creation can occur manually [[Visual3D:Tutorials:Modeling:Building_a_Model|Tutorial: Building a Model]] or via the command pipeline [[Visual3D:Documentation:Pipeline:Model_Commands:Modeling_Commands|Pipeline Commands:Modeling]]. This tutorial will show two examples: one that shows how to construct the model via step by step commands or by using commands to apply an already constructed model template.
=== Model Metrics ===
First let's set the stage by discussing model metrics. [[Visual3D:Documentation:Modeling:Model_Metrics_|Model Metrics]] are values used in the construction of a model. These metrics include the MASS and HEIGHT of the subject, segment radius values that are computed during the construction of segments, or any other needed values to construct the model (i.e. leg length; knee width; ankle width; rotation correction - [[|Model Metrics Example 1]]; [[Visual3D:Documentation:Modeling:Segments:Knee_Alignment_Device|Knee Alignment Device]]- KAD arm length). Model metrics can be added and edited manually or pipeline commands can be used to add or edit. The model metric pipeline commands are:
* [[Visual3D:Documentation:Pipeline:Model_Commands:Set_Model_Metric|Set_Model_Metric]]
* [[Visual3D:Documentation:Pipeline:Model_Commands:Set_Subject_Height|Set_Subject_Height]]
* [[Visual3D:Documentation:Pipeline:Model_Commands:Set_Subject_Weight|Set_Subject_Weight]]
Users can be prompted to enter in values (see example in previous section https://www.c-motion.com/v3dwiki/index.php?title=Tutorial:_Advanced_Command_Pipeline#Direct_input_prompts or this page for another example [[Visual3D:Tutorials:Pipeline:Basic_Pipeline_for_Processing_a_Session|Tutorial Basic Pipeline For Processing A Session]]). Both [[Visual3D:Documentation:Pipeline:Model_Commands:Set_Subject_Height|Set_Subject_Height]] and [[Visual3D:Documentation:Pipeline:Model_Commands:Set_Subject_Weight|Set_Subject_Weight]] pages show how expressions can be used in the model metric command. The [[Visual3D:Documentation:Pipeline:Model_Commands:Set_Subject_Weight|Set_Subject_Weight]] page shows an example of how one would calculate subject weight based on the force platform signal and set the metric subject weight.
Refer to his page [[Visual3D:Documentation:Pipeline:Metric_Commands:Metric_From_Parameter|Metric From Parameter]] for an example of pulling in height, weight, etc that was saved in a C3D parameter section by the motion system.
=== Build Model ===
In some circumstances Visual3D does not automatically rebuild the model. When constucting your pipeline commands, always place the command [[Visual3D:Documentation:Pipeline:Model_Commands:Build_Model|Build_Model]] at the end of your modeling related commands. For example,
! Create a landmark Lab_X
Add_Landmark
/LANDMARK_NAME=LAB_X
/CALIBRATION_FILE=*static.c3d
! /USER_GENERATED=TRUE
! /USE_PERCENTAGE=FALSE
! /CALIBRATION_ONLY=FALSE
!/USE_TARGETS=FALSE
/SEGMENT_NAME=LAB
! /TARGET_TYPES=
! /TARGET_NAMES=
/MCSX=.01
/MCSY=0
/MCSZ=0
! /LANDMARK_LOCATION=
! /REFERENCE_LOCATION_NAME=
! /REFERENCE_LOCATION_TYPE=
! /USE_REFERENCE_LOCATION=FALSE
;
! Update the landmarks by building the model
Build_Model
! /CALIBRATION_FILE=
! /REBUILD_ALL_MODELS=FALSE
! /DISPLAY_RESULTS=TRUE
;
=== Using commands to apply an already constructed model template ===
Typically a model is defined manualy and a model template is saved for that model. Commands can be used to [[Visual3D:Documentation:Pipeline:Model_Commands:Apply_Model_Template|Apply Model Template]] to the static and [[Visual3D:Documentation:Pipeline:Model_Commands:Assign_Model_File|Assign Model File]] to the movement files. A great example can be found on [[|Pipeline Processing Example 2]]. [[|Pipeline Processing Example 6]] expands on this to apply a model template to multiple conditions.
=== Using commands to modify a model ===
There are several pipeline commands relating to modification of a model. Commands are available for adding or modifying landmarks and setting segment properties. Model creation can be also be accomplished via **HYBRID_SEGMENT** command which isn't available in the pipeline workshop interface but the syntax is available in the [[Visual3D:Documentation:Modeling:Model_Templates|Model Templates]]. The example in the next section uses this command. Care should be taken using this command.
== Add or modify landmarks ==
Landmarks can be added and modified using the [[Visual3D:Documentation:Pipeline:Model_Commands:Add_Landmark|Add_Landmark]] and [[Visual3D:Documentation:Pipeline:Model_Commands:Modify_Landmark|Modify_Landmark]] commands.
There is an example on https://www.c-motion.com/v3dwiki/index.php?title=Static_Trial#Multiple_Static_trials_using_a_Pipeline where one or more markers are used to define a segment that is obscured. The pipeline script will create a segment and add a landmark.
Another great example can be seen on [[Visual3D:Documentation:Modeling:Landmarks:Example_-_Landmarks_from_Motion_File|Landmarks From Motion File]]. This example creates landmarks from a set of stairs.
== Segment Properties ==
Segment properties can be defined or edited via the [[Visual3D:Documentation:Pipeline:Model_Commands:Set_Segment_Properties|Set Segment Properties]] command. Any property can be changed/edited using this command.
Since Visual3D does not allow users to specify the segment depth as an expression, a user could construct the segment (i.e. Thorax) with a "dummy" depth number (0.12) and use the pipeline below to calculate a depth value based on targets/landmarks on the segment. Some great examples can be found on [[Visual3D:Documentation:Modeling:Segments:Segment_Properties_Example|Segment Properties Example1]].
==== Compute Link based Model ====
The command [[Visual3D:Documentation:Pipeline:Model_Based_Data_Commands:Compute_Model_Based_Data|Compute Model Based Data]] will
=== Joint Angles ===
=== Joint Moments ===
== Normalization ==
Moments can be normalized to subject mass in kg (which is the default) or subject mass*leg length or subject mass*height. The [[Visual3D:Documentation:Pipeline:Model_Based_Data_Commands:JOINT_MOMENT|Model_Based_Item:_JOINT_MOMENT]] has two pipeline script examples regarding normalization. One related to mass*height and the other relating to mass*leg length. The [[Visual3D:Documentation:Pipeline:Model_Based_Data_Commands:JOINT_MOMENT#Calculating_leg_length_-_distance_between_ASIS_and_Medial_Malleolus|Model_Based_Item:_JOINT_MOMENT#Calculating_leg_length_-_distance_between_ASIS_and_Medial_Malleolus]] will calculate the leg length based on the distance between the ASIS and medial malleolus. The script will then create a model metric for mass*leg length that can be used to normalize the joint moment.
==== Event Creation ====
The command pipeline has several commands related to creating and managing events. Refer to [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Commands_Overview|Event Commands]] and [[Visual3D:Tutorials:Events:Event_Processing_|Tutorial: Event Processing]] for more information on how to manually create events. Remember that an event is simply an occurrence of interest that correlates to a motion capture frame, i.e. to a particular time point within a movement. There are many ways to create and use events. Any signal whether it is an analog signal, derived signal, or even a compute model based signal can be used to define an event. This section will detail some examples of how events may be used in your pipeline command scripts. More examples can be found on [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Examples|Event_Examples]]
=== Event Explicit ===
We recommend always defining an explicit event for the start and end of file (EOF) in your scripts. Either time or frames can be used. It does not have to be the first frame or last frame. Any set of frames that will bookend the time frame of interest will do. Refer to [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Explicit|Event_Explicit]] for details on the command and a few examples. You can also refer to [[Visual3D:Documentation:Pipeline:Event_Commands:Example_-_Creating_Event_at_the_last_frame_of_data|Events:Example 1]] for 3 examples defining an event at the last frame or EOF. [[Visual3D:Documentation:Pipeline:Event_Commands:Example_-_Using_Event_Explicit|Events:Example 9]] also has a good explicit event example.
=== Events from Force Platform Signals ===
Force platforms can be used to define an event for heelstrike and toeoff. We will illustrate two examples; one using [[Visual3D:Documentation:Pipeline:Event_Commands:Automatic_Gait_Events|Automatic_Gait_Events]] command and the other using the [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Threshold|Event_Threshold]] command.
== Automatic_Gait_Events ==
This command uses the force platform signal to define foot strike and toeoff events. If the parameter **/USE_TPR=TRUE**, then the TPR algorithm is used to find the heelstrike (HS) and toeoff (TO) based on the trajectory of the proximal end of the foot segment (i.e. **LHS**, **LTO**, **LON**, **LOFF**). If this parameter is set to **FALSE**, then "ON" and "OFF" events will be created (i.e. **LON**, **LOFF**). Refer to [[Visual3D:Documentation:Pipeline:Event_Commands:Automatic_Gait_Events|Automatic_Gait_Events]] for more detail.
Automatic_Gait_Events
! /SELECT_X=FALSE
! /SELECT_Y=FALSE
! /SELECT_Z=TRUE
! /FRAME_WINDOW=8
! /USE_TPR=TRUE
;
== Event_Threshold for Force Platform events ==
The [[Visual3D:Documentation:Pipeline:Event_Commands:Automatic_Gait_Events|Automatic_Gait_Events]] command does the bookeeping for you regarding the side that contacts the force platform. If you are collecting unilateral data and wish to control the onset or threshold value, the [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Threshold|Event_Threshold]] command can be used. Here is an example of using this command to find the right foot contact and right toeoff based on a threshold of 30 for the Z component of the FP1 force platform signal. The ascending and descending parameters are used to define the event. Notice the use of explicit events here.
Explicit
/EVENT_NAME=Start
/FRAME=1
! /TIME=
;
Event_Explicit
/EVENT_NAME=End
/FRAME=250
! /TIME=
;
Event_Threshold
/SIGNAL_TYPES=FORCE
/SIGNAL_NAMES=FP1
/SIGNAL_FOLDER=PROCESSED
/EVENT_NAME=Right_Foot_Contact
! /SELECT_X=FALSE
! /SELECT_Y=FALSE
/SELECT_Z=TRUE
! /SELECT_RESIDUAL=FALSE
/THRESHOLD=30
! /FRAME_WINDOW=8
! /FRAME_OFFSET=0
/ASCENDING=TRUE
! /DESCENDING=FALSE
! /ENSURE_RANGE_FRAMES_BEFORE_THRESHOLD_CROSSING=FALSE
! /ENSURE_RANGE_FRAMES_AFTER_THRESHOLD_CROSSING=FALSE
/START_AT_EVENT=Start
/END_AT_EVENT=End
/EVENT_INSTANCE=1
;
Event_Threshold
/SIGNAL_TYPES=FORCE
/SIGNAL_NAMES=FP1
/SIGNAL_FOLDER=PROCESSED
/EVENT_NAME=Right_Toe_Off
! /SELECT_X=FALSE
! /SELECT_Y=FALSE
/SELECT_Z=TRUE
! /SELECT_RESIDUAL=FALSE
/THRESHOLD=30
! /FRAME_WINDOW=8
! /FRAME_OFFSET=0
! /ASCENDING=FALSE
/DESCENDING=TRUE
! /ENSURE_RANGE_FRAMES_BEFORE_THRESHOLD_CROSSING=FALSE
! /ENSURE_RANGE_FRAMES_AFTER_THRESHOLD_CROSSING=FALSE
/START_AT_EVENT=Right_Foot_Contact
! /END_AT_EVENT=End
/EVENT_INSTANCE=1
;
=== Event_TPR_Signal ===
This example uses the [[Visual3D:Documentation:Pipeline:Event_Commands:Event_TPR_Signal|Event_TPR_Signal]] command to create events based on a heel strike event **RHS** that was created manually. The [[Visual3D:Documentation:Pipeline:Event_Commands:Event_TPR_Signal|Event_TPR_Signal]] command in this example creates another heel strike event based on the **X** (anterior/posterior) and **Z** (vertical) components of the **RHEEL** target signal.
Event_TPR_Signal
/PATTERN_FILE=C:\Data\Walking.c3d
/PATTERN_TYPE=TARGET
/PATTERN_SIGNAL=RHEEL
! /PATTERN_FOLDER=ORIGINAL
/PATTERN_EVENT_NAME=RHS
! /PATTERN_EVENT_INSTANCE=1
/SELECT_X=TRUE
! /SELECT_Y=FALSE
/SELECT_Z=TRUE
! /TPR_WINDOW=7
/TOLERANCE=20
/SIGNAL_TYPES=TARGET
/SIGNAL_NAMES=RHEEL
! /SIGNAL_FOLDER=ORIGINAL
/EVENT_NAME=RHS
;
**Note:** The [[Visual3D:Documentation:Pipeline:Event_Commands:Event_TPR_Signal|Event_TPR_Signal]] command can be used to find any event based on matching data from a range of frames against the same (or a different signal). It can be used for creating events based on any signal (not just gait related events). Something to keep in mind...
=== Event_Threshold ===
The [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Threshold|Event_Threshold]] command can be used for more than force platform signals. There are several great examples in the wiki using the Event_Threshold command. Rather than construct another example here, we will list a few for your review:
* [[Visual3D:Documentation:Pipeline:Event_Commands:Example_-_Event_Threshold_to_create_10%_increments|Events:Example 4]] uses **Event_Threshold** command to create 10% increments of the range of motion of a signal.
* [[Visual3D:Documentation:Pipeline:Event_Commands:Example_-_Event_Threshold_using_height_of_a_segment_|Events:Example 5]] uses the **Event_Threshold** command to compute an event based on the height of the hand relative to the height of the acromium.
* [[Visual3D:Documentation:EMG:Filtering:Linear_Envelope|EMG_Onset]] uses the **Event_Threshold** command to compute the onset of EMG activity.
=== Event_Onset ===
You might use the command [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Onset|Event_Onset]] to create an event at an initiation of movement (i.e. gait initiation). This example calculates the heel velocity and uses the [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Onset|Event_Onset]] command to create an event when the baseline of the signal ascends to a particular threshold. In this case the baseline is 0 and the threshold is set at .001. Another great example can be found on the [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Onset|Event_Onset]] page.
!Calculate heel velocity
First_Derivative
/SIGNAL_TYPES=TARGET
/SIGNAL_NAMES=RHEEL
! /SIGNAL_FOLDER=ORIGINAL
! /RESULT_NAMES=
! /RESULT_TYPES=
! /RESULT_FOLDER=PROCESSED
/RESULT_SUFFIX=_Vel
;
! Create an event when the heel velocity rises from zero to a threshold of .001
Event_Onset
/SIGNAL_TYPES=TARGET
/SIGNAL_NAMES=RHEEL_Vel
/SIGNAL_FOLDER=PROCESSED
/EVENT_NAME=TEST
/SELECT_X=FALSE
/SELECT_Y=TRUE
! /SELECT_Z=FALSE
/THRESHOLD=.001
! /THRESHOLD_INSTANCE=0
! /BASELINE=0
! /FRAME_WINDOW=8
! /FRAME_OFFSET=0
/ASCENDING=TRUE
! /DESCENDING=FALSE
/START_AT_EVENT=START
/END_AT_EVENT=END
;
=== Creating Events at Maximums and Minimums ===
Events can be created at signal maximums and minimums. This can be a global maximum or minimum event using either the [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Global_Minimum|Event_Global_Minimum]] or [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Global_Maximum|Event_Global_Maximum]] commands. Or it can be several maximum or minimum events for the signal using either the [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Minimum|Event_Minimum]] or [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Maximum|Event_Maximum]] commands. Using these commands allows you to bookend your analysis with these events or find values and timing based on the events. Here is a common example of using the [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Global_Maximum|Event_Global_Maximum]] command to find the event at the maximum of a signal, then find the value at that event, and the timing.
! This example finds the vertical force from a force platform and then find the value
! of the maximum force and timing.
! Find event at peak vertical force
Event_Global_Maximum
/SIGNAL_TYPES=FORCE
/SIGNAL_NAMES=FP1
/SIGNAL_FOLDER=PROCESSED
/EVENT_NAME=Event_Peak_Fz
! /SELECT_X=FALSE
! /SELECT_Y=FALSE
/SELECT_Z=TRUE
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
/START_AT_EVENT=RHS
/END_AT_EVENT=RTO
;
! Find the force at the maximum event Event_Peak_Fz
Metric_Signal_Value_At_Event
/RESULT_METRIC_NAME=Peak_Fz
! /RESULT_METRIC_FOLDER=PROCESSED
/SIGNAL_TYPES=FORCE
/SIGNAL_NAMES=FP1
/SIGNAL_FOLDER=PROCESSED
/EVENT_NAME=Event_Peak_Fz
/GENERATE_MEAN_AND_STDDEV=FALSE
! /APPEND_TO_EXISTING_VALUES=FALSE
! /GENERATE_VECTOR_LENGTH_METRIC=FALSE
! /RETAIN_NO_DATA_VALUES=FALSE
;
! Find the time to the Peak_Fz from the RHS event
Metric_Time_Between_Events
/RESULT_METRIC_NAME=Time_to_Peak_Fz
! /RESULT_METRIC_FOLDER=PROCESSED
/EVENT_SEQUENCE=RHS+Event_Peak_Fz
/EXCLUDE_EVENTS=
/GENERATE_MEAN_AND_STDDEV=FALSE
! /APPEND_TO_EXISTING_VALUES=FALSE
;
Here are a few more examples for your review:
* [[Visual3D:Documentation:Pipeline:Event_Commands:Example_-_Creating_Event_at_the_last_frame_of_data|Events:Example 1]] shows an example of creating an event at the last frame of data using the [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Global_Maximum|Event_Global_Maximum]] command.
* [[Visual3D:Documentation:Pipeline:Event_Commands:Example_-_Identify_Events_at_Local_Max|Events:Example 13]] shows an example of creating events at the maximums of a sinusoidal signal.
=== Event Management ===
There are several commands relating to event management (copy, delete, or highlight events). These commands can be very useful in your pipeline scripts.
The [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Copy|Event_Copy]] command can be used to copy an event with a different name for temporary processing or the command can be used to offset an event via time or frame. Below is an example of copying an event with an offset.
! Calculate an event INITIATION_100 which would be 100 frames prior to the INITIATION event
Event_Copy
/EVENT_NAME=INITIATION
/NEW_EVENT_NAME=INITIATION_100
/FRAME_OFFSET=-100
! /EVENT_INSTANCE=0
! /RANGE_INSTANCE=0
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
! /START_AT_EVENT=
! /END_AT_EVENT=
;
Another example can be found on [[Visual3D:Documentation:Pipeline:Event_Commands:Example_-_Using_Event_Copy|Events:Example 10]]. Your pipeline may use temporary events during processing. To clean up your events the [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Delete|Event_Delete]] command can be used to delete these temporary events. A great example of using both [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Copy|Event_Copy]] and [[Visual3D:Documentation:Pipeline:Event_Commands:Event_Delete|Event_Delete]] for pipeline calculations is found on the [[Visual3D:Documentation:Pipeline:Event_Commands:Example_-_Using_Event_Delete|Events:Example 3]].
[[Visual3D:Documentation:Pipeline:Other_Commands:Highlight_Event_Label|Highlight_Event_Label]] is another command that is useful for checking events that are created. This command highlights an Event in the 2D Graphs (in Signal and Event Processing Mode). For convenience in checking the created events, Visual3D can be switched to Event Processing mode. Below is an example.
! Graph the vertical position of the heel marker and highlight the events
Switch_to_Event_Processing_Mode
;
Interactive_Graph_Signals
/SIGNAL_TYPES=TARGET
/SIGNAL_NAMES=RHEEL
/SIGNAL_FOLDER=PROCESSED
/SIGNAL_COMPONENTS=Z
/GRAPH_INDEX=1
/GRAPH_SUBINDEX=1
/REPLACE_CURRENT=TRUE
;
Highlight_Event_Label
/EVENT_LABEL=RHS+RON+ROFF+RTO
;
To make it easier to export event times, you can use the evaluate_epression command to extract the event times and copy them to a particular folder (i.e. metric folder). Go to [[Visual3D:Documentation:Pipeline:Expressions:Expressions_Overview#Example:_Extract_Event_Times|Expressions#Example:_Extract_Event_Times]] for an example.
==== Metric ====
[[Visual3D:Documentation:Visual3D_Signal_Types:METRIC_Data_Type|Metrics]] are discrete quantitative values of signals such as maximum value, median value, value at a specified frame. In other words, metrics do not have a time-base like the other signals. Visual 3D has many commands to create metric values from signals. We will discuss some commands and give some examples for your review.
A great example that encompasses two metric commands can be found on the [[Visual3D:Documentation:Pipeline:Model_Based_Data_Commands:Joint_Work|Joint_Work]] page. This example uses [[Visual3D:Documentation:Pipeline:Metric_Commands:Metric_Integrate|Metric_Integrate]] to calcuate the time integral and [[Visual3D:Documentation:Pipeline:Metric_Commands:Metric_Sum|Metric_Sum]] to sum the positive and negative work to calculate total work.
=== Metric Explicit ===
You can create an explicit value by using the [[Visual3D:Documentation:Pipeline:Metric_Commands:Metric_Explicit|Metric_Explicit]] command. This can be useful to define an initial value of a metric or provide a counter for a loop. A great example of this can be found on [[Visual3D:Documentation:EMG:Processing:Normalize_EMG_to_MVC|EMG Example 3]] where the [[Visual3D:Documentation:Pipeline:Metric_Commands:Metric_Explicit|Metric_Explicit]] is used to define a counter in a loop. A [[Visual3D:Documentation:Pipeline:Metric_Commands:Metric_Explicit|Metric_Explicit]] can also be used to force an error in your pipeline script. An example from [[|Pipeline Processing Example 7]] is shown below:
! Initialize a Global Metric that we will use to force an error in the pipeline
Explicit_Metric
/RESULT_METRIC_NAME=GLOBAL::TEST
! /RESULT_METRIC_FOLDER=PROCESSED
/METRIC_VALUE=0
;
=== Metric Maximums and Metric Minimums ===
Maximums and minimums are the most common type of metric. Users can choose to:
* calculate an event at maximum or minimum signal and then find the value at that event
* calculate a maximum or minimum signal value
This section describes finding a maximum or minimum value. A good example can be found on [[Visual3D:Documentation:Pipeline:Event_Commands:Example_-_Event_Threshold_to_create_10%_increments|Events:Example 4]]. This example creates a series of Event Labels in which the threshold crossing is set at 10% increments of the range of motion of a signal (in this example the y-component of LFT1).
=== Metric_Signal_Value_At_Event ===
As previously mentioned, a user can choose to find an event at a maximum or minimum signal and then calcuate the value at that event. The [[Visual3D:Documentation:Pipeline:Metric_Commands:Metric_Signal_Value_At_Event|Metric_Signal_Value_At_Event]] is used to find the value at an event. The first example [[Visual3D:Documentation:Pipeline:Metric_Commands:Example_-_Value_at_an_Event|Metrics_Example_2]] combines the uses of loops to iterate through events and calculate the metric signal at those events. This is a great example of finding a metric at multiple occurances for left and right sides and the resulting values are combined in one metric signal. Another good example can be found on [[Visual3D:Documentation:Pipeline:Signal_Commands:Computing_the_Range_of_Motion#Example_1:_Compute_Range_of_Motion_from_events|Computing_the_Range_of_Motion#Example_1:_Compute_Range_of_Motion_from_events]]. The script for this example can be used to find range of motion at a joint.
Currently this command outputs all three components of a signal. The [[Visual3D:Documentation:Pipeline:Metric_Commands:Metric_Signal_Value_At_Event|Metric_Signal_Value_At_Event]] page has a workaround that will allow the user to output one component using the Evaluate_Expression command. In a future version of Visual3D, the option to select a component will be implemented.
=== Metric Time Between Events ===
Many times it is necessary to calculate times relative to a particular event. The command [[Visual3D:Documentation:Pipeline:Metric_Commands:Metric_Time_Between_Events|Metric Time Between Events]] will perform this calculation. This example calculates the time between the beginning event, **BEGIN_EVENT** and ending event, **END_EVENT** to get a time range, **RANGE_TIME**. The example also calculates time to max, **MAX_TIME** which is the time between the **BEGIN_EVENT** to **MAX_EVENT**. In addition, the **MAX_TIME** is found as a percentage of **RANGE_TIME**.
! Calculate time range between begin and end events
Metric_Time_Between_Events
/RESULT_METRIC_NAME=RANGE_TIME
! /RESULT_METRIC_FOLDER=PROCESSED
/EVENT_SEQUENCE=BEGIN_EVENT+END_EVENT
/EXCLUDE_EVENTS=
! /GENERATE_MEAN_AND_STDDEV=TRUE
! /APPEND_TO_EXISTING_VALUES=FALSE
;
! Calculate time to max
Metric_Time_Between_Events
/RESULT_METRIC_NAME=MAX_TIME
! /RESULT_METRIC_FOLDER=PROCESSED
/EVENT_SEQUENCE=BEGIN_EVENT+MAX_EVENT
/EXCLUDE_EVENTS=
! /GENERATE_MEAN_AND_STDDEV=TRUE
! /APPEND_TO_EXISTING_VALUES=FALSE
;
! Calculate the max time in percentage MAX_PERCENTAGE by dividing MAX_TIME by RANGE_TIME
Divide_Signals
/SIGNAL_TYPES=METRIC+METRIC
/SIGNAL_NAMES=MAX_TIME+RANGE_TIME
/SIGNAL_FOLDER=PROCESSED+PROCESSED
/RESULT_NAME=MAX_PERCENTAGE
! /RESULT_FOLDER=PROCESSED
;
The above example works great unless the maximum event is located at the start event (time between = 0). The command [[Visual3D:Documentation:Pipeline:Metric_Commands:Metric_Time_Between_Events|Metric_Time_Between_Events]] will not allow zero time. This is because there could be multiple foot contact event instances and Visual 3D would not know which instance of that event to use for the calculation. To workaround this, we recommend making another event 2 frames prior to the start event. After using the metric_time_between_events command to find the time, use evaluate expression to account for the 2 frame offset in timing and percent.
! Get the time for the range
Metric_Time_Between_Events
/RESULT_METRIC_NAME=RANGE
! /RESULT_METRIC_FOLDER=PROCESSED
/EVENT_SEQUENCE=LHS+LTO
/EXCLUDE_EVENTS=
/GENERATE_MEAN_AND_STDDEV=FALSE
! /APPEND_TO_EXISTING_VALUES=FALSE
;
! Find an event at the maximum value in an event sequence
Event_Global_Maximum
/SIGNAL_TYPES=TARGET
/SIGNAL_NAMES=LFT1
! /SIGNAL_FOLDER=ORIGINAL
/EVENT_NAME=LFT1_Max
!/SELECT_X=FALSE
! /SELECT_Y=FALSE
/SELECT_Z=TRUE
/EVENT_SEQUENCE=LHS+LTO
! /EXCLUDE_EVENTS=
! /START_AT_EVENT=
! /END_AT_EVENT=
;
! Flexion Peak Value
Metric_Signal_Value_At_Event
/Result_Metric_Name=LFT1_Max
/Result_Metric_Folder=PROCESSED
/Signal_Types=TARGET
/Signal_Names=LFT1
/Signal_Folder=ORIGINAL
/Event_Name=LFT1_Max
/Generate_Mean_And_Stddev=FALSE
/Append_To_Existing_Values=FALSE
/Generate_Metric_Length_Metric=FALSE
/Retain_No_Data_Values=TRUE
;
! Get the time from the copied event to the max event
Metric_Time_Between_Events
/RESULT_METRIC_NAME=LFT1_Max_Time_Command
! /RESULT_METRIC_FOLDER=PROCESSED
/EVENT_SEQUENCE=LHS+LFT1_Max
/EXCLUDE_EVENTS=
/GENERATE_MEAN_AND_STDDEV=FALSE
! /APPEND_TO_EXISTING_VALUES=FALSE
;
! Copy the first event in the sequence with an offset of -2 frames
Event_Copy
/EVENT_NAME=LHS
/NEW_EVENT_NAME=LHS_M2
/FRAME_OFFSET=-2
! /TIME_OFFSET=
! /PERCENT_OFFSET=
! /EVENT_INSTANCE=0
! /RANGE_INSTANCE=0
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
! /START_AT_EVENT=
! /END_AT_EVENT=
;
! Get the time from the copied event to the max event
Metric_Time_Between_Events
/RESULT_METRIC_NAME=LFT1_Max_Time_M2
! /RESULT_METRIC_FOLDER=PROCESSED
/EVENT_SEQUENCE=LHS_M2+LFT1_Max
/EXCLUDE_EVENTS=
/GENERATE_MEAN_AND_STDDEV=FALSE
! /APPEND_TO_EXISTING_VALUES=FALSE
;
! Get the time of maximum within the range (accounting for the offset).
Evaluate_Expression
/EXPRESSION=METRIC::PROCESSED::LFT1_Max_Time_M2-(2/PARAMETER::POINT::RATE)
/RESULT_NAME=LFT1_Max_Time
/RESULT_TYPE=METRIC
! /RESULT_FOLDER=PROCESSED
;
! Get the % time of maximum within the range (accounting for the offset).
Evaluate_Expression
/EXPRESSION=(METRIC::PROCESSED::LFT1_Max_Time_M2-(2/PARAMETER::POINT::RATE))/(METRIC::PROCESSED::RANGE)
/RESULT_NAME=LFT1_Max_Time_Per
/RESULT_TYPE=METRIC
! /RESULT_FOLDER=PROCESSED
;
==== Report Generation ====
Visual3D has several report pipeline commands. These can be found on the [[Visual3D:Documentation:Pipeline:Report_Commands:Report_Commands_Overview|Report Commands]] page.
=== Example ===
Here is an example of a script that will create a report (1 page) with normal data from a normal database file (*.vnd). The created graphs will be annotated by a vertical line for TO. Events will be created at the Global maxes and mins for each angle. The graphs will be annotated with black "x's" for mins and maxes. The script will print the newly created report. This example assumes that the Left Hip and Knee angles have been created and events LHS have been created.
!******************************************************************************
!This script is an example of how to create a report from the command pipeline
!******************************************************************************
! Switch the view to Report Mode
Switch_to_Report_Mode
! /SHOW_ANIMATION=FALSE
! /PAGE_NUMBER=
;
! Set Report options such as page layout
Set_Report_Options
! /PAGE_LAYOUT=LANDSCAPE
;
! Set the Report Title page
Set_Report_Page_Title
/PAGE_NUMBER=1
/PAGE_TITLE=Left Joint Angles
;
!---------------------------------------------------------------------------------------
! Graph Left Hip Angles and add a line for TO as well as a cross for max and min points
!---------------------------------------------------------------------------------------
! Add a graph to report page 1 at col 1 row 1
! Left Hip Angle component X (Flex/Ext) for ALL_FILES. The line color is Red
! and it is plotted from LHS to LHS
Make_Line_Graph
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=1
! /COLUMN_SPAN=1
! /ROW_SPAN=1
/GRAPH_TITLE=Hip Angle
/FILES_TO_GRAPH=ALL_FILES
! /DISPLAY_LEGEND=FALSE
! /LEGEND_LOCATION=UR
! /LEGEND_TEXT=
! /LINE_STYLE=Solid
/LINE_COLOR=Red
! /LINE_BOLD=FALSE
! /SHOW_POINTS=FALSE
! /GRAPH_MEAN=FALSE
! /GRAPH_STDDEV=FALSE
! /MEAN_STDDEV_LINE_STYLE=Solid
! /MEAN_STDDEV_LINE_COLOR=Black
! /MEAN_STDDEV_LINE_BOLD=FALSE
/USE_EVENT_RANGE=TRUE
/START_EVENT_LABEL=LHS
/END_EVENT_LABEL=LHS
! /INTERMEDIATE_EVENTS=
! /EXCLUDE_EVENTS=
! /X_AXIS_LABEL=
/X_DATA_TYPE=FRAME_NUMBERS
/X_DATA_NAME=Time
! /X_DATA_COMPONENT=
! /X_DATA_PROCESSED=ORIGINAL
! /X_AXIS_SCALE=Normalize 0% to 100%
/Y_AXIS_LABEL=Degrees
/Y_DATA_TYPE=LINK_MODEL_BASED
/Y_DATA_NAME=Left Hip Angle
/Y_DATA_COMPONENT=X
/Y_DATA_PROCESSED=ORIGINAL
! /Y_AXIS_SCALE=Global Min to Max
! /Y_USE_SCIENTIFIC_NOTATION=FALSE
;
! Set the Y axis range explicitly for Left Hip Angles
Modify_Line_Graph
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=1
! /COLUMN_SPAN=1
! /ROW_SPAN=1
! /GRAPH_TITLE=
! /X_AXIS_LABEL=
! /X_AXIS_SCALE=Normalize 0% to 100%
! /X_AXIS_MIN=
! /X_AXIS_MAX=
! /Y_AXIS_LABEL=
/Y_AXIS_SCALE=By Explicit Setting
/Y_AXIS_MIN=-20
/Y_AXIS_MAX=30
! /Y_USE_SCIENTIFIC_NOTATION=FALSE
;
! Create a vertical red line at LTO
Add_Graph_Annotation
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=1
/DRAW_ORDER=1
/ANNOTATION_EVENT=LTO
/ANNOTATION_STYLE=Vertical Line
/ANNOTATION_COLOR=Red
! /ANNOTATION_SIZE=Normal
/ANNOTATION_GLOBAL=FALSE
/ANNOTATION_AVERAGE_EVENT=TRUE
;
! Create a Global Max Event for Left Hip Angles from LHS to LHS
Event_Global_Maximum
/SIGNAL_TYPES=LINK_MODEL_BASED
/SIGNAL_NAMES=Left Hip Angle
! /SIGNAL_FOLDER=ORIGINAL
/EVENT_NAME=Left Hip Angles MAX
/SELECT_X=TRUE
! /SELECT_Y=FALSE
! /SELECT_Z=FALSE
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
/START_AT_EVENT=LHS
/END_AT_EVENT=LHS
;
! Create a Global Min Event for Left Hip Angles from LHS to LHS
Event_Global_Minimum
/SIGNAL_TYPES=LINK_MODEL_BASED
/SIGNAL_NAMES=Left Hip Angle
! /SIGNAL_FOLDER=ORIGINAL
/EVENT_NAME=Left Hip Angles MIN
/SELECT_X=TRUE
! /SELECT_Y=FALSE
! /SELECT_Z=FALSE
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
/START_AT_EVENT=LHS
/END_AT_EVENT=LHS
;
! Create a black cross mark on Left Hip Angle Max
Add_Graph_Annotation
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=1
/DRAW_ORDER=1
/ANNOTATION_EVENT=Left Hip Angles Max
/ANNOTATION_STYLE=Cross
/ANNOTATION_COLOR=Black
! /ANNOTATION_SIZE=Normal
/ANNOTATION_GLOBAL=FALSE
/ANNOTATION_AVERAGE_EVENT=FALSE
;
! Create a black cross mark on Left Hip Angle Min
Add_Graph_Annotation
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=1
/DRAW_ORDER=1
/ANNOTATION_EVENT=Left Hip Angles Min
/ANNOTATION_STYLE=Cross
/ANNOTATION_COLOR=Black
! /ANNOTATION_SIZE=Normal
/ANNOTATION_GLOBAL=FALSE
/ANNOTATION_AVERAGE_EVENT=FALSE
;
!---------------------------------------------------------------------------------------
! Graph Left Knee Angles and add a line for TO as well as a cross for max and min points
!---------------------------------------------------------------------------------------
! Add a graph to report page 1 at col 1 row 2
! Left Knee Angle component X (Flex/Ext) for ALL_FILES. The line color is Red
! and it is plotted from LHS to LHS
Make_Line_Graph
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=2
! /COLUMN_SPAN=1
! /ROW_SPAN=1
/GRAPH_TITLE=Knee Angle
/FILES_TO_GRAPH=ALL_FILES
! /DISPLAY_LEGEND=FALSE
! /LEGEND_LOCATION=UR
! /LEGEND_TEXT=
! /LINE_STYLE=Solid
/LINE_COLOR=Red
! /LINE_BOLD=FALSE
! /SHOW_POINTS=FALSE
! /GRAPH_MEAN=FALSE
! /GRAPH_STDDEV=FALSE
! /MEAN_STDDEV_LINE_STYLE=Solid
! /MEAN_STDDEV_LINE_COLOR=Black
! /MEAN_STDDEV_LINE_BOLD=FALSE
/USE_EVENT_RANGE=TRUE
/START_EVENT_LABEL=LHS
/END_EVENT_LABEL=LHS
! /INTERMEDIATE_EVENTS=
! /EXCLUDE_EVENTS=
! /X_AXIS_LABEL=
/X_DATA_TYPE=FRAME_NUMBERS
/X_DATA_NAME=Time
! /X_DATA_COMPONENT=
! /X_DATA_PROCESSED=ORIGINAL
! /X_AXIS_SCALE=Normalize 0% to 100%
/Y_AXIS_LABEL=Degrees
/Y_DATA_TYPE=LINK_MODEL_BASED
/Y_DATA_NAME=Left Knee Angle
/Y_DATA_COMPONENT=X
/Y_DATA_PROCESSED=ORIGINAL
! /Y_AXIS_SCALE=Global Min to Max
! /Y_USE_SCIENTIFIC_NOTATION=FALSE
;
! To set the Y axis range explicitly for Left Knee Angles
Modify_Line_Graph
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=2
! /COLUMN_SPAN=1
! /ROW_SPAN=1
! /GRAPH_TITLE=
! /X_AXIS_LABEL=
! /X_AXIS_SCALE=Normalize 0% to 100%
! /X_AXIS_MIN=
! /X_AXIS_MAX=
! /Y_AXIS_LABEL=
/Y_AXIS_SCALE=By Explicit Setting
/Y_AXIS_MIN=-75
/Y_AXIS_MAX=25
! /Y_USE_SCIENTIFIC_NOTATION=FALSE
;
! Create a Global Max Event for Left Knee Angles from LHS to LHS
Event_Global_Maximum
/SIGNAL_TYPES=LINK_MODEL_BASED
/SIGNAL_NAMES=Left Knee Angle
! /SIGNAL_FOLDER=ORIGINAL
/EVENT_NAME=Left Knee Angles MAX
/SELECT_X=TRUE
! /SELECT_Y=FALSE
! /SELECT_Z=FALSE
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
/START_AT_EVENT=LHS
/END_AT_EVENT=LHS
;
! Create a Global Min Event for Left Knee Angles from LHS to LHS
Event_Global_Minimum
/SIGNAL_TYPES=LINK_MODEL_BASED
/SIGNAL_NAMES=Left Knee Angle
! /SIGNAL_FOLDER=ORIGINAL
/EVENT_NAME=Left Knee Angles MIN
/SELECT_X=TRUE
! /SELECT_Y=FALSE
! /SELECT_Z=FALSE
! /EVENT_SEQUENCE=
! /EXCLUDE_EVENTS=
/START_AT_EVENT=LHS
/END_AT_EVENT=LHS
;
! Create an annotation for Knee Angle - vertical red line at LTO
Add_Graph_Annotation
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=2
/DRAW_ORDER=1
/ANNOTATION_EVENT=LTO
/ANNOTATION_STYLE=Vertical Line
/ANNOTATION_COLOR=Red
! /ANNOTATION_SIZE=Normal
/ANNOTATION_GLOBAL=FALSE
/ANNOTATION_AVERAGE_EVENT=TRUE
;
! Create a black cross mark on Left Knee Angle Max
Add_Graph_Annotation
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=2
/DRAW_ORDER=1
/ANNOTATION_EVENT=Left Knee Angles Max
/ANNOTATION_STYLE=Cross
/ANNOTATION_COLOR=Black
! /ANNOTATION_SIZE=Normal
/ANNOTATION_GLOBAL=FALSE
/ANNOTATION_AVERAGE_EVENT=FALSE
;
! Create a black cross mark on Left Knee Angle Min
Add_Graph_Annotation
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=2
/DRAW_ORDER=1
/ANNOTATION_EVENT=Left Knee Angles Min
/ANNOTATION_STYLE=Cross
/ANNOTATION_COLOR=Black
! /ANNOTATION_SIZE=Normal
/ANNOTATION_GLOBAL=FALSE
/ANNOTATION_AVERAGE_EVENT=FALSE
;
!-----------------------------------------------------------------------------------
! This section will bring in the normal database *.vnd file and plot the P2D normal
! data on each graph
!-----------------------------------------------------------------------------------
! Open the *.vnd normal database file
File_Open
! /FILE_NAME=
;
! Add a graph to report page 1 at col 1 row 1
! Left Hip Angle component X (Flex/Ext) for ALL_FILES The line color is Black
Make_Line_Graph
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=1
! /COLUMN_SPAN=1
! /ROW_SPAN=1
/GRAPH_TITLE=Hip Angle
/FILES_TO_GRAPH=ALL_FILES
! /DISPLAY_LEGEND=FALSE
! /LEGEND_LOCATION=UR
! /LEGEND_TEXT=
/LINE_STYLE=Solid
/LINE_COLOR=Black
! /LINE_BOLD=FALSE
! /SHOW_POINTS=FALSE
! /GRAPH_MEAN=FALSE
! /GRAPH_STDDEV=FALSE
! /MEAN_STDDEV_LINE_STYLE=Solid
! /MEAN_STDDEV_LINE_COLOR=Black
! /MEAN_STDDEV_LINE_BOLD=FALSE
!/USE_EVENT_RANGE=FALSE
!/START_EVENT_LABEL=
!/END_EVENT_LABEL=
! /INTERMEDIATE_EVENTS=
! /EXCLUDE_EVENTS=
! /X_AXIS_LABEL=
/X_DATA_TYPE=P2D
/X_DATA_NAME=Hip FlexExtension.p2d
/X_DATA_COMPONENT=1
! /X_DATA_PROCESSED=ORIGINAL
! /X_AXIS_SCALE=Normalize 0% to 100%
/Y_AXIS_LABEL=Degrees
/Y_DATA_TYPE=P2D
/Y_DATA_NAME=Hip FlexExtension.p2d
/Y_DATA_COMPONENT=2
/Y_DATA_PROCESSED=ORIGINAL
/Y_AXIS_SCALE=Global Min to Max
! /Y_USE_SCIENTIFIC_NOTATION=FALSE
;
! Add a graph to report page 1 at col 1 row 1
! Left Hip Angle component X (Flex/Ext) for ALL_FILES The line color is Black
Make_Line_Graph
/PAGE_NUMBER=1
/COLUMN_NUMBER=1
/ROW_NUMBER=1
! /COLUMN_SPAN=1
! /ROW_SPAN=1
/GRAPH_TITLE=Hip Angle
/FILES_TO_GRAPH=ALL_FILES
! /DISPLAY_LEGEND=FALSE
! /LEGEND_LOCATION=UR
! /LEGEND_TEXT=
/LINE_STYLE=Solid
/LINE_COLOR=Black
! /LINE_BOLD=FALSE
! /SHOW_POINTS=FALSE
! /GRAPH_MEAN=FALSE
! /GRAPH_STDDEV=FALSE
! /MEAN_STDDEV_LINE_STYLE=Solid
! /MEAN_STDDEV_LINE_COLOR=Black
! /MEAN_STDDEV_LINE_BOLD=FALSE
!/USE_EVENT_RANGE=FALSE
!/START_EVENT_LABEL=
!/END_EVENT_LABEL=
! /INTERMEDIATE_EVENTS=
! /EXCLUDE_EVENTS=
! /X_AXIS_LABEL=
/X_DATA_TYPE=P2D
/X_DATA_NAME=Knee FlexExtension.p2d
/X_DATA_COMPONENT=1
! /X_DATA_PROCESSED=ORIGINAL
! /X_AXIS_SCALE=Normalize 0% to 100%
/Y_AXIS_LABEL=Degrees
/Y_DATA_TYPE=P2D
/Y_DATA_NAME=Knee FlexExtension.p2d
/Y_DATA_COMPONENT=2
/Y_DATA_PROCESSED=ORIGINAL
/Y_AXIS_SCALE=Global Min to Max
! /Y_USE_SCIENTIFIC_NOTATION=FALSE
;
! Print Report
Print_Report
! /USE_SYSTEM_PRINTER_DEFAULTS=TRUE
! /SHOW_PRINTER_PROMPT=TRUE
! /PAPER_SIZE=LETTER
! /PORTRAIT=FALSE
;
==== Export and Import ====
=== Export Graphs ===
=== Export Images ===
* An example of exporting graphs and metrics and screen shot images is there. We prefer actually building a report in V3D and exporting graphs as SVG or PNG images rather than exporting raw ASCII data for consistency and easy error checking reasons.
=== Export to ASCII ===
An example of can be found on [[|Pipeline Processing Example 3]]. There are some great pipeline script examples of the [[Visual3D:Documentation:Pipeline:File_Commands:Export_Data_To_ASCII_File|Export Data To ASCII File]] page
=== Import from ASCII ===
Refer to [[Visual3D:Documentation:Pipeline:File_Commands:Import_Data_From_ASCII_File|Import Data From ASCII File]] page for an example of how to import an ASCII file into a Visual3D.
==== Save the CMO File ====
==== MetaCommands ====
Meta-Commands are used for complex functions or general processing. A meta-command is a Visual3D pipeline into which parameters can be passed. The meta-command should be stored in a folder labeled Meta-Commands, which is located in the Visual3D Plugins Folder. For a more detailed discussion on meta-commands go to the [[Visual3D:Documentation:Pipeline:Meta_Commands:Meta_Commands_Overview|Pipeline Commands:Meta Commands]] page.
==== Summary ====