Changeset 42972
- Timestamp:
- Mar 19, 2026, 5:23:27 PM (7 weeks ago)
- Location:
- trunk/ippMonitor
- Files:
-
- 1 added
- 7 edited
-
INSTALL (modified) (1 diff)
-
czartool/czarpoll.pl (modified) (4 diffs)
-
czartool/extra_labels.dat (modified) (1 diff)
-
raw/czartool_labels.php (modified) (40 diffs)
-
raw/dataquality.php (modified) (3 diffs)
-
raw/functions.php (added)
-
raw/pointing.php (modified) (2 diffs)
-
raw/storage.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ippMonitor/INSTALL
r42834 r42972 45 45 # czartool_plots -> /export/ipp113.0/ipp/czartool_plots/ 46 46 # --usePDO selects a modern PHP/mysql interface 47 psconfigure --htdocs /var/www/localhost/htdocs --wwwbin /var/www/localhost/wwwbin --pltdir /var/www/localhost/htdocs/ippMonitor --site ~/ippconfig/ippmonitor.config --usePDO 47 #psconfigure --htdocs /var/www/localhost/htdocs --wwwbin /var/www/localhost/wwwbin --pltdir /var/www/localhost/htdocs/ippMonitor --site ~/ippconfig/ippmonitor.config --usePDO 48 # for ippm@grens1 49 psconfigure --htdocs /var/www/html --wwwbin /var/www/html/wwwbin --pltdir /var/www/html/ippMonitor --site ~/ippconfig/ippmonitor.config --usePDO 48 50 49 51 # note that modern php requires the use of PDO, the older MDB2 and DB mysql interfaces have been deprecated -
trunk/ippMonitor/czartool/czarpoll.pl
r42931 r42972 26 26 use czartool::DayMetrics; 27 27 use czartool::MetricsIndex; 28 29 # --- Logging setup --- 30 use IO::Handle; 31 my $log_file = "/tmp/czarpoll.log"; 32 open(my $LOG, '>>', $log_file) or die "Cannot open log file $log_file: $!"; 33 $LOG->autoflush(1); 34 select($LOG); # Redirect all print statements to the log file 35 open(STDERR, '>&', $LOG) or die "Cannot redirect STDERR to log file: $!"; 28 36 29 37 my $period = 60; … … 149 157 my @labels = @{$pantasks->getLabels($server,'gpc1')}; 150 158 push (@allLabels, @labels); 159 #print "[$server gpc1] labels: ", join(", ", @labels), "\n"; 151 160 152 161 my @labels2 = @{$pantasks->getLabels($server,'gpc2')}; 153 162 push (@allLabels2, @labels2); 163 #print "[$server gpc2] labels: ", join(", ", @labels2), "\n"; 154 164 } 155 165 #The way gpc2 pantasks are set up is different from gpc1. Therefore, the same label can appear in both stdscience and distribution. … … 309 319 while (1) { 310 320 321 # --- Truncate log file at start of each iteration --- 322 close($LOG); 323 open($LOG, '>', $log_file) or die "Cannot reopen log file $log_file: $!"; 324 $LOG->autoflush(1); 325 select($LOG); # Redirect STDERR (error messages) to the same log file 326 open(STDERR, '>&', $LOG) or die "Cannot redirect STDERR to log file: $!"; 327 328 print "\n======================== CZARPOLL ITERATION START ========================\n"; 329 print scalar(localtime) . "\n"; 330 print "==========================================================================\n"; 331 311 332 my $iterationStartTime = time(); 312 333 … … 447 468 448 469 print "--------------------------------------------------------------------------\n"; 470 print "Iteration complete at " . scalar(localtime) . "\n"; 471 print "==========================================================================\n"; 449 472 if ($iterationTime < $period) { 450 473 print "* Going to sleep\n"; -
trunk/ippMonitor/czartool/extra_labels.dat
r42794 r42972 2 2 ## Priorities for the labels must be added to the priorities mySQL table for the relevant telescope, if desired. 3 3 ## PV3.Pole.Reprocess.20180510 gpc1 4 ps_ud_QUB gpc14 ## ps_ud_QUB gpc1 5 5 ## update.ipp138.fix gpc1 6 6 ## update.ipp138.fix gpc2 -
trunk/ippMonitor/raw/czartool_labels.php
r42923 r42972 25 25 menu($myMenu, 'Czartool on '.$lastUpdateTime, 'ipp.css', $ID['link'], $ID['proj']); 26 26 27 $stages =array(28 "chip",29 "cam",30 "fake",31 "warp",32 "stack",33 "staticsky",34 "fullforce",35 "diff",36 "dist",37 "pub",38 );39 40 $getFailures = array(41 "chip" => "failedChipProcessedImfile.php",42 "cam" => "failedCamProcessedExp.php",43 "fake" => "failedFakeProcessedImfile.php",44 "warp" => "failedWarpSkyfiles.php",45 "stack" => "failedStackSkyfile.php",46 "staticsky" => "failedStaticsky.php",47 "fullforce" => "failedFullForceSkyfiles.php",48 "diff" => "failedDiffSkyfile.php",49 "dist" => "NONE",50 "pub" => "publishDone.php",51 ); 52 53 $mainTable = array(54 "chip" => "chipRun",55 "cam" => "camRun",56 "fake" => "fakeRun",57 "warp" => "warpRun",58 "stack" => "stackRun",59 "staticsky" => "staticskyRun",60 "fullforce" => "fullForceRun",61 "diff" => "diffRun",62 "dist" => "distRun",63 "pub" => "publishRun",64 ); 65 66 $addSearchState = array(67 "chip" => 0,68 "cam" => 0,69 "fake" => 1,70 "warp" => 0,71 "stack" => 0,72 "staticsky" => 0,73 "fullforce" => 0,74 "diff" => 0,75 "dist" => 0,76 "pub" => 0,77 ); 27 $stages = [ 28 "chip", 29 "cam", 30 "fake", 31 "warp", 32 "stack", 33 "staticsky", 34 "fullforce", 35 "diff", 36 "dist", 37 "pub", 38 ]; 39 40 $getFailures = [ 41 "chip" => "failedChipProcessedImfile.php", 42 "cam" => "failedCamProcessedExp.php", 43 "fake" => "failedFakeProcessedImfile.php", 44 "warp" => "failedWarpSkyfiles.php", 45 "stack" => "failedStackSkyfile.php", 46 "staticsky" => "failedStaticsky.php", 47 "fullforce" => "failedFullForceSkyfiles.php", 48 "diff" => "failedDiffSkyfile.php", 49 "dist" => "NONE", 50 "pub" => "publishDone.php", 51 ]; 52 53 $mainTable = [ 54 "chip" => "chipRun", 55 "cam" => "camRun", 56 "fake" => "fakeRun", 57 "warp" => "warpRun", 58 "stack" => "stackRun", 59 "staticsky" => "staticskyRun", 60 "fullforce" => "fullForceRun", 61 "diff" => "diffRun", 62 "dist" => "distRun", 63 "pub" => "publishRun", 64 ]; 65 66 $addSearchState = [ 67 "chip" => 0, 68 "cam" => 0, 69 "fake" => 1, 70 "warp" => 0, 71 "stack" => 0, 72 "staticsky" => 0, 73 "fullforce" => 0, 74 "diff" => 0, 75 "dist" => 0, 76 "pub" => 0, 77 ]; 78 78 79 79 $pass = $ID['pass']; … … 159 159 160 160 // The Update mode of czartool is obsolete. selectedMode is hardcoded to stdscience above. 161 $isUpdate = ($selectedMode == "update");161 // $isUpdate = ($selectedMode == "update"); 162 162 $isUpdate = 0; 163 163 … … 211 211 echo $table; 212 212 createTableTitle("Status and links", 2); 213 echo "<tr><td>ippMonitor Notes </td> 214 <td> PHP: v.$phpversion 215  |  <a href=\"$svnlink/browser/trunk/ippMonitor\" target=new><font color=\"blue\">SVN: v.$svnversion</font></a> 216 217  |  <a href=\"http://ippmonitor.ipp.ifa.hawaii.edu/ippMonitor/czartool_labels.php?pass=$pass&proj=$proj\"><font color=\"blue\">online (ipp113) </font></a>, 218   <a href=\"http://ipp117.ipp.ifa.hawaii.edu/ippMonitor/czartool_labels.php?pass=$pass&proj=$proj\"><font color=\"blue\">dev (ipp117) </font></a> 219 version </td></tr>"; 220 echo "<tr><td>Pan-STARRS Data Store</td> 221 <td><a href=\"https://svn.ifa.hawaii.edu/\" target=new><font color=\"blue\">Home</font></a> 222  |  <a href=\"https://svn.ifa.hawaii.edu/summit/ds/gpc1/\" target=new><font color=\"blue\">GPC1</font></a> 223  |  <a href=\"https://svn.ifa.hawaii.edu/conductorb/ds/gpc2/\" target=new><font color=\"blue\">GPC2</font></a> 224  |  <a href=\"http://ipp.ifa.hawaii.edu/skycoverage.20201110\" target=new><font color=\"blue\">Sky Coverage</font></a></td></tr>"; 225 echo "<tr><td>Observations Metrics</td> 226 <td><a href=\"https://ps1wiki.ifa.hawaii.edu/data/metrics/index.html\" target=new><font color = \"blue\"> PS1</font></a> 227  |  <a href=\"https://ps1wiki.ifa.hawaii.edu/data/ps2metrics/index.html\" target=new><font color = \"blue\"> PS2</font></a> 228  |  <a href=\"http://ippmonitor.ipp.ifa.hawaii.edu/ippMonitor/ippMetrics/index.html\" target=new><font color=\"blue\">IPP</font></a></td></tr>"; 229 echo "<tr><td>Postage Stamp Server</td> 230 <td><a href=\"http://pstamp.ipp.ifa.hawaii.edu/pshome.php\" target=new><font color=\"blue\">Home</font></a> 231  |  <a href=\"http://pstamp.ipp.ifa.hawaii.edu/status.php\" target=new><font color=\"blue\">Status</font></a> 232  |  <a href=\"http://pstamp.ipp.ifa.hawaii.edu/dsroot.php\" target=new><font color=\"blue\">Data Store</font></a></td></tr>"; 233 echo "<tr><td>IPP Cluster Ganglia Monitor</td> 234 <td><a href=\"$ganglia/?r=hour&s=descending&hc=6&c=IPP%2520Production\" target=new> <font color=\"blue\">Load_reports</font></a> 235  |  <a href=\"$ganglia/?m=cpu_report&r=hour&s=by%2520name&c=IPP+Production&h=&sh=1&hc=8&z=small\" target=new> <font color=\"blue\">CPU_reports</font></a> 236  |  <a href=\"$ganglia/?m=mem_report&r=hour&s=by%2520name&c=IPP+Production&h=&sh=1&hc=8&z=small\" target=new> <font color=\"blue\">Memory_reports</font></a> 237 </td></tr>"; 238 echo "<tr><td>Documentations for IPP</td> 239 <td><a href=\"$conflink/wiki/spaces/IPPCZAR/pages/679903282/Czarblog+Roll\" target=new><font color=\"blue\">Czarblog</font></a> 240  |  <a href=\"$conflink/wiki/spaces/IPPCZAR/pages/678634250/Czar+Guidelines\" target=new><font color=\"blue\">Czar guidelines</font></a> 241  |  <a href=\"$conflink/browse/IPP-86\" target=new><font color=\"blue\">ippMonitor Jira</font></a> 242  |  <a href=\"$conflink/wiki/spaces/IKB/pages/678298859/IPP+Hardware+Status\" target=new><font color=\"blue\">Hardware</font></a> 243  |  <a href=\"$svnlink/\" target=new><font color=\"blue\">trac</font></a> 244 </td></tr>"; 245 echo "<tr><td>Current nightly science status</td> 246 <td>".getNightlyScienceStatus($czardb, $proj)."</td></tr>"; 247 echo "<tr><td>Czardb last update time</td> 248 <td> $hsttime1 (HST), $utctime1 (UTC), $mjdday (MJD)</td></tr>"; 213 214 $html = <<<HTML 215 <tr> 216 <td>ippMonitor Notes</td> 217 <td> 218 PHP: v.$phpversion  |  219 <a href="$svnlink/browser/trunk/ippMonitor" target="_blank" style="color: blue; text-decoration: none;">SVN: v.$svnversion</a>  |  220 <a href="./czartool_labels.php?pass=$pass&proj=$proj" target="_blank" style="color: blue; text-decoration: none;">online (grens1)</a>  |  221 <a href="http://ipp117.ipp.ifa.hawaii.edu/ippMonitor/czartool_labels.php?pass=$pass&proj=$proj" target="_blank" style="color: blue; text-decoration: none;">dev (ipp117)</a> version 222 </td> 223 </tr> 224 <tr> 225 <td>Pan-STARRS Data Store</td> 226 <td> 227 <a href="https://svn.ifa.hawaii.edu/" target="_blank" style="color: blue; text-decoration: none;">Home</a>  |  228 <a href="https://svn.ifa.hawaii.edu/summit/ds/gpc1/" target="_blank" style="color: blue; text-decoration: none;">GPC1</a>  |  229 <a href="https://svn.ifa.hawaii.edu/conductorb/ds/gpc2/" target="_blank" style="color: blue; text-decoration: none;">GPC2</a>  |  230 <a href="http://ipp.ifa.hawaii.edu/skycoverage.20201110" target="_blank" style="color: blue; text-decoration: none;">Sky Coverage</a> 231 </td> 232 </tr> 233 <tr> 234 <td>Observations Metrics</td> 235 <td> 236 <a href="https://ps1wiki.ifa.hawaii.edu/data/metrics/index.html" target="_blank" style="color: blue; text-decoration: none;">PS1</a>  |  237 <a href="https://ps1wiki.ifa.hawaii.edu/data/ps2metrics/index.html" target="_blank" style="color: blue; text-decoration: none;">PS2</a>  |  238 <a href="./ippMetrics/index.html" target="_blank" style="color: blue; text-decoration: none;">IPP</a> 239 </td> 240 </tr> 241 <tr> 242 <td>Postage Stamp Server</td> 243 <td> 244 <a href="http://pstamp.ipp.ifa.hawaii.edu/pshome.php" target="_blank" style="color: blue; text-decoration: none;">Home</a>  |  245 <a href="http://pstamp.ipp.ifa.hawaii.edu/status.php" target="_blank" style="color: blue; text-decoration: none;">Status</a>  |  246 <a href="http://pstamp.ipp.ifa.hawaii.edu/dsroot.php" target="_blank" style="color: blue; text-decoration: none;">Data Store</a> 247 </td> 248 </tr> 249 <tr> 250 <td>IPP Cluster Ganglia Monitor</td> 251 <td> 252 <a href="$ganglia/?r=hour&s=descending&hc=6&c=IPP%2520Production" target="_blank" style="color: blue; text-decoration: none;">Load_reports</a>  |  253 <a href="$ganglia/?m=cpu_report&r=hour&s=by%2520name&c=IPP+Production&h=&sh=1&hc=8&z=small" target="_blank" style="color: blue; text-decoration: none;">CPU_reports</a>  |  254 <a href="$ganglia/?m=mem_report&r=hour&s=by%2520name&c=IPP+Production&h=&sh=1&hc=8&z=small" target="_blank" style="color: blue; text-decoration: none;">Memory_reports</a> 255 </td> 256 </tr> 257 <tr> 258 <td>Documentations for IPP</td> 259 <td> 260 <a href="$conflink/wiki/spaces/IPPCZAR/pages/679903282/Czarblog+Roll" target="_blank" style="color: blue; text-decoration: none;">Czarblog</a>  |  261 <a href="$conflink/wiki/spaces/IPPCZAR/pages/678634250/Czar+Guidelines" target="_blank" style="color: blue; text-decoration: none;">Czar guidelines</a>  |  262 <a href="$conflink/issues/?jql=project+%3D+%22IPP%22+AND+component+%3D+%22ippMonitor%22" target="_blank" style="color: blue; text-decoration: none;">ippMonitor Jira</a>  |  263 <a href="$conflink/wiki/spaces/IKB/pages/678298859/IPP+Hardware+Status" target="_blank" style="color: blue; text-decoration: none;">Hardware</a>  |  264 <a href="$svnlink/" target="_blank" style="color: blue; text-decoration: none;">trac</a> 265 </td> 266 </tr> 267 268 HTML; 269 echo $html; 270 echo "<tr><td>Current nightly science status</td> <td>".getNightlyScienceStatus($czardb, $proj)."</td></tr>"; 271 echo "<tr><td>Czardb last update time</td> <td>$hsttime1 (HST), $utctime1 (UTC), $mjdday (MJD)</td></tr>"; 249 272 echo "</table><br>"; 250 273 251 252 274 createLabelsTable($pass, $proj, $czardb, $selectedMode, $labels, $distLabelsExist, $pubLabelsExist, $stages, "new", $selectedLabel, $selectedStage, $plotType); 253 if ($selectedMode == "update") {echo "<br>"; createPStampDataTable();} 254 255 # XXX EAM : 2017.09.17 : debugging slowness 256 # CCL : 2019.11.09 : debugging slowness 257 createSummitDataTable2($projectdb, $pass, $proj, $debug); // this is slow because of the join between summitExp and rawExp, but not the major one 275 276 createSummitDataTable($projectdb, $pass, $proj, $debug); 258 277 259 278 createChunkDataTable($projectdb, $debug); // this is another part for slowness during nightly processing 260 279 261 // createDatesTable($czardb, $proj); what is this for? 280 // Postage stamp requests list 281 // createPStampDataTable(); 282 283 // Current dates assigned for selected pantasks servers 284 // createDatesTable($czardb, $proj); 262 285 263 286 // Database status … … 266 289 $start = microtime(true); 267 290 echo "<tr>"; 268 createTableTitle("Database status (update fix log <a href=\"http://svn.pan-starrs.ifa.hawaii.edu/trac/ipp/wiki/Replication_Issues\" ><font color=\"blue\">here</a>)", 3);291 createTableTitle("Database status (update fix log <a href=\"http://svn.pan-starrs.ifa.hawaii.edu/trac/ipp/wiki/Replication_Issues\" target=_blank><font color=\"blue\">here</a>)", 3); 269 292 270 293 echo "<tr>"; … … 324 347 showPingStatus($HOST_NAGIOS, $LABEL_NAGIOS); 325 348 showPingStatus($HOST_SVN, $LABEL_SVN); 326 showPingStatus($HOST_CONFLUENCE, $LABEL_CONFLUENCE);349 //showPingStatus($HOST_CONFLUENCE, $LABEL_CONFLUENCE); 327 350 showPingStatus($HOST_MAILMAN, $LABEL_MAILMAN); 328 351 … … 339 362 340 363 #2nd table column empty contnets 341 echo "<td style=height:200px;width: 10px;text-align:top;\"><br>";364 //echo "<td style=height:200px;width: 10px;text-align:top;\"><br>"; 342 365 343 366 #3rd table column for plots 344 367 echo "<td style=height:200px;width:600px;text-align:top;\"><br>"; 345 # plots 368 369 // processing times series plots 346 370 if ($selectedStage == "all_stages" && $selectedLabel == "all") { 347 371 // Use old method with gnuplots as the rate query is slow with all stages and labels … … 351 375 352 376 // Uncomment for dev version with Google Charts 353 //echo Gettimeseries($czardb, $selectedMode, $selectedLabel, $proj, $selectedStage);354 //echo Getrate($czardb, $selectedMode, $selectedLabel, $proj, $selectedStage);377 # echo Gettimeseries($czardb, $selectedMode, $selectedLabel, $proj, $selectedStage); 378 # echo Getrate($czardb, $selectedMode, $selectedLabel, $proj, $selectedStage); 355 379 } else { 356 380 // Use Google Charts for specific stage and label … … 359 383 } 360 384 361 // Helper function to generate image tags for plots 385 require_once 'functions.php'; 386 // data quality for current day 387 echo getDataQuality($projectdb, 'today', $proj); 388 389 // storage timeseries 390 echo getSpaces($czardb); 391 392 // storage plot 393 echo getHosts($czardb); 394 395 396 # timer for main page end 397 echo "<tr><th colspan=3>"; 398 echo "overall loading in " . round((microtime(true) - $mainstart), 3) . " seconds."; 399 echo "</th></tr>"; 400 echo "</table>"; 401 402 menu_end(); 403 404 405 ///////////////////////////////////////////////////////////////////////////// 406 // // 407 // Functions // 408 // // 409 ///////////////////////////////////////////////////////////////////////////// 410 411 ########################################################################### 412 # 413 # Display images 414 # Helper function to generate image tags for plots 415 # 416 ########################################################################### 362 417 function displayImage($type, $mode, $label, $proj, $stage, $plottype) { 363 418 $src = "czartool_getplot.php?mode=" . urlencode($mode) . … … 370 425 } 371 426 372 # data quality timeseries373 echo getDataQuality2($projectdb); // new version of data quality plots374 375 # storage timeseries376 echo getSpaces($czardb);377 # storage plot378 echo getHosts($czardb);379 380 # timer for main page end381 echo "<tr><th colspan=3>";382 echo "overall loading in " . round((microtime(true) - $mainstart), 3) . " seconds.";383 echo "</th></tr>";384 echo "</table>";385 386 menu_end();387 388 389 /////////////////////////////////////////////////////////////////////////////390 // //391 // Functions //392 // //393 /////////////////////////////////////////////////////////////////////////////394 427 395 428 ########################################################################### … … 399 432 ########################################################################### 400 433 function createPStampDataTable() { 401 402 $sql = "SELECT label, COUNT(job_id) AS 'Unfinished Jobs', IFNULL(priority,10000) AS priority FROM pstampRequest JOIN pstampJob USING(req_id) LEFT JOIN Label USING(label) WHERE pstampJob.state ='run' and pstampRequest.state ='run' GROUP by label"; 403 404 $pstampdb = DB::connect("mysql://ippuser:ippuser@ipp113/ippRequestServer"); 405 $qry = $pstampdb->query($sql); 406 if (dberror($qry)) { 434 // timer start 435 $start = microtime(true); 436 437 $dsn = "mysql:host=ipp113;dbname=ippRequestServer;charset=utf8mb4"; 438 $pdo = new PDO($dsn, 'ippuser', 'ippuser', [ 439 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 440 ]); 441 442 // SQL statement 443 $sql = " 444 SELECT label, 445 COUNT(job_id) AS `Unfinished Jobs`, 446 IFNULL(priority,10000) AS priority 447 FROM pstampRequest 448 JOIN pstampJob USING(req_id) 449 LEFT JOIN Label USING(label) 450 WHERE pstampJob.state ='run' 451 AND pstampRequest.state ='run' 452 GROUP BY label 453 "; 454 455 try { 456 // Execute the query 457 $stmt = $pdo->query($sql); 458 $rows = $stmt->fetchAll(PDO::FETCH_NUM); 459 460 } catch (PDOException $e) { 407 461 echo "<b>error reading pstamp table</b><br>\n"; 408 echo "<br><small><b> table query : $sql</b></small><br>\n";462 echo "<br><small><b> table query : " . htmlspecialchars($sql) . " </b></small><br>\n"; 409 463 menu_end(); 464 return; // stop executing the rest of the function 410 465 } 411 466 … … 414 469 echo $table; 415 470 416 #echo "<table width=\"$width\" align=\"middle\" border=\"1\" cellspacing=\"0\" cellpadding=\"4\" style=\"font-size:80%\">\n";417 471 echo "<tr>"; 418 472 createTableTitle("Postage stamp requests", 3); … … 423 477 424 478 // list the results 425 while ($qry->fetchInto($row)) {479 foreach ($rows as $row) { 426 480 echo "<tr>"; 427 echo "<td> $row[0]</td>";428 echo "<td> $row[1]</td>";429 echo "<td> $row[2]</td>";481 echo "<td>" . htmlspecialchars($row[0]) . "</td>"; 482 echo "<td>" . htmlspecialchars($row[1]) . "</td>"; 483 echo "<td>" . htmlspecialchars($row[2]) . "</td>"; 430 484 echo "</tr>"; 431 485 } 432 echo "</table>\n"; 433 } 434 486 487 // End timer 488 echo "<tr><th colspan=10>"; 489 $total_time = round(microtime(true) - $start, 3); 490 echo "<center>loading in $total_time seconds<br></center>"; 491 echo "</table><br>"; 492 } 435 493 436 494 ########################################################################### … … 448 506 $mjdDay = getMJD(); 449 507 $expname = "o{$mjdDay}%"; 450 451 508 $date = gmdate("Y-m-d"); 452 $sql = "SELECT MIN(exp_id) FROM rawExp WHERE exp_name like '$expname' "; 453 if ($debug) {echo "$sql<br>";} 454 $qry = $projectdb->query($sql); 455 456 if (dberror($qry)) { 509 510 $sql = "SELECT MIN(exp_id) FROM rawExp WHERE exp_name LIKE :expname"; 511 if ($debug) { 512 echo "$sql<br>"; 513 } 514 515 try { 516 // Prepare and execute 517 $stmt = $projectdb->prepare($sql); 518 $stmt->execute([':expname' => $expname]); 519 520 // Fetch the single row 521 $row = $stmt->fetch(PDO::FETCH_NUM); 522 523 if ($row === false || $row[0] === null) { 524 echo "*** WARNING: No data for tonight **\n"; 525 $refExpID = 0; 526 } else { 527 $refExpID = $row[0]; 528 } 529 } catch (PDOException $e) { 457 530 echo "*** WARNING: No data for tonight **\n"; 458 531 $refExpID = 0; 459 } else { 460 $qry->fetchInto($refExpID); 461 $refExpID = isset($refExpID[0]) ? $refExpID[0] : 0; 462 } 532 533 // (optional) debug 534 if ($debug) { 535 echo "DB error: " . $e->getMessage() . "<br>"; 536 } 537 } 538 463 539 // Print the result of the query 464 if ($debug) {echo "The first exp_id of tonight is: $refExpID<br>";} 465 466 #do a query of raw/chip/cam/warp counts for this night, split by chunk. 467 #we need to do a subquery to find the total number of skycells in warpSkyfile, as well as the number of those with a bad quality 468 $query = "SELECT suba.chunk,suba.Nvis1,suba.Nvis2,suba.Nvis3,suba.Nvis4,suba.Ncamgood,suba.Ncambad,subb.Nwarpgood,subb.Nwarpbad FROM "; 469 $query .= " (SELECT substr(comment, 1, position(' ' in comment)) AS chunk,count(if(rawExp.comment LIKE '%visit 1%',1,NULL)) AS Nvis1,"; 470 $query .= " count(if(rawExp.comment LIKE '%visit 2%',1,NULL)) AS Nvis2,count(if(rawExp.comment LIKE '%visit 3%',1,NULL)) AS Nvis3,"; 471 $query .= " count(if(rawExp.comment LIKE '%visit 4%',1,NULL)) AS Nvis4, count(if(camProcessedExp.sigma_ra <= 5 AND camProcessedExp.sigma_dec <= 5 AND camProcessedExp.quality = 0,1,NULL)) AS Ncamgood,"; 472 $query .= " count(if(camProcessedExp.fwhm_major > 12 OR camProcessedExp.sigma_ra > 5 OR camProcessedExp.sigma_dec > 5 OR camProcessedExp.quality > 0,1,NULL)) AS Ncambad"; 473 $query .= " FROM rawExp LEFT JOIN chipRun USING (exp_id) LEFT JOIN camRun USING (chip_id) JOIN camProcessedExp USING (cam_id) LEFT JOIN fakeRun USING (cam_id) LEFT JOIN warpRun USING (fake_id)"; 474 $query .= " WHERE exp_name like '$expname' AND exp_type = 'OBJECT' AND rawExp.comment like '%visit%'"; 475 $query .= " AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') AND obs_mode NOT LIKE 'ENGINEERING' AND obs_mode NOT LIKE 'MANUAL'"; 476 $query .= " GROUP BY chunk ORDER BY dateobs) as suba "; 477 $query .= "LEFT JOIN"; 478 $query .= " (SELECT subc.chunk, count(if(subc.Nwarpskycellbad < subc.Nwarpskycell,1,NULL)) AS Nwarpgood, count(if(subc.Nwarpskycellbad = subc.Nwarpskycell AND subc.Nwarpskycell > 0,1,NULL)) AS Nwarpbad"; 479 $query .= " FROM "; 480 $query .= " (SELECT substr(comment, 1, position(' ' in comment)) AS chunk,count(warpSkyfile.quality) AS Nwarpskycell,count(if(warpSkyfile.quality > 0,1,NULL)) AS Nwarpskycellbad"; 481 $query .= " FROM rawExp LEFT JOIN chipRun USING (exp_id) LEFT JOIN camRun USING (chip_id) LEFT JOIN fakeRun USING (cam_id) LEFT JOIN warpRun USING (fake_id) JOIN warpSkyfile USING (warp_id)"; 482 $query .= " WHERE exp_name like '$expname' AND exp_type = 'OBJECT' AND rawExp.comment like '%visit%'"; 483 $query .= " AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') AND obs_mode NOT LIKE 'ENGINEERING' AND obs_mode NOT LIKE 'MANUAL'"; 484 $query .= " GROUP BY exp_name) as subc"; 485 $query .= " GROUP BY chunk) AS subb "; 486 $query .= "ON suba.chunk=subb.chunk"; 487 488 if ($debug) {echo "$query<br>";} 489 $qry = $projectdb->query($query); 490 491 if (dberror($qry)) { 540 if ($debug) { 541 echo "The first exp_id of tonight is: $refExpID<br>"; 542 } 543 544 // Build the query (same SQL, but parameterized for $expname) 545 $query = "SELECT suba.chunk,suba.Nvis1,suba.Nvis2,suba.Nvis3,suba.Nvis4, 546 suba.Ncamgood,suba.Ncambad,subb.Nwarpgood,subb.Nwarpbad 547 FROM ( 548 SELECT substr(comment, 1, position(' ' in comment)) AS chunk, 549 count(if(rawExp.comment LIKE '%visit 1%',1,NULL)) AS Nvis1, 550 count(if(rawExp.comment LIKE '%visit 2%',1,NULL)) AS Nvis2, 551 count(if(rawExp.comment LIKE '%visit 3%',1,NULL)) AS Nvis3, 552 count(if(rawExp.comment LIKE '%visit 4%',1,NULL)) AS Nvis4, 553 count(if(camProcessedExp.sigma_ra <= 5 554 AND camProcessedExp.sigma_dec <= 5 555 AND camProcessedExp.quality = 0,1,NULL)) AS Ncamgood, 556 count(if(camProcessedExp.fwhm_major > 12 557 OR camProcessedExp.sigma_ra > 5 558 OR camProcessedExp.sigma_dec > 5 559 OR camProcessedExp.quality > 0,1,NULL)) AS Ncambad 560 FROM rawExp 561 LEFT JOIN chipRun USING (exp_id) 562 LEFT JOIN camRun USING (chip_id) 563 JOIN camProcessedExp USING (cam_id) 564 LEFT JOIN fakeRun USING (cam_id) 565 LEFT JOIN warpRun USING (fake_id) 566 WHERE exp_name LIKE :expname 567 AND exp_type = 'OBJECT' 568 AND rawExp.comment LIKE '%visit%' 569 AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') 570 AND obs_mode NOT LIKE 'ENGINEERING' 571 AND obs_mode NOT LIKE 'MANUAL' 572 GROUP BY chunk ORDER BY dateobs 573 ) as suba 574 LEFT JOIN ( 575 SELECT subc.chunk, 576 count(if(subc.Nwarpskycellbad < subc.Nwarpskycell,1,NULL)) AS Nwarpgood, 577 count(if(subc.Nwarpskycellbad = subc.Nwarpskycell 578 AND subc.Nwarpskycell > 0,1,NULL)) AS Nwarpbad 579 FROM ( 580 SELECT substr(comment, 1, position(' ' in comment)) AS chunk, 581 count(warpSkyfile.quality) AS Nwarpskycell, 582 count(if(warpSkyfile.quality > 0,1,NULL)) AS Nwarpskycellbad 583 FROM rawExp 584 LEFT JOIN chipRun USING (exp_id) 585 LEFT JOIN camRun USING (chip_id) 586 LEFT JOIN fakeRun USING (cam_id) 587 LEFT JOIN warpRun USING (fake_id) 588 JOIN warpSkyfile USING (warp_id) 589 WHERE exp_name LIKE :expname 590 AND exp_type = 'OBJECT' 591 AND rawExp.comment LIKE '%visit%' 592 AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') 593 AND obs_mode NOT LIKE 'ENGINEERING' 594 AND obs_mode NOT LIKE 'MANUAL' 595 GROUP BY exp_name 596 ) as subc 597 GROUP BY chunk 598 ) AS subb 599 ON suba.chunk=subb.chunk"; 600 601 if ($debug) { echo "$query<br>"; } 602 603 try { 604 $stmt = $projectdb->prepare($query); 605 $stmt->execute([':expname' => $expname]); 606 } catch (PDOException $e) { 492 607 echo "<b>error querying SQL table</b><br>\n"; 493 608 echo "<br><small><b> table query : $query </b></small><br>\n"; 494 609 menu_end(); 495 } 496 610 exit; 611 } 612 497 613 // set up the table 498 614 global $table; … … 512 628 createTableColumnHeader("wsd_pub"); 513 629 createTableColumnHeader("Completion"); 514 630 515 631 $msg = "No science images taken since $date"; 516 632 633 $badcamflag = 0; 634 $badwarpflag = 0; 635 $baddiffflag = 0; 517 636 // list the results 518 while ($qry->fetchInto($row)) { 519 $Nvis1 = 0; 520 $Nvis2 = 0; 521 $Nvis3 = 0; 522 $Nvis4 = 0; 523 $Ncamgood = 0; 524 $Ncambad = 0; 525 $Nwarpgood = 0; 526 $Nwarpbad = 0; 637 while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { 638 $chunkname = $row['chunk'] ?? ''; 639 $Nvis1 = $row['Nvis1'] ?? 0; 640 $Nvis2 = $row['Nvis2'] ?? 0; 641 $Nvis3 = $row['Nvis3'] ?? 0; 642 $Nvis4 = $row['Nvis4'] ?? 0; 643 $Ncamgood = $row['Ncamgood'] ?? 0; 644 $Ncambad = $row['Ncambad'] ?? 0; 645 $Nwarpgood = $row['Nwarpgood'] ?? 0; 646 $Nwarpbad = $row['Nwarpbad'] ?? 0; 647 648 if($Ncambad >= 1) $badcamflag = 1; 649 if($Nwarpbad >= 1) $badwarpflag = 1; 650 651 $query1 = "SELECT suba.chunk, 652 SUM(IF(suba.Nvisits = 2,1,NULL)) as totvis2, 653 SUM(IF(suba.Nvisits = 3 OR suba.Nvisits = 4,2,NULL)) as totvis34 654 FROM ( 655 SELECT substr(comment, 1, position(' ' in comment)) AS chunk, 656 count(distinct(comment)) AS Nvisits 657 FROM rawExp 658 LEFT JOIN chipRun USING (exp_id) 659 LEFT JOIN camRun USING (chip_id) 660 WHERE exp_name LIKE :expname 661 AND exp_type = 'OBJECT' 662 AND rawExp.comment LIKE '%visit%' 663 AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') 664 AND obs_mode NOT LIKE 'ENGINEERING' 665 AND obs_mode NOT LIKE 'MANUAL' 666 AND substr(comment,1,position(' ' in comment)) LIKE :chunkname 667 GROUP BY object 668 ) as suba 669 GROUP BY chunk"; 670 671 $stmt1 = $projectdb->prepare($query1); 672 $stmt1->execute([':expname'=>$expname, ':chunkname'=>"$chunkname%"]); 673 $row1 = $stmt1->fetch(PDO::FETCH_ASSOC); 527 674 $NexpWWdiff = 0; 528 $Npubwarps = 0; 529 530 $chunkname = $row[0]; 531 if($row[1] > 0) $Nvis1 = $row[1]; 532 if($row[2] > 0) $Nvis2 = $row[2]; 533 if($row[3] > 0) $Nvis3 = $row[3]; 534 if($row[4] > 0) $Nvis4 = $row[4]; 535 if($row[5] > 0) $Ncamgood = $row[5]; 536 if($row[6] > 0) $Ncambad = $row[6]; 537 if($row[7] > 0) $Nwarpgood = $row[7]; 538 if($row[8] > 0) $Nwarpbad = $row[8]; 539 540 #set flags if present 541 if($Ncambad >= 1) $badcamflag = 1; 542 if($Nwarpbad >= 1) $badwarpflag = 1; 543 544 $query1 = "SELECT suba.chunk, SUM(IF(suba.Nvisits = 2,1,NULL)) as totvis2, SUM(IF(suba.Nvisits = 3 OR suba.Nvisits = 4,2,NULL)) as totvis34 FROM"; 545 $query1 .= " (SELECT substr(comment, 1, position(' ' in comment)) AS chunk,count(distinct(comment)) AS Nvisits FROM"; 546 $query1 .= " rawExp LEFT JOIN chipRun USING (exp_id) LEFT JOIN camRun USING (chip_id) "; 547 $query1 .= " WHERE exp_name like '$expname'"; 548 $query1 .= " AND exp_type = 'OBJECT' AND rawExp.comment like '%visit%' AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') AND obs_mode NOT LIKE 'ENGINEERING' AND obs_mode NOT LIKE 'MANUAL'"; 549 $query1 .= " AND substr(comment, 1, position(' ' in comment)) LIKE '$chunkname%' group by object) as suba group by chunk;"; 550 551 $qry1 = $projectdb->query($query1); 552 while ($qry1->fetchInto($row)) {$NexpWWdiff = $row[1] + $row[2];} 553 554 #find the unique diff_ids for each chunk, to be matched to the diffRun catalog 555 $query2 = " SELECT diff_id,warp1,stack1,warp2,stack2 FROM "; 556 $query2 .= " diffInputSkyfile JOIN warpRun ON (warp1=warp_id OR warp2=warp_id) JOIN fakeRun USING (fake_id) JOIN camRun USING (cam_id) JOIN camProcessedExp USING (cam_id) JOIN chipRun USING (chip_id) JOIN rawExp USING (exp_id)"; 557 $query2 .= " WHERE exp_name like '$expname'"; 558 $query2 .= " AND exp_type = 'OBJECT' AND rawExp.comment like '%visit%' AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%')"; 559 $query2 .= " AND obs_mode NOT LIKE 'ENGINEERING' AND obs_mode NOT LIKE 'MANUAL' AND substr(comment, 1, position(' ' in comment)) LIKE '$chunkname%' GROUP By diff_id"; 560 $qry2 = $projectdb->query($query2); 561 562 $NWWdiffgood = 0; 563 $NWWdiffbad = 0; 564 $NWWdiffpub = 0; 565 566 $NWSdiffgood = 0; 567 $NWSdiffbad = 0; 568 $NWSdiffpub = 0; 569 $wrpcnt = array(); 570 571 while ($qry2->fetchInto($row2)) { 572 #distinguish between WW and WS diffs based on stack2 573 if ($row2[4] == 0) { 574 #find the total number of skycell and the number of skycell with a bad quality flag as well as the full publish state 575 $query3 = " SELECT count(diffSkyfile.quality) AS Ndiff,count(if(diffSkyfile.quality > 0,1,NULL)) AS Ndiffbad,count(if(publishRun.state LIKE 'full',1,NULL)) AS Npub FROM "; 576 $query3 .= " diffRun JOIN diffSkyfile USING (diff_id) LEFT JOIN publishRun ON (diffRun.diff_id = stage_id)"; 577 $query3 .= " WHERE diff_id='$row2[0]' GROUP BY diffRun.diff_id"; 578 $qry3 = $projectdb->query($query3); 579 580 while ($qry3->fetchInto($row3)) { 581 #if all skycells have bad quality, this is a bad diff. If all the skycells are in a full state in publishRun, it is fully published 582 if ($row3[1]<$row3[0]) $NWWdiffgood ++; 583 if ($row3[1]==$row3[0]) $NWWdiffbad ++; 584 if ($row3[2]==$row3[0]) $NWWdiffpub ++; 585 586 #if this wwdiff is published, record its corresponding warp_ids to see how many unique ones there are 587 if ($row3[2]==$row3[0]) $wrpcnt{$row2[1]}++; # record the presence of warp1 588 if ($row3[2]==$row3[0]) $wrpcnt{$row2[3]}++; # record the presence of warp2 589 } 590 } 591 592 if ($row2[4] > 0) { 593 #find the total number of skycell and the number of skycell with a bad quality flag as well as the full publish state 594 $query3 = " SELECT count(diffSkyfile.quality) AS Ndiff,count(if(diffSkyfile.quality > 0,1,NULL)) AS Ndiffbad,count(if(publishRun.state LIKE 'full',1,NULL)) AS Npub FROM "; 595 $query3 .= " diffRun JOIN diffSkyfile USING (diff_id) LEFT JOIN publishRun ON (diffRun.diff_id = stage_id)"; 596 $query3 .= " WHERE diff_id='$row2[0]' GROUP BY diffRun.diff_id"; 597 $qry3 = $projectdb->query($query3); 598 599 while ($qry3->fetchInto($row3)) { 600 #if all skycells have bad quality, this is a bad diff. If all the skycells are in a full state in publishRun, it is fully published 601 if ($row3[1]<$row3[0]) $NWSdiffgood ++; 602 if ($row3[1]==$row3[0]) $NWSdiffbad ++; 603 if ($row3[2]==$row3[0]) $NWSdiffpub ++; 604 } 605 } 675 if ($row1) { 676 $NexpWWdiff = ($row1['totvis2'] ?? 0) + ($row1['totvis34'] ?? 0); 606 677 } 607 #pull out the unique warp_ids 678 679 $query2 = "SELECT diff_id,warp1,stack1,warp2,stack2 680 FROM diffInputSkyfile 681 JOIN warpRun ON (warp1=warp_id OR warp2=warp_id) 682 JOIN fakeRun USING (fake_id) 683 JOIN camRun USING (cam_id) 684 JOIN camProcessedExp USING (cam_id) 685 JOIN chipRun USING (chip_id) 686 JOIN rawExp USING (exp_id) 687 WHERE exp_name LIKE :expname 688 AND exp_type = 'OBJECT' 689 AND rawExp.comment LIKE '%visit%' 690 AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') 691 AND obs_mode NOT LIKE 'ENGINEERING' 692 AND obs_mode NOT LIKE 'MANUAL' 693 AND substr(comment,1,position(' ' in comment)) LIKE :chunkname 694 GROUP BY diff_id"; 695 696 $stmt2 = $projectdb->prepare($query2); 697 $stmt2->execute([':expname'=>$expname, ':chunkname'=>"$chunkname%"]); 698 699 $NWWdiffgood = $NWWdiffbad = $NWWdiffpub = 0; 700 $NWSdiffgood = $NWSdiffbad = $NWSdiffpub = 0; 701 $wrpcnt = []; 702 703 while ($row2 = $stmt2->fetch(PDO::FETCH_ASSOC)) { 704 $diff_id = $row2['diff_id']; 705 $warp1 = $row2['warp1']; 706 $warp2 = $row2['warp2']; 707 $stack2 = $row2['stack2']; 708 709 // Build $query3 (same for WW and WS) 710 $query3 = "SELECT count(diffSkyfile.quality) AS Ndiff, 711 count(if(diffSkyfile.quality > 0,1,NULL)) AS Ndiffbad, 712 count(if(publishRun.state LIKE 'full',1,NULL)) AS Npub 713 FROM diffRun 714 JOIN diffSkyfile USING (diff_id) 715 LEFT JOIN publishRun ON (diffRun.diff_id = stage_id) 716 WHERE diff_id=:diffid 717 GROUP BY diffRun.diff_id"; 718 719 $stmt3 = $projectdb->prepare($query3); 720 $stmt3->execute([':diffid'=>$diff_id]); 721 $row3 = $stmt3->fetch(PDO::FETCH_ASSOC); 722 if (!$row3) continue; 723 724 $Ndiff = $row3['Ndiff'] ?? 0; 725 $Ndiffbad = $row3['Ndiffbad'] ?? 0; 726 $Npub = $row3['Npub'] ?? 0; 727 728 if ($stack2 == 0) { 729 if ($Ndiffbad < $Ndiff) $NWWdiffgood++; 730 if ($Ndiffbad == $Ndiff) $NWWdiffbad++; 731 if ($Npub == $Ndiff) $NWWdiffpub++; 732 if ($Npub == $Ndiff) { 733 $wrpcnt[$warp1] = ($wrpcnt[$warp1] ?? 0) + 1; 734 $wrpcnt[$warp2] = ($wrpcnt[$warp2] ?? 0) + 1; 735 } 736 } else { 737 if ($Ndiffbad < $Ndiff) $NWSdiffgood++; 738 if ($Ndiffbad == $Ndiff) $NWSdiffbad++; 739 if ($Npub == $Ndiff) $NWSdiffpub++; 740 } 741 } 742 743 // Pull out the unique warp_ids 608 744 $Npubwarps = count($wrpcnt); 609 610 #check for bad diffs 611 if(($NWWdiffbad >= 1) or ($NWSdiffbad >= 1)) $baddiffflag = 1; 612 745 746 // Check for bad diffs 747 if (($NWWdiffbad >= 1) || ($NWSdiffbad >= 1)) { 748 $baddiffflag = 1; 749 } 750 751 // Decide on completion text 613 752 if ($Nvis1 != $Nvis4) { 614 if ($NWWdiffpub != $NexpWWdiff) $complete = "chunk incomplete, not done"; 615 if ($NWWdiffpub == $NexpWWdiff) $complete = "chunk incomplete, done"; 753 $complete = ($NWWdiffpub == $NexpWWdiff) 754 ? "chunk incomplete, done" 755 : "chunk incomplete, not done"; 756 } else { 757 $complete = ($NWWdiffpub == $NexpWWdiff) 758 ? "chunk complete, done" 759 : "chunk complete, not done"; 616 760 } 617 if ($Nvis1 == $Nvis4) { 618 if ($NWWdiffpub != $NexpWWdiff) $complete = "chunk complete, not done"; 619 if ($NWWdiffpub == $NexpWWdiff) $complete = "chunk complete, done"; 620 621 } 622 761 762 // Now output the row 623 763 echo "<tr>"; 624 625 echo "<td>$chunkname</td>"; 764 echo "<td>" . htmlspecialchars($chunkname) . "</td>"; 626 765 echo "<td>$Nvis1/$Nvis2/$Nvis3/$Nvis4</td>"; 627 766 echo "<td>$Ncamgood/$Ncambad</td>"; … … 633 772 echo "<td>$NWSdiffpub</td>"; 634 773 echo "<td>$complete</td>"; 635 636 774 echo "</tr>"; 637 775 } 638 639 776 640 777 #----------------------------------------- 641 # list bad quality cam exposures778 # list bad quality cam exposures 642 779 if ($badcamflag != 0) { 643 780 644 781 // set up another table 645 782 global $table; … … 654 791 createTableColumnHeader("sigma_dec"); 655 792 createTableColumnHeader("comment"); 656 657 #query the bad cam exposures 658 $query = "SELECT exp_name,cam_id, camProcessedExp.quality, camProcessedExp.sigma_ra, camProcessedExp.sigma_dec, comment"; 659 $query .= " FROM rawExp"; 660 $query .= " JOIN chipRun USING (exp_id)"; 661 $query .= " JOIN camRun USING (chip_id)"; 662 $query .= " JOIN camProcessedExp USING (cam_id)"; 663 //$query .= " WHERE dateobs LIKE '$date%' AND exp_id > $refExpID"; 664 $query .= " WHERE exp_name like '$expname'"; 665 $query .= " AND exp_type = 'OBJECT'"; 666 $query .= " AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') AND obs_mode NOT LIKE 'ENGINEERING' AND obs_mode NOT LIKE 'MANUAL'"; 667 $query .= " AND (camProcessedExp.fwhm_major > 12 OR camProcessedExp.quality > 0 OR camProcessedExp.sigma_ra > 5 OR camProcessedExp.sigma_dec > 5)"; 668 $query .= " ORDER BY comment"; 669 670 $qry1 = $projectdb->query($query); 671 while ($qry1->fetchInto($row)) { 672 793 794 // query the bad cam exposures 795 $query = " 796 SELECT exp_name, 797 cam_id, 798 camProcessedExp.quality, 799 camProcessedExp.sigma_ra, 800 camProcessedExp.sigma_dec, 801 comment 802 FROM rawExp 803 JOIN chipRun USING (exp_id) 804 JOIN camRun USING (chip_id) 805 JOIN camProcessedExp USING (cam_id) 806 WHERE exp_name LIKE :expname 807 AND exp_type = 'OBJECT' 808 AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') 809 AND obs_mode NOT LIKE 'ENGINEERING' 810 AND obs_mode NOT LIKE 'MANUAL' 811 AND ( 812 camProcessedExp.fwhm_major > 12 OR 813 camProcessedExp.quality > 0 OR 814 camProcessedExp.sigma_ra > 5 OR 815 camProcessedExp.sigma_dec > 5 816 ) 817 ORDER BY comment"; 818 819 if ($debug) { echo "$query<br>"; } 820 // prepare & execute 821 $stmt = $projectdb->prepare($query); 822 $stmt->execute([':expname' => $expname]); 823 824 // output rows 825 while ($row = $stmt->fetch(PDO::FETCH_NUM)) { 673 826 echo "<tr>"; 674 675 echo "<td>$row[0]</td>"; 676 echo "<td>$row[1]</td>"; 677 echo "<td>$row[2]</td>"; 678 echo "<td>$row[3]</td>"; 679 echo "<td>$row[4]</td>"; 680 echo "<td>$row[5]</td>"; 681 827 echo "<td>" . htmlspecialchars($row[0]) . "</td>"; // exp_name 828 echo "<td>" . htmlspecialchars($row[1]) . "</td>"; // cam_id 829 echo "<td>" . htmlspecialchars($row[2]) . "</td>"; // quality 830 echo "<td>" . htmlspecialchars($row[3]) . "</td>"; // sigma_ra 831 echo "<td>" . htmlspecialchars($row[4]) . "</td>"; // sigma_dec 832 echo "<td>" . htmlspecialchars($row[5]) . "</td>"; // comment 682 833 echo "</tr>"; 683 834 } … … 685 836 686 837 #----------------------------------------- 687 # list bad quality warp exposures838 # list bad quality warp exposures 688 839 if ($badwarpflag != 0) { 689 840 690 841 // set up another table 691 842 global $table; … … 697 848 createTableColumnHeader("warp_id"); 698 849 createTableColumnHeader("comment"); 699 700 #query the bad warps 701 $query = "SELECT exp_name,warp_id,count(warpSkyfile.quality) AS Nwarpskycell,count(if(warpSkyfile.quality > 0,1,NULL)) AS Nwarpskycellbad, comment"; 702 $query .= " FROM rawExp LEFT JOIN chipRun USING (exp_id) LEFT JOIN camRun USING (chip_id) LEFT JOIN fakeRun USING (cam_id) LEFT JOIN warpRun USING (fake_id) JOIN warpSkyfile USING (warp_id)"; 703 $query .= " WHERE exp_name like '$expname'"; 704 $query .= " AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') AND obs_mode NOT LIKE 'ENGINEERING' AND obs_mode NOT LIKE 'MANUAL'"; 705 $query .= " GROUP BY exp_name ORDER BY comment"; 706 707 $qry1 = $projectdb->query($query); 708 while ($qry1->fetchInto($row)) { 709 850 851 // query the bad warps 852 $query = " 853 SELECT exp_name, 854 warp_id, 855 COUNT(warpSkyfile.quality) AS Nwarpskycell, 856 COUNT(IF(warpSkyfile.quality > 0,1,NULL)) AS Nwarpskycellbad, 857 comment 858 FROM rawExp 859 LEFT JOIN chipRun USING (exp_id) 860 LEFT JOIN camRun USING (chip_id) 861 LEFT JOIN fakeRun USING (cam_id) 862 LEFT JOIN warpRun USING (fake_id) 863 JOIN warpSkyfile USING (warp_id) 864 WHERE exp_name LIKE :expname 865 AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') 866 AND obs_mode NOT LIKE 'ENGINEERING' 867 AND obs_mode NOT LIKE 'MANUAL' 868 GROUP BY exp_name 869 ORDER BY comment"; 870 871 // prepare and execute 872 $stmt = $projectdb->prepare($query); 873 $stmt->execute([':expname' => $expname]); 874 875 // loop through rows 876 while ($row = $stmt->fetch(PDO::FETCH_NUM)) { 710 877 echo "<tr>"; 711 712 echo "<td>$row[0]</td>"; 713 echo "<td>$row[1]</td>"; 714 echo "<td>$row[2]</td>"; 715 878 echo "<td>" . htmlspecialchars($row[0]) . "</td>"; // exp_name 879 echo "<td>" . htmlspecialchars($row[1]) . "</td>"; // warp_id 880 echo "<td>" . htmlspecialchars($row[4]) . "</td>"; // comment 716 881 echo "</tr>"; 717 882 } 718 883 } 719 884 720 #-----------------------------------------721 #list bad quality diff exposures722 885 if ($baddiffflag != 0) { 723 886 // set up another table … … 734 897 createTableColumnHeader("stack2"); 735 898 createTableColumnHeader("comment"); 736 737 #query the bad diffs738 $query = " SELECT diff_id,warp1,stack1,warp2,stack2,exp_name,comment FROM ";739 $query .= " diffInputSkyfile JOIN warpRun ON (warp1=warp_id OR warp2=warp_id) JOIN fakeRun USING (fake_id) JOIN camRun USING (cam_id) JOIN camProcessedExp USING (cam_id) JOIN chipRun USING (chip_id) JOIN rawExp USING (exp_id)";740 $query .= " WHERE exp_name like '$expname'";741 $query .= " AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') AND obs_mode NOT LIKE 'ENGINEERING' AND obs_mode NOT LIKE 'MANUAL'";742 $query .= " GROUP By diff_id";743 if ($debug) {echo "$query<br>";}744 745 $qry1 = $projectdb->query($query);746 while ($qry1->fetchInto($row)) {747 #distinguish between WW and WS diffs based on stack2748 if ($row[4] == 0) {749 #find the total number of skycell and the number of skycell with a bad quality flag as well as the full publish state750 $query3 = " SELECT count(diffSkyfile.quality) AS Ndiff,count(if(diffSkyfile.quality > 0,1,NULL)) AS Ndiffbad,count(if(publishRun.state LIKE 'full',1,NULL)) AS Npub FROM ";751 $query3 .= " diffRun JOIN diffSkyfile USING (diff_id) LEFT JOIN publishRun ON (diffRun.diff_id = stage_id)";752 $query3 .= " WHERE diff_id='$row[0]' GROUP BY diffRun.diff_id";753 $qry3 = $projectdb->query($query3);754 755 while ($qry3->fetchInto($row3)) {756 #if all skycells have bad quality, this is a bad diff. If all the skycells are in a full state in publishRun, it is fully published757 if ($row3[1]==$row3[0]) {758 echo "<tr>";759 760 echo "<td>$row[5]</td>";761 echo "<td>$row[0]</td>";762 echo "<td>$row[1]</td>";763 echo "<td>$row[2]</td>";764 echo "<td>$row[3]</td>";765 echo "<td>$row[4]</td>";766 echo "<td>$row[6]</td>";767 768 echo "</tr>";769 }770 }771 }772 773 if ($row[4] > 0) {774 #find the total number of skycell and the number of skycell with a bad quality flag as well as the full publish state 775 $query3 = " SELECT count(diffSkyfile.quality) AS Ndiff,count(if(diffSkyfile.quality > 0,1,NULL)) AS Ndiffbad,count(if(publishRun.state LIKE 'full',1,NULL)) AS Npub FROM ";776 $query3 .= " diffRun JOIN diffSkyfile USING (diff_id) LEFT JOIN publishRun ON (diffRun.diff_id = stage_id)";777 $query3 .= " WHERE diff_id='$row[0]' GROUP BY diffRun.diff_id";778 $qry3 = $projectdb->query($query3);779 780 while ($qry3->fetchInto($row3)) {781 #if all skycells have bad quality, this is a bad diff. If all the skycells are in a full state in publishRun, it is fully published782 if ($row3[1]==$row3[0]) {783 echo "<tr>";784 785 echo "<td>$row[5]</td>";786 echo "<td>$row[0]</td>";787 echo "<td>$row[1]</td>";788 echo "<td>$row[2]</td>";789 echo "<td>$row[3]</td>";790 echo "<td>$row[4]</td>";791 echo "<td>$row[6]</td>";792 793 echo "</tr>";794 }795 }899 900 // main query with a placeholder for exp_name 901 $query = " 902 SELECT diff_id, warp1, stack1, warp2, stack2, exp_name, comment 903 FROM diffInputSkyfile 904 JOIN warpRun ON (warp1=warp_id OR warp2=warp_id) 905 JOIN fakeRun USING (fake_id) 906 JOIN camRun USING (cam_id) 907 JOIN camProcessedExp USING (cam_id) 908 JOIN chipRun USING (chip_id) 909 JOIN rawExp USING (exp_id) 910 WHERE exp_name LIKE :expname 911 AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') 912 AND obs_mode NOT LIKE 'ENGINEERING' 913 AND obs_mode NOT LIKE 'MANUAL' 914 GROUP BY diff_id 915 "; 916 917 if ($debug) { echo "$query<br>"; } 918 919 // prepare & execute main query 920 $stmt = $projectdb->prepare($query); 921 $stmt->execute([':expname' => $expname]); 922 923 // prepare secondary query once, reuse it 924 $query3 = " 925 SELECT 926 COUNT(diffSkyfile.quality) AS Ndiff, 927 COUNT(IF(diffSkyfile.quality > 0,1,NULL)) AS Ndiffbad, 928 COUNT(IF(publishRun.state LIKE 'full',1,NULL)) AS Npub 929 FROM diffRun 930 JOIN diffSkyfile USING (diff_id) 931 LEFT JOIN publishRun ON (diffRun.diff_id = stage_id) 932 WHERE diff_id = :diffid 933 GROUP BY diffRun.diff_id 934 "; 935 936 if ($debug) { echo "$query3<br>"; } 937 938 $stmt3 = $projectdb->prepare($query3); 939 940 // iterate through main query results 941 while ($row = $stmt->fetch(PDO::FETCH_NUM)) { 942 943 // run the nested query regardless of warp2==0 or >0 944 $stmt3->execute([':diffid' => $row[0]]); 945 946 while ($row3 = $stmt3->fetch(PDO::FETCH_NUM)) { 947 // if all skycells have bad quality 948 if ($row3[1] == $row3[0]) { 949 echo "<tr>"; 950 echo "<td>" . htmlspecialchars($row[5]) . "</td>"; // exp_name 951 echo "<td>" . htmlspecialchars($row[0]) . "</td>"; // diff_id 952 echo "<td>" . htmlspecialchars($row[1]) . "</td>"; // warp1 953 echo "<td>" . htmlspecialchars($row[2]) . "</td>"; // stack1 954 echo "<td>" . htmlspecialchars($row[3]) . "</td>"; // warp2 955 echo "<td>" . htmlspecialchars($row[4]) . "</td>"; // stack2 956 echo "<td>" . htmlspecialchars($row[6]) . "</td>"; // comment 957 echo "</tr>"; 958 } 796 959 } 797 960 } … … 800 963 #----------------------------------------- 801 964 #check for overridden exposures 802 $query = "SELECT COUNT(comment), comment"; 803 $query .= " FROM rawExp"; 804 $query .= " JOIN chipRun USING (exp_id)"; 805 $query .= " JOIN camRun USING (chip_id)"; 806 $query .= " WHERE exp_name like '$expname'"; 807 $query .= " AND exp_type = 'OBJECT'"; 808 $query .= " AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') AND obs_mode NOT LIKE 'ENGINEERING' AND obs_mode NOT LIKE 'MANUAL'"; 809 $query .= " GROUP BY comment"; 810 811 $qry1 = $projectdb->query($query); 812 $doHeader = 1; 813 814 while ($qry1->fetchInto($row)) { 965 // first query: count per comment 966 $query1 = " 967 SELECT COUNT(comment) AS cnt, comment 968 FROM rawExp 969 JOIN chipRun USING (exp_id) 970 JOIN camRun USING (chip_id) 971 WHERE exp_name LIKE :expname 972 AND exp_type = 'OBJECT' 973 AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') 974 AND obs_mode NOT LIKE 'ENGINEERING' 975 AND obs_mode NOT LIKE 'MANUAL' 976 GROUP BY comment 977 "; 978 $stmt1 = $projectdb->prepare($query1); 979 $stmt1->execute([':expname' => $expname]); 980 981 if ($debug) { echo "$query1<br>"; } 982 983 $doHeader = 1; 984 985 // loop over comments with duplicates 986 while ($row = $stmt1->fetch(PDO::FETCH_NUM)) { 815 987 if ($row[0] > 1) { 816 $query = "SELECT exp_name,dateobs, comment"; 817 $query .= " FROM rawExp"; 818 $query .= " JOIN chipRun USING (exp_id)"; 819 $query .= " JOIN camRun USING (chip_id)"; 820 $query .= " WHERE exp_name like '$expname'"; 821 $query .= " AND comment LIKE '$row[1]'"; 822 $query .= " AND exp_type = 'OBJECT'"; 823 $query .= " AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') AND obs_mode NOT LIKE 'ENGINEERING' AND obs_mode NOT LIKE 'MANUAL'"; 824 $query .= " ORDER BY dateobs DESC"; 825 $qry2 = $projectdb->query($query); 988 // second query: get exposures with this comment 989 $query2 = " 990 SELECT exp_name, dateobs, comment 991 FROM rawExp 992 JOIN chipRun USING (exp_id) 993 JOIN camRun USING (chip_id) 994 WHERE exp_name LIKE :expname 995 AND comment LIKE :comment 996 AND exp_type = 'OBJECT' 997 AND (obs_mode LIKE '%SS%' OR obs_mode LIKE '%BRIGHT%') 998 AND obs_mode NOT LIKE 'ENGINEERING' 999 AND obs_mode NOT LIKE 'MANUAL' 1000 ORDER BY dateobs DESC 1001 "; 1002 $stmt2 = $projectdb->prepare($query2); 1003 $stmt2->execute([ 1004 ':expname' => $expname, 1005 ':comment' => $row[1] 1006 ]); 1007 1008 if ($debug) { echo "$query2<br>"; } 826 1009 827 1010 $doskip = 0; 828 while ($ qry2->fetchInto($row2)) {829 if ($doskip) {1011 while ($row2 = $stmt2->fetch(PDO::FETCH_NUM)) { 1012 if ($doskip) { 830 1013 if ($doHeader) { 831 // set up another table832 global $table;833 echo $table;834 echo "<tr>";835 createTableTitle("Overridden exposures", 3);836 echo "<tr>";837 createTableColumnHeader("exp_name");838 createTableColumnHeader("dateobs");839 createTableColumnHeader("comment");840 $doHeader = 0;1014 // set up another table 1015 global $table; 1016 echo $table; 1017 echo "<tr>"; 1018 createTableTitle("Overridden exposures", 3); 1019 echo "<tr>"; 1020 createTableColumnHeader("exp_name"); 1021 createTableColumnHeader("dateobs"); 1022 createTableColumnHeader("comment"); 1023 $doHeader = 0; 841 1024 } 1025 842 1026 echo "<tr>"; 843 844 echo "<td>$row2[0]</td>"; 845 echo "<td>$row2[1]</td>"; 846 echo "<td>$row2[2]</td>"; 847 1027 echo "<td>" . htmlspecialchars($row2[0]) . "</td>"; 1028 echo "<td>" . htmlspecialchars($row2[1]) . "</td>"; 1029 echo "<td>" . htmlspecialchars($row2[2]) . "</td>"; 848 1030 echo "</tr>"; 849 1031 } 850 $doskip = 1; 1032 $doskip = 1; // skip the first row of each comment group 851 1033 } 852 1034 } 853 1035 } 1036 854 1037 if (!$doHeader) { print "\n"; } 855 856 1038 857 1039 // End timer … … 870 1052 # 871 1053 ########################################################################### 872 function getLabels($db, $proj, $server) { 873 874 # order by descending priority as set in project database 875 $sql = "SELECT label FROM science_labels WHERE server LIKE '$server' AND telescope LIKE '$proj' ORDER BY priority DESC, label"; 876 if ($debug) {echo "$sql<br>";} 877 878 $qry = $db->query($sql); 879 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";} 880 while ($qry->fetchInto($row)) { 881 882 $labels[] = $row[0]; 883 } 884 885 return $labels; 1054 function getLabels(PDO $db, string $proj, string $server, bool $useLike = false, bool $debug = false): array { 1055 // Use equality unless $useLike is true (then add wildcards) 1056 if ($useLike) { 1057 $sql = "SELECT label FROM science_labels 1058 WHERE server LIKE :server AND telescope LIKE :proj 1059 ORDER BY priority DESC, label"; 1060 // add wildcards only if caller didn't already include them 1061 $serverParam = (strpos($server, '%') === false && strpos($server, '_') === false) ? "%{$server}%" : $server; 1062 $projParam = (strpos($proj, '%') === false && strpos($proj, '_') === false) ? "%{$proj}%" : $proj; 1063 } else { 1064 $sql = "SELECT label FROM science_labels 1065 WHERE server = :server AND telescope = :proj 1066 ORDER BY priority DESC, label"; 1067 $serverParam = $server; 1068 $projParam = $proj; 1069 } 1070 1071 if ($debug) { echo htmlspecialchars($sql) . "<br>\n"; } 1072 1073 try { 1074 $stmt = $db->prepare($sql); 1075 $stmt->execute([':server' => $serverParam, ':proj' => $projParam]); 1076 1077 // fetch all values from the first (and only) column 1078 $labels = $stmt->fetchAll(PDO::FETCH_COLUMN); 1079 return $labels ?: []; // ensure an array is always returned 1080 } catch (PDOException $e) { 1081 // handle/log error in a way that suits your app 1082 if ($debug) { 1083 echo "<b>DB error:</b> " . htmlspecialchars($e->getMessage()) . "<br>\n"; 1084 } 1085 return []; // fail gracefully 1086 } 886 1087 } 887 1088 … … 982 1183 983 1184 foreach ($stages as &$stage) { 1185 global $addSearchState; // add this line if inside a function 984 1186 // Note: Do not include the state for chip, cam, and warp so that both new and update faults are listed 985 $myTable = $mainTable[$stage];986 $myFailures = $getFailures[$stage];1187 $myTable = $mainTable[$stage]; 1188 $myFailures = $getFailures[$stage]; 987 1189 # echo "myTable: $myTable"; 988 1190 989 if ("$myFailures" == "NONE") {1191 if ("$myFailures" == "NONE") { 990 1192 $link = $defaultlink; 991 1193 } else { 992 1194 $link = $myFailures . "?pass=" . $pass . "&proj=" . $proj . "&" . $myTable . ".label=" . $thisLabel; 993 if ($addSearchState[$stage]) {994 // Note: Do not include the state for chip, cam, and warp so that both new and update faults are listed995 $link .= "&" . $myTable . ".state=" . $searchState;996 }1195 if ($addSearchState[$stage]) { 1196 // Note: Do not include the state for chip, cam, and warp so that both new and update faults are listed 1197 $link .= "&" . $myTable . ".state=" . $searchState; 1198 } 997 1199 } 998 getStateAndFaults($db, $thisLabel, $proj, $selectedState, $stage, $str, $anyFaults); 999 //echo "getStateAndFaults $db, $thisLabel, $proj, $selectedState, $stage, $str, $anyFaults<br>"; 1000 1001 $cellcolor = 0; 1002 if ("$stage" == "dist") { 1003 $cellcolor = (!$isUpdate && !$distributing) ? "gray" : 0; 1004 } 1005 if ("$stage" == "pub") { 1006 $cellcolor = (!$isUpdate && !$publishing) ? "gray" : 0; 1007 } 1008 createFormattedTableCell($anyFaults, $link, $str, $anyFaults, $cellcolor); 1200 getStateAndFaults($db, $thisLabel, $proj, $selectedState, $stage, $str, $anyFaults); 1201 1202 $cellcolor = 0; 1203 if ("$stage" == "dist") { 1204 $cellcolor = (!$isUpdate && !$distributing) ? "gray" : 0; 1205 } 1206 if ("$stage" == "pub") { 1207 $cellcolor = (!$isUpdate && !$publishing) ? "gray" : 0; 1208 } 1209 createFormattedTableCell($anyFaults, $link, $str, $anyFaults, $cellcolor); 1009 1210 } 1010 1211 echo "</tr>\n"; … … 1099 1300 # 1100 1301 ########################################################################### 1101 function getNightlyScienceStatus ($db, $proj) {1302 function getNightlyScienceStatus_old($db, $proj) { 1102 1303 1103 1304 $sql = "SELECT status FROM science_nightlyscience WHERE telescope LIKE '$proj'"; … … 1109 1310 1110 1311 return $row[0]; 1312 } 1313 1314 function getNightlyScienceStatus(PDO $db, $proj, $debug = false) { 1315 $sql = "SELECT status FROM science_nightlyscience WHERE telescope LIKE :proj"; 1316 $stmt = $db->prepare($sql); 1317 $stmt->execute([':proj' => "%$proj%"]); // add wildcards 1318 $row = $stmt->fetch(PDO::FETCH_ASSOC); 1319 return $row ? $row['status'] : ''; 1111 1320 } 1112 1321 … … 1132 1341 ########################################################################### 1133 1342 function getRevertStatus($db, $proj, $stage) { 1134 1343 // Note: The $db parameter is now a PDO object. 1344 1345 // Use a prepared statement to prevent SQL injection. 1346 $sql = "SELECT reverting FROM science_reverts WHERE stage LIKE ? AND telescope LIKE ?"; 1347 1348 try { 1349 $stmt = $db->prepare($sql); 1350 $stmt->execute([$stage, $proj]); 1351 1352 // Fetch a single column from the next row 1353 return $stmt->fetchColumn(); 1354 1355 } catch (PDOException $e) { 1356 // Handle database errors 1357 error_log("Database error in getRevertStatus: " . $e->getMessage()); 1358 return null; // Return a safe default value 1359 } 1360 } 1361 1362 ########################################################################### 1363 # 1364 # Returns state and fault-count (if new) as a string 1365 # 1366 ########################################################################### 1367 function getStateAndFaults($db, $label, $proj, $state, $stage, &$str, &$anyFaults) { 1135 1368 $anyFaults = false; 1136 1369 1137 $sql = "SELECT reverting FROM science_reverts WHERE stage LIKE '$stage' AND telescope LIKE '$proj'"; 1138 if ($debug) {echo "$sql<br>";} 1139 1140 $qry = $db->query($sql); 1141 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";} 1142 $qry->fetchInto($row); 1143 1144 return $row[0]; 1145 } 1146 1147 ########################################################################### 1148 # 1149 # Returns state and fault-count (if new) as a string 1150 # 1151 ########################################################################### 1152 function getStateAndFaults($db, $label, $proj, $state, $stage, &$str, &$anyFaults) { 1153 1154 $anyFaults = false; 1155 $sql = "SELECT pending, faults FROM $stage WHERE label LIKE '$label' AND dbname LIKE '$proj' ORDER BY timestamp DESC LIMIT 1"; 1156 if ($debug) {echo "$sql<br>";} 1157 1158 $qry = $db->query($sql); 1159 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";} 1160 $qry->fetchInto($row); 1161 1162 $pending = $row[0]; 1163 $faults = $row[1]; 1164 1165 if ($pending == 0) 1166 $str = ""; 1167 else 1168 $str = "$pending"; 1169 1170 if ($state == "new") { 1171 1172 if ($faults > 0) { 1173 1174 $str = $str."(".$faults.")"; 1175 $anyFaults = true; 1370 // Use a prepared statement to prevent SQL injection. 1371 $sql = "SELECT pending, faults FROM $stage WHERE label LIKE ? AND dbname LIKE ? ORDER BY timestamp DESC LIMIT 1"; 1372 1373 try { 1374 $stmt = $db->prepare($sql); 1375 $stmt->execute([$label, $proj]); 1376 1377 // Fetch the result as a numerically indexed array 1378 $row = $stmt->fetch(PDO::FETCH_NUM); 1379 1380 if ($row) { 1381 $pending = $row[0]; 1382 $faults = $row[1]; 1383 1384 if ($pending == 0) { 1385 $str = ""; 1386 } else { 1387 $str = "$pending"; 1388 } 1389 1390 if ($state == "new" && $faults > 0) { 1391 $str .= "($faults)"; 1392 $anyFaults = true; 1393 } 1394 } else { 1395 // Handle case where no row is found 1396 $pending = null; 1397 $faults = null; 1176 1398 } 1399 1400 } catch (PDOException $e) { 1401 // Handle database errors 1402 error_log("Database error in getStateAndFaults: " . $e->getMessage()); 1403 $pending = null; 1404 $faults = null; 1405 // Optionally, you can set a default message for $str and $anyFaults 1177 1406 } 1178 1407 } … … 1210 1439 } 1211 1440 1212 1213 1441 ########################################################################### 1214 1442 # … … 1217 1445 ########################################################################### 1218 1446 function createServerDateRow($db, $proj, $server) { 1219 1220 $sql = "SELECT date FROM science_server_dates WHERE server LIKE '$server' AND telescope LIKE '$proj' ORDER BY date"; 1221 if ($debug) {echo "$sql<br>";} 1222 1223 $qry = $db->query($sql); 1224 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";} 1225 $dates = ""; 1226 $firstIn = true; 1227 while ($qry->fetchInto($row)) { 1228 if ($firstIn) { 1229 $dates = $row[0]; 1230 $firstIn = false; 1447 // Note: The $db parameter is now a PDO object. 1448 1449 // Use a prepared statement to prevent SQL injection. 1450 $sql = "SELECT date FROM science_server_dates WHERE server LIKE ? AND telescope LIKE ? ORDER BY date"; 1451 1452 try { 1453 $stmt = $db->prepare($sql); 1454 $stmt->execute([$server, $proj]); 1455 1456 $dates = ""; 1457 $firstIn = true; 1458 while ($row = $stmt->fetch(PDO::FETCH_NUM)) { 1459 if ($firstIn) { 1460 $dates = $row[0]; 1461 $firstIn = false; 1462 } else { 1463 $dates .= ", " . $row[0]; 1464 } 1231 1465 } 1232 else $dates = $dates . ", " . $row[0]; 1466 } catch (PDOException $e) { 1467 // Handle database errors 1468 error_log("Database error in createServerDateRow: " . $e->getMessage()); 1469 $dates = "DB ERROR"; 1233 1470 } 1234 1471 … … 1237 1474 echo "<td>$dates</td>"; 1238 1475 echo "</tr>"; 1239 1240 1476 } 1241 1477 … … 1333 1569 # 1334 1570 ########################################################################### 1335 function getServerStatus($db,$proj, $server, &$alive, &$running, &$host) { 1336 1337 # $sql = "SELECT alive, running FROM science_servers WHERE server LIKE '$server' AND telescope LIKE '$proj' ORDER BY timestamp DESC LIMIT 1"; 1338 $sql = "SELECT alive, running, host FROM live_servers WHERE server LIKE '$server' AND telescope LIKE '$proj' ORDER BY timestamp DESC LIMIT 1"; 1339 if($debug){echo "$sql<br>";} 1340 1341 $qry = $db->query($sql); 1342 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";} 1343 $qry->fetchInto($row); 1344 1345 $alive = $row[0]; 1346 $running = $row[1]; 1347 $host = $row[2]; 1571 1572 function getServerStatus($db, $proj, $server, &$alive, &$running, &$host) { 1573 // Note: The $db parameter is now expected to be a PDO object. 1574 1575 // Use a prepared statement to prevent SQL injection. 1576 $sql = "SELECT alive, running, host FROM live_servers WHERE server LIKE ? AND telescope LIKE ? ORDER BY timestamp DESC LIMIT 1"; 1577 1578 try { 1579 $stmt = $db->prepare($sql); 1580 1581 // Bind parameters and execute the query 1582 $stmt->execute([$server, $proj]); 1583 1584 // Fetch the result as a numerically indexed array, matching the old behavior 1585 $row = $stmt->fetch(PDO::FETCH_NUM); 1586 1587 if ($row) { 1588 $alive = $row[0]; 1589 $running = $row[1]; 1590 $host = $row[2]; 1591 } else { 1592 // Handle case where no data is found for the server 1593 $alive = null; 1594 $running = null; 1595 $host = null; 1596 } 1597 1598 } catch (PDOException $e) { 1599 // Handle database errors 1600 error_log("Database error in getServerStatus: " . $e->getMessage()); 1601 $alive = null; 1602 $running = null; 1603 $host = null; 1604 } 1348 1605 } 1349 1606 … … 1353 1610 # 1354 1611 ########################################################################### 1355 function getLastUpdateTime($db) { 1356 1357 $anyFaults = false; 1612 function getLastUpdateTime(PDO $db) { 1358 1613 $sql = "SELECT timestamp FROM chip ORDER BY timestamp DESC LIMIT 1"; 1359 if ($debug) {echo "$sql<br>";} 1360 1361 $qry = $db->query($sql); 1362 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";} 1363 $qry->fetchInto($row); 1364 1365 return $row[0]; 1614 1615 // run the query 1616 $stmt = $db->query($sql); 1617 if (!$stmt) { 1618 // if query fails, print error info 1619 $errorInfo = $db->errorInfo(); 1620 echo "<b>Error with $sql:</b> " . $errorInfo[2] . "<br>\n"; 1621 return null; 1622 } 1623 1624 // fetch the first row as numeric array 1625 $row = $stmt->fetch(PDO::FETCH_NUM); 1626 1627 return $row ? $row[0] : null; // return timestamp or null 1366 1628 } 1367 1629 … … 1391 1653 ########################################################################### 1392 1654 function showReplicationsStatus($replHost, $replUser, $replPassword, $replDatabaseName) { 1393 //print "<br>$replHost, $replUser, $replPassword, $replDatabaseName<br/>";1394 1655 global $czardb; 1395 1656 1396 // Prepare storage info early, https://panstarrs.atlassian.net/browse/IPP-23381397 1657 $storageInfo = ''; 1398 1658 $hostPrefixParts = explode(' ', $replDatabaseName); 1399 $hostPrefix = addslashes($hostPrefixParts[0]);1400 1401 $sql = sprintf(1402 "SELECT host, FORMAT(total,1), FORMAT(available,2), FORMAT(used,2), writable, readable, FORMAT(used/total*100,1)1403 FROM hosts1404 WHERE host LIKE '%s%%' order by available desc1405 LIMIT 1",1406 $hostPrefix1407 ); 1408 1409 $qry = $czardb->query($sql);1410 if (PEAR::isError($qry)) {1411 $ storageInfo = "<td style=\"background-color: red; color: white;\">Storage query error</td>";1412 } else { 1413 if ($ qry->fetchInto($row)) {1659 $hostPrefix = $hostPrefixParts[0]; 1660 1661 // Using a prepared statement with a placeholder for security 1662 $sql = "SELECT host, FORMAT(total,1), FORMAT(available,2), FORMAT(used,2), writable, readable, FORMAT(used/total*100,1) 1663 FROM hosts 1664 WHERE host LIKE ? 1665 ORDER BY available DESC 1666 LIMIT 1"; 1667 1668 try { 1669 $stmt = $czardb->prepare($sql); 1670 $stmt->execute(["$hostPrefix%"]); 1671 $row = $stmt->fetch(PDO::FETCH_NUM); 1672 1673 if ($row) { 1414 1674 list($host, $total, $available, $used, $writable, $readable, $ratioStr) = $row; 1415 $ratio = floatval($ratioStr); // convert to number 1416 1417 // Determine color 1675 $ratio = floatval($ratioStr); 1676 1418 1677 if ($ratio < 80) { 1419 1678 $color = 'lightgreen'; … … 1423 1682 $color = 'pink'; 1424 1683 } 1425 1684 1426 1685 $storageInfo = "<td style=\"background-color: $color;\">$ratioStr% of $total</td>"; 1427 1686 } else { 1428 1687 $storageInfo = "<td>No host storage data</td>"; 1429 1688 } 1430 } 1431 1432 $dbRepl = DB::connect("mysql://$replUser:$replPassword@$replHost"); 1433 if (PEAR::isError($dbRepl)) { 1689 } catch (PDOException $e) { 1690 $storageInfo = "<td style=\"background-color: red; color: white;\">Storage query error</td>"; 1691 } 1692 1693 // Connect to the replication database using PDO 1694 try { 1695 $dbRepl = new PDO("mysql:host=$replHost;", $replUser, $replPassword); 1696 $dbRepl->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 1697 } catch (PDOException $e) { 1434 1698 echo "<tr><td>$replDatabaseName</td>$storageInfo<td style=\"background-color: pink;\">MySQL DB connection error - check configuration</td></tr>"; 1435 return -1; // Don't stop the rest of the script1699 return -1; 1436 1700 } 1437 1701 1438 1702 // Query replication status 1439 $res = $dbRepl->query('SHOW SLAVE STATUS'); 1440 if (PEAR::isError($res)) { 1703 try { 1704 $res = $dbRepl->query('SHOW SLAVE STATUS'); 1705 $row = $res->fetch(PDO::FETCH_NUM); 1706 } catch (PDOException $e) { 1441 1707 echo "<tr><td>$replDatabaseName</td>$storageInfo<td style=\"background-color: pink;\">MySQL query error - invalid user or privileges</td></tr>"; 1442 $dbRepl ->disconnect();1708 $dbRepl = null; 1443 1709 return -1; 1444 1710 } 1445 1711 1446 if (!$r es->fetchInto($row)) {1712 if (!$row) { 1447 1713 echo "<tr><td>$replDatabaseName</td>$storageInfo<td style=\"background-color: pink;\">No replication data available</td></tr>"; 1448 $dbRepl ->disconnect();1714 $dbRepl = null; 1449 1715 return 0; 1450 1716 } 1451 1717 1718 // Note: The index for 'Seconds_Behind_Master' and 'Last_IO_Error' might vary based on MySQL version. 1719 // It's safer to use PDO::FETCH_ASSOC and the column names. 1452 1720 $errorStatusInMySql = $row[18]; 1453 1721 $sec_behind = $row[32]; … … 1463 1731 1464 1732 echo "<tr><td>$replDatabaseName</td>$storageInfo"; 1465 1466 1733 echo "<td>$replStatus</td></tr>"; 1467 1734 … … 1471 1738 } 1472 1739 1473 $dbRepl->disconnect(); 1474 1475 } 1476 1740 $dbRepl = null; // Close connection 1741 } 1477 1742 ########################################################################### 1478 1743 # … … 1481 1746 ########################################################################### 1482 1747 function showDatabaseStatus($Host, $User, $Password, $DatabaseName) { 1483 //print "<br>$Host, $User, $Password, $DatabaseName<br/>";1484 1748 global $czardb; 1485 // Prepare storage info early, https://panstarrs.atlassian.net/browse/IPP-23381486 1749 $storageInfo = ''; 1487 1750 $hostPrefixParts = explode(' ', $DatabaseName); 1488 1751 $hostPrefix = addslashes($hostPrefixParts[0]); 1489 1752 1490 $sql = sprintf( 1491 "SELECT host, FORMAT(total,1), FORMAT(available,2), FORMAT(used,2), writable, readable, FORMAT(used/total*100,1) 1492 FROM hosts 1493 WHERE host LIKE '%s%%' order by available desc 1494 LIMIT 1", 1495 $hostPrefix 1496 ); 1497 1498 $qry = $czardb->query($sql); 1499 if (PEAR::isError($qry)) { 1500 $storageInfo = "<td style=\"background-color: red; color: white;\">Storage query error</td>"; 1501 } else { 1502 if ($qry->fetchInto($row)) { 1753 $sql = "SELECT host, FORMAT(total,1), FORMAT(available,2), FORMAT(used,2), writable, readable, FORMAT(used/total*100,1) 1754 FROM hosts 1755 WHERE host LIKE ? 1756 ORDER BY available DESC 1757 LIMIT 1"; 1758 1759 try { 1760 $stmt = $czardb->prepare($sql); 1761 $stmt->execute(["$hostPrefix%"]); 1762 $row = $stmt->fetch(PDO::FETCH_NUM); 1763 1764 if ($row) { 1503 1765 list($host, $total, $available, $used, $writable, $readable, $ratioStr) = $row; 1504 $ratio = floatval($ratioStr); // convert to number 1505 1506 // Determine color 1766 $ratio = floatval($ratioStr); 1767 1507 1768 if ($ratio < 80) { 1508 1769 $color = 'lightgreen'; … … 1512 1773 $color = 'pink'; 1513 1774 } 1514 1775 1515 1776 $storageInfo = "<td style=\"background-color: $color;\">$ratioStr% of $total</td>"; 1516 1777 } else { 1517 1778 $storageInfo = "<td>No host storage data</td>"; 1518 1779 } 1519 } 1520 1521 $db = DB::connect("mysql://$User:$Password@$Host"); 1522 if (PEAR::isError($db)) { 1780 } catch (PDOException $e) { 1781 $storageInfo = "<td style=\"background-color: red; color: white;\">Storage query error</td>"; 1782 } 1783 1784 try { 1785 $db = new PDO("mysql:host=$Host;", $User, $Password); 1786 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 1787 $Status = "OK"; 1788 } catch (PDOException $e) { 1789 $Status = "<font style=\"BACKGROUND-COLOR: yellow\" color=\"red\">PROBLEM</font>"; 1523 1790 echo "<tr><td>$DatabaseName</td>$storageInfo<td>$Status</td>"; 1524 1791 return -1; 1525 1792 } 1526 $Status = ($errorStatusInMySql==0?"OK":"<font style=\"BACKGROUND-COLOR: yellow\" color=\"red\">PROBLEM</font>"); 1793 1527 1794 echo "<tr><td>$DatabaseName</td>$storageInfo<td>$Status</td>"; 1528 1529 $db->disconnect(); 1795 $db = null; // Close connection 1530 1796 } 1531 1797 … … 1571 1837 # 1572 1838 ########################################################################### 1573 function createSummitDataTable2($projectdb, $pass, $proj, $debug) { 1574 1839 function createSummitDataTable($projectdb, $pass, $proj, $debug) { 1575 1840 // timer start 1576 1841 $start = microtime(true); 1577 1842 1578 1843 // Define constants 1579 $mjdDay = getMJD(); 1580 $expname = "%{$mjdDay}%"; 1581 1844 $mjdDay = getMJD(); 1845 $expname = "%{$mjdDay}%"; 1582 1846 $mjdDaym1 = $mjdDay - 1; 1583 1847 $expnamem1 = "%{$mjdDaym1}%"; 1584 1585 1848 $mjdDaym5 = $mjdDay - 5; 1586 1849 $expnamem5 = "o{$mjdDaym5}%"; 1587 1850 1588 $currentDate = gmdate("Y-m-d H:i:s");1851 $currentDate = gmdate("Y-m-d H:i:s"); 1589 1852 $previousDate = gmdate("Y-m-d", strtotime("-1 day")); 1590 1853 … … 1597 1860 echo "<tr>"; 1598 1861 createTableColumnHeader("Exposure type"); 1599 createTableColumnHeader("<a href=\"czartool_labels.php?pass=".$pass."&proj=".$proj."&label=all&stage=summitExp\"><font color=\"blue\">summitExp status</font></a>"); 1600 createTableColumnHeader("<a href=\"czartool_labels.php?pass=".$pass."&proj=".$proj."&label=all&stage=downloadExp\"><font color=\"blue\">downloadExp status</font></a>"); 1601 createTableColumnHeader("<a href=\"czartool_labels.php?pass=".$pass."&proj=".$proj."&label=all&stage=rawExp\"><font color=\"blue\">rawExp </a>/ 1602 <a href=\"czartool_labels.php?pass=".$pass."&proj=".$proj."&label=all&stage=newExp\"><font color=\"blue\"> newExp</font></a>"); 1603 1862 createTableColumnHeader("<a href=\"czartool_labels.php?pass=$pass&proj=$proj&label=all&stage=summitExp\"><font color=\"blue\">summitExp status</font></a>"); 1863 createTableColumnHeader("<a href=\"czartool_labels.php?pass=$pass&proj=$proj&label=all&stage=downloadExp\"><font color=\"blue\">downloadExp status</font></a>"); 1864 createTableColumnHeader("<a href=\"czartool_labels.php?pass=$pass&proj=$proj&label=all&stage=rawExp\"><font color=\"blue\">rawExp</font></a> / 1865 <a href=\"czartool_labels.php?pass=$pass&proj=$proj&label=all&stage=newExp\"><font color=\"blue\">newExp</font></a>"); 1866 1867 // --- Query 1 --- 1604 1868 $sql = " 1605 SELECT sum_type, pzstate, rawstate, count(*), sum_exp, pz_exp, raw_exp 1606 FROM 1607 (SELECT summitExp.exp_type as sum_type, pzDownloadExp.state as pzstate, rawExp.state as rawstate, summitExp.exp_name as sum_exp, pzDownloadExp.exp_name as pz_exp, rawExp.exp_name as raw_exp 1608 FROM summitExp 1609 LEFT JOIN pzDownloadExp USING (summit_id) 1610 LEFT JOIN rawExp ON summitExp.exp_name = rawExp.exp_name 1611 WHERE summitExp.summit_id >= ( 1612 SELECT COALESCE(MIN(summit_id), 0) 1613 FROM summitExp 1614 WHERE exp_name LIKE '$expnamem5' 1615 ) 1616 AND summitExp.exp_name LIKE '$expname' ORDER BY summitExp.dateobs desc) as sub 1869 SELECT sum_type, pzstate, rawstate, count(*), sum_exp, pz_exp, raw_exp 1870 FROM (SELECT summitExp.exp_type as sum_type, 1871 pzDownloadExp.state as pzstate, 1872 rawExp.state as rawstate, 1873 summitExp.exp_name as sum_exp, 1874 pzDownloadExp.exp_name as pz_exp, 1875 rawExp.exp_name as raw_exp 1876 FROM summitExp 1877 LEFT JOIN pzDownloadExp USING (summit_id) 1878 LEFT JOIN rawExp ON summitExp.exp_name = rawExp.exp_name 1879 WHERE summitExp.summit_id >= ( 1880 SELECT COALESCE(MIN(summit_id), 0) 1881 FROM summitExp WHERE exp_name LIKE '$expnamem5') 1882 AND summitExp.exp_name LIKE '$expname' 1883 ORDER BY summitExp.dateobs desc) as sub 1617 1884 GROUP BY sum_type, pzstate, rawstate"; 1618 1885 if ($debug) {echo "$sql<br>";} 1619 1886 1620 1621 1887 $qry = $projectdb->query($sql); 1622 while ($ qry->fetchInto($tmp)) {1888 while ($tmp = $qry->fetch(PDO::FETCH_NUM)) { 1623 1889 list($expType, $downloadState, $rawState, $count, $summit_exp, $pz_exp, $raw_exp) = $tmp; 1624 if ($proj == "gpc1") { 1625 $summit_exp_link = "<a href=\"https://svn.ifa.hawaii.edu/summit/ds/gpc1/$summit_exp/\" target='_blank'><font color=\"blue\">$summit_exp</font></a>"; 1890 $summit_exp_link = ($proj == "gpc1") 1891 ? "<a href=\"https://svn.ifa.hawaii.edu/summit/ds/gpc1/$summit_exp/\" target='_blank'><font color=\"blue\">$summit_exp</font></a>" 1892 : "<a href=\"https://svn.ifa.hawaii.edu/conductorb/ds/gpc2/$summit_exp/\" target='_blank'><font color=\"blue\">$summit_exp</font></a>"; 1893 1894 if ($downloadState === NULL) { 1895 echo "<tr><td>$summit_exp_link $expType <td>loading imfiles <td>null <td bgcolor=\"yellow\"><font color=\"red\">$count"; 1896 } elseif ($downloadState === 'run') { 1897 echo "<tr><td>$summit_exp_link $expType <td>$pz_exp copying <td>$pz_exp saving <td bgcolor=$columnHeaderColor><font color=\"red\">$count"; 1626 1898 } else { 1627 $summit_exp_link = "<a href=\"https://svn.ifa.hawaii.edu/conductorb/ds/gpc2/$summit_exp/\" target='_blank'><font color=\"blue\">$summit_exp</font></a>"; 1899 if ($rawState === NULL) { 1900 echo "<tr><td>$summit_exp_link $expType <td>$pz_exp $downloadState <td>$pz_exp registering <td bgcolor=$columnHeaderColor><font color=\"blue\">$count"; 1901 } else { 1902 echo "<tr><td>$summit_exp_link $expType <td>$pz_exp $downloadState <td>$raw_exp $rawState <td>$count"; 1903 } 1628 1904 } 1629 if ($downloadState == NULL) { 1630 echo "<tr><td> $summit_exp_link $expType <td> loading imfiles <td> null <td bgcolor=\"yellow\"> <font color=\"red\">$count"; 1631 } else { 1632 if ($downloadState == 'run') { 1633 echo "<tr><td> $summit_exp_link $expType <td> $pz_exp copying <td> $pz_exp saving <td bgcolor=$columnHeaderColor> <font color=\"red\">$count"; 1634 } else { 1635 if ($rawState == NULL) { 1636 echo "<tr><td> $summit_exp_link $expType <td> $pz_exp $downloadState <td> $pz_exp registering <td bgcolor=$columnHeaderColor> <font color=\"blue\">$count"; 1637 } else { 1638 echo "<tr><td> $summit_exp_link $expType <td> $pz_exp $downloadState <td> $raw_exp $rawState <td> $count"; 1639 } 1640 } 1641 } 1642 } 1643 1905 } 1906 1907 // --- Query 2 --- 1644 1908 echo "<tr><th colspan=4>Last night $previousDate (UTC), $mjdDaym1 (MJD)"; 1645 1909 $sql = " 1646 SELECT sum_type, pzstate, rawstate, count(*), sum_exp, pz_exp, raw_exp 1647 FROM 1648 (SELECT summitExp.exp_type as sum_type, pzDownloadExp.state as pzstate, rawExp.state as rawstate, summitExp.exp_name as sum_exp, pzDownloadExp.exp_name as pz_exp, rawExp.exp_name as raw_exp 1649 FROM summitExp 1650 LEFT JOIN pzDownloadExp USING (summit_id) 1651 LEFT JOIN rawExp ON summitExp.exp_name = rawExp.exp_name 1652 WHERE summitExp.summit_id >= ( 1653 SELECT COALESCE(MIN(summit_id), 0) 1654 FROM summitExp 1655 WHERE exp_name LIKE '$expnamem5' 1656 ) 1657 AND summitExp.exp_name LIKE '$expnamem1' ORDER BY summitExp.dateobs desc) as sub 1910 SELECT sum_type, pzstate, rawstate, count(*), sum_exp, pz_exp, raw_exp 1911 FROM (SELECT summitExp.exp_type as sum_type, 1912 pzDownloadExp.state as pzstate, 1913 rawExp.state as rawstate, 1914 summitExp.exp_name as sum_exp, 1915 pzDownloadExp.exp_name as pz_exp, 1916 rawExp.exp_name as raw_exp 1917 FROM summitExp 1918 LEFT JOIN pzDownloadExp USING (summit_id) 1919 LEFT JOIN rawExp ON summitExp.exp_name = rawExp.exp_name 1920 WHERE summitExp.summit_id >= ( 1921 SELECT COALESCE(MIN(summit_id), 0) 1922 FROM summitExp WHERE exp_name LIKE '$expnamem5') 1923 AND summitExp.exp_name LIKE '$expnamem1' 1924 ORDER BY summitExp.dateobs desc) as sub 1658 1925 GROUP BY sum_type, pzstate, rawstate"; 1659 1926 if ($debug) {echo "$sql<br>";} 1660 1927 1661 1928 $qry = $projectdb->query($sql); 1662 while ($ qry->fetchInto($tmp)) {1929 while ($tmp = $qry->fetch(PDO::FETCH_NUM)) { 1663 1930 list($expType, $downloadState, $rawState, $count, $summit_exp, $pz_exp, $raw_exp) = $tmp; 1664 if ($proj == "gpc1") { 1665 $summit_exp_link = "<a href=\"https://svn.ifa.hawaii.edu/summit/ds/gpc1/$summit_exp/\" target='_blank'><font color=\"blue\">$summit_exp</font></a>"; 1931 $summit_exp_link = ($proj == "gpc1") 1932 ? "<a href=\"https://svn.ifa.hawaii.edu/summit/ds/gpc1/$summit_exp/\" target='_blank'><font color=\"blue\">$summit_exp</font></a>" 1933 : "<a href=\"https://svn.ifa.hawaii.edu/conductorb/ds/gpc2/$summit_exp/\" target='_blank'><font color=\"blue\">$summit_exp</font></a>"; 1934 1935 if ($downloadState === NULL) { 1936 echo "<tr><td>$summit_exp_link $expType <td>loading imfiles <td>null <td bgcolor=\"yellow\"><font color=\"red\">$count"; 1937 } elseif ($downloadState === 'run') { 1938 echo "<tr><td>$summit_exp_link $expType <td>$pz_exp copying <td>$pz_exp saving <td bgcolor=$columnHeaderColor><font color=\"red\">$count"; 1666 1939 } else { 1667 $summit_exp_link = "<a href=\"https://svn.ifa.hawaii.edu/conductorb/ds/gpc2/$summit_exp/\" target='_blank'><font color=\"blue\">$summit_exp</font></a>"; 1940 if ($rawState === NULL) { 1941 echo "<tr><td>$summit_exp_link $expType <td>$pz_exp $downloadState <td>$pz_exp registering <td bgcolor=$columnHeaderColor><font color=\"blue\">$count"; 1942 } else { 1943 echo "<tr><td>$summit_exp_link $expType <td>$pz_exp $downloadState <td>$raw_exp $rawState <td>$count"; 1944 } 1668 1945 } 1669 if ($downloadState == NULL) { 1670 echo "<tr><td> $summit_exp_link $expType <td> loading imfiles <td> null <td bgcolor=\"yellow\"> <font color=\"red\">$count"; 1671 } else { 1672 if ($downloadState == 'run') { 1673 echo "<tr><td> $summit_exp_link $expType <td> $pz_exp copying <td> $pz_exp saving <td bgcolor=$columnHeaderColor> <font color=\"red\">$count"; 1674 } else { 1675 if ($rawState == NULL) { 1676 echo "<tr><td> $summit_exp_link $expType <td> $pz_exp $downloadState <td> $pz_exp registering <td bgcolor=$columnHeaderColor> <font color=\"blue\">$count"; 1677 } else { 1678 echo "<tr><td> $summit_exp_link $expType <td> $pz_exp $downloadState <td> $raw_exp $rawState <td> $count"; 1679 } 1680 } 1681 } 1682 } 1683 1946 } 1947 1948 // End timer 1684 1949 echo "<tr><th colspan=4>"; 1685 // End timer1686 1950 $total_time = round(microtime(true) - $start, 3); 1687 1951 echo "<center>loading in $total_time seconds<br></center>"; 1688 1689 1952 echo "</th></tr>"; 1690 1953 echo "</table><br>"; 1691 1954 } 1692 1693 function formatState($state) {1694 // Formats display of the state for better readability1695 if (is_null($state)) {1696 return "<span style='color: red;'>null</span>";1697 } elseif ($state == 'run') {1698 return "<span style='color: red;'>loading</span>";1699 } else {1700 return $state;1701 }1702 }1703 ###########################################################################1704 #1705 # Gets disk status1706 #1707 ###########################################################################1708 function getHostsold($db) {1709 // timer start1710 $time = microtime();1711 $time = explode(' ', $time);1712 $time = $time[1] + $time[0];1713 $start = $time;1714 1715 #echo "<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>";1716 echo "<script type=\"text/javascript\" src=\"loader.js\"></script>";1717 echo "<br><div class=\"chartWithOverlay\" style=\"position: relative; width: 640px\">";1718 echo " <div id=\"disk_div\" style=\"width:640px; height:5000px\"></div>";1719 echo " <div class=\"overlay\" style=\"position: absolute; width: 100px; top: 35px; right: 20px;\">";1720 echo " <div style=\"font-size: 12px; height: 14px; border: 1px solid; background-color: #00ff00\"><center>Free</div>";1721 echo " <div style=\"font-size: 12px; height: 14px; border: 1px solid; background-color: #ffff00\"><center>Used</div>";1722 echo " <div style=\"font-size: 12px; height: 14px; border: 1px solid; background-color: #ff0000\"><center>> 97% limit</div>";1723 echo " <div style=\"font-size: 12px; height: 14px; border: 1px solid; background-color: #bbbbbb\"><center>Down | Repair</div>";1724 echo " <div style=\"font-size: 12px; height: 14px; border: 1px solid; background-color: #ffffff\"><center>Power Off</div>";1725 echo " </div>";1726 echo "</div>";1727 1728 echo "<script type=\"text/javascript\">";1729 echo "google.charts.load('current', {packages: ['corechart', 'bar']});";1730 echo "google.charts.setOnLoadCallback(drawBarColors);";1731 echo "function drawBarColors() {";1732 echo " var data = google.visualization.arrayToDataTable([";1733 echo " ['Host', ";1734 echo " 'used', {type: 'string', role: 'style'}, {type: 'string', role: 'tooltip', 'p': {'html': true}}, ";1735 echo " 'free', {type: 'string', role: 'style'}, {type: 'string', role: 'tooltip', 'p': {'html': true}}],";1736 1737 //$sql = "SELECT host, format(total,1), format(available,2), format(used,2), writable, readable, format(used/total*100,2) FROM hosts";1738 $sql = "SELECT host, format(total, 2), format(available, 2), format(used, 2), writable, readable, format(used/total*100,3) as ratio FROM hosts where xattr <> 3 ";1739 if ($debug) {echo "$sql<br>";}1740 $qry = $db->query($sql);1741 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";}1742 1743 // Set environment variables1744 putenv("PATH=/usr/local/bin:/usr/bin:/bin:/data/ippc65.0/ipp/src/psconfig//ipp-20210708-gentoo.lin64/bin");1745 putenv("PERL5LIB=/data/ippc65.0/ipp/src/psconfig//ipp-20210708-gentoo.lin64/lib");1746 1747 # not sure why neb-host doesn't work on ipp113 CCL.202102161748 exec("neb-host |cut -b 17-30,86-", $hostnoteall);1749 while ($qry->fetchInto($row)) {1750 list($host, $total, $available, $used, $writable, $readable, $ratio) = $row;1751 $hostnotes = preg_grep("/$host/", $hostnoteall);1752 $hostnote = array_values($hostnotes);1753 if ($writable == 1 && $readable == 1) {1754 if ($ratio >= 97) {1755 # space used over limits, up mode (read/write ok).1756 echo "[ \"$host:up\", ";1757 echo " $used, \"stroke-width: 0.3;\"+\"stroke-color: black;\"+\"color: #ff0000;\", \"<i><b>$host: $ratio% of $total TB used</b></i><br>$hostnote[0]\", ";1758 echo " $available, \"stroke-width: 0.3;\"+\"stroke-color: black;\"+\"color: #00ff00;\", \"<i><b>$host: $available TB free</b></i>\"],";1759 }1760 else {1761 # enough space, up mode (read/write ok).1762 echo "[ \"$host:up\", ";1763 echo " $used, \"stroke-width: 0.3;\"+\"stroke-color: black;\"+\"color: #ffff00;\", \"<i><b>$host: $ratio% of $total TB used</b></i><br>$hostnote[0]\", ";1764 echo " $available, \"stroke-width: 0.3;\"+\"stroke-color: black;\"+\"color: #00ff00;\", \"<i><b>$host: $available TB free</b></i>\"],";1765 }1766 }1767 else if ($writable == 0 && $readable == 1) {1768 if ($ratio >= 97) {1769 # space used over limits, repair mode (read only).1770 echo "[ \"$host:repair\", ";1771 echo " $used, \"stroke-width: 0.3;\"+\"stroke-color: black;\"+\"color: #ff0000;\", \"<i><b>$host: $ratio% of $total TB used<br><font color=red>$hostnote[0]\", ";1772 echo " $available, \"stroke-width: 0.3;\"+\"stroke-color: black;\"+\"color: #bbbbbb;\", \"<i><b>$host: $available TB free</b></i>\"],";1773 }1774 else {1775 # enough space, but hosts are unstable, repair mode (read only).1776 echo "[ \"$host:repair\", ";1777 echo " $used, \"stroke-width: 0.3;\"+\"stroke-color: black;\"+\"color: #ffff00;\", \"<i><b>$host: $ratio% of $total TB used<br>$hostnote[0]\", ";1778 echo " $available, \"stroke-width: 0.3;\"+\"stroke-color: black;\"+\"color: #bbbbbb;\", \"<i><b>$host: $available TB free</b></i>\"],";1779 }1780 }1781 else {1782 # down mode (can't read or write).1783 echo "[ \"$host:down\", ";1784 echo " $used, \"stroke-width: 0.3;\"+\"stroke-color: black;\"+\"color: #bbbbbb;\", \"<i><b>$host: $ratio% used<br>$hostnote[0]\", ";1785 echo " $available, \"stroke-width: 0.3;\"+\"stroke-color: black;\"+\"color: #bbbbbb;\", \"<i><b>$host: $available TB free</b></i>\"],";1786 }1787 }1788 echo " ]);";1789 echo " var options = {";1790 echo " title: 'Nebulous Disk Use across IPP Clusters',";1791 echo " titleTextStyle: {color: 'black', fontSize: 15},";1792 echo " width: '100%',";1793 echo " height: '100%',";1794 echo " tooltip: {isHtml: true},";1795 echo " legend: { position: 'none',";1796 echo " alignment: 'end',";1797 echo " maxLines: 3},";1798 echo " hAxis: { title: 'Space (TB)',";1799 echo " gridlines: {count: 10}";1800 echo " },";1801 echo " vAxis: { textPosition: 'in', direction: 1 },";1802 echo " bar: { groupWidth: '95%' },";1803 echo " chartArea: {left:20, top:30, right:20, bottom:40},";1804 echo " fontSize: 15,";1805 echo " isStacked: true,";1806 echo " colors: ['#76A7FA', '#FF5733', '#C70039', '#900C3F', '#581845']";1807 echo " };";1808 echo " var chart = new google.visualization.BarChart(document.getElementById('disk_div'));";1809 echo " chart.draw(data, options);";1810 echo " }";1811 echo "</script>";1812 $time = microtime();1813 $time = explode(' ', $time);1814 $time = $time[1] + $time[0];1815 $finish = $time;1816 $total_time = round(($finish - $start), 3);1817 $start= $finish;1818 echo "<center>loading in $total_time seconds<br></center>";1819 }1820 1821 ###########################################################################1822 #1823 # Gets disk status1824 #1825 ###########################################################################1826 function getHosts($db) {1827 $start = microtime(true);1828 1829 1830 // Set environment variables1831 putenv("PATH=/usr/local/bin:/usr/bin:/bin:/data/ippc65.0/ipp/src/psconfig//ipp-20210708-gentoo.lin64/bin");1832 putenv("PERL5LIB=/data/ippc65.0/ipp/src/psconfig//ipp-20210708-gentoo.lin64/lib");1833 1834 $hostnoteall = array();1835 exec("neb-host |cut -b 17-30,86-", $hostnoteall);1836 1837 $sql = "SELECT host, format(total, 2), format(available, 2), format(used, 2), writable, readable, format(used/total*100,3) as ratio FROM hosts where xattr <> 3 ORDER BY CASE WHEN ROUND(used/total*100,3) = 100 THEN 0 ELSE 1 END, CASE WHEN host LIKE '%\_bck.0' THEN 1 ELSE 0 END, host;";1838 $qry = $db->query($sql);1839 1840 if ($qry === false) {1841 echo "<b>Error with SQL query</b><br>";1842 return;1843 }1844 1845 $sqlMax = "SELECT MAX(total) AS max_total FROM hosts WHERE xattr <> 3";1846 $qryMax = $db->query($sqlMax);1847 $maxUsed = 0;1848 1849 if ($qryMax && $qryMax->fetchInto($rowMax)) {1850 $maxUsed = $rowMax[0]; // max_total value1851 }1852 1853 $dataRows = array();1854 while ($qry->fetchInto($row)) {1855 // Access by index1856 $host = $row[0]; // ipp071.01857 $total = $row[1]; // 80.0352 TB1858 $available = $row[2]; // 10.8096 TB1859 $used = $row[3]; // 69.2256 TB1860 $writable = $row[4]; // 01861 $readable = $row[5]; // 11862 $ratio = $row[6]; // 86.4939 %1863 1864 // Match notes1865 $hostnotes = preg_grep("/$host/", $hostnoteall);1866 $hostnote = reset($hostnotes);1867 1868 // Defaults1869 $styles = "stroke-width: .5; stroke-color: black;";1870 $status = "down";1871 $usedColor = "lightgrey";1872 $freeColor = "lightgrey";1873 1874 // Status logic1875 if ($writable == 1 && $readable == 1) {1876 $status = "up";1877 $usedColor = ($ratio >= 97) ? "pink" : "yellow"; // red if â¥97%1878 $freeColor = "#a6ec99"; // green free1879 } elseif ($writable == 0 && $readable == 1) {1880 $status = "repair";1881 $usedColor = ($ratio >= 97) ? "pink" : "yellow";1882 $freeColor = "lightgrey"; // grey free1883 } elseif ($available < 1) {1884 $used = $maxUsed;1885 $available = 0;1886 $status = "offline";1887 $usedColor = "white";1888 $freeColor = "white";1889 }1890 1891 if ($status == "down") {1892 $tooltipUsed = $host . ": " . round($ratio, 1) . "% of " . $total . " TB used ".1893 "<span style='color:red; font-weight:bold;'> <br>" . $hostnote . "</span>";1894 $tooltipFree = "<span style='color:red; font-weight:bold;'>" .1895 $host . ": " . $available . " TB free" .1896 "</span>";1897 } elseif ($status == "offline") {1898 $tooltipUsed = $host . ": " . round($ratio, 1) . "% of " . $total . " TB used ".1899 "<span style='color:red; font-weight:bold;'> <br>" . $hostnote . "</span>";1900 $tooltipFree = "<span style='color:red; font-weight:bold;'>" .1901 $host . ": " . $total . " TB free" .1902 "</span>";1903 } else {1904 $tooltipUsed = $host . ": " . round($ratio, 1) . "% of " . $total . " TB used<br>" . $hostnote;1905 $tooltipFree = $host . ": " . $available . " TB free";1906 }1907 1908 // Build data row (manual string concatenation for old PHP)1909 $dataRows[] =1910 "[ \"" . $host . ":" . $status . "\", " .1911 $used . ", \"" . $styles . " color: " . $usedColor . ";\", \"" . $tooltipUsed . "\", " .1912 $available . ", \"" . $styles . " color: " . $freeColor . ";\", \"" . $tooltipFree . "\" ]";1913 1914 }1915 echo "<script type=\"text/javascript\">1916 google.charts.load('current', {packages: ['corechart', 'bar']});1917 google.charts.setOnLoadCallback(drawBarColors);1918 1919 function drawBarColors() {1920 var data = google.visualization.arrayToDataTable([1921 ['Host', 'Used', {type: 'string', role: 'style'}, {type: 'string', role: 'tooltip', 'p': {'html': true}},1922 'Free', {type: 'string', role: 'style'}, {type: 'string', role: 'tooltip', 'p': {'html': true}}],1923 " . implode(",\n", $dataRows) . "1924 ]);1925 1926 var options = {1927 title: 'Nebulous Disk Use across IPP Clusters',1928 titleTextStyle: {color: 'black', fontSize: 15},1929 width: '100%',1930 height: '100%',1931 tooltip: {isHtml: true},1932 legend: { position: 'none', alignment: 'end', maxLines: 3 },1933 hAxis: { title: 'Space (TB)', gridlines: {count: 20} },1934 vAxis: { textStyle: {fontSize: 15}, format: 'string', textPosition: 'in', direction: 1},1935 bar: { groupWidth: '95%' },1936 chartArea: {left:40, top:50, right:20, bottom:40},1937 fontSize: 15,1938 allowHtml: true,1939 isStacked: true1940 };1941 1942 var chart = new google.visualization.BarChart(document.getElementById('disk_div'));1943 chart.draw(data, options);1944 }1945 </script>";1946 1947 echo "<script type='text/javascript' src='loader.js'></script>1948 <br>1949 <div class='chartWithOverlay' style='position: relative; width: 100%'>1950 1951 <div id='disk_div' style='width:100%; height:5000px'></div>1952 1953 <div class='overlay' style='position: absolute; width:160px; top:50px; right:30px; font-family:Arial, sans-serif;'>1954 1955 <div style='font-size:15px; border:1px solid #888; background-color:lightgreen; color:black; text-align:center; margin-bottom:1px;'>Free</div>1956 <div style='font-size:15px; border:1px solid #888; background-color:yellow ; color:black; text-align:center; margin-bottom:1px;'>Used</div>1957 <div style='font-size:15px; border:1px solid #888; background-color:pink ; color:black; text-align:center; margin-bottom:1px;'>97% Usage</div>1958 <div style='font-size:15px; border:1px solid #888; background-color:lightgrey ; color:black; text-align:center; margin-bottom:1px;'>Down/Repair</div>1959 <div style='font-size:15px; border:1px solid #888; background-color:white ; color:black; text-align:center; margin-bottom:1px;'>Offline</div>1960 <div style='font-size:15px; border:1px solid #888; background-color:#42a5f5 ; color:white; text-align:center; margin-bottom:1px;'>1961 <a href='https://atrcganglia.ifa.hawaii.edu/' target='_blank' style='text-decoration:none; color:white; font-weight:bold;'>ATRC ganglia</a>1962 </div>1963 1964 </div>1965 1966 </div>";1967 1968 $total_time = round(microtime(true) - $start, 3);1969 echo "<center>loading in $total_time seconds<br></center>";1970 }1971 1972 ###########################################################################1973 #1974 # Gets disk spaces status1975 #1976 ###########################################################################1977 function getSpaces($db) {1978 // timer start1979 $time = microtime();1980 $time = explode(' ', $time);1981 $time = $time[1] + $time[0];1982 $start = $time;1983 1984 1985 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host like 'ippb%' and xattr <> 3")->fetchInto($row);1986 $ippbusable = $row[0];1987 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host like 'ippb%' and writable = 1 and xattr <> 3")->fetchInto($row);1988 $ippbfree = $row[0];1989 1990 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host not like 'ippb%' and xattr <> 3")->fetchInto($row);1991 $ippusable = $row[0];1992 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host not like 'ippb%' and writable = 1 and xattr <> 3")->fetchInto($row);1993 $ippfree = $row[0];1994 1995 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host like 'ipp%_bck.0' and xattr <> 3")->fetchInto($row);1996 $bckusable = $row[0];1997 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host like 'ipp%_bck.0' and writable = 1 and xattr <> 3")->fetchInto($row);1998 $bckfree = $row[0];1999 2000 $sql = "select format(used/total*100,1), usable from cluster_space order by timestamp desc limit 1;";2001 2002 if ($debug) {echo "$sql<br>";}2003 $qry = $db->query($sql);2004 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";}2005 $qry->fetchInto($row);2006 $allocated = $row[0];2007 $usable = $row[1];2008 2009 #echo "<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>";2010 echo "<script type=\"text/javascript\" src=\"loader.js\"></script>";2011 echo "<br><div class=\"chartWithOverlay\" style=\"position: relative; width: 640; height:400\">";2012 echo " <div id=\"space_div\" style=\"width:640; \"></div>";2013 echo " <div class=\"overlay\" style=\"position: absolute; width: 500px; bottom: 60px; left: 85px;\">";2014 echo " <div style=\"font-size: 16px; color:#0000ff; \"><b>ipp*_bck: $bckusable TB (usable)</b></div>";2015 echo " <div style=\"font-size: 16px; color:#33a532; \"><b>ipp*_bck: $bckfree TB (free)</b></div>";2016 echo " </div>";2017 echo "</div>";2018 2019 echo "<script type=\"text/javascript\">";2020 echo "google.charts.load('current', {packages: ['corechart']});";2021 echo "google.charts.setOnLoadCallback(drawChart);";2022 echo "function drawChart() {";2023 echo " var data = new google.visualization.DataTable();";2024 echo " data.addColumn('datetime', 'Day');";2025 echo " data.addColumn('number', 'Usable (ipp:$ippusable, ippb:$ippbusable) TB');";2026 echo " data.addColumn('number', 'Free (ipp:$ippfree, ippb:$ippbfree) TB');";2027 echo " data.addRows([";2028 $interval = 10;2029 $sql = "select sub.dated, sub.usable, sub.available from (select date_format(timestamp, \"%Y.%m.%d.%H.%i\") as dated, usable, available from cluster_space where timestamp > curdate() - INTERVAL $interval DAY) as sub group by dated;";2030 if ($debug) {echo "$sql<br>";}2031 $qry = $db->query($sql);2032 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";}2033 while ($qry->fetchInto($row)) {2034 $tsp = explode('.', $row[0]);2035 $mon = $tsp[1]-1;2036 $timestamp = $row[0];2037 $usable = $row[1];2038 $available = $row[2];2039 # new Date(Year, Month, Day, Hours, Minutes, Seconds, Milliseconds)2040 echo "[new Date($tsp[0], $mon, $tsp[2], $tsp[3], $tsp[4]), $usable, $available],";2041 }2042 echo " ]);";2043 echo " var options = {";2044 echo " chart: {";2045 echo " position: 'center', " ;2046 echo " },";2047 echo " title: 'Total Available Cluster Space in the Past $interval Days ($allocated% of total allocated)',";2048 echo " titleTextStyle: {color: 'black', fontSize: 15},";2049 echo " width: '100%',";2050 echo " height: 400,";2051 echo " legend: { position: 'top',";2052 echo " alignment: 'center',";2053 echo " },";2054 echo " lineWidth: 2, ";2055 echo " series: {";2056 echo " 0: { color: '#0000ff', lineWidth: 3 }, ";2057 echo " 1: { color: '#33a532', lineWidth: 3 }, ";2058 echo " },";2059 echo " hAxis: { ";2060 echo " title: 'Date/Time (HST)',";2061 echo " format: 'MMM dd',";2062 echo " gridlines: {count: -1},";2063 echo " },";2064 echo " vAxis: { ";2065 echo " title: 'Available (TB)',";2066 echo " viewWindow: { min: 500 }, ";2067 echo " },";2068 echo " chartArea: {left:80, top:50, right:20, bottom:50},";2069 echo " fontSize: 12,";2070 echo " };";2071 echo " var chart = new google.visualization.LineChart(document.getElementById('space_div'));";2072 echo " chart.draw(data, options);";2073 echo " }";2074 echo "</script>";2075 $time = microtime();2076 $time = explode(' ', $time);2077 $time = $time[1] + $time[0];2078 $finish = $time;2079 $total_time = round(($finish - $start), 3);2080 $start= $finish;2081 echo "<center>loading in $total_time seconds<br></center>";2082 }2083 2084 ###########################################################################2085 #2086 # Gets data quality status2087 #2088 ###########################################################################2089 function getDataQuality($db) {2090 // timer start2091 $time = microtime();2092 $time = explode(' ', $time);2093 $time = $time[1] + $time[0];2094 $start = $time;2095 2096 $date = gmdate("Y-m-d");2097 $sql = "SELECT MAX(exp_id) FROM rawExp WHERE dateobs BETWEEN DATE_SUB('$date', INTERVAL 20 DAY) AND DATE_SUB('$date', INTERVAL 10 DAY)";2098 if ($debug) {echo "$sql<br>";}2099 $qry = $db->query($sql);2100 2101 if (dberror($qry)) {2102 echo "*** WARNING: No data in the period 10-20 days before requested date (query will be slower) **\n";2103 $refExpID = 0;2104 } else {2105 $qry->fetchInto($refExpID);2106 $refExpID = isset($refExpID[0]) ? $refExpID[0] : 0;2107 }2108 // Print the result of the query2109 if ($debug) {echo "The result of MAX(exp_id) is: $refExpID<br>";}2110 {echo "The result of MAX(exp_id) is: $refExpID<br>";}2111 2112 #Query for the needed data2113 $DQarray = array();2114 2115 $sql = "SELECT subtime(dateobs,'10:00:00') as time,iq_fwhm_major,iq_fwhm_minor,zpt_obs,zpt_stdev,rawExp.filter,rawExp.exp_time,rawExp.comment FROM rawExp JOIN chipRun using (exp_id) JOIN camRun using (chip_id) JOIN camProcessedExp using (cam_id)";2116 # $sql.= " WHERE (rawExp.dateobs > utc_date() - INTERVAL 14 hour) and (rawExp.dateobs < utc_date() + INTERVAL 10 hour)";2117 $sql.= " WHERE (rawExp.dateobs > utc_date())";2118 # $sql.= " WHERE (rawExp.dateobs > '2024-10-24')";2119 # $sql.= " AND (rawExp.dateobs < '2024-10-25')";2120 $sql.= " AND exp_id > $refExpID[0]";2121 $sql.= " AND exp_type = 'OBJECT' AND camRun.state like 'full' ORDER BY dateobs asc;";2122 if ($debug) {echo "$sql<br>";}2123 $qry = $db->query($sql);2124 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";}2125 # echo "<b>error with $sql </b><br>\n";2126 while ($qry->fetchInto($row)) {2127 $DQarray[] = $row;2128 }2129 2130 #also find the median zeropoint2131 # foreach($DQarray as $row) {2132 # $zpt[] = $row[3];2133 # }2134 2135 # sort($zpt);2136 # $count = sizeof($zpt); // cache the count2137 # $index = floor($count/2); // cache the index2138 # $zpt_med = $zpt[$index];2139 2140 #echo "<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>";2141 echo "<script type=\"text/javascript\" src=\"loader.js\"></script>";2142 echo "<br><div class=\"chartWithOverlay\" style=\"position: relative; width: 640; height:400\">";2143 echo " <div id=\"dq_div\" style=\"width:640; \"></div>";2144 echo " <div class=\"overlay\" style=\"position: absolute; width: 400px; bottom: 60px; left: 85px;\">";2145 echo " </div>";2146 echo "</div>";2147 2148 echo "<script type=\"text/javascript\">";2149 echo "google.charts.load('current', {packages: ['corechart']});";2150 echo "google.charts.setOnLoadCallback(drawChart);";2151 echo "function drawChart() {";2152 echo " var data = new google.visualization.DataTable();";2153 echo " data.addColumn('datetime', 'Time');";2154 echo " data.addColumn('number', 'FWHM_maj');";2155 echo " data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});";2156 echo " data.addColumn('number', 'FWHM_min');";2157 echo " data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});";2158 echo " data.addColumn('number', 'seeing=1');";2159 echo " data.addColumn('number', 'seeing=1.5');";2160 echo " data.addRows([";2161 2162 foreach($DQarray as $row) {2163 $tsp = explode(' ', $row[0]);2164 $dat = explode('-', $tsp[0]);2165 $tm = explode(':', $tsp[1]);2166 $timestamp = $row[0];2167 $fwhm_maj = $row[1];2168 $fwhm_min = $row[2];2169 2170 $tt_string1 = sprintf('time: %s\n FWHM_major: %s\n filter: %s\n exp_time: %s\n comment: %s', $timestamp, $fwhm_maj,$row[5],$row[6],$row[7]);2171 $tt_string2 = sprintf('time: %s\n FWHM_minor: %s\n filter: %s\n exp_time: %s\n comment: %s', $timestamp, $fwhm_min,$row[5],$row[6],$row[7]);2172 # new Date(Year, Month, Day, Hours, Minutes, Seconds, Milliseconds)2173 echo "[new Date($dat[0], $dat[1]-1, $dat[2], $tm[0], $tm[1]), $fwhm_maj,'$tt_string1',$fwhm_min,'$tt_string2',3.85,5.76],";2174 }2175 echo " ]);";2176 echo " var options = {";2177 echo " chart: {";2178 echo " position: 'center', " ;2179 echo " },";2180 echo " title: 'FWHM overview during the last night',";2181 echo " titleTextStyle: {color: 'black', fontSize: 15},";2182 echo " width: '100%',";2183 echo " height: 400,";2184 echo " legend: { position: 'top',";2185 echo " alignment: 'center',";2186 echo " },";2187 echo " lineWidth: 2, ";2188 echo " series: {";2189 echo " 0: { color: '#0000ff', lineWidth: 3 }, ";2190 echo " 1: { color: '#33a532', lineWidth: 3 }, ";2191 echo " 2: { color: 'red', lineWidth: 2 }, ";2192 echo " 3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4] }, ";2193 echo " },";2194 echo " hAxis: { ";2195 echo " title: 'Date/Time (HST)',";2196 echo " format: 'HH:mm',";2197 echo " gridlines: {count: -1},";2198 echo " },";2199 echo " vAxis: { ";2200 echo " title: 'FWHM (pixels)',";2201 echo " },";2202 echo " chartArea: {left:80, top:50, right:20, bottom:50},";2203 echo " fontSize: 12,";2204 echo " };";2205 echo " var chart = new google.visualization.LineChart(document.getElementById('dq_div'));";2206 echo " chart.draw(data, options);";2207 echo " }";2208 echo "</script>";2209 2210 # ---------------------------------------2211 # Also the zeropoint2212 2213 #echo "<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>";2214 echo "<script type=\"text/javascript\" src=\"loader.js\"></script>";2215 echo "<br><div class=\"chartWithOverlay\" style=\"position: relative; width: 640; height:400\">";2216 echo " <div id=\"dqzp_div\" style=\"width:640; \"></div>";2217 echo " <div class=\"overlay\" style=\"position: absolute; width: 400px; bottom: 60px; left: 85px;\">";2218 echo " </div>";2219 echo "</div>";2220 2221 echo "<script type=\"text/javascript\">";2222 echo "google.charts.load('current', {packages: ['corechart']});";2223 echo "google.charts.setOnLoadCallback(drawChart);";2224 echo "function drawChart() {";2225 echo " var data = new google.visualization.DataTable();";2226 echo " data.addColumn('datetime', 'Time');";2227 echo " data.addColumn('number', 'zeropoint');";2228 echo " data.addColumn({'type': 'string', 'role': 'style'});";2229 echo " data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});";2230 echo " data.addColumn({id:'i0', type:'number', role:'interval'});";2231 echo " data.addColumn({id:'i0','type': 'string', 'role': 'style'});";2232 echo " data.addColumn({id:'i0', type:'number', role:'interval'});";2233 echo " data.addColumn({id:'i0','type': 'string', 'role': 'style'});";2234 echo " data.addRows([";2235 foreach($DQarray as $row) {2236 $tsp = explode(' ', $row[0]);2237 $dat = explode('-', $tsp[0]);2238 $tm = explode(':', $tsp[1]);2239 $timestamp = $row[0];2240 $zp = $row[3];2241 $zp_stdev = $row[4];2242 $zp_low = $zp-$zp_stdev;2243 $zp_high = $zp+$zp_stdev;2244 $col_string = '#0000ff';2245 $zpt_off = 0.;2246 2247 $tt_string1 = sprintf('time: %s\n zeropoint: %s\n filter: %s\n exp_time: %s\n comment: %s', $timestamp, $zp,$row[5],$row[6],$row[7]);2248 # new Date(Year, Month, Day, Hours, Minutes, Seconds, Milliseconds)2249 echo "[new Date($dat[0], $dat[1]-1, $dat[2], $tm[0], $tm[1]), $zp,'$col_string','$tt_string1', $zp_low,'$col_string', $zp_high,'$col_string'],";2250 }2251 2252 echo " ]);";2253 echo " var options = {";2254 echo " chart: {";2255 echo " position: 'center', " ;2256 echo " },";2257 echo " title: 'Zeropoint overview during the last night',";2258 echo " titleTextStyle: {color: 'black', fontSize: 15},";2259 echo " width: '100%',";2260 echo " height: 400,";2261 echo " legend: { position: 'top',";2262 echo " alignment: 'center',";2263 echo " },";2264 echo " series: {";2265 echo " 0: { color: '#0000ff'}, ";2266 echo " },";2267 echo " intervals: { color: 'grey','style':'points', pointSize: 1 }, ";2268 echo " hAxis: { ";2269 echo " title: 'Date/Time (HST)',";2270 echo " format: 'HH:mm',";2271 echo " gridlines: {count: -1},";2272 echo " },";2273 echo " vAxis: { ";2274 echo " title: 'Zeropoint (mag)',";2275 echo " },";2276 echo " chartArea: {left:80, top:50, right:20, bottom:50},";2277 echo " fontSize: 12,";2278 echo " };";2279 echo " var chart = new google.visualization.ScatterChart(document.getElementById('dqzp_div'));";2280 echo " chart.draw(data, options);";2281 echo " }";2282 echo "</script>";2283 2284 # ---------------------------------------2285 # And a fixed zoom in on the zeropoint to see details2286 2287 #echo "<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>";2288 echo "<script type=\"text/javascript\" src=\"loader.js\"></script>";2289 echo "<br><div class=\"chartWithOverlay\" style=\"position: relative; width: 640; height:400\">";2290 echo " <div id=\"dqzp_zoom_div\" style=\"width:640; \"></div>";2291 echo " <div class=\"overlay\" style=\"position: absolute; width: 400px; bottom: 60px; left: 85px;\">";2292 echo " </div>";2293 echo "</div>";2294 2295 echo "<script type=\"text/javascript\">";2296 echo "google.charts.load('current', {packages: ['corechart']});";2297 echo "google.charts.setOnLoadCallback(drawChart);";2298 echo "function drawChart() {";2299 echo " var data = new google.visualization.DataTable();";2300 echo " data.addColumn('datetime', 'Time');";2301 echo " data.addColumn('number', 'zeropoint');";2302 echo " data.addColumn({'type': 'string', 'role': 'style'});";2303 echo " data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});";2304 echo " data.addColumn({id:'i0', type:'number', role:'interval'});";2305 echo " data.addColumn({id:'i1', type:'number', role:'interval'});";2306 echo " data.addRows([";2307 foreach($DQarray as $row) {2308 $tsp = explode(' ', $row[0]);2309 $dat = explode('-', $tsp[0]);2310 $tm = explode(':', $tsp[1]);2311 $timestamp = $row[0];2312 $zp = $row[3];2313 $zp_stdev = $row[4];2314 $zp_low = $zp_stdev;2315 $zp_high = $zp_stdev;2316 $col_string = '#0000ff';2317 $zpt_off = 0.;2318 2319 #if(substr($row[5],0,1) == 'g') {$col_string = 'blue'; $zpt_off = $zp - 24.563;}2320 #if(substr($row[5],0,1) == 'r') {$col_string = 'red'; $zpt_off = $zp - 24.740;}2321 #if(substr($row[5],0,1) == 'i') {$col_string = '#6a3d9a'; $zpt_off = $zp - 24.611;}2322 #if(substr($row[5],0,1) == 'z') {$col_string = 'green'; $zpt_off = $zp - 24.250;}2323 #if(substr($row[5],0,1) == 'y') {$col_string = 'cyan'; $zpt_off = $zp - 23.320;}2324 #if(substr($row[5],0,1) == 'w') {$col_string = 'grey'; $zpt_off = $zp - 26.300;}2325 2326 #define new zeropoints2327 if(substr($row[5],0,1) == 'g') {$col_string = '#00f000'; $zpt_off = $zp - 25.013;}2328 if(substr($row[5],0,1) == 'r') {$col_string = '#f00000'; $zpt_off = $zp - 24.840;}2329 if(substr($row[5],0,1) == 'i') {$col_string = '#f05000'; $zpt_off = $zp - 24.711;}2330 if(substr($row[5],0,1) == 'z') {$col_string = '#0050a0'; $zpt_off = $zp - 24.300;}2331 if(substr($row[5],0,1) == 'y') {$col_string = '#ffe000'; $zpt_off = $zp - 23.570;}2332 if(substr($row[5],0,1) == 'w') {$col_string = '#808080'; $zpt_off = $zp - 26.060;}2333 2334 $tt_string1 = sprintf('time: %s\n zeropoint: %s\n filter: %s\n exp_time: %s\n comment: %s', $timestamp, $zp,$row[5],$row[6],$row[7]);2335 # new Date(Year, Month, Day, Hours, Minutes, Seconds, Milliseconds)2336 echo "[new Date($dat[0], $dat[1]-1, $dat[2], $tm[0], $tm[1]), $zpt_off,'$col_string','$tt_string1', $zp_low, $zp_high],";2337 }2338 2339 echo " ]);";2340 echo " var options = {";2341 echo " chart: {";2342 echo " position: 'center', " ;2343 echo " },";2344 echo " title: 'Zeropoint zoom-in during the last night',";2345 echo " titleTextStyle: {color: 'black', fontSize: 15},";2346 echo " width: '100%',";2347 echo " height: 400,";2348 echo " legend: { position: 'top',";2349 echo " alignment: 'center',";2350 echo " },";2351 echo " pointSize: 3, ";2352 echo " series: {";2353 echo " 0: { color: '#0000ff'}, ";2354 echo " },";2355 echo " intervals: { color: 'grey','style':'points', pointSize: 1 }, ";2356 echo " hAxis: { ";2357 echo " title: 'Date/Time (HST)',";2358 echo " format: 'HH:mm',";2359 echo " gridlines: {count: -1},";2360 echo " },";2361 echo " vAxis: { ";2362 echo " title: 'Zeropoint offset (mag)',";2363 echo " viewWindow: { min: -0.25, max: 0.25 }, ";2364 echo " },";2365 echo " chartArea: {left:80, top:50, right:20, bottom:50},";2366 echo " fontSize: 12,";2367 echo " };";2368 echo " var chart = new google.visualization.ScatterChart(document.getElementById('dqzp_zoom_div'));";2369 echo " chart.draw(data, options);";2370 echo " }";2371 echo "</script>";2372 2373 2374 2375 $time = microtime();2376 $time = explode(' ', $time);2377 $time = $time[1] + $time[0];2378 $finish = $time;2379 $total_time = round(($finish - $start), 3);2380 $start= $finish;2381 echo "<center>loading plot in $total_time seconds<br></center>";2382 }2383 2384 1955 2385 1956 … … 3269 2840 } 3270 2841 3271 3272 ###########################################################################3273 #3274 # Get data quality3275 #3276 ###########################################################################3277 function getDataQuality2($db) {3278 // Start timer3279 $start = microtime(true);3280 3281 $mjdDay = getMJD();3282 $expname = "o".$mjdDay."%";3283 3284 $sql = "SELECT SUBTIME(dateobs, '10:00:00') AS time,3285 round(( 367*YEAR(dateobs)- FLOOR((7 * (YEAR(dateobs) + FLOOR((MONTH(dateobs) + 9) / 12))) / 4) + FLOOR(275 * MONTH(dateobs) / 9)3286 + DAY(dateobs) + 1721013.5 + (HOUR(dateobs) / 24.0) + (MINUTE(dateobs) / 1440.0) + (SECOND(dateobs) / 86400.0) - 2400000.5), 5) AS MJD,3287 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_id3288 FROM rawExp JOIN chipRun using (exp_id) JOIN camRun using (chip_id) JOIN camProcessedExp using (cam_id)3289 WHERE rawExp.exp_name like '$expname'3290 AND exp_type = 'OBJECT'3291 AND camRun.state like 'full'3292 AND camProcessedExp.fault = 03293 AND camProcessedExp.zpt_obs != 0; ";3294 3295 $DQarray = array();3296 $qry = $db->query($sql);3297 if (dberror($qry)) {3298 echo "<b>Error with $sql</b><br>\n";3299 return;3300 }3301 3302 while ($qry->fetchInto($row)) {3303 $DQarray[] = $row;3304 }3305 3306 // Ensure $DQarray is not empty3307 if (empty($DQarray)) {3308 echo "<center><b> No data for MJD: $mjdDay </b></center>";3309 return; // Stop execution if no data to encode3310 }3311 3312 // Convert data array to JSON for easier handling in JavaScript3313 $dataJson = json_encode($DQarray);3314 3315 if ($dataJson === false) {3316 echo "<b>Error encoding JSON:</b> " . json_last_error_msg(); // Display any JSON encoding errors3317 return; // Stop execution if JSON encoding fails3318 }3319 3320 echo "<script>console.log(" . json_encode($dataJson) . ");</script>"; // Log JSON output to console for debugging3321 3322 echo <<<HTML3323 <script type="text/javascript" src="loader.js"></script>3324 3325 <script type="text/javascript">3326 google.charts.load('current', {packages: ['corechart']});3327 3328 // Use the encoded JSON directly in JavaScript3329 const dataArray = JSON.parse('{$dataJson}'); // Directly parse the PHP JSON string3330 3331 // draw FWHM vs MJD3332 function drawFWHMChart() {3333 var data = new google.visualization.DataTable();3334 data.addColumn('number', 'MJD');3335 data.addColumn('number', 'FWHM_major');3336 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});3337 data.addColumn('number', 'FWHM_minor');3338 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});3339 data.addColumn('number', 'seeing ~ 1"');3340 data.addColumn('number', 'seeing ~ 3"');3341 3342 const rows = dataArray.map(row => {3343 const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id] = row;3344 3345 return [3346 parseFloat(mjd), // Position Angle3347 parseFloat(iq_fwhm_maj), // RA_offset (AST_R0)3348 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,3349 parseFloat(iq_fwhm_min), // Dec_offset (AST_D0)3350 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>HST: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment,3351 4,3352 123353 ];3354 });3355 3356 data.addRows(rows);3357 3358 const options = {3359 title: 'FWHM (MJD)',3360 titleTextStyle: {color: 'black', fontSize: 15},3361 width: '100%',3362 height: 480,3363 legend: { position: 'top', alignment: 'center' },3364 series: {3365 0: { color: '#0000ff', pointSize: 3, lineWidth: 1 },3366 1: { color: '#33a532', pointSize: 3, lineWidth: 1 },3367 2: { color: 'red', lineWidth: 2, pointSize: 0 },3368 3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }3369 },3370 intervals: { color: 'red', lineWidth: 2, style: 'sticks' },3371 hAxis: {3372 title: 'MJD',3373 gridlines: {count: -1}3374 },3375 vAxis: {3376 title: 'FWHM (pixels)',3377 },3378 tooltip: { isHtml: true }, // Render tooltips as HTML3379 chartArea: {left: '8%', top: 60, right: '5%', bottom: 50}, // Adjust left and right3380 fontSize: 12,3381 };3382 3383 const chart = new google.visualization.LineChart(document.getElementById('dq_div_fwhm'));3384 chart.draw(data, options);3385 }3386 3387 // draw zoomed zerpoint vs mjd3388 function drawZOOMZPTChart() {3389 var data = new google.visualization.DataTable();3390 data.addColumn('number', 'MJD');3391 3392 // Add columns for each filter type to handle separate colors3393 data.addColumn('number', 'g (24.563, 25.013)');3394 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3395 data.addColumn({type: 'number', role: 'interval'});3396 data.addColumn({type: 'number', role: 'interval'});3397 data.addColumn('number', 'r (24.750, 24.840)');3398 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3399 data.addColumn({type: 'number', role: 'interval'});3400 data.addColumn({type: 'number', role: 'interval'});3401 data.addColumn('number', 'i (24.611, 24.711)');3402 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3403 data.addColumn({type: 'number', role: 'interval'});3404 data.addColumn({type: 'number', role: 'interval'});3405 data.addColumn('number', 'z (24.240, 24.300)');3406 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3407 data.addColumn({type: 'number', role: 'interval'});3408 data.addColumn({type: 'number', role: 'interval'});3409 data.addColumn('number', 'y (23.320, 23.570)');3410 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3411 data.addColumn({type: 'number', role: 'interval'});3412 data.addColumn({type: 'number', role: 'interval'});3413 data.addColumn('number', 'w (26.000, 26.300)');3414 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3415 data.addColumn({type: 'number', role: 'interval'});3416 data.addColumn({type: 'number', role: 'interval'});3417 3418 const rows = dataArray.map(row => {3419 const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id] = row;3420 3421 // Initialize all filter values as null3422 let zp_g = null, zp_r = null, zp_i = null, zp_z = null, zp_y = null, zp_w = null;3423 3424 // Set the zeropoint offset based on filter and assign it to the correct series3425 switch (filter[0]) {3426 case 'g':3427 zp_g = zpt_obs - 24.563;3428 break;3429 case 'r':3430 zp_r = zpt_obs - 24.750;3431 break;3432 case 'i':3433 zp_i = zpt_obs - 24.611;3434 break;3435 case 'z':3436 zp_z = zpt_obs - 24.240;3437 break;3438 case 'y':3439 zp_y = zpt_obs - 23.320;3440 break;3441 case 'w':3442 zp_w = zpt_obs - 26.000;3443 break;3444 }3445 3446 return [3447 parseFloat(mjd), // MJD value3448 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),3449 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),3450 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),3451 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),3452 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),3453 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)3454 ];3455 });3456 3457 data.addRows(rows);3458 3459 const options = {3460 title: 'Zeropoint zoom-in (MJD)',3461 titleTextStyle: { color: 'black', fontSize: 15 },3462 width: '100%',3463 height: 480,3464 legend: { position: 'top', alignment: 'start', maxLines: 3 },3465 series: {3466 0: { color: '#00f000', pointSize: 10, pointShape: 'circle', linewidth: 1}, // 'g' filter3467 1: { color: '#f00000', pointSize: 10, pointShape: 'triangle', linewidth: 1}, // 'r' filter3468 2: { color: '#f05000', pointSize: 10, pointShape: 'square', linewidth: 1}, // 'i' filter3469 3: { color: '#0050a0', pointSize: 10, pointShape: 'diamond', linewidth: 1}, // 'z' filter3470 4: { color: '#ffe000', pointSize: 10, pointShape: 'star', linewidth: 1}, // 'y' filter3471 5: { color: '#808080', pointSize: 10, pointShape: 'polygon', linewidth: 1}, // 'w' filter3472 },3473 intervals: { color: 'red', lineWidth: 1, style: 'sticks' },3474 hAxis: {3475 title: 'MJD',3476 gridlines: { count: -1 }3477 },3478 vAxis: {3479 title: 'Zeropoint (mag)',3480 viewWindow: { min: -1.00, max: .5 },3481 },3482 tooltip: { isHtml: true },3483 chartArea: { left: '9%', top: 60, right: '5%', bottom: 50 },3484 fontSize: 12,3485 };3486 3487 const chart = new google.visualization.LineChart(document.getElementById('dq_div_zoomzpt'));3488 chart.draw(data, options);3489 }3490 3491 // draw zeropoint vs mjd3492 function drawZPTChart() {3493 var data = new google.visualization.DataTable();3494 data.addColumn('number', 'MJD');3495 3496 // Add columns for each filter type to handle separate colors3497 data.addColumn('number', 'g' );3498 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3499 data.addColumn({type: 'number', role: 'interval'});3500 data.addColumn({type: 'number', role: 'interval'});3501 data.addColumn('number', 'r' );3502 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3503 data.addColumn({type: 'number', role: 'interval'});3504 data.addColumn({type: 'number', role: 'interval'});3505 data.addColumn('number', 'i' );3506 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3507 data.addColumn({type: 'number', role: 'interval'});3508 data.addColumn({type: 'number', role: 'interval'});3509 data.addColumn('number', 'z' );3510 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3511 data.addColumn({type: 'number', role: 'interval'});3512 data.addColumn({type: 'number', role: 'interval'});3513 data.addColumn('number', 'y' );3514 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3515 data.addColumn({type: 'number', role: 'interval'});3516 data.addColumn({type: 'number', role: 'interval'});3517 data.addColumn('number', 'w' );3518 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});3519 data.addColumn({type: 'number', role: 'interval'});3520 data.addColumn({type: 'number', role: 'interval'});3521 3522 // Count occurrences of each filter3523 const filterCounts = { g: 0, r: 0, i: 0, z: 0, y: 0, w: 0 };3524 const rows = dataArray.map(row => {3525 const [timestamp, mjd, filter, comment, ra, dec, exp_name, alt, az, iq_fwhm_maj, iq_fwhm_min, zpt_obs, zpt_stdev, exp_id] = row;3526 3527 // Initialize all filter values as null3528 let zp_g = null, zp_r = null, zp_i = null, zp_z = null, zp_y = null, zp_w = null;3529 3530 // Increment the count for the filter3531 if (filterCounts.hasOwnProperty(filter[0])) {3532 filterCounts[filter[0]] += 1;3533 }3534 3535 // Set the zeropoint offset based on filter and assign it to the correct series3536 switch (filter[0]) {3537 case 'g':3538 zp_g = zpt_obs - 0.0;3539 break;3540 case 'r':3541 zp_r = zpt_obs - 0.0;3542 break;3543 case 'i':3544 zp_i = zpt_obs - 0.0;3545 break;3546 case 'z':3547 zp_z = zpt_obs - 0.0;3548 break;3549 case 'y':3550 zp_y = zpt_obs - 0.0;3551 break;3552 case 'w':3553 zp_w = zpt_obs - 0.0;3554 break;3555 }3556 3557 return [3558 parseFloat(mjd), // MJD value3559 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),3560 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),3561 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),3562 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),3563 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),3564 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),3565 3566 ];3567 });3568 data.addRows(rows);3569 3570 // Include counts in the title using string concatenation3571 const countsTitle = 'Zeropoint (MJD) g: ' + filterCounts.g + ', r: ' + filterCounts.r + ', i: ' + filterCounts.i + ', z: ' + filterCounts.z + ', y: ' + filterCounts.y + ', w: ' + filterCounts.w;3572 3573 3574 console.log(countsTitle);3575 3576 const options = {3577 title: countsTitle,3578 titleTextStyle: { color: 'black', fontSize: 15 },3579 width: '100%',3580 height: 480,3581 legend: { position: 'top', alignment: 'center' },3582 series: {3583 0: { color: '#00f000', pointSize: 10, pointShape: 'circle', linewidth: 1}, // 'g' filter3584 1: { color: '#f00000', pointSize: 10, pointShape: 'triangle', linewidth: 1}, // 'r' filter3585 2: { color: '#f05000', pointSize: 10, pointShape: 'square', linewidth: 1}, // 'i' filter3586 3: { color: '#0050a0', pointSize: 10, pointShape: 'diamond', linewidth: 1}, // 'z' filter3587 4: { color: '#ffe000', pointSize: 10, pointShape: 'star', linewidth: 1}, // 'y' filter3588 5: { color: '#808080', pointSize: 10, pointShape: 'polygon', linewidth: 1}, // 'w' filter3589 },3590 intervals: { color: 'red', lineWidth: 1, style: 'sticks' },3591 hAxis: {3592 title: 'MJD',3593 gridlines: { count: -1 }3594 },3595 vAxis: {3596 title: 'Zeropoint (mag)'3597 },3598 tooltip: { isHtml: true },3599 chartArea: { left: '9%', top: 60, right: '5%', bottom: 50 },3600 fontSize: 12,3601 };3602 3603 const chart = new google.visualization.LineChart(document.getElementById('dq_div_zpt'));3604 chart.draw(data, options);3605 }3606 3607 google.charts.setOnLoadCallback(drawFWHMChart);3608 google.charts.setOnLoadCallback(drawZPTChart);3609 google.charts.setOnLoadCallback(drawZOOMZPTChart);3610 3611 </script>3612 3613 <div class="chartWithOverlay" style="position: relative; width: 640px; height:500px;">3614 <div id="dq_div_fwhm" style="width:640px;"></div>3615 <div class="overlay" style="position: absolute; width: 400px; bottom: 60px; left: 85px;"></div>3616 </div>3617 3618 <div class="chartWithOverlay" style="position: relative; width: 640px; height:500px;">3619 <div id="dq_div_zpt" style="width:640px;"></div>3620 <div class="overlay" style="position: absolute; width: 400px; bottom: 60px; left: 85px;"></div>3621 </div>3622 3623 <div class="chartWithOverlay" style="position: relative; width: 640px; height:500px;">3624 <div id="dq_div_zoomzpt" style="width:640px;"></div>3625 <div class="overlay" style="position: absolute; width: 400px; bottom: 60px; left: 85px;"></div>3626 </div>3627 3628 HTML;3629 // End timer3630 $total_time = round(microtime(true) - $start, 3);3631 echo "<center>loading plot in $total_time seconds<br></center>";3632 3633 }3634 3635 3636 3637 2842 function getprocrate ($proc1, $proc0, $trange) { 3638 2843 if($proc1 > $proc0) { … … 3646 2851 3647 2852 3648 3649 2853 ?> -
trunk/ippMonitor/raw/dataquality.php
r42795 r42972 15 15 else {$myMenu = "ipp.czar.dat";} 16 16 17 menu($myMenu, 'Czartool on '.$lastUpdateTime, 'ipp.css', $ID['link'], $ID['proj']);17 menu($myMenu, 'Czartool on', ' ipp.css', $ID['link'], $ID['proj']); 18 18 19 19 $pass = $ID['pass']; … … 22 22 23 23 // Fetch data based on range selection 24 $range = isset($_GET['range']) ? $_GET['range'] : 'yday'; 24 $range = isset($_GET['range']) ? $_GET['range'] : 'week'; 25 26 require_once 'functions.php'; 25 27 26 28 echo "<table border=\"0\">"; … … 28 30 echo " <td style=width:1240>"; 29 31 echo " <h1 align=\"middle\">Data Quality Report</h1>"; 30 echo " <center>"; 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> '; 32 33 # 34 # project selector 35 echo '<center>'; 36 # Project selector with highlight 37 $projects = ["gpc1" => "GPC1", "gpc2" => "GPC2"]; 38 foreach ($projects as $key => $label) { 39 if ($proj == $key) { 40 echo "<strong style='color:blue;'>$label</strong> | "; 41 } else { 42 echo '<a href="?pass=' . urlencode($pass) . '&proj=' . $key . '&range=' . urlencode($range) . '">' . $label . '</a> | '; 43 } 44 } 45 echo "<br>"; 46 47 # range links with highlighting 48 $ranges = [ 49 "today" => "Today", 50 "yesterday" => "Yesterday", 51 "week" => "Week", 52 "month" => "Month", 53 "year" => "Year", 54 "all" => "All" 55 ]; 56 57 foreach ($ranges as $key => $label) { 58 if ($range == $key) { 59 echo "<strong style='color:blue;'>$label</strong> | "; 60 } else { 61 echo '<a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=' . $key . '">' . $label . '</a> | '; 62 } 63 } 64 37 65 echo " </td>"; 38 66 echo "</tr>"; 39 67 echo "</table>"; 40 echo getDataQuality($projectdb, $range); 68 69 echo " <div style=\"margin-bottom:10px; font-size:14px; color:#555;\">"; 70 echo " Current MJD: " . getMJD(); 71 echo " </div>"; 72 73 echo getDataQuality($projectdb, $range, $proj); 41 74 42 75 menu_end(); 43 76 44 /////////////////////////////////////////////////////////////////////////////45 // //46 // Functions //47 // //48 /////////////////////////////////////////////////////////////////////////////49 50 ###########################################################################51 #52 # Get data quality53 #54 ###########################################################################55 function getDataQuality($db, $range = 'yday') {56 // Start timer57 $start = microtime(true);58 59 $mjdDay = getMJD();60 $mjdDay_yearback = $mjdDay - 366;61 $mjdDay_monthback = $mjdDay - 32;62 $min_exp_id = 0;63 64 // Determine the reference exp_name based on the selected range65 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 night80 break;81 }82 83 // Query to get the minimum exp_id84 $expIdQuery = "SELECT MIN(exp_id) AS min_exp_id FROM rawExp WHERE rawExp.exp_name LIKE '$expname'";85 $result = $db->query($expIdQuery);86 87 if (DB::isError($result)) {88 die("Database error: " . $result->getMessage());89 }90 91 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);92 93 if (!empty($row['min_exp_id'])) {94 $min_exp_id = $row['min_exp_id'];95 // echo "Minimum exp_id: " . $min_exp_id;96 } else {97 echo "No results found.";98 }99 100 //echo "<br><br>";101 102 // Determine the date constraint based on the range103 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 night127 $dateConstraint = "rawExp.exp_name LIKE 'o" . ($mjdDay - 1) . "%' AND rawExp.exp_id >= $min_exp_id";128 break;129 }130 131 // Updated SQL query132 $sql = "select * from (SELECT SUBTIME(dateobs, '10:00:00') AS time,133 round(( 367*YEAR(dateobs)- FLOOR((7 * (YEAR(dateobs) + FLOOR((MONTH(dateobs) + 9) / 12))) / 4) + FLOOR(275 * MONTH(dateobs) / 9)134 + DAY(dateobs) + 1721013.5 + (HOUR(dateobs) / 24.0) + (MINUTE(dateobs) / 1440.0) + (SECOND(dateobs) / 86400.0) - 2400000.5), 5) AS MJD,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.label136 FROM rawExp137 JOIN chipRun USING (exp_id)138 JOIN camRun USING (chip_id)139 JOIN camProcessedExp USING (cam_id)140 WHERE $dateConstraint141 AND exp_type = 'OBJECT'142 AND camRun.state LIKE 'full'143 AND camProcessedExp.fault = 0144 AND camProcessedExp.zpt_obs != 0 ORDER BY RAND() limit 5000) as sub order by time;";145 146 $DQarray = array();147 $qry = $db->query($sql);148 if (dberror($qry)) {149 echo "<b>Error with $sql</b><br>\n";150 return;151 }152 // echo "$sql<br><br>\n";153 154 while ($qry->fetchInto($row)) {155 $DQarray[] = $row;156 }157 158 // Ensure $DQarray is not empty159 if (empty($DQarray)) {160 echo "<center><b> No data for MJD: $mjdDay </b></center>";161 return; // Stop execution if no data to encode162 }163 164 // Convert data array to JSON for easier handling in JavaScript165 $dataJson = json_encode($DQarray);166 167 if ($dataJson === false) {168 echo "<b>Error encoding JSON:</b> " . json_last_error_msg(); // Display any JSON encoding errors169 return; // Stop execution if JSON encoding fails170 }171 172 echo "<script>console.log(" . json_encode($dataJson) . ");</script>"; // Log JSON output to console for debugging173 echo <<<HTML174 <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 successfully178 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 fails185 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 file189 document.head.appendChild(script);190 }191 </script>192 193 <script type="text/javascript">194 google.charts.load('current', {packages: ['corechart']});195 196 // Use the encoded JSON directly in JavaScript197 const dataArray = JSON.parse('{$dataJson}'); // Directly parse the PHP JSON string198 199 // draw FWHM vs MJD200 function drawFWHMChart() {201 var data = new google.visualization.DataTable();202 data.addColumn('number', 'MJD');203 data.addColumn('number', 'FWHM_major');204 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});205 data.addColumn('number', 'FWHM_minor');206 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});207 data.addColumn('number', 'seeing ~ 1"');208 data.addColumn('number', 'seeing ~ 3"');209 210 const rows = dataArray.map(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;212 213 return [214 parseFloat(mjd), // Position Angle215 parseFloat(iq_fwhm_maj), // RA_offset (AST_R0)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,217 parseFloat(iq_fwhm_min), // Dec_offset (AST_D0)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,219 4,220 12221 ];222 });223 224 data.addRows(rows);225 226 // Extract the first MJD value from dataArray227 //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 231 const options = {232 title: 'FWHM (MJD: '+firstMJD+')',233 titleTextStyle: {color: 'black', fontSize: 15},234 width: '100%',235 height: 480,236 legend: { position: 'top', alignment: 'center' },237 series: {238 0: { color: '#0000ff', pointSize: 2, lineWidth: 0. },239 1: { color: '#33a532', pointSize: 2, lineWidth: 0. },240 2: { color: 'red', lineWidth: 2, pointSize: 0 },241 3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }242 },243 intervals: { color: 'red', lineWidth: 2, style: 'sticks' },244 hAxis: {245 title: 'MJD',246 gridlines: {count: -1}247 },248 vAxis: {249 title: 'FWHM (pixels)',250 },251 tooltip: { isHtml: true }, // Render tooltips as HTML252 chartArea: {left: '8%', top: 60, right: '5%', bottom: 50}, // Adjust left and right253 fontSize: 12,254 };255 256 const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_fwhm'));257 chart.draw(data, options);258 }259 260 // draw zoomed zerpoint vs mjd261 function drawZOOMZPTChart() {262 var data = new google.visualization.DataTable();263 data.addColumn('number', 'MJD');264 265 // Add columns for each filter type to handle separate colors266 data.addColumn('number', 'g (24.563, 25.013)');267 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});268 data.addColumn({type: 'number', role: 'interval'});269 data.addColumn({type: 'number', role: 'interval'});270 data.addColumn('number', 'r (24.750, 24.840)');271 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});272 data.addColumn({type: 'number', role: 'interval'});273 data.addColumn({type: 'number', role: 'interval'});274 data.addColumn('number', 'i (24.611, 24.711)');275 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});276 data.addColumn({type: 'number', role: 'interval'});277 data.addColumn({type: 'number', role: 'interval'});278 data.addColumn('number', 'z (24.240, 24.300)');279 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});280 data.addColumn({type: 'number', role: 'interval'});281 data.addColumn({type: 'number', role: 'interval'});282 data.addColumn('number', 'y (23.320, 23.570)');283 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});284 data.addColumn({type: 'number', role: 'interval'});285 data.addColumn({type: 'number', role: 'interval'});286 data.addColumn('number', 'w (26.000, 26.300)');287 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});288 data.addColumn({type: 'number', role: 'interval'});289 data.addColumn({type: 'number', role: 'interval'});290 291 const rows = dataArray.map(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;293 294 // Initialize all filter values as null295 let zp_g = null, zp_r = null, zp_i = null, zp_z = null, zp_y = null, zp_w = null;296 297 // Set the zeropoint offset based on filter and assign it to the correct series298 switch (filter[0]) {299 case 'g':300 zp_g = zpt_obs - 24.563;301 break;302 case 'r':303 zp_r = zpt_obs - 24.750;304 break;305 case 'i':306 zp_i = zpt_obs - 24.611;307 break;308 case 'z':309 zp_z = zpt_obs - 24.240;310 break;311 case 'y':312 zp_y = zpt_obs - 23.320;313 break;314 case 'w':315 zp_w = zpt_obs - 26.000;316 break;317 }318 319 return [320 parseFloat(mjd), // MJD value321 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)333 ];334 });335 336 data.addRows(rows);337 338 const options = {339 title: 'Zeropoint zoom-in (MJD)',340 titleTextStyle: { color: 'black', fontSize: 15 },341 width: '100%',342 height: 480,343 legend: { position: 'top', alignment: 'start', maxLines: 3 },344 series: {345 0: { color: '#00f000', pointSize: 5, pointShape: 'circle', linewidth: .0}, // 'g' filter346 1: { color: '#f00000', pointSize: 5, pointShape: 'triangle', linewidth: .0}, // 'r' filter347 2: { color: '#f05000', pointSize: 5, pointShape: 'square', linewidth: .0}, // 'i' filter348 3: { color: '#0050a0', pointSize: 5, pointShape: 'diamond', linewidth: .0}, // 'z' filter349 4: { color: '#ffe000', pointSize: 5, pointShape: 'star', linewidth: .0}, // 'y' filter350 5: { color: '#808080', pointSize: 5, pointShape: 'polygon', linewidth: .0}, // 'w' filter351 },352 intervals: { color: 'red', lineWidth: .0, style: 'sticks' },353 hAxis: {354 title: 'MJD',355 gridlines: { count: -1 }356 },357 vAxis: {358 title: 'Zeropoint (mag)',359 viewWindow: { min: -1.00, max: .5 },360 },361 tooltip: { isHtml: true },362 chartArea: { left: '9%', top: 60, right: '5%', bottom: 50 },363 fontSize: 12,364 };365 366 const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_zoomzpt'));367 chart.draw(data, options);368 }369 370 // draw zeropoint vs mjd371 function drawZPTChart() {372 var data = new google.visualization.DataTable();373 data.addColumn('number', 'MJD');374 375 // Add columns for each filter type to handle separate colors376 data.addColumn('number', 'g' );377 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});378 data.addColumn({type: 'number', role: 'interval'});379 data.addColumn({type: 'number', role: 'interval'});380 data.addColumn('number', 'r' );381 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});382 data.addColumn({type: 'number', role: 'interval'});383 data.addColumn({type: 'number', role: 'interval'});384 data.addColumn('number', 'i' );385 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});386 data.addColumn({type: 'number', role: 'interval'});387 data.addColumn({type: 'number', role: 'interval'});388 data.addColumn('number', 'z' );389 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});390 data.addColumn({type: 'number', role: 'interval'});391 data.addColumn({type: 'number', role: 'interval'});392 data.addColumn('number', 'y' );393 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});394 data.addColumn({type: 'number', role: 'interval'});395 data.addColumn({type: 'number', role: 'interval'});396 data.addColumn('number', 'w' );397 data.addColumn({type: 'string', role: 'tooltip', 'p': {'html': true}});398 data.addColumn({type: 'number', role: 'interval'});399 data.addColumn({type: 'number', role: 'interval'});400 401 // Count occurrences of each filter402 const filterCounts = { g: 0, r: 0, i: 0, z: 0, y: 0, w: 0 };403 const rows = dataArray.map(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;405 406 // Initialize all filter values as null407 let zp_g = null, zp_r = null, zp_i = null, zp_z = null, zp_y = null, zp_w = null;408 409 // Increment the count for the filter410 if (filterCounts.hasOwnProperty(filter[0])) {411 filterCounts[filter[0]] += 1;412 }413 414 // Set the zeropoint offset based on filter and assign it to the correct series415 switch (filter[0]) {416 case 'g':417 zp_g = zpt_obs - 0.0;418 break;419 case 'r':420 zp_r = zpt_obs - 0.0;421 break;422 case 'i':423 zp_i = zpt_obs - 0.0;424 break;425 case 'z':426 zp_z = zpt_obs - 0.0;427 break;428 case 'y':429 zp_y = zpt_obs - 0.0;430 break;431 case 'w':432 zp_w = zpt_obs - 0.0;433 break;434 }435 436 return [437 parseFloat(mjd), // MJD value438 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),450 ];451 });452 data.addRows(rows);453 454 // Include counts in the title using string concatenation455 const countsTitle = 'Zeropoint (MJD) g: ' + filterCounts.g + ', r: ' + filterCounts.r + ', i: ' + filterCounts.i + ', z: ' + filterCounts.z + ', y: ' + filterCounts.y + ', w: ' + filterCounts.w;456 457 458 console.log(countsTitle);459 460 const options = {461 title: countsTitle,462 titleTextStyle: { color: 'black', fontSize: 15 },463 width: '100%',464 height: 480,465 legend: { position: 'top', alignment: 'center' },466 series: {467 0: { color: '#00f000', pointSize: 5, pointShape: 'circle', linewidth: 1}, // 'g' filter468 1: { color: '#f00000', pointSize: 5, pointShape: 'triangle', linewidth: 1}, // 'r' filter469 2: { color: '#f05000', pointSize: 5, pointShape: 'square', linewidth: 1}, // 'i' filter470 3: { color: '#0050a0', pointSize: 5, pointShape: 'diamond', linewidth: 1}, // 'z' filter471 4: { color: '#ffe000', pointSize: 5, pointShape: 'star', linewidth: 1}, // 'y' filter472 5: { color: '#808080', pointSize: 5, pointShape: 'polygon', linewidth: 1}, // 'w' filter473 },474 intervals: { color: 'red', lineWidth: 0, style: 'sticks' },475 hAxis: {476 title: 'MJD',477 gridlines: { count: -1 }478 },479 vAxis: {480 title: 'Zeropoint (mag)'481 },482 tooltip: { isHtml: true },483 chartArea: { left: '9%', top: 60, right: '5%', bottom: 50 },484 fontSize: 12,485 };486 487 const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_zpt'));488 chart.draw(data, options);489 }490 491 google.charts.setOnLoadCallback(drawFWHMChart);492 google.charts.setOnLoadCallback(drawZPTChart);493 google.charts.setOnLoadCallback(drawZOOMZPTChart);494 495 </script>496 497 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">498 <div id="dq_div_fwhm" style="width:100%;"></div>499 <div class="overlay" style="position: absolute; width: 400px; bottom: 60px; left: 85px;"></div>500 </div>501 502 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">503 <div id="dq_div_zpt" style="width:100%;"></div>504 <div class="overlay" style="position: absolute; width: 400px; bottom: 60px; left: 85px;"></div>505 </div>506 507 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">508 <div id="dq_div_zoomzpt" style="width:100%;"></div>509 <div class="overlay" style="position: absolute; width: 400px; bottom: 60px; left: 85px;"></div>510 </div>511 512 HTML;513 // End timer514 $total_time = round(microtime(true) - $start, 3);515 echo "<center>loading plot in $total_time seconds<br></center>";516 517 }518 519 520 521 77 ?> 522 78 -
trunk/ippMonitor/raw/pointing.php
r42795 r42972 15 15 else {$myMenu = "ipp.czar.dat";} 16 16 17 menu($myMenu, 'Czartool on ' .$lastUpdateTime, 'ipp.css', $ID['link'], $ID['proj']);17 menu($myMenu, 'Czartool on ', 'ipp.css', $ID['link'], $ID['proj']); 18 18 19 19 $pass = $ID['pass']; … … 22 22 23 23 // Fetch data based on range selection 24 $range = isset($_GET['range']) ? $_GET['range'] : 'yday'; 24 $range = isset($_GET['range']) ? $_GET['range'] : 'week'; 25 26 require_once 'functions.php'; 25 27 26 28 echo "<table border=\"0\">"; 27 29 echo "<tr>"; 28 30 echo " <td style=width:1240>"; 29 echo " <h1 align=\"middle\">Pointing Report</h1>"; 30 echo " <center>"; 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> '; 31 echo " <h1 align=\"middle\">Data Quality Report</h1>"; 32 33 # 34 # project selector 35 echo '<center>'; 36 # Project selector with highlight 37 $projects = ["gpc1" => "GPC1", "gpc2" => "GPC2"]; 38 foreach ($projects as $key => $label) { 39 if ($proj == $key) { 40 echo "<strong style='color:blue;'>$label</strong> | "; 41 } else { 42 echo '<a href="?pass=' . urlencode($pass) . '&proj=' . $key . '&range=' . urlencode($range) . '">' . $label . '</a> | '; 43 } 44 } 45 echo "<br>"; 46 47 # range links with highlighting 48 $ranges = [ 49 "today" => "Today", 50 "yesterday" => "Yesterday", 51 "week" => "Week", 52 "month" => "Month", 53 "year" => "Year", 54 "all" => "All" 55 ]; 56 57 foreach ($ranges as $key => $label) { 58 if ($range == $key) { 59 echo "<strong style='color:blue;'>$label</strong> | "; 60 } else { 61 echo '<a href="?pass=' . urlencode($pass) . '&proj=' . urlencode($proj) . '&range=' . $key . '">' . $label . '</a> | '; 62 } 63 } 64 37 65 echo " </td>"; 38 66 echo "</tr>"; 39 67 echo "</table>"; 40 echo getPointing($projectdb, $range);41 68 69 echo " <div style=\"margin-bottom:10px; font-size:14px; color:#555;\">"; 70 echo " Current MJD: " . getMJD(); 71 echo " </div>"; 72 73 echo getPointing($projectdb, $range, $proj); 42 74 menu_end(); 43 44 45 /////////////////////////////////////////////////////////////////////////////46 // //47 // Functions //48 // //49 /////////////////////////////////////////////////////////////////////////////50 ###########################################################################51 #52 # Get data quality53 #54 ###########################################################################55 function getPointing($db, $range = 'yday') {56 // Start timer57 $start = microtime(true);58 59 $mjdDay = getMJD();60 $mjdDay_yearback = $mjdDay - 366;61 $mjdDay_monthback = $mjdDay - 32;62 $min_exp_id = 0;63 64 // Determine the reference exp_name based on the selected range65 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 night80 break;81 }82 83 // Query to get the minimum exp_id84 $expIdQuery = "SELECT MIN(exp_id) AS min_exp_id FROM rawExp WHERE rawExp.exp_name LIKE '$expname'";85 $result = $db->query($expIdQuery);86 87 if (DB::isError($result)) {88 die("Database error: " . $result->getMessage());89 }90 91 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);92 93 if (!empty($row['min_exp_id'])) {94 $min_exp_id = $row['min_exp_id'];95 // echo "Minimum exp_id: " . $min_exp_id;96 } else {97 echo "No results found.";98 }99 100 //echo "<br><br>";101 102 // Determine the date constraint based on the range103 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 night127 $dateConstraint = "rawExp.exp_name LIKE 'o" . ($mjdDay - 1) . "%' AND rawExp.exp_id >= $min_exp_id";128 break;129 }130 131 // Updated SQL query132 $sql = "select * from (SELECT SUBTIME(dateobs, '10:00:00') AS time, AST_R0, AST_D0,133 round(( 367*YEAR(dateobs)- FLOOR((7 * (YEAR(dateobs) + FLOOR((MONTH(dateobs) + 9) / 12))) / 4) + FLOOR(275 * MONTH(dateobs) / 9)134 + DAY(dateobs) + 1721013.5 + (HOUR(dateobs) / 24.0) + (MINUTE(dateobs) / 1440.0) + (SECOND(dateobs) / 86400.0) - 2400000.5), 5) AS MJD,135 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, camRun.label136 FROM rawExp137 JOIN chipRun USING (exp_id)138 JOIN camRun USING (chip_id)139 JOIN camProcessedExp USING (cam_id)140 WHERE $dateConstraint141 AND exp_type = 'OBJECT'142 AND camRun.state LIKE 'full'143 AND camProcessedExp.fault = 0144 AND camProcessedExp.zpt_obs != 0 ORDER BY RAND() limit 5000) as sub order by time;";145 146 $DQarray = array();147 $qry = $db->query($sql);148 if (dberror($qry)) {149 echo "<b>Error with $sql</b><br>\n";150 return;151 }152 // echo "$sql<br><br>\n";153 154 while ($qry->fetchInto($row)) {155 $DQarray[] = $row;156 }157 158 // Ensure $DQarray is not empty159 if (empty($DQarray)) {160 echo "<center><b> No data for MJD: $mjdDay </b></center>";161 return; // Stop execution if no data to encode162 }163 164 // Convert data array to JSON for easier handling in JavaScript165 $dataJson = json_encode($DQarray);166 167 if ($dataJson === false) {168 echo "<b>Error encoding JSON:</b> " . json_last_error_msg(); // Display any JSON encoding errors169 return; // Stop execution if JSON encoding fails170 }171 172 echo "<script>console.log(" . json_encode($dataJson) . ");</script>"; // Log JSON output to console for debugging173 echo <<<HTML174 <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 successfully178 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 fails185 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 file189 document.head.appendChild(script);190 }191 </script>192 193 <script type="text/javascript">194 google.charts.load('current', {packages: ['corechart']});195 196 // Use the encoded JSON directly in JavaScript197 const dataArray = JSON.parse('{$dataJson}'); // Directly parse the PHP JSON string198 199 // draw pointing vs mjd200 function drawMJDChart() {201 var data = new google.visualization.DataTable();202 data.addColumn('number', 'MJD');203 data.addColumn('number', 'RA_offset (AST_R0)');204 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});205 data.addColumn('number', 'Dec_offset (AST_D0)');206 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});207 data.addColumn('number', '20 TP unit ~5.1"');208 data.addColumn('number', '-20 TP unit ~5.1"');209 210 const rows = dataArray.map(row => {211 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, cam_label] = row;212 213 return [214 parseFloat(mjd), // MJD215 parseFloat(ra_offset), // RA_offset (AST_R0)216 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,217 parseFloat(dec_offset), // Dec_offset (AST_D0)218 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,219 20, // Dummy value for 20 TP unit220 -20 // Dummy value for -20 TP unit221 ];222 });223 224 data.addRows(rows);225 226 // Extract the first MJD value from dataArray227 //const firstMJD = dataArray.length > 0 ? parseFloat(dataArray[0][1]) : "N/A";228 const firstMJD = dataArray.length > 0 ? Math.floor(parseFloat(dataArray[0][3])) : "N/A";229 console.log("First MJD Value:", firstMJD);230 231 const options = {232 title: 'Pointing Offset (MJD: '+firstMJD+')',233 titleTextStyle: {color: 'black', fontSize: 15},234 width: '100%',235 height: 480,236 legend: { position: 'top', alignment: 'center' },237 series: {238 0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series239 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series240 2: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }, // Line at y = 20241 3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 } // Line at y = -20242 },243 intervals: { color: 'red', lineWidth: 2, style: 'sticks' },244 hAxis: {245 title: 'MJD',246 gridlines: {count: -1}247 },248 vAxis: {249 title: 'Offset (TP units)',250 },251 tooltip: { isHtml: true }, // Render tooltips as HTML252 chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right253 fontSize: 15,254 };255 256 const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_mjd'));257 chart.draw(data, options);258 }259 260 // draw pointing scatter261 function drawSIGChart() {262 var data = new google.visualization.DataTable();263 data.addColumn('number', 'MJD');264 data.addColumn('number', 'RA_offset_scatter (AST_RS)');265 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});266 data.addColumn('number', 'Dec_offset_scatter (AST_DS)');267 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});268 269 const rows = dataArray.map(row => {270 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, cam_label] = row;271 272 return [273 parseFloat(mjd), // MJD274 parseFloat(ra_offset_sig), // RA_offset_scatter (AST_RS)275 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,276 parseFloat(dec_offset_sig), // Dec_offset_scatter (AST_DS)277 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,278 ];279 });280 281 data.addRows(rows);282 283 const options = {284 title: 'Pointing Offset Scatter (MJD)',285 titleTextStyle: {color: 'black', fontSize: 15},286 width: '100%',287 height: 480,288 legend: { position: 'top', alignment: 'center' },289 series: {290 0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series291 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series292 2: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 }, // Line at y = 20293 3: { color: 'red', lineWidth: 2, lineDashStyle: [8, 4], pointSize: 0 } // Line at y = -20294 },295 intervals: { color: 'red', lineWidth: 2, style: 'sticks' },296 hAxis: {297 title: 'MJD',298 gridlines: {count: -1}299 },300 vAxis: {301 title: 'Offset Scatter (TP units)',302 },303 tooltip: { isHtml: true }, // Render tooltips as HTML304 chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right305 fontSize: 15,306 };307 308 const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_sig'));309 chart.draw(data, options);310 }311 312 313 // position angle314 function drawPOSChart() {315 var data = new google.visualization.DataTable();316 data.addColumn('number', 'MJD');317 data.addColumn('number', 'RA_offset (AST_R0)');318 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});319 data.addColumn('number', 'Dec_offset (AST_D0)');320 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});321 322 const rows = dataArray.map(row => {323 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, cam_label] = row;324 325 return [326 parseFloat(position_ang), // Position Angle327 parseFloat(ra_offset), // RA_offset (AST_R0)328 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,329 parseFloat(dec_offset), // Dec_offset (AST_D0)330 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,331 ];332 });333 334 data.addRows(rows);335 336 const options = {337 title: 'Pointing Offset (Position Angle)',338 titleTextStyle: {color: 'black', fontSize: 15},339 width: '100%',340 height: 480,341 legend: { position: 'top', alignment: 'center' },342 // pointSize: 5, // Point size for scatter plot343 // lineWidth: 2,344 series: {345 0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series346 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series347 },348 intervals: { color: 'red', lineWidth: 2, style: 'sticks' },349 hAxis: {350 title: 'Position Angle',351 gridlines: {count: -1}352 },353 vAxis: {354 title: 'Offset (TP units)',355 },356 tooltip: { isHtml: true }, // Render tooltips as HTML357 chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right358 fontSize: 15,359 };360 361 const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_pos'));362 chart.draw(data, options);363 }364 365 function drawALTChart() {366 var data = new google.visualization.DataTable();367 data.addColumn('number', 'Altitute');368 data.addColumn('number', 'RA_offset (AST_R0)');369 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});370 data.addColumn('number', 'Dec_offset (AST_D0)');371 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});372 373 const rows = dataArray.map(row => {374 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, cam_label] = row;375 376 return [377 parseFloat(alt), // Position Angle378 parseFloat(ra_offset), // RA_offset (AST_R0)379 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,380 parseFloat(dec_offset), // Dec_offset (AST_D0)381 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,382 ];383 });384 385 data.addRows(rows);386 387 const options = {388 title: 'Pointing Offset (Altitude)',389 titleTextStyle: {color: 'black', fontSize: 15},390 width: '100%',391 height: 480,392 legend: { position: 'top', alignment: 'center' },393 series: {394 0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series395 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series396 },397 intervals: { color: 'red', lineWidth: 2, style: 'sticks' },398 hAxis: {399 title: 'Altitude',400 gridlines: {count: -1}401 },402 vAxis: {403 title: 'Offset (TP units)',404 },405 tooltip: { isHtml: true }, // Render tooltips as HTML406 //chartArea: {left: 80, top: 50, right: 20, bottom: 50},407 chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right408 fontSize: 15,409 };410 411 const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_alt'));412 chart.draw(data, options);413 }414 415 function drawAZChart() {416 var data = new google.visualization.DataTable();417 data.addColumn('number', 'Azumith');418 data.addColumn('number', 'RA_offset (AST_R0)');419 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});420 data.addColumn('number', 'Dec_offset (AST_D0)');421 data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});422 423 const rows = dataArray.map(row => {424 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, cam_label] = row;425 426 return [427 parseFloat(az), // Position Angle428 parseFloat(ra_offset), // RA_offset (AST_R0)429 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,430 parseFloat(dec_offset), // Dec_offset (AST_D0)431 "expname: "+exp_name+"<br>exp_id: "+exp_id+"<br>timestamp: "+timestamp+"<br>RA: "+ra+"<br>DEC: "+dec+"<br>filter: "+filter+"<br>comment: "+comment+"<br>cam_label: "+cam_label,432 ];433 });434 435 data.addRows(rows);436 437 const options = {438 title: 'Pointing Offset (Azumith)',439 titleTextStyle: {color: 'black', fontSize: 15},440 width: '100%',441 height: 480,442 legend: { position: 'top', alignment: 'center' },443 series: {444 0: { color: '#0000ff', pointSize: 3, lineWidth: 0 }, // RA_offset series445 1: { color: '#33a532', pointSize: 3, lineWidth: 0 }, // Dec_offset series446 },447 intervals: { color: 'red', lineWidth: 2, style: 'sticks' },448 hAxis: {449 title: 'Azumith',450 gridlines: {count: -1}451 },452 vAxis: {453 title: 'Offset (TP units)',454 },455 tooltip: { isHtml: true }, // Render tooltips as HTML456 //chartArea: {left: 80, top: 50, right: 20, bottom: 50},457 chartArea: {left: '7%', top: 60, right: '4%', bottom: 50}, // Adjust left and right458 fontSize: 15,459 };460 461 const chart = new google.visualization.ScatterChart(document.getElementById('dq_div_az'));462 chart.draw(data, options);463 }464 465 google.charts.setOnLoadCallback(drawMJDChart);466 google.charts.setOnLoadCallback(drawSIGChart);467 google.charts.setOnLoadCallback(drawPOSChart);468 google.charts.setOnLoadCallback(drawALTChart);469 google.charts.setOnLoadCallback(drawAZChart);470 </script>471 472 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">473 <div id="dq_div_mjd" style="width:1240px;"></div>474 <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>475 </div>476 477 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">478 <div id="dq_div_sig" style="width:1240px;"></div>479 <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>480 </div>481 482 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">483 <div id="dq_div_pos" style="width:1240px;"></div>484 <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>485 </div>486 487 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">488 <div id="dq_div_alt" style="width:1240px;"></div>489 <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>490 </div>491 492 <div class="chartWithOverlay" style="position: relative; width: 1240px; height:500px;">493 <div id="dq_div_az" style="width:1240px;"></div>494 <div class="overlay" style="position: absolute; width: 800px; bottom: 60px; left: 85px;"></div>495 </div>496 HTML;497 498 // End timer499 $total_time = round(microtime(true) - $start, 3);500 echo "<center>Loading plot in $total_time seconds<br></center>";501 502 }503 75 504 76 ?> -
trunk/ippMonitor/raw/storage.php
r42923 r42972 12 12 $projectdb = dbconnect($ID['proj']); 13 13 14 14 15 if ($ID['menu']) {$myMenu = $ID['menu'];} 15 16 else {$myMenu = "ipp.czar.dat";} 16 17 17 menu($myMenu, 'Czartool on ' .$lastUpdateTime, 'ipp.css', $ID['link'], $ID['proj']);18 menu($myMenu, 'Czartool on ', 'ipp.css', $ID['link'], $ID['proj']); 18 19 19 20 $pass = $ID['pass']; … … 25 26 echo " <td style=width:1200px>"; 26 27 echo " <h1 align=\"middle\">Storage status</h1>"; 28 29 require_once 'functions.php'; 30 27 31 # storage timeseries 28 32 echo getSpaces($czardb); … … 35 39 menu_end(); 36 40 37 38 /////////////////////////////////////////////////////////////////////////////39 // //40 // Functions //41 // //42 /////////////////////////////////////////////////////////////////////////////43 44 ###########################################################################45 #46 # Gets disk status47 #48 ###########################################################################49 function getHosts($db) {50 $start = microtime(true);51 52 53 // Set environment variables54 putenv("PATH=/usr/local/bin:/usr/bin:/bin:/data/ippc65.0/ipp/src/psconfig//ipp-20210708-gentoo.lin64/bin");55 putenv("PERL5LIB=/data/ippc65.0/ipp/src/psconfig//ipp-20210708-gentoo.lin64/lib");56 57 $hostnoteall = array();58 exec("neb-host |cut -b 17-30,86-", $hostnoteall);59 60 $sql = "SELECT host, format(total, 2), format(available, 2), format(used, 2), writable, readable, format(used/total*100,3) as ratio FROM hosts where xattr <> 3 ORDER BY CASE WHEN ROUND(used/total*100,3) = 100 THEN 0 ELSE 1 END, xattr, host;";61 $qry = $db->query($sql);62 63 if ($qry === false) {64 echo "<b>Error with SQL query</b><br>";65 return;66 }67 68 $sqlMax = "SELECT MAX(total) AS max_total FROM hosts WHERE xattr <> 3";69 $qryMax = $db->query($sqlMax);70 $maxUsed = 0;71 72 if ($qryMax && $qryMax->fetchInto($rowMax)) {73 $maxUsed = $rowMax[0]; // max_total value74 }75 76 $dataRows = array();77 while ($qry->fetchInto($row)) {78 // Access by index79 $host = $row[0]; // ipp071.080 $total = $row[1]; // 80.0352 TB81 $available = $row[2]; // 10.8096 TB82 $used = $row[3]; // 69.2256 TB83 $writable = $row[4]; // 084 $readable = $row[5]; // 185 $ratio = $row[6]; // 86.4939 %86 87 // Match notes88 $hostnotes = preg_grep("/$host/", $hostnoteall);89 $hostnote = reset($hostnotes);90 91 // Defaults92 $styles = "stroke-width: .5; stroke-color: black;";93 $status = "down";94 $usedColor = "lightgrey";95 $freeColor = "lightgrey";96 97 // Status logic98 if ($writable == 1 && $readable == 1) {99 $status = "up";100 $usedColor = ($ratio >= 97) ? "pink" : "yellow"; // red if â¥97%101 $freeColor = "#a6ec99"; // green free102 } elseif ($writable == 0 && $readable == 1) {103 $status = "repair";104 $usedColor = ($ratio >= 97) ? "pink" : "yellow";105 $freeColor = "lightgrey"; // grey free106 } elseif ($available < 1) {107 $used = $maxUsed;108 $available = 0;109 $status = "offline";110 $usedColor = "white";111 $freeColor = "white";112 }113 114 if ($status == "down") {115 $tooltipUsed = $host . ": " . round($ratio, 1) . "% of " . $total . " TB used ".116 "<span style='color:red; font-weight:bold;'> <br>" . $hostnote . "</span>";117 $tooltipFree = "<span style='color:red; font-weight:bold;'>" .118 $host . ": " . $available . " TB free" .119 "</span>";120 } elseif ($status == "offline") {121 $tooltipUsed = $host . ": " . round($ratio, 1) . "% of " . $total . " TB used ".122 "<span style='color:red; font-weight:bold;'> <br>" . $hostnote . "</span>";123 $tooltipFree = "<span style='color:red; font-weight:bold;'>" .124 $host . ": " . $total . " TB free" .125 "</span>";126 } else {127 $tooltipUsed = $host . ": " . round($ratio, 1) . "% of " . $total . " TB used<br>" . $hostnote ;128 $tooltipFree = $host . ": " . $available . " TB free";129 }130 131 132 // Build data row (manual string concatenation for old PHP)133 $dataRows[] =134 "[ \"" . $host . ":" . $status . "\", " .135 $used . ", \"" . $styles . " color: " . $usedColor . ";\", \"" . $tooltipUsed . "\", " .136 $available . ", \"" . $styles . " color: " . $freeColor . ";\", \"" . $tooltipFree . "\" ]";137 138 }139 echo "<script type=\"text/javascript\">140 google.charts.load('current', {packages: ['corechart', 'bar']});141 google.charts.setOnLoadCallback(drawBarColors);142 143 function drawBarColors() {144 var data = google.visualization.arrayToDataTable([145 ['Host', 'Used', {type: 'string', role: 'style'}, {type: 'string', role: 'tooltip', 'p': {'html': true}},146 'Free', {type: 'string', role: 'style'}, {type: 'string', role: 'tooltip', 'p': {'html': true}}],147 " . implode(",\n", $dataRows) . "148 ]);149 150 var options = {151 title: 'Nebulous Disk Use across IPP Clusters',152 titleTextStyle: {color: 'black', fontSize: 15},153 width: '100%',154 height: '100%',155 tooltip: {isHtml: true},156 legend: { position: 'none', alignment: 'end', maxLines: 3 },157 hAxis: { title: 'Space (TB)', gridlines: {count: 20} },158 vAxis: { textStyle: {fontSize: 14}, format: 'string', textPosition: 'in', direction: 1},159 bar: { groupWidth: '95%' },160 chartArea: {left:40, top:50, right:20, bottom:40},161 fontSize: 15,162 allowHtml: true,163 isStacked: true164 };165 166 var chart = new google.visualization.BarChart(document.getElementById('disk_div'));167 chart.draw(data, options);168 }169 </script>";170 171 echo "<script type='text/javascript' src='loader.js'></script>172 <br>173 <div class='chartWithOverlay' style='position: relative; width: 100%'>174 175 <div id='disk_div' style='width:100%; height:5000px'></div>176 177 <div class='overlay' style='position: absolute; width:160px; top:50px; right:30px; font-family:Arial, sans-serif;'>178 179 <div style='font-size:15px; border:1px solid #888; background-color:lightgreen; color:black; text-align:center; margin-bottom:1px;'>Free</div>180 <div style='font-size:15px; border:1px solid #888; background-color:yellow ; color:black; text-align:center; margin-bottom:1px;'>Used</div>181 <div style='font-size:15px; border:1px solid #888; background-color:pink ; color:black; text-align:center; margin-bottom:1px;'>97% Usage</div>182 <div style='font-size:15px; border:1px solid #888; background-color:lightgrey ; color:black; text-align:center; margin-bottom:1px;'>Down/Repair</div>183 <div style='font-size:15px; border:1px solid #888; background-color:white ; color:black; text-align:center; margin-bottom:1px;'>Offline</div>184 <div style='font-size:15px; border:1px solid #888; background-color:#42a5f5 ; color:white; text-align:center; margin-bottom:1px;'>185 <a href='https://atrcganglia.ifa.hawaii.edu/' target='_blank' style='text-decoration:none; color:white; font-weight:bold;'>ATRC ganglia</a>186 </div>187 188 </div>189 190 </div>";191 192 $total_time = round(microtime(true) - $start, 3);193 echo "<center>loading in $total_time seconds<br></center>";194 }195 196 197 ###########################################################################198 #199 # Gets disk spaces status200 #201 ###########################################################################202 function getSpaces($db) {203 // timer start204 $time = microtime();205 $time = explode(' ', $time);206 $time = $time[1] + $time[0];207 $start = $time;208 209 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host like 'ippb%' and xattr <> 3")->fetchInto($row);210 $ippbusable = $row[0];211 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host like 'ippb%' and writable = 1 and xattr <> 3")->fetchInto($row);212 $ippbfree = $row[0];213 214 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host not like 'ippb%' and xattr <> 3")->fetchInto($row);215 $ippusable = $row[0];216 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host not like 'ippb%' and writable = 1 and xattr <> 3")->fetchInto($row);217 $ippfree = $row[0];218 219 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host like 'ipp%_bck.0' and xattr <> 3")->fetchInto($row);220 $bckusable = $row[0];221 $db->query("SELECT FORMAT(IFNULL(SUM(available), 0), 1) FROM hosts where host like 'ipp%_bck.0' and writable = 1 and xattr <> 3")->fetchInto($row);222 $bckfree = $row[0];223 224 225 $sql = "select format(used/total*100,1), usable from cluster_space order by timestamp desc limit 1;";226 227 if ($debug) {echo "$sql<br>";}228 $qry = $db->query($sql);229 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";}230 $qry->fetchInto($row);231 $allocated = $row[0];232 $usable = $row[1];233 234 #echo "<script type=\"text/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>";235 echo "<script type=\"text/javascript\" src=\"loader.js\"></script>";236 echo "<br><div class=\"chartWithOverlay\" style=\"position: relative; width: 100%; height:400\">";237 echo " <div id=\"space_div\" style=\"width:100%; \"></div>";238 echo " <div class=\"overlay\" style=\"position: absolute; width: 500px; bottom: 60px; left: 80px;\">";239 echo " <div style=\"font-size: 16px; color:#0000ff; \"><b>ipp*_bck: $bckusable TB (usable)</b></div>";240 echo " <div style=\"font-size: 16px; color:#33a532; \"><b>ipp*_bck: $bckfree TB (free)</b></div>";241 echo " </div>";242 echo "</div>";243 244 echo "<script type=\"text/javascript\">";245 echo "google.charts.load('current', {packages: ['corechart']});";246 echo "google.charts.setOnLoadCallback(drawChart);";247 echo "function drawChart() {";248 echo " var data = new google.visualization.DataTable();";249 echo " data.addColumn('datetime', 'Day');";250 echo " data.addColumn('number', 'Usable (ipp:$ippusable, ippb:$ippbusable) TB');";251 echo " data.addColumn('number', 'Free (ipp:$ippfree, ippb:$ippbfree) TB');";252 echo " data.addRows([";253 $interval = 10;254 $sql = "select sub.dated, sub.usable, sub.available from (select date_format(timestamp, \"%Y.%m.%d.%H.%i\") as dated, usable, available from cluster_space where timestamp > curdate() - INTERVAL $interval DAY) as sub group by dated;";255 if ($debug) {echo "$sql<br>";}256 $qry = $db->query($sql);257 if (dberror($qry)) {echo "<b>error with $sql </b><br>\n";}258 while ($qry->fetchInto($row)) {259 $tsp = explode('.', $row[0]);260 $mon = $tsp[1]-1;261 $timestamp = $row[0];262 $usable = $row[1];263 $available = $row[2];264 # new Date(Year, Month, Day, Hours, Minutes, Seconds, Milliseconds)265 echo "[new Date($tsp[0], $mon, $tsp[2], $tsp[3], $tsp[4]), $usable, $available],";266 }267 echo " ]);";268 echo " var options = {";269 echo " chart: {";270 echo " position: 'center', " ;271 echo " },";272 echo " title: 'Total Available Cluster Space in the Past $interval Days ($allocated% of total allocated)',";273 echo " titleTextStyle: {color: 'black', fontSize: 15},";274 echo " width: '100%',";275 echo " height: 400,";276 echo " legend: { position: 'top',";277 echo " alignment: 'center',";278 echo " },";279 echo " lineWidth: 2, ";280 echo " series: {";281 echo " 0: { color: '#0000ff', lineWidth: 3 }, ";282 echo " 1: { color: '#33a532', lineWidth: 3 }, ";283 echo " },";284 echo " hAxis: { ";285 echo " title: 'Date/Time (HST)',";286 echo " format: 'MMM dd',";287 echo " gridlines: {count: -1},";288 echo " },";289 echo " vAxis: { ";290 echo " title: 'Available (TB)',";291 echo " viewWindow: { min: 500 }, ";292 echo " },";293 echo " chartArea: {left:80, top:50, right:20, bottom:50},";294 echo " fontSize: 12,";295 echo " };";296 echo " var chart = new google.visualization.LineChart(document.getElementById('space_div'));";297 echo " chart.draw(data, options);";298 echo " }";299 echo "</script>";300 $time = microtime();301 $time = explode(' ', $time);302 $time = $time[1] + $time[0];303 $finish = $time;304 $total_time = round(($finish - $start), 3);305 $start= $finish;306 echo "<center>loading in $total_time seconds<br></center>";307 }308 309 310 41 ?> 311 42
Note:
See TracChangeset
for help on using the changeset viewer.
