001 package edu.nrao.sss.model.resource.vla; 002 003 import java.math.BigDecimal; 004 import java.util.ArrayList; 005 import java.util.List; 006 import java.util.SortedSet; 007 import java.util.TreeSet; 008 009 import javax.xml.bind.annotation.XmlElement; 010 import javax.xml.bind.annotation.XmlRootElement; 011 012 import edu.nrao.sss.astronomy.PolarizationType; 013 import edu.nrao.sss.electronics.DigitalSignal; 014 import edu.nrao.sss.measure.Frequency; 015 import edu.nrao.sss.measure.FrequencyRange; 016 import edu.nrao.sss.measure.FrequencyUnits; 017 import edu.nrao.sss.model.resource.CorrelatorBasebandAbs; 018 import edu.nrao.sss.model.resource.CorrelatorConfiguration; 019 import edu.nrao.sss.model.resource.CorrelatorSubband; 020 021 /** 022 * A baseband pair of the VLA correlator. 023 * <p> 024 * This class is here for completeness but might never be used. 025 * We have a short-term mission to support the VLA correlator, 026 * but VLA support will end once WIDAR takes over.</p> 027 * <p> 028 * <b>Version Info:</b> 029 * <table style="margin-left:2em"> 030 * <tr><td>$Revision: 2271 $</td></tr> 031 * <tr><td>$Date: 2009-04-28 12:02:17 -0600 (Tue, 28 Apr 2009) $</td></tr> 032 * <tr><td>$Author: dharland $ (last person to modify)</td></tr> 033 * </table></p> 034 * 035 * @author David M. Harland 036 * @since 2008-06-25 037 */ 038 @XmlRootElement 039 public class VlaBasebandPair 040 extends CorrelatorBasebandAbs 041 { 042 private static final Frequency MIN_BW = 043 new Frequency("195312.5", FrequencyUnits.HERTZ); 044 045 private static final Frequency MAX_BW = 046 new Frequency("50000000.0", FrequencyUnits.HERTZ); 047 048 @XmlElement private DigitalSignal inputSignalA; 049 @XmlElement private DigitalSignal inputSignalB; 050 051 private VlaConfiguration container; 052 053 /** 054 * Helps create a new VLA baseband pair. 055 * @throws IllegalArgumentException 056 * if {@code input} is <i>null</i>. 057 */ 058 protected VlaBasebandPair(DigitalSignal inputA, DigitalSignal inputB) 059 { 060 this(); 061 initInput(inputA, inputB); 062 } 063 064 //This is here only for persistence mechanisms 065 protected VlaBasebandPair() 066 { 067 super(); 068 container = null; 069 } 070 071 /** Sets the input signal for this baseband. */ 072 private void initInput(DigitalSignal inputA, DigitalSignal inputB) 073 { 074 if (inputA == null || inputB == null) 075 throw new IllegalArgumentException( 076 "Cannot configure correlator baseband with a NULL input signal."); 077 078 //TODO Do we need to compare the inputs to make sure they have 079 // same freq range? Same init quant? Diff polzns? 080 inputSignalA = inputA; 081 inputSignalB = inputB; 082 } 083 084 //============================================================================ 085 // IDENTIFICATION 086 //============================================================================ 087 088 /* (non-Javadoc) 089 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getName() 090 */ 091 public String getName() 092 { 093 return inputSignalA.getName() + "/" + inputSignalB.getName(); 094 } 095 096 /* (non-Javadoc) 097 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#isSinglet() 098 */ 099 public boolean isSinglet() { return false; } 100 101 //============================================================================ 102 // CONTAINER 103 //============================================================================ 104 105 /** 106 * Returns the correlator configuration that holds this baseband. 107 * It is possible for the returned value to be <i>null</i>. 108 * If not <i>null</i>, the returned object will always be of type 109 * {@link VlaConfiguration}. 110 */ 111 protected CorrelatorConfiguration getContainer() 112 { 113 return container; 114 } 115 116 /** 117 * Sets the correlator configuration to which this baseband belongs. 118 * The {@code newContainer} is allowed to be <i>null</i>. 119 * If not <i>null</i>, the type of {@code newContainer} must be 120 * {@link VlaConfiguration}. 121 */ 122 protected void setContainer(CorrelatorConfiguration newContainer) 123 { 124 container = (VlaConfiguration)newContainer; 125 } 126 127 //============================================================================ 128 // FREQUENCY 129 //============================================================================ 130 131 /* (non-Javadoc) 132 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getProxiedRange() 133 */ 134 public FrequencyRange getProxiedRange() 135 { 136 return getProxiedRange(inputSignalA); 137 } 138 139 /* (non-Javadoc) 140 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#proxiedRangeIsReversed() 141 */ 142 public boolean proxiedRangeIsReversed() 143 { 144 return inputSignalA.proxiedRangeIsReversed(); 145 } 146 147 /* (non-Javadoc) 148 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getMinimumBandwidth() 149 */ 150 public Frequency getMinimumBandwidth() 151 { 152 return MIN_BW.clone(); 153 } 154 155 /* (non-Javadoc) 156 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getMaximumBandwidth() 157 */ 158 public Frequency getMaximumBandwidth() 159 { 160 return MAX_BW.clone(); 161 } 162 163 /* (non-Javadoc) 164 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#hasDiscreteBandwidths() 165 */ 166 public boolean hasDiscreteBandwidths() 167 { 168 return true; 169 } 170 171 /* (non-Javadoc) 172 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getAllowableBandwidths() 173 */ 174 public SortedSet<Frequency> getAllowableBandwidths() 175 { 176 SortedSet<Frequency> bws = new TreeSet<Frequency>(); 177 178 BigDecimal minHz = getMinimumBandwidth().toUnits(FrequencyUnits.HERTZ); 179 180 double maxHz = 181 getMaximumBandwidth().toUnits(FrequencyUnits.HERTZ).doubleValue(); 182 183 //Only non-negative powers-of-two multiples of min are allowed 184 //However, the frequency that corresponds to twice 185 //the minimum is not allowed. 186 bws.add(new Frequency(minHz, FrequencyUnits.HERTZ).normalize()); 187 for (double hertz = minHz.doubleValue() * 4.0; hertz <= maxHz; hertz *= 2.0) 188 { 189 bws.add(new Frequency(new BigDecimal(hertz), 190 FrequencyUnits.HERTZ).normalize()); 191 } 192 return bws; 193 } 194 195 //============================================================================ 196 // QUANTIZATION & POLARIZATION 197 //============================================================================ 198 199 /* (non-Javadoc) 200 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getInitialQuantization() 201 */ 202 public int getInitialQuantization() 203 { 204 return inputSignalA.getBitDepth(); 205 } 206 207 /** @deprecated Use {@link #getPolarizations()}. */ 208 @Deprecated 209 public PolarizationType getPolarization() 210 { 211 return getPolarizations().get(0); 212 } 213 214 /* (non-Javadoc) 215 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getPolarizations() 216 */ 217 public List<PolarizationType> getPolarizations() 218 { 219 List<PolarizationType> answer = new ArrayList<PolarizationType>(); 220 answer.add(inputSignalA.getPolarization()); 221 answer.add(inputSignalB.getPolarization()); 222 return answer; 223 } 224 225 //============================================================================ 226 // SUBBAND 227 //============================================================================ 228 229 /* (non-Javadoc) 230 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getMaxSubbandCount() 231 */ 232 public int getMaxSubbandCount() 233 { 234 return 1; 235 } 236 237 /* (non-Javadoc) 238 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#makeNewSubband() 239 */ 240 public VlaSubband makeNewSubband() 241 { 242 return new VlaSubband(); 243 } 244 245 /* (non-Javadoc) 246 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getSubbandGrid() 247 */ 248 public SortedSet<Frequency> getSubbandGrid() 249 { 250 return new TreeSet<Frequency>(); 251 } 252 253 public void addSubband(CorrelatorSubband newSubband) 254 { 255 addNewSubband((VlaSubband)newSubband); 256 } 257 258 //============================================================================ 259 // 260 //============================================================================ 261 262 /** 263 * Returns a copy of this baseband. 264 * <p> 265 * If anything goes wrong during the cloning procedure, 266 * a {@code RuntimeException} will be thrown.</p> 267 */ 268 @Override 269 public VlaBasebandPair clone() 270 { 271 VlaBasebandPair clone = null; 272 273 try 274 { 275 clone = (VlaBasebandPair)super.clone(); 276 277 clone.inputSignalA = this.inputSignalA.clone(); 278 clone.inputSignalB = this.inputSignalB.clone(); 279 } 280 catch (Exception ex) 281 { 282 throw new RuntimeException(ex); 283 } 284 285 return clone; 286 } 287 288 /** Returns <i>true</i> if {@code o} is equal to this baseband. */ 289 @Override 290 public boolean equals(Object o) 291 { 292 //Quick exit if super class says not equal 293 if (!super.equals(o)) 294 return false; 295 296 //A safe cast if we got this far 297 VlaBasebandPair other = (VlaBasebandPair)o; 298 299 //Equal if they have the same input signals, even if those 300 //signals are in a different order 301 return 302 (other.inputSignalA.equals(this.inputSignalA) && 303 other.inputSignalB.equals(this.inputSignalB)) 304 || 305 (other.inputSignalA.equals(this.inputSignalB) && 306 other.inputSignalB.equals(this.inputSignalA)); 307 } 308 309 /** Returns a hash code value for this baseband. */ 310 @Override 311 public int hashCode() 312 { 313 //Taken from the Effective Java book by Joshua Bloch. 314 //The constants 17 & 37 are arbitrary & carry no meaning. 315 int result = super.hashCode(); 316 317 //You MUST keep this method in sync w/ the equals method 318 319 //Want two BBs that have the same input signals to give same 320 //hashCode, even if those signals are ordered differently. 321 result = 37 * result + inputSignalA.hashCode() + inputSignalB.hashCode(); 322 323 return result; 324 } 325 }