001    package edu.nrao.sss.model.project;
002    
003    import java.util.HashMap;
004    import java.util.HashSet;
005    import java.util.Map;
006    import java.util.Set;
007    
008    import edu.nrao.sss.astronomy.SkyPosition;
009    import edu.nrao.sss.model.RepositoryException;
010    import edu.nrao.sss.model.project.scan.ScanMode;
011    import edu.nrao.sss.model.source.Source;
012    import edu.nrao.sss.model.source.SourceFilter;
013    import edu.nrao.sss.model.source.SourceProvider;
014    
015    /**
016     * A selector of sources that can be used for observation calibration.
017     * <p>
018     * This class has the astronomical knowledge that is needed for choosing
019     * calibrators for different goals of source observation.  It is meant
020     * to act as a virtual astronomer for calibrator selection.</p>
021     * <p>
022     * TODO: At this time this class is a placeholder for later developement.</p> 
023     * <p>
024     * <b>Version Info:</b>
025     * <table style="margin-left:2em">
026     *   <tr><td>$Revision: 1118 $</td></tr>
027     *   <tr><td>$Date: 2008-02-26 10:52:29 -0700 (Tue, 26 Feb 2008) $</td></tr>
028     *   <tr><td>$Author: dharland $</td></tr>
029     * </table></p>
030     *  
031     * @author David M. Harland
032     * @since 2006-06-29
033     */
034    public class CalibratorSelector
035    {
036      private Set<SourceProvider> providers;
037    
038      /** Creates a new selector. */
039      public CalibratorSelector()
040      {
041        providers = new HashSet<SourceProvider>();
042      }
043    
044      //============================================================================
045      // CONFIGURATION
046      //============================================================================
047    
048      /**
049       * Adds {@code newProvider} to this selector's collection.
050       * The <i>find</i> methods will search all providers held by
051       * this selector.
052       * 
053       * @param newProvider a source provider that this selector uses when searching
054       *                    for calibrators.
055       */
056      public void addProvider(SourceProvider newProvider)
057      {
058        if (newProvider != null)
059          providers.add(newProvider);
060      }
061      
062      /** Removes all source providers from this selector. */
063      public void removeAllProviders()
064      {
065        providers.clear();
066      }
067    
068      //A method like this would determine whether this selector returned
069      //a lot of calibrators, or only those that were determined to be
070      //of some quality level.
071      //TODO
072      //public void setStringencyLevel(... level)
073      
074      //This method would set the maximum number of calibrators returned
075      //for any one type of calibration.  Like the stringency level,
076      //it would help narrow the list of calibrators returned.
077      //Presumably, this method would return the highest ranked calibrators.
078      //TODO
079      //public void setMaxCalibratorCount(int max)
080      
081      //============================================================================
082      // SELECTION
083      //============================================================================
084    
085      /**
086       * Returns a collection of calibrators that are suitable for the given
087       * observational parameters.
088       * <p>
089       * The form of the returned collection is a map where the key is an
090       * observation mode and the value is a set of zero or more calibrator
091       * sources.
092       * The map contains keys for only those modes that are deemed
093       * necessary for the given observation parameters.</p>
094       * 
095       * @param observationType
096       * @param sourcePosition
097       * 
098       * @return a map whose keys are of type
099       *         {@link ScanMode} and
100       *         whose values are sets of {@code Source}s.
101       */
102      public Map<ScanMode, Set<Source>> findCalibratorsFor(Object      observationType,
103                                                           SkyPosition sourcePosition)
104      {
105        Map<ScanMode, Set<Source>> result = 
106          new HashMap<ScanMode, Set<Source>>();
107        
108        //Find the different types of calibration needed
109        Set<ScanMode> obsModes = determineObservationModes(observationType);
110        
111        //For each calibration type, find good calibrators
112        for (ScanMode obsMode : obsModes)
113        {
114          Set<Source> sources = findCalibratorsFor(obsMode, observationType,
115                                                            sourcePosition);
116          result.put(obsMode, sources);
117        }
118    
119        return result;
120      }
121      
122      /**
123       * Returns a collection of calibrators that are suitable for the given
124       * observational parameters.
125       * <p>
126       * The form of the returned collection is a set of zero or more calibrator
127       * sources.</p>
128       * 
129       * @param observationMode
130       * @param observationType
131       * @param sourcePosition
132       * 
133       * @return a collection of calibrators.
134       */
135      public Set<Source> findCalibratorsFor(ScanMode observationMode, Object observationType, SkyPosition sourcePosition)
136      {
137        Set<Source> result = new HashSet<Source>();
138        
139        SourceFilter filter = configureFilterFor(observationMode, observationType, sourcePosition);
140        
141        for (SourceProvider provider : providers)
142        {
143          try {
144            result.addAll(provider.getSources(filter));
145          }
146          catch (RepositoryException ex) {
147            //TODO: Decide: Remove catch & have method throw?
148            //              Catch & log?
149            //              Catch & convert to diff Excep type?
150          }
151        }
152    
153        return result;
154      }
155    
156      /**
157       * Returns a set of the observation modes needed for the given
158       * observation type.
159       * 
160       * @param observationType
161       * 
162       * @return a set of observation modes.
163       */
164      private Set<ScanMode> determineObservationModes(Object observationType)
165      {
166        Set<ScanMode> result = new HashSet<ScanMode>();
167        
168        //TODO: Replace temp coding w/ real
169        for (ScanMode type : ScanMode.values())
170          result.add(type);
171        
172        return result;
173      }
174    
175      /**
176       * Returns a source filter that is configured for the given observational
177       * parameters.
178       * 
179       * @param calibration
180       * @param observationType
181       * @param observationMode
182       * @param sourcePosition
183       * 
184       * @return
185       */
186      private SourceFilter configureFilterFor(ScanMode observationMode, Object observationType, SkyPosition sourcePosition)
187      {
188        SourceFilter result = new SourceFilter();
189      
190        //TODO: configure filter here
191        
192        return result;
193      }
194    }