001    package edu.nrao.sss.model.resource.evla;
002    
003    import java.util.ArrayList;
004    import java.util.Collection;
005    import java.util.List;
006    import java.util.SortedSet;
007    import java.util.TreeSet;
008    
009    import edu.nrao.sss.electronics.DigitalSignal;
010    import edu.nrao.sss.electronics.Digitizer;
011    import edu.nrao.sss.electronics.SignalPipe;
012    import edu.nrao.sss.electronics.SignalProcessor;
013    import edu.nrao.sss.electronics.SignalSampler;
014    import edu.nrao.sss.measure.Frequency;
015    
016    /**
017     * The EVLA D301 Sampler / DTS.
018     * <p>
019     * This device holds a single eight-bit sampler and a pair of three-bit
020     * samplers.  The output of this device is derived from either the 8-bit
021     * or the two 3-bit input streams.</p>
022     * <p>
023     * As used by the {@link EvlaAntennaElectronics EVLA electronics}, the
024     * inputs are feed by a pair of T304 downconverters.  In 8-bit mode,
025     * a single T304 is connected to one of the four D301s.  In 3-bit mode,
026     * a single D301 is connected to a pair of T304s, either an A/C or B/D
027     * (RCP/LCP) pair.</p>
028     * <img src="doc-files/D301.png" alt="D301 Dgm"/>
029     * <p>
030     * <b>Version Info:</b>
031     * <table style="margin-left:2em">
032     *   <tr><td>$Revision: 1241 $</td></tr>
033     *   <tr><td>$Date: 2008-04-25 14:37:37 -0600 (Fri, 25 Apr 2008) $</td></tr>
034     *   <tr><td>$Author: dharland $ (last person to modify)</td></tr>
035     * </table></p>
036     * 
037     * @author David M. Harland
038     * @since 2007-11-02
039     */
040    public class D301
041      implements SignalProcessor, Digitizer
042    {
043      private static final String DEFAULT_NAME = "[unnamed-D301]";
044      
045      private String name;
046      
047      private SignalSampler eightBitSampler;
048      private SignalSampler threeBitSampler0;
049      private SignalSampler threeBitSampler1;
050      
051      private int configuredForBits;
052    
053      //============================================================================
054      // OBJECT CONSTRUCTION
055      //============================================================================
056    
057      /**
058       * Creates a new D301 with the given name.  This D301 is initially
059       * configured to produce eight-bit output.
060       * 
061       * @param deviceName
062       *   an optional name for this device.  If this value is <i>null</i>
063       *   a default name will be used in its place.
064       */
065      public D301(String deviceName)
066      {
067        name = (deviceName == null) ? DEFAULT_NAME : deviceName;
068        
069        constructInternalComponents();
070        connectInternalComponents();
071        
072        setBitsPerSample(8);
073      }
074      
075      /**
076       * Builds, but does not connect, the internal components of this device.
077       */
078      private void constructInternalComponents()
079      {
080        eightBitSampler = new SignalSampler(name+"-8bit", 8, new Frequency("2.048"));
081      
082        Frequency rate = new Frequency("4.096");
083        
084        threeBitSampler0 = new SignalSampler(name+"-3bit-0", 3, rate);
085        threeBitSampler1 = new SignalSampler(name+"-3bit-1", 3, rate);
086      }
087      
088      /**
089       * Connects the prebuilt internal components of this device to one another.
090       */
091      private void connectInternalComponents()
092      {
093        //no longer connecting anything
094      }
095    
096      //============================================================================
097      // 
098      //============================================================================
099    
100      /**
101       * Returns the name of this device.
102       * @return the name of this device.
103       */
104      public String getName()
105      {
106        return name;
107      }
108      
109      /**
110       * Returns the input pipe that feeds the internal 8-bit sampler.
111       * A typical usage pattern for this method is:<pre>
112       * myDigitizer.getEightBitInputPipe().connectInputTo(mySource);</pre>
113       * 
114       * @return the input pipe that feeds the internal 8-bit sampler.
115       */
116      public SignalPipe getEightBitInputPipe()
117      {
118        return eightBitSampler.getInputPipe();
119      }
120      
121      /**
122       * Returns the input pipes that feed the internal 3-bit samplers.
123       * A typical usage pattern for this method is:<pre>
124       * myDigitizer.getThreeBitInputPipes().get(0).connectInputTo(mySource);</pre>
125       * 
126       * @return the input pipe that feeds the internal 8-bit sampler.
127       */
128      public List<SignalPipe> getThreeBitInputPipes()
129      {
130        List<SignalPipe> inputs = new ArrayList<SignalPipe>();
131        
132        inputs.add(threeBitSampler0.getInputPipe());
133        inputs.add(threeBitSampler1.getInputPipe());
134        
135        return inputs;
136      }
137      
138      /* (non-Javadoc)
139       * @see edu.nrao.sss.electronics.Digitizer#getBitsPerSample()
140       */
141      public int getBitsPerSample()
142      {
143        return configuredForBits;
144      }
145      
146      /**
147       * Configures this digitizer so that it produces output with
148       * the given number of bits per sample.
149       * <p>
150       * The only legal values for this digitizer are <tt>3</tt> and <tt>8</tt>.
151       * Other values will be converted to the nearest legal value.</p>
152       * 
153       * @param numberOfBits
154       *   the type of output, expressed as bits per sample, that this
155       *   digitizer should produce.
156       */
157      public void setBitsPerSample(int numberOfBits)
158      {
159        configuredForBits = (numberOfBits <= 5) ? 3 : 8;
160      }
161      
162      /* (non-Javadoc)
163       * @see edu.nrao.sss.electronics.Digitizer#getAllowableBitsPerSample()
164       */
165      public SortedSet<Integer> getAllowableBitsPerSample()
166      {
167        SortedSet<Integer> allowable = new TreeSet<Integer>();
168        allowable.add(3);
169        allowable.add(8);
170        return allowable;
171      }
172      
173      /**
174       * Returns the signals produced by this digitizer.
175       * <p>
176       * In 8-bit mode, the returned collection will hold a single signal.
177       * In 3-bit mode, the returned collection will hold two signals.</p>
178       * 
179       * @return the signals produced by this digitizer.
180       */
181      public Collection<DigitalSignal> getSignals()
182      {
183        Collection<DigitalSignal> signals = new ArrayList<DigitalSignal>();
184        
185        if (configuredForBits == 8)
186        {
187          DigitalSignal s = eightBitSampler.getMostRecentOutput();
188          if (s != null)
189            signals.add(s);
190        }
191        else //3-bit output
192        {
193          DigitalSignal s = threeBitSampler0.getMostRecentOutput();
194          if (s != null)
195            signals.add(s);
196          
197          s = threeBitSampler1.getMostRecentOutput();
198          if (s != null)
199            signals.add(s);
200        }
201        
202        return signals;
203      }
204    
205      /** Sets the names of this devices outputs. */
206      void setOutputNames(String eightBitOutput,
207                          String threeBitOutput1, String threeBitOutput2)
208      {
209        eightBitSampler.setName(eightBitOutput);
210        threeBitSampler0.setName(threeBitOutput1);
211        threeBitSampler1.setName(threeBitOutput2);
212      }
213    
214      /**
215       * Erases this device's memory of its most recent execution.
216       * @see #getSignals()
217       */
218      public void eraseSignalMemory()
219      {
220        eightBitSampler.eraseSignalMemory();
221        threeBitSampler0.eraseSignalMemory();
222        threeBitSampler1.eraseSignalMemory();
223      }
224    
225      //============================================================================
226      // INTERFACE SignalProcessor
227      //============================================================================
228      
229      /**
230       * Runs the internal samplers for which this digitizer has been
231       * {@link #configuredForBits configured}.  The results of the execution
232       * are available via the {@link #getSignals()} method.
233       */
234      public void execute()
235      {
236        runSamplers();    
237      }
238      
239      /**
240       * See {@link SignalProcessor#executeUpTo(SignalProcessor)}.
241       */
242      public void executeUpTo(SignalProcessor firstUnexecutedDevice)
243      {
244        if (firstUnexecutedDevice != this)
245        {
246          runSamplers();    
247        }
248      }
249    
250      /**
251       * See {@link SignalProcessor#executeFromStartOfChainUpTo(SignalProcessor)}.
252       */
253      public void executeFromStartOfChainUpTo(SignalProcessor firstUnexecutedDevice)
254      {
255        if (configuredForBits == 3)
256        {
257          threeBitSampler0.executeFromStartOfChainUpTo(firstUnexecutedDevice);
258          threeBitSampler1.executeFromStartOfChainUpTo(firstUnexecutedDevice);
259        }
260        else if (configuredForBits == 8)
261        {
262          eightBitSampler.executeFromStartOfChainUpTo(firstUnexecutedDevice);
263        }
264      }
265    
266      /** Does the work for the execute methods. */
267      private void runSamplers()
268      {
269        if (configuredForBits == 3)
270        {
271          threeBitSampler0.executeUpTo(threeBitSampler0.getOutputPipe());
272          threeBitSampler1.executeUpTo(threeBitSampler1.getOutputPipe());
273        }
274        else if (configuredForBits == 8)
275        {
276          eightBitSampler.executeUpTo(eightBitSampler.getOutputPipe());
277        }
278      }
279    
280      //============================================================================
281      // 
282      //============================================================================
283      /*
284      public static void main(String[] args) throws Exception
285      {
286        D301 d301 = new D301("Test D301");
287        
288        d301.getEightBitInputPipe().connectInputTo(new SignalSource()
289        {
290          public Signal getSignal()
291          {
292              return new Signal(new FrequencyRange(new Frequency(1.024),
293                                                   new Frequency(2.048)), PolarizationType.L);
294          } 
295        });
296        
297        d301.getThreeBitInputPipes().get(0).connectInputTo(new SignalSource()
298        {
299          public Signal getSignal()
300          {
301              return new Signal(new FrequencyRange(new Frequency(2.048),
302                                                   new Frequency(4.096)), PolarizationType.L);
303          } 
304        });
305        
306        d301.getThreeBitInputPipes().get(1).connectInputTo(new SignalSource()
307        {
308          public Signal getSignal()
309          {
310              return new Signal(new FrequencyRange(new Frequency(2.048),
311                                                   new Frequency(4.096)), PolarizationType.L);
312          } 
313        });
314    
315        d301.configureForOutputBits(8);
316        
317        d301.execute();
318        
319        System.out.println("Output Signals");
320        System.out.println();
321    
322        for (Signal output : d301.getSignals())
323        {
324          System.out.println(output);
325        }
326      }
327      */
328    }