PennLINC / fw-heudiconv

Heuristic-based Data Curation on Flywheel
BSD 3-Clause "New" or "Revised" License
6 stars 11 forks source link

Attribute Error in `convert_to_bids` #70

Closed isabelannwingert closed 4 years ago

isabelannwingert commented 4 years ago

Hi @TinasheMTapera ,

I have solidified the heuristic that auto-populates keys per our goal.

It looks like there's a variable in the code convert_to_bids that doesn't recognize items within the tuple object.

Below is my output. Thanks again!

[wingerti@chead wingert_workspace]$ fw-heudiconv-curate --project BIDSTestSingleSubject --heuristic Single_subject_heuristic-test.py --subject 113385 --dry-run
/home/wingerti/opt/python-3.7.1/lib/python3.7/site-packages/fw_heudiconv/query.py:4: UserWarning: The DICOM readers are highly experimental, unstable, and only work for Siemens time-series at the moment
Please use with caution.  We would be grateful for your help in improving them
  from nibabel.nicom.dicomwrappers import wrapper_from_data
INFO: =================: fw-heudiconv curator starting up :=================

INFO: Loading heuristic file...
INFO: Querying Flywheel server...
DEBUG: Found project: BIDSTestSingleSubject (5e5fcb59782dc822c0f1ea23)
DEBUG: Found sessions:
    20100611-1424 (5e5fcb5b782dc822c0f1ea34)
INFO: Applying heuristic to 20100611-1424 (1/1)...
DEBUG: Found SeqInfos:

