1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
###############################################################################
# Copyright (c) 2009-2024 by Altair Engineering, Inc.
# All rights reserved.
#
# Altair Engineering, Inc. makes this software available as part of the Vision
# tool platform.  As long as you are a licensee of the Vision tool platform
# you may make copies of the software and modify it to be used within the
# Vision tool platform, but you must include all of this notice on any copy.
# Redistribution without written permission to any third party, with or
# without modification, is not permitted.
# Altair Engineering, Inc. does not warrant that this software is error free
# or fit for any purpose.  Altair Engineering, Inc. disclaims any liability for
# all claims, expenses, losses, damages and costs any user may incur as a
# result of using, copying or modifying the software.
# =============================================================================
#   @userware
#       Highlight for Transient
#   @section
#       Miscellaneous Userware Examples
#   @description
#       This example shows how to use the waveform parser to
#             - read a DC analysis result file
#             - traverse all curves defined in this file
#             - highlight elements in the schematic from this data
#
#       - Load the spice netlist "demo/spice/Fig24_30/Fig24_30.sp".
#       - Load this userware file. A small GUI will open
#       - Open the tran simulation result "demo/spice/Fig24_30/Fig24_30.csv"
#       - Select a type such as "volt".
#       - Define a min / max value such as 0.0 and 0.01
#       - Click "Highlight"
#       - The concerned nets are highlighted in the schematic.
#
#   @files
#       analogWave/highlight_for_tran.tcl
#   @example
#       demo/spice/Fig24_30/Fig24_30.sp
#       demo/spice/Fig24_30/Fig24_30.csv
#   @tag
#       gui analog
###############################################################################


# -----------------------------------------------------------------------------
# get_type_name - This function returns a type name for a given type_index.
# -----------------------------------------------------------------------------
#
proc get_type_name {type_index} {
    set type_name [af_wp_find_type_property $type_index "prop_type_name"]
    if {$type_name == ""} {
        set type_name [af_wp_find_type_property $type_index "prop_type_unit"]
    }
    return $type_name
}


# -----------------------------------------------------------------------------
# highlight_for_section_and_type - This function is called when clicking the
#                                  "Highlight" button.
#
# It traverses all curves. If the curve makes use of the type "type_index" and
# the value matches the [min, max] interval, it is highlighted.
# -----------------------------------------------------------------------------
#
proc highlight_for_section_and_type {
    section_id
    type_index
    x_value
    min_value
    max_value
} {
    ##
    # The name of the current StarVision zdb is required to highlight
    # components.
    #
    set db [gui database get]

    ##
    # This function generates a mapping for the waveform section defined by
    # $section_id and the currently loaded schematic.
    # This mapping is required to map curve names to the oid names of the
    # schematic.
    #
    set rc [af_sv_compute_mapping ${section_id}]
    if {$rc ne "ok"} {
        zmessage print ERR "failed to create mapping !"
    }

    ##
    # As we want to traverse all variables in the section we have to get the
    # number of variables defined in the section.
    # The first variables might be sweep variables holding the x-axis values.
    # They aren't interesting here.
    #
    set nb_sweep_variables [af_wp_find_section_property $section_id \
                                    "prop_section_number_of_sweep_variables"]
    set nb_all_variables [af_wp_find_section_property $section_id \
                                    "prop_section_total_number_of_variables"]

    set type_name [get_type_name $type_index]
    set highlight_counter 0

    ##
    # We traverse all curves of the section "section_id"
    #
    for {set curve_index $nb_sweep_variables} \
        {$curve_index<$nb_all_variables} \
        {incr curve_index} \
    {
        ##
        # Here we retrieve some information on the current variable.
        #
        set curve_name [af_wp_find_curve_property $section_id $curve_index \
                                                        "prop_variable_name"]
        set curve_type_index [af_wp_find_curve_property \
                    $section_id $curve_index "prop_variable_y_axis_type_index"]

        ##
        # Check if the type_index is the required one.
        #
        if {$curve_type_index == $type_index} {
            ##
            # Here we apply the mapping computed above. For a given curve name
            # it returns a matching oid.
            #
            set oid [af_sv_apply_mapping_waveform_to_oid $curve_name]

            ##
            # Check if the curve was mapped correctly.
            #
            if {$oid != ""} {
                ##
                # Interpolate the curve's value at x_value.
                #
                set value [af_wp_evaluate_curve_value $section_id $curve_index \
                                                      $x_value]

                ##
                # The string value "error" is returned when the iinterpolation
                # fails.
                # Check if "value" holds valid data.
                #
                if {![af_wp_check_is_return_code $value]} {
                    set data_is_valid 0
                    if {[string is double $value]} {
                        set data_is_valid 1
                    }
                    if {$data_is_valid && [string is double $min_value]} {
                        if {$value < $min_value} {
                            set data_is_valid 0
                        }
                    }
                    if {$data_is_valid && [string is double $max_value]} {
                        if {$value > $max_value} {
                            set data_is_valid 0
                        }
                    }
                    if {$data_is_valid} {
                        set hi_col [gui settings get "hiColor"]
                        $db flathilight $oid set $hi_col
                        incr highlight_counter
                    }
                }

                ##
                # release the curve data
                #
                af_wp_release_curve $section_id $curve_index
            }
        }
    }

    ##
    # inform the GUI that highlighting changed
    #
    gui highlight changed

    ##
    # Return a string that will be shown in the GUI.
    #
    return "$highlight_counter elements highlighted for type \"$type_name\"."
}


