def from_points(cls, lons, lats, depths=None, sitemodel=None, req_site_params=()): """ Build the site collection from :param lons: a sequence of longitudes :param lats: a sequence of latitudes :param depths: a sequence of depths (or None) :param sitemodel: None or an object containing site parameters as attributes :param req_site_params: a sequence of required site parameters, possibly empty """ assert len(lons) < U32LIMIT, len(lons) if depths is None: depths = numpy.zeros(len(lons)) assert len(lons) == len(lats) == len(depths), (len(lons), len(lats), len(depths)) self = object.__new__(cls) self.complete = self req = ['sids', 'lon', 'lat', 'depth'] + sorted( par for par in req_site_params if par not in ('lon', 'lat')) if 'vs30' in req and 'vs30measured' not in req: req.append('vs30measured') dtype = numpy.dtype([(p, site_param_dt[p]) for p in req]) self.array = arr = numpy.zeros(len(lons), dtype) arr['sids'] = numpy.arange(len(lons), dtype=numpy.uint32) arr['lon'] = fix_lon(numpy.array(lons)) arr['lat'] = numpy.array(lats) arr['depth'] = numpy.array(depths) if sitemodel is None: pass elif hasattr(sitemodel, 'reference_vs30_value'): # sitemodel is actually an OqParam instance self._set('vs30', sitemodel.reference_vs30_value) self._set('vs30measured', sitemodel.reference_vs30_type == 'measured') if 'z1pt0' in req_site_params: self._set('z1pt0', sitemodel.reference_depth_to_1pt0km_per_sec) if 'z2pt5' in req_site_params: self._set('z2pt5', sitemodel.reference_depth_to_2pt5km_per_sec) if 'backarc' in req_site_params: self._set('backarc', sitemodel.reference_backarc) else: for name in sitemodel.dtype.names: if name not in ('lon', 'lat'): self._set(name, sitemodel[name]) dupl = get_duplicates(self.array, 'lon', 'lat') if dupl: # raise a decent error message displaying only the first 9 # duplicates (there could be millions) n = len(dupl) dots = ' ...' if n > 9 else '' items = list(dupl.items())[:9] raise ValueError('There are %d duplicate sites %s%s' % (n, items, dots)) return self
def _get_site_model(fname, req_site_params): sm = hdf5.read_csv(fname, site.site_param_dt).array sm['lon'] = numpy.round(sm['lon'], 5) sm['lat'] = numpy.round(sm['lat'], 5) dupl = general.get_duplicates(sm, 'lon', 'lat') if dupl: raise InvalidFile('Found duplicate sites %s in %s' % (dupl, fname)) z = numpy.zeros(len(sm), sorted(sm.dtype.descr)) for name in z.dtype.names: z[name] = sm[name] return z
def get_site_model(oqparam): """ Convert the NRML file into an array of site parameters. :param oqparam: an :class:`openquake.commonlib.oqvalidation.OqParam` instance :returns: an array with fields lon, lat, vs30, ... """ req_site_params = get_gsim_lt(oqparam).req_site_params if 'amplification' in oqparam.inputs: req_site_params.add('ampcode') arrays = [] for fname in oqparam.inputs['site_model']: if isinstance(fname, str) and fname.endswith('.csv'): sm = hdf5.read_csv(fname, site.site_param_dt).array sm['lon'] = numpy.round(sm['lon'], 5) sm['lat'] = numpy.round(sm['lat'], 5) dupl = get_duplicates(sm, 'lon', 'lat') if dupl: raise InvalidFile( 'Found duplicate sites %s in %s' % (dupl, fname)) if 'site_id' in sm.dtype.names: raise InvalidFile('%s: you passed a sites.csv file instead of ' 'a site_model.csv file!' % fname) z = numpy.zeros(len(sm), sorted(sm.dtype.descr)) for name in z.dtype.names: # reorder the fields z[name] = sm[name] arrays.append(z) continue nodes = nrml.read(fname).siteModel params = [valid.site_param(node.attrib) for node in nodes] missing = req_site_params - set(params[0]) if 'vs30measured' in missing: # use a default of False missing -= {'vs30measured'} for param in params: param['vs30measured'] = False if 'backarc' in missing: # use a default of False missing -= {'backarc'} for param in params: param['backarc'] = False if 'ampcode' in missing: # use a default of b'' missing -= {'ampcode'} for param in params: param['ampcode'] = b'' if missing: raise InvalidFile('%s: missing parameter %s' % (oqparam.inputs['site_model'], ', '.join(missing))) # NB: the sorted in sorted(params[0]) is essential, otherwise there is # an heisenbug in scenario/test_case_4 site_model_dt = numpy.dtype([(p, site.site_param_dt[p]) for p in sorted(params[0])]) sm = numpy.array([tuple(param[name] for name in site_model_dt.names) for param in params], site_model_dt) dupl = "\n".join( '%s %s' % loc for loc, n in countby(sm, 'lon', 'lat').items() if n > 1) if dupl: raise InvalidFile('There are duplicated sites in %s:\n%s' % (fname, dupl)) arrays.append(sm) return numpy.concatenate(arrays)