Esempio n. 1
0
    def test_hypolist_but_not_sliplist(self):
        simple_file = BytesIO(b"""\
<?xml version='1.0' encoding='utf-8'?>
<nrml xmlns:gml="http://www.opengis.net/gml"
      xmlns="http://openquake.org/xmlns/nrml/0.4">
    <sourceModel name="Some Source Model">
        <simpleFaultSource
        id="3"
        name="Mount Diablo Thrust"
        tectonicRegion="Active Shallow Crust"
        >
            <simpleFaultGeometry>
                <gml:LineString>
                    <gml:posList>
                        -121.8229 37.7301 -122.0388 37.8771
                    </gml:posList>
                </gml:LineString>
                <dip>
                    45.0
                </dip>
                <upperSeismoDepth>
                    10.0
                </upperSeismoDepth>
                <lowerSeismoDepth>
                    20.0
                </lowerSeismoDepth>
            </simpleFaultGeometry>
            <magScaleRel>
                WC1994
            </magScaleRel>
            <ruptAspectRatio>
                1.5
            </ruptAspectRatio>
            <incrementalMFD
            binWidth="0.1"
            minMag="5.0"
            >
                <occurRates>
                    0.0010614989 0.00088291627 0.00073437777 0.0006108288 0.0005080653
                </occurRates>
            </incrementalMFD>
            <rake>
                30.0
            </rake>
            <hypoList>
                <hypo alongStrike="0.25" downDip="0.25" weight="0.3"/>
                <hypo alongStrike="0.75" downDip="0.75" weight="0.7"/>
            </hypoList>
        </simpleFaultSource>
    </sourceModel>
</nrml>
""")
        # check that the error raised by hazardlib is wrapped correctly
        msg = ('node simpleFaultSource: hypo_list and slip_list have to be '
               'both given')
        with self.assertRaises(ValueError) as ctx:
            parse_source_model(simple_file, self.converter)
        self.assertIn(msg, str(ctx.exception))
Esempio n. 2
0
    def test_hypolist_but_not_sliplist(self):
        simple_file = StringIO("""\
<?xml version='1.0' encoding='utf-8'?>
<nrml xmlns:gml="http://www.opengis.net/gml"
      xmlns="http://openquake.org/xmlns/nrml/0.4">
    <sourceModel name="Some Source Model">
        <simpleFaultSource
        id="3"
        name="Mount Diablo Thrust"
        tectonicRegion="Active Shallow Crust"
        >
            <simpleFaultGeometry>
                <gml:LineString>
                    <gml:posList>
                        -121.8229 37.7301 -122.0388 37.8771
                    </gml:posList>
                </gml:LineString>
                <dip>
                    45.0
                </dip>
                <upperSeismoDepth>
                    10.0
                </upperSeismoDepth>
                <lowerSeismoDepth>
                    20.0
                </lowerSeismoDepth>
            </simpleFaultGeometry>
            <magScaleRel>
                WC1994
            </magScaleRel>
            <ruptAspectRatio>
                1.5
            </ruptAspectRatio>
            <incrementalMFD
            binWidth="0.1"
            minMag="5.0"
            >
                <occurRates>
                    0.0010614989 0.00088291627 0.00073437777 0.0006108288 0.0005080653
                </occurRates>
            </incrementalMFD>
            <rake>
                30.0
            </rake>
            <hypoList>
                <hypo alongStrike="0.25" downDip="0.25" weight="0.3"/>
                <hypo alongStrike="0.75" downDip="0.75" weight="0.7"/>
            </hypoList>
        </simpleFaultSource>
    </sourceModel>
</nrml>
""")
        # check that the error raised by hazardlib is wrapped correctly
        msg = ('node simpleFaultSource: hypo_list and slip_list have to be '
               'both given')
        with self.assertRaises(ValueError) as ctx:
            parse_source_model(simple_file, self.converter)
        self.assertIn(msg, str(ctx.exception))
Esempio n. 3
0
 def test(self):
     nrml_to_hazardlib = source_input.NrmlHazardlibConverter(
         investigation_time=50.,
         rupture_mesh_spacing=1,  # km
         width_of_mfd_bin=0.1,  # for Truncated GR MFDs
         area_source_discretization=10.)
     with self.assertRaises(source_input.DuplicateID):
         source_input.parse_source_model(
             INVALID_SRC_MODEL, nrml_to_hazardlib)
