001    package edu.nrao.sss.model.resource;
002    
003    import java.util.List;
004    import java.util.SortedSet;
005    
006    import edu.nrao.sss.measure.Frequency;
007    import edu.nrao.sss.measure.FrequencyRange;
008    import edu.nrao.sss.util.Identifiable;
009    
010    /**
011     * A portion of a correlator baseband.
012     * <p>
013     * The main properties of a subband are its location in frequency space,
014     * its (re)quantization, and its correlation products.  Rather than
015     * hold its correlation products directly, this subband holds them
016     * indirectly through {@link CorrelationProductGroup groups of
017     * correlation products}.  A group is formed by a collection of products
018     * that have identical properties, such as integration times or
019     * allocated correlator resources.  For applications that do not make
020     * use of groups, merely populate a group with a single product.</p>  
021     * <p>
022     * <b>Version Info:</b>
023     * <table style="margin-left:2em">
024     *   <tr><td>$Revision: 1986 $</td></tr>
025     *   <tr><td>$Date: 2009-02-19 16:47:31 -0700 (Thu, 19 Feb 2009) $</td></tr>
026     *   <tr><td>$Author: dharland $ (last person to modify)</td></tr>
027     * </table></p>
028     * 
029     * @author David M. Harland
030     * @since 2008-01-23
031     */
032    public interface CorrelatorSubband
033      extends Cloneable, HasBandwidth, Identifiable
034    {
035      /**
036       * Resets this instance's ID, and the IDs of all its components,
037       * to a value that represents the unidentified state.
038       * <p>
039       * This method is useful for preparing an instance for storage in a database.
040       * The ID property (as of now, though this may change in the future) is
041       * used by our persistence mechanism to identify objects.  If you are
042       * persisting this instance for the first time, you may need to call
043       * this method before performing a save.  This is especially true if
044       * you have created this instance from XML, as the XML unmarshalling
045       * brings along the ID property.</p> 
046       */
047      public void clearId();
048      
049      /**
050       * Sets the (optional) name of this subband.
051       * The default state is to have no name.
052       * 
053       * @param newName
054       *   the new name for this subband.  A value of <i>null</i> may be used to
055       *   make this an unnamed subband, which is its default state.
056       */
057      public void setName(String newName);
058      
059      /**
060       * Returns the name of this subband.  If this subband has no name,
061       * the empty string (<tt>""</tt>) is returned.
062       * 
063       * @return
064       *   the name of this subband or the empty string if it has no name.
065       */
066      public String getName();
067    
068      //============================================================================
069      // FREQUENCY
070      //============================================================================
071    
072      /**
073       * Sets the bandwidth of this subband.
074       * <p>
075       * An attempt to set the bandwidth to a value lower than this subband's
076       * minimum will result in a bandwidth equal to the lowest allowable,
077       * and likewise for exceeding this subband's maximum.</p>
078       * <p>
079       * If this subband has a discrete set of allowable bandwidths, then this
080       * method will set the bandwidth to that which is closest to
081       * {@code newWidth}.  If the {@code newWidth} is
082       * not an allowable bandwidth and is
083       * equally distant from two allowable values, this
084       * subband's bandwidth will be set to the smaller of those values.</p>
085       * <p>
086       * When changing the bandwidth, this method will attempt to leave this
087       * subband's center where it is.  However, if doing so would result in
088       * a frequency range whose low value is less than zero, the center
089       * will be reset to be half of the bandwidth.</p>
090       * 
091       * @param newWidth
092       *   the new bandwidth of this subband.
093       */
094      public void setBandwidth(Frequency newWidth);
095      
096      /**
097       * Sets the central frequency of this subband.
098       * <p>
099       * When moving the center, this method will always leave the bandwidth
100       * unchanged.  If an attempt is made to move the center in such a way
101       * that the low end of this subband's range would be negative, the
102       * center will be moved to the lowest value that would not force
103       * this subband to contain negative frequencies.  This value is
104       * equal to one half the bandwidth.  Likewise, if this subband belongs
105       * to a baseband, this method will not move the center frequency
106       * such that any part of this subband extends beyond the high
107       * end of its baseband.</p>
108       * 
109       * @param newCenter
110       *   the central frequency of this subband.
111       */
112      public void setCentralFrequency(Frequency newCenter);
113      
114      /**
115       * Returns the central frequency of this subband.
116       * @return the central frequency of this subband.
117       */
118      public Frequency getCentralFrequency();
119    
120      /**
121       * Returns the smallest allowable central frequency for this subband.
122       * The returned value will be equal to half of this subband's bandwidth.
123       * 
124       * @return the smallest allowable central frequency for this subband.
125       */
126      public Frequency getMinimumCentralFrequency();
127    
128      /**
129       * Returns the largest allowable central frequency for this subband.
130       * If this subband belongs to no baseband, the returned value is infinite.
131       * Otherwise it is equal to the bandwidth of the baseband less one
132       * half the bandwidth of this subband.
133       * 
134       * @return the largest allowable central frequency for this subband.
135       */
136      public Frequency getMaximumCentralFrequency();
137      
138      /**
139       * Returns the frequency range covered by this subband.
140       * @return the frequency range covered by this subband.
141       */
142      public FrequencyRange getFrequencyRange();
143      
144      /**
145       * Returns the portion of frequency space for which this subband is a proxy.
146       * If this subband belongs to no baseband, then the range returned is the
147       * same as the range returned by {@link #getFrequencyRange()}.  If, on the
148       * other hand, this subband belongs to a baseband, the range returned will
149       * follow this example:
150       * <pre>
151       *   Let the baseband go from 0.0GHz to 2.0GHz.
152       *   Let the above range represent sky frequencies from 41.5GHz to 43.5GHz.
153       *   If this subband has a range from 0.4GHz to 1.1GHz, the range returned
154       *   by this method will be 41.9GHz to 42.6GHz.
155       * </pre>
156       * 
157       * @return
158       *   the portion of frequency space for which this subband is a proxy.
159       */
160      public FrequencyRange getProxiedRange();
161    
162      /**
163       * Modifies this subband so that its new center is a proxy for
164       * {@code newSkyCenter}.  This subband may need to move its center
165       * in such a way that it no longer proxies {@code newSkyCenter}.
166       * This would be true if the calculated center frequency is outside
167       * of the bounds of this subband's baseband, or if there are certain
168       * restrictions for the placement of a subband within it baseband.
169       * Concrete implementations are expected to get the actual center
170       * as close as possible to the value that represents {@code newSkyCenter}.
171       *  
172       * @param newSkyCenter
173       *   the new center sky, or proxied, frequency for this subband.
174       */
175      public void setCentralProxiedFrequency(Frequency newSkyCenter);
176    
177      //============================================================================
178      // QUANTIZATION
179      //============================================================================
180    
181      /**
182       * Returns the set of allowable requantization values for this subband.
183       * @return the set of allowable requantization values for this subband.
184       */
185      public SortedSet<Integer> getAllowableRequantizations();
186      
187      /**
188       * Sets the number of bits to which data should be requantized.
189       * <p>
190       * This subband allows only certain values for the number of bits.
191       * These values are given by {@link #getAllowableRequantizations()}.
192       * If a disallowed value is sent to this method, it will be replaced
193       * by the nearest acceptable value.  If it is equally near two
194       * acceptable values, the smaller one will be used.</p>
195       * 
196       * @param bits
197       *   the number of bits to which data should be requantized.
198       */
199      public void setRequantization(int bits);
200      
201      /**
202       * Returns the number of bits to which the data in this subband will be
203       * requantized.
204       * 
205       * @return the number of bits to which the data in this subband will be
206       *         requantized.
207       *         
208       * @see CorrelatorBaseband#getInitialQuantization()
209       */
210      public int getRequantization();
211      
212      //============================================================================
213      // CORRELATION PRODUCT GROUPS
214      //============================================================================
215      
216      /**
217       * Returns this subband's collection of correlation product groups.
218       * @return this subband's collection of correlation product groups.
219       */
220      public List<CorrelationProductGroup> getCorrelationProductGroups();
221      
222      /**
223       * Creates a new correlation product group, adds it to this subband, and
224       * returns it.
225       * 
226       * @return a new correlation product group of this subband.
227       */
228      public CorrelationProductGroup addNewCorrelationProductGroup();
229      
230      /**
231       * Removes a correlation product group from this subband.
232       * 
233       * @param unwantedGroup
234       *   a correlation product group to be removed from this subband.
235       */
236      public void removeCorrelationProductGroup(CorrelationProductGroup unwantedGroup);
237      
238      //============================================================================
239      // BASEBAND
240      //============================================================================
241      
242      /**
243       * Returns the baseband to which this subband belongs.
244       * <p>
245       * Some implementations may allow for the creation of subbands apart from
246       * any baseband, with the idea that this subband would eventually be added
247       * to a baseband.  Prior to being added to a baseband the return value
248       * from this method would be <i>null</i>.</p>
249       *  
250       * @return
251       *   the baseband to which this subband belongs, or <i>null</i> if it belongs
252       *   to no baseband.
253       */
254      public CorrelatorBaseband getBaseband();
255      
256      //============================================================================
257      // VALIDATION
258      //============================================================================
259      
260      //TODO a boolean method to notify in/out of compliance?
261      //TODO a List<String> method w/ violation notices?
262      //TODO Maybe neither of above, but instead go w/ Validation framework
263      
264      //TODO go back into other methods and note that they may put this subband
265      //     into invalid state
266    
267    }