Part 1: Integrating Parkinson’s disease cohorts#

In this notebook we demo the utility of mgnipy in curating cross-study datasets from MGnify for secondary analysis.

Specifically, we integrate the gut microbiome profiles of multiple Parkinson’s disease vs. healthy control cohorts from various MGnify studies, relying on the sample metadata available on MGnify , ENA or BioSamples for the disease status label.

The mgnipy curated abundance dataset with metadata is then further preprocessed in Part 2.


# uncomment if colab
# !pip install mgnipy

Searching for studies using MGnifier#

To start we configure our MGnipy client and access the MGnify API Studies resource.

We will filter our query to studies of the gut microbiome that mention “parkinson”s disease.

We can preview the resulting query urls via .explain()

from mgnipy import MGnipy

# Initialize MGnipy with a cache directory
MG = MGnipy(cache_dir="downloads")

# Search for studies related to Parkinson's disease in the human gut microbiome
pd_studies = MG.studies(
    search="parkinson",
    biome_lineage="root:Host-associated:Human:Digestive system:Large intestine:Fecal",
)

# Show all of the request urls for the search i.e., the query set
pd_studies.explain()
https://www.ebi.ac.uk/metagenomics/api/v2/studies?biome_lineage=root%3AHost-associated%3AHuman%3ADigestive+system%3ALarge+intestine%3AFecal&search=parkinson&page=1

looks good. we can proceed with actually executing the list query/queries via .get(). To enrich our list of studies with metadata details we can do this in bulk using .enrich_details() or asynchronously via .aenrich_details()

# as http client manager
async with MG:
    # populate study list
    await pd_studies.aget()
    # enrich study list with metadta
    await pd_studies.aenrich_details()

# can view as pandas or even save to file if you prefer
study_meta = pd_studies.metadata
# taking a look
study_meta.to_pandas(expand_nested_dicts=True)

Hide code cell output