Esempio n. 4
0
 def test_duplicate_id(self):
     converter = s.SourceConverter(
         investigation_time=50.,
         rupture_mesh_spacing=1,
         width_of_mfd_bin=0.1,
         area_source_discretization=10,
     )
     with self.assertRaises(s.DuplicateID):
         s.parse_source_model(DUPLICATE_ID_SRC_MODEL, converter)
Esempio n. 5
0
 def test_duplicate_id(self):
     converter = s.SourceConverter(
         investigation_time=50.,
         rupture_mesh_spacing=1,
         width_of_mfd_bin=0.1,
         area_source_discretization=10,
     )
     with self.assertRaises(s.DuplicateID):
         s.parse_source_model(
             DUPLICATE_ID_SRC_MODEL, converter)
Esempio n. 6
0
 def test_duplicate_id(self):
     converter = s.SourceConverter(  # different from self.converter
         investigation_time=50.,
         rupture_mesh_spacing=1,
         complex_fault_mesh_spacing=1,
         width_of_mfd_bin=0.1,
         area_source_discretization=10,
     )
     with self.assertRaises(DuplicatedID):
         parse_source_model(DUPLICATE_ID_SRC_MODEL, converter)
Esempio n. 7
0
 def test_duplicate_id(self):
     converter = s.SourceConverter(  # different from self.converter
         investigation_time=50.,
         rupture_mesh_spacing=1,
         complex_fault_mesh_spacing=1,
         width_of_mfd_bin=0.1,
         area_source_discretization=10,
     )
     with self.assertRaises(DuplicatedID):
         parse_source_model(
             DUPLICATE_ID_SRC_MODEL, converter)
Esempio n. 8
0
 def from_model_files(cls, limits, input_model, investigation_time=1.0,
         simple_mesh_spacing=1.0, complex_mesh_spacing=5.0,
         mfd_width=0.1, area_discretisation=10.0):
     """
     Reads the hazard model from a file
     :param list limits:
          Grid configuration [west, east, xspc, south, north, yspc,
                              upper, lower, zspc]
     :param str input_model:
         Path to input source model
     :param float investigation_time:
         Investigation time of Poisson model
     :param float simple_mesh_spacing:
         Rupture mesh spacing of simple fault (km)
     :param float complex_mesh_spacing:
         Rupture mesh spacing of complex fault (km)
     :param float mfd_width:
         Spacing (in magnitude units) of MFD
     :param float area_discretisation:
         Spacing of discretisation of area source (km)
     """
     converter = SourceConverter(investigation_time,
                                 simple_mesh_spacing,
                                 complex_mesh_spacing,
                                 mfd_width,
                                 area_discretisation)
     full_model = parse_source_model(input_model, converter)
     sources = []
     for model in full_model:
         sources.extend(list(model.sources))
     return cls(limits, sources, area_discretisation)
Esempio n. 9
0
    def initialize_sources(self):
        """
        Parse source models and validate source logic trees. It also
        filters the sources far away and apply uncertainties to the
        relevant ones. Notice that sources are automatically split.

        :returns:
            a list with the number of sources for each source model
        """
        logs.LOG.progress("initializing sources")
        self.source_model_lt = logictree.SourceModelLogicTree.from_hc(self.hc)
        sm_paths = distinct(self.source_model_lt)
        nrml_to_hazardlib = source.SourceConverter(
            self.hc.investigation_time,
            self.hc.rupture_mesh_spacing,
            self.hc.width_of_mfd_bin,
            self.hc.area_source_discretization,
        )
        # define an ordered dictionary trt_model_id -> SourceCollector
        self.source_collector = collections.OrderedDict()
        for i, (sm, weight, smpath) in enumerate(sm_paths):
            fname = os.path.join(self.hc.base_path, sm)
            apply_unc = self.source_model_lt.make_apply_uncertainties(smpath)
            try:
                source_collectors = source.parse_source_model(
                    fname, nrml_to_hazardlib, apply_unc)
            except ValueError as e:
                if str(e) == ('Surface does not conform with Aki & '
                              'Richards convention'):
                    raise InvalidFile('''\
%s: %s. Probably you are using an obsolete model.
In that case you can fix the file with the command
python -m openquake.engine.tools.correct_complex_sources %s
''' % (fname, e, fname))
                else:
                    raise
            trts = [sc.trt for sc in source_collectors]

            self.source_model_lt.tectonic_region_types.update(trts)
            lt_model = models.LtSourceModel.objects.create(
                hazard_calculation=self.hc, sm_lt_path=smpath, ordinal=i,
                sm_name=sm, weight=weight)
            if self.hc.inputs.get('gsim_logic_tree'):  # check TRTs
                gsims_by_trt = lt_model.make_gsim_lt(trts).values
            else:
                gsims_by_trt = {}

            # save TrtModels for each tectonic region type
            for sc in source_collectors:
                # NB: the source_collectors are ordered by number of sources
                # and lexicographically, so the models are in the right order
                trt_model_id = models.TrtModel.objects.create(
                    lt_model=lt_model,
                    tectonic_region_type=sc.trt,
                    num_sources=len(sc.sources),
                    num_ruptures=sc.num_ruptures,
                    min_mag=sc.min_mag,
                    max_mag=sc.max_mag,
                    gsims=gsims_by_trt.get(sc.trt, [])).id
                self.source_collector[trt_model_id] = sc
