def get_converter_class(self): return get_converter(self.value)
def _validate_(self): ocgis_lh(logger="operations", msg="validating operations") def _raise_(msg, obj=OutputFormat): e = DefinitionValidationError(obj, msg) ocgis_lh(exc=e, logger="operations") # assert the driver may be written to the appropriate output format for rd in self.dataset.iter_request_datasets(): rd.driver.validate_ops(self) # validate the converter converter_klass = get_converter(self.output_format) converter_klass.validate_ops(self) # no regridding with a spatial operation of clip if self.regrid_destination is not None: if self.spatial_operation == "clip": msg = 'Regridding not allowed with spatial "clip" operation.' raise DefinitionValidationError(SpatialOperation, msg) # collect projections for the dataset sets. None is returned if one is not parsable. the WGS84 default is # actually done in the RequestDataset object. projections = [] for rd in self.dataset.itervalues(): if not any([_ == rd.crs for _ in projections]): projections.append(rd.crs) # if there is not output CRS and projections differ, raise an exception. however, it is okay to have data with # different projections in the numpy output. if len(projections) > 1 and self.output_format != "numpy": # @UndefinedVariable if self.output_crs is None: _raise_( "Dataset coordinate reference systems must be equivalent if no output CRS is chosen.", obj=OutputCRS ) # clip and/or aggregation operations may not be written back to CFRotatedPole at this time. hence, the output # crs must be set to CFWGS84. if CFRotatedPole in map(type, projections): if self.output_crs is not None and not isinstance(self.output_crs, WGS84): msg = ( '{0} data may only be written to the same coordinate system (i.e. "output_crs=None") ' "or {1}." ).format(CFRotatedPole.__name__, CFWGS84.__name__) _raise_(msg, obj=OutputCRS) if self.aggregate or self.spatial_operation == "clip": msg = ( "{0} data if clipped or spatially averaged must be written to " '{1}. The "output_crs" is being updated to {2}.' ).format(CFRotatedPole.__name__, CFWGS84.__name__, CFWGS84.__name__) ocgis_lh(level=logging.WARN, msg=msg, logger="operations") self._get_object_("output_crs")._value = CFWGS84() # only WGS84 may be written to to GeoJSON if self.output_format == "geojson": if any([element != WGS84() for element in projections if element is not None]): _raise_("Only data with a WGS84 projection may be written to GeoJSON.") if self.output_crs is not None: if self.output_crs != WGS84(): _raise_("Only data with a WGS84 projection may be written to GeoJSON.") # snippet only relevant for subsetting not operations with a calculation or time region if self.snippet: if self.calc is not None: _raise_( "Snippets are not implemented for calculations. Apply a limiting time range for faster responses.", obj=Snippet, ) for rd in self.dataset.iter_request_datasets(): if rd.time_region is not None: _raise_("Snippets are not implemented for time regions.", obj=Snippet) # no slicing with a geometry - can easily lead to extent errors if self.slice is not None: assert self.geom is None # file only operations only valid for netCDF and calculations. if self.file_only: if self.output_format != "nc": _raise_('Only netCDF-CF may be written with file_only as "True".', obj=FileOnly) if self.calc is None: _raise_("File only outputs are only relevant for computations.", obj=FileOnly) # validate any calculations against the operations object. if the calculation is a string eval function do not # validate. if self.calc is not None: if self._get_object_("calc")._is_eval_function: if self.calc_grouping is not None: msg = "Calculation groups are not applicable for string function expressions." _raise_(msg, obj=CalcGrouping) else: for c in self.calc: c["ref"].validate(self)