# -----------------------------------------------------------------------------
# highlight_dialog - This function creates a simple Tk dialog.
#
# This dialog allows to select a type and highlight schematic components
# -----------------------------------------------------------------------------
#
proc highlight_dialog {section_id} {
    variable dialog_variable
    variable selected_type_index
    variable x_value
    variable min_value
    variable max_value

    ##
    # variable set when selection changes
    #
    set selected_type_index -1

    ##
    # variable holding x-axis values
    #
    set x_value 0.6e-6

    ##
    # variable holding min and max values
    #
    set min_value ""
    set max_value ""

    ##
    # Create toplevel dialog
    #
    set w .af_dialog
    catch {destroy $w}
    toplevel $w
    wm title $w "Create Highlighting From Transient file"
    wm protocol $w WM_DELETE_WINDOW {set dialog_variable 0}
    set dlg .af_dialog.main_frame
    set txt "Select a type and if defined,\na sub-type to highlight "
    set txt "components in the schematic\nfor all curves of this type."
    ttk::frame $dlg
    ttk::label $dlg.label \
        -text $txt

    ##
    # menu button allowing to select the type.
    #
    ttk::menubutton $dlg.mb_type -menu $dlg.mb_type.menu -text "Select a type" \
        -direction below
    menu $dlg.mb_type.menu -tearoff 0

    ttk::frame $dlg.x_values
    ttk::label $dlg.x_values.label -text "X Axis Value"
    ttk::entry $dlg.x_values.value -textvariable x_value
    pack $dlg.x_values.label  $dlg.x_values.value -padx 10 -pady 10 -side left

    ttk::frame $dlg.min_values
    ttk::label $dlg.min_values.label -text "Min Value"
    ttk::entry $dlg.min_values.value -textvariable min_value
    pack $dlg.min_values.label  $dlg.min_values.value -padx 10 -pady 10 \
        -side left

    ttk::frame $dlg.max_values
    ttk::label $dlg.max_values.label -text "Max Value"
    ttk::entry $dlg.max_values.value -textvariable max_value
    pack $dlg.max_values.label  $dlg.max_values.value -padx 10 -pady 10 \
        -side left

    ##
    # a label for feedback
    #
    ttk::label $dlg.feedback -text "0 elements highlighted."

    pack $dlg.label $dlg.mb_type $dlg.x_values $dlg.min_values $dlg.max_values \
         $dlg.feedback -padx 20 -pady 10

    ##
    # button bar
    #
    ttk::frame $dlg.buttons
    ttk::button $dlg.buttons.ok -width 10 -text "Highlight" \
        -default active \
        -command {.af_dialog.main_frame.feedback configure \
                -text [highlight_for_section_and_type $section_id \
                          $selected_type_index $x_value $min_value $max_value]}
    ttk::button $dlg.buttons.cancel -width 10 -text "Close" \
        -command {catch {set dialog_variable 0}}
    pack $dlg.buttons.ok $dlg.buttons.cancel -padx 10 -pady 10 -side right

    pack $dlg.buttons -anchor s -side right
    pack $dlg -expand yes -fill both

    ##
    # Here we create the menu holding the types and sub-types (or type fields).
    # We get the number of defined types
    #
    set nb_types [af_wp_find_global_property "prop_global_number_of_types"]

    ##
    # We traverse the types
    #
    for {set type_index 0} {$type_index<$nb_types} {incr type_index} {
        set number_of_sub_types [af_wp_find_type_property $type_index \
                                            "prop_type_number_of_sub_types"]
        set type_name [get_type_name $type_index]

        $dlg.mb_type.menu add command -label $type_name \
            -command [list set selected_type_index $type_index]
    }

    ##
    # Wait for the dialog to close
    #
    tkwait variable dialog_variable

    destroy $w
}


##
#
#
set script_path [file dirname [file normalize [info script]]]

##
# This function loads the waveform parser
#       and makes the functions af_wp_... and af_sv_... available.
#
af_waveform_parser_create

##
# Define a file with dc data over the file dialog.
#
set file_name "${script_path}/../../spice/Fig24_30/Fig24_30.csv"
set file_name [tk_getOpenFile -title "Open Transient File" \
                            -initialdir $script_path -initialfile ${file_name}]

##
# Clear all data in the waveform parser.
#
af_wp_release_all

##
# Parse the file
#
set rc [af_wp_read_file ${file_name}]

##
# if cucessful at least 1 section is created
#
set nb_sections [af_wp_get_number_of_sections]

if {${nb_sections} > 0} {
    ##
    # Each file might define several data sections for example for several runs
    # with different parameters.
    # At least one section has been parsed. We use the first one here.
    # We need to work with the section_id. This section_id doesn't change, even
    # if other files are parsed, reloaded or released.
    #
    set section_id [af_wp_get_section_identifier 0]

    ##
    # Create a dialog to highlight components in the schematics
    #
    highlight_dialog $section_id
} else {
    zmessage print ERR "failed to load file ${file_name}"
}

##
# Everything is released.
#
af_wp_release_all

##
# unloads the waveform parser
#
af_waveform_parser_delete