3000000) { throw new RuntimeException('Exceeded filesize limit.'); } // Check MIME type. Only accept text files. if (!preg_match('/text\//', $_FILES['ephemfile']['type'])) { throw new RuntimeException('Accepting only text files.'); } // You should name it uniquely. // DO NOT USE $_FILES['ephemfile']['name'] WITHOUT ANY VALIDATION !! // On this example, obtain safe unique name from its binary data. $hash = sha1_file($_FILES['ephemfile']['tmp_name']); $uploadedFile = sprintf($uploadDir.'/%s.%s',$hash,'txt'); if (!move_uploaded_file($_FILES['ephemfile']['tmp_name'],$uploadedFile)) { throw new RuntimeException('Failed to record uploaded file.'); } } catch (RuntimeException $e) { $uploadError = true; $errorMessage = $e->getMessage(); } // Proceed with processing of Horizons file if upload was successful if ($uploadError == false) { // Read JPL ephemeris file // - capture info from header // - determine type of date (JD, CAL or BOTH) // - store ephemeris data // // Flag: detect processing errors $processError = false; // Flag: are we processing lines in the area containing the ephemeris data? $withinEphemZone = false; // Time format: can be CAL, JD or BOTH depending on user's choice when running Horizons $timeFormat = ""; // Open the input file $input = fopen($uploadedFile,"r"); // Create the name for the output file if ($_POST['outputName'] != "") { // If output name was given in the form, remove any path information and sanitize the file name $outputFileName = sanitize(pathinfo($_POST['outputName'],PATHINFO_FILENAME)) ; } else { // If no name was given, simply use the name of the temp file (random). $outputFileName = pathinfo($_FILES['ephemfile']['tmp_name'],PATHINFO_FILENAME) ; } // Append standard extension ie ".eph" to name of output file $outputFileName .= ".eph"; $tempName = tempnam($uploadDir,"PAF"); // Full path for the output file (impose the output directory) // $outputFile = sprintf($uploadDir.'/%s', $outputFileName); $outputFile = $tempName; // Proceed only if the input file could be opened w/o errors if ($input) { // Open output file $output = fopen($outputFile,"w"); // Write standard PAF header fwrite($output,"PAF.HDR.START; # Start of PAF Header\n"); fwrite($output,"PAF.TYPE \"Instrument Setup\"; # Type of PAF\n"); fwrite($output,"PAF.ID \"\"; # ID for PAF\n"); fwrite($output,str_pad("PAF.NAME \"$outputFileName\";",60," ",STR_PAD_RIGHT) . "# Name of PAF\n"); // We make sure that we process all dates as UT time (set the default timezone) date_default_timezone_set('UTC'); $warningMessages = ""; // Flag: did we find data with invalid format? $invalidFormat = false; $foundData = false; /// Main loop on the lines of the input file while (($line = fgets($input)) !== false) { // process the line we just read... // trim the line $line = trim($line); // skip the line if it is empty if ( $line == "" ) { continue; } // detect start of ephemeris data (marker: $$SOE) if ( $line == "\$\$SOE" ) { // Set the flag: we found the start of the actual data $withinEphemZone = true; $foundData = true; // Write rest of PAF header to output file fwrite($output,"PAF.CRTE.NAME \"crossEphem2PAF.php\"; # Name of creator\n"); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Generates the date for today // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $cDate = gmdate('c'); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Generates the last part of PAF header // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ fwrite($output,str_pad("PAF.CRTE.DAYTIM \"$cDate\";",60," ",STR_PAD_RIGHT) . "# UTC time of creation\n"); fwrite($output,"PAF.LCHG.NAME \"\"; # Name of person/appl. changing\n"); fwrite($output,"PAF.LCHG.DAYTIM \"\"; # Timestamp of last change\n"); fwrite($output,"PAF.CHCK.NAME \"\"; # Name of appl. checking\n"); fwrite($output,"PAF.HDR.END; # End of PAF Header\n"); fwrite($output,"\n#------------------------------------------------------------------------------\n\n"); fwrite($output,"TPL.FILE.DIRNAME \"\$INS_ROOT/SYSTEM/DETDATA\"; # Storage filename\n"); fwrite($output,"\n#------------------------------------------------------------------------------\n\n"); continue; } // detect end of ephemeris data (marker: $$EOE) if ( $line == "\$\$EOE" ) { $withinEphemZone = false; break; } // If we are within the 'data zone' but did not detect the time format, issue error. if ( $withinEphemZone && $timeFormat == "" ) { // Found ephemeris data but no time format info available: cannot proceed $processError = true; $processMessage = "ERROR: no info about chosen time format in input file!"; } elseif ( $withinEphemZone ) { //// now we deal with ephemeris data // The line must start with a numeric entry and not contain '>' (comment lines are sometimes inserted // in the output, we skip those). if ( is_numeric($line[0]) && !strpos($line,">") ) { // Retrieve the line elements (we split the csv line) $lineElements = explode(",",$line); // PAF Keyword for epehemeris data $newLine = "INS.EPHEM.RECORD \""; // Depending on the chosen time format the input file contains // the Gregorian date, Julian date, or both. switch ($timeFormat) { // Julian date case "JD": $CALdate = ""; $JDdate = trim($lineElements[0]); $RA = trim($lineElements[3]); $DEC = trim($lineElements[4]); $dRA = trim($lineElements[5]); $dDEC = trim($lineElements[6]); $otherInfoIndex = 7; break; // Gregorian date case "CAL": $CALdate = trim($lineElements[0]); $JDdate = ""; $RA = trim($lineElements[3]); $DEC = trim($lineElements[4]); $dRA = trim($lineElements[5]); $dDEC = trim($lineElements[6]); $otherInfoIndex = 7; break; // ... or both types of date case "BOTH": $CALdate = trim($lineElements[0]); $JDdate = trim($lineElements[1]); $RA = trim($lineElements[4]); $DEC = trim($lineElements[5]); $dRA = trim($lineElements[6]); $dDEC = trim($lineElements[7]); $otherInfoIndex = 8; break; } // Convert dRA and dDEC from arcsec/h to arcsec/s // if no value given, set to 0. if ( $dRA == "" || $dDEC == "" ) { $dRAsec = 0.; $dDECsec = 0.; } elseif ( !is_numeric($dRA) || !is_numeric($dDEC) ) { // If not numbers, raise error flag and skip the line altogether $invalidFormat = true; $errorTypes[] = "diffVel"; continue; } else { // Convert to arcsec/s from arcsec/h $dRAsec = sprintf("%+9.6f",$dRA/3600.0); $dDECsec = sprintf("%+9.6f",$dDEC/3600.0); } // Proceed with date conversions and/or reformatting if ( $CALdate == "" ) { // If the Gregorian date is not present in the input file... // Check that the Julian date is a number as expected, // otherwise raise the error flag and skip the line if ( !isTrueFloat($JDdate) ) { $invalidFormat = true; $errorTypes[] = "JDdate"; continue; } // Create 'Unix' timestamp based on Julian date $timeStamp = ($JDdate - 2440587.5) * 86400 ; // Trick: fractional seconds are not handled natively by PHP... // ... retrieve the seconds based on the timestamp (this is truncated // to the nearest second by PHP $seconds = gmdate('s',$timeStamp); // ... then get the fractional seconds $milliseconds = $timeStamp - floor($timeStamp); // ...and create the string with seconds + fractional part $secondsString = sprintf("%06.3f",$seconds + $milliseconds); //echo('

