docs: def export(self):
          """
          Generate a NIDM-Results export.
          """
          try:
              if not os.path.isdir(self.export_dir):
                  os.mkdir(self.export_dir)
  
              # Initialise main bundle
              self._create_bundle(self.version)
  
              self.add_object(self.software)
  
              # Add model fitting steps
              if not isinstance(self.model_fittings, list):
                  self.model_fittings = list(self.model_fittings.values())
  
              for model_fitting in self.model_fittings:
                  # Design Matrix
                  # model_fitting.activity.used(model_fitting.design_matrix)
                  self.bundle.used(model_fitting.activity.id,
                                   model_fitting.design_matrix.id)
                  self.add_object(model_fitting.design_matrix)
                  # *** Export visualisation of the design matrix
                  self.add_object(model_fitting.design_matrix.image)
  
                  if model_fitting.design_matrix.image.file is not None:
                      self.add_object(model_fitting.design_matrix.image.file)
  
                  if model_fitting.design_matrix.hrf_models is not None:
                      # drift model
                      self.add_object(model_fitting.design_matrix.drift_model)
  
                  if self.version['major'] > 1 or \
                          (self.version['major'] == 1 and
                           self.version['minor'] >= 3):
                      # Machine
                      # model_fitting.data.wasAttributedTo(model_fitting.machine)
                      self.bundle.wasAttributedTo(model_fitting.data.id,
                                                  model_fitting.machine.id)
                      self.add_object(model_fitting.machine)
  
                      # Imaged subject or group(s)
                      for sub in model_fitting.subjects:
                          self.add_object(sub)
                          # model_fitting.data.wasAttributedTo(sub)
                          self.bundle.wasAttributedTo(model_fitting.data.id,
                                                      sub.id)
  
                  # Data
                  # model_fitting.activity.used(model_fitting.data)
                  self.bundle.used(model_fitting.activity.id,
                                   model_fitting.data.id)
                  self.add_object(model_fitting.data)
  
                  # Error Model
                  # model_fitting.activity.used(model_fitting.error_model)
                  self.bundle.used(model_fitting.activity.id,
                                   model_fitting.error_model.id)
                  self.add_object(model_fitting.error_model)
  
                  # Parameter Estimate Maps
                  for param_estimate in model_fitting.param_estimates:
                      # param_estimate.wasGeneratedBy(model_fitting.activity)
                      self.bundle.wasGeneratedBy(param_estimate.id,
                                                 model_fitting.activity.id)
                      self.add_object(param_estimate)
                      self.add_object(param_estimate.coord_space)
                      self.add_object(param_estimate.file)
  
                      if param_estimate.derfrom is not None:
                          self.bundle.wasDerivedFrom(param_estimate.id,
                                                     param_estimate.derfrom.id)
                          self.add_object(param_estimate.derfrom)
                          self.add_object(param_estimate.derfrom.file,
                                          export_file=False)
  
                  # Residual Mean Squares Map
                  # model_fitting.rms_map.wasGeneratedBy(model_fitting.activity)
                  self.add_object(model_fitting.rms_map)
                  self.bundle.wasGeneratedBy(model_fitting.rms_map.id,
                                             model_fitting.activity.id)
                  self.add_object(model_fitting.rms_map.coord_space)
                  self.add_object(model_fitting.rms_map.file)
                  if model_fitting.rms_map.derfrom is not None:
                      self.bundle.wasDerivedFrom(
                          model_fitting.rms_map.id,
                          model_fitting.rms_map.derfrom.id)
                      self.add_object(model_fitting.rms_map.derfrom)
                      self.add_object(model_fitting.rms_map.derfrom.file,
                                      export_file=False)
  
                  # Resels per Voxel Map
                  if model_fitting.rpv_map is not None:
                      self.add_object(model_fitting.rpv_map)
                      self.bundle.wasGeneratedBy(model_fitting.rpv_map.id,
                                                 model_fitting.activity.id)
                      self.add_object(model_fitting.rpv_map.coord_space)
                      self.add_object(model_fitting.rpv_map.file)
                      if model_fitting.rpv_map.inf_id is not None:
                          self.bundle.used(model_fitting.rpv_map.inf_id,
                                           model_fitting.rpv_map.id)
                      if model_fitting.rpv_map.derfrom is not None:
                          self.bundle.wasDerivedFrom(
                              model_fitting.rpv_map.id,
                              model_fitting.rpv_map.derfrom.id)
                          self.add_object(model_fitting.rpv_map.derfrom)
                          self.add_object(model_fitting.rpv_map.derfrom.file,
                                          export_file=False)
  
                  # Mask
                  # model_fitting.mask_map.wasGeneratedBy(model_fitting.activity)
                  self.bundle.wasGeneratedBy(model_fitting.mask_map.id,
                                             model_fitting.activity.id)
                  self.add_object(model_fitting.mask_map)
                  if model_fitting.mask_map.derfrom is not None:
                      self.bundle.wasDerivedFrom(
                          model_fitting.mask_map.id,
                          model_fitting.mask_map.derfrom.id)
                      self.add_object(model_fitting.mask_map.derfrom)
                      self.add_object(model_fitting.mask_map.derfrom.file,
                                      export_file=False)
  
                  # Create coordinate space export
                  self.add_object(model_fitting.mask_map.coord_space)
                  # Create "Mask map" entity
                  self.add_object(model_fitting.mask_map.file)
  
                  # Grand Mean map
                  # model_fitting.grand_mean_map.wasGeneratedBy(model_fitting.activity)
                  self.bundle.wasGeneratedBy(model_fitting.grand_mean_map.id,
                                             model_fitting.activity.id)
                  self.add_object(model_fitting.grand_mean_map)
                  # Coordinate space entity
                  self.add_object(model_fitting.grand_mean_map.coord_space)
                  # Grand Mean Map entity
                  self.add_object(model_fitting.grand_mean_map.file)
  
                  # Model Parameters Estimation activity
                  self.add_object(model_fitting.activity)
                  self.bundle.wasAssociatedWith(model_fitting.activity.id,
                                                self.software.id)
                  # model_fitting.activity.wasAssociatedWith(self.software)
                  # self.add_object(model_fitting)
  
              # Add contrast estimation steps
              analysis_masks = dict()
              for (model_fitting_id, pe_ids), contrasts in list(
                      self.contrasts.items()):
                  for contrast in contrasts:
                      model_fitting = self._get_model_fitting(model_fitting_id)
                      # for contrast in contrasts:
                      # contrast.estimation.used(model_fitting.rms_map)
                      self.bundle.used(contrast.estimation.id,
                                       model_fitting.rms_map.id)
                      # contrast.estimation.used(model_fitting.mask_map)
                      self.bundle.used(contrast.estimation.id,
                                       model_fitting.mask_map.id)
                      analysis_masks[contrast.estimation.id] = \
                          model_fitting.mask_map.id
                      self.bundle.used(contrast.estimation.id,
                                       contrast.weights.id)
                      self.bundle.used(contrast.estimation.id,
                                       model_fitting.design_matrix.id)
                      # contrast.estimation.wasAssociatedWith(self.software)
                      self.bundle.wasAssociatedWith(contrast.estimation.id,
                                                    self.software.id)
  
                      for pe_id in pe_ids:
                          # contrast.estimation.used(pe_id)
                          self.bundle.used(contrast.estimation.id, pe_id)
  
                      # Create estimation activity
                      self.add_object(contrast.estimation)
  
                      # Create contrast weights
                      self.add_object(contrast.weights)
  
                      if contrast.contrast_map is not None:
                          # Create contrast Map
                          # contrast.contrast_map.wasGeneratedBy(contrast.estimation)
                          self.bundle.wasGeneratedBy(contrast.contrast_map.id,
                                                     contrast.estimation.id)
                          self.add_object(contrast.contrast_map)
                          self.add_object(contrast.contrast_map.coord_space)
                          # Copy contrast map in export directory
                          self.add_object(contrast.contrast_map.file)
  
                          if contrast.contrast_map.derfrom is not None:
                              self.bundle.wasDerivedFrom(
                                  contrast.contrast_map.id,
                                  contrast.contrast_map.derfrom.id)
                              self.add_object(contrast.contrast_map.derfrom)
                              self.add_object(contrast.contrast_map.derfrom.file,
                                              export_file=False)
  
                      # Create Std Err. Map (T-tests) or Explained Mean Sq. Map
                      # (F-tests)
                      # contrast.stderr_or_expl_mean_sq_map.wasGeneratedBy
                      # (contrast.estimation)
                      stderr_explmeansq_map = (
                          contrast.stderr_or_expl_mean_sq_map)
                      self.bundle.wasGeneratedBy(
                          stderr_explmeansq_map.id,
                          contrast.estimation.id)
                      self.add_object(stderr_explmeansq_map)
                      self.add_object(
                          stderr_explmeansq_map.coord_space)
                      if isinstance(stderr_explmeansq_map,
                                    ContrastStdErrMap) and \
                              stderr_explmeansq_map.contrast_var:
                          self.add_object(
                              stderr_explmeansq_map.contrast_var)
                          if stderr_explmeansq_map.var_coord_space:
                              self.add_object(
                                  stderr_explmeansq_map.var_coord_space)
                          if stderr_explmeansq_map.contrast_var.coord_space:
                              self.add_object(
                                  stderr_explmeansq_map.contrast_var.coord_space)
                          self.add_object(
                              stderr_explmeansq_map.contrast_var.file,
                              export_file=False)
                          self.bundle.wasDerivedFrom(
                              stderr_explmeansq_map.id,
                              stderr_explmeansq_map.contrast_var.id)
                      self.add_object(stderr_explmeansq_map.file)
  
                      # Create Statistic Map
                      # contrast.stat_map.wasGeneratedBy(contrast.estimation)
                      self.bundle.wasGeneratedBy(contrast.stat_map.id,
                                                 contrast.estimation.id)
                      self.add_object(contrast.stat_map)
                      self.add_object(contrast.stat_map.coord_space)
                      # Copy Statistical map in export directory
                      self.add_object(contrast.stat_map.file)
  
                      if contrast.stat_map.derfrom is not None:
                          self.bundle.wasDerivedFrom(
                              contrast.stat_map.id,
                              contrast.stat_map.derfrom.id)
                          self.add_object(contrast.stat_map.derfrom)
                          self.add_object(contrast.stat_map.derfrom.file,
                                          export_file=False)
  
                      # Create Z Statistic Map
                      if contrast.z_stat_map:
                          # contrast.z_stat_map.wasGeneratedBy(contrast.estimation)
                          self.bundle.wasGeneratedBy(contrast.z_stat_map.id,
                                                     contrast.estimation.id)
                          self.add_object(contrast.z_stat_map)
                          self.add_object(contrast.z_stat_map.coord_space)
                          # Copy Statistical map in export directory
                          self.add_object(contrast.z_stat_map.file)
  
                      # self.add_object(contrast)
  
              # Add inference steps
              for contrast_id, inferences in list(self.inferences.items()):
                  contrast = self._get_contrast(contrast_id)
  
                  for inference in inferences:
                      if contrast.z_stat_map:
                          used_id = contrast.z_stat_map.id
                      else:
                          used_id = contrast.stat_map.id
                      # inference.inference_act.used(used_id)
                      self.bundle.used(inference.inference_act.id, used_id)
                      # inference.inference_act.wasAssociatedWith(self.software)
                      self.bundle.wasAssociatedWith(inference.inference_act.id,
                                                    self.software.id)
  
                      # self.add_object(inference)
                      # Excursion set
                      # inference.excursion_set.wasGeneratedBy(inference.inference_act)
                      self.bundle.wasGeneratedBy(inference.excursion_set.id,
                                                 inference.inference_act.id)
                      self.add_object(inference.excursion_set)
                      self.add_object(inference.excursion_set.coord_space)
                      if inference.excursion_set.visu is not None:
                          self.add_object(inference.excursion_set.visu)
                          if inference.excursion_set.visu.file is not None:
                              self.add_object(inference.excursion_set.visu.file)
                      # Copy "Excursion set map" file in export directory
                      self.add_object(inference.excursion_set.file)
                      if inference.excursion_set.clust_map is not None:
                          self.add_object(inference.excursion_set.clust_map)
                          self.add_object(inference.excursion_set.clust_map.file)
                          self.add_object(
                              inference.excursion_set.clust_map.coord_space)
  
                      if inference.excursion_set.mip is not None:
                          self.add_object(inference.excursion_set.mip)
                          self.add_object(inference.excursion_set.mip.file)
  
                      # Height threshold
                      if inference.height_thresh.equiv_thresh is not None:
                          for equiv in inference.height_thresh.equiv_thresh:
                              self.add_object(equiv)
                      self.add_object(inference.height_thresh)
  
                      # Extent threshold
                      if inference.extent_thresh.equiv_thresh is not None:
                          for equiv in inference.extent_thresh.equiv_thresh:
                              self.add_object(equiv)
                      self.add_object(inference.extent_thresh)
  
                      # Display Mask (potentially more than 1)
                      if inference.disp_mask:
                          for mask in inference.disp_mask:
                              # inference.inference_act.used(mask)
                              self.bundle.used(inference.inference_act.id,
                                               mask.id)
                              self.add_object(mask)
                              # Create coordinate space entity
                              self.add_object(mask.coord_space)
                              # Create "Display Mask Map" entity
                              self.add_object(mask.file)
  
                              if mask.derfrom is not None:
                                  self.bundle.wasDerivedFrom(mask.id,
                                                             mask.derfrom.id)
                                  self.add_object(mask.derfrom)
                                  self.add_object(mask.derfrom.file,
                                                  export_file=False)
  
                      # Search Space
                      self.bundle.wasGeneratedBy(inference.search_space.id,
                                                 inference.inference_act.id)
                      # inference.search_space.wasGeneratedBy(inference.inference_act)
                      self.add_object(inference.search_space)
                      self.add_object(inference.search_space.coord_space)
                      # Copy "Mask map" in export directory
                      self.add_object(inference.search_space.file)
  
                      # Peak Definition
                      if inference.peak_criteria:
                          # inference.inference_act.used(inference.peak_criteria)
                          self.bundle.used(inference.inference_act.id,
                                           inference.peak_criteria.id)
                          self.add_object(inference.peak_criteria)
  
                      # Cluster Definition
                      if inference.cluster_criteria:
                          # inference.inference_act.used(inference.cluster_criteria)
                          self.bundle.used(inference.inference_act.id,
                                           inference.cluster_criteria.id)
                          self.add_object(inference.cluster_criteria)
  
                      if inference.clusters:
                          # Clusters and peaks
                          for cluster in inference.clusters:
                              # cluster.wasDerivedFrom(inference.excursion_set)
                              self.bundle.wasDerivedFrom(
                                  cluster.id, inference.excursion_set.id)
                              self.add_object(cluster)
                              for peak in cluster.peaks:
                                  self.bundle.wasDerivedFrom(peak.id, cluster.id)
                                  self.add_object(peak)
                                  self.add_object(peak.coordinate)
  
                              if cluster.cog is not None:
                                  self.bundle.wasDerivedFrom(cluster.cog.id,
                                                             cluster.id)
                                  self.add_object(cluster.cog)
                                  self.add_object(cluster.cog.coordinate)
  
                      # Inference activity
                      # inference.inference_act.wasAssociatedWith(inference.software_id)
                      # inference.inference_act.used(inference.height_thresh)
                      self.bundle.used(inference.inference_act.id,
                                       inference.height_thresh.id)
                      # inference.inference_act.used(inference.extent_thresh)
                      self.bundle.used(inference.inference_act.id,
                                       inference.extent_thresh.id)
                      self.bundle.used(inference.inference_act.id,
                                       analysis_masks[contrast.estimation.id])
                      self.add_object(inference.inference_act)
  
              # Write-out prov file
              self.save_prov_to_files()
  
              return self.out_dir
          except Exception:
              self.cleanup()
              raise