예제 #1
0
    def serialize(self, data):
        """
        Serialize loss map data to XML.

        See :meth:`LossMapWriter.serialize` for expected input.
        """
        _assert_valid_input(data)

        with NRMLFile(self._dest, 'w') as output:
            root = et.Element("nrml")

            loss_map_el = self._create_loss_map_elem(root)

            current_location = None
            current_node = None
            for loss in data:

                if (current_location is None
                        or loss.location.wkt != current_location):
                    current_node = et.SubElement(loss_map_el, "node")
                    current_location = _append_location(
                        current_node, loss.location)

                loss_elem = et.SubElement(current_node, "loss")
                loss_elem.set("assetRef", str(loss.asset_ref))

                if loss.std_dev is not None:
                    loss_elem.set("mean", FIVEDIGITS % loss.value)
                    loss_elem.set("stdDev", FIVEDIGITS % loss.std_dev)
                else:
                    loss_elem.set("value", FIVEDIGITS % loss.value)

            nrml.write(list(root), output)
예제 #2
0
    def serialize(self, total_fractions, locations_fractions):
        """
        Actually serialize the fractions.

        :param dict total_fractions:
            maps a value of `variable` with a tuple representing the absolute
            losses and the fraction
        :param dict locations_fractions:
            a dictionary mapping a tuple (longitude, latitude) to
            bins. Each bin is a dictionary with the same structure of
            `total_fractions`.
        """

        def write_bins(parent, bin_data):
            for value, (absolute_loss, fraction) in bin_data.items():
                bin_element = et.SubElement(parent, "bin")
                bin_element.set("value", str(value))
                bin_element.set("absoluteLoss", "%.4e" % absolute_loss)
                bin_element.set("fraction", "%.5f" % fraction)

        with NRMLFile(self.dest, 'w') as output:
            root = et.Element("nrml")

            # container element
            container = et.SubElement(root, "lossFraction")
            container.set("investigationTime",
                          "%.2f" % self.hazard_metadata.investigation_time)

            if self.poe is not None:
                container.set("poE", "%.4f" % self.poe)

            container.set(
                "sourceModelTreePath", self.hazard_metadata.sm_path or "")
            container.set("gsimTreePath", self.hazard_metadata.gsim_path or "")

            if self.hazard_metadata.statistics is not None:
                container.set("statistics", self.hazard_metadata.statistics)

            if self.hazard_metadata.quantile is not None:
                container.set(
                    "quantileValue", "%.4f" % self.hazard_metadata.quantile)
            container.set("lossCategory", self.loss_category)
            container.set("unit", self.loss_unit)
            container.set("variable", self.variable)
            container.set("lossType", self.loss_type)

            # total fractions
            total = et.SubElement(container, "total")
            write_bins(total, total_fractions)

            # map
            map_element = et.SubElement(container, "map")

            for lon_lat, bin_data in locations_fractions.items():
                node_element = et.SubElement(map_element, "node")
                node_element.set("lon", str(lon_lat[0]))
                node_element.set("lat", str(lon_lat[1]))
                write_bins(node_element, bin_data)

            nrml.write(list(root), output)
예제 #3
0
    def serialize(self, data):
        """
        Serialize loss map data to a file as a GeoJSON feature collection.

        See :meth:`LossMapWriter.serialize` for expected input.
        """
        _assert_valid_input(data)

        feature_coll = {
            'type': 'FeatureCollection',
            'features': [],
            'oqtype': 'LossMap',
            # TODO: oqnrmlversion has little meaning now
            'oqnrmlversion': '0.4',
            'oqmetadata': self._create_oqmetadata(),
        }

        for loss in data:
            loc = loss.location

            loss_node = {
                'type': 'Feature',
                'geometry': {
                    'type': 'Point',
                    'coordinates': [float(loc.x), float(loc.y)]
                },
                'properties': {
                    'loss': float(loss.value),
                    'asset_ref': loss.asset_ref
                },
            }
            feature_coll['features'].append(loss_node)

            if loss.std_dev is not None:
                loss_node['properties']['std_dev'] = float(loss.std_dev)

        with NRMLFile(self._dest, 'w') as fh:
            json.dump(feature_coll,
                      fh,
                      sort_keys=True,
                      indent=4,
                      separators=(',', ': '))
예제 #4
0
    def serialize(self, data):
        """
        Serialize loss map data to XML.

        See :meth:`LossMapWriter.serialize` for expected input.
        """
        _assert_valid_input(data)

        with NRMLFile(self._dest, 'w') as output:
            root = etree.Element("nrml", nsmap=SERIALIZE_NS_MAP)

            loss_map_el = self._create_loss_map_elem(root)

            current_location = None
            current_node = None
            for loss in data:

                if (current_location is None
                        or loss.location.wkt != current_location):
                    current_node = etree.SubElement(loss_map_el, "node")
                    current_location = _append_location(
                        current_node, loss.location)

                loss_elem = etree.SubElement(current_node, "loss")
                loss_elem.set("assetRef", str(loss.asset_ref))

                if loss.std_dev is not None:
                    loss_elem.set("mean", str(loss.value))
                    loss_elem.set("stdDev", str(loss.std_dev))
                else:
                    loss_elem.set("value", str(loss.value))

            output.write(
                etree.tostring(root,
                               pretty_print=True,
                               xml_declaration=True,
                               encoding="UTF-8"))