{'3D_PASL': [], 'AAHead_Scout': [], 'AAHead_Scout_MPR_cor': [], 'AAHead_Scout_MPR_sag': [], 'AAHead_Scout_MPR_tra': [], 'ABCD_T1w_MPR_vNav_moco': [], 'ABCD_T1w_MPR_vNav_moco_ND': [], 'ABCD_T1w_MPR_vNav_moco_ND_RMS': [], 'ABCD_T1w_MPR_vNav_moco_RMS': [], 'ABCD_T1w_MPR_vNav_passive': [], 'ABCD_T1w_MPR_vNav_passive_ND': [], 'ABCD_T1w_MPR_vNav_passive_ND_RMS': [], 'ABCD_T1w_MPR_vNav_passive_RMS': [], 'ABCD_T1w_MPR_vNav_passive_(SECTRA)': [], 'ABCD_T1w_MPR_vNav_passive_(SECTRA)_ND': [], 'ABCD_T1w_MPR_vNav_passive_(SECTRA)_ND_RMS': [], 'ABCD_T1w_MPR_vNav_passive_(SECTRA)_RMS': [], 'ABCD_T1w_MPR_vNav_setter': [], 'ABCD_T2w_SPC_vNav_setter': [], 'AX_FLAIR_3mm': [], 'Axial_DTI': [], 'Axial_DTI_ADC': [], 'Axial_DTI_A>>P': [], 'Axial_DTI_A>>P_ADC': [], 'Axial_DTI_ColFA': [], 'Axial_DTI_FA': [], 'Axial_DTI_TRACEW': [], 'Axial_FLAIR_3mm': [], 'Axial_PD-T2_TSE': [], 'Ax_rsfMRI': [], 'Ax_rsfMRI_A>>P': [], 'Ax_rsfMRI_P>>A': [], 'B0_map': [], 'BOLD_resting_2x2x2': [], 'calizer': [], 'DTI_2x32_35': [], 'DTI_2x32_36': [], 'DTI_30dir': [], 'DTI_30dir_noDiCo_vox2_1000': [], 'DTI_34dir': [], 'ep2d_bold_restingZE6min': [], 'ep2d_casl_UI_1500ms': [], 'ep2d_diff_MDDW_12': [], 'ep2d_DTI_30dir_T': [], 'ep2d_DTI_30dir_T_ADC': [], 'ep2d_DTI_30dir_T_ColFA': [], 'ep2d_DTI_30dir_T_EXP': [], 'ep2d_DTI_30dir_T_FA': [], 'ep2d_DTI_30dir_T_TRACEW': [], 'ep2d_fairest_UI_1500ms': [], 'ep2d_fairest_UI_M0': [], 'ep2d_max_pace': [], 'ep2d_max_pace_151': [], 'ep2d_max_pace_165': [], 'ep2d_max_pace_205': [], 'ep2d_max_pace_35': [], 'ep2d_max_pace_45': [], 'ep2d_se_pcasl_PHC_1500ms': [], 'fieldmap_GRE': [], 'FLAIR_sag': [], 'GRE_3D_segEPI_2.5x2.5x2.5': [], 'localizer': [], 'Localizer': [], 'long_DTI_P-A': [], 'long_rsfMRI_P-A': [], 'Mag_Images': [], 'MDDW_DTI_AXIAL_30_DIRECTION': [], 'MDDW_DTI_AXIAL_30_DIRECTION_ColFA': [], 'MDDW_DTI_AXIAL_30_DIRECTION_EXP': [], 'MDDW_DTI_AXIAL_30_DIRECTION_FA': [], 'MDDW_DTI_AXIAL_30_DIRECTION_TRACEW': [], 'mIP_Images(SW)': [], 'MoCoSeries': [], 'MPRAGE_BodyCoil_ref': [], 'MPRAGE_GRAPPA2': [], 'MPRAGE_SAG_ISO': [], 'no_AA_long_DTI_P-A': [], 'NODDI_B_2000': [], 'NODDI_B_300': [], 'NODDI_B_700': [], 'PCASL_resting_90mm': [], 'pd_tse_tra': [], 'Perfusion_Weighted': [], 'Pha_Images': [], 'Resting_bold_124': [], 'rfMRI_REST_PA': [], 'rfMRI_REST_PA_SBRef': [], 'Sagittal_MP-Rage': [], 'SpinEchoFieldMap_AP': [], 'SpinEchoFieldMap_PA': [], 'SPIRAL_V20_HCP_ASL': [], 'SPIRAL_V20_HCP_M0': [], 'SPIRAL_V20_HCP_MeanPerf': [], 'SWI_Images': [], 't1_mpr_AX_MPRAGE': [], 't1_se_sag': [], 'T2_2D_0.4x0.4x1.2mm_180flip_aa_temp': [], 'T2_2D_0.4x0.4x1.2mm_180flip_aa_temp_ND': [], 'T2_2D_0.4x0.4x1.2mm_180flip_aa_temp_repeat': [], 'T2_2D_0.4x0.4x1.2mm_180flip_aa_temp_repeat_ND': [], 'T2_2D_0.4x0.4x1.2mm_180flip_aa_temp_(SECTRA)': [], 'T2_2D_0.4x0.4x1.2mm_180flip_aa_temp_(SECTRA)_ND': [], 'T2_AXIAL_FLAIR': [], 'T2_Axial_space': [], 'T2_COR_HIGH_RES': [], 't2_nex_1': [], 'T2_sag': [], 't2_tse_obl_448_2mm': [], 't2_tse_tra': [], 't2_tse_tra8CHANNEL': [], 'T2w_SPC_vNav_passive': [], 'T2w_SPC_vNav_passive_ND': [], 'T2w_SPC_vNav_passive_(SECTRA)': [], 'T2w_SPC_vNav_passive_(SECTRA)_ND': [], 'ViSTa_3D_segEPI_2.5x2.5x2.5': []}
('sub-{subject}_ses-{session}_acq-3DxPASL_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AAHeadxScout_localizer', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AAHeadxScoutxMPRxcor_localizer', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AAHeadxScoutxMPRxsag_localizer', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AAHeadxScoutxMPRxtra_localizer', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxmoco_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxmocoxND_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxmocoxNDxRMS_T1W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxmocoxRMS_T1W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxpassive_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxpassivexND_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxpassivexNDxRMS_T1W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxpassivexRMS_T1W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxpassivex(SECTRA)_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxpassivex(SECTRA)xND_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxpassivex(SECTRA)xNDxRMS_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxpassivex(SECTRA)xRMS_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT1wxMPRxvNavxsetter_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ABCDxT2wxSPCxvNavxsetter_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AXxFLAIRx3mm_flair', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxialxDTI_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxialxDTIxADC_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxialxDTIxA>>P_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxialxDTIxA>>PxADC_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxialxDTIxColFA_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxialxDTIxFA_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxialxDTIxTRACEW_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxialxFLAIRx3mm_flair', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxialxPDxT2xTSE_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxxrsfMRI_bold', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxxrsfMRIxA>>P_bold', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-AxxrsfMRIxP>>A_bold', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-B0xmap_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-BOLDxrestingx2x2x2_bold', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-calizer_localizer', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-DTIx2x32x35_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-DTIx2x32x36_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-DTIx30dir_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-DTIx30dirxnoDiCoxvox2x1000_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-DTIx34dir_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxboldxrestingZE6min_bold', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxcaslxUIx1500ms_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxdiffxMDDWx12_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxDTIx30dirxT_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxDTIx30dirxTxADC_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxDTIx30dirxTxColFA_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxDTIx30dirxTxEXP_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxDTIx30dirxTxFA_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxDTIx30dirxTxTRACEW_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxfairestxUIx1500ms_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxfairestxUIxM0_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxmaxxpace_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxmaxxpacex151_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxmaxxpacex165_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxmaxxpacex205_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxmaxxpacex35_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxmaxxpacex45_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ep2dxsexpcaslxPHCx1500ms_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-fieldmapxGRE_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-FLAIRxsag_flair', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-GREx3DxsegEPIx2.5x2.5x2.5_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-localizer_localizer', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-Localizer_localizer', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-longxDTIxPxA_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-longxrsfMRIxPxA_bold', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-MagxImages_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-MDDWxDTIxAXIALx30xDIRECTION_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-MDDWxDTIxAXIALx30xDIRECTIONxColFA_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-MDDWxDTIxAXIALx30xDIRECTIONxEXP_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-MDDWxDTIxAXIALx30xDIRECTIONxFA_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-MDDWxDTIxAXIALx30xDIRECTIONxTRACEW_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-mIPxImages(SW)_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-MoCoSeries_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-MPRAGExBodyCoilxref_T1W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-MPRAGExGRAPPA2_T1W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-MPRAGExSAGxISO_T1W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-noxAAxlongxDTIxPxA_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-NODDIxBx2000_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-NODDIxBx300_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-NODDIxBx700_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-PCASLxrestingx90mm_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-pdxtsextra_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-PerfusionxWeighted_dwi', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-PhaxImages_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-Restingxboldx124_bold', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-rfMRIxRESTxPA_bold', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-rfMRIxRESTxPAxSBRef_bold', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-SagittalxMPxRage_T1W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-SpinEchoFieldMapxAP_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-SpinEchoFieldMapxPA_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-SPIRALxV20xHCPxASL_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-SPIRALxV20xHCPxM0_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-SPIRALxV20xHCPxMeanPerf_asl', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-SWIxImages_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-t1xmprxAXxMPRAGE_T1W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-t1xsexsag_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2x2Dx0.4x0.4x1.2mmx180flipxaaxtemp_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2x2Dx0.4x0.4x1.2mmx180flipxaaxtempxND_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2x2Dx0.4x0.4x1.2mmx180flipxaaxtempxrepeat_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2x2Dx0.4x0.4x1.2mmx180flipxaaxtempxrepeatxND_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2x2Dx0.4x0.4x1.2mmx180flipxaaxtempx(SECTRA)_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2x2Dx0.4x0.4x1.2mmx180flipxaaxtempx(SECTRA)xND_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2xAXIALxFLAIR_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2xAxialxspace_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2xCORxHIGHxRES_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-t2xnexx1_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2xsag_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-t2xtsexoblx448x2mm_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-t2xtsextra_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-t2xtsextra8CHANNEL_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2wxSPCxvNavxpassive_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2wxSPCxvNavxpassivexND_T2W', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2wxSPCxvNavxpassivex(SECTRA)_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-T2wxSPCxvNavxpassivex(SECTRA)xND_nonBids', ('nii.gz',), None)
('sub-{subject}_ses-{session}_acq-ViSTax3DxsegEPIx2.5x2.5x2.5_asl', ('nii.gz',), None)
Traceback (most recent call last):
  File "/home/wingerti/opt/python-3.7.1/bin/fw-heudiconv-curate", line 11, in <module>
    load_entry_point('fw-heudiconv==0.1.8', 'console_scripts', 'fw-heudiconv-curate')()
  File "/home/wingerti/opt/python-3.7.1/lib/python3.7/site-packages/fw_heudiconv/cli/curate.py", line 212, in main
    dry_run=args.dry_run)
  File "/home/wingerti/opt/python-3.7.1/lib/python3.7/site-packages/fw_heudiconv/cli/curate.py", line 126, in convert_to_bids
    for key, val in to_rename.items():
