diff --git a/satpy/etc/readers/fci_l2_bufr.yaml b/satpy/etc/readers/fci_l2_bufr.yaml new file mode 100644 index 0000000000..ef515d0471 --- /dev/null +++ b/satpy/etc/readers/fci_l2_bufr.yaml @@ -0,0 +1,1256 @@ +reader: + name: fci_l2_bufr + short_name: FCI l2 BUFR + long_name: MTGi Level 2 products in BUFR format + description: FCI L2 BUFR Product Reader + status: Alpha + supports_fsspec: false + sensors: [fci] + default_channels: [] + reader: !!python/name:satpy.readers.yaml_reader.GEOFlippableFileYAMLReader + +file_types: + fci_l2_bufr_asr: + file_reader: !!python/name:satpy.readers.eum_l2_bufr.EumetsatL2BufrFileHandler + file_patterns: + - '{pflag}_{location_indicator},{data_designator},MTI{spacecraft_id:1d}+FCI-2-ASR-{subtype}-{coverage}-{subsetting}-{component1}-{component2}-{component3}-{purpose}-BUFR_{oflag}_{originator}_{processing_time:%Y%m%d%H%M%S}_{facility_or_tool}_{environment}_{start_time:%Y%m%d%H%M%S}_{end_time:%Y%m%d%H%M%S}_{processing_mode}_{special_compression}_{disposition_mode}_{repeat_cycle_in_day:>04d}_{count_in_repeat_cycle:>04d}.bin' + fci_l2_bufr_amv: + file_reader: !!python/name:satpy.readers.eum_l2_bufr.EumetsatL2BufrFileHandler + file_patterns: + - '{pflag}_{location_indicator},{data_designator},MTI{spacecraft_id:1d}+FCI-2-AMV-{subtype}-{coverage}-{subsetting}-{component1}-{component2}-{component3}-{purpose}-BUFR_{oflag}_{originator}_{processing_time:%Y%m%d%H%M%S}_{facility_or_tool}_{environment}_{start_time:%Y%m%d%H%M%S}_{end_time:%Y%m%d%H%M%S}_{processing_mode}_{special_compression}_{disposition_mode}_{repeat_cycle_in_day:>04d}_{count_in_repeat_cycle:>04d}.bin' + +datasets: + #----- COMMON ------------------ + latitude: + name: latitude + key: '#1#latitude' + resolution: [32000, -1] + file_type: [fci_l2_bufr_asr,fci_l2_bufr_amv] + standard_name: latitude + units: degree_north + fill_value: -1.e+100 + + longitude: + name: longitude + key: '#1#longitude' + resolution: [32000, -1] + file_type: [fci_l2_bufr_asr,fci_l2_bufr_amv] + standard_name: longitude + units: degree_east + fill_value: -1.e+100 + + + # ---- AMV products ------------ + pressure: + name: pressure + long_name: Pressure of AMV feature + standard_name: air_pressure_at_wind_level + file_type: fci_l2_bufr_amv + key: '#1#pressure' + units: Pa + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + temperature: + name: temperature + long_name: Temperature of AMV feature + standard_name: air_temperature_at_wind_level + file_type: fci_l2_bufr_amv + key: '#1#airTemperature' + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + height: + name: height + long_name: Height of AMV feature + standard_name: height_at_wind_level + file_type: fci_l2_bufr_amv + key: '#1#heightOfTopOfCloud' + units: m + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + direction: + name: direction + long_name: Direction of AMV + standard_name: wind_to_direction + file_type: fci_l2_bufr_amv + key: '#1#windDirection' + units: degree_north + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + speed: + name: speed + long_name: Speed of AMV + standard_name: wind_speed + file_type: fci_l2_bufr_amv + key: '#1#windSpeed' + units: m/s + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + speed_u_component: + name: speed_u_component + long_name: Speed U component of AMV + standard_name: wind_speed_horizontal_component + file_type: fci_l2_bufr_amv + key: '#1#u' + units: m/s + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + speed_v_component: + name: speed_v_component + long_name: Speed V component of AMV + standard_name: wind_speed_vertival_component + file_type: fci_l2_bufr_amv + key: '#1#v' + units: m/s + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + target_type: + name: target_type + long_name: Target type (cloud or clearsky) + standard_name: wind_target_type + file_type: fci_l2_bufr_amv + key: '#1#extendedHeightAssignmentMethod' + units: "" + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + wind_method: + name: wind_method + long_name: Wind derivation method + standard_name: wind_wind_method + file_type: fci_l2_bufr_amv + key: 'satelliteDerivedWindComputationMethod' + units: "" + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + qi: + name: qi + long_name: Overall Reliability of AMV + standard_name: wind_overall_reliability + file_type: fci_l2_bufr_amv + key: '#1#percentConfidence' + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + qi_excl_fcst: + name: qi_excl_fcst + long_name: Overall Reliability (excluding forecast) of AMV + standard_name: wind_overall_reliability_exc_forecast + file_type: fci_l2_bufr_amv + key: '#2#percentConfidence' + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + channel_id: + name: channel_id + long_name: Channel Id + standard_name: channel_id + file_type: fci_l2_bufr_amv + key: '#1#channelNumber' + units: "" + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + # ---- ASR products ------------ + bt_mean_all_ir38: + name: bt_mean_all_ir38 + long_name: TOA Brightness Temperature segment mean at 3.8um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#19#brightnessTemperature' + wavelength: [3.4, 3.8, 4.2] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_clear_ir38: + name: bt_mean_clear_ir38 + long_name: TOA Brightness Temperature segment mean at 3.8um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#20#brightnessTemperature' + wavelength: [3.4, 3.8, 4.2] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_cloudy_ir38: + name: bt_mean_cloudy_ir38 + long_name: TOA Brightness Temperature segment mean at 3.8um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#21#brightnessTemperature' + wavelength: [3.4, 3.8, 4.2] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_all_wv63: + name: bt_mean_all_wv63 + long_name: TOA Brightness Temperature segment mean at 6.3um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#25#brightnessTemperature' + wavelength: [5.3, 6.3, 7.3] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_clear_wv63: + name: bt_mean_clear_wv63 + long_name: TOA Brightness Temperature segment mean at 6.3um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#26#brightnessTemperature' + wavelength: [5.3, 6.3, 7.3] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_cloudy_wv63: + name: bt_mean_cloudy_wv63 + long_name: TOA Brightness Temperature segment mean at 6.3um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#27#brightnessTemperature' + wavelength: [5.3, 6.3, 7.3] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_all_wv73: + name: bt_mean_all_wv73 + long_name: TOA Brightness Temperature segment mean at 7.3um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#31#brightnessTemperature' + wavelength: [6.85, 7.35, 7.85] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_clear_wv73: + name: bt_mean_clear_wv73 + long_name: TOA Brightness Temperature segment mean at 7.3um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#32#brightnessTemperature' + wavelength: [6.85, 7.35, 7.85] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_cloudy_wv73: + name: bt_mean_cloudy_wv73 + long_name: TOA Brightness Temperature segment mean at 7.3um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#33#brightnessTemperature' + wavelength: [6.85, 7.35, 7.85] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_all_ir87: + name: bt_mean_all_ir87 + long_name: TOA Brightness Temperature segment mean at 8.7um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#37#brightnessTemperature' + wavelength: [8.3, 8.7, 9.1] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_clear_ir87: + name: bt_mean_clear_ir87 + long_name: TOA Brightness Temperature segment mean at 8.7um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#38#brightnessTemperature' + wavelength: [8.3, 8.7, 9.1] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_cloudy_ir87: + name: bt_mean_cloudy_ir87 + long_name: TOA Brightness Temperature segment mean at 8.7um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#39#brightnessTemperature' + wavelength: [8.3, 8.7, 9.1] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_all_ir97: + name: bt_mean_all_ir97 + long_name: TOA Brightness Temperature segment mean at 9.7um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#43#brightnessTemperature' + wavelength: [9.36, 9.66, 9.96] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_clear_ir97: + name: bt_mean_clear_ir97 + long_name: TOA Brightness Temperature segment mean at 9.7um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#44#brightnessTemperature' + wavelength: [9.36, 9.66, 9.96] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_cloudy_ir97: + name: bt_mean_cloudy_ir97 + long_name: TOA Brightness Temperature segment mean at 9.7um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#45#brightnessTemperature' + wavelength: [9.36, 9.66, 9.96] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_all_ir105: + name: bt_mean_all_ir105 + long_name: TOA Brightness Temperature segment mean at 10.5um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#49#brightnessTemperature' + wavelength: [9.8, 10.5, 11.2] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_clear_ir105: + name: bt_mean_clear_ir105 + long_name: TOA Brightness Temperature segment mean at 10.5um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#50#brightnessTemperature' + wavelength: [9.8, 10.5, 11.2] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_cloudy_ir105: + name: bt_mean_cloudy_ir105 + long_name: TOA Brightness Temperature segment mean at 10.5um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#51#brightnessTemperature' + wavelength: [9.8, 10.5, 11.2] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_all_ir123: + name: bt_mean_all_ir123 + long_name: TOA Brightness Temperature segment mean at 12.3um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#55#brightnessTemperature' + wavelength: [11.8, 12.3, 12.8] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_clear_ir123: + name: bt_mean_clear_ir123 + long_name: TOA Brightness Temperature segment mean at 12.3um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#56#brightnessTemperature' + wavelength: [11.8, 12.3, 12.8] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_cloudy_ir123: + name: bt_mean_cloudy_ir123 + long_name: TOA Brightness Temperature segment mean at 12.3um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#57#brightnessTemperature' + wavelength: [11.8, 12.3, 12.8] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_all_ir133: + name: bt_mean_all_ir133 + long_name: TOA Brightness Temperature segment mean at 13.3um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#61#brightnessTemperature' + wavelength: [12.7, 13.3, 13.9] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_clear_ir133: + name: bt_mean_clear_ir133 + long_name: TOA Brightness Temperature segment mean at 13.3um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#62#brightnessTemperature' + wavelength: [12.7, 13.3, 13.9] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + bt_mean_cloudy_ir133: + name: bt_mean_cloudy_ir133 + long_name: TOA Brightness Temperature segment mean at 13.3um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#63#brightnessTemperature' + wavelength: [12.7, 13.3, 13.9] + cell_method: area:mean + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_all_ir38: + name: quality_bt_all_ir38 + long_name: TOA Brightness Temperature % confidence at 3.8um (all pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#19#brightnessTemperature->percentConfidence' + wavelength: [3.4, 3.8, 4.2] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_clear_ir38: + name: quality_bt_clear_ir38 + long_name: TOA Brightness Temperature % confidence at 3.8um (clear pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#20#brightnessTemperature->percentConfidence' + wavelength: [3.4, 3.8, 4.2] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_cloudy_ir38: + name: quality_bt_cloudy_ir38 + long_name: TOA Brightness Temperature % confidence at 3.8um (cloudy pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#21#brightnessTemperature->percentConfidence' + wavelength: [3.4, 3.8, 4.2] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_all_wv63: + name: quality_bt_all_wv63 + long_name: TOA Brightness Temperature % confidence at 6.3um (all pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#25#brightnessTemperature->percentConfidence' + wavelength: [5.3, 6.3, 7.3] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_clear_wv63: + name: quality_bt_clear_wv63 + long_name: TOA Brightness Temperature % confidence at 6.3um (clear pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#26#brightnessTemperature->percentConfidence' + wavelength: [5.3, 6.3, 7.3] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_cloudy_wv63: + name: quality_bt_cloudy_wv63 + long_name: TOA Brightness Temperature % confidence at 6.3um (cloudy pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#27#brightnessTemperature->percentConfidence' + wavelength: [5.3, 6.3, 7.3] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_all_wv73: + name: quality_bt_all_wv73 + long_name: TOA Brightness Temperature % confidence at 7.3um (all pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#31#brightnessTemperature->percentConfidence' + wavelength: [6.85, 7.35, 7.85] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_clear_wv73: + name: quality_bt_clear_wv73 + long_name: TOA Brightness Temperature % confidence at 7.3um (clear pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#32#brightnessTemperature->percentConfidence' + wavelength: [6.85, 7.35, 7.85] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_cloudy_wv73: + name: quality_bt_cloudy_wv73 + long_name: TOA Brightness Temperature % confidence at 7.3um (cloudy pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#33#brightnessTemperature->percentConfidence' + wavelength: [6.85, 7.35, 7.85] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_all_ir87: + name: quality_bt_all_ir87 + long_name: TOA Brightness Temperature % confidence at 8.7um (all pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#37#brightnessTemperature->percentConfidence' + wavelength: [8.3, 8.7, 9.1] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_clear_ir87: + name: quality_bt_clear_ir87 + long_name: TOA Brightness Temperature % confidence at 8.7um (clear pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#38#brightnessTemperature->percentConfidence' + wavelength: [8.3, 8.7, 9.1] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_cloudy_ir87: + name: quality_bt_cloudy_ir87 + long_name: TOA Brightness Temperature % confidence at 8.7um (cloudy pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#39#brightnessTemperature->percentConfidence' + wavelength: [8.3, 8.7, 9.1] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_all_ir97: + name: quality_bt_all_ir97 + long_name: TOA Brightness Temperature % confidence at 9.7um (all pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#43#brightnessTemperature->percentConfidence' + wavelength: [9.36, 9.66, 9.96] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_clear_ir97: + name: quality_bt_clear_ir97 + long_name: TOA Brightness Temperature % confidence at 9.7um (clear pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#44#brightnessTemperature->percentConfidence' + wavelength: [9.36, 9.66, 9.96] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_cloudy_ir97: + name: quality_bt_cloudy_ir97 + long_name: TOA Brightness Temperature % confidence at 9.7um (cloudy pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#45#brightnessTemperature->percentConfidence' + wavelength: [9.36, 9.66, 9.96] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_all_ir105: + name: quality_bt_all_ir105 + long_name: TOA Brightness Temperature % confidence at 10.5um (all pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#49#brightnessTemperature->percentConfidence' + wavelength: [9.8, 10.5, 11.2] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_clear_ir105: + name: quality_bt_clear_ir105 + long_name: TOA Brightness Temperature % confidence at 10.5um (clear pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#50#brightnessTemperature->percentConfidence' + wavelength: [9.8, 10.5, 11.2] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_cloudy_ir105: + name: quality_bt_cloudy_ir105 + long_name: TOA Brightness Temperature % confidence at 10.5um (cloudy pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#51#brightnessTemperature->percentConfidence' + wavelength: [9.8, 10.5, 11.2] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_all_ir123: + name: quality_bt_all_ir123 + long_name: TOA Brightness Temperature % confidence at 12.3um (all pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#55#brightnessTemperature->percentConfidence' + wavelength: [11.8, 12.3, 12.8] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_clear_ir123: + name: quality_bt_clear_ir123 + long_name: TOA Brightness Temperature % confidence at 12.3um (clear pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#56#brightnessTemperature->percentConfidence' + wavelength: [11.8, 12.3, 12.8] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_cloudy_ir123: + name: quality_bt_cloudy_ir123 + long_name: TOA Brightness Temperature % confidence at 12.3um (cloudy pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#57#brightnessTemperature->percentConfidence' + wavelength: [11.8, 12.3, 12.8] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_all_ir133: + name: quality_bt_all_ir133 + long_name: TOA Brightness Temperature % confidence at 13.3um (all pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#61#brightnessTemperature->percentConfidence' + wavelength: [12.7, 13.3, 13.9] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_clear_ir133: + name: quality_bt_clear_ir133 + long_name: TOA Brightness Temperature % confidence at 13.3um (clear pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#62#brightnessTemperature->percentConfidence' + wavelength: [12.7, 13.3, 13.9] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + quality_bt_cloudy_ir133: + name: quality_bt_cloudy_ir133 + long_name: TOA Brightness Temperature % confidence at 13.3um (cloudy pixels) + standard_name: quality + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#63#brightnessTemperature->percentConfidence' + wavelength: [12.7, 13.3, 13.9] + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_all_ir38: + name: std_bt_all_ir38 + long_name: TOA Brightness Temperature standard deviation at 3.8um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#19#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [3.4, 3.8, 4.2] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_clear_ir38: + name: std_bt_clear_ir38 + long_name: TOA Brightness Temperature standard deviation at 3.8um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#20#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [3.4, 3.8, 4.2] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_cloudy_ir38: + name: std_bt_cloudy_ir38 + long_name: TOA Brightness Temperature standard deviation at 3.8um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#21#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [3.4, 3.8, 4.2] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_all_wv63: + name: std_bt_all_wv63 + long_name: TOA Brightness Temperature standard deviation at 6.3um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#25#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [5.3, 6.3, 7.3] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_clear_wv63: + name: std_bt_clear_wv63 + long_name: TOA Brightness Temperature standard deviation at 6.3um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#26#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [5.3, 6.3, 7.3] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_cloudy_wv63: + name: std_bt_cloudy_wv63 + long_name: TOA Brightness Temperature standard deviation at 6.3um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#27#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [5.3, 6.3, 7.3] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_all_wv73: + name: std_bt_all_wv73 + long_name: TOA Brightness Temperature standard deviation at 7.3um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#31#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [6.85, 7.35, 7.85] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_clear_wv73: + name: std_bt_clear_wv73 + long_name: TOA Brightness Temperature standard deviation at 7.3um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#32#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [6.85, 7.35, 7.85] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_cloudy_wv73: + name: std_bt_cloudy_wv73 + long_name: TOA Brightness Temperature standard deviation at 7.3um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#33#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [6.85, 7.35, 7.85] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_all_ir87: + name: std_bt_all_ir87 + long_name: TOA Brightness Temperature standard deviation at 8.7um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#37#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [8.3, 8.7, 9.1] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_clear_ir87: + name: std_bt_clear_ir87 + long_name: TOA Brightness Temperature standard deviation at 8.7um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#38#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [8.3, 8.7, 9.1] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_cloudy_ir87: + name: std_bt_cloudy_ir87 + long_name: TOA Brightness Temperature standard deviation at 8.7um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#39#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [8.3, 8.7, 9.1] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_all_ir97: + name: std_bt_all_ir97 + long_name: TOA Brightness Temperature standard deviation at 9.7um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#43#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [9.36, 9.66, 9.96] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_clear_ir97: + name: std_bt_clear_ir97 + long_name: TOA Brightness Temperature standard deviation at 9.7um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#44#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [9.36, 9.66, 9.96] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_cloudy_ir97: + name: std_bt_cloudy_ir97 + long_name: TOA Brightness Temperature standard deviation at 9.7um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#45#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [9.36, 9.66, 9.96] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_all_ir105: + name: std_bt_all_ir105 + long_name: TOA Brightness Temperature standard deviation at 10.5um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#49#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [9.8, 10.5, 11.2] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_clear_ir105: + name: std_bt_clear_ir105 + long_name: TOA Brightness Temperature standard deviation at 10.5um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#50#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [9.8, 10.5, 11.2] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_cloudy_ir105: + name: std_bt_cloudy_ir105 + long_name: TOA Brightness Temperature standard deviation at 10.5um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#51#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [9.8, 10.5, 11.2] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_all_ir123: + name: std_bt_all_ir123 + long_name: TOA Brightness Temperature standard deviation at 12.3um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#55#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [11.8, 12.3, 12.8] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_clear_ir123: + name: std_bt_clear_ir123 + long_name: TOA Brightness Temperature standard deviation at 12.3um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#56#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [11.8, 12.3, 12.8] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_cloudy_ir123: + name: std_bt_cloudy_ir123 + long_name: TOA Brightness Temperature standard deviation at 12.3um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#57#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [11.8, 12.3, 12.8] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_all_ir133: + name: std_bt_all_ir133 + long_name: TOA Brightness Temperature standard deviation at 13.3um (all pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#61#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [12.7, 13.3, 13.9] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_clear_ir133: + name: std_bt_clear_ir133 + long_name: TOA Brightness Temperature standard deviation at 13.3um (clear pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#62#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [12.7, 13.3, 13.9] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + std_bt_cloudy_ir133: + name: std_bt_cloudy_ir133 + long_name: TOA Brightness Temperature standard deviation at 13.3um (cloudy pixels) + standard_name: toa_brightess_temperature + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#63#brightnessTemperature->firstOrderStatisticalValue' + wavelength: [12.7, 13.3, 13.9] + cell_method: area:standard_deviation + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + pixel_percentage_clear: + name: pixel_percentage_clear + long_name: Clear Sky Fraction in Segment + standard_name: pixels_used_fraction + resolution: 32000 + file_type: fci_l2_bufr_asr + key: '#1#amountSegmentCloudFree' + fill_value: -1.0e+100 + units: '%' + coordinates: + - longitude + - latitude diff --git a/satpy/etc/readers/fci_l2_nc.yaml b/satpy/etc/readers/fci_l2_nc.yaml index ab91e592b5..6a465f3f7a 100644 --- a/satpy/etc/readers/fci_l2_nc.yaml +++ b/satpy/etc/readers/fci_l2_nc.yaml @@ -183,7 +183,7 @@ datasets: intm_pressure: name: intm_pressure - standard_name: wind_pressure + standard_name: air_pressure_at_wind_level file_type: nc_fci_amvi nc_key: intm_pressure coordinates: @@ -192,7 +192,7 @@ datasets: intm_temperature: name: intm_temperature - standard_name: wind_temperature + standard_name: air_temperature_at_wind_level file_type: nc_fci_amvi nc_key: intm_temperature coordinates: @@ -275,7 +275,7 @@ datasets: pressure: name: pressure - standard_name: wind_pressure + standard_name: air_pressure_at_wind_level file_type: nc_fci_amv nc_key: pressure coordinates: @@ -284,7 +284,7 @@ datasets: temperature: name: temperature - standard_name: wind_temperature + standard_name: air_temperature_at_wind_level file_type: nc_fci_amv nc_key: temperature coordinates: diff --git a/satpy/etc/readers/seviri_l2_bufr.yaml b/satpy/etc/readers/seviri_l2_bufr.yaml index e0c51c4370..d998afd8d9 100644 --- a/satpy/etc/readers/seviri_l2_bufr.yaml +++ b/satpy/etc/readers/seviri_l2_bufr.yaml @@ -11,48 +11,48 @@ reader: file_types: seviri_l2_bufr_asr: - file_reader: !!python/name:satpy.readers.seviri_l2_bufr.SeviriL2BufrFileHandler + file_reader: !!python/name:satpy.readers.eum_l2_bufr.EumetsatL2BufrFileHandler file_patterns: - 'ASRBUFRProd_{start_time:%Y%m%d%H%M%S}Z_00_{server:s}_{satellite:s}_{mission:s}_{subsat:s}' - '{spacecraft:s}-SEVI-MSGASRE-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}.bfr' - '{spacecraft:s}-SEVI-MSGASRE-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}' seviri_l2_bufr_cla: - file_reader: !!python/name:satpy.readers.seviri_l2_bufr.SeviriL2BufrFileHandler + file_reader: !!python/name:satpy.readers.eum_l2_bufr.EumetsatL2BufrFileHandler file_patterns: - 'CLABUFRProd_{start_time:%Y%m%d%H%M%S}Z_00_{server:s}_{satellite:s}_{mission:s}_{subsat:s}' - '{spacecraft:s}-SEVI-MSGCLAP-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}.bfr' - '{spacecraft:s}-SEVI-MSGCLAP-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}' seviri_l2_bufr_csr: - file_reader: !!python/name:satpy.readers.seviri_l2_bufr.SeviriL2BufrFileHandler + file_reader: !!python/name:satpy.readers.eum_l2_bufr.EumetsatL2BufrFileHandler file_patterns: - 'CSRBUFRProd_{start_time:%Y%m%d%H%M%S}Z_00_{server:s}_{satellite:s}_{mission:s}_{subsat:s}' - '{spacecraft:s}-SEVI-MSGCSKR-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}.bfr' - '{spacecraft:s}-SEVI-MSGCSKR-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}' seviri_l2_bufr_gii: - file_reader: !!python/name:satpy.readers.seviri_l2_bufr.SeviriL2BufrFileHandler + file_reader: !!python/name:satpy.readers.eum_l2_bufr.EumetsatL2BufrFileHandler file_patterns: - 'GIIBUFRProduct_{start_time:%Y%m%d%H%M%S}Z_00_{server:s}_{satellite:s}_{mission:s}_{subsat:s}' - '{spacecraft:s}-SEVI-MSGGIIN-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}.bfr' - '{spacecraft:s}-SEVI-MSGGIIN-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}' seviri_l2_bufr_thu: - file_reader: !!python/name:satpy.readers.seviri_l2_bufr.SeviriL2BufrFileHandler + file_reader: !!python/name:satpy.readers.eum_l2_bufr.EumetsatL2BufrFileHandler file_patterns: - 'THBUFRProd_{start_time:%Y%m%d%H%M%S}Z_00_{server:s}_{satellite:s}_{mission:s}_{subsat:s}' - '{spacecraft:s}-SEVI-MSGTPHU-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}.bfr' - '{spacecraft:s}-SEVI-MSGTPHU-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}' seviri_l2_bufr_toz: - file_reader: !!python/name:satpy.readers.seviri_l2_bufr.SeviriL2BufrFileHandler + file_reader: !!python/name:satpy.readers.eum_l2_bufr.EumetsatL2BufrFileHandler file_patterns: - 'TOZBUFRProd_{start_time:%Y%m%d%H%M%S}Z_00_{server:s}_{satellite:s}_{mission:s}_{subsat:s}' - '{spacecraft:s}-SEVI-MSGTOZN-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}.bfr' - '{spacecraft:s}-SEVI-MSGTOZN-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}' seviri_l2_bufr_amv: - file_reader: !!python/name:satpy.readers.seviri_l2_bufr.SeviriL2BufrFileHandler + file_reader: !!python/name:satpy.readers.eum_l2_bufr.EumetsatL2BufrFileHandler file_patterns: - 'AMVBUFRProd_{start_time:%Y%m%d%H%M%S}Z_00_{server:s}_{satellite:s}_{mission:s}_{subsat:s}' - '{spacecraft:s}-SEVI-MSGAMVE-{loc1:s}-{loc2:s}-{start_time:%Y%m%d%H%M%S}.000000000Z-{time1:%Y%m%d%H%M%S}-{ord1:s}.bfr' @@ -65,7 +65,7 @@ datasets: key: '#1#latitude' long_name: Latitude standard_name: latitude - resolution: [48006.450653072,9001.209497451,72009.675979608] + resolution: [48006.450653072,48006.450653072,48006.450653072,9001.209497451,48006.450653072,9001.209497451,-1] file_type: [seviri_l2_bufr_asr,seviri_l2_bufr_cla,seviri_l2_bufr_csr,seviri_l2_bufr_gii,seviri_l2_bufr_thu,seviri_l2_bufr_toz,seviri_l2_bufr_amv] units: degree_north fill_value: -1.e+100 @@ -73,7 +73,7 @@ datasets: longitude: name: longitude key: '#1#longitude' - resolution: [48006.450653072,9001.209497451,72009.675979608] + resolution: [48006.450653072,48006.450653072,48006.450653072,9001.209497451,48006.450653072,9001.209497451,-1] file_type: [seviri_l2_bufr_asr,seviri_l2_bufr_cla,seviri_l2_bufr_csr,seviri_l2_bufr_gii,seviri_l2_bufr_thu,seviri_l2_bufr_toz,seviri_l2_bufr_amv] long_name: Longitude standard_name: longitude @@ -1081,7 +1081,7 @@ datasets: coordinates: - longitude - latitude - units: "" + units: "°C" file_type: seviri_l2_bufr_gii fill_value: -1.e+100 @@ -1094,7 +1094,7 @@ datasets: coordinates: - longitude - latitude - units: "" + units: "°C" file_type: seviri_l2_bufr_gii fill_value: -1.e+100 @@ -1107,7 +1107,7 @@ datasets: coordinates: - longitude - latitude - units: "" + units: "°C" file_type: seviri_l2_bufr_gii fill_value: -1.e+100 @@ -1120,7 +1120,7 @@ datasets: coordinates: - longitude - latitude - units: mm + units: kg/m2 file_type: seviri_l2_bufr_gii fill_value: -1.e+100 @@ -1133,7 +1133,7 @@ datasets: coordinates: - longitude - latitude - units: mm + units: kg/m2 file_type: seviri_l2_bufr_gii fill_value: -1.e+100 @@ -1146,7 +1146,7 @@ datasets: coordinates: - longitude - latitude - units: mm + units: kg/m2 file_type: seviri_l2_bufr_gii fill_value: -1.e+100 @@ -1159,7 +1159,7 @@ datasets: coordinates: - longitude - latitude - units: "" + units: "°C" file_type: seviri_l2_bufr_gii fill_value: -1.e+100 @@ -1172,7 +1172,7 @@ datasets: coordinates: - longitude - latitude - units: degrees + units: degrees_north file_type: seviri_l2_bufr_gii fill_value: 0 @@ -1185,7 +1185,7 @@ datasets: coordinates: - longitude - latitude - units: mm + units: kg/m2 file_type: seviri_l2_bufr_gii fill_value: -1.e+100 @@ -1246,41 +1246,170 @@ datasets: flag_meanings: ['not processed', 'first guess', 'high cloud (not processed)', 'successful retrieval', 'bad retrieval'] # ---- AMV products ------------ - speed: - name: speed - long_name: Wind Speed - standard_name: wind_speed - key: '#1#windSpeed' - resolution: 72009.675979608 + pressure: + name: pressure + long_name: Air Pressure at Wind Level + standard_name: air_pressure file_type: seviri_l2_bufr_amv - units: m s-1 + key: '#1#pressure' + units: Pa fill_value: -1.e+100 coordinates: - longitude - latitude + oca_pressure: + name: oca_pressure + long_name: Air Pressure at Wind Level feature from OCA hight assignment + standard_name: air_pressure_at_wind_level + file_type: fci_l2_bufr_amv + key: '#3#pressure' + units: Pa + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + temperature: + name: temperature + long_name: Temperature of AMV feature + standard_name: air_temperature_at_wind_level + file_type: seviri_l2_bufr_amv + key: '#1#airTemperature' + units: K + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + height: + name: height + file_type: seviri_l2_bufr_amv + key: '#1#heightOfTopOfCloud' + long_name: Height of AMV feature + standard_name: height_at_wind_level + units: m + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + direction: name: direction long_name: Wind Direction standard_name: wind_to_direction - key: '#1#windDirection' - resolution: 72009.675979608 file_type: seviri_l2_bufr_amv - units: deg + key: '#1#windDirection' + units: degrees_north fill_value: -1.e+100 coordinates: - longitude - latitude - pressure: - name: pressure - long_name: Air Pressure at Wind Level - standard_name: air_pressure - key: '#1#pressure' - resolution: 72009.675979608 + speed: + name: speed + long_name: Wind Speed + standard_name: wind_speed file_type: seviri_l2_bufr_amv - units: Pa + key: '#1#windSpeed' + units: m/s fill_value: -1.e+100 coordinates: - longitude - latitude + + speed_u_component: + name: speed_u_component + long_name: Speed U component of AMV + standard_name: wind_speed_horizontal_component + file_type: seviri_l2_bufr_amv + key: '#1#u' + units: m/s + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + speed_v_component: + name: speed_v_component + long_name: Speed V component of AMV + standard_name: wind_speed_vertival_component + file_type: seviri_l2_bufr_amv + key: '#1#v' + units: m/s + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + target_type: + name: target_type + long_name: Target type (cloud or clearsky) + standard_name: wind_target_type + file_type: seviri_l2_bufr_amv + key: '#1#extendedHeightAssignmentMethod' + units: "" + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + wind_method: + name: wind_method + long_name: Wind derivation method + standard_name: wind_wind_method + file_type: seviri_l2_bufr_amv + key: 'satelliteDerivedWindComputationMethod' + units: "" + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + qi: + name: qi + long_name: Overall Reliability of AMV + standard_name: wind_overall_reliability + file_type: seviri_l2_bufr_amv + key: '#1#percentConfidence' + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + qi_excl_fcst: + name: qi_excl_fcst + long_name: Overall Reliability (excluding forecast) of AMV + standard_name: wind_overall_reliability_exc_forecast + file_type: seviri_l2_bufr_amv + key: '#2#percentConfidence' + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + qi_excl_fcst_oca: + name: qi_excl_fcst_oca + long_name: Overall Reliability (excluding forecast and OCA) of AMV + standard_name: wind_overall_reliability_exc_forecast_and_oca + file_type: seviri_l2_bufr_amv + key: '#4#percentConfidence' + units: '%' + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude + + channel_id: + name: channel_id + long_name: Channel Id + standard_name: channel_id + file_type: seviri_l2_bufr_amv + key: '#1#channelNumber' + units: "" + fill_value: -1.0e+100 + coordinates: + - longitude + - latitude diff --git a/satpy/readers/seviri_l2_bufr.py b/satpy/readers/eum_l2_bufr.py similarity index 58% rename from satpy/readers/seviri_l2_bufr.py rename to satpy/readers/eum_l2_bufr.py index a48a7e00d6..15c594bf73 100644 --- a/satpy/readers/seviri_l2_bufr.py +++ b/satpy/readers/eum_l2_bufr.py @@ -26,6 +26,7 @@ import datetime as dt import logging +import os import dask.array as da import numpy as np @@ -44,20 +45,26 @@ raise ImportError( "Missing eccodes-python and/or eccodes C-library installation. Use conda to install eccodes") +logger = logging.getLogger("EumetsatL2Bufr") + CHUNK_SIZE = get_legacy_chunk_size() -logger = logging.getLogger("SeviriL2Bufr") -data_center_dict = {55: {"ssp": "E0415", "name": "08"}, 56: {"ssp": "E0455", "name": "09"}, - 57: {"ssp": "E0095", "name": "10"}, 70: {"ssp": "E0000", "name": "11"}} +SSP_DEFAULT = 0.0 +BUFR_FILL_VALUE = -1.e+100 + +data_center_dict = {55: {"ssp": "E0415", "name": "MSG1"}, 56: {"ssp": "E0455", "name": "MSG2"}, + 57: {"ssp": "E0095", "name": "MSG3"}, 70: {"ssp": "E0000", "name": "MSG4"}, + 71: {"ssp": "E0000", "name": "MTGi1"}} + +# Sensor resolution (pixel size in m) used to deermine product segment sizes +resolution_dict = {"fci": 2000, "seviri": 3000} -seg_size_dict = {"seviri_l2_bufr_asr": 16, "seviri_l2_bufr_cla": 16, - "seviri_l2_bufr_csr": 16, "seviri_l2_bufr_gii": 3, - "seviri_l2_bufr_thu": 16, "seviri_l2_bufr_toz": 3, - "seviri_l2_bufr_amv": 24} +# List of variables that are now returned by eccodes as array, but that we want as single value +deprecate_to_single_value = ["satelliteIdentifier"] -class SeviriL2BufrFileHandler(BaseFileHandler): - """File handler for SEVIRI L2 BUFR products. +class EumetsatL2BufrFileHandler(BaseFileHandler): + """File handler for EUMETSAT Central Facility SEVIRI and FCI L2 BUFR products. **Loading data with AreaDefinition** @@ -66,8 +73,8 @@ class SeviriL2BufrFileHandler(BaseFileHandler): be loaded with a SwathDefinition, i.e. similar to how the data are stored in the BUFR file: scene = satpy.Scene(filenames, - reader='seviri_l2_bufr', - reader_kwargs={'with_area_definition': False}) + reader="seviri_l2_bufr", + reader_kwargs={"with_area_definition": False}) **Defining dataset recticifation longitude** @@ -77,62 +84,78 @@ class SeviriL2BufrFileHandler(BaseFileHandler): rectification longitude can be defined by the user by providing `rectification_longitude` in the `reader_kwargs`: scene = satpy.Scene(filenames, - reader='seviri_l2_bufr', - reader_kwargs={'rectification_longitude': 0.0}) + reader="seviri_l2_bufr", + reader_kwargs={"rectification_longitude": 0.0}) If not done, default values applicable to the operational grids of the respective SEVIRI instruments will be used. """ def __init__(self, filename, filename_info, filetype_info, with_area_definition=False, rectification_longitude="default", **kwargs): - """Initialise the file handler for SEVIRI L2 BUFR data.""" - super(SeviriL2BufrFileHandler, self).__init__(filename, - filename_info, - filetype_info) + """Initialise the file handler for EUMETSAT SEVIRI and FCI L2 BUFR data.""" + super(EumetsatL2BufrFileHandler, self).__init__(filename, + filename_info, + filetype_info) + + # Set this environment variable to get consistent array sizes from eccodes. This fixes the cases + # where all values in the expected array are the same (in particular fill values) which causes + # eccodes to encode them and return them as a single value + os.environ["ECCODES_BUFR_MULTI_ELEMENT_CONSTANT_ARRAYS"] = "1" if ("server" in filename_info): # EUMETSAT Offline Bufr product - self.mpef_header = self._read_mpef_header() + self.bufr_header = self._read_mpef_header() else: # Product was retrieved from the EUMETSAT Data Center - timeStr = self.get_attribute("typicalDate")+self.get_attribute("typicalTime") - buf_start_time = dt.datetime.strptime(timeStr, "%Y%m%d%H%M%S") - sc_id = self.get_attribute("satelliteIdentifier") - self.mpef_header = {} - self.mpef_header["NominalTime"] = buf_start_time - self.mpef_header["SpacecraftName"] = data_center_dict[sc_id]["name"] - self.mpef_header["RectificationLongitude"] = data_center_dict[sc_id]["ssp"] + attr = self.get_attributes(["typicalDate", "typicalTime", "satelliteIdentifier"]) + timeStr = attr["typicalDate"]+attr["typicalTime"] + sc_id = int(attr["satelliteIdentifier"]) + + self.bufr_header = {} + self.bufr_header["NominalTime"] = dt.datetime.strptime(timeStr, "%Y%m%d%H%M%S") + self.bufr_header["SpacecraftName"] = data_center_dict[sc_id]["name"] + self.bufr_header["RectificationLongitude"] = data_center_dict[sc_id]["ssp"] if rectification_longitude != "default": - self.mpef_header["RectificationLongitude"] = f"E{int(rectification_longitude * 10):04d}" + self.bufr_header["RectificationLongitude"] = f"E{int(rectification_longitude * 10):04d}" + self.filetype = filetype_info["file_type"] self.with_adef = with_area_definition - if self.with_adef and filetype_info["file_type"] == "seviri_l2_bufr_amv": - logging.warning("AMV BUFR data cannot be loaded with an area definition. Setting self.with_def = False.") - self.with_adef = False - self.seg_size = seg_size_dict[filetype_info["file_type"]] + def __del__(self): + """Delete the instance and environment variable.""" + try: + del os.environ["ECCODES_BUFR_MULTI_ELEMENT_CONSTANT_ARRAYS"] + except KeyError: + pass @property def start_time(self): """Return the repeat cycle start time.""" - return self.mpef_header["NominalTime"] - - @property - def end_time(self): - """Return the repeat cycle end time.""" - return self.start_time + dt.timedelta(minutes=15) + return self.bufr_header["NominalTime"] @property def platform_name(self): """Return spacecraft name.""" - return "MET{}".format(self.mpef_header["SpacecraftName"]) + if self.bufr_header["SpacecraftName"].isdigit(): + # self._read_mpef_header will return the SpacecraftName as a string with an integer, representing the + # Meteosat series number (1-11). This is cnverted to the corresponding MSG ID. + return f'MSG{int(self.bufr_header["SpacecraftName"])-7}' + else: + return self.bufr_header["SpacecraftName"] + + @property + def sensor_name(self): + """Return instrument name.""" + if self.platform_name.startswith("MSG"): + return "seviri" + elif self.platform_name.startswith("MTG"): + return "fci" @property def ssp_lon(self): """Return subsatellite point longitude.""" - # e.g. E0415 - ssp_lon = self.mpef_header["RectificationLongitude"] + ssp_lon = self.bufr_header["RectificationLongitude"] return float(ssp_lon[1:])/10. def get_area_def(self, key): @@ -147,23 +170,40 @@ def _read_mpef_header(self): hdr = np.fromfile(self.filename, mpef_product_header, 1) return recarray2dict(hdr) - def get_attribute(self, key): + def get_attributes(self, keys): """Get BUFR attributes.""" # This function is inefficient as it is looping through the entire - # file to get 1 attribute. It causes a problem though if you break - # from the file early - dont know why but investigating - fix later + # file to get a list of attributes. It causes a problem though if you break + # from the file early - dont know why but investigating - fix later. fh = open(self.filename, "rb") + + # Initialize output + attrs = dict() + while True: - # get handle for message + # Get handle for message bufr = ec.codes_bufr_new_from_file(fh) if bufr is None: break ec.codes_set(bufr, "unpack", 1) - attr = ec.codes_get(bufr, key) + for k in keys: + try: + if k in deprecate_to_single_value: + # With ECCODES_BUFR_MULTI_ELEMENT_CONSTANT_ARRAYS set to 1 all values, including scalars, are + # returned as arrays. Hence, we extract the single value here. + value = ec.codes_get_array(bufr, k)[0] + else: + value = ec.codes_get(bufr, k) + attrs[k] = value + + except BaseException: + attrs[k] = None + logging.warning(f"Failed to read key {k} from message") + ec.codes_release(bufr) fh.close() - return attr + return attrs def get_array(self, key): """Get all data from file for the given BUFR key.""" @@ -176,13 +216,16 @@ def get_array(self, key): ec.codes_set(bufr, "unpack", 1) + if not ec.codes_is_defined(bufr, key): + logging.warning(f"Key: {key} does not exist in BUFR file") + return None + # if is the first message initialise our final array if (msgCount == 0): - arr = da.from_array(ec.codes_get_array( - bufr, key, float), chunks=CHUNK_SIZE) + arr = da.from_array(ec.codes_get_array(bufr, key, float), chunks=CHUNK_SIZE) + else: - tmpArr = da.from_array(ec.codes_get_array( - bufr, key, float), chunks=CHUNK_SIZE) + tmpArr = da.from_array(ec.codes_get_array(bufr, key, float), chunks=CHUNK_SIZE) arr = da.concatenate((arr, tmpArr)) msgCount = msgCount+1 @@ -202,19 +245,21 @@ def get_dataset(self, dataset_id, dataset_info): """ arr = self.get_array(dataset_info["key"]) - if self.with_adef: + if self.with_adef and "resolution" in dataset_id: xarr = self.get_dataset_with_area_def(arr, dataset_id) - # coordinates are not relevant when returning data with an AreaDefinition + # Coordinates are not relevant when returning data with an AreaDefinition if "coordinates" in dataset_info.keys(): del dataset_info["coordinates"] else: + if self.with_adef: + logging.warning("Trying to use `with_area_definition=True` for a dataset without resolution. " + "This is not supported and the keyword will be ignored.") xarr = xr.DataArray(arr, dims=["y"]) if "fill_value" in dataset_info: xarr = xarr.where(xarr != dataset_info["fill_value"]) self._add_attributes(xarr, dataset_info) - return xarr def get_dataset_with_area_def(self, arr, dataset_id): @@ -224,7 +269,6 @@ def get_dataset_with_area_def(self, arr, dataset_id): xarr = xr.DataArray(arr, dims=["y"]) else: lons_1d, lats_1d, data_1d = da.compute(self.longitude, self.latitude, arr) - self._area_def = self._construct_area_def(dataset_id) icol, irow = self._area_def.get_array_indices_from_lonlat(lons_1d, lats_1d) @@ -249,19 +293,17 @@ def _construct_area_def(self, dataset_id): AreaDefinition: A pyresample AreaDefinition object containing the area definition. """ - res = dataset_id["resolution"] - - area_naming_input_dict = {"platform_name": "msg", - "instrument_name": "seviri", - "resolution": res, + area_naming_input_dict = {"platform_name": self.platform_name[:3].lower(), + "instrument_name": self.sensor_name, + "resolution": dataset_id["resolution"], } area_naming = get_geos_area_naming({**area_naming_input_dict, - **get_service_mode("seviri", self.ssp_lon)}) + **get_service_mode(self.sensor_name, self.ssp_lon)}) # Datasets with a segment size of 3 pixels extend outside the original SEVIRI 3km grid (with 1238 x 1238 # segments a 3 pixels). Hence, we need to use corresponding area defintions in areas.yaml - if self.seg_size == 3: + if self.sensor_name=="seviri" and round(dataset_id["resolution"])==9001: area_naming["area_id"] += "_ext" area_naming["description"] += " (extended outside original 3km grid)" @@ -272,8 +314,13 @@ def _construct_area_def(self, dataset_id): def _add_attributes(self, xarr, dataset_info): """Add dataset attributes to xarray.""" - xarr.attrs["sensor"] = "SEVIRI" + xarr.attrs["sensor"] = self.sensor_name.upper() xarr.attrs["platform_name"] = self.platform_name xarr.attrs["ssp_lon"] = self.ssp_lon - xarr.attrs["seg_size"] = self.seg_size + if ("resolution" not in dataset_info) or (dataset_info["resolution"] is None): + xarr.attrs["seg_size"] = None + xarr.attrs["resolution"] = None + else: + xarr.attrs["seg_size"] = round(dataset_info["resolution"]/resolution_dict[self.sensor_name]) + xarr.attrs.update(dataset_info) diff --git a/satpy/tests/reader_tests/test_eum_l2_bufr.py b/satpy/tests/reader_tests/test_eum_l2_bufr.py new file mode 100644 index 0000000000..274dbdab8b --- /dev/null +++ b/satpy/tests/reader_tests/test_eum_l2_bufr.py @@ -0,0 +1,379 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2017-2019 Satpy developers +# +# This file is part of satpy. +# +# satpy is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# satpy is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# satpy. If not, see . +"""Unittesting the EUMETSAT L2 BUFR reader.""" + +import sys +import unittest +from datetime import datetime +from unittest import mock + +import dask.array as da +import numpy as np +import pytest +from pyresample import geometry + +from satpy.tests.utils import make_dataid + +AREA_DEF_MSG_IODC = geometry.AreaDefinition( + "msg_seviri_iodc_48km", + "MSG SEVIRI Indian Ocean Data Coverage service area definition with 48 km resolution", + "", + {"a": 6378169., "b": 6356583.8, "lon_0": 45.5, + "h": 35785831., "proj": "geos", "units": "m"}, + 232, + 232, + (-5570248.686685662, -5567248.28340708, 5567248.28340708, 5570248.686685662) +) + +AREA_DEF_MSG_FES = geometry.AreaDefinition( + + "msg_seviri_fes_48km", + "MSG SEVIRI Full Earth Scanning service area definition with 48 km resolution", + "", + {"a": 6378169., "b": 6356583.8, "lon_0": 0.0, + "h": 35785831., "proj": "geos", "units": "m"}, + 232, + 232, + (-5570248.6867, -5567248.2834, 5567248.2834, 5570248.6867) +) + +AREA_DEF_MSG_IODC_EXT = geometry.AreaDefinition( + "msg_seviri_iodc_9km_ext", + "MSG SEVIRI Indian Ocean Data Coverage service area definition with 9 km resolution " + "(extended outside original 3km grid)", + "", + {"a": 6378169., "b": 6356583.8, "lon_0": 45.5, + "h": 35785831., "proj": "geos", "units": "m"}, + 1238, + 1238, + (-5571748.8883, -5571748.8882, 5571748.8882, 5571748.8883) +) + +AREA_DEF_FCI_FES = geometry.AreaDefinition( + "mtg_fci_fdss_32km", + "MTG FCI Full Disk Scanning Service area definition with 32 km SSP resolution", + "", + {"x_0": 0, "y_0": 0, "ellps": "WGS84", "lon_0": 0.0, + "h": 35786400., "proj": "geos", "units": "m"}, + 348, + 348, + (-5567999.998550739, -5567999.998550739, 5567999.994203017, 5567999.994203017) +) + +AREA_DEF_MSG_FES_3km_ext = geometry.AreaDefinition( + "msg_seviri_fes_9km_ext", + "MSG SEVIRI Full Earth Scanning service area definition with 9 km resolution", + "", + {"a": 6378169., "b": 6356583.8, "lon_0": 0.0, + "h": 35785831., "proj": "geos", "units": "m"}, + 1238, + 1238, + (-5571748.888268564, -5571748.888155806, 5571748.888155806, 5571748.888268564) +) + +# Test data for mock file +DATA = np.random.default_rng().uniform(low=250, high=350, size=(128,)) +LAT = np.random.default_rng().uniform(low=-80, high=80, size=(128,)) +LON = np.random.default_rng().uniform(low=-38.5, high=121.5, size=(128,)) + +# Test cases dictionaries +TEST_DATA = {"GIIBUFRProduct_20231027140000Z_00_OMPEFS03_MET10_FES_E0000": { + "platform_name": "MSG3", + "spacecraft_number": "10", + "RectificationLongitude": "E0000", + "ssp_lon": 0.0, + "area": AREA_DEF_MSG_FES_3km_ext, + "seg_size": 3, + "file_type": "seviri_l2_bufr_gii", + "key": "#1#brightnessTemperature", + "resolution": 9001, + "data": DATA}, + "ASRBUFRProd_20231022224500Z_00_OMPEFS03_MET10_FES_E0000": { + "platform_name": "MSG3", + "spacecraft_number": "10", + "RectificationLongitude": "E0000", + "ssp_lon": 0.0, + "area": AREA_DEF_MSG_FES, + "seg_size": 16, + "file_type": "seviri_l2_bufr_asr", + "key": "#1#brightnessTemperature", + "resolution": 48006, + "data": DATA}, + "AMVBUFRProd_20231023044500Z_00_OMPEFS02_MET09_FES_E0455": { + "platform_name": "MSG2", + "spacecraft_number": "9", + "RectificationLongitude": "E0455", + "area": AREA_DEF_MSG_IODC, + "ssp_lon": 45.5, + "seg_size": None, + "file_type": "seviri_l2_bufr_amv", + "key": "#1#brightnessTemperature", + "resolution": None, + "data": DATA}, + "MSG2-SEVI-MSGASRE-0101-0101-20191106130000.000000000Z-20191106131702-1362128.bfr": { + "platform_name": "MSG2", + "spacecraft_number": "9", + "RectificationLongitude": "E0455", + "area": AREA_DEF_MSG_IODC, + "ssp_lon": 45.5, + "seg_size": 16, + "file_type": "seviri_l2_bufr_asr", + "key": "#1#brightnessTemperature", + "resolution": 48006, + "data": DATA}, + """W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-2-ASR--FD------BUFR_C_EUMT_ + 20230623092246_L2PF_IV_20170410170000_20170410171000_V__C_0103_0000.bin""": { + "platform_name": "MTGi1", + "spacecraft_number": "24", + "RectificationLongitude": "E0000", + "area": AREA_DEF_FCI_FES, + "ssp_lon": 0.0, + "seg_size": 16, + "file_type": "fci_l2_bufr_asr", + "key": "#1#brightnessTemperature", + "resolution": 32000, + "data": DATA}, + """W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-2-AMV--FD------BUFR_C_EUMT_ +20230623092246_L2PF_IV_20170410170000_20170410171000_V__C_0103_0000.bin""": { + "platform_name": "MTGi1", + "spacecraft_number": "24", + "RectificationLongitude": "E0000", + "area": AREA_DEF_FCI_FES, + "ssp_lon": 0.0, + "seg_size": None, + "file_type": "fci_l2_bufr_amv", + "key": "#1#brightnessTemperature", + "resolution": None, + "data": DATA}} + +TEST_FILES = list(TEST_DATA.keys()) + + +class L2BufrData: + """Mock L2 BUFR data.""" + + @unittest.skipIf(sys.platform.startswith("win"), "'eccodes' not supported on Windows") + def __init__(self, filename, test_data, with_adef=False, rect_lon="default"): + """Initialize by mocking test data for testing the L2 BUFR reader.""" + import eccodes as ec + + from satpy.readers.eum_l2_bufr import EumetsatL2BufrFileHandler + + self.buf1 = ec.codes_bufr_new_from_samples("BUFR4_local_satellite") + ec.codes_set(self.buf1, "unpack", 1) + # write the bufr test data twice as we want to read in and then concatenate the data in the reader + # 55 id corresponds to METEOSAT 8 + ec.codes_set(self.buf1, "satelliteIdentifier", 47 + int(test_data["spacecraft_number"])) + ec.codes_set_array(self.buf1, "#1#latitude", LAT) + ec.codes_set_array(self.buf1, "#1#longitude", LON) + ec.codes_set_array(self.buf1, test_data["key"], test_data["data"]) + + self.m = mock.mock_open() + + FILETYPE_INFO = {"file_type": test_data["file_type"]} + + # only our offline product contain MPEF product headers so we get the metadata from there + if ("BUFRProd" in filename): + with mock.patch("satpy.readers.eum_l2_bufr.np.fromfile") as fromfile: + + MPEF_PRODUCT_HEADER = { + "NominalTime": datetime(2019, 11, 6, 18, 0), + "SpacecraftName": test_data["spacecraft_number"], + "RectificationLongitude": test_data["RectificationLongitude"] + } + fromfile.return_value = MPEF_PRODUCT_HEADER + with mock.patch("satpy.readers.eum_l2_bufr.recarray2dict") as recarray2dict: + recarray2dict.side_effect = (lambda x: x) + + FILENAME_INFO = {"start_time": "20231022224500", "spacecraft": test_data["platform_name"], + "server": "TESTSERVER"} + self.fh = EumetsatL2BufrFileHandler( + filename, FILENAME_INFO, FILETYPE_INFO, + with_area_definition=with_adef, + rectification_longitude=int(test_data["RectificationLongitude"][1:]) / 10) + self.fh.mpef_header = MPEF_PRODUCT_HEADER + + else: + # No Mpef Header so we get the metadata from the BUFR messages + with mock.patch("satpy.readers.eum_l2_bufr.open", self.m, create=True): + with mock.patch("eccodes.codes_bufr_new_from_file", + side_effect=[self.buf1, None, self.buf1, None, self.buf1, None]) as ec1: + ec1.return_value = ec1.side_effect + with mock.patch("eccodes.codes_set") as ec2: + ec2.return_value = 1 + with mock.patch("eccodes.codes_release") as ec5: + ec5.return_value = 1 + + FILENAME_INFO = {"start_time": "20191112000000", + "spacecraft": test_data["platform_name"]} + self.fh = EumetsatL2BufrFileHandler( + filename, FILENAME_INFO, FILETYPE_INFO, + with_area_definition=with_adef, + rectification_longitude=int(test_data["RectificationLongitude"][1:]) / 10) + + self.resolution = test_data["resolution"] + + def get_data(self, dataset_name, key, coordinates): + """Read data from mock file.""" + DATASET_INFO = { + "name": dataset_name, + "key": key, + "fill_value": -1.e+100, + "resolution": self.resolution + } + if coordinates: + DATASET_INFO.update({"coordinates": ("longitude", "latitude")}) + + with mock.patch("satpy.readers.eum_l2_bufr.open", self.m, create=True): + with mock.patch("eccodes.codes_bufr_new_from_file", + side_effect=[self.buf1, self.buf1, None]) as ec1: + ec1.return_value = ec1.side_effect + with mock.patch("eccodes.codes_set") as ec2: + ec2.return_value = 1 + with mock.patch("eccodes.codes_release") as ec5: + ec5.return_value = 1 + z = self.fh.get_dataset(make_dataid(name=dataset_name, resolution=self.resolution), + DATASET_INFO) + + return z + + +@pytest.mark.parametrize("input_file", TEST_FILES) +class TestL2BufrReader: + """Test EUMETSAT L2 BUFR Reader.""" + + @staticmethod + def test_lonslats(input_file): + """Test reading of longitude and latitude data with EUMETSAT L2 BUFR reader.""" + test_data = TEST_DATA[input_file] + bufr_obj = L2BufrData(input_file, test_data) + zlat = bufr_obj.get_data("latitude", "#1#latitude", coordinates=False) + zlon = bufr_obj.get_data("longitude", "#1#longitude", coordinates=False) + np.testing.assert_array_equal(zlat.values, np.concatenate((LAT, LAT), axis=0)) + np.testing.assert_array_equal(zlon.values, np.concatenate((LON, LON), axis=0)) + + @staticmethod + def test_attributes_with_swath_definition(input_file): + """Test correctness of dataset attributes with data loaded with a SwathDefinition (default behaviour).""" + test_data = TEST_DATA[input_file] + bufr_obj = L2BufrData(input_file, test_data) + z = bufr_obj.get_data(dataset_name="TestData", key=test_data["key"], coordinates=True) + assert z.attrs["platform_name"] == test_data["platform_name"] + assert z.attrs["ssp_lon"] == test_data["ssp_lon"] + assert z.attrs["seg_size"] == test_data["seg_size"] + + @staticmethod + def test_attributes_with_area_definition(input_file): + """Test correctness of dataset attributes with data loaded with a AreaDefinition.""" + test_data = TEST_DATA[input_file] + bufr_obj = L2BufrData(input_file, test_data, with_adef=True) + _ = bufr_obj.get_data("latitude", "#1#latitude", coordinates=False) + _ = bufr_obj.get_data("longitude", "#1#longitude", coordinates=False) + + z = bufr_obj.get_data(dataset_name="TestData", key=test_data["key"], coordinates=True) + assert z.attrs["platform_name"] == test_data["platform_name"] + assert z.attrs["ssp_lon"] == test_data["ssp_lon"] + assert z.attrs["seg_size"] == test_data["seg_size"] + + @staticmethod + def test_data_with_swath_definition(input_file): + """Test data loaded with SwathDefinition (default behaviour).""" + test_data = TEST_DATA[input_file] + bufr_obj = L2BufrData(input_file, test_data) + with pytest.raises(NotImplementedError): + bufr_obj.fh.get_area_def(None) + + # concatenate original test arrays as get_dataset will have read and concatented the data + x1 = np.concatenate((DATA, DATA), axis=0) + z = bufr_obj.get_data(dataset_name="TestData", key=test_data["key"], coordinates=True) + np.testing.assert_array_equal(z.values, x1) + + def test_data_with_area_definition(self, input_file): + """Test data loaded with an area definition.""" + test_data = TEST_DATA[input_file] + if test_data["seg_size"] is None: + # Skip this test + return + + bufr_obj = L2BufrData(input_file, test_data, with_adef=True) + _ = bufr_obj.get_data("latitude", "#1#latitude", coordinates=False) + _ = bufr_obj.get_data("longitude", "#1#longitude", coordinates=False) + + z = bufr_obj.get_data(dataset_name="TestData", key=test_data["key"], coordinates=True) + + ad = bufr_obj.fh.get_area_def(None) + + assert ad == test_data["area"] + data_1d = np.concatenate((DATA, DATA), axis=0) + + # Put BUFR data on 2D grid that the 2D array returned by get_dataset should correspond to + lons_1d, lats_1d = da.compute(bufr_obj.fh.longitude, bufr_obj.fh.latitude) + icol, irow = ad.get_array_indices_from_lonlat(lons_1d, lats_1d) + + data_2d = np.empty(ad.shape) + data_2d[:] = np.nan + data_2d[irow.compressed(), icol.compressed()] = data_1d[~irow.mask] + np.testing.assert_array_equal(z.values, data_2d) + + # Removed assert dedicated to products with seg_size=3 (covered by GII test case) + + def test_data_with_rect_lon(self, input_file): + """Test data loaded with an area definition and a rectification longitude.""" + test_data = TEST_DATA[input_file] + if test_data["seg_size"] is None: + # Skip this test + return + + bufr_obj = L2BufrData(input_file, test_data, with_adef=True) + np.testing.assert_equal(bufr_obj.fh.ssp_lon, + int(test_data["RectificationLongitude"][1:]) / 10) + _ = bufr_obj.get_data("latitude", "#1#latitude", coordinates=False) + _ = bufr_obj.get_data("longitude", "#1#longitude", coordinates=False) + _ = bufr_obj.get_data(dataset_name="TestData", key=test_data["key"], coordinates=True) + # We need to lead the data in order to create the AreaDefinition + + ad = bufr_obj.fh.get_area_def(None) + assert ad == test_data["area"] + + def test_resolution(self, input_file): + """Test data loaded with the correct resolution attribute .""" + test_data = TEST_DATA[input_file] + bufr_obj = L2BufrData(input_file, test_data, with_adef=True) + _ = bufr_obj.get_data("latitude", "#1#latitude", coordinates=False) + _ = bufr_obj.get_data("longitude", "#1#longitude", coordinates=False) + + z = bufr_obj.get_data(dataset_name="TestData", key=test_data["key"], coordinates=True) + + assert z.attrs["resolution"] == bufr_obj.resolution + + def test_amv_with_area_def(self, input_file): + """Test that AMV data can not be loaded with an area definition. + + The way to test this is to try load a variable with with_adef=True. The reader shall ignore this flag + and return a 1D array, not a 2D. + """ + test_data = TEST_DATA[input_file] + if test_data["file_type"] not in ["seviri_l2_bufr_amv", "fci_l2_bufr_amv"]: + return # Skip this test for non AMV datasets + + bufr_obj = L2BufrData(input_file, test_data, with_adef=True) + _ = bufr_obj.get_data("latitude", "#1#latitude", coordinates=False) + _ = bufr_obj.get_data("longitude", "#1#longitude", coordinates=False) + z = bufr_obj.get_data(dataset_name="TestData", key=test_data["key"], coordinates=True) + + assert len(z.dims) == 1 diff --git a/satpy/tests/reader_tests/test_seviri_l2_bufr.py b/satpy/tests/reader_tests/test_seviri_l2_bufr.py deleted file mode 100644 index 5696cbbef0..0000000000 --- a/satpy/tests/reader_tests/test_seviri_l2_bufr.py +++ /dev/null @@ -1,281 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (c) 2017-2019 Satpy developers -# -# This file is part of satpy. -# -# satpy is free software: you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation, either version 3 of the License, or (at your option) any later -# version. -# -# satpy is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along with -# satpy. If not, see . -"""Unittesting the SEVIRI L2 BUFR reader.""" - -import datetime as dt -import sys -import unittest -from unittest import mock - -import dask.array as da -import numpy as np -import pytest -from pyresample import geometry - -from satpy.tests.utils import RANDOM_GEN, make_dataid - -FILETYPE_INFO = {"file_type": "seviri_l2_bufr_asr"} - -FILENAME_INFO = {"start_time": "20191112000000", - "spacecraft": "MSG2"} -FILENAME_INFO2 = {"start_time": "20191112000000", - "spacecraft": "MSG2", - "server": "TESTSERVER"} -MPEF_PRODUCT_HEADER = { - "NominalTime": dt.datetime(2019, 11, 6, 18, 0), - "SpacecraftName": "09", - "RectificationLongitude": "E0455" -} - -DATASET_INFO = { - "name": "testdata", - "key": "#1#brightnessTemperature", - "coordinates": ("longitude", "latitude"), - "fill_value": 0 -} - -DATASET_INFO_LAT = { - "name": "latitude", - "key": "#1#latitude", - "fill_value": -1.e+100 -} - -DATASET_INFO_LON = { - "name": "longitude", - "key": "#1#longitude", - "fill_value": -1.e+100 -} - - -DATASET_ATTRS = { - "platform_name": "MET09", - "ssp_lon": 45.5, - "seg_size": 16 -} - -AREA_DEF = geometry.AreaDefinition( - "msg_seviri_iodc_48km", - "MSG SEVIRI Indian Ocean Data Coverage service area definition with 48 km resolution", - "", - {"a": 6378169., "b": 6356583.8, "lon_0": DATASET_ATTRS["ssp_lon"], - "h": 35785831., "proj": "geos", "units": "m"}, - 232, - 232, - (-5570248.6867, -5567248.2834, 5567248.2834, 5570248.6867) -) - -AREA_DEF_FES = geometry.AreaDefinition( - "msg_seviri_res_48km", - "MSG SEVIRI Full Earth Scanning service area definition with 48 km resolution", - "", - {"a": 6378169., "b": 6356583.8, "lon_0": 0.0, - "h": 35785831., "proj": "geos", "units": "m"}, - 232, - 232, - (-5570248.6867, -5567248.2834, 5567248.2834, 5570248.6867) -) - -AREA_DEF_EXT = geometry.AreaDefinition( - "msg_seviri_iodc_9km_ext", - "MSG SEVIRI Indian Ocean Data Coverage service area definition with 9 km resolution " - "(extended outside original 3km grid)", - "", - {"a": 6378169., "b": 6356583.8, "lon_0": DATASET_ATTRS["ssp_lon"], - "h": 35785831., "proj": "geos", "units": "m"}, - 1238, - 1238, - (-5571748.8883, -5571748.8882, 5571748.8882, 5571748.8883) -) - -TEST_FILES = [ - "ASRBUFRProd_20191106130000Z_00_OMPEFS02_MET09_FES_E0000", - "MSG2-SEVI-MSGASRE-0101-0101-20191106130000.000000000Z-20191106131702-1362128.bfr", - "MSG2-SEVI-MSGASRE-0101-0101-20191106101500.000000000Z-20191106103218-1362148" -] - -# Test data -DATA = RANDOM_GEN.uniform(low=250, high=350, size=(128,)) -LAT = RANDOM_GEN.uniform(low=-80, high=80, size=(128,)) -LON = RANDOM_GEN.uniform(low=-38.5, high=121.5, size=(128,)) - - -class SeviriL2BufrData: - """Mock SEVIRI L2 BUFR data.""" - - @unittest.skipIf(sys.platform.startswith("win"), "'eccodes' not supported on Windows") - def __init__(self, filename, with_adef=False, rect_lon="default"): - """Initialize by mocking test data for testing the SEVIRI L2 BUFR reader.""" - import eccodes as ec - - from satpy.readers.seviri_l2_bufr import SeviriL2BufrFileHandler - self.buf1 = ec.codes_bufr_new_from_samples("BUFR4_local_satellite") - ec.codes_set(self.buf1, "unpack", 1) - # write the bufr test data twice as we want to read in and then concatenate the data in the reader - # 55 id corresponds to METEOSAT 8` - ec.codes_set(self.buf1, "satelliteIdentifier", 56) - ec.codes_set_array(self.buf1, "#1#latitude", LAT) - ec.codes_set_array(self.buf1, "#1#latitude", LAT) - ec.codes_set_array(self.buf1, "#1#longitude", LON) - ec.codes_set_array(self.buf1, "#1#longitude", LON) - ec.codes_set_array(self.buf1, "#1#brightnessTemperature", DATA) - ec.codes_set_array(self.buf1, "#1#brightnessTemperature", DATA) - - self.m = mock.mock_open() - # only our offline product contain MPEF product headers so we get the metadata from there - if ("BUFRProd" in filename): - with mock.patch("satpy.readers.seviri_l2_bufr.np.fromfile") as fromfile: - fromfile.return_value = MPEF_PRODUCT_HEADER - with mock.patch("satpy.readers.seviri_l2_bufr.recarray2dict") as recarray2dict: - recarray2dict.side_effect = (lambda x: x) - self.fh = SeviriL2BufrFileHandler(filename, FILENAME_INFO2, FILETYPE_INFO, - with_area_definition=with_adef, rectification_longitude=rect_lon) - self.fh.mpef_header = MPEF_PRODUCT_HEADER - - else: - # No Mpef Header so we get the metadata from the BUFR messages - with mock.patch("satpy.readers.seviri_l2_bufr.open", self.m, create=True): - with mock.patch("eccodes.codes_bufr_new_from_file", - side_effect=[self.buf1, None, self.buf1, None, self.buf1, None]) as ec1: - ec1.return_value = ec1.side_effect - with mock.patch("eccodes.codes_set") as ec2: - ec2.return_value = 1 - with mock.patch("eccodes.codes_release") as ec5: - ec5.return_value = 1 - self.fh = SeviriL2BufrFileHandler(filename, FILENAME_INFO, FILETYPE_INFO, - with_area_definition=with_adef, - rectification_longitude=rect_lon) - - def get_data(self, dataset_info): - """Read data from mock file.""" - with mock.patch("satpy.readers.seviri_l2_bufr.open", self.m, create=True): - with mock.patch("eccodes.codes_bufr_new_from_file", - side_effect=[self.buf1, self.buf1, None]) as ec1: - ec1.return_value = ec1.side_effect - with mock.patch("eccodes.codes_set") as ec2: - ec2.return_value = 1 - with mock.patch("eccodes.codes_release") as ec5: - ec5.return_value = 1 - z = self.fh.get_dataset(make_dataid(name=dataset_info["name"], resolution=48000), dataset_info) - - return z - - -@pytest.mark.parametrize("input_file", TEST_FILES) -class TestSeviriL2BufrReader: - """Test SEVIRI L2 BUFR Reader.""" - - @staticmethod - def test_lonslats(input_file): - """Test reading of longitude and latitude data with SEVIRI L2 BUFR reader.""" - bufr_obj = SeviriL2BufrData(input_file) - zlat = bufr_obj.get_data(DATASET_INFO_LAT) - zlon = bufr_obj.get_data(DATASET_INFO_LON) - np.testing.assert_array_equal(zlat.values, np.concatenate((LAT, LAT), axis=0)) - np.testing.assert_array_equal(zlon.values, np.concatenate((LON, LON), axis=0)) - - @staticmethod - def test_attributes_with_swath_definition(input_file): - """Test correctness of dataset attributes with data loaded with a SwathDefinition (default behaviour).""" - bufr_obj = SeviriL2BufrData(input_file) - z = bufr_obj.get_data(DATASET_INFO) - assert z.attrs["platform_name"] == DATASET_ATTRS["platform_name"] - assert z.attrs["ssp_lon"] == DATASET_ATTRS["ssp_lon"] - assert z.attrs["seg_size"] == DATASET_ATTRS["seg_size"] - - @staticmethod - def test_attributes_with_area_definition(input_file): - """Test correctness of dataset attributes with data loaded with a AreaDefinition.""" - bufr_obj = SeviriL2BufrData(input_file, with_adef=True) - _ = bufr_obj.get_data(DATASET_INFO_LAT) # We need to load the lat/lon data in order to - _ = bufr_obj.get_data(DATASET_INFO_LON) # populate the file handler with these data - z = bufr_obj.get_data(DATASET_INFO) - assert z.attrs["platform_name"] == DATASET_ATTRS["platform_name"] - assert z.attrs["ssp_lon"] == DATASET_ATTRS["ssp_lon"] - assert z.attrs["seg_size"] == DATASET_ATTRS["seg_size"] - - @staticmethod - def test_data_with_swath_definition(input_file): - """Test data loaded with SwathDefinition (default behaviour).""" - bufr_obj = SeviriL2BufrData(input_file) - with pytest.raises(NotImplementedError): - bufr_obj.fh.get_area_def(None) - - # concatenate original test arrays as get_dataset will have read and concatented the data - x1 = np.concatenate((DATA, DATA), axis=0) - z = bufr_obj.get_data(DATASET_INFO) - np.testing.assert_array_equal(z.values, x1) - - def test_data_with_area_definition(self, input_file): - """Test data loaded with AreaDefinition.""" - bufr_obj = SeviriL2BufrData(input_file, with_adef=True) - _ = bufr_obj.get_data(DATASET_INFO_LAT) # We need to load the lat/lon data in order to - _ = bufr_obj.get_data(DATASET_INFO_LON) # populate the file handler with these data - z = bufr_obj.get_data(DATASET_INFO) - - ad = bufr_obj.fh.get_area_def(None) - assert ad == AREA_DEF - data_1d = np.concatenate((DATA, DATA), axis=0) - - # Put BUFR data on 2D grid that the 2D array returned by get_dataset should correspond to - lons_1d, lats_1d = da.compute(bufr_obj.fh.longitude, bufr_obj.fh.latitude) - icol, irow = ad.get_array_indices_from_lonlat(lons_1d, lats_1d) - - data_2d = np.empty(ad.shape) - data_2d[:] = np.nan - data_2d[irow.compressed(), icol.compressed()] = data_1d[~irow.mask] - np.testing.assert_array_equal(z.values, data_2d) - - # Test that the correct AreaDefinition is identified for products with 3 pixel segements - bufr_obj.fh.seg_size = 3 - ad_ext = bufr_obj.fh._construct_area_def(make_dataid(name="dummmy", resolution=9000)) - assert ad_ext == AREA_DEF_EXT - - def test_data_with_rect_lon(self, input_file): - """Test data loaded with AreaDefinition and user defined rectification longitude.""" - bufr_obj = SeviriL2BufrData(input_file, with_adef=True, rect_lon=0.0) - np.testing.assert_equal(bufr_obj.fh.ssp_lon, 0.0) - _ = bufr_obj.get_data(DATASET_INFO_LAT) # We need to load the lat/lon data in order to - _ = bufr_obj.get_data(DATASET_INFO_LON) # populate the file handler with these data - _ = bufr_obj.get_data(DATASET_INFO) # We need to lead the data in order to create the AreaDefinition - - ad = bufr_obj.fh.get_area_def(None) - assert ad == AREA_DEF_FES - - -class SeviriL2AMVBufrData: - """Mock SEVIRI L2 AMV BUFR data.""" - - @unittest.skipIf(sys.platform.startswith("win"), "'eccodes' not supported on Windows") - def __init__(self, filename): - """Initialize by mocking test data for testing the SEVIRI L2 BUFR reader.""" - from satpy.readers.seviri_l2_bufr import SeviriL2BufrFileHandler - - with mock.patch("satpy.readers.seviri_l2_bufr.np.fromfile"): - self.fh = SeviriL2BufrFileHandler(filename, FILENAME_INFO2, - filetype_info={"file_type": "seviri_l2_bufr_amv"}, - with_area_definition=True) - - -class TestSeviriL2AMVBufrReader: - """Test SEVIRI L2 BUFR Reader for AMV data.""" - - @staticmethod - def test_amv_with_area_def(): - """Test that AMV data can not be loaded with an area definition.""" - bufr_obj = SeviriL2AMVBufrData("AMVBUFRProd_20201110124500Z_00_OMPEFS04_MET11_FES_E0000") - assert bufr_obj.fh.with_adef is False