Esempio n. 10
0
def get_source_model(source_file, inv_time=50.0, simple_mesh_spacing=1.0,
                     complex_mesh_spacing=10.0, mfd_spacing=0.1,
                     area_discretisation=10.0):
    conv = SourceConverter(
        inv_time, simple_mesh_spacing, complex_mesh_spacing, mfd_spacing,
        area_discretisation)
    return parse_source_model(source_file, conv)
Esempio n. 11
0
 def from_model_files(cls,
                      limits,
                      input_model,
                      investigation_time=1.0,
                      simple_mesh_spacing=1.0,
                      complex_mesh_spacing=5.0,
                      mfd_width=0.1,
                      area_discretisation=10.0):
     """
     Reads the hazard model from a file
     :param list limits:
          Grid configuration [west, east, xspc, south, north, yspc,
                              upper, lower, zspc]
     :param str input_model:
         Path to input source model
     :param float investigation_time:
         Investigation time of Poisson model
     :param float simple_mesh_spacing:
         Rupture mesh spacing of simple fault (km)
     :param float complex_mesh_spacing:
         Rupture mesh spacing of complex fault (km)
     :param float mfd_width:
         Spacing (in magnitude units) of MFD
     :param float area_discretisation:
         Spacing of discretisation of area source (km)
     """
     converter = SourceConverter(investigation_time, simple_mesh_spacing,
                                 complex_mesh_spacing, mfd_width,
                                 area_discretisation)
     full_model = parse_source_model(input_model, converter)
     sources = []
     for model in full_model:
         sources.extend(list(model.sources))
     return cls(limits, sources, area_discretisation)
Esempio n. 12
0
def get_source_model(source_file,
                     inv_time=50.0,
                     simple_mesh_spacing=1.0,
                     complex_mesh_spacing=10.0,
                     mfd_spacing=0.1,
                     area_discretisation=10.0):
    conv = SourceConverter(inv_time, simple_mesh_spacing, complex_mesh_spacing,
                           mfd_spacing, area_discretisation)
    return parse_source_model(source_file, conv)
Esempio n. 13
0
 def setUpClass(cls):
     cls.converter = s.SourceConverter(
         investigation_time=50.,
         rupture_mesh_spacing=1,  # km
         complex_fault_mesh_spacing=1,  # km
         width_of_mfd_bin=1.,  # for Truncated GR MFDs
         area_source_discretization=1.)
     cls.source_collector = dict((sc.trt, sc) for sc in parse_source_model(
         MIXED_SRC_MODEL, cls.converter, lambda src: None))
     cls.sitecol = site.SiteCollection(cls.SITES)
Esempio n. 14
0
 def setUpClass(cls):
     cls.converter = s.SourceConverter(
         investigation_time=50.,
         rupture_mesh_spacing=1,  # km
         width_of_mfd_bin=1.,  # for Truncated GR MFDs
         area_source_discretization=1.)
     cls.source_collector = dict(
         (sc.trt, sc) for sc in s.parse_source_model(
             MIXED_SRC_MODEL, cls.converter, lambda src: None))
     cls.sitecol = site.SiteCollection(cls.SITES)
