001 package edu.nrao.sss.model.resource; 002 003 import java.util.ArrayList; 004 import java.util.List; 005 006 /** 007 * A selection of receivers, typically created by a {@link ReceiverSelector}. 008 * Instances of this class are immutable. 009 * <p> 010 * <b>Version Info:</b> 011 * <table style="margin-left:2em"> 012 * <tr><td>$Revision: 1096 $</td></tr> 013 * <tr><td>$Date: 2008-02-12 11:01:13 -0700 (Tue, 12 Feb 2008) $</td></tr> 014 * <tr><td>$Author: dharland $</td></tr> 015 * </table></p> 016 * 017 * @author David M. Harland 018 * @since 2007-01-11 019 */ 020 public class ReceiverSelection 021 { 022 private List<ReceiverBand> receivers; 023 private ResourceSpecification originalSpecifications; 024 private ResourceSpecification modifiedSpecifications; 025 026 private transient double fractionalCoverage = -1.0; 027 028 /** 029 * Creates a new selection of receivers. 030 * 031 * @param selections the selected receivers. If no receivers were selected, 032 * send either an empty list, or <i>null</i>, which will 033 * be converted to an empty list by this constructor. 034 * 035 * @param original the resource specifications used to select the receivers. 036 * This parameter may not be <i>null</i>. 037 * 038 * @param modified the intersection of the original specifications and the 039 * frequency ranges of the selected receivers. 040 * This parameter may not be <i>null</i>. 041 */ 042 ReceiverSelection(List<ReceiverBand> selections, 043 ResourceSpecification original, 044 ResourceSpecification modified) 045 { 046 originalSpecifications = original.clone(); 047 modifiedSpecifications = modified.clone(); 048 049 receivers = new ArrayList<ReceiverBand>(); 050 051 //We're not adding clones of the Receivers in selections because 052 //Receiver instances are immutable. 053 if (selections != null) 054 receivers.addAll(selections); 055 } 056 057 /** 058 * Returns the selected receivers. 059 * The returned list is a copy, but the references to the receivers in the 060 * returned list are the same as those held by this object's list. 061 * 062 * @return the selected receivers. 063 */ 064 public List<ReceiverBand> getReceivers() 065 { 066 return new ArrayList<ReceiverBand>(receivers); 067 } 068 069 /** 070 * Returns the resource specifications that were used to create this 071 * selection. 072 * <p> 073 * Note that the returned specification is a copy of that held by 074 * this receiver selection. That means that any changes made to the 075 * returned specification will not be reflected in this object.</p> 076 * 077 * @return the specifications that were used to create this selection. 078 */ 079 public ResourceSpecification getOriginalSpecifications() 080 { 081 return originalSpecifications.clone(); 082 } 083 084 /** 085 * Returns the resource specifications that represent the intersection 086 * between the original specifications and the bandwidth covered by the 087 * selected receivers. 088 * <p> 089 * Note that the returned specification is a copy of that held by 090 * this receiver selection. That means that any changes made to the 091 * returned specification will not be reflected in this object.</p> 092 * 093 * @return a modification to the original resource specifications that 094 * reflects the capabilities of the selected receivers. 095 */ 096 public ResourceSpecification getModifiedSpecifications() 097 { 098 return modifiedSpecifications.clone(); 099 } 100 101 /** 102 * Returns the fraction of the bandwidth requested in the original 103 * specifications that can be satisfied by the selected receivers. 104 * The value will returned will be between zero and one, inclusive. 105 * 106 * @return the fraction of the requested bandwidth covered by the 107 * selected receivers. 108 */ 109 public double getFractionalBandwidthCoverage() 110 { 111 if (fractionalCoverage < 0.0) 112 calculateFractionalBandwidthCoverage(); 113 114 return fractionalCoverage; 115 } 116 117 private void calculateFractionalBandwidthCoverage() 118 { 119 //We can divide the amt covered by the modified specs by the amt 120 //covered by the original specs only because we know that each 121 //range of the modified specs is a subset (including being the 122 //complete range) of a corresponding range in the original specs. 123 fractionalCoverage = 124 modifiedSpecifications.getSpectrum().getAmountCovered().dividedBy( 125 originalSpecifications.getSpectrum().getAmountCovered()).doubleValue(); 126 } 127 }