001 package edu.nrao.sss.model.resource.evla; 002 003 import java.io.FileNotFoundException; 004 import java.io.Reader; 005 import java.util.List; 006 007 import javax.xml.bind.JAXBException; 008 import javax.xml.bind.annotation.XmlElement; 009 import javax.xml.bind.annotation.XmlRootElement; 010 import javax.xml.stream.XMLStreamException; 011 012 import ca.nrc.widar.jaxb.vci.BaseBand; 013 import ca.nrc.widar.jaxb.vci.BbParams; 014 015 import edu.nrao.sss.astronomy.PolarizationType; 016 import edu.nrao.sss.electronics.DigitalSignal; 017 import edu.nrao.sss.electronics.Signal; 018 import edu.nrao.sss.measure.Frequency; 019 import edu.nrao.sss.measure.FrequencyRange; 020 import edu.nrao.sss.util.JaxbUtility; 021 022 /** 023 * A baseband pair of the WIDAR correlator. 024 * <p> 025 * <b>Version Info:</b> 026 * <table style="margin-left:2em"> 027 * <tr><td>$Revision: 2271 $</td></tr> 028 * <tr><td>$Date: 2009-04-28 12:02:17 -0600 (Tue, 28 Apr 2009) $</td></tr> 029 * <tr><td>$Author: dharland $ (last person to modify)</td></tr> 030 * </table></p> 031 * 032 * @author David M. Harland 033 * @since 2008-06-24 034 */ 035 @XmlRootElement 036 public class WidarBasebandPair 037 extends WidarBaseband 038 { 039 @XmlElement private DigitalSignal inputSignalA; 040 @XmlElement private DigitalSignal inputSignalB; 041 042 /** 043 * Creates a new WIDAR baseband pair. 044 * @throws IllegalArgumentException 045 * if {@code inputA} or {@code inputB} is <i>null</i>. 046 */ 047 public WidarBasebandPair(DigitalSignal inputA, DigitalSignal inputB) 048 { 049 this(); 050 initInput(inputA, inputB, true); 051 } 052 053 //This is here only for persistence mechanisms 054 protected WidarBasebandPair() 055 { 056 super(); 057 } 058 059 /** Sets the input signal for this baseband. */ 060 private void initInput(DigitalSignal inputA, DigitalSignal inputB, boolean forceBwUpdate) 061 { 062 if (inputA == null || inputB == null) 063 throw new IllegalArgumentException( 064 "Cannot configure correlator baseband with a NULL input signal."); 065 066 //TODO Do we need to compare the inputs to make sure they have 067 // same freq range? Same init quant? Diff polzns? 068 inputSignalA = inputA; 069 inputSignalB = inputB; 070 071 bandwidth = inputSignalA.getCurrentRange().getWidth(); 072 } 073 074 /** 075 * Sets the input signals for this baseband pair. 076 * Classes that override this method should have 077 * <tt>super.setInput(input, input)</tt> as their first line. 078 */ 079 public void setInput(DigitalSignal inputA, DigitalSignal inputB) 080 { 081 initInput(inputA, inputB, false); 082 } 083 084 //============================================================================ 085 // IDENTIFICATION 086 //============================================================================ 087 088 static String makeName(Signal signalA, Signal signalB) 089 { 090 String nameA = signalA.getName(); 091 String nameB = signalB.getName(); 092 093 //Avoid pairs such as C2/A2; force to A2/C2. 094 return nameA.compareTo(nameB) <= 0 ? nameA + "/" + nameB : nameB + "/" + nameA; 095 } 096 097 /* (non-Javadoc) 098 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getName() 099 */ 100 public String getName() 101 { 102 return makeName(inputSignalA, inputSignalB); 103 } 104 105 /* (non-Javadoc) 106 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#isSinglet() 107 */ 108 public boolean isSinglet() { return false; } 109 110 //============================================================================ 111 // FREQUENCY 112 //============================================================================ 113 114 Frequency getInputBandwidth() 115 { 116 return inputSignalA.getCurrentRange().getWidth(); 117 } 118 119 /* (non-Javadoc) 120 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getProxiedRange() 121 */ 122 public FrequencyRange getProxiedRange() 123 { 124 return getProxiedRange(inputSignalA); 125 } 126 127 /* (non-Javadoc) 128 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#proxiedRangeIsReversed() 129 */ 130 public boolean proxiedRangeIsReversed() 131 { 132 return proxiedRangeIsReversed(inputSignalA); 133 } 134 135 //============================================================================ 136 // QUANTIZATION & POLARIZATION 137 //============================================================================ 138 139 /* (non-Javadoc) 140 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getInitialQuantization() 141 */ 142 public int getInitialQuantization() 143 { 144 return getInitialQuantization(inputSignalA); 145 } 146 147 /** @deprecated Use {@link #getPolarizations()}. */ 148 @Deprecated 149 public PolarizationType getPolarization() 150 { 151 return getPolarizations().get(0); 152 } 153 154 /* (non-Javadoc) 155 * @see edu.nrao.sss.model.resource.CorrelatorBaseband#getPolarizations() 156 */ 157 public List<PolarizationType> getPolarizations() 158 { 159 return getPolarizations(inputSignalA, inputSignalB); 160 } 161 162 //============================================================================ 163 // PARTNERED BASEBANDS 164 //============================================================================ 165 166 /** Always returns <i>false</i>. Baseband pairs do not have partners. */ 167 public boolean isPartnerOf(WidarBaseband other) { return false; } 168 169 /** Always returns <i>false</i>. Baseband pairs do not have partners. */ 170 public boolean hasPartner() { return false; } 171 172 /** Always returns <i>null</i>. Baseband pairs do not have partners. */ 173 public WidarBaseband getPartner() { return null; } 174 175 /** 176 * Returns an array of two single, partnered, basebands based on this pair. 177 */ 178 WidarBasebandSinglet[] toSinglePartners() 179 { 180 WidarBasebandSinglet bbA = new WidarBasebandSinglet(inputSignalA); 181 WidarBasebandSinglet bbB = new WidarBasebandSinglet(inputSignalB); 182 183 EvlaWidarConfiguration myContainer = getEvlaWidarConfiguration(); 184 185 bbA.setEvlaWidarConfiguration(myContainer); 186 bbB.setEvlaWidarConfiguration(myContainer); 187 188 WidarBasebandSinglet.formPartnership(bbA, bbB); 189 190 //TODO configure singlets from this pair. Eg, subbands 191 192 return new WidarBasebandSinglet[] {bbA, bbB}; 193 } 194 195 //============================================================================ 196 // SUBBAND 197 //============================================================================ 198 199 //============================================================================ 200 // VCI ELEMENTS 201 //============================================================================ 202 203 void setWidarBbIds(BaseBand widarBB, boolean primary) 204 { 205 int[] idVciBbA = getVciBbIds(inputSignalA.getName()); 206 int[] idVciBbB = getVciBbIds(inputSignalB.getName()); 207 208 int index = 0; 209 210 if (!primary && idVciBbA.length == 2) 211 index = 1; 212 213 widarBB.setBbA(idVciBbA[index]); 214 widarBB.setBbB(idVciBbB[index]); 215 } 216 217 void addBbParams(List<BbParams> bbParamList, int stationId) 218 { 219 addBbParams(bbParamList, stationId, inputSignalA); 220 addBbParams(bbParamList, stationId, inputSignalB); 221 } 222 223 //============================================================================ 224 // 225 //============================================================================ 226 227 /** 228 * Creates a new baseband from the XML data in the given file. 229 * 230 * @param xmlFile 231 * the name of an XML file. This method will attempt to locate 232 * the file by using {@link Class#getResource(String)}. 233 * 234 * @return 235 * a new baseband from the XML data in the given file. 236 * 237 * @throws FileNotFoundException 238 * if the XML file cannot be found. 239 * 240 * @throws JAXBException 241 * if the schema file used (if any) is malformed, if the XML file cannot be 242 * read, or if the XML file is not schema-valid. 243 * 244 * @throws XMLStreamException 245 * if there is a problem opening the XML file, if the XML is not well-formed, 246 * or for some other "unexpected processing conditions". 247 */ 248 public static WidarBasebandPair fromXml(String xmlFile) 249 throws JAXBException, XMLStreamException, FileNotFoundException 250 { 251 return JaxbUtility.getSharedInstance() 252 .xmlFileToObject(xmlFile, WidarBasebandPair.class); 253 } 254 255 /** 256 * Creates a new baseband based on the XML data read from {@code reader}. 257 * 258 * @param reader 259 * the source of the XML data. 260 * If this value is <i>null</i>, <i>null</i> is returned. 261 * 262 * @return 263 * a new baseband based on the XML data read from {@code reader}. 264 * 265 * @throws XMLStreamException 266 * if the XML is not well-formed, 267 * or for some other "unexpected processing conditions". 268 * 269 * @throws JAXBException 270 * if anything else goes wrong during the transformation. 271 */ 272 public static WidarBasebandPair fromXml(Reader reader) 273 throws JAXBException, XMLStreamException 274 { 275 return JaxbUtility.getSharedInstance() 276 .readObjectAsXmlFrom(reader, WidarBasebandPair.class, null); 277 } 278 279 //============================================================================ 280 // 281 //============================================================================ 282 283 /** 284 * Returns a copy of this baseband. 285 * <p> 286 * If anything goes wrong during the cloning procedure, 287 * a {@code RuntimeException} will be thrown.</p> 288 */ 289 @Override 290 public WidarBasebandPair clone() 291 { 292 WidarBasebandPair clone = null; 293 294 try 295 { 296 clone = (WidarBasebandPair)super.clone(); 297 298 clone.inputSignalA = this.inputSignalA.clone(); 299 clone.inputSignalB = this.inputSignalB.clone(); 300 } 301 catch (Exception ex) 302 { 303 throw new RuntimeException(ex); 304 } 305 306 return clone; 307 } 308 309 /** Returns <i>true</i> if {@code o} is equal to this baseband. */ 310 @Override 311 public boolean equals(Object o) 312 { 313 //Quick exit if super class says not equal 314 if (!super.equals(o)) 315 return false; 316 317 //A safe cast if we got this far 318 WidarBasebandPair other = (WidarBasebandPair)o; 319 320 //Equal if they have the same input signals, even if those 321 //signals are in a different order 322 return 323 (other.inputSignalA.equals(this.inputSignalA) && 324 other.inputSignalB.equals(this.inputSignalB)) 325 || 326 (other.inputSignalA.equals(this.inputSignalB) && 327 other.inputSignalB.equals(this.inputSignalA)); 328 } 329 330 /** Returns a hash code value for this baseband. */ 331 @Override 332 public int hashCode() 333 { 334 //Taken from the Effective Java book by Joshua Bloch. 335 //The constants 17 & 37 are arbitrary & carry no meaning. 336 int result = super.hashCode(); 337 338 //You MUST keep this method in sync w/ the equals method 339 340 //Want two BBs that have the same input signals to give same 341 //hashCode, even if those signals are ordered differently. 342 result = 37 * result + inputSignalA.hashCode() + inputSignalB.hashCode(); 343 344 return result; 345 } 346 347 //============================================================================ 348 // 349 //============================================================================ 350 /* 351 public static void main(String[] args) 352 { 353 WidarBuilder builder = new WidarBuilder(); 354 355 WidarBasebandPair bbp = builder.makeBasebandPair(); 356 357 try 358 { 359 bbp.writeAsXmlTo(new java.io.PrintWriter(System.out)); 360 } 361 catch (Exception ex) 362 { 363 System.out.println("Trouble w/ bb.toXml. Msg:"); 364 System.out.println(ex.getMessage()); 365 ex.printStackTrace(); 366 367 System.out.println("Attempting to write XML w/out schema verification:"); 368 JaxbUtility.getSharedInstance().setLookForDefaultSchema(false); 369 try 370 { 371 System.out.println(bbp.toXml()); 372 } 373 catch (JAXBException ex2) 374 { 375 System.out.println("Still had trouble w/ bb.toXml. Msg:"); 376 System.out.println(ex2.getMessage()); 377 ex2.printStackTrace(); 378 } 379 } 380 381 BaseBand[] vciBB = bbp.toVci(); 382 System.out.println(); System.out.println("-------------"); System.out.println(); 383 try 384 { 385 VciJaxbUtil.writeObjectAsXmlTo(new java.io.PrintWriter(System.out), vciBB[0]); 386 if (vciBB.length > 1) 387 { 388 System.out.println(); System.out.println("-------------"); System.out.println(); 389 VciJaxbUtil.writeObjectAsXmlTo(new java.io.PrintWriter(System.out), vciBB[1]); 390 } 391 } 392 catch (Exception ex) 393 { 394 throw new RuntimeException(ex); 395 } 396 } 397 */ 398 /* 399 public static void main(String[] args) throws Exception 400 { 401 java.io.FileReader reader = 402 new java.io.FileReader("/export/home/calmer/dharland/JUNK/WidarBBP-IN.xml"); 403 404 WidarBasebandPair bbp = WidarBasebandPair.fromXml(reader); 405 406 java.io.FileWriter writer = 407 new java.io.FileWriter("/export/home/calmer/dharland/JUNK/WidarBBP-OUT.xml"); 408 409 bbp.writeAsXmlTo(writer); 410 } 411 */ 412 }