Changeset 42795 for trunk/ippMonitor/raw/dataquality.php
- Timestamp:
- Mar 25, 2025, 4:08:45 PM (14 months ago)
- File:
-
- 1 edited
-
trunk/ippMonitor/raw/dataquality.php (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ippMonitor/raw/dataquality.php
r42790 r42795 22 22 23 23 // Fetch data based on range selection 24 $range = isset($_GET['range']) ? $_GET['range'] : ' week';24 $range = isset($_GET['range']) ? $_GET['range'] : 'yday'; 25 25 26 26 echo "<table border=\"0\">"; … … 29 29 echo " <h1 align=\"middle\">Data Quality Report</h1>"; 30 30 echo " <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> | '; 31 echo ' <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=yday">Last night (default)</a> | '; 32 echo ' <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=day">Today (MJD '.getMJD().')</a> | '; 33 echo ' <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=week">Past 7 days</a> | '; 34 echo ' <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=month">Past 30 days</a> | '; 35 echo ' <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=year">Past 365 days</a> | '; 36 echo ' <a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=all">All </a> '; 35 37 echo " </td>"; 36 38 echo "</tr>"; 37 39 echo "</table>"; 38 echo getDataQuality 2($projectdb, $range);40 echo getDataQuality($projectdb, $range); 39 41 40 42 menu_end(); … … 51 53 # 52 54 ########################################################################### 53 function getDataQuality 2($db, $range = 'week') {55 function getDataQuality($db, $range = 'yday') { 54 56 // Start timer 55 57 $start = microtime(true); … … 61 63 62 64 // 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; 69 81 } 70 82 71 83 // 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'"; 74 85 $result = $db->query($expIdQuery); 75 86 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); 78 92 79 93 if (!empty($row['min_exp_id'])) { 80 94 $min_exp_id = $row['min_exp_id']; 81 echo "Minimum exp_id: " . $min_exp_id;95 // echo "Minimum exp_id: " . $min_exp_id; 82 96 } else { 83 97 echo "No results found."; 84 98 } 85 99 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; 105 129 } 106 130 … … 109 133 round(( 367*YEAR(dateobs)- FLOOR((7 * (YEAR(dateobs) + FLOOR((MONTH(dateobs) + 9) / 12))) / 4) + FLOOR(275 * MONTH(dateobs) / 9) 110 134 + 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 112 136 FROM rawExp 113 137 JOIN chipRun USING (exp_id) … … 126 150 return; 127 151 } 128 echo "<b>Error with $sql</b><br>\n";152 // echo "$sql<br><br>\n"; 129 153 130 154 while ($qry->fetchInto($row)) { … … 148 172 echo "<script>console.log(" . json_encode($dataJson) . ");</script>"; // Log JSON output to console for debugging 149 173 echo <<<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> 151 192 152 193 <script type="text/javascript"> … … 168 209 169 210 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; 171 212 172 213 return [ 173 214 parseFloat(mjd), // Position Angle 174 215 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, 176 217 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, 178 219 4, 179 220 12 … … 183 224 data.addRows(rows); 184 225 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 185 231 const options = { 186 title: 'FWHM (MJD )',232 title: 'FWHM (MJD: '+firstMJD+')', 187 233 titleTextStyle: {color: 'black', fontSize: 15}, 188 234 width: '100%', … … 190 236 legend: { position: 'top', alignment: 'center' }, 191 237 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. }, 194 240 2: { color: 'red', lineWidth: 2, pointSize: 0 }, 195 241 3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 } … … 208 254 }; 209 255 210 const chart = new google.visualization. LineChart(document.getElementById('dq_div_fwhm'));256 const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_fwhm')); 211 257 chart.draw(data, options); 212 258 } … … 244 290 245 291 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; 247 293 248 294 // Initialize all filter values as null … … 273 319 return [ 274 320 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, 322 parseFloat(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, 324 parseFloat(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, 326 parseFloat(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, 328 parseFloat(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, 330 parseFloat(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, 332 parseFloat(zp_w - zpt_stdev), parseFloat(zp_w - zpt_stdev*-1) 281 333 ]; 282 334 }); … … 291 343 legend: { position: 'top', alignment: 'start', maxLines: 3 }, 292 344 series: { 293 0: { color: '#00f000', pointSize: 10, pointShape: 'circle', linewidth: 1}, // 'g' filter294 1: { color: '#f00000', pointSize: 10, pointShape: 'triangle', linewidth: 1}, // 'r' filter295 2: { color: '#f05000', pointSize: 10, pointShape: 'square', linewidth: 1}, // 'i' filter296 3: { color: '#0050a0', pointSize: 10, pointShape: 'diamond', linewidth: 1}, // 'z' filter297 4: { color: '#ffe000', pointSize: 10, pointShape: 'star', linewidth: 1}, // 'y' filter298 5: { color: '#808080', pointSize: 10, pointShape: 'polygon', linewidth: 1}, // 'w' filter299 }, 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' }, 301 353 hAxis: { 302 354 title: 'MJD', … … 312 364 }; 313 365 314 const chart = new google.visualization. LineChart(document.getElementById('dq_div_zoomzpt'));366 const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_zoomzpt')); 315 367 chart.draw(data, options); 316 368 } … … 350 402 const filterCounts = { g: 0, r: 0, i: 0, z: 0, y: 0, w: 0 }; 351 403 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; 353 405 354 406 // Initialize all filter values as null … … 384 436 return [ 385 437 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, 439 parseFloat(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, 441 parseFloat(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, 443 parseFloat(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, 445 parseFloat(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, 447 parseFloat(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, 449 parseFloat(zp_w - zpt_stdev), parseFloat(zp_w - zpt_stdev*-1), 392 450 ]; 393 451 }); … … 407 465 legend: { position: 'top', alignment: 'center' }, 408 466 series: { 409 0: { color: '#00f000', pointSize: 10, pointShape: 'circle', linewidth: 1}, // 'g' filter410 1: { color: '#f00000', pointSize: 10, pointShape: 'triangle', linewidth: 1}, // 'r' filter411 2: { color: '#f05000', pointSize: 10, pointShape: 'square', linewidth: 1}, // 'i' filter412 3: { color: '#0050a0', pointSize: 10, pointShape: 'diamond', linewidth: 1}, // 'z' filter413 4: { color: '#ffe000', pointSize: 10, pointShape: 'star', linewidth: 1}, // 'y' filter414 5: { color: '#808080', pointSize: 10, pointShape: 'polygon', linewidth: 1}, // 'w' filter415 }, 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' }, 417 475 hAxis: { 418 476 title: 'MJD', … … 427 485 }; 428 486 429 const chart = new google.visualization. LineChart(document.getElementById('dq_div_zpt'));487 const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_zpt')); 430 488 chart.draw(data, options); 431 489 } … … 460 518 461 519 462 ###########################################################################463 #464 # Get data quality465 #466 ###########################################################################467 function getDataQuality($db, $range = 'week') {468 // Start timer469 $start = microtime(true);470 471 $mjdDay = getMJD();472 473 $expnames = array();474 // Determine the number of days based on the selected range475 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_id496 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 = 0501 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 empty515 if (empty($DQarray)) {516 echo "<b>Error:</b> Data array is empty.";517 return; // Stop execution if no data to encode518 }519 520 // Convert data array to JSON for easier handling in JavaScript521 $dataJson = json_encode($DQarray);522 523 if ($dataJson === false) {524 echo "<b>Error encoding JSON:</b> " . json_last_error_msg(); // Display any JSON encoding errors525 return; // Stop execution if JSON encoding fails526 }527 528 echo "<script>console.log(" . json_encode($dataJson) . ");</script>"; // Log JSON output to console for debugging529 530 echo <<<HTML531 <!-- 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 successfully536 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 fails543 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 file547 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 JavaScript555 const dataArray = JSON.parse('{$dataJson}'); // Directly parse the PHP JSON string556 557 // draw pointing vs mjd558 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), // MJD573 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 unit578 -20 // Dummy value for -20 TP unit579 ];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 series591 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series592 2: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }, // Line at y = 20593 3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 } // Line at y = -20594 },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 HTML604 chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right605 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 scatter614 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), // MJD627 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 series644 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series645 2: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }, // Line at y = 20646 3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 } // Line at y = -20647 },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 HTML657 chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right658 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 angle667 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 Angle680 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 plot696 // lineWidth: 2,697 series: {698 0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series699 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series700 },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 HTML710 chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right711 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 Angle731 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 series748 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series749 },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 HTML759 //chartArea: {left: 80, top: 50, right: 20, bottom: 50},760 chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right761 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 Angle781 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 series798 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series799 },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 HTML809 //chartArea: {left: 80, top: 50, right: 20, bottom: 50},810 chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right811 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 timer852 $total_time = round(microtime(true) - $start, 3);853 echo "<center>Loading plot in $total_time seconds<br></center>";854 855 }856 520 857 521 ?>
Note:
See TracChangeset
for help on using the changeset viewer.
