001    package edu.nrao.sss.model.project.scan;
002    
003    import java.util.List;
004    
005    import edu.nrao.sss.model.resource.Resource;
006    import edu.nrao.sss.model.resource.TelescopeBackend;
007    import edu.nrao.sss.model.resource.CorrelatorName;
008    import edu.nrao.sss.model.resource.vla.CorrelatorMode;
009    import edu.nrao.sss.model.resource.vla.IFPair;
010    import edu.nrao.sss.model.resource.vla.VlaConfiguration;
011    import edu.nrao.sss.validation.AbstractValidator;
012    import edu.nrao.sss.validation.DataNotEnteredValidation;
013    import edu.nrao.sss.validation.FailureSeverity;
014    import edu.nrao.sss.validation.Validation;
015    import edu.nrao.sss.validation.ValidationPurpose;
016    import edu.nrao.sss.validation.Validator;
017    
018    /**
019     * A validator of {@link PointingScan pointing scans}.
020     * <p>
021     * <u>Validations Performed for All Purposes</u>
022     * <ol>
023     *   <li>All validations performed by {@link SimpleScanValidator}.</li>
024     *   <li>Scan has at least one position.</li>
025     *   <li>Contained positions are valid.<sup>1</sup></li>
026     * </ol>
027     * <sup>1</sup><i>The particular validations performed depend on the
028     * validator used by this one to operate on those contained positions.
029     * </i></p>
030     * <p>
031     * <b>Version Info:</b>
032     * <table style="margin-left:2em">
033     *   <tr><td>$Revision: 1971 $</td></tr>
034     *   <tr><td>$Date: 2009-02-13 09:30:50 -0700 (Fri, 13 Feb 2009) $</td></tr>
035     *   <tr><td>$Author: btruitt $</td></tr>
036     * </table></p>
037     * 
038     * @author David M. Harland
039     * @since 2007-02-13
040     */
041    public class PointingScanValidator
042      extends ScanValidator<PointingScan>
043    {
044      private Validator pointingPositionValidator;
045      
046      /** Creates a new instance. */
047      public PointingScanValidator()
048      {
049        super(PointingScanValidator.class.getName(), PointingScan.class);
050      }
051      
052      /* (non-Javadoc)
053       * @see AbstractValidator#makeValidationList(ValidationPurpose)
054       */
055      @Override
056      protected List<Validation<PointingScan>>
057        makeValidationList(ValidationPurpose purpose)
058      {
059        List<Validation<PointingScan>> validations =
060          super.makeValidationList(purpose);
061        
062        // TODO: uncomment the following line.  We currently do not require any
063        // pointing positions.  This will eventually change.
064        //validations.add(new HasPosition       (this, purpose));
065        validations.add(new UsesSkyFrequencies(this, purpose));
066        
067        return validations; 
068      }
069    
070      /* (non-Javadoc)
071       * @see edu.nrao.sss.model.validation.AbstractValidator#validate()
072       */
073      @Override
074      protected void validate()
075      {
076        super.validate();
077    
078        //Validate the contained settings
079        /* TODO:  Re-enable this when we allow pointing positions again!
080        Validator ppVal = getPointingPositionValidator();
081        
082        for (PointingPosition pp : target.getPositions())
083          failures.addAll(ppVal.validate(pp, purpose));
084        */
085      }
086      
087      //============================================================================
088      // COMPONENT VALIDATORS
089      //============================================================================
090    
091      /**
092       * Sets the validator to use for the pointing positions of the target scan.
093       * It is acceptable to use a <i>null</i> parameter, in which case
094       * this validator will contact its manager for a pointing-position validator
095       * or create one itself.
096       * 
097       * @param newValidator a validator to use on the pointing positions of this
098       *                     validator's target scan.
099       */
100      public void setPointingPositionValidator(Validator newValidator)
101      {
102        pointingPositionValidator = newValidator;
103      }
104    
105      /** Returns a validator for delay settings. */
106      public Validator getPointingPositionValidator()
107      {
108        Validator validator = pointingPositionValidator;
109        
110        if (validator == null)
111        {
112          if (manager != null)
113            validator = manager.getValidator(PointingPosition.class);
114          
115          if (validator == null)
116            validator = new PointingPositionValidator();
117        }
118        
119        return validator;
120      }
121      
122      //============================================================================
123      // UNITIALIZED FIELD VALIDATIONS
124      //============================================================================
125      
126      class HasPosition extends DataNotEnteredValidation<PointingScan>
127      {
128        protected HasPosition(AbstractValidator<PointingScan> validationContainer,
129                              ValidationPurpose               reasonForValidation)
130        {
131          super(validationContainer, reasonForValidation,
132                "pointing scan", "pointing position", "0");
133        }
134        
135        @Override
136        protected String getCurrentValue()
137        {
138          specificTargetName = target.getName();
139    
140          return Integer.toString(target.getPositions().size());
141        }
142      }
143    
144      // TODO: This is Vla correlator specific!!  Must update for widar!
145      class UsesSkyFrequencies extends Validation<PointingScan>
146      {
147        protected UsesSkyFrequencies(AbstractValidator<PointingScan> validationContainer, ValidationPurpose reasonForValidation)
148        {
149          super(validationContainer, reasonForValidation);
150          severity = (reasonForValidation == ValidationPurpose.CERTIFY_READY_TO_USE)? FailureSeverity.ERROR : FailureSeverity.WARNING;
151        }
152        
153        @Override
154        public boolean passesTest()
155        {
156          Resource rsrc = target.getResource();
157    
158          if (rsrc != null)
159          {
160            List<TelescopeBackend> backEnds = rsrc.getBackends();
161            if (backEnds != null && !backEnds.isEmpty())
162            {
163              // We only care about/look at the first back end.
164              TelescopeBackend be = backEnds.get(0);
165              if (be.getName().equals(CorrelatorName.VLA))
166              {
167                VlaConfiguration conf = (VlaConfiguration)be;
168                CorrelatorMode mode = conf.getCorrelatorMode();
169                if ((mode.uses(IFPair.AC) && !conf.isSkyFrequency(IFPair.AC)) ||
170                    (mode.uses(IFPair.BD) && !conf.isSkyFrequency(IFPair.BD)))
171                {
172                  return false;
173                }
174              }
175            }
176          }
177          
178          return true;
179        }
180    
181        @Override
182        public String debugMessage()
183        {
184          return displayMessage();
185        }
186    
187        @Override
188        public String displayMessage()
189        {
190          StringBuilder msg = new StringBuilder("Pointing scan: ");
191          msg.append(target.getName());
192          msg.append(" is using a rest frequency as opposed to a sky frequency in its hardware configuration.");
193          msg.append("  Rest frequencies are not allowed in tipping and pointing scans.");
194    
195          if (severity != FailureSeverity.ERROR)
196            msg.append("  This is ok for now, but you will not be able to observe with this configuration.");
197    
198          return msg.toString();
199        }
200      }
201    }