Esempio n. 15
0
    def initialize_sources(self):
        """
        Parse source models and validate source logic trees. It also
        filters the sources far away and apply uncertainties to the
        relevant ones. Notice that sources are automatically split.

        :returns:
            a list with the number of sources for each source model
        """
        logs.LOG.progress("initializing sources")
        self.source_model_lt = logictree.SourceModelLogicTree.from_hc(self.hc)
        sm_paths = distinct(self.source_model_lt)
        nrml_to_hazardlib = source.NrmlHazardlibConverter(
            self.hc.investigation_time,
            self.hc.rupture_mesh_spacing,
            self.hc.width_of_mfd_bin,
            self.hc.area_source_discretization,
        )
        # define an ordered dictionary trt_model_id -> SourceCollector
        self.source_collector = collections.OrderedDict()
        for i, (sm, weight, smpath) in enumerate(sm_paths):
            fname = os.path.join(self.hc.base_path, sm)
            apply_unc = self.source_model_lt.make_apply_uncertainties(smpath)
            source_collectors = source.parse_source_model(
                fname, nrml_to_hazardlib, apply_unc)
            trts = [sc.trt for sc in source_collectors]

            self.source_model_lt.tectonic_region_types.update(trts)
            lt_model = models.LtSourceModel.objects.create(
                hazard_calculation=self.hc, sm_lt_path=smpath, ordinal=i,
                sm_name=sm, weight=weight)

            # save TrtModels for each tectonic region type
            gsims_by_trt = lt_model.make_gsim_lt(trts).values
            for sc in source_collectors:
                if not sc.trt in gsims_by_trt:
                    gsim_file = self.hc.inputs['gsim_logic_tree']
                    raise ValueError(
                        "Found in %r a tectonic region type %r inconsistent "
                        "with the ones in %r" % (sm, sc.trt, gsim_file))
                # NB: the source_collectors are ordered by number of sources
                # and lexicographically, so the models are in the right order
                trt_model_id = models.TrtModel.objects.create(
                    lt_model=lt_model,
                    tectonic_region_type=sc.trt,
                    num_sources=len(sc.sources),
                    num_ruptures=sc.num_ruptures,
                    min_mag=sc.min_mag,
                    max_mag=sc.max_mag,
                    gsims=gsims_by_trt[sc.trt]).id
                self.source_collector[trt_model_id] = sc
Esempio n. 16
0
def get_source_models(oqparam, source_model_lt, sitecol=None, in_memory=True):
    """
    Build all the source models generated by the logic tree.

    :param oqparam:
        an :class:`openquake.commonlib.oqvalidation.OqParam` instance
    :param source_model_lt:
        a :class:`openquake.commonlib.logictree.SourceModelLogicTree` instance
    :param in_memory:
        if True, keep in memory the sources, else just collect the TRTs
    :returns:
        an iterator over :class:`openquake.commonlib.source.SourceModel`
        tuples
    """
    converter = sourceconverter.SourceConverter(
        oqparam.investigation_time,
        oqparam.rupture_mesh_spacing,
        oqparam.complex_fault_mesh_spacing,
        oqparam.width_of_mfd_bin,
        oqparam.area_source_discretization)

    # consider only the effective realizations
    rlzs = logictree.get_effective_rlzs(source_model_lt)
    samples_by_lt_path = source_model_lt.samples_by_lt_path()
    for i, rlz in enumerate(rlzs):
        sm = rlz.value  # name of the source model
        smpath = rlz.lt_path
        num_samples = samples_by_lt_path[smpath]
        if num_samples > 1:
            logging.warn('The source path %s was sampled %d times',
                         smpath, num_samples)
        fname = possibly_gunzip(os.path.join(oqparam.base_path, sm))
        if in_memory:
            apply_unc = source_model_lt.make_apply_uncertainties(smpath)
            try:
                trt_models = source.parse_source_model(
                    fname, converter, apply_unc)
            except ValueError as e:
                if str(e) in ('Surface does not conform with Aki & '
                              'Richards convention',
                              'Edges points are not in the right order'):
                    raise InvalidFile('''\
    %s: %s. Probably you are using an obsolete model.
    In that case you can fix the file with the command
    python -m openquake.engine.tools.correct_complex_sources %s
    ''' % (fname, e, fname))
                else:
                    raise
        else:  # just collect the TRT models
            smodel = read_nodes(fname, lambda el: 'sourceModel' in el.tag,
                                source.nodefactory['sourceModel']).next()
            trt_models = source.TrtModel.collect(smodel)
        trts = [mod.trt for mod in trt_models]
        source_model_lt.tectonic_region_types.update(trts)

        gsim_file = oqparam.inputs.get('gsim_logic_tree')
        if gsim_file:  # check TRTs
            gsim_lt = get_gsim_lt(oqparam, trts)
            for trt_model in trt_models:
                if trt_model.trt not in gsim_lt.values:
                    raise ValueError(
                        "Found in %r a tectonic region type %r inconsistent "
                        "with the ones in %r" % (sm, trt_model.trt, gsim_file))
                trt_model.gsims = gsim_lt.values[trt_model.trt]
        else:
            gsim_lt = logictree.DummyGsimLogicTree()
        weight = rlz.weight / num_samples
        yield source.SourceModel(
            sm, weight, smpath, trt_models, gsim_lt, i, num_samples)
