docs: def parse_niftis(layout, niftis, subj, config, **kwargs):
      """
      Loop through niftis in a BIDSLayout and generate the appropriate description
      type for each scan. Compile all of the descriptions into a list.
  
      Parameters
      ----------
      layout : :obj:`bids.layout.BIDSLayout`
          Layout object for a BIDS dataset.
      niftis : :obj:`list` or :obj:`grabbit.core.File`
          List of nifti files in layout corresponding to subject/session combo.
      subj : :obj:`str`
          Subject ID.
      config : :obj:`dict`
          Configuration info for methods generation.
      """
      kwargs = {k: v for k, v in kwargs.items() if v is not None}
  
      description_list = []
      skip_task = {}  # Only report each task once
      for nifti_struct in niftis:
          nii_file = nifti_struct.path
          metadata = layout.get_metadata(nii_file)
          if not metadata:
              LOGGER.warning('No json file found for %s', nii_file)
          else:
              import nibabel as nib
              img = nib.load(nii_file)
  
              # Assume all data were acquired the same way.
              if not description_list:
                  description_list.append(general_acquisition_info(metadata))
  
              if nifti_struct.entities['datatype'] == 'func':
                  if not skip_task.get(nifti_struct.entities['task'], False):
                      echos = layout.get_echoes(subject=subj, extensions='nii.gz',
                                                task=nifti_struct.entities['task'],
                                                **kwargs)
                      n_echos = len(echos)
                      if n_echos > 0:
                          metadata['EchoTime'] = []
                          for echo in sorted(echos):
                              echo_struct = layout.get(subject=subj, echo=echo,
                                                       extensions='nii.gz',
                                                       task=nifti_struct.entities['task'],
                                                       **kwargs)[0]
                              echo_file = echo_struct.path
                              echo_meta = layout.get_metadata(echo_file)
                              metadata['EchoTime'].append(echo_meta['EchoTime'])
  
                      n_runs = len(layout.get_runs(subject=subj,
                                                   task=nifti_struct.entities['task'],
                                                   **kwargs))
                      description_list.append(func_info(nifti_struct.entities['task'],
                                                        n_runs, metadata, img,
                                                        config))
                      skip_task[nifti_struct.entities['task']] = True
  
              elif nifti_struct.entities['datatype'] == 'anat':
                  suffix = nifti_struct.entities['suffix']
                  if suffix.endswith('w'):
                      suffix = suffix[:-1] + '-weighted'
                  description_list.append(anat_info(suffix, metadata, img,
                                                    config))
              elif nifti_struct.entities['datatype'] == 'dwi':
                  bval_file = nii_file.replace('.nii.gz', '.bval')
                  description_list.append(dwi_info(bval_file, metadata, img,
                                                   config))
              elif nifti_struct.entities['datatype'] == 'fmap':
                  description_list.append(fmap_info(metadata, img, config,
                                                    layout))
  
      return description_list