001    package edu.nrao.sss.astronomy;
002    
003    import java.math.BigDecimal;
004    import java.math.RoundingMode;
005    import java.util.Calendar;
006    import java.util.Date;
007    
008    import edu.nrao.sss.measure.ArcUnits;
009    import edu.nrao.sss.measure.Latitude;
010    import edu.nrao.sss.measure.Distance;
011    import edu.nrao.sss.measure.DistanceUnits;
012    import edu.nrao.sss.measure.LinearVelocity;
013    import edu.nrao.sss.measure.LinearVelocityUnits;
014    import edu.nrao.sss.measure.Longitude;
015    
016    /**
017     * Helper for test classes; builds an ephemeris table.
018     * <p>
019     * <b>Version Info:</b>
020     * <table style="margin-left:2em">
021     *   <tr><td>$Revision: 1314 $</td></tr>
022     *   <tr><td>$Date: 2008-05-30 11:31:14 -0600 (Fri, 30 May 2008) $</td></tr>
023     *   <tr><td>$Author: dharland $</td></tr>
024     * </table></p>
025     *  
026     * @since 2006-10-02
027     */
028    public class EphemerisTableBuilder
029    {
030      private Latitude       decStart,      decEnd;
031      private Longitude      raStart,       raEnd;
032      private Distance       distStart,     distEnd;
033      private LinearVelocity velocityStart, velocityEnd;
034      private Date           dateStart,     dateEnd;
035      
036      private int tableSize;
037      
038      public void setDeclinationRange(Latitude first, Latitude last)
039      {
040        decStart = first;
041        decEnd   = last;
042      }
043      
044      public void setRightAscensionRange(Longitude first, Longitude last)
045      {
046        raStart = first;
047        raEnd   = last;
048      }
049      
050      public void setDistanceRange(Distance first, Distance last)
051      {
052        distStart = first;
053        distEnd   = last;
054      }
055      
056      public void setVelocityRange(LinearVelocity first, LinearVelocity last)
057      {
058        velocityStart = first;
059        velocityEnd   = last;
060      }
061      
062      public void setDateRange(Date first, Date last)
063      {
064        dateStart = first;
065        dateEnd   = last;
066      }
067      
068      public void setTableSize(int numberOfEntries)
069      {
070        tableSize = numberOfEntries;
071      }
072      
073      public EphemerisTable makeTable()
074      {
075        EphemerisTable table = new EphemerisTable();
076        
077        table.setOriginOfInformation("EphemerisTableBuilder.java");
078    
079        int count = (tableSize > 0) ? tableSize : 10 + (int)(10.0 * Math.random());
080    
081        BigDecimal divisor = new BigDecimal(count - (count > 1 ? 1 : 0));
082        
083        Calendar cal = Calendar.getInstance();
084        Date[] dates = getDates();
085        long date = dates[0].getTime();
086        long dateIncr = (dates[1].getTime() - date) / divisor.longValue();
087        
088        Latitude[] decs = getDeclinations();
089        BigDecimal decDegrees = decs[0].toUnits(ArcUnits.DEGREE);
090        BigDecimal decIncr = decs[1].toUnits(ArcUnits.DEGREE)
091                                    .subtract(decDegrees).divide(divisor, RoundingMode.HALF_UP);
092        
093        Longitude[] ras = getRightAscensions();
094        BigDecimal raDegrees = ras[0].toUnits(ArcUnits.DEGREE);
095        BigDecimal raIncr = ras[1].toUnits(ArcUnits.DEGREE)
096                                  .subtract(raDegrees).divide(divisor, RoundingMode.HALF_UP);
097        
098        Distance[] dists = getDistances();
099        BigDecimal au = dists[0].toUnits(DistanceUnits.ASTRONOMICAL_UNIT);
100        BigDecimal auIncr = dists[1].toUnits(DistanceUnits.ASTRONOMICAL_UNIT)
101                                    .subtract(au).divide(divisor, RoundingMode.HALF_UP);
102        
103        LinearVelocity[] speeds = getVelocities();
104        BigDecimal kms = speeds[0].toUnits(LinearVelocityUnits.KILOMETERS_PER_SECOND);
105        BigDecimal kmsIncr = speeds[1].toUnits(LinearVelocityUnits.KILOMETERS_PER_SECOND)
106                                      .subtract(kms).divide(divisor, RoundingMode.HALF_UP);
107    
108        for (int e=0; e < count; e++)
109        {
110          EphemerisTableEntry entry = new EphemerisTableEntry();
111          
112          cal.setTimeInMillis(date);
113          entry.setTime(cal.getTime());
114          date += dateIncr;
115          
116          entry.setLatitude(new Latitude(decDegrees));
117          decDegrees = decDegrees.add(decIncr);
118          
119          entry.setLongitude(new Longitude(raDegrees));
120          raDegrees = raDegrees.add(raIncr);
121          
122          entry.setDistance(new Distance(au, DistanceUnits.ASTRONOMICAL_UNIT));
123          au = au.add(auIncr);
124          
125          entry.setVelocity(new LinearVelocity(kms));
126          kms.add(kmsIncr);
127          
128          table.add(entry);
129        }
130        
131        return table;
132      }
133      
134      private Latitude[] getDeclinations()
135      {
136        Latitude[] decs = new Latitude[2];
137        
138        decs[0] = (decStart == null) ?
139          new Latitude(Double.toString(-90.0 + 180.0 * Math.random())) : decStart;
140        
141        decs[1] = (decEnd == null) ?
142          new Latitude(Double.toString(-90.0 + 180.0 * Math.random())) : decEnd;
143        
144        return decs;
145      }
146      
147      private Longitude[] getRightAscensions()
148      {
149        Longitude[] ras = new Longitude[2];
150        
151        ras[0] = (raStart == null) ?
152          new Longitude(Double.toString(360.0 * Math.random())) : raStart;
153        
154        ras[1] = (raEnd == null) ?
155          new Longitude(Double.toString(360.0 * Math.random())) : raEnd;
156        
157        return ras;
158      }
159      
160      private Distance[] getDistances()
161      {
162        Distance[] dists = new Distance[2];
163        
164        dists[0] = (distStart == null) ?
165          new Distance(Double.toString(3.0 + 47.0 * Math.random()),
166                                       DistanceUnits.ASTRONOMICAL_UNIT) : distStart;
167        
168        dists[1] = (distEnd == null) ?
169          new Distance(Double.toString(3.0 + 47.0 * Math.random()),
170                                       DistanceUnits.ASTRONOMICAL_UNIT) : distEnd;
171        
172        return dists;
173      }
174      
175      private LinearVelocity[] getVelocities()
176      {
177        LinearVelocity[] speeds = new LinearVelocity[2];
178        
179        speeds[0] = (velocityStart == null) ?
180          new LinearVelocity(Double.toString(-100.0 + 200.0 * Math.random())) : velocityStart;
181        
182        speeds[1] = (velocityEnd == null) ?
183          new LinearVelocity(Double.toString(-100.0 + 200.0 * Math.random())) : velocityEnd;
184        
185        return speeds;
186      }
187      
188      private Date[] getDates()
189      {
190        Date[] dates = new Date[2];
191    
192        Calendar cal = Calendar.getInstance();
193    
194        if ((dateStart != null) && (dateEnd != null))
195        {
196          dates[0] = dateStart;
197          dates[1] = dateEnd;
198        }
199        else if ((dateStart != null) && (dateEnd == null))
200        {
201          cal.setTime(dateStart);
202          cal.add(Calendar.MONTH, 3);
203          dates[0] = dateStart;
204          dates[1] = cal.getTime();
205        }
206        else if ((dateStart == null) && (dateEnd != null))
207        {
208          cal.setTime(dateEnd);
209          cal.add(Calendar.MONTH, -3);
210          dates[0] = cal.getTime();
211          dates[1] = dateEnd;
212        }
213        else //if ((dateStart == null) && (dateEnd == null))
214        {
215          dates[0] = cal.getTime();
216          cal.add(Calendar.MONTH, 3);
217          dates[1] = cal.getTime();
218        }
219        
220        return dates;
221      }
222      /*
223      public static void main(String[] args)
224      {
225        EphemerisTableBuilder etb = new EphemerisTableBuilder();
226        System.out.println(etb.makeTable());
227      }
228      */
229    }