AttributeError: 'tuple' object has no attribute 'items'
[wingerti@chead wingert_workspace]$ 
TinasheMTapera commented 4 years ago

@isabelannwingert please paste the heuristic in as well

isabelannwingert commented 4 years ago
# NEW HEURISTIC PLANNING (NOTES)
### Pandas Dataframe import of two columns: UNIQUE Series-Description and {modality} label suffixes for BIDS filenames
### Create dictionary for modality labels
### These two objects are used to populate seq_info

# HEURISTIC_AUTOPOPULATE.py
### Isabel Ann Wingert & Tinashe M Tapera
##### isabel.wingert@pennmedicine.upenn.edu
##### Also available on the following GitHub Repositories
### 4th March 2020 v 1.0

# Importing Modalities and Packages for Use
import os # --- Working Directory Set-up
import pandas as pd # --- Pandas is a module that allows information from fw-heudiconv-tabulate to be passed

# create_key function for dictionary seq_info
def create_key(template, outtype=('nii.gz',), annotation_classes=None):
    if template is None or not template:
        raise ValueError('Template must be a valid format string')
    return template, outtype, annotation_classes

from collections.abc import Mapping
def rec_key_replace(obj):
    if isinstance(obj, Mapping):
        return {key.replace('_', 'x').replace("-", "x"): rec_key_replace(val) for key, val in obj.items()}
    return obj

