code: def test_manual_report_2d(tmp_path, invisible_fig):
      """Simulate user manually creating report by adding one file at a time."""
      pytest.importorskip("sklearn")
      pytest.importorskip("pandas")
  
      from sklearn.exceptions import ConvergenceWarning
  
      r = Report(title="My Report")
      raw = read_raw_fif(raw_fname)
      raw.pick(raw.ch_names[:6]).crop(10, None)
      raw.info.normalize_proj()
      cov = read_cov(cov_fname)
      cov = pick_channels_cov(cov, raw.ch_names)
      events = read_events(events_fname)
      event_id = {
          "auditory/left": 1,
          "auditory/right": 2,
          "visual/left": 3,
          "visual/right": 4,
          "face": 5,
          "buttonpress": 32,
      }
      metadata, metadata_events, metadata_event_id = make_metadata(
          events=events,
          event_id=event_id,
          tmin=-0.2,
          tmax=0.5,
          sfreq=raw.info["sfreq"],
      )
      epochs_without_metadata = Epochs(
          raw=raw, events=events, event_id=event_id, baseline=None
      )
      epochs_with_metadata = Epochs(
          raw=raw,
          events=metadata_events,
          event_id=metadata_event_id,
          baseline=None,
          metadata=metadata,
      )
      evokeds = read_evokeds(evoked_fname)
      evoked = evokeds[0].pick("eeg")
  
      with pytest.warns(ConvergenceWarning, match="did not converge"):
          ica = ICA(n_components=3, max_iter=1, random_state=42).fit(
              inst=raw.copy().crop(tmax=1)
          )
      ica_ecg_scores = ica_eog_scores = np.array([3, 0, 0])
      ica_ecg_evoked = (
          ica_eog_evoked
      ) = epochs_without_metadata.average()
  
      r.add_raw(
          raw=raw,
          title="my raw data",
          tags=("raw",),
          psd=True,
          projs=False,
      )
      r.add_raw(
          raw=raw,
          title="my raw data 2",
          psd=False,
          projs=False,
          butterfly=1,
      )
      r.add_events(
          events=events_fname,
          title="my events",
          sfreq=raw.info["sfreq"],
      )
      r.add_epochs(
          epochs=epochs_without_metadata,
          title="my epochs",
          tags=("epochs",),
          psd=False,
          projs=False,
      )
      r.add_epochs(
          epochs=epochs_without_metadata,
          title="my epochs 2",
          psd=1,
          projs=False,
      )
      r.add_epochs(
          epochs=epochs_without_metadata,
          title="my epochs 2",
          psd=True,
          projs=False,
      )
      assert "Metadata" not in r.html[-1]
  
      # Try with metadata
      r.add_epochs(
          epochs=epochs_with_metadata,
          title="my epochs with metadata",
          psd=False,
          projs=False,
      )
      assert "Metadata" in r.html[-1]
  
      with pytest.raises(
          ValueError, match="requested to calculate PSD on a duration"
      ):
          r.add_epochs(
              epochs=epochs_with_metadata,
              title="my epochs 2",
              psd=100000000,
              projs=False,
          )
  
      r.add_evokeds(
          evokeds=evoked,
          noise_cov=cov_fname,
          titles=["my evoked 1"],
          tags=("evoked",),
          projs=False,
          n_time_points=2,
      )
      r.add_projs(
          info=raw_fname,
          projs=ecg_proj_fname,
          title="my proj",
          tags=("ssp", "ecg"),
      )
      r.add_ica(ica=ica, title="my ica", inst=None)
      with pytest.raises(RuntimeError, match="not preloaded"):
          r.add_ica(ica=ica, title="ica", inst=raw)
      r.add_ica(
          ica=ica,
          title="my ica with raw inst",
          inst=raw.copy().load_data(),
          picks=[2],
          ecg_evoked=ica_ecg_evoked,
          eog_evoked=ica_eog_evoked,
          ecg_scores=ica_ecg_scores,
          eog_scores=ica_eog_scores,
      )
      assert "ICA component 2" in r._content[-1].html
      epochs_baseline = epochs_without_metadata.copy().load_data()
      epochs_baseline.apply_baseline((None, 0))
      r.add_ica(
          ica=ica,
          title="my ica with epochs inst",
          inst=epochs_baseline,
          picks=[0],
      )
      r.add_ica(
          ica=ica,
          title="my ica with picks=None",
          inst=epochs_baseline,
          picks=None,
      )
      r.add_covariance(cov=cov, info=raw_fname, title="my cov")
      r.add_forward(
          forward=fwd_fname,
          title="my forward",
          subject="sample",
          subjects_dir=subjects_dir,
      )
      r.add_html(html="<strong>Hello</strong>", title="Bold")
      r.add_code(code=__file__, title="my code")
      r.add_sys_info(title="my sysinfo")
  
      # drop locations (only EEG channels in `evoked`)
      evoked_no_ch_locs = evoked.copy()
      for ch in evoked_no_ch_locs.info["chs"]:
          ch["loc"][:3] = np.nan
  
      with pytest.warns(
          RuntimeWarning,
          match="No EEG channel locations found, cannot create joint plot",
      ):
          r.add_evokeds(
              evokeds=evoked_no_ch_locs,
              titles=["evoked no chan locs"],
              tags=("evoked",),
              projs=False,
              n_time_points=1,
          )
      assert "Time course" not in r._content[-1].html
      assert "Topographies" not in r._content[-1].html
      assert evoked.info[
          "projs"
      ]  # only then the following test makes sense
      assert "Projectors" not in r._content[-1].html
      assert "Global field power" in r._content[-1].html
  
      # Drop locations from Info used for projs
      info_no_ch_locs = raw.info.copy()
      for ch in info_no_ch_locs["chs"]:
          ch["loc"][:3] = np.nan
  
      with pytest.raises(
          ValueError, match="does not contain.*channel locations"
      ):
          r.add_projs(info=info_no_ch_locs, title="Projs no chan locs")
  
      # Drop locations from ICA
      ica_no_ch_locs = ica.copy()
      for ch in ica_no_ch_locs.info["chs"]:
          ch["loc"][:3] = np.nan
  
      with pytest.warns(
          RuntimeWarning, match="No Magnetometers channel locations"
      ):
          r.add_ica(
              ica=ica_no_ch_locs,
              picks=[0],
              inst=raw.copy().load_data(),
              title="ICA",
          )
      assert "ICA component properties" not in r._content[-1].html
      assert "ICA component topographies" not in r._content[-1].html
      assert "Original and cleaned signal" in r._content[-1].html
  
      fname = tmp_path / "report.html"
      r.save(fname=fname, open_browser=False)
  
imports: import base64
  import copy
  import glob
  import os
  import pickle
  import re
  import shutil
  from io import BytesIO
  from pathlib import Path
  import numpy
  import pytest
  from matplotlib import pyplot
  from mne import Epochs, create_info, pick_channels_cov, read_cov, read_events, read_evokeds
  from mne._fiff.write import DATE_NONE
  from mne.datasets import testing
  from mne.epochs import make_metadata
  from mne.io import RawArray, read_info, read_raw_fif
  from mne.preprocessing import ICA
  from mne.report import Report, _ReportScraper, open_report, report
  from mne.report import report
  from mne.report.report import _ALLOWED_IMAGE_FORMATS, CONTENT_ORDER, _webp_supported
  from mne.utils import Bunch
  from mne.utils._testing import assert_object_equal
  from mne.viz import plot_alignment
label_desc: Use image node_id 24 for calling a global function with example usage: test_manual_report_2d(tmp_path, invisible_fig) without return types