예제 #5
0
    def serialize(self, data):
        """
        Serialize an aggregation loss curve.

        :param data:
            An object representing an aggregate loss curve. This object should:

            * define an attribute `poes`, which is a list of floats
              describing the probabilities of exceedance.
            * define an attribute `losses`, which is a list of floats
              describing the losses.
            * define an attribute `average_loss`, which is a float
              describing the average loss associated to the loss curve
            * define an attribute `stddev_loss`, which is a float
              describing the standard deviation of losses if the loss curve
              has been computed with an event based approach. Otherwise, it
              is None

            Also, `poes`, `losses` values must be indexed coherently,
            i.e.: the loss at index zero is related to the probability
            of exceedance at the same index.
        """

        if data is None:
            raise ValueError("You can not serialize an empty document")

        with NRMLFile(self._dest, 'wb') as output:
            root = etree.Element("nrml", nsmap=SERIALIZE_NS_MAP)

            aggregate_loss_curve = etree.SubElement(root, "aggregateLossCurve")

            aggregate_loss_curve.set("investigationTime",
                                     str(self._investigation_time))

            if self._source_model_tree_path is not None:
                aggregate_loss_curve.set("sourceModelTreePath",
                                         str(self._source_model_tree_path))

            if self._gsim_tree_path is not None:
                aggregate_loss_curve.set("gsimTreePath",
                                         str(self._gsim_tree_path))

            if self._statistics is not None:
                aggregate_loss_curve.set("statistics", str(self._statistics))

            if self._quantile_value is not None:
                aggregate_loss_curve.set("quantileValue",
                                         str(self._quantile_value))

            if self._unit is not None:
                aggregate_loss_curve.set("unit", str(self._unit))

            aggregate_loss_curve.set("lossType", self._loss_type)

            poes = etree.SubElement(aggregate_loss_curve, "poEs")
            poes.text = " ".join([str(p) for p in data.poes])

            losses = etree.SubElement(aggregate_loss_curve, "losses")
            losses.text = " ".join(["%.4f" % p for p in data.losses])

            losses = etree.SubElement(aggregate_loss_curve, "averageLoss")
            losses.text = "%.4e" % data.average_loss

            if data.stddev_loss is not None:
                losses = etree.SubElement(aggregate_loss_curve, "stdDevLoss")
                losses.text = "%.4e" % data.stddev_loss

            output.write(
                etree.tostring(root,
                               pretty_print=True,
                               xml_declaration=True,
                               encoding="UTF-8"))
예제 #6
0
    def serialize(self, data):
        """
        Serialize a collection of loss curves.

        :param data:
            An iterable of loss curve objects. Each object should:

            * define an attribute `location`, which is itself an object
              defining two attributes, `x` containing the longitude value
              and `y` containing the latitude value.
            * define an attribute `asset_ref`, which contains the unique
              identifier of the asset related to the loss curve.
            * define an attribute `poes`, which is a list of floats
              describing the probabilities of exceedance.
            * define an attribute `losses`, which is a list of floats
              describing the losses.
            * define an attribute `loss_ratios`, which is a list of floats
              describing the loss ratios.
            * define an attribute `average_loss`, which is a float
              describing the average loss associated to the loss curve
            * define an attribute `stddev_loss`, which is a float
              describing the standard deviation of losses if the loss curve
              has been computed with an event based approach. Otherwise,
              it is None

            All attributes must be defined, except for `loss_ratios` that
            can be `None` since it is optional in the schema.

            Also, `poes`, `losses` and `loss_ratios` values must be indexed
            coherently, i.e.: the loss (and optionally loss ratio) at index
            zero is related to the probability of exceedance at the same
            index.
        """

        _assert_valid_input(data)

        with NRMLFile(self._dest, 'w') as output:
            root = etree.Element("nrml", nsmap=SERIALIZE_NS_MAP)

            for curve in data:
                if self._loss_curves is None:
                    self._create_loss_curves_elem(root)

                loss_curve = etree.SubElement(self._loss_curves, "lossCurve")

                _append_location(loss_curve, curve.location)
                loss_curve.set("assetRef", curve.asset_ref)

                poes = etree.SubElement(loss_curve, "poEs")
                poes.text = " ".join([str(p) for p in curve.poes])

                losses = etree.SubElement(loss_curve, "losses")
                losses.text = " ".join([str(p) for p in curve.losses])

                if curve.loss_ratios is not None:
                    loss_ratios = etree.SubElement(loss_curve, "lossRatios")

                    loss_ratios.text = " ".join(
                        [str(p) for p in curve.loss_ratios])

                losses = etree.SubElement(loss_curve, "averageLoss")
                losses.text = "%.4e" % curve.average_loss

                if curve.stddev_loss is not None:
                    losses = etree.SubElement(loss_curve, "stdDevLoss")
                    losses.text = "%.4e" % curve.stddev_loss

            output.write(
                etree.tostring(root,
                               pretty_print=True,
                               xml_declaration=True,
                               encoding="UTF-8"))