os.chdir('/home/wingerti/wingert_workspace') ### Make sure Pandas DataFrame is in working folder

### Reading Unique Series Descriptions in with Pandas
df_series_desc = pd.read_excel('BIDSTestHUP3TLegacy_SeriesModalityInfo.xlsx', usecols="A")
series_desc = df_series_desc.values.tolist()
series_desc = [item for sublist in series_desc for item in sublist]

df_modality_labels = pd.read_excel('BIDSTestHUP3TLegacy_SeriesModalityInfo.xlsx', usecols="B")
modality_labels = df_modality_labels.values.tolist()
modality_labels = [item for sublist in modality_labels for item in sublist]

### Dictionary for Create Keys:
keys_series_desc = dict.fromkeys(series_desc, [])
key_modality_labels = dict.fromkeys(modality_labels, [])

### Dictionary for Modality Labels (by hand):
#df_modality_lookup =
#modality_lookup = {'T1w': 'T1w', 'T2w': 'T2w', 'FLAIR': 'FLAIR', 'bold': 'bold', 'dwi': 'dwi', 'localizer': 'localizer'}
ser_mod_pairs = dict(zip(series_desc, modality_labels))
ser_mod_pairs = rec_key_replace(ser_mod_pairs)

def infotodict(seqinfo):

    global keys_series_desc

    info = {}

    for s in seqinfo:
        protocol = s.protocol_name.lower()
        series_desc = s.series_description.lower()

        if series_desc in list(keys_series_desc.keys()):
            keys_series_desc[series_desc].append(s.series_id)

    print(keys_series_desc)

    out_string = []
    create_key_list = []
    for key, values in keys_series_desc.items():
        if key:
            key = key.replace("_", "x",).replace("-", "x")
            out_string_i = 'sub-{subject}_ses-{session}_acq-' + key
            out_string.append(out_string_i)

    for w in range(len(out_string)):
            BIDS_filename = out_string[w] + '_' + modality_labels[w]
            create_key_list.append(BIDS_filename)

    for create_key_list_i in create_key_list:
            new_key = create_key(create_key_list_i)
            print(new_key)

    return info, new_key
