//*********************************************************************************
// class BuildTestPluto99 // default package
// Software released under the General Public License (version 2 or later), available at
// http://www.gnu.org/copyleft/gpl.html
//*********************************************************************************
import java.io.*;
import java.text.*;
import jephem.astro.planets.Pluto99;
import jephem.astro.SolarSystemConstants;
import jephem.astro.Body;
/******************************************************************
Contains methods used to build jephem.astro.planets.Pluto99.java.
<BR>This class is NOT part of 'jephem' package, and can be useful to developpers who want to transform
BDL Pluto99 file.
<BR>See a description of its use in the <A HREF="../../../ephemeris/et400pluto99_en.htm" TARGET="_top">page about Pluto99</A> of JEphem site.
<BR><CODE>BuildTestPluto99</CODE> needs to have in the current directory the file <CODE>plutoxyz.dat</CODE> which can be found at <A HREF="ftp://ftp.bdl.fr/pub/polac/solarsys/pluto">ftp://ftp.bdl.fr/pub/polac/solarsys/pluto</A>.
@author Thierry Graff
@history Aug 12 2001 : Creation
@history Dec 21 2001 : Put Phi in radians - tested velocities
*****************************************************************/
public class BuildTestPluto99{
//=================================================================================
// PUBLIC CONSTANTS
//=================================================================================
/** Parameter to pass to <CODE>main()</CODE> to call <CODE>buildPluto99()</CODE> - value = "build". */
public static final String PARAM_BUILD = "build";
/** Parameter to pass to <CODE>main()</CODE> to call <CODE>testPositions()</CODE> - value = "testPositions". */
public static final String PARAM_TEST_POSITIONS = "testPositions";
/** Parameter to pass to <CODE>main()</CODE> to call <CODE>calcGeoPrec()</CODE> - value = "calcGeoPrec". */
public static final String PARAM_CALC_GEO_PREC = "calcGeoPrec";
/** Parameter to pass to <CODE>main()</CODE> to call <CODE>testVelocities()</CODE> - value = "testVelocities". */
public static final String PARAM_TEST_VELOCITIES = "testVelocities";
/** Parameter to pass to <CODE>buildPluto99() to generate term Phi in degrees. - value = "degrees". */
public static final String PARAM_DEGREES = "degrees";
/** Parameter to pass to <CODE>buildPluto99() to generate term Phi in radians. - value = "radians". */
public static final String PARAM_RADIANS = "radians";
//=================================================================================
// PRIVATE CONSTANTS
//=================================================================================
private final static String InputFileName = "plutoxyz.dat.txt"; // added '.txt' for convenience under windows
/** Line separator */
private final static String LS = System.getProperty("line.separator");
/** Number of coordinates; */
private final static int NB_COORD = 3;
/** Number of orders; */
private final static int NB_ORDERS = 3;
/** Names of coordinates; */
private final static String[] COORDNAMES = {"X", "Y", "Z"};
/** Number of lines contained by the header. */
private final static int NB_LINES_IN_HEADER = 12;
/** Number of lines at the beginning of a coordinate, before data line. */
private final static int NB_LINES_BEFORE_ORDER0 = 8;
/** Number of lines contained by the header. */
private final static int NB_LINES_BETWEEN_ORDERS = 4;
/** String of one blank character. */
private final static String BLANK = " ";
/** Number of Poisson terms */
private static final int[][] nbTerms = {
{193, 26, 13}, // Poisson terms for X, order 0, 1, 2
{183, 29, 14}, // Poisson terms for Y, order 0, 1, 2
{170, 20, 11} // Poisson terms for Z, order 0, 1, 2
}; // total 659 terms
private final static int NB_TESTS = 11;
/** To format radian values of Phi. */
private static final DecimalFormat NF = new DecimalFormat();
static{
NF.setMaximumFractionDigits(7);
NF.setMinimumFractionDigits(7);
DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setDecimalSeparator('.');
NF.setDecimalFormatSymbols(dfs);
};
/*
private static final NumberFormat NF = NumberFormat.getNumberInstance();
static{
NF.setMaximumFractionDigits(7);
NF.setMinimumFractionDigits(7);
};
*/
//=================================================================================
// METHODS
//=================================================================================
//**************** main ************************
/** Dispatches the call to different methods, depending on first argument.
@param args The first argument must be one of ARG_XXX constants ; indicates which method will be
called. The following arguments are passed to the called method.
*/
public static void main(String[] args){
String paramList = "'" + PARAM_BUILD + "' or '" + PARAM_TEST_POSITIONS + "' or '" + PARAM_CALC_GEO_PREC + "'";
if (args.length == 0){
System.out.println("Call to main must have at least one parameter :");
System.out.println(paramList);
System.exit(0);
}
if (args[0].compareToIgnoreCase(PARAM_BUILD) == 0){
if (args.length == 2)
buildPluto99(args[1]);
else{
System.out.println("buildPluto99() needs 1 argument - so call main with 2 parameters");
System.exit(0);
}
}
else if (args[0].compareToIgnoreCase(PARAM_TEST_POSITIONS) == 0)
testPositions();
else if (args[0].compareToIgnoreCase(PARAM_TEST_VELOCITIES) == 0)
testVelocities();
else if (args[0].compareToIgnoreCase(PARAM_CALC_GEO_PREC) == 0)
calcGeoPrec();
else{
System.out.println("First parameter must be :");
System.out.println(paramList);
}
}// end main
//**************** buildPluto99() ************************
/** Method used to transform 'plutoxyz.dat' to a java array.
<BR>Only terms 'Ampli', 'Nu' and 'Phi' are used.
<BR>It generates a file 'result.txt' which contains a java formatted array containing the terms of Pluto99.
@param strUnit : can be "radians" or "degrees", depending on the unit you want phi to be expressed.
*/
public static void buildPluto99(String strUnit){
try{
int DEGREES = 0;
int RADIANS = 1;
int unit = -1;
// parameter parsing
System.out.println(strUnit);
if (strUnit.compareToIgnoreCase(PARAM_DEGREES) == 0)
unit = DEGREES;
else if (strUnit.compareToIgnoreCase(PARAM_RADIANS) == 0)
unit = RADIANS;
else{
System.out.println("Argument 'strUnit must be either " + PARAM_RADIANS + " or " + PARAM_DEGREES);
System.exit(0);
}
FileOutputStream fos = new FileOutputStream(new File("result.txt"));
LineNumberReader lnr = new LineNumberReader(new FileReader(new File(InputFileName)));
// Declaration of variables
String strRes = new String(); // result String
String line = new String(); // current line read
// for radian conversion
String strTmp;
double phi;
int i; // used several times
int iCoord, iOrder; // indexes of current coordinate and current order.
int spaceIdx; // used for line parsing
// 1 - Write declaration of the array
strRes += " // Array containing the terms for summation" + LS;
strRes += " private static final double[][][][] terms = {" + LS;
// 2 - Skip header of plutoxyz.dat.
for (i = 0; i < NB_LINES_IN_HEADER; i++) line = lnr.readLine();
// 3 - parse for each coord.
for (iCoord = 0; iCoord < NB_COORD; iCoord ++){
System.out.println("Parsing coord " + COORDNAMES[iCoord]);
// 3.1 - Skip secular terms and header for order 0.
for (i = 0; i < NB_LINES_BEFORE_ORDER0; i++)
line = lnr.readLine();
strRes += " { // Poisson terms for " + COORDNAMES[iCoord] + LS;
// 3.2 - parse for each order.
for (iOrder = 0; iOrder < NB_ORDERS; iOrder++){
System.out.println(" order " + iOrder);
// 3.2.1 write header for this order
strRes += " { // " + COORDNAMES[iCoord] + ", order " + iOrder + " - "
+ nbTerms[iCoord][iOrder] + " terms" + LS;
// 3.2.2 parse data line ans write in strRes
for (i = 0; i < nbTerms[iCoord][iOrder]; i++){
strRes += " { ";
line = lnr.readLine().trim();
// parse Ampli
spaceIdx = line.indexOf(BLANK);
strRes += line.substring(0, spaceIdx) + ", ";
// parse Nu
line = line.substring(spaceIdx).trim();
spaceIdx = line.indexOf(BLANK);
strRes += line.substring(0, spaceIdx) + ", ";
// parse phi and generate either degrees or radians
line = line.substring(spaceIdx).trim();
spaceIdx = line.indexOf(BLANK);
if (unit == DEGREES)
strRes += line.substring(0, spaceIdx) + " }";
else{ // radians
strTmp = line.substring(0, spaceIdx);
phi = Math.toRadians(Double.parseDouble(strTmp));
strRes += NF.format(phi) + " }";
}
// write end of array
if (!(iOrder == NB_ORDERS -1 && iCoord == NB_COORD -1 && i == nbTerms[iCoord][iOrder] - 1))
strRes += ",";
strRes += LS;
}// end for (i = 0; i < nbTerms[iCoord][iOrder]; i++)
// 3.3.3 Close the array for this order
strRes += " }";
if (iOrder < NB_ORDERS -1)
strRes += ",";
strRes += LS;
// 3.3 - Skip terms between orders only for order 0 and 1 (end of order 2 = end of coord).
if (iOrder < NB_ORDERS - 1)
for (i = 0; i < NB_LINES_BETWEEN_ORDERS; i++) line = lnr.readLine();
fos.write(strRes.getBytes());
strRes = "";
}// end for (iOrder = 0; iOrder < NB_ORDERS; iOrder ++)
// Close the array for this coordinate
strRes += " }";
if (iCoord < NB_COORD -1)
strRes += ",";
strRes += LS;
// skip supplementary blank line
line = lnr.readLine();
}// end for (iCoord = 0; iCoord < NB_COORD; iCoord ++)
// 4 - Close the general array
strRes += " }; // end terms[][][]" + LS;
fos.write(strRes.getBytes());
fos.close();
}
catch(Exception e){
System.out.println("Exception" + e.toString());
}
}// end buildPluto99()
//**************** testPositions() ************************
/** Method used to test first version of class Pluto99 (with phi in degrees);
values taken from <B>NOTICE</B>. */
public static void testPositions(){
double jd[] = { 807932.5, // -2500 Jan 01
990557.5, // -2000 Jan 01
1173182.5, // -1500 Jan 01
1355807.5, // -1000 Jan 01
1538432.5, // -500 Jan 01
1721057.5, // 0 Jan 01
1903682.5, // 500 Jan 01
2086307.5, // 1000 Jan 01
2268932.5, // 1500 Jan 01
2451557.5, // 2000 Jan 14
2634182.5 // 2500 Jan 17
}; // 11 dates
double[][] coord = {
{ -24.450898, 27.864841, 4.020151 },
{ -28.090595, 20.600908, 5.869147 },
{ -30.166984, 12.762686, 7.327759 },
{ -30.612416, 4.703150, 8.334771 },
{ -29.447885, -3.154766, 8.849075 },
{ -26.904668, -10.265583, 8.881072 },
{ -23.346605, -16.332474, 8.505363 },
{ -19.112797, -21.288876, 7.813304 },
{ -14.504729, -25.154226, 6.893533 },
{ -9.837480, -27.977994, 5.841542 },
{ -5.418324, -29.873589, 4.758520 }
};
int i;
double tmp0, tmp1, tmp2;
double[] res = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // contains the results
Body b = new Body (SolarSystemConstants.PLUTO);
for (i = 0; i< NB_TESTS; i++){
Pluto99.calcCoord(jd[i], b, false);
//System.out.println("jd " + jd[i] + " : " + b.getX1() + " " + b.getX2() + " " + b.getX3());
tmp0 = b.getX1() - coord[i][0];
tmp1 = b.getX2() - coord[i][1];
tmp2 = b.getX3() - coord[i][2];
System.out.println("jd " + jd[i] + " : " + tmp0 + " " + tmp1 + " " + tmp2);
}
}// end testPositions()
//**************** testVelocities() ************************
/** Method used to test the second version of class Pluto99 (with phi in radians);
<BR>The refence values are obtained from <CODE>Pluto99_deg.java</CODE>., in the current directory
*/
public static void testVelocities(){
// compute the average speed, in a.u. per Julian year.
double aphelion = 7304.3E6 / 149597870.61; // in a.u.
double perihelion = 4435E6 / 149597870.61; // in a.u.
double period = 90588 / 365.25; // in years
double r = (aphelion + perihelion) / 2;
double meanVel = 2 * Math.PI * r / period;
System.out.println("meanVel : " + meanVel);
double start = 626150.5, end = 2811150.5; // start and end dates
double testInterval = 10000; // a test will be done every 'testInterval' days
double curJd = start + testInterval;
double deltaT = 0.1;
double years = 2 * deltaT / 365.25;
double dist;
double v1, v2, v3;
Body bi = new Body (SolarSystemConstants.PLUTO); // t - deltaT
Body b = new Body (SolarSystemConstants.PLUTO); // t
Body bf = new Body (SolarSystemConstants.PLUTO); // t + deltaT
while(curJd < end - deltaT){
Pluto99.calcCoord(curJd - deltaT, bi, false);
Pluto99.calcCoord(curJd, b, true);
Pluto99.calcCoord(curJd + deltaT, bf, false);
// distance between bi and bf - in a.u.
dist = Math.sqrt((bi.getX1()-bf.getX1())*(bi.getX1()-bf.getX1())
+(bi.getX2()-bf.getX2())*(bi.getX1()-bf.getX2())
+(bi.getX3()-bf.getX3())*(bi.getX1()-bf.getX3())
);
v1 = (bf.getX1()-bi.getX1())/years;
v2 = (bf.getX2()-bi.getX2())/years;
v3 = (bf.getX3()-bi.getX3())/years;
System.out.println("b.v1 = " + b.getV1() + " meanV : " + v1 + " - diff : " + (b.getV1() - v1));
System.out.println("b.v2 = " + b.getV2() + " meanV : " + v2 + " - diff : " + (b.getV2() - v2));
System.out.println("b.v3 = " + b.getV3() + " meanV : " + v3 + " - diff : " + (b.getV3() - v3));
// increment curJD for next test
curJd += testInterval;
}
/* int i;
double tmp0, tmp1, tmp2;
double[] res = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // contains the results
Body b = new Body (SolarSystemConstants.PLUTO);
for (i = 0; i< NB_TESTS; i++){
Pluto99.calcCoord(jd[i], b, false);
//System.out.println("jd " + jd[i] + " : " + b.getX1() + " " + b.getX2() + " " + b.getX3());
tmp0 = b.getX1() - coord[i][0];
tmp1 = b.getX2() - coord[i][1];
tmp2 = b.getX3() - coord[i][2];
System.out.println("jd " + jd[i] + " : " + tmp0 + " " + tmp1 + " " + tmp2);
}
*/
}// end testVelocities()
//**************** calcGeocentricPrecision() ************************
/** Small method which calculates the geocentric precision an error of 0.00005 u.a. represents. */
public static void calcGeoPrec(){
double deltaPos = 0.00005; // u.a.
// minimal distance between Sun and Pluto - approximate value found on the web.
double minDist = 28.72; // u.a.
// minDist -1 when Earth is between Sun and Pluto
double alpha = Math.atan(deltaPos / (minDist - 1)) * 206264.806247096355156473357330779; // arc seconds
System.out.println("alpha = " + alpha);
}// end calcGeoPrec
}//end class BuildTestPluto99