accession ena_accessions title updated_at downloads first_accession metadata__study_name metadata__center_name metadata__study_title metadata__study_accession metadata__study_description metadata__secondary_study_accession biome__biome_name biome__lineage
0 MGYS00005601 [ERP113090, PRJEB30615] Identification of Intestinal Bacterial Taxa wi... 2026-05-28T15:47:01.054000+00:00 [{'file_type': 'tsv', 'download_type': 'Taxono... ERP113090 NaN NaN NaN NaN NaN NaN Fecal root:Host-associated:Human:Digestive system:La...
1 MGYS00006759 [ERP146353, PRJEB61255] EMG produced TPA metagenomics assembly of PRJN... 2026-05-28T15:47:02.660000+00:00 [{'file_type': 'tsv', 'download_type': 'Taxono... ERP146353 NaN NaN NaN NaN NaN NaN Fecal root:Host-associated:Human:Digestive system:La...
2 MGYS00006121 [ERP142200, PRJEB57228] Dietary intervention of people with Parkinson'... 2026-05-28T15:47:01.432000+00:00 [{'file_type': 'tsv', 'download_type': 'Taxono... ERP142200 NaN NaN NaN NaN NaN NaN Fecal root:Host-associated:Human:Digestive system:La...
3 MGYS00005755 [PRJNA510730, SRP173877] Microbiota composition of Parkinson's disease ... 2026-05-06T11:35:50.490000+00:00 [{'file_type': 'tsv', 'download_type': 'Taxono... SRP173877 NaN NaN NaN NaN NaN NaN Fecal root:Host-associated:Human:Digestive system:La...
4 MGYS00006760 [ERP148661, PRJEB63522] EMG produced TPA metagenomics assembly of PRJN... 2026-05-28T15:47:02.672000+00:00 [{'file_type': 'tsv', 'download_type': 'Taxono... ERP148661 NaN NaN NaN NaN NaN NaN Fecal root:Host-associated:Human:Digestive system:La...
5 MGYS00001650 [ERP004264, PRJEB4927] Alterations of the Fecal Microbiome in Parkins... 2026-05-28T15:47:02.598000+00:00 [{'file_type': 'tsv', 'download_type': 'Taxono... ERP004264 Fecal Microbiome in Parkinson's Disease Institute of Biotechnology;University of Helsi... Alterations of the Fecal Microbiome in Parkins... PRJEB4927 In the course of Parkinson’s disease (PD), the... ERP004264 Fecal root:Host-associated:Human:Digestive system:La...
6 MGYS00005129 [ERP109659, PRJEB27564] Gut microbiota in Parkinson's disease: tempora... 2026-05-06T12:25:31.349000+00:00 [{'file_type': 'tsv', 'download_type': 'Taxono... ERP109659 Parkinson's disease gut microbiota follow-up Institute of Biotechnology;University of Helsi... Gut microbiota in Parkinson's disease: tempora... PRJEB27564 Aiming to explore the temporal stability of gu... ERP109659 Fecal root:Host-associated:Human:Digestive system:La...
7 MGYS00005130 [ERP112853, PRJEB30401] Gut Microbiome Alterations Drive Distinct Meta... 2026-05-06T10:02:48.163000+00:00 [{'file_type': 'tsv', 'download_type': 'Taxono... ERP112853 Gut Microbiome and Parkinson's Disease University of Cagliari Gut Microbiome Alterations Drive Distinct Meta... PRJEB30401 Parkinson's disease is a neurodegenerative dis... ERP112853 Fecal root:Host-associated:Human:Digestive system:La...

Now that we found some studies that match our sesarch criteria, we can take a look at their datasets.


Using MGazine to access the study datasets#

we can access the mgazine of datasets (kinda like a list of available datasets) via .datasets attribute. The study details we retrieved above will also be passed on to the mgazine

# access mgazine
MZ = pd_studies.datasets

# take a look
print(MZ)

Hide code cell output

MGazine containing:
- MGnify pipeline versions: ['v3', 'v4_1', 'v5', 'v6']
- Number of downloads: 72
- Short descriptions: ['Complete GO annotation',
 'DwC-Ready summary of 16S-V3-V4 ASV taxonomies using -PR2 as ref DB',
 'DwC-Ready summary of 16S-V3-V4 ASV taxonomies using -SILVA as ref DB',
 'DwC-Ready summary of closed-ref taxonomies using ITSoneDB as ref DB',
 'DwC-Ready summary of closed-ref taxonomies using PR2 as ref DB',
 'DwC-Ready summary of closed-ref taxonomies using SILVA-LSU as ref DB',
 'DwC-Ready summary of closed-ref taxonomies using SILVA-SSU as ref DB',
 'GO slim annotation',
 'InterPro matches',
 'Phylum level taxonomies',
 'Phylum level taxonomies LSU',
 'Phylum level taxonomies SSU',
 'Summary of DADA2-PR2 taxonomies',
 'Summary of DADA2-SILVA taxonomies',
 'Summary of ITSoneDB taxonomies',
 'Summary of PR2 taxonomies',
 'Summary of SILVA-LSU taxonomies',
 'Summary of SILVA-SSU taxonomies',
 'Taxonomic assignments',
 'Taxonomic assignments LSU',
 'Taxonomic assignments SSU',
 'Taxonomic diversity metrics']
- Nonempty metadata sets: .mgnify_studies

Notice in “Nonempty metadata sets” we can see that the study details we collected above are preserved in the mgazine.

The mgnify_studies attribute is a MGnifyMetadata object so contains all the same methods for viewing e.g.:

  • MZ_SSU.mgnify_studies.to_pandas(expand_nested_dicts=True)

  • ... .to_list()

  • ... .to_polars()

  • ... .records()

  • etc.

Later on in Using MGnetizer to colllect more metadata we will assign additional sets of metadata to .mgnify_runs and .biosamples_metadata which will also convert the lists of records into a MGnifyMetadata object

Filtering the dataset list#

We can filter by the pipeline version and short descriptions of the datasets.

For the ABaCo demo we will use the taxonomic analyses and we will use v4 onwards due to differences in pipeline versions and specifically SILVA databases that were used for the taxonomic analysis

# we can filter by passing as index
V3 = MZ["Taxonomic assignments"]
V4_5 = MZ["Taxonomic assignments SSU"]
V6 = MZ["Summary of SILVA-SSU taxonomies"]

print(V3, V4_5, V6)

Hide code cell output

MGazine containing:
- MGnify pipeline versions: ['v3']
- Number of downloads: 1
- Short descriptions: ['Taxonomic assignments']
- Nonempty metadata sets: .mgnify_studies
 MGazine containing:
- MGnify pipeline versions: ['v4_1', 'v5']
- Number of downloads: 6
- Short descriptions: ['Taxonomic assignments SSU']
- Nonempty metadata sets: .mgnify_studies
 MGazine containing:
- MGnify pipeline versions: ['v6']
- Number of downloads: 3
- Short descriptions: ['Summary of SILVA-SSU taxonomies']
- Nonempty metadata sets: .mgnify_studies

Combining dataset lists#

# can add magazines
MZ_SSU = V3 + V4_5 + V6

# keeping latest pipeline version if multiple output files 
dedupe_downloads: list[dict] = (
    MZ_SSU.downloads_df()
    .sort_values(by='pipeline_version', ascending=False)
    .drop_duplicates(subset='accession', keep='first')
).to_dict(orient='records')

MZ_SSU.downloads = dedupe_downloads
# print still works
print(MZ_SSU)

Hide code cell output

MGazine containing:
- MGnify pipeline versions: ['v3', 'v5', 'v6']
- Number of downloads: 8
- Short descriptions: ['Summary of SILVA-SSU taxonomies',
 'Taxonomic assignments',
 'Taxonomic assignments SSU']
- Nonempty metadata sets: .mgnify_studies

Now that we have filtered our list of datasets a bit, let’s actually get and merge the taxonomic datasets.


(Lazy)loading into one taxonomic dataset#

Currently availble in mgnipy are special MGazines for handling taxonomic assignment datasets in the classic taxa x sample/run format TaxaMGazine or in Darwin core-ready format DWCTaxaMGazine

we can also access these from an existing MGazine instance via .taxonomic or .taxonomic_dwc_ready

taxo = MZ_SSU.taxonomic

Hide code cell output

TaxaMGazine containing:
- MGnify pipeline versions: ['v3', 'v5', 'v6']
- Number of downloads: 8
- Short descriptions: ['Summary of SILVA-SSU taxonomies',
 'Taxonomic assignments',
 'Taxonomic assignments SSU']
- Nonempty metadata sets: .mgnify_studies
-----------------------
Next steps: Use `.load()` to initialize.

now load where the datasets will be merged as polars.LazyFrame

# lazyload the mgnify taxanomic assignments datasets
taxo.load()

# calling to_pandas or to_polars will collect the data and return a dataframe
taxo.to_pandas().head()

Hide code cell output

taxonomy SRR11321049 SRR11321050 SRR11321051 SRR11321052 SRR11321053 SRR11321054 SRR11321055 SRR11321056 SRR11321057 ... ERR365973 ERR365974 ERR365975 ERR365976 ERR365977 ERR365978 ERR365979 ERR365980 ERR365981 ERR365982
0 sk__Archaea 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 sk__Archaea;k__;p__Candidatus_Thermoplasmatota... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 sk__Archaea;k__;p__Candidatus_Thermoplasmatota... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 sk__Archaea;k__;p__Candidatus_Thermoplasmatota... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 sk__Archaea;k__;p__Candidatus_Thermoplasmatota... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

5 rows × 1977 columns

additionally there is a method .taxonomic_metadata() that parses “taxonomy” into the taxonomic ranks, returning as pandas or polars dataframe which is configured via arg df_engine=. The default is pandas.

also any run and sample metadata relevant to the observations (i.e., by run accessions) can be merged and viewed using .obs_metadata() again as polars or pandas dataframes. As we know metadata() for the observations in the taxonomic mgazine is not available:

# see first 5 sample's metadata
display(taxo.obs_metadata().head())

# recall the "Nonempty metadata set:"
print(taxo)

Hide code cell output

_mgnipy_runs_accs
ERR2730148
ERR2730149
ERR2730150
ERR2730151
ERR2730152
TaxaMGazine containing:
- MGnify pipeline versions: ['v3', 'v5', 'v6']
- Number of downloads: 8
- Short descriptions: ['Summary of SILVA-SSU taxonomies',
 'Taxonomic assignments',
 'Taxonomic assignments SSU']
- Nonempty metadata sets: .mgnify_studies

if we recall from earlier and again in the print statement, we only had .mgnify_studies enriched.

We still need to enrich with run and/or sample metadata, which we will do next :)


Using MGnetizer to collect more metadata#

MGnetizer is designed to retrieve the rich metadata from MGnify for a given list of MGnify accessions/ids.

First we get the ids to pass on

# separate run and assembly ids
runs_ids: list[str] = [x for x in taxo.runs_accessions if not x.startswith('ERZ')]
assembly_ids: list[str] = [x for x in taxo.runs_accessions if x.startswith('ERZ')]
print(f"Runs: {len(runs_ids)}")
print(f"Assemblies: {len(assembly_ids)}")
Runs: 1024
Assemblies: 952

Now we will instantiate the MGnetizers and pass the accessions/ids.

# initialize mgnetizer for runs and assemblies
mnet_run = MG.mgnetizer(resource="run", all_ids=runs_ids)
mnet_acc = MG.mgnetizer(resource="assembly", all_ids=assembly_ids)

# now making the API calls with context manager
async with MG:
    await mnet_run.aenrich(limit=None)
    await mnet_acc.aenrich(limit=None)

.metadata attribute of MGnetizer returns a MGnifyMetadata object just like with the MGnifiers. the MGnifyMetadata’s can be combined:

# we can combine the metadata from both runs and assemblies into one MGnifyMetadata
run_metadata = mnet_run.metadata + mnet_acc.metadata

if wanting to do some cleaning, do so (which below I do as a pandas df) and then convert back to list of dicts for the MGazine .mgnify_run property.

Hide code cell source

# cleaning up metadata
df_run = run_metadata.to_pandas()
# fill in missing study_accession
df_run["study_accession"] = df_run["study_accession"].fillna(
    df_run["assembly_study_accession"]
)
# keep pipeline_version
df_run = df_run.merge(
    (
        taxo.downloads_df()[['accession', 'pipeline_version']]
        .rename(columns={"accession": "study_accession_temp"})
    ),
    how='left',
    left_on='study_accession',
    right_on='study_accession_temp'
)
# drop assembly_study_accession column and any columns that are all NaN
df_run = df_run.drop(columns=["assembly_study_accession", "study_accession_temp"])
df_run = df_run.dropna(axis=1, how="all")

Now can pass tidied metadata back to our MGazine of taxonomic data:

# now back to TaxaMGazine instance as list of records
taxo.mgnify_runs = df_run.to_dict(orient="records")

# and now
print(taxo)

# also the metadata is updated
taxo.obs_metadata().info()

Hide code cell output

TaxaMGazine containing:
- MGnify pipeline versions: ['v3', 'v5', 'v6']
- Number of downloads: 8
- Short descriptions: ['Summary of SILVA-SSU taxonomies',
 'Taxonomic assignments',
 'Taxonomic assignments SSU']
- Nonempty metadata sets: .mgnify_runs, .mgnify_studies
<class 'pandas.core.frame.DataFrame'>
Index: 1976 entries, ERR2730148 to SRR8352125
Data columns (total 26 columns):
 #   Column                                     Non-Null Count  Dtype  
---  ------                                     --------------  -----  
 0   experiment_type                            1024 non-null   object 
 1   instrument_model                           1024 non-null   object 
 2   instrument_platform                        1024 non-null   object 
 3   sample_accession                           1976 non-null   object 
 4   study_accession                            1976 non-null   object 
 5   updated_at                                 952 non-null    object 
 6   run_accession                              952 non-null    object 
 7   status                                     952 non-null    object 
 8   pipeline_version                           1976 non-null   object 
 9   sample__accession                          1024 non-null   object 
 10  sample__ena_accessions                     1024 non-null   object 
 11  sample__sample_title                       296 non-null    object 
 12  sample__biome                              0 non-null      float64
 13  sample__updated_at                         1024 non-null   object 
 14  study__accession                           1024 non-null   object 
 15  study__ena_accessions                      1024 non-null   object 
 16  study__title                               1024 non-null   object 
 17  study__updated_at                          1024 non-null   object 
 18  study__biome.biome_name                    1024 non-null   object 
 19  study__biome.lineage                       1024 non-null   object 
 20  study__metadata.study_name                 562 non-null    object 
 21  study__metadata.center_name                562 non-null    object 
 22  study__metadata.study_title                562 non-null    object 
 23  study__metadata.study_accession            562 non-null    object 
 24  study__metadata.study_description          562 non-null    object 
 25  study__metadata.secondary_study_accession  562 non-null    object 
dtypes: float64(1), object(25)
memory usage: 416.8+ KB

However, the available run/sample metadata is not consistent for all e.g. sample__sample_title which has lots missing. We can try to get additional sample metadata from the BioSamples database.


Collecting even more sample metadata using BioSampler#

BioSampler is designed to retrieve the rich sample metadata from BioSamples for a list of Run or Sample ENA accessions.

we again start from the mgnipy instance to automatically pass on the configuration

# getting list of sample ids to go to BioSamples
sample_ids = taxo.mgnify_runs.to_pandas()["sample_accession"].to_list()

# init biosampler
bios = MG.biosampler(sample_ids=sample_ids)

# now making the API calls with context manager
async with bios:
    await bios.aenrich(limit=None, incl_ena=False)

again we can pass this metadata as list of records to the MGazine instance to .biosamples_metadata for merging:

# assign the biosamples metadata to the taxo object
taxo.biosamples_metadata = bios.metadata.to_list(drop_duplicates=True)
# now can see the additional metadata set
print(taxo)
TaxaMGazine containing:
- MGnify pipeline versions: ['v3', 'v5', 'v6']
- Number of downloads: 8
- Short descriptions: ['Summary of SILVA-SSU taxonomies',
 'Taxonomic assignments',
 'Taxonomic assignments SSU']
- Nonempty metadata sets: .mgnify_runs, .mgnify_studies, .biosamples_metadata

and now if we were to look at the observations metadata .obs_metadata() there is even more info.


Finding disease label in sample (obs) metadata#

inspecting the metadata we found disease status distrbuted between the following columns, which we normalise into a new label column has_parkinsons_disease with Y and N

samples for which disease status could not be identified from the metadata are then excluded.

Hide code cell source

disease_status_columns = {
    "host_phenotype": {
        "Y": ["Parkinson's Disease"], 
        "N": ["Healthy Control"]
    },
    "host disease status": {
        "Y": ["Parkinson's disease", "Parkinson's Disease [DOID:14330]"],
        "N": ["healthy control", "Healthy [NCIT:C115935]"],
    },
    "parkinson": {
        "Y": ["yes"], 
        "N": ["no"]
    },
    "Case_status": {
        "Y": ["PD"], 
        "N": ["Control"]
    },
    "disease status": {
        "Y": ["Parkinson's disease"], 
        "N": ["Not"]
    },#MGYS00001650
}

# copy the metadata to a new dataframe to work with
df_obs = taxo.obs_metadata().copy()
#for MGYS00001650
df_obs.loc[
    (
        (df_obs['study_accession']== 'MGYS00001650') & 
        (df_obs['disease status'].isna())
    ), 
    'disease status'
] = "Not"

# filter out samples with no disease status metadata
df_obs_filt = df_obs[df_obs[disease_status_columns.keys()].notna().any(axis=1)].copy()
print(f"Filtered down to {len(df_obs_filt)} samples with disease status metadata.")

# create a new column to indicate if the sample has Parkinson's disease or not
df_obs_filt["has_parkinsons_disease"] = None
for col in disease_status_columns:
    df_obs_filt[col] = df_obs_filt[col].map(
        lambda x: (
            "Y"
            if x in disease_status_columns[col]["Y"]
            else ("N" if x in disease_status_columns[col]["N"] else None)
        )
    )

# new col
df_obs_filt["has_parkinsons_disease"] = df_obs_filt.loc[
    :, disease_status_columns.keys()
].apply(
    lambda x: "Y" if "Y" in x.values else ("N" if "N" in x.values else None), axis=1
)
print(
    f"PD samples: {len(df_obs_filt[df_obs_filt['has_parkinsons_disease'] == 'Y'])}, Non-PD samples: {len(df_obs_filt[df_obs_filt['has_parkinsons_disease'] == 'N'])}"
)

# list of studies
filt_studies = df_obs_filt["study_accession"].unique()
print(f"Studies: {filt_studies}")
Filtered down to 1606 samples with disease status metadata.
PD samples: 975, Non-PD samples: 631
Studies: ['MGYS00005129' 'MGYS00005601' 'MGYS00001650' 'MGYS00006121'
 'MGYS00006759' 'MGYS00005755']

We will only include the studies with samples with disease status metadata and will move on with this demonstration.

Also using .obs we can assign our cleaned metadata set which will be given priority over the other sets:

# filter datasets in mgazine to the filtered studies
taxo.downloads = [x for x in taxo.downloads if x['accession'] in filt_studies]
# also add on the observation metadata that we had prepared just before
taxo.obs = df_obs_filt.reset_index().to_dict(orient="records")
print(taxo)
TaxaMGazine containing:
- MGnify pipeline versions: ['v3', 'v5', 'v6']
- Number of downloads: 6
- Short descriptions: ['Summary of SILVA-SSU taxonomies',
 'Taxonomic assignments',
 'Taxonomic assignments SSU']
- Nonempty metadata sets: .mgnify_runs, .mgnify_studies, .biosamples_metadata, .obs

then the TaxaMGazine can handle the rest and we can export to_anndata() if we want

ad_tax = taxo.to_anndata()
ad_tax
AnnData object with n_obs × n_vars = 1606 × 3247
    obs: 'experiment_type', 'instrument_model', 'instrument_platform', 'sample_accession', 'study_accession', 'updated_at', 'run_accession', 'status', 'pipeline_version', 'sample__accession', 'sample__ena_accessions', 'sample__sample_title', 'sample__biome', 'sample__updated_at', 'study__accession', 'study__ena_accessions', 'study__title', 'study__updated_at', 'study__biome.biome_name', 'study__biome.lineage', 'study__metadata.study_name', 'study__metadata.center_name', 'study__metadata.study_title', 'study__metadata.study_accession', 'study__metadata.study_description', 'study__metadata.secondary_study_accession', 'GivenID', 'RunID', 'SRA accession', 'name', 'taxid', 'ENA first public', 'ENA-CHECKLIST', 'External Id', 'INSDC center name', 'INSDC last update', 'INSDC status', 'Submitter Id', 'broad-scale environmental context', 'collection date', 'description', 'environmental medium', 'geographic location (country and/or sea)', 'geographic location (latitude)', 'geographic location (longitude)', 'host age', 'host diet', 'host disease status', 'host family relationship', 'host sex', 'host subject id', 'local environmental context', 'organism', 'project name', 'scientific_name', 'sequencing method', 'title', 'ENA-FIRST-PUBLIC', 'ENA-LAST-UPDATE', 'INSDC first public', 'age', 'body product', 'disease status', 'environment (biome)', 'environment (feature)', 'environment (material)', 'geographic location (countryand/orsea,region)', 'human gut environmental package', 'investigation type', 'medical history performed', 'miscellaneous parameter', 'multiplex identifiers', 'pcr primers', 'sex', 'target gene', 'target subfragment', 'host body product', 'parkinson', 'timepoint', 'gastrointestinal tract disorder', 'sample collection device or method', 'sample storage duration', 'sample storage temperature', 'INSDC secondary accession', 'NCBI submission model', 'NCBI submission package', 'env_broad_scale', 'env_local_scale', 'env_medium', 'geo loc name', 'host', 'host_phenotype', 'isolate', 'status__biosamples_metadata', 'isolation source', 'lat lon', 'collection_date', 'descrip', 'geo_loc_name', 'isolation_source', 'lat_lon', 'Age_at_collection', 'Anti_inflammatory_drugs', 'Antibiotics_current', 'Antibiotics_past_3_months', 'Antihistamines', 'Asthma_or_COPD_med', 'BMI', 'BioSampleModel', 'Birth_control_or_estrogen', 'Blood_pressure_med', 'Blood_thinners', 'Bristol_stool_chart', 'Case_status', 'Celiac_disease', 'Cholesterol_med', 'Co_Q_10', 'Colitis', 'Constipation', 'Crohns_disease', 'Day_of_stool_collection_abdominal_pain', 'Day_of_stool_collection_bloating', 'Day_of_stool_collection_constipation', 'Day_of_stool_collection_diarrhea', 'Day_of_stool_collection_digestion_issue', 'Day_of_stool_collection_excess_gas', 'Depression_anxiety_mood_med', 'Diabetes_med', 'Diarrhea', 'Do_you_drink_alcohol', 'Do_you_drink_caffeinated_beverages', 'Do_you_smoke', 'GI_cancer_past_3_months', 'Gained_10lbs_in_last_year', 'Hispanic_or_Latino', 'How_often_do_you_eat_FRUITS_or_VEGETABLES', 'How_often_do_you_eat_GRAINS', 'How_often_do_you_eat_NUTS', 'How_often_do_you_eat_POULTRY_BEEF_PORK_SEAFOOD_EGGS', 'How_often_do_you_eat_YOGURT', 'IBD', 'IBS', 'INSDC center alias', 'Indigestion_drugs', 'Intestinal_disease', 'Jewish_ancestry', 'Laxatives', 'Loss_10lbs_in_last_year', 'Pain_med', 'Probiotic', 'Race', 'Radiation_Chemo', 'SIBO', 'Sex', 'Sleep_aid', 'Thyroid_med', 'Ulcer_past_3_months', 'broker name', 'collection_method', 'has_parkinsons_disease'
    var: 'Superkingdom', 'Kingdom', 'Phylum', 'Class', 'Order', 'Family', 'Genus', 'Species'

Using MGni.py we could find Parkinson’s disease cohorts and integrate their abundance tables along with sample metadata from MGnify and BioSamples.

In Part 2 we further pre-process the data including cleaning and normalising the taxonomic matrix, followed by ABaCo for batch correction between the studies.

# exporting to h5ad file 
ad_tax.obs = ad_tax.obs.astype(str) #workaround for h5ad export issue with mixed types in obs
ad_tax.write_h5ad('pd.h5ad')