secondsString='.$secondsString.' seconds='.$seconds.' milliseconds='.$milliseconds.' timeStamp='.$timeStamp.'

'); if ($secondsString == '60.000') { $timeStamp = $timeStamp + 60; $secondsString = '00.000'; } // Concatenate the date with the seconds $CALdate = gmdate('Y-m-d\TH:i:',$timeStamp) . $secondsString; // Format the Julian date for uniformity $JDdate = sprintf("%7.9f",$JDdate); } elseif ( $JDdate == "" ) { // If the Julian date is not present in the input file try { // Create new DateTime object based on Gregorian date $date = new DateTime($CALdate); // Compute the 'Unix' timestamp: use strtotime and retrieve the // fractional seconds from the DateTime instance (that handles microseconds) $timeStamp = strtotime($CALdate) + $date->format('u')/1000000 ; $CALdate = $date->format('Y-m-d\TH:i:') . sprintf("%06.3f",$date->format('s.u')); // Compute the Julian date based on the Unix timestamp $JDdate=sprintf("%7.9f",$timeStamp/86400 + 2440587.5) ; } catch (Exception $e) { // Catch possible exceptions if DateTime object could not be created // (case of wrong date formatting) $invalidFormat = true; $errorTypes[] = "CALdate"; continue; } } else { // Third case: both dates are present in the input file, then // we just reformat them to the agreed format try { // Create new DateTime object based on Gregorian date $date = new DateTime($CALdate); // Reformat the Gregorian date, DateTime object handles the microseconds $CALdate = $date->format('Y-m-d\TH:i:') . sprintf("%06.3f",$date->format('s.u')); // Check the format of the Julian date, if incorrect then skip line if ( !isTrueFloat($JDdate) ) { $invalidFormat = true; $errorTypes[] = "JDdate"; continue; } // Format the Julian date for uniformity $JDdate = sprintf("%7.9f",$JDdate); } catch (Exception $e) { // Catch possible exceptions if DateTime object could not be created // (case of wrong date formatting) $invalidFormat = true; $errorTypes[] = "CALdate"; continue; } } // Check format of RA and DEC if ( !isRA($RA) || !isDEC($DEC) ) { // If RA or DEC not in expected format, raise error flag and skip the line $invalidFormat = true; $errorTypes[] = "coords"; continue; } // If everything went fine we format the new line for the ephemeris file in PAF format... $newLine .= $CALdate . ", " . $JDdate . ", " . $RA . ", " . $DEC . ", " . $dRAsec . ", " . $dDECsec ; // .. and we include possible other fields (ancillary information) for ($i = $otherInfoIndex ; $i < count($lineElements); $i++) { $dataField = trim($lineElements[$i]); // We only include those fields that are not empty if ( $dataField != "" ) { $newLine .= ", " . $dataField ; } } $newLine .= "\""; // Last step: write the new line to the output file fwrite($output,$newLine . "\n"); } } else { // Here we deal with other data than the ephemeris itself (header) if ( strstr($line,"Ephemeris / WWW_USER") ) { fwrite($output,"PAF.DESC \"" . str_pad($line,79," ",STR_PAD_RIGHT) . "\"\n"); } // We identify the header items we want to keep in the PAF file $colonIndex = strpos($line,":"); if ($colonIndex != false) { $headerItem = trim(substr($line,0,$colonIndex)); switch ($headerItem) { case "Time format" : // Get the chosen time format (CAL, JD or BOTH) in order to know // what date(s) to expect in the ephemeris $timeFormat = trim(substr($line,$colonIndex+1)); break; case "Target body name" : case "Center bocy name" : case "Center-site name" : case "Start time" : case "Stop time" : case "Step-size" : case "Target pole/equ" : case "Target radii" : case "Atmos refraction" : case "Table cut-offs 1" : case "Table cut-offs 2" : // Write the header line to the PAF header fwrite($output,"PAF.DESC \"" . str_pad($line,79," ",STR_PAD_RIGHT) . "\"\n"); break; default: break; } } } } if ($foundData == false) { $processError = true; $processMessage = "ERROR: could not find ephemeris data in input file!"; } // Processing finished: close the input and output file fclose($input); fclose($output); // Remove the input file uploaded by user unlink($uploadedFile); // Deal with warnings/errors: if we encountered data with unexpected format raise a warning if ($invalidFormat) { $warningMessages .= "

