Snippets
Created by
John Peck
last modified
John Peck
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 | #!/opt/ActiveTcl-8.6/bin/tclsh
# Hey Emacs, use -*- Tcl -*- mode
set scriptname [file rootname $argv0]
# ----------------------- Gnuplot settings ----------------------------
# The wxt terminal can keep windows alive after the gnuplot process
# exits. This allows calling multiple persistent windows which allow
# zooming and annotation.
set gnuplot_terminal wxt
# ---------------------- Command line parsing -------------------------
package require cmdline
set usage "usage: [file tail $argv0] \[options] filename"
set options {
}
try {
array set params [::cmdline::getoptions argv $options $usage]
} trap {CMDLINE USAGE} {msg o} {
# Trap the usage signal, print the message, and exit the application.
# Note: Other errors are not caught and passed through to higher levels!
puts $msg
exit 1
}
proc iterint {start points} {
# Return a list of increasing integers starting with start with
# length points
set count 0
set intlist [list]
while {$count < $points} {
lappend intlist [expr $start + $count]
incr count
}
return $intlist
}
proc dashline {width} {
# Return a string of dashes of length width
set dashline ""
foreach dashchar [iterint 0 $width] {
append dashline "-"
}
return $dashline
}
# After cmdline is done, argv will point to the last argument
if {[llength $argv] == 1} {
set input_file_name $argv
} else {
puts [cmdline::usage $options $usage]
exit 1
}
proc iterint {start points} {
# Return a list of increasing integers starting with start with
# length points
set count 0
set intlist [list]
while {$count < $points} {
lappend intlist [expr $start + $count]
incr count
}
return $intlist
}
proc lmean {input_list} {
# Find the mean of a list
set total 0
set count 0
foreach item $input_list {
incr count
set total [expr $total + $item]
}
set mean [expr $total/double($count)]
return $mean
}
proc loffset {input_list offset} {
# Move all list elements by offset
foreach item $input_list {
lappend no_offset_list [expr $item - $offset]
}
return $no_offset_list
}
proc lrms {input_list} {
# Calculate RMS value of list
set sum 0
set count 0
foreach item $input_list {
incr count
set sum [expr $sum + $item**2]
}
set rms [expr sqrt( $sum/double($count) )]
return $rms
}
proc read_file {filename} {
# Return a list of lines from an input file
#
# Arguments:
# filename -- relative or full path to file
if { [catch {open $filename r} fid] } {
puts "Could not open file $filename"
return
}
set datafile_list [split [read $fid] "\n"]
return $datafile_list
}
proc write_gnuplot_data {filename frequency_hz_list magnitude_db_list} {
# Write a data file that can be plotted by gnuplot
#
# Arguments:
# filename -- Name of the output data file
# frequency_hz_list -- List of frequencies in Hz
# magnitude_db_list -- List of transfer function magnitudes in dB
global params
if { [catch {open $filename w} fp] } {
puts "Could not open $filename for writing"
return
}
foreach frequency $frequency_hz_list magnitude $magnitude_db_list {
puts $fp "$frequency $magnitude"
}
close $fp
}
proc write_gnuplot_script {filename datafile measurement_dict} {
# Write a gnuplot script to plot data in datafile
#
# Arguments:
# filename -- Name of the gnuplot script to be written
# datafile -- Name of the file containing data to be plotted
global gnuplot_terminal
global scriptname
global input_file_name
if { [catch {open $filename w} fp] } {
puts "Could not open $filename for writing"
return
}
# Set the fractional amount of padding to require at the top
# of the y-axis. This makes more room for the plot legend. A
# value of 1 will give no padding, and a value of 2 will make
# the padding twice the maximum current value plotted.
set plot_padding 1.5
# Annotation x postion in graph (0 --> 1) coordinates
set anno_x 0.05
# Annotation y position in graph (0 --> 1) coordinates
set anno_y 0.7
# Spacing between annotation lines in graph (0 --> 1) coordinates
set anno_incr 0.05
puts $fp "reset"
puts $fp "set terminal $gnuplot_terminal size 800,600"
puts $fp "set logscale x"
puts $fp "set format y '%0.1s %c'"
puts $fp "set format x '%0.0s %c'"
puts $fp "set mxtics 10"
puts $fp "set xlabel 'Frequency (Hz)'"
puts $fp "set ylabel 'Magnitude (dB)'"
puts $fp "set title 'Lafayette transimpedance bandwidth"
# Start annotations
foreach measurement [dict keys $measurement_dict] {
set annotation "[dict get $measurement_dict $measurement title] = "
append annotation [format "%0.1f" [dict get $measurement_dict $measurement value]]
append annotation " [dict get $measurement_dict $measurement units]"
puts $fp "set label '$annotation' at graph $anno_x,$anno_y"
set anno_y [expr $anno_y - $anno_incr]
}
# Use noenhanced here to prevent underscores from becoming subscripts
set plot_instruction "using 1:2 with lines title '$input_file_name' noenhanced"
puts $fp "plot '$datafile' $plot_instruction"
puts $fp {yaxis_max = GPVAL_Y_MAX}
puts $fp {ydata_max = GPVAL_DATA_Y_MAX}
puts $fp {yaxis_min = GPVAL_Y_MIN}
puts $fp {ydata_min = GPVAL_DATA_Y_MIN}
puts $fp "if (yaxis_max < ($plot_padding * ydata_max)) \{"
puts $fp " set yrange \[ydata_min:($plot_padding * ydata_max)\] "
puts $fp " replot"
puts $fp "\}"
puts $fp "set output '$scriptname.eps'"
puts $fp "set terminal postscript eps color size 6in,4in"
puts $fp "replot"
puts $fp "set terminal wxt size 800,600"
puts $fp "replot"
close $fp
}
########################## Main entry point ##########################
set file_line_list [read_file $input_file_name]
if {[llength $file_line_list] == 0} {
puts "No input data"
exit
}
set counter -1
foreach line $file_line_list {
incr counter
if {$counter == 0} {
# This is the header row
continue
}
if {[llength $line] == 0} {
# This is a blank line
continue
}
set line_list [split $line ","]
lappend frequency_hz_list [lindex $line_list 0]
lappend magnitude_db_list [lindex $line_list 1]
}
set flatband_gain [lmean [lrange $magnitude_db_list 0 9]]
set 3db_frequency_hz 0
set in_flatband true
foreach gain $magnitude_db_list frequency $frequency_hz_list {
set normalized_db [expr $gain - $flatband_gain]
lappend normalized_db_list $normalized_db
if {$normalized_db <= -3 && $in_flatband} {
set in_flatband false
set 3db_frequency_hz $frequency
}
}
dict set measurement_dict bandwidth title "-3dB bandwidth"
dict set measurement_dict bandwidth value [expr $3db_frequency_hz/1e6]
dict set measurement_dict bandwidth units "MHz"
dict set measurement_dict shunt title "Shunt resistance"
dict set measurement_dict shunt value 6.2
dict set measurement_dict shunt units ohms
write_gnuplot_data gnuplot.dat $frequency_hz_list $normalized_db_list
write_gnuplot_script bandwidth.gp gnuplot.dat $measurement_dict
set gnuplot "c:/Program Files/gnuplot/bin/wgnuplot.exe"
exec $gnuplot -persist bandwidth.gp
|
Comments (0)
You can clone a snippet to your computer for local editing. Learn more.