"""Data Checks===========Utilities designed to check the validity of data inputs."""from__future__importannotationsfromcollections.abcimportSequenceimportxarrayasxrfromxclim.core._exceptionsimportValidationErrorfromxclim.core.calendarimportcompare_offsets,parse_offsetfromxclim.core.optionsimportdatacheck
[docs]@datacheckdefcheck_freq(var:xr.DataArray,freq:str|Sequence[str],strict:bool=True)->None:""" Raise an error if not series has not the expected temporal frequency or is not monotonically increasing. Parameters ---------- var : xr.DataArray Input array. freq : str or sequence of str The expected temporal frequencies, using Pandas frequency terminology (e.g. {'Y', 'M', 'D', 'h', 'min', 's', 'ms', 'us'}) and multiples thereof. To test strictly for 'W', pass '7D' with `strict=True`. This ignores the start/end flag and the anchor (ex: 'YS-JUL' will validate against 'Y'). strict : bool Whether multiples of the frequencies are considered invalid or not. With `strict` set to False, a '3h' series will not raise an error if freq is set to 'h'. Raises ------ ValidationError - If the frequency of `var` is not inferrable. - If the frequency of `var` does not match the requested `freq`. """ifisinstance(freq,str):freq=[freq]exp_base=[parse_offset(frq)[1]forfrqinfreq]v_freq=xr.infer_freq(var.time)ifv_freqisNone:raiseValidationError("Unable to infer the frequency of the time series. To mute this, set xclim's option data_validation='log'.")v_base=parse_offset(v_freq)[1]ifv_basenotinexp_baseor(strictandall(compare_offsets(v_freq,"!=",frq)forfrqinfreq)):raiseValidationError(f"Frequency of time series not {'strictly'ifstrictelse''} in {freq}. ""To mute this, set xclim's option data_validation='log'.")
[docs]defcheck_daily(var:xr.DataArray)->None:""" Raise an error if series has a frequency other that daily, or is not monotonically increasing. Parameters ---------- var : xr.DataArray Input array. Notes ----- This does not check for gaps in series. """check_freq(var,"D")
[docs]@datacheckdefcheck_common_time(inputs:Sequence[xr.DataArray])->None:""" Raise an error if the list of inputs doesn't have a single common frequency. Parameters ---------- inputs : Sequence of xr.DataArray Input arrays. Raises ------ ValidationError - if the frequency of any input can't be inferred - if inputs have different frequencies - if inputs have a daily or hourly frequency, but they are not given at the same time of day. """# Check all have the same freqfreqs=[xr.infer_freq(da.time)fordaininputs]ifNoneinfreqs:raiseValidationError("Unable to infer the frequency of the time series. To mute this, set xclim's option data_validation='log'.")iflen(set(freqs))!=1:raiseValidationError(f"Inputs have different frequencies. Got : {freqs}.To mute this, set xclim's option data_validation='log'.")# Check if anchor is the samefreq=freqs[0]base=parse_offset(freq)[1]fmt={"h":":%M","D":"%H:%M"}ifbaseinfmt:outs={da.indexes["time"][0].strftime(fmt[base])fordaininputs}iflen(outs)>1:raiseValidationError(f"All inputs have the same frequency ({freq}), but they are not anchored on the same "f"minutes (got {outs}). xarray's alignment would silently fail. You can try to fix this "f"with `da.resample('{freq}').mean()`. To mute this, set xclim's option data_validation='log'.")