WARNING! Found some data with unexpected format in input file. Please check the output carefully!

"; $warningMessages .= "

Problems were found with:

"; } } else { // error opening the file: raise error $processError = true; $processMessage = "ERROR opening the file!"; } } // If no fatal error was detected during the upload or the processing, // we trigger an automatic download of the resulting file after 3 seconds. if ( $uploadError == false && $processError == false) { $p=pathinfo($tempName,PATHINFO_BASENAME) ; header("Refresh: 3; url=ephemDownload.php?f=$outputFileName&p=$p"); } } include 'frame_top.php'; ?>

Moving targets - Converter for ephemeris files

This online converter allows you to upload an ephemeris file produced with the JPL Horizons tool and to retrieve it in a format suitable for use with your Observation Blocks prepared with P2PP. Simply upload the Horizons file, optionally choose a name for the resulting file and click on 'Convert'.


Convert your Horizons file to VLT format

ERROR uploading your file: $errorMessage
"; echo "Cannot proceed with the conversion.

"; } elseif ( isset($processError) && $processError == false ) { // If no fatal processing error was detected... if ($invalidFormat) { // In case of data with invalid format, issue an error message echo("
$warningMessages

"); echo("Your ephemeris file was converted to PAF format but there were some errors. The generated file may thus be incomplete. Your download should start automatically. If not, please click on the following link and save the file to the directory of your choice:

"); echo("$outputFileName

"); } else { // If everything went well display standard message only echo("

Your ephemeris file was successfully converted to PAF format for use with your Observation Blocks. Your download should start automatically. If not, please click on the following link and save the file to the directory of your choice:

"); echo("$outputFileName


"); } } elseif ( isset($processError) && $processError == true ) { // Issue error message if fatal error occurred while processing the file echo("

$processMessage
Cannot proceed with the conversion.

"); } ?>



Please note: the following settings must be used when running the JPL Horizons tool in order to produce a VLT-compliant ephemeris file:

  • In the "Current Settings" table set the value in the right column:
Current Settings
Ephemeris type OBSERVER
Target Body favorite target or reference object
Observer Location Cerro Paranal [309]
Time Span start and end of the ephemerides, time step
Display/Output download/save

 

  • The "Table Settings" parameters should have the following values:
Table Settings
observer quantities

1 Astrometric RA & DEC  

3 Rates: RA & DEC

9 Visual mag. & Surface Brght

(other quantities are optional)

day/time format Julian day
angle format hours/degrees minutes seconds
Refraction model airless model (no refraction)
Airmass Limit 2.6 (or smaller)
Elevation cutoff 20 (or larger)
Skip daylight checked
Extra precision checked
Reference system ICRF/J2000.0
CSV format checked