function rot_hpc($x, $y, $tstart, $tend, $spacecraft = null, $vstart = null, $vend = null) { /* Given a location on the Sun referred to using the Helioprojective Cartesian co-ordinate system in the units of arcseconds, use the solar rotation profile to find that location at some later or earlier time. Parameters ----------- x: float or numpy ndarray helio-projective x-co-ordinate in arcseconds y: float or numpy ndarray helio-projective y-co-ordinate in arcseconds tstart: date/time to which x and y are referred; can be in any acceptable time format. tend: Date/time at which x and y will be rotated to; can be in any acceptable time format. spacecraft: { None | "soho" | "stereo_a" | "stereo_b" } calculate the rotation from the point of view of the SOHO, STEREO A, or STEREO B spacecraft. TODO: the ability to do this rotation for data from the SOHO point of view and the STEREO A, B point of views. See Also -------- IDL code equavalent: http://hesperia.gsfc.nasa.gov/ssw/gen/idl/solar/rot_xy.pro Note: rot_xy uses arcmin2hel.pro and hel2arcmin.pro to implement the same functionality. These two functions seem to perform inverse operations of each other to a high accuracy. The corresponding equivalent functions here are convert_hpc_hg and convert_hg_hpc respectively. These two functions seem to perform inverse operations of each other to a high accuracy. However, the values returned by arcmin2hel.pro are slightly different from those provided by convert_hpc_hg. This leads to slightly different results from rot_hpc compared to rot_xy. */ # must have pairs of co-ordinates if (count($x) != count($y) || is_scalar($x) !== is_scalar($y)) { throw new Exception('Input co-ordinates must have the same shape.'); } # Make sure we have enough time information to perform a solar differential # rotation # Start time $dstart = parse_time($tstart); $dend = parse_time($tend); # Fractional days $interval = ($dend->format('U') - $dstart->format('U')) / 60.0 / 60.0 / 24.0; # Get the Sun's position from the vantage point at the start time if ($vstart === null) { $vstart = pb0r($dstart, $spacecraft); } # Compute heliographic co-ordinates - returns (longitude, latitude). Points # off the limb are returned as NaN list($longitude, $latitude) = convert_hpc_hg(RADIUS, AU * sunearth_distance($t = $dstart), 'arcsec', 'arcsec', $vstart["b0"], $vstart["l0"], $x, $y); # Compute the differential rotation $drot = diff_rot($interval, $latitude, $frame_time = 'synodic'); # Convert back to heliocentric cartesian in units of arcseconds if ($vend === null) { $vend = pb0r($dend, $spacecraft); } # It appears that there is a difference in how the SSWIDL function # hel2arcmin and the function below performs this co-ordinate # transform. list($newx, $newy) = convert_hg_hpc(RADIUS, AU * sunearth_distance($t = $dend), $vend["b0"], $vend["l0"], $longitude + $drot, $latitude, $units = 'arcsec'); return array($newx, $newy); }
private function _parseEvents($result) { include_once HV_ROOT_DIR . '/../src/Helper/DateTimeConversions.php'; include_once HV_ROOT_DIR . '/../scripts/rot_hpc.php'; include_once HV_ROOT_DIR . '/../src/Database/DbConnection.php'; $dbConnection = new Database_DbConnection(); if (count($result['result']) > 0) { foreach ($result['result'] as $k => $event) { $event_starttime = new DateTime($event['event_starttime'] . 'Z'); $event_endtime = new DateTime($event['event_endtime'] . 'Z'); //Cache dir location to store bounding boxes images $cache_base_dir = HV_CACHE_DIR . '/events/' . $event_starttime->format('Y') . '/' . $event_starttime->format('m') . '/' . $event_starttime->format('d'); // Scalar for normalizing HEK hpc_x and hpc_y coordinates based on the // apparent size of the Sun as seen from Earth at the specified timestamp. // A reasonable approximation in the absence of the appropriate // spacecraft's position at the timestamp of the image(s) used for F/E detection. $au_scalar = sunearth_distance($event['event_starttime'] . '.000Z'); // Get Unique ID for the event $event['hv_labels_formatted'] = $this->_buildLabelArray($event); // Generate polygon PNG for events that have a chain code if ($event['hpc_boundcc'] != '') { $this->drawPolygon($event, $au_scalar, $polyOffsetX, $polyOffsetY, $polyURL, $polyWidth, $polyHeight); // Save polygon info into $data to be cached $event['hv_poly_hpc_x_ul_scaled_norot'] = $polyOffsetX; $event['hv_poly_hpc_y_ul_scaled_norot'] = $polyOffsetY; $event['hv_poly_url'] = $polyURL; $event['hv_poly_width_max_zoom_pixels'] = $polyWidth; $event['hv_poly_height_max_zoom_pixels'] = $polyHeight; } // Calculate radial distance for determining whether or not to apply differential rotation. $event['hv_hpc_r_scaled'] = sqrt(pow($event['hpc_x'], 2) + pow($event['hpc_y'], 2)) * $au_scalar; if ($event['hv_hpc_r_scaled'] < 961.07064) { // Differential rotation of the event marker's X,Y position $rotateFromTime = $event['event_starttime'] . '.000Z'; $rotateToTime = $event['event_starttime'] . '.000Z'; //$startTime; if ($event['frm_name'] == 'SPoCA') { $rotateFromTime = $event['event_endtime'] . '.000Z'; } else { if ($event['frm_name'] == 'Emerging flux region module' && floatval($event['frm_versionnumber']) < 0.55) { $rotateFromTime = $event['event_peaktime'] . '.000Z'; } } list($event['hv_hpc_x_notscaled_rot'], $event['hv_hpc_y_notscaled_rot']) = rot_hpc($event['hpc_x'], $event['hpc_y'], $rotateFromTime, $rotateToTime, $spacecraft = null, $vstart = null, $vend = null); $event['hv_hpc_x_rot_delta_notscaled'] = $event['hv_hpc_x_notscaled_rot'] - $event['hpc_x']; $event['hv_hpc_y_rot_delta_notscaled'] = $event['hv_hpc_y_notscaled_rot'] - $event['hpc_y']; $event['hv_hpc_x_scaled_rot'] = $event['hv_hpc_x_notscaled_rot'] * $au_scalar; $event['hv_hpc_y_scaled_rot'] = $event['hv_hpc_y_notscaled_rot'] * $au_scalar; $event['hv_rot_hpc_time_base'] = $event['event_starttime']; $event['hv_rot_hpc_time_targ'] = $event['event_starttime']; //$startTime; // These values will be used to place the event marker // in the viewport, screenshots, and movies. $event['hv_hpc_x_final'] = $event['hv_hpc_x_scaled_rot']; $event['hv_hpc_y_final'] = $event['hv_hpc_y_scaled_rot']; // Drop events whose calculated marker position is NaN if (is_nan($event['hv_hpc_x_final']) || is_nan($event['hv_hpc_y_final'])) { continue; } // Apply differential rotation offset to the region // polygon's upper-left X,Y position if (isset($event['hv_poly_hpc_x_ul_scaled_norot']) && isset($event['hv_poly_hpc_y_ul_scaled_norot']) && is_numeric($event['hv_poly_hpc_x_ul_scaled_norot']) && is_numeric($event['hv_poly_hpc_y_ul_scaled_norot'])) { $event['hv_poly_hpc_x_ul_scaled_rot'] = $event['hv_poly_hpc_x_ul_scaled_norot'] + $event['hv_hpc_x_rot_delta_notscaled'] * $au_scalar; $event['hv_poly_hpc_y_ul_scaled_rot'] = $event['hv_poly_hpc_y_ul_scaled_norot'] + $event['hv_hpc_y_rot_delta_notscaled'] * $au_scalar; // These values will be used to place the region // polygon in the viewport, screenshots, and movies. // Represents upper-left corner of polygon PNG. $event['hv_poly_hpc_x_final'] = $event['hv_poly_hpc_x_ul_scaled_rot']; $event['hv_poly_hpc_y_final'] = $event['hv_poly_hpc_y_ul_scaled_rot']; } } else { // Don't apply differential rotation to objects beyond // the disk but do normalize them with the $au_scalar. // These values will be used to place the event marker // in the viewport, screenshots, and movies. $event['hv_hpc_x_final'] = $event['hpc_x'] * $au_scalar; $event['hv_hpc_y_final'] = $event['hpc_y'] * $au_scalar; if (isset($event['hv_poly_hpc_x_ul_scaled_norot']) && isset($event['hv_poly_hpc_y_ul_scaled_norot']) && is_numeric($event['hv_poly_hpc_x_ul_scaled_norot']) && is_numeric($event['hv_poly_hpc_y_ul_scaled_norot'])) { // These values will be used to place the event // polygons in the viewport, screenshots, and movies. $event['hv_poly_hpc_x_final'] = $event['hv_poly_hpc_x_ul_scaled_norot']; $event['hv_poly_hpc_y_final'] = $event['hv_poly_hpc_y_ul_scaled_norot']; } } // Sort HEK results by parameter name if (defined('PHP_VERSION_ID') && PHP_VERSION_ID >= 50400) { ksort($event, SORT_NATURAL | SORT_FLAG_CASE); } else { ksort($event, SORT_STRING); } //Store Result in Database $sql = "REPLACE INTO `events` \n\t \t\t(`kb_archivid`, `frm_name`, `concept`, `frm_specificid`, \n\t \t\t`event_starttime`, `event_endtime`, `event_peaktime`, `event_type`, \n\t \t\t`event_before`, `event_after`, `hpc_boundcc`, \n\t \t\t`hv_labels_formatted`, `hv_poly_url`, `hv_event_starttime`, `hv_event_endtime`, \n\t \t\t`hv_rot_hpc_time_base`, `hv_rot_hpc_time_targ`, `hv_hpc_x_notscaled_rot`, \n\t \t\t`hv_hpc_y_notscaled_rot`, `hv_hpc_x_rot_delta_notscaled`, `hv_hpc_y_rot_delta_notscaled`, \n\t \t\t`hv_hpc_x_scaled_rot`, `hv_hpc_y_scaled_rot`, `hv_hpc_y_final`, \n\t \t\t`hv_hpc_x_final`, `hv_hpc_r_scaled`, `hv_poly_hpc_x_final`, \n\t \t\t`hv_poly_hpc_y_final`, `hv_poly_hpc_x_ul_scaled_rot`, \n\t \t\t`hv_poly_hpc_y_ul_scaled_rot`, `hv_poly_hpc_x_ul_scaled_norot`, \n\t \t\t`hv_poly_hpc_y_ul_scaled_norot`, `hv_poly_width_max_zoom_pixels`, \n\t \t\t`hv_poly_height_max_zoom_pixels`, `event_json`) \n\t \tVALUES ( \n\t \t\t'" . str_replace("ivo://helio-informatics.org/", "", $event['kb_archivid']) . "', \n\t \t\t'" . (isset($event['frm_name']) ? $event['frm_name'] : '') . "', \n\t \t\t'" . (isset($event['concept']) ? $event['concept'] : '') . "', \n\t \t\t'" . (isset($event['frm_specificid']) ? $event['frm_specificid'] : '') . "', \n\t \t\t" . (isset($event['event_starttime']) ? "'" . $event['event_starttime'] . "'" : 'null') . ", \n\t \t\t" . (isset($event['event_endtime']) ? "'" . $event['event_endtime'] . "'" : 'null') . ", \n\t \t\t" . (isset($event['event_peaktime']) && !empty($event['event_peaktime']) ? "'" . $event['event_peaktime'] . "'" : 'null') . ", \n\t \t\t'" . (isset($event['event_type']) ? $event['event_type'] : '') . "', \n\t \t\t'" . (isset($event['event_before']) ? $event['event_before'] : '') . "', \n\t \t\t'" . (isset($event['event_after']) ? $event['event_after'] : '') . "', \n\t \t\t'" . (isset($event['hpc_boundcc']) ? $event['hpc_boundcc'] : '') . "', \n\t \t\t'" . json_encode($event['hv_labels_formatted']) . "', \n\t \t\t'" . (isset($event['hv_poly_url']) ? $event['hv_poly_url'] : '') . "', \n\t \t\t" . (isset($event['hv_event_starttime']) ? "'" . $event['hv_event_starttime'] . "'" : 'null') . ", \n\t \t\t" . (isset($event['hv_event_endtime']) ? "'" . $event['hv_event_endtime'] . "'" : 'null') . ", \n\t \t\t" . (isset($event['hv_rot_hpc_time_base']) ? "'" . $event['hv_rot_hpc_time_base'] . "'" : 'null') . ", \n\t \t\t" . (isset($event['hv_rot_hpc_time_targ']) ? "'" . $event['hv_rot_hpc_time_targ'] . "'" : 'null') . ", \n\t \t\t" . (isset($event['hv_hpc_x_notscaled_rot']) ? $event['hv_hpc_x_notscaled_rot'] : 'null') . ", \n\t \t\t" . (isset($event['hv_hpc_y_notscaled_rot']) ? $event['hv_hpc_y_notscaled_rot'] : 'null') . ", \n\t \t\t" . (isset($event['hv_hpc_x_rot_delta_notscaled']) ? $event['hv_hpc_x_rot_delta_notscaled'] : 'null') . ", \n\t \t\t" . (isset($event['hv_hpc_y_rot_delta_notscaled']) ? $event['hv_hpc_y_rot_delta_notscaled'] : 'null') . ", \n\t \t\t" . (isset($event['hv_hpc_x_scaled_rot']) ? $event['hv_hpc_x_scaled_rot'] : 'null') . ", \n\t \t\t" . (isset($event['hv_hpc_y_scaled_rot']) ? $event['hv_hpc_y_scaled_rot'] : 'null') . ", \n\t \t\t" . (isset($event['hv_hpc_y_final']) ? $event['hv_hpc_y_final'] : 'null') . ", \n\t \t\t" . (isset($event['hv_hpc_x_final']) ? $event['hv_hpc_x_final'] : 'null') . ", \n\t \t\t" . (isset($event['hv_hpc_r_scaled']) ? $event['hv_hpc_r_scaled'] : 'null') . ", \n\t \t\t" . (isset($event['hv_poly_hpc_x_final']) ? $event['hv_poly_hpc_x_final'] : 'null') . ", \n\t \t\t" . (isset($event['hv_poly_hpc_y_final']) ? $event['hv_poly_hpc_y_final'] : 'null') . ", \n\t \t\t" . (isset($event['hv_poly_hpc_x_ul_scaled_rot']) ? $event['hv_poly_hpc_x_ul_scaled_rot'] : 'null') . ", \n\t \t\t" . (isset($event['hv_poly_hpc_y_ul_scaled_rot']) ? $event['hv_poly_hpc_y_ul_scaled_rot'] : 'null') . ", \n\t \t\t" . (isset($event['hv_poly_hpc_x_ul_scaled_norot']) ? $event['hv_poly_hpc_x_ul_scaled_norot'] : 'null') . ", \n\t \t\t" . (isset($event['hv_poly_hpc_y_ul_scaled_norot']) ? $event['hv_poly_hpc_y_ul_scaled_norot'] : 'null') . ", \n\t \t\t" . (isset($event['hv_poly_width_max_zoom_pixels']) ? $event['hv_poly_width_max_zoom_pixels'] : 'null') . ", \n\t \t\t" . (isset($event['hv_poly_height_max_zoom_pixels']) ? $event['hv_poly_height_max_zoom_pixels'] : 'null') . ", \n\t \t\t'" . str_replace("'", "\\'", json_encode($event)) . "');"; $dbConnection->query($sql); unset($event); unset($result['result'][$k]); } } }