<commit_before><!DOCTYPE html>
<html>
<meta  content="text/html; charset=UTF-8"  http-equiv="content-type">
<head>
    <title>T-Line Voltage Pulse</title>

    <style>
        fieldset {background-color:lightgrey;
                  width:420px;
                  margin:auto;
                  text-align:left;
                }
        legend {background-color:white;
                border:2px solid grey;
                padding-left: 5px;
                padding-right: 5px;
               }
        button {background-color:lightblue;
               border:2px solid grey;
               padding-left: 5px;
               padding-right: 5px;
              }
        table {
            /* make the border continuous (without gaps between columns) */
            border-collapse: collapse;
        }
        tr.separated td {
            /* set border style for separated rows */
            border-bottom: 1px solid grey;
        }
        .params {
            table-layout: fixed;
            width: 100%;
            white-space: nowrap;
            cellspacing: 5px;
            cellpadding: 5px;
        }
        .params td {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .params .col-1 {
            width: 10%;
            text-align: right;
        }
        .params .col-2 {
            width: 40%;
        }
        .params .col-3 {
            width: 10%;
            text-align: right;
        }
        .params .col-4 {
            width: 30%;
        }
        .Rinput {
            width: 60px;
        }
    </style>

</head>
<body>
<div style="text-align:center" width:700px margin:auto>
    <h2>Voltage Pulse on a Transmission Line</h2>
    <!-- <canvas id="canvas_tline_fig" width="500" height="150"></canvas>
    <p> </p> -->
    <canvas id="canvas" width="600" height="300"></canvas>
    <p> </p>
    <button id="idTogButton" onclick="toggleButton()">Start</button>
    <button id="idResetButton" onclick="resetButton()">Reset</button>
    <br />
    <br />

    <fieldset>
        <legend>Parameters</legend>

        <table class="params">
            <!-- <col class="col-1" />
            <col class="col-2" /> -->
            <tr>
                <td class="col-1">
                    <label for="idSelectVoltage">v<sub>g</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <select name="vglist" id="idSelectVoltage" oninput="vgUpdate(value)">
                        <option value="1.0">1.0 V</option>
                        <option value="3.3">3.3 V</option>
                        <option value="5.0">5.0 V</option>
                    </select>
                </td>
                <td class="col-3">
                    <p></p>
                </td>
                <td class="col-4">
                    <p></p>
                </td>
            </tr>
            <tr>
                <td class="col-1">
                    <label for="idGammag">&#915;<sub>g</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <input type="range" id="idGammag" min="-1" max="0.99" value="0"
                         step="any" oninput="GammagUpdate(value)">
                    <output for="idGammag" id="idGammagValue">0</output>
                </td>
                <td class="col-3">
                    <label for="idRg">R<sub>g</sub> &nbsp;</label>
                </td>
                <td class="col-4">
                    <input type="number" id="idRg" min="0" value="50"
                         class="Rinput" oninput="RgUpdate(value)">
                    <output for="idRg" id="idRgValue">&Omega;</output>
                </td>
            </tr>
            <tr>
                <td class="col-1">
                    <label for="idGammaL">&#915;<sub>L</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <input type="range" id="idGammaL" min="-1" max="0.99" value="0.5"
                           step="any" oninput="GammaLUpdate(value)">
                    <output for="idGammaL" id="idGammaLValue">0.8</output>
                </td>
                <td class="col-3">
                    <label for="idRL">R<sub>L</sub> &nbsp;</label>
                </td>
                <td class="col-4">
                    <input type="number" id="idRL" min="0" value="150"
                         class="Rinput" oninput="RLUpdate(value)">
                    <output for="idRL" id="idRLValue">&Omega;</output>
                </td>
            </tr>
            <tr class="separated">
                <td><p></p></td> <td><p></p></td> <td><p></p></td> <td><p></p></td>
            </tr>
            <tr>
                <td><p></p></td> <td><p></p></td> <td><p></p></td> <td><p></p></td>
            </tr>
            <tr>
                <td class="col-1">
                    <label for="idZ0">Z<sub>0</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <input type="number" id="idZ0" value="50"
                         class="Rinput" disabled>
                    <output for="idZ0" id="idZ0Value">&Omega;</output>
                </td>
                <td class="col-3">
                    <p></p>
                </td>
                <td class="col-4">
                    <p></p>
                </td>
            </tr>
            <tr>
                <td class="col-1">
                    <label for="idv1plus">v<sup>+</sup><sub>1</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <input type="number" id="idv1plus" value="0.5"
                         class="Rinput" disabled>
                    <output for="idv1plus" id="idv1plusValue">V (initial voltage)</output>
                </td>
                <td class="col-3">
                    <p></p>
                </td>
                <td class="col-4">
                    <p></p>
                </td>
            </tr>
            <tr>
                <td class="col-1">
                    <label for="idvss">v<sub>ss</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <input type="number" id="idvss" value="0.75"
                         class="Rinput" disabled>
                    <output for="idvss" id="idvssValue">V (steady state)</output>
                </td>
                <td class="col-3">
                    <p></p>
                </td>
                <td class="col-4">
                    <p></p>
                </td>
            </tr>
        </table>
    </fieldset>
</div>

    <p id="values" style="text-align:center"></p>
    <p id="demo2"></p>



<script>

var Z0 = 50;
var v_g = 1.0;
update_params();

//draw_tline_fig();

function GammaL() {
    return Number(document.querySelector('#idGammaL').value);
}

function Gammag() {
    return Number(document.querySelector('#idGammag').value);
}

function RL() {
    return R_from_Gamma(GammaL());
}

function Rg() {
    return R_from_Gamma(Gammag());
}

function v1_plus() {
    return v_g * Z0 / (Z0 + Rg());
}

function v_steadystate() {
    if (GammaL() == 1) {
        return v_g;
    } else {
        return v_g * RL() / (RL() + Rg());
    }
}

function update_params() {
    calc_delta_voltages();
    document.querySelector('#idv1plus').value = v1_plus().toFixed(2);
    document.querySelector('#idvss').value = v_steadystate().toFixed(2);
}

function R_from_Gamma(g) {
    return Z0 * (1.0 + g) / (1.0 - g);
}

function Gamma_from_R(R) {
    return (R-Z0) / (R+Z0);
}

function vgUpdate(value) {
    v_g = Number(value);
    console.log(value, v_g);
    update_params();
    set_axes();
    drawAll();
}

function GammaLUpdate(value) {
	document.querySelector('#idGammaLValue').innerHTML = Number(value).toFixed(2);
    var temp = R_from_Gamma(Number(value));
    document.querySelector('#idRL').value = RL().toFixed(1);
    update_params();
    if (!timerRunning) drawAll();
}

function GammagUpdate(value) {
	document.querySelector('#idGammagValue').innerHTML = Number(value).toFixed(2);
    var temp = R_from_Gamma(Number(value));
    document.querySelector('#idRg').value = temp.toFixed(1);
    update_params();
    if (!timerRunning) drawAll();
}

function RgUpdate(value) {
    var temp = Gamma_from_R(Number(value));
    console.log(Z0, value, temp, Gamma_from_R(value));
    document.querySelector('#idGammagValue').innerHTML = temp.toFixed(2);
    document.querySelector('#idGammag').value = temp;
    update_params();
    if (!timerRunning) drawAll();
}

function RLUpdate(value) {
    var temp = Gamma_from_R(Number(value));
    console.log(Z0, value, temp, Gamma_from_R(value));
    document.querySelector('#idGammaLValue').innerHTML = temp.toFixed(2);
    document.querySelector('#idGammaL').value = temp;
    update_params();
    if (!timerRunning) drawAll();

}


var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var frac_max_x = 0.8;
var frac_max_y = 0.75;
var axes={};
axes.x0 = canvas.width * (1-frac_max_x)/2;  // x0 pixels from left to x=0
axes.y0 = canvas.height * (frac_max_y/2 + (1-frac_max_y)/2);// + (1-frac_max_y)/2); // y0 pixels from top to y=0
set_axes();

function set_axes() {
    axes.zmin = 0.;
    axes.zmax = 30.;
    axes.vmin = -v_g*2.1;
    axes.vmax = v_g*2.1;
    axes.zrange = axes.zmax - axes.zmin;
    axes.vrange = axes.vmax - axes.vmin;
    axes.zscale = canvas.width * frac_max_x / axes.zrange;  // # canvas pixels per unit in z
    axes.vscale = canvas.height * frac_max_y / axes.vrange;  // # canvas pixels per unit in v
}


var num_roundtrips = 5;
var v_delta = [];
for (i=0; i<=2*num_roundtrips; i++) {
    v_delta.push(0);
}
calc_delta_voltages();
for (i=0; i<=2*num_roundtrips; i++) {
    console.log(i, v_delta[i]);
}
var numpnts = 100;
var voltage = [];
for (var i=0; i<numpnts; i++) {
    voltage.push(0);
}
var z = [];
for (var i=0; i<numpnts; i++) {
    z.push(axes.zmin + (axes.zmax - axes.zmin)*i/(numpnts-1));
}

function calc_delta_voltages() {
    // v_delta[0] += v1_plus();
    for (var i=0; i<=num_roundtrips*2; i++) {
        if (i == 0) {
            v_delta[i] = v1_plus();
        } else {
                if (isOdd(i)) {
                var gamma = GammaL();
            } else {
                var gamma = Gammag();
            }
            v_delta[i] = gamma * v_delta[i-1];
        }
    }
}

var framecounter = 0;
var num_frames_per_L = 100;  // number of frames to go from z=0 to z=L (end of t-line)
// var T = num_frames_per_L;
var u_pnts_per_frame = 1;
var T = numpnts / u_pnts_per_frame;
var u_z_per_frame = axes.zrange / T; // velocity in z per frame
var pulse_length_T = 0.4; // pulse length in units of T
var pulse_length_numpnts = numpnts * pulse_length_T; // pulse length in units of points on plot
var pulse_length_z = pulse_length_T * axes.zrange; // pulse length in units of z
console.log(T, pulse_length_T, pulse_length_numpnts, pulse_length_z, u_z_per_frame);
drawAll();
var timerRunning = false;
redrawAll();

function pulse_forward(a) {
    // console.log(framecounter, a, pulse_length_z);
    if ((a < 0) && (a > -pulse_length_z)) {
        return 1.0;
    } else {
        return 0.0;
    }
}

function pulse_reverse(a) {
    // console.log(framecounter, a, pulse_length_z);
    if ((a > 0) && (a < pulse_length_z)) {
        return 1.0;
    } else {
        return 0.0;
    }
}

function pulse(a, forward) {
    // console.log(framecounter, a, pulse_length_z);
    var result;
    if (forward) {
        result = (a < 0) && (a > -pulse_length_numpnts) ? 1.0 : 0.0;
    }
    else {
        result = (a > 0) && (a < pulse_length_numpnts) ? 1.0 : 0.0;
    }
    return result;
}


function drawAll() {
    calcV();
    ctx.clearRect(0,0,canvas.width,canvas.height);
    // ctx.fillStyle = "#ccffff";
    // ctx.fillRect(0,0,canvas.width,canvas.height);
    drawAxes();
    drawLinePath();
    drawTextOnGraph();
}

function redrawAll() {
    if (timerRunning) {
        //document.getElementById("values").innerHTML = framecounter;
        drawAll();
        framecounter++;
    };
    requestAnimationFrame(redrawAll);
}

// coordinate transformation from plot coordinates to canvas coordinates
function to_x(xplot) {return xplot*axes.zscale + axes.x0;}
function to_y(yplot) {return -yplot*axes.vscale + axes.y0;}

function drawTextOnGraph() {
    ctx.save();
    ctx.fillStyle = "#ffffff";
    ctx.textAlign = "left";
    ctx.textBaseline = "middle";
    ctx.font = "15px Arial";
    ctx.fillStyle = "black";
    ctx.fillText("t = " + timeInUnitsOfT().toFixed(2) + " T",to_x(2),to_y(axes.vmax));
    ctx.fillText("v(" + z[numpnts-1].toFixed(0) + ") = " + voltage[numpnts-1].toFixed(3) + " V", to_x(23),to_y(axes.vmax) );
    ctx.restore();
}

function timeInUnitsOfT() {
    return framecounter / T; //numpnts;
    // return framecounter / num_frames_per_L; //numpnts;
}

// Calculate the voltage at the current time and position
function calcV() {
    set_voltage_to_0();
    for (var ii=0; ii<numpnts; ii++) {
        if (framecounter < T + pulse_length_numpnts) {
            voltage[ii] += v_delta[0] * pulse(ii - u_pnts_per_frame*framecounter, true);
            // voltage[ii] += v_delta[0] * pulse_forward(z[ii] - u_z_per_frame*framecounter);
            // console.log(framecounter, "a", ii, ii - u_pnts_per_frame*framecounter, voltage[ii])
        }
        var temp=1.0;
        if ((framecounter >= T) && (framecounter < 2*T + pulse_length_numpnts)) {
            voltage[ii] += v_delta[1] * pulse((numpnts-ii) - u_pnts_per_frame*(framecounter-T), true);
        }
        if ((framecounter >= 2*T) && (framecounter < 3*T + pulse_length_numpnts)) {
            voltage[ii] += v_delta[2] * pulse((ii) - u_pnts_per_frame*(framecounter-2*T), true);
        }
        if ((framecounter >= 3*T) && (framecounter < 4*T + pulse_length_numpnts)) {
            voltage[ii] += v_delta[3] * pulse((numpnts-ii) - u_pnts_per_frame*(framecounter-3*T), true);
        }
        if ((framecounter >= 4*T) && (framecounter < 5*T + pulse_length_numpnts)) {
            voltage[ii] += v_delta[4] * pulse((ii) - u_pnts_per_frame*(framecounter-4*T), true);
        }
        if ((framecounter >= 5*T) && (framecounter < 6*T + pulse_length_numpnts)) {
            voltage[ii] += v_delta[5] * pulse((numpnts-ii) - u_pnts_per_frame*(framecounter-5*T), true);
        }
    }
    // if (timerRunning) {
    //     var ii = framecounter % numpnts;
    //     var trip_number = Math.floor(framecounter/numpnts);
    //     if (isOdd(trip_number)) {
    //         ii = (numpnts-1) - ii;
    //     }
    //     voltage[ii] += v_delta[trip_number];
    //     // console.log(framecounter, trip_number, ii, voltage.length, v_delta[trip_number], isOdd(trip_number), framecounter % numpnts)
    //     //
    // }
}

function isOdd(num) { return (num % 2) == 1; }

function set_voltage_to_0() {
    for (var i=0; i<numpnts; i++) {
        voltage[i] = 0;
    }
}

function drawLinePath() {
    ctx.beginPath();
    ctx.lineWidth = 2;
    ctx.strokeStyle = "blue";
    ctx.moveTo(to_x(z[0]),to_y(voltage[0]));
    for (var i=1;i<=voltage.length;i++) {
        ctx.lineTo(to_x(z[i]),to_y(voltage[i]));
    }
    ctx.stroke();
}

function toggleButton() {
    if (timerRunning) {
        timerRunning = false;
        //document.getElementById("demo2").innerHTML = "Timer is stopped";
        document.getElementById("idTogButton").innerHTML = "Start";
    } else {
        timerRunning = true;
        //document.getElementById("demo2").innerHTML = "Timer is running";
        document.getElementById("idTogButton").innerHTML = "Stop";
        document.getElementById("idGammag").disabled = true;
        document.getElementById("idGammaL").disabled = true;
        document.getElementById("idSelectVoltage").disabled = true;
        document.getElementById("idRg").disabled = true;
        document.getElementById("idRL").disabled = true;
    };
}

function resetButton() {
    framecounter = 0;
    document.getElementById("idGammag").disabled = false;
    document.getElementById("idGammaL").disabled = false;
    document.getElementById("idSelectVoltage").disabled = false;
    document.getElementById("idRg").disabled = false;
    document.getElementById("idRL").disabled = false;
    set_voltage_to_0();
    calc_delta_voltages();
    drawAll();
};

function selectedVoltage() {
    return document.getElementById("idSelectVoltage").value;
}

function drawAxes() {
    ctx.beginPath();
    ctx.strokeStyle = "rgb(0,0,0)";
    ctx.lineWidth=0.5;
    ctx.moveTo(to_x(axes.zmin),to_y(axes.vmin)); ctx.lineTo(to_x(axes.zmax),to_y(axes.vmin)); // z axis
    ctx.moveTo(to_x(0),to_y(axes.vmin)); ctx.lineTo(to_x(0),to_y(axes.vmax)); // v axis on left
    ctx.moveTo(to_x(axes.zmax),to_y(axes.vmin)); ctx.lineTo(to_x(axes.zmax),to_y(axes.vmax)); // v axis on right
    // major & minor tic marks on horizontal axis
    for (var i = 0; i <= axes.zmax; i++) {
        var half_tic = i % 5 ? 0.015*axes.vrange : 0.025*axes.vrange;
        ctx.moveTo(to_x(i*1.0),to_y(axes.vmin+half_tic)); ctx.lineTo(to_x(i*1.0),to_y(axes.vmin-half_tic));
    }
    // major & minor tic marks on vertical axis
    var vtickstep = selectedVoltage() == "5.0" ? 5 : 2; // reduce # of minor steps if v_g is 5V
    var vtickmajorminor = vtickstep == 2 ? 5 : 2; // how many divisions for minor steps?
    for (var i=Math.floor(axes.vmin+1)*10; i <= axes.vmax*10; i+=vtickstep) {
        var half_tic = i % vtickmajorminor ? 0.15 : 0.25;
        ctx.moveTo(to_x(axes.zmin-half_tic),to_y(i/10));
        ctx.lineTo(to_x(axes.zmin+half_tic),to_y(i/10));
        ctx.moveTo(to_x(axes.zmax-half_tic),to_y(i/10));
        ctx.lineTo(to_x(axes.zmax+half_tic),to_y(i/10));
    }
    ctx.stroke();
    // Set up text properties
    ctx.textAlign = "left";
    ctx.textBaseline = "middle";
    ctx.font = "15px Arial";
    ctx.fillStyle = "#000000";
    ctx.textAlign = "center";
    // Vertical axis label tic labels
    var indexstep = selectedVoltage() == "1.0" ? 1 : 2;
    var vto = 0.8;
    for (var i=Math.floor(axes.vmin+1); i<=Math.floor(axes.vmax); i+=indexstep) {
        ctx.fillText(i.toFixed(0),to_x(axes.zmin-vto),to_y(i));
        ctx.fillText(i.toFixed(0),to_x(axes.zmax+vto),to_y(i));
    }
    // Vertical axis label
    ctx.save();
    ctx.translate(to_x(0),to_y(0));
    ctx.rotate(-Math.PI/2);
    ctx.fillText("Voltage (V)", 0, -35);
    ctx.restore();
    // Horizontal axis label tic labels
    ctx.font = "12px Arial";
    var hTicLabelOffsetFactor = -0.06;
    var vto = axes.vrange * hTicLabelOffsetFactor;
    ctx.fillText("0",to_x(0),to_y(axes.vmin+vto));
    ctx.fillText("5",to_x(axes.zmax/6),to_y(axes.vmin+vto));
    ctx.fillText("10",to_x(axes.zmax*2/6),to_y(axes.vmin+vto));
    ctx.fillText("15",to_x(axes.zmax*3/6),to_y(axes.vmin+vto));
    ctx.fillText("20",to_x(axes.zmax*4/6),to_y(axes.vmin+vto));
    ctx.fillText("25",to_x(axes.zmax*5/6),to_y(axes.vmin+vto));
    ctx.fillText("30",to_x(axes.zmax),to_y(axes.vmin+vto));
    // Horizontal axis label
    ctx.fillText("z (m)", to_x(axes.zrange/2), to_y(axes.vmin+vto*2.1));
}

//----------------------------------------
// Draw transmission line figure
//----------------------------------------

function draw_tline_fig() {<commit_msg>Finish updating-modifying-refactoring code; re-organize code and add comments<commit_after><!DOCTYPE html>
<html>
<meta  content="text/html; charset=UTF-8"  http-equiv="content-type">

<!-- Author: <NAME>
     2/5/16
     Purpose: Visualize voltage pulse on transmission line
 -->

<head>
    <title>T-Line Voltage Pulse</title>

    <style>
        fieldset {
            background-color:lightgrey;
            width:420px;
            margin:auto;
            text-align:left;
        }
        legend {
            background-color:white;
            border:2px solid grey;
            padding-left: 5px;
            padding-right: 5px;
        }
        button {
            background-color:lightblue;
            border:2px solid grey;
            padding-left: 5px;
            padding-right: 5px;
        }
        table {
            /* make the border continuous (without gaps between columns) */
            border-collapse: collapse;
        }
        tr.separated td {
            /* set border style for separated rows */
            border-bottom: 1px solid grey;
        }
        .params {
            table-layout: fixed;
            width: 100%;
            white-space: nowrap;
            cellspacing: 5px;
            cellpadding: 5px;
        }
        .params td {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .params .col-1 {
            width: 10%;
            text-align: right;
        }
        .params .col-2 {
            width: 40%;
        }
        .params .col-3 {
            width: 10%;
            text-align: right;
        }
        .params .col-4 {
            width: 30%;
        }
        .Rinput {
            /* set width of textboxes */
            width: 60px;
        }
    </style>

</head>
<body>
<div style="text-align:center" width:700px margin:auto>
    <h2>Voltage Pulse on a Transmission Line</h2>
    <!-- <canvas id="canvas_tline_fig" width="500" height="150"></canvas>
    <p> </p> -->
    <canvas id="canvas" width="600" height="300"></canvas>
    <p> </p>
    <button id="idTogButton" onclick="toggleButton()">Start</button>
    <button id="idResetButton" onclick="resetButton()">Reset</button>
    <br />
    <br />

    <fieldset>
        <legend>Parameters</legend>

        <table class="params">
            <!-- <col class="col-1" />
            <col class="col-2" /> -->
            <tr>
                <td class="col-1">
                    <label for="idSelectVoltage">v<sub>g</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <select name="vglist" id="idSelectVoltage" oninput="vgUpdate(value)">
                        <option value="1.0">1.0 V</option>
                        <option value="3.3">3.3 V</option>
                        <option value="5.0">5.0 V</option>
                    </select>
                </td>
                <td class="col-3">
                    <p></p>
                </td>
                <td class="col-4">
                    <p></p>
                </td>
            </tr>
            <tr>
                <td class="col-1">
                    <label for="idtpulse">t<sub>pulse</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <input type="number" id="idtpulse" min="0" value="0.4"
                        max="20" class="Rinput" oninput="tpulseUpdate(value)">
                    <output for="idtpulse" id="idtpulseUnits">T</output>
                </td>
                <td class="col-3">
                    <p></p>
                </td>
                <td class="col-4">
                    <p></p>
                </td>
            </tr>
            <tr>
                <td class="col-1">
                    <label for="idGammag">&#915;<sub>g</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <input type="range" id="idGammag" min="-1" max="0.99" value="0"
                         step="any" oninput="GammagUpdate(value)">
                    <output for="idGammag" id="idGammagValue">0</output>
                </td>
                <td class="col-3">
                    <label for="idRg">R<sub>g</sub> &nbsp;</label>
                </td>
                <td class="col-4">
                    <input type="number" id="idRg" min="0" value="50"
                         class="Rinput" oninput="RgUpdate(value)">
                    <output for="idRg" id="idRgValue">&Omega;</output>
                </td>
            </tr>
            <tr>
                <td class="col-1">
                    <label for="idGammaL">&#915;<sub>L</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <input type="range" id="idGammaL" min="-1" max="0.99" value="0.5"
                           step="any" oninput="GammaLUpdate(value)">
                    <output for="idGammaL" id="idGammaLValue">0.8</output>
                </td>
                <td class="col-3">
                    <label for="idRL">R<sub>L</sub> &nbsp;</label>
                </td>
                <td class="col-4">
                    <input type="number" id="idRL" min="0" value="150"
                         class="Rinput" oninput="RLUpdate(value)">
                    <output for="idRL" id="idRLValue">&Omega;</output>
                </td>
            </tr>
            <tr class="separated">
                <td><p></p></td> <td><p></p></td> <td><p></p></td> <td><p></p></td>
            </tr>
            <tr>
                <td><p></p></td> <td><p></p></td> <td><p></p></td> <td><p></p></td>
            </tr>
            <tr>
                <td class="col-1">
                    <label for="idZ0">Z<sub>0</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <input type="number" id="idZ0" value="50"
                         class="Rinput" disabled>
                    <output for="idZ0" id="idZ0Value">&Omega;</output>
                </td>
                <td class="col-3">
                    <p></p>
                </td>
                <td class="col-4">
                    <p></p>
                </td>
            </tr>
            <tr>
                <td class="col-1">
                    <label for="idv1plus">v<sup>+</sup><sub>1</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <input type="number" id="idv1plus" value="0.5"
                         class="Rinput" disabled>
                    <output for="idv1plus" id="idv1plusValue">V (initial voltage)</output>
                </td>
                <td class="col-3">
                    <p></p>
                </td>
                <td class="col-4">
                    <p></p>
                </td>
            </tr>
            <tr>
                <td class="col-1">
                    <label for="idvss">v<sub>ss</sub> &nbsp;</label>
                </td>
                <td class="col-2">
                    <input type="number" id="idvss" value="0.75"
                         class="Rinput" disabled>
                    <output for="idvss" id="idvssValue">V (steady state)</output>
                </td>
                <td class="col-3">
                    <p></p>
                </td>
                <td class="col-4">
                    <p></p>
                </td>
            </tr>
        </table>
    </fieldset>
</div>

<p id="values" style="text-align:center"></p>
<p id="demo2"></p>



<script>

//---------------------------------------------------------------------
// Define and initialize parameters, start animation loop
//---------------------------------------------------------------------

var Z0 = 50;
var v_g = 1.0;
update_params();

// Set up canvas and drawing area on canvas (values in "axes" are critical)
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var frac_max_x = 0.8;
var frac_max_y = 0.75;
var axes={};
set_axes();

//draw_tline_fig();

// Set up v1plus, v1minus, v2plus, v2minus, etc in array v_delta
var num_roundtrips = 15;
var v_delta = [];
for (i=0; i<=2*num_roundtrips; i++) {
    v_delta.push(0);
}
calc_delta_voltages();
print_delta_voltages();
var v_tolerance = 0.01; // only use v_delta values greater than this

// Set up voltage and z-axis arrays
var numpnts = 100;
var voltage = [];
for (var i=0; i<numpnts; i++) {
    voltage.push(0);
}
var z = [];
for (var i=0; i<numpnts; i++) {
    z.push(axes.zmin + (axes.zmax - axes.zmin)*i/(numpnts-1));
}

// Set up frame counter, velocity, T, pulse length (all in units of points)
var framecounter = 0;
var u_pnts_per_frame = 1; // velocity in points on z-axis traveled per frame
var T = numpnts / u_pnts_per_frame; // how long it takes in frames to travel once down t-line
var pulse_length_T = 0.4; // pulse length in units of T
var pulse_length_numpnts; // pulse length in units of points on plot
var pulse_length_z; // pulse length in units of z
pulse_length_update(); // initialize pulse_length_numpnts & pulse_length_z
console.log(T, pulse_length_T, pulse_length_numpnts, pulse_length_z);

// Make initial drawing on Canvas
drawAll();

// Start animation loop
var timerRunning = false;
redrawAll();

//---------------------------------------------------------------------
// Set up main drawing functions
//---------------------------------------------------------------------

function drawAll() {
    calcV();
    ctx.clearRect(0,0,canvas.width,canvas.height);
    // ctx.fillStyle = "#ccffff";
    // ctx.fillRect(0,0,canvas.width,canvas.height);
    drawAxes();
    drawLinePath();
    drawTextOnGraph();
}

function redrawAll() {
    if (timerRunning) {
        //document.getElementById("values").innerHTML = framecounter;
        drawAll();
        framecounter++;
    };
    requestAnimationFrame(redrawAll);
}

//---------------------------------------------------------------------
// Calculate voltage on t-line
//---------------------------------------------------------------------

function calc_delta_voltages() {
    // v_delta[0] = v1_plus();
    for (var i=0; i<=num_roundtrips*2; i++) {
        if (i==0) {
            v_delta[i] = v1_plus();
        }
        else {
            var gamma = isOdd(i) ? GammaL() : Gammag();
            v_delta[i] = gamma * v_delta[i-1];
        }
    }
}

function pulse(a) {
    return (a < 0) && (a > -pulse_length_numpnts) ? 1.0 : 0.0;
}

// Calculate the voltage at the current time and position
function calcV() {
    set_voltage_to_0();
    for (var i=0; i<numpnts; i++) {
        voltage[i] = voltage_at_i(i);
    }
}

function set_voltage_to_0() {
    for (var i=0; i<numpnts; i++) {
        voltage[i] = 0;
    }
}

function voltage_at_i(i) {
    var j=0;
    var temp_voltage = 0;
    while ((Math.abs(v_delta[j]) > v_tolerance) && (j < v_delta.length)) {
        if ((framecounter >= j*T) && (framecounter < (j+1)*T + pulse_length_numpnts)) {
            var index = isOdd(j) ? numpnts-i : i;
            temp_voltage += v_delta[j] * pulse(index - u_pnts_per_frame*(framecounter - j*T));
        }
        j++;
    }
    // console.log(framecounter,i,j,v_delta.length,v_delta[j-1],temp_voltage);
    return temp_voltage;
}

//---------------------------------------------------------------------
// Utility functions
//---------------------------------------------------------------------

// coordinate transformation from plot coordinates to canvas coordinates
function to_x(xplot) {return xplot*axes.zscale + axes.x0;}
function to_y(yplot) {return -yplot*axes.vscale + axes.y0;}

function set_axes() {
    axes.x0 = canvas.width * (1-frac_max_x)/2;  // x0 pixels from left to x=0
    axes.y0 = canvas.height * (frac_max_y/2 + (1-frac_max_y)/2); // y0 pixels from top to y=0
    axes.zmin = 0.;
    axes.zmax = 30.;
    axes.vmin = -v_g*2.1;
    axes.vmax = v_g*2.1;
    axes.zrange = axes.zmax - axes.zmin;
    axes.vrange = axes.vmax - axes.vmin;
    axes.zscale = canvas.width * frac_max_x / axes.zrange;  // # canvas pixels per unit in z
    axes.vscale = canvas.height * frac_max_y / axes.vrange;  // # canvas pixels per unit in v
}

function isOdd(num) { return (num % 2) == 1; }

function pulse_length_update() {
    pulse_length_numpnts = numpnts * pulse_length_T; // pulse length in units of points on plot
    pulse_length_z = pulse_length_T * axes.zrange; // pulse length in units of z
}

function print_delta_voltages() {
    console.log("-----------start v_delta,", v_delta.length, "values-----------");
    for (i=0; i<=2*num_roundtrips; i++) {
        console.log(i, v_delta[i]);
    }
    console.log('-----------end v_delta-----------');
}

function GammaL() {
    return Number(document.querySelector('#idGammaL').value);
}

function Gammag() {
    return Number(document.querySelector('#idGammag').value);
}

function RL() {
    return R_from_Gamma(GammaL());
}

function Rg() {
    return R_from_Gamma(Gammag());
}

function v1_plus() {
    return v_g * Z0 / (Z0 + Rg());
}

function v_steadystate() {
    if (GammaL() == 1) {
        return v_g;
    } else {
        return v_g * RL() / (RL() + Rg());
    }
}

function update_params() {
    calc_delta_voltages();
    document.querySelector('#idv1plus').value = v1_plus().toFixed(2);
    document.querySelector('#idvss').value = v_steadystate().toFixed(2);
}

function R_from_Gamma(g) {
    return Z0 * (1.0 + g) / (1.0 - g);
}

function Gamma_from_R(R) {
    return (R-Z0) / (R+Z0);
}

function timeInUnitsOfT() {
    return framecounter / T; //numpnts;
}

function selectedVoltage() {
    return document.getElementById("idSelectVoltage").value;
}

//---------------------------------------------------------------------
// Callback functions for controls (buttons, sliders, textboxes, etc.)
//---------------------------------------------------------------------

function toggleButton() {
    if (timerRunning) {
        timerRunning = false;
        //document.getElementById("demo2").innerHTML = "Timer is stopped";
        document.getElementById("idTogButton").innerHTML = "Start";
    } else {
        timerRunning = true;
        //document.getElementById("demo2").innerHTML = "Timer is running";
        document.getElementById("idTogButton").innerHTML = "Stop";
        document.getElementById("idGammag").disabled = true;
        document.getElementById("idGammaL").disabled = true;
        document.getElementById("idSelectVoltage").disabled = true;
        document.getElementById("idtpulse").disabled = true;
        document.getElementById("idRg").disabled = true;
        document.getElementById("idRL").disabled = true;
    };
}

function resetButton() {
    framecounter = 0;
    document.getElementById("idGammag").disabled = false;
    document.getElementById("idGammaL").disabled = false;
    document.getElementById("idSelectVoltage").disabled = false;
    document.getElementById("idtpulse").disabled = false;
    document.getElementById("idRg").disabled = false;
    document.getElementById("idRL").disabled = false;
    set_voltage_to_0();
    calc_delta_voltages();
    drawAll();
};

function vgUpdate(value) {
    v_g = Number(value);
    console.log(value, v_g);
    update_params();
    set_axes();
    drawAll();
}

function tpulseUpdate(value) {
    pulse_length_T = Number(value);
    pulse_length_update();
}

function GammaLUpdate(value) {
	document.querySelector('#idGammaLValue').innerHTML = Number(value).toFixed(2);
    var temp = R_from_Gamma(Number(value));
    document.querySelector('#idRL').value = RL().toFixed(1);
    update_params();
    if (!timerRunning) drawAll();
}

function GammagUpdate(value) {
	document.querySelector('#idGammagValue').innerHTML = Number(value).toFixed(2);
    var temp = R_from_Gamma(Number(value));
    document.querySelector('#idRg').value = temp.toFixed(1);
    update_params();
    if (!timerRunning) drawAll();
}

function RgUpdate(value) {
    var temp = Gamma_from_R(Number(value));
    console.log(Z0, value, temp, Gamma_from_R(value));
    document.querySelector('#idGammagValue').innerHTML = temp.toFixed(2);
    document.querySelector('#idGammag').value = temp;
    update_params();
    if (!timerRunning) drawAll();
}

function RLUpdate(value) {
    var temp = Gamma_from_R(Number(value));
    console.log(Z0, value, temp, Gamma_from_R(value));
    document.querySelector('#idGammaLValue').innerHTML = temp.toFixed(2);
    document.querySelector('#idGammaL').value = temp;
    update_params();
    if (!timerRunning) drawAll();

}

//---------------------------------------------------------------------
// Nitty-gritty drawing functions
//---------------------------------------------------------------------

function drawLinePath() {
    ctx.beginPath();
    ctx.lineWidth = 2;
    ctx.strokeStyle = "blue";
    ctx.moveTo(to_x(z[0]),to_y(voltage[0]));
    for (var i=1;i<=voltage.length;i++) {
        ctx.lineTo(to_x(z[i]),to_y(voltage[i]));
    }
    ctx.stroke();
}

function drawTextOnGraph() {
    ctx.save();
    ctx.fillStyle = "#ffffff";
    ctx.textAlign = "left";
    ctx.textBaseline = "middle";
    ctx.font = "15px Arial";
    ctx.fillStyle = "black";
    ctx.fillText("t = " + timeInUnitsOfT().toFixed(2) + " T",to_x(2),to_y(axes.vmax));
    ctx.fillText("v(" + z[numpnts-1].toFixed(0) + ") = " + voltage[numpnts-1].toFixed(3) + " V", to_x(23),to_y(axes.vmax) );
    ctx.restore();
}

function drawAxes() {
    ctx.beginPath();
    ctx.strokeStyle = "rgb(0,0,0)";
    ctx.lineWidth=0.5;
    ctx.moveTo(to_x(axes.zmin),to_y(axes.vmin)); ctx.lineTo(to_x(axes.zmax),to_y(axes.vmin)); // z axis
    ctx.moveTo(to_x(0),to_y(axes.vmin)); ctx.lineTo(to_x(0),to_y(axes.vmax)); // v axis on left
    ctx.moveTo(to_x(axes.zmax),to_y(axes.vmin)); ctx.lineTo(to_x(axes.zmax),to_y(axes.vmax)); // v axis on right
    // major & minor tic marks on horizontal axis
    for (var i = 0; i <= axes.zmax; i++) {
        var half_tic = i % 5 ? 0.015*axes.vrange : 0.025*axes.vrange;
        ctx.moveTo(to_x(i*1.0),to_y(axes.vmin+half_tic)); ctx.lineTo(to_x(i*1.0),to_y(axes.vmin-half_tic));
    }
    // major & minor tic marks on vertical axis
    var vtickstep = selectedVoltage() == "5.0" ? 5 : 2; // reduce # of minor steps if v_g is 5V
    var vtickmajorminor = vtickstep == 2 ? 5 : 2; // how many divisions for minor steps?
    for (var i=Math.floor(axes.vmin+1)*10; i <= axes.vmax*10; i+=vtickstep) {
        var half_tic = i % vtickmajorminor ? 0.15 : 0.25;
        ctx.moveTo(to_x(axes.zmin-half_tic),to_y(i/10));
        ctx.lineTo(to_x(axes.zmin+half_tic),to_y(i/10));
        ctx.moveTo(to_x(axes.zmax-half_tic),to_y(i/10));
        ctx.lineTo(to_x(axes.zmax+half_tic),to_y(i/10));
    }
    ctx.stroke();
    // Set up text properties
    ctx.textAlign = "left";
    ctx.textBaseline = "middle";
    ctx.font = "15px Arial";
    ctx.fillStyle = "#000000";
    ctx.textAlign = "center";
    // Vertical axis label tic labels
    var indexstep = selectedVoltage() == "1.0" ? 1 : 2;
    var vto = 0.8;
    for (var i=Math.floor(axes.vmin+1); i<=Math.floor(axes.vmax); i+=indexstep) {
        ctx.fillText(i.toFixed(0),to_x(axes.zmin-vto),to_y(i));
        ctx.fillText(i.toFixed(0),to_x(axes.zmax+vto),to_y(i));
    }
    // Vertical axis label
    ctx.save();
    ctx.translate(to_x(0),to_y(0));
    ctx.rotate(-Math.PI/2);
    ctx.fillText("Voltage (V)", 0, -35);
    ctx.restore();
    // Horizontal axis label tic labels
    ctx.font = "12px Arial";
    var hTicLabelOffsetFactor = -0.06;
    var vto = axes.vrange * hTicLabelOffsetFactor;
    ctx.fillText("0",to_x(0),to_y(axes.vmin+vto));
    ctx.fillText("5",to_x(axes.zmax/6),to_y(axes.vmin+vto));
    ctx.fillText("10",to_x(axes.zmax*2/6),to_y(axes.vmin+vto));
    ctx.fillText("15",to_x(axes.zmax*3/6),to_y(axes.vmin+vto));
    ctx.fillText("20",to_x(axes.zmax*4/6),to_y(axes.vmin+vto));
    ctx.fillText("25",to_x(axes.zmax*5/6),to_y(axes.vmin+vto));
    ctx.fillText("30",to_x(axes.zmax),to_y(axes.vmin+vto));
    // Horizontal axis label
    ctx.fillText("z (m)", to_x(axes.zrange/2), to_y(axes.vmin+vto*2.1));
}

//----------------------------------------
// Draw transmission line figure
// (2/5/16: unused for this visualization--needs updated)
//----------------------------------------

function draw_tline_fig() {
{'fraction_non_alphanumeric': 0.18820976126785444, 'fraction_numerical': 0.01915409074849846, 'mean_word_length': 1.9377270368448365, 'pattern_counts': {'":': 0, '<': 497, '<?xml version=': 0, '>': 474, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '967192', 'n_tokens_mistral': 13928, 'n_tokens_neox': 13187, 'n_words': 2479}