IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 25, 2025, 4:08:45 PM (14 months ago)
Author:
cclin33
Message:

update czar plot code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ippMonitor/raw/dataquality.php

    r42790 r42795  
    2222
    2323// Fetch data based on range selection
    24 $range = isset($_GET['range']) ? $_GET['range'] : 'week';
     24$range = isset($_GET['range']) ? $_GET['range'] : 'yday';
    2525
    2626echo "<table border=\"0\">";
     
    2929echo "    <h1 align=\"middle\">Data Quality Report</h1>";
    3030echo "  <center>";
    31 echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=day">Today (MJD: '.getMJD().')</a> | ';
    32 echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=week">Past week (default)</a> | ';
    33 echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=month">Past month</a> | ';
    34 echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=year">Past year </a> | ';
     31echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=yday">Last night (default)</a> | ';
     32echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=day">Today (MJD '.getMJD().')</a> | ';
     33echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=week">Past 7 days</a> | ';
     34echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=month">Past 30 days</a> | ';
     35echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=year">Past 365 days</a> | ';
     36echo '    <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=all">All </a>   ';
    3537echo "  </td>";
    3638echo "</tr>";
    3739echo "</table>";
    38 echo getDataQuality2($projectdb, $range);
     40echo getDataQuality($projectdb, $range);
    3941
    4042menu_end();
     
    5153#
    5254###########################################################################
    53 function getDataQuality2($db, $range = 'week') {
     55function getDataQuality($db, $range = 'yday') {
    5456    // Start timer
    5557    $start = microtime(true);
     
    6163
    6264    // Determine the reference exp_name based on the selected range
    63     if ($range === 'year') {
    64         $expname = "o" . $mjdDay_yearback . "%";
    65     } elseif ($range === 'month') {
    66         $expname = "o" . $mjdDay_monthback . "%";
    67     } else {
    68         $expname = "o" . ($mjdDay - 7) . "%"; // Default week-based constraint
     65    switch ($range) {
     66        case 'year':
     67            $expname = "o" . $mjdDay_yearback . "%";
     68            break;
     69        case 'month':
     70            $expname = "o" . $mjdDay_monthback . "%";
     71            break;
     72        case 'week':
     73            $expname = "o" . ($mjdDay - 7) . "%";
     74            break;
     75        case 'day':
     76            $expname = "o" . $mjdDay . "%";
     77            break;
     78        default:
     79            $expname = "o" . ($mjdDay - 1) . "%"; // Default: last night
     80            break;
    6981    }
    7082
    7183    // Query to get the minimum exp_id
    72     $expIdQuery = "SELECT MIN(exp_id) AS min_exp_id FROM rawExp WHERE rawExp.exp_name LIKE '$expname';";
    73 
     84    $expIdQuery = "SELECT MIN(exp_id) AS min_exp_id FROM rawExp WHERE rawExp.exp_name LIKE '$expname'";
    7485    $result = $db->query($expIdQuery);
    7586
    76     // Fetch result into $row as an associative array
    77     $result->fetchInto($row, DB_FETCHMODE_ASSOC);
     87    if (DB::isError($result)) {
     88        die("Database error: " . $result->getMessage());
     89    }
     90
     91    $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
    7892
    7993    if (!empty($row['min_exp_id'])) {
    8094        $min_exp_id = $row['min_exp_id'];
    81         echo "Minimum exp_id: " . $min_exp_id;
     95    //    echo "Minimum exp_id: " . $min_exp_id;
    8296    } else {
    8397        echo "No results found.";
    8498    }
    8599
    86     echo "<br><br>";
    87 
    88     // Apply different constraints based on the selected range
    89     if ($range === 'year') {
    90         // Constraint by dateobs within the last 365 days
    91         $dateConstraint = "dateobs >= NOW() - INTERVAL 365 DAY AND rawExp.exp_id >= $min_exp_id";
    92     } elseif ($range === 'month') {
    93         // Constraint by dateobs within the last 30 days
    94         $dateConstraint = "dateobs >= NOW() - INTERVAL 30 DAY AND rawExp.exp_id >= $min_exp_id";
    95     } else {
    96         // Constraint by exp_name for week and day ranges
    97         $expnames = array();
    98         $days = ($range === 'day') ? 1 : 7; // Set days to 1 for 'day', otherwise default to 7 (week)
    99 
    100         for ($i = 0; $i < $days; $i++) {
    101             $expnames[] = "'o" . ($mjdDay - $i) . "%'";
    102         }
    103         $expnameFilter = " (rawExp.exp_name LIKE " . implode(" OR rawExp.exp_name LIKE ", $expnames) . ") AND rawExp.exp_id >= $min_exp_id";
    104         $dateConstraint = $expnameFilter;
     100    //echo "<br><br>";
     101
     102    // Determine the date constraint based on the range
     103    switch ($range) {
     104        case 'year':
     105            $dateConstraint = "dateobs >= NOW() - INTERVAL 365 DAY AND rawExp.exp_id >= $min_exp_id";
     106            break;
     107        case 'month':
     108            $dateConstraint = "dateobs >= NOW() - INTERVAL 30 DAY AND rawExp.exp_id >= $min_exp_id";
     109            break;
     110        case 'week':
     111            $expnames = array();
     112            for ($i = 0; $i < 7; $i++) {
     113                $expnames[] = "rawExp.exp_name LIKE 'o" . ($mjdDay - $i) . "%'";
     114            }
     115            $dateConstraint = "(" . implode(" OR ", $expnames) . ") AND rawExp.exp_id >= $min_exp_id";
     116            break;
     117        case 'yday':
     118            $dateConstraint = "rawExp.exp_name LIKE 'o" . ($mjdDay - 1) . "%' AND rawExp.exp_id >= $min_exp_id";
     119            break;
     120        case 'day':
     121            $dateConstraint = "rawExp.exp_name LIKE 'o$mjdDay%' AND rawExp.exp_id >= $min_exp_id";
     122            break;
     123        case 'all':
     124            $dateConstraint = "rawExp.exp_id >= 0";
     125            break;
     126        default: // Default to last night
     127            $dateConstraint = "rawExp.exp_name LIKE 'o" . ($mjdDay - 1) . "%' AND rawExp.exp_id >= $min_exp_id";
     128            break;
    105129    }
    106130
     
    109133                   round(( 367*YEAR(dateobs)- FLOOR((7 * (YEAR(dateobs) + FLOOR((MONTH(dateobs) + 9) / 12))) / 4) + FLOOR(275 * MONTH(dateobs) / 9)
    110134                   + DAY(dateobs) + 1721013.5 + (HOUR(dateobs) / 24.0) + (MINUTE(dateobs) / 1440.0) + (SECOND(dateobs) / 86400.0) - 2400000.5), 5) AS MJD,
    111                    filter, comment, ra*180/pi() as RA, decl*180/pi() as DECL, exp_name, alt, az, fwhm_major, fwhm_minor, zpt_obs, zpt_stdev, rawExp.exp_id
     135                   filter, comment, ra*180/pi() as RA, decl*180/pi() as DECL, exp_name, alt, az, fwhm_major, fwhm_minor, zpt_obs, zpt_stdev, rawExp.exp_id, camRun.label
    112136            FROM rawExp
    113137            JOIN chipRun USING (exp_id)
     
    126150        return;
    127151    }
    128         echo "<b>Error with $sql</b><br>\n";
     152    //    echo "$sql<br><br>\n";
    129153
    130154    while ($qry->fetchInto($row)) {
     
    148172    echo "<script>console.log(" . json_encode($dataJson) . ");</script>"; // Log JSON output to console for debugging
    149173echo <<<HTML
    150 <script type="text/javascript" src="loader.js"></script>
     174<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js" onerror="loadLocalGoogleCharts()"></script>
     175
     176<script type="text/javascript">
     177    // Check if Google Charts library loaded successfully
     178    window.addEventListener("load", function() {
     179        if (typeof google === "undefined" || typeof google.charts === "undefined") {
     180            loadLocalGoogleCharts();
     181        }
     182    });
     183
     184    // Function to load local version of Google Charts if CDN fails
     185    function loadLocalGoogleCharts() {
     186        console.warn("Google Charts CDN failed, loading local loader.js instead.");
     187        var script = document.createElement("script");
     188        script.src = "loader.js"; // Path to your local loader.js file
     189        document.head.appendChild(script);
     190    }
     191</script>
    151192
    152193<script type="text/javascript">
     
    168209
    169210        const rows = dataArray.map(row => {
    170             const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id] = row;
     211            const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id, cam_label] = row;
    171212
    172213            return [
    173214                parseFloat(mjd),      // Position Angle
    174215                parseFloat(iq_fwhm_maj),         // RA_offset (AST_R0)
    175                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
     216                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
    176217                parseFloat(iq_fwhm_min),        // Dec_offset (AST_D0)
    177                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
     218                "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,
    178219                4,
    179220                12
     
    183224        data.addRows(rows);
    184225
     226        // Extract the first MJD value from dataArray
     227        //const firstMJD = dataArray.length > 0 ? parseFloat(dataArray[0][1]) : "N/A";
     228        const firstMJD = dataArray.length > 0 ? Math.floor(parseFloat(dataArray[0][1])) : "N/A";
     229        console.log("First MJD Value:", firstMJD);
     230
    185231        const options = {
    186             title: 'FWHM (MJD) ',
     232            title: 'FWHM (MJD: '+firstMJD+')',
    187233            titleTextStyle: {color: 'black', fontSize: 15},
    188234            width: '100%',
     
    190236            legend: { position: 'top', alignment: 'center' },
    191237            series: {
    192                 0: { color: '#0000ff', pointSize: 3, lineWidth: 1 },
    193                 1: { color: '#33a532', pointSize: 3, lineWidth: 1 },
     238                0: { color: '#0000ff', pointSize: 2, lineWidth: 0. },
     239                1: { color: '#33a532', pointSize: 2, lineWidth: 0. },
    194240                2: { color: 'red', lineWidth: 2, pointSize: 0 },
    195241                3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }
     
    208254        };
    209255
    210         const chart = new google.visualization.LineChart(document.getElementById('dq_div_fwhm'));
     256        const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_fwhm'));
    211257        chart.draw(data, options);
    212258    }
     
    244290
    245291        const rows = dataArray.map(row => {
    246             const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id] = row;
     292            const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id, cam_label] = row;
    247293
    248294            // Initialize all filter values as null
     
    273319            return [
    274320                parseFloat(mjd), // MJD value
    275                 zp_g, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_g - zpt_stdev), parseFloat(zp_g - zpt_stdev*-1),
    276                 zp_r, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_r - zpt_stdev), parseFloat(zp_r - zpt_stdev*-1),
    277                 zp_i, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_i - zpt_stdev), parseFloat(zp_i - zpt_stdev*-1),
    278                 zp_z, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_z - zpt_stdev), parseFloat(zp_z - zpt_stdev*-1),
    279                 zp_y, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_y - zpt_stdev), parseFloat(zp_y - zpt_stdev*-1),
    280                 zp_w, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_w - zpt_stdev), parseFloat(zp_w - zpt_stdev*-1)
     321                zp_g, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     322parseFloat(zp_g - zpt_stdev), parseFloat(zp_g - zpt_stdev*-1),
     323                zp_r, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     324parseFloat(zp_r - zpt_stdev), parseFloat(zp_r - zpt_stdev*-1),
     325                zp_i, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     326parseFloat(zp_i - zpt_stdev), parseFloat(zp_i - zpt_stdev*-1),
     327                zp_z, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     328parseFloat(zp_z - zpt_stdev), parseFloat(zp_z - zpt_stdev*-1),
     329                zp_y, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     330parseFloat(zp_y - zpt_stdev), parseFloat(zp_y - zpt_stdev*-1),
     331                zp_w, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     332parseFloat(zp_w - zpt_stdev), parseFloat(zp_w - zpt_stdev*-1)
    281333            ];
    282334        });
     
    291343            legend: { position: 'top', alignment: 'start', maxLines: 3 },
    292344            series: {
    293                 0: { color: '#00f000', pointSize: 10, pointShape: 'circle',   linewidth: 1},  // 'g' filter
    294                 1: { color: '#f00000', pointSize: 10, pointShape: 'triangle', linewidth: 1},  // 'r' filter
    295                 2: { color: '#f05000', pointSize: 10, pointShape: 'square',   linewidth: 1},  // 'i' filter
    296                 3: { color: '#0050a0', pointSize: 10, pointShape: 'diamond',  linewidth: 1},  // 'z' filter
    297                4: { color: '#ffe000', pointSize: 10, pointShape: 'star',     linewidth: 1},  // 'y' filter
    298                 5: { color: '#808080', pointSize: 10, pointShape: 'polygon',  linewidth: 1},  // 'w' filter
    299             },
    300             intervals: { color: 'red', lineWidth: 1, style: 'sticks' },
     345                0: { color: '#00f000', pointSize: 5, pointShape: 'circle',   linewidth: .0},  // 'g' filter
     346                1: { color: '#f00000', pointSize: 5, pointShape: 'triangle', linewidth: .0},  // 'r' filter
     347                2: { color: '#f05000', pointSize: 5, pointShape: 'square',   linewidth: .0},  // 'i' filter
     348                3: { color: '#0050a0', pointSize: 5, pointShape: 'diamond',  linewidth: .0},  // 'z' filter
     349                4: { color: '#ffe000', pointSize: 5, pointShape: 'star',     linewidth: .0},  // 'y' filter
     350                5: { color: '#808080', pointSize: 5, pointShape: 'polygon',  linewidth: .0},  // 'w' filter
     351            },
     352            intervals: { color: 'red', lineWidth: .0, style: 'sticks' },
    301353            hAxis: {
    302354                title: 'MJD',
     
    312364        };
    313365
    314         const chart = new google.visualization.LineChart(document.getElementById('dq_div_zoomzpt'));
     366        const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_zoomzpt'));
    315367        chart.draw(data, options);
    316368    }
     
    350402        const filterCounts = { g: 0, r: 0, i: 0, z: 0, y: 0, w: 0 };
    351403       const rows = dataArray.map(row => {
    352             const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id] = row;
     404            const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id, cam_label] = row;
    353405
    354406            // Initialize all filter values as null
     
    384436            return [
    385437                parseFloat(mjd), // MJD value
    386                 zp_g, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_g - zpt_stdev), parseFloat(zp_g - zpt_stdev*-1),
    387                 zp_r, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_r - zpt_stdev), parseFloat(zp_r - zpt_stdev*-1),
    388                 zp_i, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_i - zpt_stdev), parseFloat(zp_i - zpt_stdev*-1),
    389                 zp_z, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_z - zpt_stdev), parseFloat(zp_z - zpt_stdev*-1),
    390                 zp_y, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_y - zpt_stdev), parseFloat(zp_y - zpt_stdev*-1),
    391                 zp_w, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,  parseFloat(zp_w - zpt_stdev), parseFloat(zp_w - zpt_stdev*-1),
     438                zp_g, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     439parseFloat(zp_g - zpt_stdev), parseFloat(zp_g - zpt_stdev*-1),
     440                zp_r, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     441parseFloat(zp_r - zpt_stdev), parseFloat(zp_r - zpt_stdev*-1),
     442                zp_i, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     443parseFloat(zp_i - zpt_stdev), parseFloat(zp_i - zpt_stdev*-1),
     444                zp_z, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     445parseFloat(zp_z - zpt_stdev), parseFloat(zp_z - zpt_stdev*-1),
     446                zp_y, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     447parseFloat(zp_y - zpt_stdev), parseFloat(zp_y - zpt_stdev*-1),
     448                zp_w, "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label, 
     449parseFloat(zp_w - zpt_stdev), parseFloat(zp_w - zpt_stdev*-1),
    392450            ];
    393451        });
     
    407465            legend: { position: 'top', alignment: 'center' },
    408466            series: {
    409                 0: { color: '#00f000', pointSize: 10, pointShape: 'circle',   linewidth: 1},  // 'g' filter
    410                 1: { color: '#f00000', pointSize: 10, pointShape: 'triangle', linewidth: 1},  // 'r' filter
    411                 2: { color: '#f05000', pointSize: 10, pointShape: 'square',   linewidth: 1},  // 'i' filter
    412                 3: { color: '#0050a0', pointSize: 10, pointShape: 'diamond',  linewidth: 1},  // 'z' filter
    413                 4: { color: '#ffe000', pointSize: 10, pointShape: 'star',     linewidth: 1},  // 'y' filter
    414                 5: { color: '#808080', pointSize: 10, pointShape: 'polygon',  linewidth: 1},  // 'w' filter
    415             },
    416             intervals: { color: 'red', lineWidth: 1, style: 'sticks' },
     467                0: { color: '#00f000', pointSize: 5, pointShape: 'circle',   linewidth: 1},  // 'g' filter
     468                1: { color: '#f00000', pointSize: 5, pointShape: 'triangle', linewidth: 1},  // 'r' filter
     469                2: { color: '#f05000', pointSize: 5, pointShape: 'square',   linewidth: 1},  // 'i' filter
     470                3: { color: '#0050a0', pointSize: 5, pointShape: 'diamond',  linewidth: 1},  // 'z' filter
     471                4: { color: '#ffe000', pointSize: 5, pointShape: 'star',     linewidth: 1},  // 'y' filter
     472                5: { color: '#808080', pointSize: 5, pointShape: 'polygon',  linewidth: 1},  // 'w' filter
     473            },
     474            intervals: { color: 'red', lineWidth: 0, style: 'sticks' },
    417475            hAxis: {
    418476                title: 'MJD',
     
    427485        };
    428486
    429         const chart = new google.visualization.LineChart(document.getElementById('dq_div_zpt'));
     487        const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_zpt'));
    430488        chart.draw(data, options);
    431489    }
     
    460518
    461519
    462 ###########################################################################
    463 #
    464 # Get data quality
    465 #
    466 ###########################################################################
    467 function getDataQuality($db, $range = 'week') {
    468     // Start timer
    469     $start = microtime(true);
    470 
    471     $mjdDay  = getMJD();
    472 
    473     $expnames = array();
    474     // Determine the number of days based on the selected range
    475     switch ($range) {
    476         case 'week':
    477             $days = 7;
    478             break;
    479         case 'month':
    480             $days = 30;
    481             break;
    482         case 'day':
    483         default:
    484             $days = 1;
    485             break;
    486     }
    487 
    488     for ($i = 0; $i < $days; $i++) {
    489         $expnames[] = "'o" . ($mjdDay - $i) . "%'";
    490     }
    491     $expnameFilter = implode(" OR rawExp.exp_name LIKE ", $expnames);
    492     $sql = "SELECT SUBTIME(dateobs, '10:00:00') AS time, AST_R0, AST_D0,
    493                    round(( 367*YEAR(dateobs)- FLOOR((7 * (YEAR(dateobs) + FLOOR((MONTH(dateobs) + 9) / 12))) / 4) + FLOOR(275 * MONTH(dateobs) / 9)
    494                    + DAY(dateobs) + 1721013.5 + (HOUR(dateobs) / 24.0) + (MINUTE(dateobs) / 1440.0) + (SECOND(dateobs) / 86400.0) - 2400000.5), 5) AS MJD,
    495                    filter, exp_time, comment, ra*180/pi() as RA, decl*180/pi() as DECL, AST_RS, AST_DS, AST_T0, posang, exp_name, alt, az, rawExp.exp_id
    496             FROM rawExp JOIN chipRun using (exp_id) JOIN camRun using (chip_id) JOIN camProcessedExp using (cam_id)
    497             WHERE (rawExp.exp_name LIKE " . $expnameFilter . ")
    498                AND exp_type = 'OBJECT'
    499                AND camRun.state like 'full'
    500                AND camProcessedExp.fault = 0
    501                AND camProcessedExp.zpt_obs != 0; ";
    502 
    503     $DQarray = array();
    504     $qry = $db->query($sql);
    505     if (dberror($qry)) {
    506         echo "<b>Error with $sql</b><br>\n";
    507         return;
    508     }
    509    
    510     while ($qry->fetchInto($row)) {
    511         $DQarray[] = $row;
    512     }
    513    
    514     // Ensure $DQarray is not empty
    515     if (empty($DQarray)) {
    516         echo "<b>Error:</b> Data array is empty.";
    517         return; // Stop execution if no data to encode
    518     }
    519    
    520     // Convert data array to JSON for easier handling in JavaScript
    521     $dataJson = json_encode($DQarray);
    522    
    523     if ($dataJson === false) {
    524         echo "<b>Error encoding JSON:</b> " . json_last_error_msg(); // Display any JSON encoding errors
    525         return; // Stop execution if JSON encoding fails
    526     }
    527    
    528     echo "<script>console.log(" . json_encode($dataJson) . ");</script>"; // Log JSON output to console for debugging
    529    
    530     echo <<<HTML
    531     <!-- Attempt to load Google Charts library from the Google CDN -->
    532     <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js" onerror="loadLocalGoogleCharts()"></script>
    533    
    534     <script type="text/javascript">
    535         // Check if Google Charts library loaded successfully
    536         window.addEventListener("load", function() {
    537             if (typeof google === "undefined" || typeof google.charts === "undefined") {
    538                 loadLocalGoogleCharts();
    539             }
    540         });
    541    
    542         // Function to load local version of Google Charts if CDN fails
    543         function loadLocalGoogleCharts() {
    544             console.warn("Google Charts CDN failed, loading local loader.js instead.");
    545             var script = document.createElement("script");
    546             script.src = "loader.js"; // Path to your local loader.js file
    547             document.head.appendChild(script);
    548         }
    549 </script>
    550 
    551 <script type="text/javascript">
    552     google.charts.load('current', {packages: ['corechart']});
    553 
    554     // Use the encoded JSON directly in JavaScript
    555     const dataArray = JSON.parse('{$dataJson}'); // Directly parse the PHP JSON string
    556 
    557     // draw pointing vs mjd
    558     function drawMJDChart() {
    559         var data = new google.visualization.DataTable();
    560             data.addColumn('number', 'MJD');
    561             data.addColumn('number', 'RA_offset (AST_R0)');
    562             data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
    563             data.addColumn('number', 'Dec_offset (AST_D0)');
    564             data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
    565             data.addColumn('number', '20 TP unit ~5.1"');
    566             data.addColumn('number', '-20 TP unit ~5.1"');
    567 
    568         const rows = dataArray.map(row => {
    569             const [timestamp, ra_offset, dec_offset, mjd, filter, exp_time, comment, ra, dec, ra_offset_sig, dec_offset_sig, boresite_ang, position_ang, exp_name, alt, az, exp_id] = row;
    570 
    571             return [
    572                 parseFloat(mjd),               // MJD
    573                 parseFloat(ra_offset),         // RA_offset (AST_R0)
    574                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
    575                 parseFloat(dec_offset),        // Dec_offset (AST_D0)
    576                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
    577                 20,                            // Dummy value for 20 TP unit
    578                 -20                            // Dummy value for -20 TP unit
    579             ];
    580         });
    581 
    582         data.addRows(rows);
    583        const options = {
    584             title: 'Pointing Offset (MJD)',
    585             titleTextStyle: {color: 'black', fontSize: 15},
    586             width: '100%',
    587             height: 480,
    588             legend: { position: 'top', alignment: 'center' },
    589             series: {
    590                 0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series
    591                 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series
    592                 2: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }, // Line at y = 20
    593                 3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }  // Line at y = -20
    594             },
    595             intervals: { color: 'red', lineWidth: 2, style: 'sticks' },
    596             hAxis: {
    597                 title: 'MJD',
    598                 gridlines: {count: -1}
    599             },
    600             vAxis: {
    601                 title: 'Offset (TP units)',
    602             },
    603             tooltip: { isHtml: true }, // Render tooltips as HTML
    604             chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right
    605             fontSize: 15,
    606         };
    607 
    608         const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_mjd'));
    609         chart.draw(data, options);
    610     }
    611 
    612 
    613     // draw pointing scatter
    614     function drawSIGChart() {
    615         var data = new google.visualization.DataTable();
    616             data.addColumn('number', 'MJD');
    617             data.addColumn('number', 'RA_offset_scatter (AST_RS)');
    618             data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
    619             data.addColumn('number', 'Dec_offset_scatter (AST_DS)');
    620             data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
    621 
    622         const rows = dataArray.map(row => {
    623             const [timestamp, ra_offset, dec_offset, mjd, filter, exp_time, comment, ra, dec, ra_offset_sig, dec_offset_sig, boresite_ang, position_ang, exp_name, alt, az, exp_id] = row;
    624 
    625             return [
    626                 parseFloat(mjd),               // MJD
    627                 parseFloat(ra_offset_sig),     // RA_offset_scatter (AST_RS)
    628                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
    629                 parseFloat(dec_offset_sig),    // Dec_offset_scatter (AST_DS)
    630                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
    631             ];
    632         });
    633 
    634         data.addRows(rows);
    635 
    636         const options = {
    637             title: 'Pointing Offset Scatter (MJD)',
    638             titleTextStyle: {color: 'black', fontSize: 15},
    639             width: '100%',
    640             height: 480,
    641             legend: { position: 'top', alignment: 'center' },
    642             series: {
    643                 0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series
    644                 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series
    645                 2: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }, // Line at y = 20
    646                 3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }  // Line at y = -20
    647             },
    648             intervals: { color: 'red', lineWidth: 2, style: 'sticks' },
    649             hAxis: {
    650                 title: 'MJD',
    651                 gridlines: {count: -1}
    652             },
    653             vAxis: {
    654                 title: 'Offset Scatter (TP units)',
    655             },
    656             tooltip: { isHtml: true }, // Render tooltips as HTML
    657             chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right
    658             fontSize: 15,
    659         };
    660 
    661         const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_sig'));
    662         chart.draw(data, options);
    663     }
    664 
    665 
    666     // position angle
    667     function drawPOSChart() {
    668         var data = new google.visualization.DataTable();
    669             data.addColumn('number', 'MJD');
    670             data.addColumn('number', 'RA_offset (AST_R0)');
    671             data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
    672             data.addColumn('number', 'Dec_offset (AST_D0)');
    673             data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
    674 
    675         const rows = dataArray.map(row => {
    676             const [timestamp, ra_offset, dec_offset, mjd, filter, exp_time, comment, ra, dec, ra_offset_sig, dec_offset_sig, boresite_ang, position_ang, exp_name, alt, az, exp_id] = row;
    677 
    678             return [
    679                 parseFloat(position_ang),      // Position Angle
    680                 parseFloat(ra_offset),         // RA_offset (AST_R0)
    681                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
    682                 parseFloat(dec_offset),        // Dec_offset (AST_D0)
    683                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
    684             ];
    685         });
    686 
    687         data.addRows(rows);
    688 
    689         const options = {
    690             title: 'Pointing Offset (Position Angle)',
    691             titleTextStyle: {color: 'black', fontSize: 15},
    692             width: '100%',
    693             height: 480,
    694             legend: { position: 'top', alignment: 'center' },
    695             // pointSize: 5, // Point size for scatter plot
    696             // lineWidth: 2,
    697             series: {
    698                 0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series
    699                 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series
    700             },
    701             intervals: { color: 'red', lineWidth: 2, style: 'sticks' },
    702             hAxis: {
    703                 title: 'Position Angle',
    704                 gridlines: {count: -1}
    705             },
    706             vAxis: {
    707                 title: 'Offset (TP units)',
    708             },
    709             tooltip: { isHtml: true }, // Render tooltips as HTML
    710             chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right
    711             fontSize: 15,
    712         };
    713 
    714         const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_pos'));
    715         chart.draw(data, options);
    716     }
    717 
    718     function drawALTChart() {
    719         var data = new google.visualization.DataTable();
    720             data.addColumn('number', 'Altitute');
    721             data.addColumn('number', 'RA_offset (AST_R0)');
    722             data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
    723             data.addColumn('number', 'Dec_offset (AST_D0)');
    724             data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
    725 
    726         const rows = dataArray.map(row => {
    727             const [timestamp, ra_offset, dec_offset, mjd, filter, exp_time, comment, ra, dec, ra_offset_sig, dec_offset_sig, boresite_ang, position_ang, exp_name, alt, az, exp_id] = row;
    728 
    729             return [
    730                 parseFloat(alt),      // Position Angle
    731                 parseFloat(ra_offset),         // RA_offset (AST_R0)
    732                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
    733                 parseFloat(dec_offset),        // Dec_offset (AST_D0)
    734                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
    735             ];
    736         });
    737 
    738         data.addRows(rows);
    739 
    740         const options = {
    741             title: 'Pointing Offset (Altitude)',
    742             titleTextStyle: {color: 'black', fontSize: 15},
    743             width: '100%',
    744             height: 480,
    745             legend: { position: 'top', alignment: 'center' },
    746             series: {
    747                 0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series
    748                 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series
    749             },
    750             intervals: { color: 'red', lineWidth: 2, style: 'sticks' },
    751             hAxis: {
    752                 title: 'Altitude',
    753                 gridlines: {count: -1}
    754             },
    755             vAxis: {
    756                 title: 'Offset (TP units)',
    757             },
    758             tooltip: { isHtml: true }, // Render tooltips as HTML
    759             //chartArea: {left: 80, top: 50, right: 20, bottom: 50},
    760             chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right
    761             fontSize: 15,
    762         };
    763 
    764         const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_alt'));
    765         chart.draw(data, options);
    766     }
    767 
    768    function drawAZChart() {
    769         var data = new google.visualization.DataTable();
    770             data.addColumn('number', 'Azumith');
    771             data.addColumn('number', 'RA_offset (AST_R0)');
    772             data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
    773             data.addColumn('number', 'Dec_offset (AST_D0)');
    774             data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
    775 
    776         const rows = dataArray.map(row => {
    777             const [timestamp, ra_offset, dec_offset, mjd, filter, exp_time, comment, ra, dec, ra_offset_sig, dec_offset_sig, boresite_ang, position_ang, exp_name, alt, az, exp_id] = row;
    778 
    779             return [
    780                 parseFloat(az),      // Position Angle
    781                 parseFloat(ra_offset),         // RA_offset (AST_R0)
    782                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
    783                 parseFloat(dec_offset),        // Dec_offset (AST_D0)
    784                 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,
    785             ];
    786         });
    787 
    788         data.addRows(rows);
    789 
    790         const options = {
    791             title: 'Pointing Offset (Azumith)',
    792             titleTextStyle: {color: 'black', fontSize: 15},
    793             width: '100%',
    794             height: 480,
    795             legend: { position: 'top', alignment: 'center' },
    796             series: {
    797                 0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series
    798                 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series
    799             },
    800             intervals: { color: 'red', lineWidth: 2, style: 'sticks' },
    801             hAxis: {
    802                 title: 'Azumith',
    803                 gridlines: {count: -1}
    804             },
    805             vAxis: {
    806                 title: 'Offset (TP units)',
    807             },
    808             tooltip: { isHtml: true }, // Render tooltips as HTML
    809             //chartArea: {left: 80, top: 50, right: 20, bottom: 50},
    810             chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right
    811             fontSize: 15,
    812         };
    813 
    814         const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_az'));
    815         chart.draw(data, options);
    816     }
    817 
    818     google.charts.setOnLoadCallback(drawMJDChart);
    819     google.charts.setOnLoadCallback(drawSIGChart);
    820     google.charts.setOnLoadCallback(drawPOSChart);
    821     google.charts.setOnLoadCallback(drawALTChart);
    822     google.charts.setOnLoadCallback(drawAZChart);
    823 </script>
    824 
    825 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
    826     <div id="dq_div_mjd" style="width:1240px;"></div>
    827     <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>
    828 </div>
    829 
    830 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
    831     <div id="dq_div_sig" style="width:1240px;"></div>
    832     <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>
    833 </div>
    834 
    835 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
    836     <div id="dq_div_pos" style="width:1240px;"></div>
    837     <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>
    838 </div>
    839 
    840 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
    841     <div id="dq_div_alt" style="width:1240px;"></div>
    842     <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>
    843 </div>
    844 
    845 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">
    846     <div id="dq_div_az" style="width:1240px;"></div>
    847     <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>
    848 </div>
    849 HTML;
    850 
    851 // End timer
    852 $total_time = round(microtime(true) - $start, 3);
    853 echo "<center>Loading plot in $total_time seconds<br></center>";
    854 
    855 }
    856520
    857521?>
Note: See TracChangeset for help on using the changeset viewer.