Example #1
0
    /**
     * Gets latest datasource coverage and return as JSON
     */
    public function getDataCoverageEvents($events, $resolution, $startDate, $endDate, $currentDate)
    {
        require_once HV_ROOT_DIR . '/../src/Helper/DateTimeConversions.php';
        $distance = $endDate->getTimestamp() - $startDate->getTimestamp();
        $interval = new DateInterval('PT' . $distance . 'S');
        $visibleStartTimestamp = $startDate->getTimestamp();
        $visibleEndTimestamp = $endDate->getTimestamp();
        $startDate->modify('-' . $distance . ' seconds');
        $endDate->modify('+' . $distance . ' seconds');
        $dateStart = toMySQLDateString($startDate);
        $dateEnd = toMySQLDateString($endDate);
        $startTimestamp = $startDate->getTimestamp();
        $endTimestamp = $endDate->getTimestamp();
        $currentTimestamp = $currentDate->getTimestamp();
        $dateStartISO = str_replace("Z", "", toISOString($startDate));
        $dateEndISO = str_replace("Z", "", toISOString($endDate));
        $sources = array();
        if (!$events) {
            return json_encode(array());
        }
        $eventsKeys = array('AR' => 0, 'CC' => 1, 'CD' => 2, 'CH' => 3, 'CJ' => 4, 'CE' => 5, 'CR' => 6, 'CW' => 7, 'EF' => 8, 'ER' => 9, 'FI' => 10, 'FA' => 11, 'FE' => 12, 'FL' => 13, 'LP' => 14, 'OS' => 15, 'PG' => 16, 'SG' => 17, 'SP' => 18, 'SS' => 19, 'OT' => 20, 'NR' => 21, 'TO' => 22, 'HY' => 23, 'BO' => 24, 'EE' => 25, 'PB' => 26, 'PT' => 27, 'UNK' => 28);
        $eventsColors = array('AR' => '#ff8f97', 'CE' => '#ffb294', 'CME' => '#ffb294', 'CD' => '#ffd391', 'CH' => '#fef38e', 'CW' => '#ebff8c', 'FI' => '#c8ff8d', 'FE' => '#a3ff8d', 'FA' => '#7bff8e', 'FL' => '#7affae', 'LP' => '#7cffc9', 'OS' => '#81fffc', 'SS' => '#8ce6ff', 'EF' => '#95c6ff', 'CJ' => '#9da4ff', 'PG' => '#ab8cff', 'OT' => '#d4d4d4', 'NR' => '#d4d4d4', 'SG' => '#e986ff', 'SP' => '#ff82ff', 'CR' => '#ff85ff', 'CC' => '#ff8acc', 'ER' => '#ff8dad', 'TO' => '#ca89ff', 'HY' => '#00ffff', 'BO' => '#a7e417', 'EE' => '#fec00a', 'PB' => '#b3d5e4', 'PT' => '#494a37', 'UNK' => '#d4d4d4');
        $eventTypes = array();
        $dbData = array();
        $dbVisibleData = array();
        $layersString = '';
        foreach ($events->toArray() as $layer) {
            if (!empty($layer['frm_name']) && $layer['frm_name'] != 'all') {
                $frms = explode(';', $layer['frm_name']);
                foreach ($frms as $frm_name) {
                    if (!empty($layersString)) {
                        $layersString .= ' OR ';
                    }
                    $frm_name = str_replace('_', ' ', $frm_name);
                    $layersString .= '(event_type = "' . $layer['event_type'] . '" AND frm_name = "' . $frm_name . '")';
                }
            } else {
                if (!empty($layersString)) {
                    $layersString .= ' OR ';
                }
                $layersString .= 'event_type = "' . $layer['event_type'] . '"';
            }
            $eventKey = $eventsKeys[$layer['event_type']];
            $dbData[$eventKey] = array();
            $dbVisibleData[$eventKey] = false;
            $sources[$eventKey] = array('data' => array(), 'event_type' => $layer['event_type'], 'res' => $resolution, 'showInLegend' => false);
        }
        switch ($resolution) {
            case 'm':
                $sql = 'SELECT 
	            		*
				FROM events
				WHERE (' . $layersString . ') AND (event_endtime >= "' . $dateStart . '" AND event_starttime <= "' . $dateEnd . '")
				ORDER BY event_starttime;';
                $beginInterval = new DateTime();
                $endInterval = new DateTime();
                $beginInterval->setTimestamp($startTimestamp);
                $endInterval->setTimestamp($endTimestamp);
                break;
            case '5m':
                $sql = 'SELECT 
	            		*
				FROM events
				WHERE (' . $layersString . ') AND (event_endtime >= "' . $dateStart . '" AND event_starttime <= "' . $dateEnd . '")
				ORDER BY event_starttime;';
                $beginInterval = new DateTime();
                $endInterval = new DateTime();
                $beginInterval->setTimestamp(floor($startTimestamp / 300) * 300);
                $endInterval->setTimestamp(floor($endTimestamp / 300) * 300);
                $interval = DateInterval::createFromDateString('5 minutes');
                $period = new DatePeriod($beginInterval, $interval, $endInterval);
                $periodSeconds = 300000;
                break;
            case '15m':
                $sql = 'SELECT 
	            		*
				FROM events
				WHERE (' . $layersString . ') AND (event_endtime >= "' . $dateStart . '" AND event_starttime <= "' . $dateEnd . '")
				ORDER BY event_starttime;';
                $beginInterval = new DateTime();
                $endInterval = new DateTime();
                $beginInterval->setTimestamp(floor($startTimestamp / 900) * 900);
                $endInterval->setTimestamp(floor($endTimestamp / 900) * 900);
                $interval = DateInterval::createFromDateString('15 minutes');
                $period = new DatePeriod($beginInterval, $interval, $endInterval);
                $periodSeconds = 900000;
                break;
            case '30m':
                $sql = 'SELECT 
	            	date,
	            	event_type,
	            	SUM(count) as count
				FROM events_coverage
				WHERE period = "30m" AND (' . $layersString . ') AND `date` BETWEEN "' . $dateStart . '" AND "' . $dateEnd . '"
				GROUP BY date, event_type
				ORDER BY date;';
                $beginInterval = new DateTime();
                $endInterval = new DateTime();
                $beginInterval->setTimestamp(floor($startTimestamp / 1800) * 1800);
                $endInterval->setTimestamp(floor($endTimestamp / 1800) * 1800);
                $interval = DateInterval::createFromDateString('30 minutes');
                $period = new DatePeriod($beginInterval, $interval, $endInterval);
                $periodSeconds = 1800000;
                break;
            case 'h':
                $sql = 'SELECT 
	            	date,
	            	event_type,
	            	SUM(count) as count
				FROM events_coverage
				WHERE period = "1H" AND (' . $layersString . ') AND `date` BETWEEN "' . $dateStart . '" AND "' . $dateEnd . '"
				GROUP BY date, event_type
				ORDER BY date;';
                $beginInterval = new DateTime(date('Y-m-d H:00:00', $startTimestamp));
                $endInterval = new DateTime(date('Y-m-d H:00:00', $endTimestamp));
                $interval = DateInterval::createFromDateString('1 hour');
                $period = new DatePeriod($beginInterval, $interval, $endInterval);
                $periodSeconds = 3600000;
                break;
            case 'D':
                $sql = 'SELECT 
	            	date,
	            	event_type,
	            	SUM(count) as count
				FROM events_coverage
				WHERE period = "1D" AND (' . $layersString . ') AND `date` BETWEEN "' . $dateStart . '" AND "' . $dateEnd . '"
				GROUP BY date, event_type
				ORDER BY date;';
                $beginInterval = new DateTime(date('Y-m-d 00:00:00', $startTimestamp));
                $endInterval = new DateTime(date('Y-m-d 00:00:00', $endTimestamp));
                $interval = DateInterval::createFromDateString('1 day');
                $period = new DatePeriod($beginInterval, $interval, $endInterval);
                break;
            case 'W':
                $sql = 'SELECT 
	            	date,
	            	event_type,
	            	SUM(count) as count
				FROM events_coverage
				WHERE period = "1W" AND (' . $layersString . ') AND `date` BETWEEN "' . $dateStart . '" AND "' . $dateEnd . '"
				GROUP BY date, event_type
				ORDER BY date;';
                $beginInterval = new DateTime(date('Y-m-d 00:00:00', strtotime('Last Monday', $startTimestamp)));
                $endInterval = new DateTime(date('Y-m-d 00:00:00', $endTimestamp));
                $interval = DateInterval::createFromDateString('1 week');
                $period = new DatePeriod($beginInterval, $interval, $endInterval);
                break;
            case 'M':
                $sql = 'SELECT 
	            	date,
	            	event_type,
	            	SUM(count) as count
				FROM events_coverage
				WHERE period = "1M" AND (' . $layersString . ') AND `date` BETWEEN "' . $dateStart . '" AND "' . $dateEnd . '"
				GROUP BY date, event_type
				ORDER BY date;';
                $beginInterval = new DateTime(date('Y-m-01 00:00:00', $startTimestamp));
                $endInterval = new DateTime(date('Y-m-01 00:00:00', $endTimestamp));
                $interval = DateInterval::createFromDateString('1 month');
                $period = new DatePeriod($beginInterval, $interval, $endInterval);
                break;
            case 'Y':
                $sql = 'SELECT 
	            	date,
	            	event_type,
	            	SUM(count) as count
				FROM events_coverage
				WHERE period = "1Y" AND (' . $layersString . ') AND `date` BETWEEN "' . $dateStart . '" AND "' . $dateEnd . '"
				GROUP BY date, event_type
				ORDER BY date;';
                $beginInterval = new DateTime(date('Y-01-01 00:00:00', $startTimestamp));
                $endInterval = new DateTime(date('Y-01-01 00:00:00', $endTimestamp));
                $interval = DateInterval::createFromDateString('1 year');
                $period = new DatePeriod($beginInterval, $interval, $endInterval);
                break;
            default:
                $msg = 'Invalid resolution specified. Valid options include: ' . implode(', ', $validRes);
                throw new Exception($msg, 25);
        }
        //build 0 data array
        if ($resolution != 'm') {
            $emptyData = array();
            foreach ($period as $dt) {
                $emptyData[$dt->getTimestamp() * 1000] = 0;
            }
        }
        //Procceed SQL Data
        $result = $this->_dbConnection->query($sql);
        $i = 1;
        $uniqueIds = array();
        $j = 0;
        while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
            //Event Name
            $key = $row['event_type'];
            $eventKey = $eventsKeys[$key];
            //Build data array
            if ($resolution == 'm') {
                $timeStart = strtotime($row['event_starttime']) * 1000;
                $timeEnd = strtotime($row['event_endtime']) * 1000;
                if ($startTimestamp * 1000 > $timeStart) {
                    $timeStart = $beginInterval->getTimestamp() * 1000;
                }
                if ($endTimestamp * 1000 < $timeEnd) {
                    $timeEnd = $endInterval->getTimestamp() * 1000;
                }
                $modifier = 0;
                if ($timeStart == $timeEnd) {
                    $modifier = round(($endTimestamp - $startTimestamp) / (3 * 60)) * 100;
                    $startTimeToDisplay = $timeStart - $modifier;
                    $timeEndToDisplay = $timeEnd + $modifier;
                } else {
                    $startTimeToDisplay = $timeStart;
                    $timeEndToDisplay = $timeEnd;
                }
                $sources[$eventKey]['data'][$j] = array('x' => $startTimeToDisplay, 'x2' => $timeEndToDisplay, 'y' => $j, 'kb_archivid' => $row['kb_archivid'], 'hv_labels_formatted' => json_decode($row['hv_labels_formatted']), 'event_type' => $row['event_type'], 'frm_name' => $row['frm_name'], 'frm_specificid' => $row['frm_specificid'], 'event_peaktime' => $row['event_peaktime'], 'event_starttime' => $row['event_starttime'], 'event_endtime' => $row['event_endtime'], 'modifier' => $modifier);
                if ($timeStart == $timeEnd) {
                    $sources[$eventKey]['data'][$j]['zeroSeconds'] = true;
                }
                if ($currentTimestamp >= $timeStart && $currentTimestamp <= $timeEnd) {
                    $sources[$eventKey]['data'][$j]['borderColor'] = '#ffffff';
                } else {
                    $sources[$eventKey]['data'][$j]['color'] = $this->colourBrightness($eventsColors[$row['event_type']], -0.9);
                }
                if ($visibleEndTimestamp >= strtotime($row['event_starttime']) && $visibleStartTimestamp <= strtotime($row['event_endtime'])) {
                    $dbVisibleData[$eventKey] = true;
                }
                $uniqueIds[$row['frm_specificid']] = $j;
                $j++;
            } else {
                $timestamp = strtotime($row['date']) * 1000;
                $dbData[$eventKey][$timestamp] = (int) $row['count'];
                if ($visibleEndTimestamp >= strtotime($row['date']) && $visibleStartTimestamp <= strtotime($row['date'])) {
                    $dbVisibleData[$eventKey] = true;
                }
            }
            $i++;
        }
        //Fill 0 values rows
        if ($resolution != 'm') {
            foreach ($dbData as $key => $row) {
                foreach ($emptyData as $timestamp => $count) {
                    if (isset($dbData[$key]) && isset($dbData[$key][$timestamp])) {
                        $count = $dbData[$key][$timestamp];
                    }
                    $sources[$key]['data'][] = array($timestamp, (int) $count);
                }
            }
        } else {
            ksort($sources);
            $i = 1;
            $levels = array();
            foreach ($sources as $k => $series) {
                //loop over all the events
                //$i = count($levels);
                //$levels = array();
                $data = array();
                foreach ($series['data'] as $dk => $event) {
                    //was this event placed in a level already?
                    $placed = false;
                    //loop through each level checking only the last event
                    foreach ($levels as $row => $events) {
                        //we only need to check the last event if they are already sorted
                        $last = end($events);
                        //does the current event start after the end time of the last event in this level
                        if ($event['x'] >= $last['x2']) {
                            //add to this level and break out of the inner loop
                            $event['y'] = $row;
                            $levels[$row][] = $event;
                            $data[] = $event;
                            $placed = true;
                            break;
                        }
                    }
                    //if not placed in another level, add a new level
                    if (!$placed) {
                        $levels[$i] = array($event);
                        $event['y'] = $i;
                        $data[] = $event;
                        $i++;
                    }
                }
                $sources[$k]['data'] = $data;
            }
        }
        //Remove not visible events
        foreach ($dbVisibleData as $k => $isVisible) {
            if ($isVisible) {
                $sources[$k]['showInLegend'] = true;
            }
        }
        ksort($sources);
        $sources = array_values($sources);
        return json_encode($sources);
    }
 /**
  * Retrieve filepaths and timestamps for images at a specified cadence of
  * a given type between the specified start and end dates.
  *
  * @param object $imgIndex  An ImgIndex object with access to the database
  * @param int    $numFrames The number of frames to go into the JPX movie
  *
  * @return array List of filepaths to images to use during JPX generation
  *               as well as a list of  times for each image in the series.
  */
 private function _queryJPXImageFramesByCadence($imgIndex, $numFrames)
 {
     $images = array();
     $dates = array();
     // Timer
     $time = toUnixTimestamp($this->_endTime);
     // Get nearest JP2 images to each time-step
     for ($i = 0; $i < $numFrames; $i++) {
         // Get next image
         $isoDate = toISOString(parseUnixTimestamp($time));
         $img = $imgIndex->getDataFromDatabase($isoDate, $this->_sourceId);
         $filepath = HV_JP2_DIR . $img['filepath'] . '/' . $img['filename'];
         // Ignore redundant images
         if (!$images || $images[0] != $filepath) {
             array_unshift($images, $filepath);
             array_unshift($dates, toUnixTimestamp($img['date']));
         }
         $time -= $this->_cadence;
     }
     // Add entry for start time if it isn't already included
     $img = $imgIndex->getDataFromDatabase($this->_startTime, $this->_sourceId);
     $jp2 = HV_JP2_DIR . $img['filepath'] . '/' . $img['filename'];
     if ($images && $images[0] != $jp2) {
         array_unshift($images, $jp2);
         array_unshift($dates, toUnixTimestamp($img['date']));
     }
     return array($images, $dates);
 }