TinasheMTapera commented 4 years ago

You forgot to add the new_keys to info. Right now, your return statement is sending back a tuple of info and the key, but fw-heudiconv is only expecting one thing: a dictionary called info.

First, when you print(keys_series_desc) you get this:

{'3D_PASL': [], 'AAHead_Scout': [], 'AAHead_Scout_MPR_cor': [], 'AAHead_Scout_MPR_sag': [],

That's good.

Then, when you print(new_key) you get this:

('sub-{subject}_ses-{session}_acq-3DxPASL_asl', ('nii.gz',), None)

That looks good too. What's missing is to put those new_keys into info. I would recommend, in your last for loop:

    for create_key_list_i in create_key_list:
            new_key = create_key(create_key_list_i)
            info[new_key] = []                      # this creates the empty info dict

Now you have an info object that you hacked. But the list of sequences still isn't full. So you have to go through your seqinfos again and add the seqinfo to the right place:

    for s in seqinfo:                              # for each sequence, again
        protocol = s.protocol_name.lower()
        series_desc = s.series_description.lower()

        for k, v in info.items():                  # unpack the info dict that you created
            if series_desc in k[0]:                # if sequence name is in the key's string
                info[k].append(s.series_id)        # add it to info

The end of your heuristic should look something like this:


def infotodict(seqinfo):

    global keys_series_desc

    info = {}

    for s in seqinfo:
        protocol = s.protocol_name.lower()
        series_desc = s.series_description.lower()

        if series_desc in list(keys_series_desc.keys()):
            keys_series_desc[series_desc].append(s.series_id)

    print(keys_series_desc)

    out_string = []
    create_key_list = []
    for key, values in keys_series_desc.items():
        if key:
            key = key.replace("_", "x",).replace("-", "x")
            out_string_i = 'sub-{subject}_ses-{session}_acq-' + key
            out_string.append(out_string_i)

    for w in range(len(out_string)):
            BIDS_filename = out_string[w] + '_' + modality_labels[w]
            create_key_list.append(BIDS_filename)

    for create_key_list_i in create_key_list:
            new_key = create_key(create_key_list_i)
            info[new_key] = []                      # this creates the empty info dict

    for s in seqinfo:                              # for each sequence, again
        protocol = s.protocol_name.lower()
        series_desc = s.series_description.lower()

        for k, v in info.items():                  # unpack the info dict that you created
            if series_desc in k[0]:                # if sequence name is in the key's string
                info[k].append(s.series_id)        # add it to info

    return info                                    # only return info
TinasheMTapera commented 4 years ago

As always, if you're unsure, go into --dry-run mode and add as many print statements at every stage as you need

isabelannwingert commented 4 years ago

Hi @TinasheMTapera , thank you for the help, no bugs happen, I'm trying to figure out how to populate subject IDs and sessions in to the fields (everything is still being sorted into nonBids)

TinasheMTapera commented 4 years ago

@isabelannwingert in that case I'll close this issue just so we can keep track of numbers. You can re-open it if you're unsuccessful.