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