docs: def dwi_info(bval_file, metadata, img, config):
      """
      Generate a paragraph describing DWI scan acquisition information.
  
      Parameters
      ----------
      bval_file : :obj:`str`
          File containing b-vals associated with DWI scan.
      metadata : :obj:`dict`
          Data from the json file associated with the DWI scan, in dictionary
          form.
      img : :obj:`nibabel.Nifti1Image`
          The nifti image of the DWI scan.
      config : :obj:`dict`
          A dictionary with relevant information regarding sequences, sequence
          variants, phase encoding directions, and task names.
  
      Returns
      -------
      desc : :obj:`str`
          A description of the DWI scan's acquisition information.
      """
      # Parse bval file
      with open(bval_file, 'r') as file_object:
          d = file_object.read().splitlines()
      bvals = [item for sublist in [l.split(' ') for l in d] for item in sublist]
      bvals = sorted([int(v) for v in set(bvals)])
      bvals = [str(v) for v in bvals]
      if len(bvals) == 1:
          bval_str = bvals[0]
      elif len(bvals) == 2:
          bval_str = ' and '.join(bvals)
      else:
          bval_str = ', '.join(bvals[:-1])
          bval_str += ', and {0}'.format(bvals[-1])
  
      if metadata.get('MultibandAccelerationFactor', 1) > 1:
          mb_str = '; MB factor={0}'.format(metadata['MultibandAccelerationFactor'])
      else:
          mb_str = ''
  
      if 'SliceTiming' in metadata.keys():
          so_str = ' in {0} order'.format(get_slice_info(metadata['SliceTiming']))
      else:
          so_str = ''
  
      if 'EchoTime' in metadata.keys():
          te = num_to_str(metadata['EchoTime']*1000)
      else:
          te = 'UNKNOWN'
  
      n_slices, vs_str, ms_str, fov_str = get_sizestr(img)
      n_vecs = img.shape[3]
      seqs, variants = get_seqstr(config, metadata)
  
      desc = '''
             One run of {variants} {seqs} diffusion-weighted (dMRI) data were collected
             ({n_slices} slices{so_str}; repetition time, TR={tr}ms;
             echo time, TE={te}ms; flip angle, FA={fa}<deg>;
             field of view, FOV={fov}mm; matrix size={ms}; voxel size={vs}mm;
             b-values of {bval_str} acquired;
             {n_vecs} diffusion directions{mb_str}).
             '''.format(variants=variants,
                        seqs=seqs,
                        n_slices=n_slices,
                        so_str=so_str,
                        tr=num_to_str(metadata['RepetitionTime']*1000),
                        te=te,
                        fa=metadata.get('FlipAngle', 'UNKNOWN'),
                        vs=vs_str,
                        fov=fov_str,
                        ms=ms_str,
                        bval_str=bval_str,
                        n_vecs=n_vecs,
                        mb_str=mb_str
                       )
      desc = desc.replace('\n', ' ').lstrip()
      while '  ' in desc:
          desc = desc.replace('  ', ' ')
  
      return desc