Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the HRPT reader to latest satpy api #1531

Merged
merged 7 commits into from
Feb 8, 2021

Conversation

mraspaud
Copy link
Member

@mraspaud mraspaud commented Feb 3, 2021

This PR adapts the HRPT reader to dask, xarray and latest pygac

@codecov
Copy link

codecov bot commented Feb 3, 2021

Codecov Report

Merging #1531 (8ca02e5) into master (e0f1fb8) will increase coverage by 0.36%.
The diff coverage is 99.53%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1531      +/-   ##
==========================================
+ Coverage   91.65%   92.02%   +0.36%     
==========================================
  Files         248      249       +1     
  Lines       36172    36309     +137     
==========================================
+ Hits        33155    33413     +258     
+ Misses       3017     2896     -121     
Flag Coverage Δ
behaviourtests 4.34% <0.00%> (-0.02%) ⬇️
unittests 92.56% <99.53%> (+0.36%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
satpy/readers/hrpt.py 98.62% <98.80%> (+92.60%) ⬆️
satpy/tests/reader_tests/test_avhrr_l0_hrpt.py 100.00% <100.00%> (ø)
satpy/tests/reader_tests/test_avhrr_l1b_gaclac.py 99.64% <100.00%> (+<0.01%) ⬆️
satpy/readers/viirs_compact.py 64.12% <0.00%> (-0.77%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e0f1fb8...7ef6de0. Read the comment docs.

@ghost
Copy link

ghost commented Feb 3, 2021

DeepCode failed to analyze this pull request

Something went wrong despite trying multiple times, sorry about that.
Please comment this pull request with "Retry DeepCode" to manually retry, or contact us so that a human can look into the issue.

Copy link

@howff howff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much for the quick PR!
But I think in hrpt.py get_dataset is treating key as a dict but it's a tuple so instead of key['name'] you need to use key.name (and same for key.calibration).

@mraspaud
Copy link
Member Author

mraspaud commented Feb 4, 2021

@howff the key is in principle an instance of a DataID. The recommended way to access its fields now is with ['name'].

@howff
Copy link

howff commented Feb 4, 2021

The tuple problem was probably me patching hrpt.py into a version of satpy older than master. But when I use this branch I can confirm that the data loads ok and the built-in composites also work, so thank you very much :)

@mraspaud
Copy link
Member Author

mraspaud commented Feb 4, 2021

You are very welcome, it was high time to update this reader! So thank you for poking us.

@mraspaud mraspaud marked this pull request as ready for review February 5, 2021 10:36
@mraspaud
Copy link
Member Author

mraspaud commented Feb 5, 2021

@howff I think I'm happy with this PR now. Any further comments?

@mraspaud mraspaud requested a review from pnuu February 5, 2021 15:15
@gerritholl
Copy link
Collaborator

I'm getting an error message with our files.

from satpy import Scene
sc = Scene(["/media/nas/x21308/scratch/20210205141010_NOAA_19.hmf"], reader="avhrr_l1b_hrpt")
sc.load(["4"])
sc.show("4")

gives:

[DEBUG: 2021-02-05 16:30:00 : satpy.readers.yaml_reader] Reading ('/home/gholl/checkouts/satpy/satpy/etc/readers/avhrr_l1b_hrpt.yaml',)
[DEBUG: 2021-02-05 16:30:00 : satpy.readers.yaml_reader] Assigning to avhrr_l1b_hrpt: ['/media/nas/x21308/scratch/20210205141010_NOAA_19.hmf']
[DEBUG: 2021-02-05 16:30:00 : satpy.composites.config_loader] Looking for composites config file avhrr-2.yaml
[DEBUG: 2021-02-05 16:30:00 : satpy.composites.config_loader] No composite config found called avhrr-2.yaml
[DEBUG: 2021-02-05 16:30:00 : satpy.composites.config_loader] Looking for composites config file avhrr-3.yaml
[DEBUG: 2021-02-05 16:30:00 : satpy.composites.config_loader] Looking for composites config file visir.yaml
[DEBUG: 2021-02-05 16:30:00 : satpy.readers.yaml_reader] No coordinates found for DataID(name='longitude', resolution=1050, modifiers=())
[WARNING: 2021-02-05 16:30:00 : satpy.readers.yaml_reader] Failed to load DataID(name='longitude', resolution=1050, modifiers=()) from <HRPTFile: '/media/nas/x21308/scratch/20210205141010_NOAA_19.hmf'>
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 687, in _load_dataset
    projectable = fh.get_dataset(dsid, ds_info)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 161, in get_dataset
    attrs['platform_name'] = self.platform_name
  File "/data/gholl/miniconda3/envs/py38b/lib/python3.8/functools.py", line 967, in __get__
    val = self.func(instance)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 156, in platform_name
    return spacecrafts[(self._data["id"]["id"][0] >> 3) & 15]
KeyError: 2
[ERROR: 2021-02-05 16:30:00 : satpy.readers.yaml_reader] Could not load dataset 'DataID(name='longitude', resolution=1050, modifiers=())': "Could not load DataID(name='longitude', resolution=1050, modifiers=()) from any provided files"
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 829, in _load_dataset_with_area
    ds = self._load_dataset_data(file_handlers, dsid, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 711, in _load_dataset_data
    proj = self._load_dataset(dsid, ds_info, file_handlers, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 696, in _load_dataset
    raise KeyError(
KeyError: "Could not load DataID(name='longitude', resolution=1050, modifiers=()) from any provided files"
[DEBUG: 2021-02-05 16:30:00 : satpy.readers.yaml_reader] No coordinates found for DataID(name='latitude', resolution=1050, modifiers=())
[WARNING: 2021-02-05 16:30:00 : satpy.readers.yaml_reader] Failed to load DataID(name='latitude', resolution=1050, modifiers=()) from <HRPTFile: '/media/nas/x21308/scratch/20210205141010_NOAA_19.hmf'>
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 687, in _load_dataset
    projectable = fh.get_dataset(dsid, ds_info)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 161, in get_dataset
    attrs['platform_name'] = self.platform_name
  File "/data/gholl/miniconda3/envs/py38b/lib/python3.8/functools.py", line 967, in __get__
    val = self.func(instance)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 156, in platform_name
    return spacecrafts[(self._data["id"]["id"][0] >> 3) & 15]
KeyError: 2
[ERROR: 2021-02-05 16:30:00 : satpy.readers.yaml_reader] Could not load dataset 'DataID(name='latitude', resolution=1050, modifiers=())': "Could not load DataID(name='latitude', resolution=1050, modifiers=()) from any provided files"
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 829, in _load_dataset_with_area
    ds = self._load_dataset_data(file_handlers, dsid, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 711, in _load_dataset_data
    proj = self._load_dataset(dsid, ds_info, file_handlers, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 696, in _load_dataset
    raise KeyError(
KeyError: "Could not load DataID(name='latitude', resolution=1050, modifiers=()) from any provided files"
[WARNING: 2021-02-05 16:30:00 : satpy.readers.yaml_reader] Failed to load coordinates for 'DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=())'
[WARNING: 2021-02-05 16:30:00 : satpy.readers.yaml_reader] Failed to load DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=()) from <HRPTFile: '/media/nas/x21308/scratch/20210205141010_NOAA_19.hmf'>
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 687, in _load_dataset
    projectable = fh.get_dataset(dsid, ds_info)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 161, in get_dataset
    attrs['platform_name'] = self.platform_name
  File "/data/gholl/miniconda3/envs/py38b/lib/python3.8/functools.py", line 967, in __get__
    val = self.func(instance)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 156, in platform_name
    return spacecrafts[(self._data["id"]["id"][0] >> 3) & 15]
KeyError: 2
[ERROR: 2021-02-05 16:30:00 : satpy.readers.yaml_reader] Could not load dataset 'DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=())': "Could not load DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=()) from any provided files"
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 829, in _load_dataset_with_area
    ds = self._load_dataset_data(file_handlers, dsid, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 711, in _load_dataset_data
    proj = self._load_dataset(dsid, ds_info, file_handlers, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 696, in _load_dataset
    raise KeyError(
KeyError: "Could not load DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=()) from any provided files"
[WARNING: 2021-02-05 16:30:00 : satpy.scene] The following datasets were not created and may require resampling to be generated: DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=())
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/dataset/data_dict.py", line 169, in __getitem__
    return super(DatasetDict, self).__getitem__(item)
KeyError: '4'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test-hrpt.py", line 5, in <module>
    sc.show("4")
  File "/home/gholl/checkouts/satpy/satpy/scene.py", line 819, in show
    img = get_enhanced_image(self[dataset_id].squeeze(), overlay=overlay)
  File "/home/gholl/checkouts/satpy/satpy/scene.py", line 644, in __getitem__
    return self._datasets[key]
  File "/home/gholl/checkouts/satpy/satpy/dataset/data_dict.py", line 171, in __getitem__
    key = self.get_key(item)
  File "/home/gholl/checkouts/satpy/satpy/dataset/data_dict.py", line 158, in get_key
    return get_key(match_key, self.keys(), num_results=num_results,
  File "/home/gholl/checkouts/satpy/satpy/dataset/data_dict.py", line 107, in get_key
    raise KeyError("No dataset matching '{}' found".format(str(key)))
KeyError: "No dataset matching 'DataQuery(name='4')' found"

@TAlonglong
Copy link
Collaborator

Do you need https://github.com/pytroll/python-geotiepoints for that?

@gerritholl
Copy link
Collaborator

Same problem after installing the latest pyorbital and pygac:

[DEBUG: 2021-02-05 16:36:41 : satpy.readers.yaml_reader] Reading ('/home/gholl/checkouts/satpy/satpy/etc/readers/avhrr_l1b_hrpt.yaml',)
[DEBUG: 2021-02-05 16:36:41 : satpy.readers.yaml_reader] Assigning to avhrr_l1b_hrpt: ['/media/nas/x21308/scratch/20210205141010_NOAA_19.hmf']
[DEBUG: 2021-02-05 16:36:41 : satpy.composites.config_loader] Looking for composites config file avhrr-3.yaml
[DEBUG: 2021-02-05 16:36:41 : satpy.composites.config_loader] Looking for composites config file visir.yaml
[DEBUG: 2021-02-05 16:36:41 : satpy.composites.config_loader] Looking for composites config file avhrr-2.yaml
[DEBUG: 2021-02-05 16:36:41 : satpy.composites.config_loader] No composite config found called avhrr-2.yaml
[DEBUG: 2021-02-05 16:36:41 : satpy.readers.yaml_reader] No coordinates found for DataID(name='longitude', resolution=1050, modifiers=())
[WARNING: 2021-02-05 16:36:41 : satpy.readers.yaml_reader] Failed to load DataID(name='longitude', resolution=1050, modifiers=()) from <HRPTFile: '/media/nas/x21308/scratch/20210205141010_NOAA_19.hmf'>
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 687, in _load_dataset
    projectable = fh.get_dataset(dsid, ds_info)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 161, in get_dataset
    attrs['platform_name'] = self.platform_name
  File "/data/gholl/miniconda3/envs/py38b/lib/python3.8/functools.py", line 967, in __get__
    val = self.func(instance)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 156, in platform_name
    return spacecrafts[(self._data["id"]["id"][0] >> 3) & 15]
KeyError: 2
[ERROR: 2021-02-05 16:36:41 : satpy.readers.yaml_reader] Could not load dataset 'DataID(name='longitude', resolution=1050, modifiers=())': "Could not load DataID(name='longitude', resolution=1050, modifiers=()) from any provided files"
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 829, in _load_dataset_with_area
    ds = self._load_dataset_data(file_handlers, dsid, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 711, in _load_dataset_data
    proj = self._load_dataset(dsid, ds_info, file_handlers, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 696, in _load_dataset
    raise KeyError(
KeyError: "Could not load DataID(name='longitude', resolution=1050, modifiers=()) from any provided files"
[DEBUG: 2021-02-05 16:36:41 : satpy.readers.yaml_reader] No coordinates found for DataID(name='latitude', resolution=1050, modifiers=())
[WARNING: 2021-02-05 16:36:41 : satpy.readers.yaml_reader] Failed to load DataID(name='latitude', resolution=1050, modifiers=()) from <HRPTFile: '/media/nas/x21308/scratch/20210205141010_NOAA_19.hmf'>
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 687, in _load_dataset
    projectable = fh.get_dataset(dsid, ds_info)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 161, in get_dataset
    attrs['platform_name'] = self.platform_name
  File "/data/gholl/miniconda3/envs/py38b/lib/python3.8/functools.py", line 967, in __get__
    val = self.func(instance)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 156, in platform_name
    return spacecrafts[(self._data["id"]["id"][0] >> 3) & 15]
KeyError: 2
[ERROR: 2021-02-05 16:36:41 : satpy.readers.yaml_reader] Could not load dataset 'DataID(name='latitude', resolution=1050, modifiers=())': "Could not load DataID(name='latitude', resolution=1050, modifiers=()) from any provided files"
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 829, in _load_dataset_with_area
    ds = self._load_dataset_data(file_handlers, dsid, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 711, in _load_dataset_data
    proj = self._load_dataset(dsid, ds_info, file_handlers, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 696, in _load_dataset
    raise KeyError(
KeyError: "Could not load DataID(name='latitude', resolution=1050, modifiers=()) from any provided files"
[WARNING: 2021-02-05 16:36:41 : satpy.readers.yaml_reader] Failed to load coordinates for 'DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=())'
[WARNING: 2021-02-05 16:36:41 : satpy.readers.yaml_reader] Failed to load DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=()) from <HRPTFile: '/media/nas/x21308/scratch/20210205141010_NOAA_19.hmf'>
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 687, in _load_dataset
    projectable = fh.get_dataset(dsid, ds_info)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 161, in get_dataset
    attrs['platform_name'] = self.platform_name
  File "/data/gholl/miniconda3/envs/py38b/lib/python3.8/functools.py", line 967, in __get__
    val = self.func(instance)
  File "/home/gholl/checkouts/satpy/satpy/readers/hrpt.py", line 156, in platform_name
    return spacecrafts[(self._data["id"]["id"][0] >> 3) & 15]
KeyError: 2
[ERROR: 2021-02-05 16:36:41 : satpy.readers.yaml_reader] Could not load dataset 'DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=())': "Could not load DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=()) from any provided files"
Traceback (most recent call last):
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 829, in _load_dataset_with_area
    ds = self._load_dataset_data(file_handlers, dsid, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 711, in _load_dataset_data
    proj = self._load_dataset(dsid, ds_info, file_handlers, **kwargs)
  File "/home/gholl/checkouts/satpy/satpy/readers/yaml_reader.py", line 696, in _load_dataset
    raise KeyError(
KeyError: "Could not load DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=()) from any provided files"
[WARNING: 2021-02-05 16:36:41 : satpy.scene] The following datasets were not created and may require resampling to be generated: DataID(name='4', wavelength=WavelengthRange(min=10.3, central=10.8, max=11.3, unit='µm'), resolution=1050, calibration=<calibration.brightness_temperature>, modifiers=())
Traceback (most recent call last):
  File "test-hrpt.py", line 7, in <module>
    ls.save_datasets(filename=str(plotdir() / "{start_time:%Y%m%d%H%M}-{platform_name:s}-{name:s}.tif"))
  File "/home/gholl/checkouts/satpy/satpy/scene.py", line 1001, in save_datasets
    raise RuntimeError("None of the requested datasets have been "
RuntimeError: None of the requested datasets have been generated or could not be loaded. Requested composite inputs may need to have matching dimensions (eg. through resampling).

from conda list:

pygac                     1.4.0                    pypi_0    pypi
pyorbital                 1.6.0+11.gf1e50fc          pypi_0    pypi
satpy                     0.25.2.dev50+g905197a3           dev_0    <develop>

@mraspaud
Copy link
Member Author

mraspaud commented Feb 5, 2021

@TAlonglong yes, and pyorbital and pygac

@mraspaud
Copy link
Member Author

mraspaud commented Feb 5, 2021

@gerritholl do you have python-geotiepoints installed?

@gerritholl
Copy link
Collaborator

It was probably a corrupted file. With other files I do get an image, but many lines are misplaced:

20210202124445_NOAA_18.hmf:

202102021244-NOAA 18-4

20210205041432_NOAA_19.hmf:

202102050414-NOAA 19-4

20210205091618_NOAA_19.hmf:

202102050916-NOAA 19-4

I don't remember having seen this before. Maybe AAPP has some error checking to remove those lines?

@mraspaud
Copy link
Member Author

mraspaud commented Feb 5, 2021

@gerritholl fun! I guess some consistancy check is in order...

@gerritholl
Copy link
Collaborator

Both 20210205091618_NOAA_19.hmf files, projected on eurol, channel 4 without any other corrections.

With the avhrr_l1b_aapp reader pre-processed by AAPP:

with-aapp

With the avhrr_l1b_hrpt reader, no processing by AAPP:

without-aapp

@howff
Copy link

howff commented Feb 5, 2021

Some misplaced scanlines is to be expected if the timestamps have been corrupted due to noisy data.
The KeyError is possibly also the same cause, if the spacecraft id in the data has been corrupted by a bit flip.
Adding a filter for this is probably something I could contribute but it's not a bug in satpy.

@mraspaud
Copy link
Member Author

mraspaud commented Feb 5, 2021

@howff, yes, corrupted timestamps are probably the issue. I was thinking of trying to fit the timestamps to a line to correct the outliers, but how would you do it?

@gerritholl
Copy link
Collaborator

I agree that it's not a bug in Satpy, rather a missing feature — but as long as the data quality reading directly is worse than when pre-processing it with AAPP, users are going to keep AAPP in their pipelines despite the additional overhead.

@gerritholl
Copy link
Collaborator

Doesn't pygac have a lot of experience in filtering the dozens of things that can go wrong with data? Could that help here? There's already a pygac dependency anyway...

@mraspaud
Copy link
Member Author

mraspaud commented Feb 5, 2021

@mraspaud
Copy link
Member Author

mraspaud commented Feb 5, 2021

ah no that won't work as HRPT doesn't have line numbers

@howff
Copy link

howff commented Feb 8, 2021

I would be happy to have this PR merged, to get the new API working, and leave the handling of dirty data to a different PR.

@mraspaud
Copy link
Member Author

mraspaud commented Feb 8, 2021

ok, great, I will merge this one then. @howff do you want to take a shot at that new PR for filter or fixing erroneous timestamps?

@mraspaud mraspaud merged commit 5200840 into pytroll:master Feb 8, 2021
@mraspaud mraspaud deleted the fix-hrpt branch February 8, 2021 09:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cannot read AVHRR in HRPT format (geoloc dtype error)
4 participants