//*********************************************************************************
// class BuildELP82 // 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 jephem.astro.planets.elp82.ELP82;
/******************************************************************
Contains methods used to build jephem.astro.planets.elp82.ELP82.java.
<BR>This class is NOT part of 'jephem' package, and can be useful to developpers who want to transform
BDL ELP files.
@author Thierry Graff
@history Aug 18 2001 : Creation
*****************************************************************/
public class BuildELP82{
private final static String ls = System.getProperty("line.separator");
/** Number of coordinates; */
private final static int NB_COORD = 3;
/** Number of data files; */
private final static int NB_FILES = 36;
/** String containing one blank character. */
private final static String BLANK = " ";
/** String containing one minus sign. */
private final static String MINUS = "-";
/** String containing one point. */
private final static String POINT = ".";
/** Prefix of data file names. */
private final static String INPUTFILENAME_PREFIX = "ELP";
/** Suffix of data file names (original files don't have, I added '.txt' during dvpt for
convenience under windows */
private final static String INPUTFILENAME_SUFFIX = ".txt";
/** Prefix of result file names. */
private final static String OUTPUTFILENAME_PREFIX = "dataELP";
/** Suffix of result file names (original files don't have, I added '.txt' during dvpt for
convenience under windows */
private final static String OUTPUTFILENAME_SUFFIX = ".txt";
/** Name of temp file containing integer terms. */
private final static String TEMP_INT_FILENAME = "res/fosTmpInt";
/** Name of temp file containing double terms. */
private final static String TEMP_DOUBLE_FILENAME = "res/fosTmpDouble";
/** Number of terms contained in the files.
<BR><CODE>nbTerms[i][j]</CODE> contains terms of file ELPXX where XX = i*NB_COORD + j.
<BR><B>WARNING</B> : the indication 'Records' in README specifies the nb of <B>lines</B> of
a file, which is nbTerms + 1 for data files.
<BR>Thi array was built putting 'records' - 1
*/
private static final int[][] nbTerms = {
{1023, 918, 704}, // nb terms in ELP1, ELP2, ELP3
{347, 316, 237}, // nb terms in ELP4, ELP5, ELP6
{14, 11, 8},
{14328, 5233, 6631},
{4384, 833, 1715},
{170, 150, 114},
{226, 188, 169}, // etc ...
{3, 2, 2},
{6, 4, 5},
{20, 12, 14},
{11, 4, 10},
{28, 13, 19} // nb terms in ELP34, ELP35, ELP36
}; // total 37872
/** The 36 data files can files can be grouped ; each group share the same format and the summation
done on terms of a file of a group uses the same formula.
<BR>Fisrt group contains ELP1, ELP2, ELP3 ; second group contains ELP4 ... ELP9 etc...
*/
private static final int[] fileGroups = {4, 10, 16, 22, 37};
/** Array to indicate how many columns files contain.
<BR><CODE>nbColInfileGroups[][0]</CODE> represent the nb of columns of integers ;
<BR><CODE>nbColInfileGroups[][1]</CODE> represent the nb of columns of doubles ;
<BR>For example, files ELP1, 2 and 3 (first group) contain 4 columns of integers and 1 of double
(this example is particular : files contain 7 cols of doubles, but only 1 is used in the formulae).
*/
private static final int[][] nbColInfileGroups = { {4, 6},
{5, 2},
{11, 2},
{11, 2},
{5, 2}
};
/** Array to indicate limits of interesting parts of parsed files.
(index based on 0 - correspond to groups as defined in 'fileGroups'. */
private static final int[][] interestingParts = { {0, 87},
{0, 35},
{0, 53},
{0, 53},
{0, 35}
};
//************************* main ********************************
public static void main(String[] args){
transformELP82(args);
//testClass();
//testGetFirstNumber();
//countTerms();
}// end main
//**************** transformELP82() ************************
/** Method to build java-formatted arrays from ELP82 original files.
<BR>Original BDL files must be in a subdirectory called 'data'
<BR>Results are stored in a subdirectory called 'res'.
<BR>3 ways to use it :
<LI><B>Without argument</B> : file ELP1 to 36 must be in /data ; all files are parsed.</LI>
<LI><B>One numeric argument</B> (between 1 and 36) : only the corresponding file is parsed.</LI>
<LI><B>One argument of type x[x]-y[y]</B> (where x and y represent numerical digits and [] means 'optionnaly' -
example : "8-15")</LI> : files between the two numbers are parsed - they must be in data/.
@param args array containing 0 or 1 element.
*/
public static void transformELP82(String[] args){
try{
// *** Get which files to parse. ***
// parameter parsing not bullet-proof : "1r-21" will throw a FormatNumberException
int iBegin, iEnd;
if (args.length == 0){
iBegin = 1;
iEnd = NB_FILES + 1;
}
else if (args.length == 1){
String str = args[0];
try{
iBegin = Integer.parseInt(str);
iEnd = iBegin + 1;
}
catch (NumberFormatException nfe){
// format should be : x[x]-y[y]
int i = str.indexOf("-");
if (i == -1)
throw new Exception("Bad syntax in parameter " + str);
else{
iBegin = Integer.parseInt(str.substring(0, i));
iEnd = Integer.parseInt(str.substring(i+1)) + 1;
}
}
}
else
throw new Exception("Only one parameter possible.");
System.out.println("Parsing files ELP" + iBegin + " to ELP" + iEnd);
// Declaration of variables
String line = new String(); // current line read
String strRes; // result Strings.
File curFile; // current file parsed (input file)
int iCurFile; // index of the current file parsed.
String strCurFileIndex; // String representation of iCurFile.
String curFileZ; // addZero done on iCurFile
String inputFileName, outputFileName;
int curFileGroup; // file group of the current file parsed.
int a, b; // to retrieve indexes of nbTerms from iCurFile.
int i, j; // to loop on the input files.
LineNumberReader lnr;
FileOutputStream fos;
// ***** Loop on the files to parse
for (iCurFile = iBegin; iCurFile < iEnd; iCurFile++){ // MAIN LOOP
strCurFileIndex = String.valueOf(iCurFile);
curFileZ = addZero(iCurFile);
curFileGroup = findFileGroup(iCurFile);
//System.out.println("File : " + iCurFile + " - group : " + curFileGroup + " - " + curNbIntCol + " " + curNbDoubleCol);
inputFileName = "data/" + INPUTFILENAME_PREFIX + strCurFileIndex + INPUTFILENAME_SUFFIX;
outputFileName = "res/" + OUTPUTFILENAME_PREFIX + curFileZ + OUTPUTFILENAME_SUFFIX;
System.out.println("Parsing file " + inputFileName);
curFile = new File(inputFileName);
lnr = new LineNumberReader(new FileReader(curFile));
fos = new FileOutputStream(new File(outputFileName));
// Find out how many lines current file contains.
a = (int)Math.floor((iCurFile - 1)/NB_COORD);
b = (iCurFile - 1)%NB_COORD;
//System.out.println("nbTerms[" + a + "][" + b + "] = " + nbTerms[a][b]);
// ***** 1 - Write general header (copy first line of the file)
line = lnr.readLine().trim() + ls; // skip first line (header present in all data files).
fos.write(line.getBytes());
// ***** 2 - Parse line after line of input file.
for(i = 0; i < nbTerms[a][b]; i++){
line = lnr.readLine();
strRes = line.substring(interestingParts[findFileGroup(iCurFile)][0],
interestingParts[findFileGroup(iCurFile)][1]) + ls;
fos.write(strRes.getBytes());
if (i%50 == 0) System.out.println(INPUTFILENAME_PREFIX + strCurFileIndex + " - line nb " + i); // log
}// end for(i = 0; i < nbTerms[a][b]; i++)
fos.close();
} // end for (int iCurFile = iBegin; iCurFile < iEnd) // MAIN LOOP ON INPUT FILES
}
catch(Exception e){
//System.out.println("Exception : " + e.toString());
e.printStackTrace();
}
}// end transformELP82()
//**************** findFileGroup ************************
/** Auxiliary method used by <CODE>transformELP82</CODE>.
@param fileIndex The index characterizing a file (1 - 36)
@returns the groupFile of <CODE>fileIndex</CODE>.
*/
private static int findFileGroup(int fileIndex){
for (int i = 0; i < fileGroups.length; i++){
if (fileIndex < fileGroups[i]){
return i;
}
}
return -1; // should not happen
}// end findFileGroup
//**************** getFirstNumber ************************
/** Returns a String representation of the first number found in a String.
<BR>Auxiliary method used by <CODE>transformELP82</CODE>.
Two successive integers are not necessarily separated by a blank.
So usual method with substring(BLANK) can't be applied.
@param line The String to parse.
*/
private static String getFirstNumber(String line){
String strRes = "";
int i = 0;
// get rid of first charcters not belonging to a number
while(i < line.length() && !Character.isDigit(line.charAt(i)) && !line.substring(i, i+1).equals(MINUS)){ while(i < line.length() && !Character.isDigit(line.charAt(i)) && !line.substring(i, i+1).equals(MINUS)){
i++;
}
// handle minus sign
if (i < line.length() && line.substring(i, i+1).equals(MINUS)){ if (i < line.length() && line.substring(i, i+1).equals(MINUS)){
strRes += MINUS;
i++;
}
// get the number (digits or point).
while(i < line.length() && (Character.isDigit(line.charAt(i)) || line.substring(i, i+1).equals(POINT))){ while(i < line.length() && (Character.isDigit(line.charAt(i)) || line.substring(i, i+1).equals(POINT))){
strRes += line.substring(i, i+1);
i++;
}
return strRes;
}// end getFirstNumber
//**************** testGetFirstNumber() ************************
/** Just test before use... */
public static void testGetFirstNumber(){
//String line = " 0 0 0 0 0 0 0 0 0 0 1 179.93197 0.00068 0.075".trim();
String line = " 0 0 5-12 0 0 0 0 -2 0 3 49.96695 0.00003 0.071".trim();
int NB_NUMBERS = 14;
String strNumber;
for(int i = 0; i < NB_NUMBERS; i++){
strNumber = getFirstNumber(line);
System.out.println("strNumber : " + strNumber);
line = line.trim();
line = line.substring(strNumber.length());
}
}// end testGetFirstNumber
//***************************** addZero ***************************************
// Taken from reference implementation in tig.util.Formats.java
/** Formats a integer to a 2 character long String. Useful for date formatting.
@param nb integer number to format.
@return A String representation of <CODE>nb</CODE> :
<LI>if <CODE>0 <= nb <= 9</CODE>, "0" followed by the digit ;</LI>
<LI>if <CODE>10 <= nb <= 99</CODE>, the two digits ;</LI>
<LI>if <CODE>nb < 0 or nb > 100</CODE>, the String "xx".</LI>
*/
private static String addZero(int nb){
if (nb<0 || nb>99) return "xx";
if (nb<10) return "0" + String.valueOf(nb);
else return String.valueOf(nb);
}// end addZero
//**************** countTerms() ************************
/** Counts the number of total terms. */
public static void countTerms(){
int res = 0;
for(int i = 0; i < NB_FILES/NB_COORD; i++)
for(int j = 0; j < NB_COORD; j++)
res += nbTerms[i][j];
System.out.println("Total nb terms in ELP82 : " + res);
}// end countTerms
}//end class BuildELP82