Esempio n. 17
0
def get_source_models(oqparam, source_model_lt, sitecol=None, in_memory=True):
    """
    Build all the source models generated by the logic tree.

    :param oqparam:
        an :class:`openquake.commonlib.oqvalidation.OqParam` instance
    :param source_model_lt:
        a :class:`openquake.commonlib.logictree.SourceModelLogicTree` instance
    :param in_memory:
        if True, keep in memory the sources, else just collect the TRTs
    :returns:
        an iterator over :class:`openquake.commonlib.source.SourceModel`
        tuples
    """
    converter = sourceconverter.SourceConverter(
        oqparam.investigation_time, oqparam.rupture_mesh_spacing,
        oqparam.complex_fault_mesh_spacing, oqparam.width_of_mfd_bin,
        oqparam.area_source_discretization)

    # consider only the effective realizations
    rlzs = logictree.get_effective_rlzs(source_model_lt)
    samples_by_lt_path = source_model_lt.samples_by_lt_path()
    for i, rlz in enumerate(rlzs):
        sm = rlz.value  # name of the source model
        smpath = rlz.lt_path
        num_samples = samples_by_lt_path[smpath]
        if num_samples > 1:
            logging.warn('The source path %s was sampled %d times', smpath,
                         num_samples)
        fname = possibly_gunzip(os.path.join(oqparam.base_path, sm))
        if in_memory:
            apply_unc = source_model_lt.make_apply_uncertainties(smpath)
            try:
                trt_models = source.parse_source_model(fname, converter,
                                                       apply_unc)
            except ValueError as e:
                if str(e) in ('Surface does not conform with Aki & '
                              'Richards convention',
                              'Edges points are not in the right order'):
                    raise InvalidFile('''\
    %s: %s. Probably you are using an obsolete model.
    In that case you can fix the file with the command
    python -m openquake.engine.tools.correct_complex_sources %s
    ''' % (fname, e, fname))
                else:
                    raise
        else:  # just collect the TRT models
            smodel = next(
                read_nodes(fname, lambda el: 'sourceModel' in el.tag,
                           source.nodefactory['sourceModel']))
            trt_models = source.TrtModel.collect(smodel)
        trts = [mod.trt for mod in trt_models]
        source_model_lt.tectonic_region_types.update(trts)

        gsim_file = oqparam.inputs.get('gsim_logic_tree')
        if gsim_file:  # check TRTs
            gsim_lt = get_gsim_lt(oqparam, trts)
            for trt_model in trt_models:
                if trt_model.trt not in gsim_lt.values:
                    raise ValueError(
                        "Found in %r a tectonic region type %r inconsistent "
                        "with the ones in %r" % (sm, trt_model.trt, gsim_file))
                trt_model.gsims = gsim_lt.values[trt_model.trt]
        else:
            gsim_lt = logictree.DummyGsimLogicTree()
        weight = rlz.weight / num_samples
        yield source.SourceModel(sm, weight, smpath, trt_models, gsim_lt, i,
                                 num_samples, None)