Example #3
0
 /**
  * Returns status information (i.e. time of most recent available data)
  * based on either observatory, instrument, detector or measurement.
  *
  * There are two types of queries that can be made:
  *
  * (1) instrument
  *
  * If key is set to instrument, then the time of the data source associated
  * with that instrument that is lagging the furthest behind is returned.
  *
  * (2) nickname
  *
  * If the key is set to nickname, then the most recent image times
  * are returned for all datasources, sorted by instrument.
  */
 public function getStatus()
 {
     // Connect to database
     include_once HV_ROOT_DIR . '/../src/Database/ImgIndex.php';
     include_once HV_ROOT_DIR . '/../src/Helper/DateTimeConversions.php';
     $imgIndex = new Database_ImgIndex();
     // Default to instrument-level status information
     if (!isset($this->_options['key'])) {
         $this->_options['key'] = 'instrument';
     }
     $statuses = array();
     // Case 1: instrument
     $instruments = $imgIndex->getDataSourcesByInstrument();
     // Date format
     $format = 'Y-m-d H:i:s';
     // Current time
     $now = new DateTime();
     // Iterate through instruments
     foreach ($instruments as $inst => $dataSources) {
         $oldest = new DateTime('2035-01-01');
         // Keep track of which datasource is the furthest behind
         foreach ($dataSources as $dataSource) {
             // Get date string for most recent image
             $dateStr = $imgIndex->getNewestData($dataSource['id']);
             // Skip data source if no images are found
             if (is_null($dateStr)) {
                 continue;
             }
             // Convert to DateTime
             $date = DateTime::createFromFormat($format, $dateStr);
             // Store if older
             if ($date < $oldest) {
                 $oldest = $date;
             }
         }
         // Get elapsed time
         $delta = $now->getTimestamp() - $oldest->getTimestamp();
         // Add to result array
         if ($delta > 0) {
             $statuses[$inst] = array('time' => toISOString($oldest), 'level' => $this->_computeStatusLevel($delta, $inst), 'secondsBehind' => $delta);
         }
     }
     // Get a list of the datasources grouped by instrument
     $this->_printJSON(json_encode($statuses));
 }