docs: def is_valid_geometry(self):
          """
          It is possible to infer the geometry only if exactly
          one of sites, sites_csv, hazard_curves_csv, gmfs_csv,
          region is set. You did set more than one, or nothing.
          """
          has_sites = (self.sites is not None or 'sites' in self.inputs
                       or 'site_model' in self.inputs)
          if not has_sites and not self.ground_motion_fields:
              # when generating only the ruptures you do not need the sites
              return True
          if ('gmfs' in self.inputs and not has_sites and
                  not self.inputs['gmfs'].endswith('.xml')):
              raise ValueError('Missing sites or sites_csv in the .ini file')
          elif ('risk' in self.calculation_mode or
                  'damage' in self.calculation_mode or
                  'bcr' in self.calculation_mode):
              return True  # no check on the sites for risk
          flags = dict(
              sites=bool(self.sites),
              sites_csv=self.inputs.get('sites', 0),
              hazard_curves_csv=self.inputs.get('hazard_curves', 0),
              gmfs_csv=self.inputs.get('gmfs', 0),
              region=bool(self.region and self.region_grid_spacing))
          # NB: below we check that all the flags
          # are mutually exclusive
          return sum(bool(v) for v in flags.values()) == 1 or self.inputs.get(
              'exposure') or self.inputs.get('site_model')