Release notes v3.6#
This release features several major new features (including completely revised disaggregation, automatic optimization of duplicated sources, fast exposure importer and taxonomy mapping) and lots of improvements, new checks and bug fixes. Nearly 200 pull requests were merged. For the complete list of changes, see the changelog: https://github.com/gem/oq-engine/blob/engine-3.6/debian/changelog
Disaggregation#
The most relevant development on the hazard side was the work on the
disaggregation calculator. We changed substantially the business
logic. While in previous versions of the engine we were disaggregating
for all possible realizations in order to compute disaggregation
statistics, in this version we gave up on statistics. Instead, we
disaggregate only for a specific realization. The realization can be
specified by the user with the rlz_index
parameter in the job.ini
file, or it can be determined automatically by the engine as the
realization closest to the mean curve for the given disaggregation
site.
Moreover, now the disaggregation calculation works like a post-calculator
(i.e. with the --hc
option) and it is able to reuse information
computed in its parent calculation: the net effect is that it is
always faster than the corresponding classical calculation while in
the past it was several times slower. We also fixed a couple of
performance bugs: there was a slow operation truncnorm.cdf
in an inner loop and ruptures outside the integration distance
were not discarded.
Finally, we changed the file names of the disaggregation outputs.
For models with thousands of realizations, the disaggregation can easily be thousands of times faster than before.
Classical PSHA calculator#
The engine is now smart enough to recognize duplicated sources
appearing in different branches of the composite source model and to
avoid redundant computations. Because this optimization is always on,
the flag optimize_same_id_sources
has been removed, as it has now
been rendered useless. There are several models in the
hazard mosaic with duplicates sources and the new optimization has a
significant impact on those. Moreover the demo LogicTreeCase2ClassicalPSHA
has become an order of magnitude faster than before thanks to the reduction
of the duplicated sources.
There was a big improvement in the computation of the statistical hazard curves which now is not only faster, but uses a lot less memory than before. The trick was to consider one site at the time, instead of a block of sites. As a consequence it is now possible to consider tens of thousands of realizations for hundreds of thousands of sites without requiring terabytes of RAM. Moreover the data transfer has been reduced by storing some auxiliary information in the datastore and reading it from the workers instead of transferring it via celery/rabbitmq.
There was a substantial change in the way the tasks are distributed for a
classical calculation. The engine has acquired the ability to estimate the
runtime of each task and if the estimated time exceeds a task_duration
parameter, the engine is able to split the task in subtasks that run
in less than task_duration
seconds. The user can set the task_duration
manually in the job.ini
, or she can leave it empty; in that case the
engine will figure out a reasonable value for it.
The approach is not perfect since there are non-splittable sources, so
there is a minimum size for a given subtask and sometimes subtasks taking
much longer that the task_duration
parameter may still appear: however,
the new approach is a drastic improvement and the situation was never better
than it is now.
We added a check on sources with a suspiciously large spatial extent (more than 5,000 km) so that a warning is printed. Usually this means that there was a bug in the generation of the source model.
We added a check on sources with suspicious hypo-depths and nodal plane distributions (i.e. distributions with duplicated values) since they make the calculation slower.
In extra-large models saving some debugging information (eg. the number of sites affected by each source) was exceedingly slow, so now the information is stored only if there are fewer than 100,000 relevant sources.
Logic trees#
There was a tricky bug with the minimum_distance
feature
in presence of multiple GSIMs in a logic tree branchset. Now
each GSIMs keeps its own minimum distance; before they were all
getting the same minimum distance, causing wrong results to be computed.
Fortunaly the minimum_distance
feature is rarely used (and only for
internal purposes) so the bug is minor. The feature is documented here:
https://github.com/gem/oq-engine/blob/engine-3.6/doc/adv-manual/special-features.rst#gmpe-logic-trees-with-minimum_distance
We implemented zero weights for intensity measure types that should be discarded in the GSIM logic tree. You can see the relevant documentation here: https://github.com/gem/oq-engine/blob/engine-3.6/doc/adv-manual/special-features.rst#gmpe-logic-trees-with-weighted-imts
We implemented risk logic trees, a.k.a. the taxonomy mapping feature. The idea is that users can map the taxonomy strings in their exposure to one or more vulnerability/fragility functions, with corresponding weights for each function assignment, to take into account the epistemic uncertainty in the exposure ⟷ vulnerability domain. The feature is documented here: https://github.com/gem/oq-engine/blob/engine-3.6/doc/adv-manual/risk-features.rst
A big conceptual change (but with no impact on the user) was
the simplification of the source model logic tree XML file. Before it
was necessary to specify a logicTreeBranchingLevel
node that was
not used internally, now that node is optional. Old
files will keep working, as long as the logicTreeBranchingLevel
contains only a single subnode. The case of multiple subnodes is now
correctly flagged as an error. Thanks to the change,
source model logic trees, gsim logic tree, and risk logic trees
are now stored in the same way internally.
Lastly, we fixed a bug in source model logic trees with the options
applyToSources
and applyToBranches
on; in some times a fake error
about the source not being in the source model - even if it actually was -
was raised.
Event based hazard#
We introduced a parameter max_sites_per_gmf
in the job.ini
(only for event_based
calculations that are trying to store
ground motion fields), with a default of 65,536 sites.
A user trying to run an event_based
calculation that has
ground_motion_fields = true
, with more than the number of
sites permitted by max_sites_per_gmf
will now get an early
validation error instead of running out of memory after
several hours of calculations. The max_sites_per_gmf
limit can
be raised beyond the default of 65,536 sites, at the user’s own
responsibility.
We also added a limit of 2**32
events in event based calculations: this is
a hard limit that cannot be raised. If your calculation produces more than
4 billion events, it will need to be be split into smaller calculations.
Such calculations involving billions of ruptures would likely never work anyway,
because it would eventually run out of memory.
We added a check for missing intensity_measure_types
: this avoids
cryptic errors in the middle of the computation of the ground motion fields.
We optimized the rupture sampling procedure for point sources (which includes multi point sources and area sources). The improvement can be quite significant, for instance the generation of ruptures for a large multipoint source for Colombia became 30x faster using 12x less memory.
We changed the way ruptures are stored internally: the
code
field in the ruptures
dataset is now a unique checksum
depending on the kind of rupture. Before it was an incremental
number depending on the order of the Python module imports which
was making debugging difficult.
The rupture CSV exporter has been enhanced, and now it exports the rupture surface boundaries as 3D multipolygons instead of 2D multipolygons.
We fixed a small bug in the rupture XML exporter, which was failing if the user did not specify the hazard sites.
We added the ability to generate hazard curves without storing the GMFs, simply by setting the flags
hazard_curves_from_gmfs = true
ground_motion_fields = false
This is useful when one is interested in the hazard curves generated
by an event_based
calculation but not in the ground motion fields
themselves. Not storing the GMFs reduces the data transfer and the
memory occupation.
In engine 3.5 we changed the gmf_data
CSV exporter to export a file
sitemodel.csv
instead of the file sitemesh.csv
. That change has
been reverted because it was generating confusion. The right way to
to export the site model information for the most recently completed
calculation - which works for all calculators,
not only for event based - is to use the command
oq show sitecol > sitecol.csv
Importing GMFs from CSV has been enhanced and now it does not require
anymore the field rlzi
: previously, this was a required field,
but it was assumed to contain always the value 0
. On the other hand,
now the GMF exporter to CSV does not export the field rlzi
, because
it is redundant: the association between events and realizations can
be found in the events table and it is exported in the
file sigma_epsilon.csv
.
In the sigma_epsilon.csv
file, we renamed the field eid
to
event_id
in order to avoid confusion with the naming used in the
gmf_data.csv
file (event_id
is the 64 bit event ID in the events
table in the datastore, eid
is the 32 bit index to the event ID
record).
Event based risk#
There was a huge refactoring of all risk calculators. As a consequence
the event_based_risk
calculator has become simpler and faster than before
(twice as fast in some cases).
In the ebrisk
calculator it is now possible to aggregate by asset_id
and therefore to produce individual loss curves and maps for each asset.
Needless to mention, this is only viable for exposures of manageable size.
There was some work to make the losses_by_event
exporter for the
ebrisk
calculator more similar to the ones for event_based_risk
and for scenario_risk
.
We fixed a bug in the agg_curves-rlzs
and agg_curves-stats
outputs
in ebrisk
: they were missing the units
compared to the same outputs
coming from the event_based_risk
calculator. This was breaking the QGIS
plugin.
We changed the agglosses
exporter in
scenario_risk
calculations, by adding a column with the realization index.
The agg_curves
exporter for event based risk was broken if the exposure
was imported in the parent calculation and not in the child calculation.
We fixed a bug in the exporter of the aggregate loss curves coming
from an ebrisk
calculation: now the loss ratios are computed
correctly even in presence of occupants. Before the exporter was
writing incorrect loss ratios to the output file.
Hazardlib#
Graeme Weatherill (@g-weatherill) contributed a finite rupture option to the Germany-adjusted Cauzzi and Derras GMPEs. Moreover, he contributed the Tromans et al. (2019) adjustable GMPE, used for a nuclear power plant in the UK.
Chris van Houtte (@cvanhoutte) contributed the Van Houtte et al. (2018) Significant duration model for New Zealand.
Robin Gee (@rcgee) fixed a bug in the GMPE Sharma (2009): there was a key error if the intensity measure level specified in the job.ini included periods that required interpolation.
Marco Pagani (@mmpagani) discovered a bug in calc_hazard_curves
which was failing with a cryptic
AttributeError: 'NoneType' object has no attribute 'within_bbox'
when used in parallel mode. It has been fixed.
Risk#
The CSV importer for the exposure has been optimized. Before, for legacy reasons, the importer was converting the CSV records into node objects similar to the ones coming from the XML importer and then it was reusing the XML logic. Now we are doing the opposite: the XML importer is producing records and reusing the logic of the CSV importer. Thanks to this change for large CSV exposure the new importer is 4-5 times faster and uses over 10 times less memory than before.
Since a long time ago the engine has the ability to reduce the hazard site collection (which can be large, think of a fine grid) only to the locations where there are assets. Such feature has been optimized in this release, up to a spectacular extent in some cases: we measured a speedup from 2h to 0.1s for Canada.
We changed how zipped exposures are managed by the engine. In version
3.5 a zipped exposure was expected to contain an XML file with the
same name of the archive, apart from the extension. Because of that
the job.ini
file had to contain a line exposure_file = <exposure_path>.xml
while now it requires a line exposure_file = <exposure_path>.zip
, which is clearer. The change was requested by
the risk team in the context of the CRAVE project because it
simplifies the unzipping of the exposure. Unzipping will overwrite
files of the same name already present, but a warning will be printed
and the original files will be not lost, but renamed with a .bak
extension.
We added a consistency check between statistics for calculations
leveraging the --hc
option, because some users were making mistakes
like trying to compute means in the child calculation without having them
in the parent calculation. Now one gets a clear error message.
We fixed a bug in classical_damage
from CSV with discrete
fragility functions: for hazard intensity measure levels different
from the fragility levels, the engine was giving incorrect results.
Vulnerability functions with the beta distribution must satisfy some consistency requirements if the coefficients of variation are nonzero. Unfortunately the consistency check were missing and it was possible to accept invalid functions raising and error in the middle of the computation. Now the error will be raised much early, at the time of the instantiating the vulnerability functions. See #4841 for more details.
Hyeuk Ryu (@dynaryu) discovered a bug in the agg_loss-curves
outputs
for the event_based_risk
calculators, which has been fixed.
Finally there were some improvements to the multi_risk
calculator in the
context of the CRAVE project. In particular now the engine is able
to manage the geometries of volcanic perils like lava, lahar and pyroclastic
flow and it is also able to manage other binary perils without requiring
the introduction of new intensity measure types.
General changes#
The CSV exporters have been enhanced: now there is an additional line
before the header, starting with a #
character, containing some
metadata, like the date when the file the generated, the version of
the engine that generated it, and some relevant parameters, like the
investigation time in the case of the hazard outputs. In the future
we may add even more metadata and extend the approach to other outputs.
Before release 3.3, the engine had the ability to associate site
model parameters to hazard sites on a grid. This feature was sometimes
buggy and removed, by recommending to the users the command oq prepare_site_model
instead. oq prepare_site_model
is able to
produce a site_model.csv
file with sites on the grid and it performs the
associations explicitly, once and for all.
In this release, we restored the ability to perform the association
directly in the engine. This is less efficient than using oq prepare_site_model
, since the same associations will be recomputed during
each run. It is still useful for people wanting to experiment with the
grid spacing: they can run several calculations and when they are
happy with the grid spacing, run oq prepare_site_model
and fix the
site model once and for all with the preferred grid spacing.
We fixed a performance regression in the ucerf_classical
calculator,
due to a change of logic in engine 3.5, which was trying to filter
thousands of sources in the controller node instead than in the
workers, thus becoming extra-slow.
We decided to change the realizations.csv
output for scenario calculations,
by replacing the branch_path
field with the GSIM representation. This is
more informative for the users and more convenient for the QGIS plugin too.
IT#
The job queue first introduced in engine-3.5 is now enabled by default. This means than only on job can run at a given time for a given engine instance.
The progress report has been improved: before in large classical calculations the progress started to be printed too late, even days after the start of the calculation.
We improved the oq abort
command to remove submitted jobs too.
Deleting a calculation in the engine has always been tricky in the case
of multiple users. In this release we fixed several issues and now an
user can delete all of her calculations with the command oq reset
.
The engine will look inside the database and correctly remove the
calculations of the user, including all the relevant .hdf5 files.
We improved the oq plot
command by adding several new kinds of plot.
They are still for internal use only (i.e. introspection and debugging).
We extended the command oq db
to run generic queries for the
openquake
user. Other users can only run SELECT
queries.
There was a bug in oq webui start
not supplying the --noreload
argument that has been fixed (the reload functionality of the Django
development server interferes with SIGCHLD and causes zombies).
We fixed another bug with the --hc
functionality in a multi-user
situation, due to the fact that the engine was searching the the datastore
of the parent calculation in the wrong directory.
There is now a better error message if the shared directory is not mounted.
Source models can now be serialized in TOML format, which is useful for debugging purposes.
Libraries and Python 3.7#
In this releases we updated some of our libraries (numpy from version 1.14 to 1.16 and scipy from version 1.0.1 to 1.3.0) to make it possible to use the engine with Python 3.7. We actually have a cluster using Python 3.7 in production.
In the future we may distribute installers for Windows and macOS based on Python 3.7, but for the moment Python 3.6 is still the only officially supported version and we not plan to abandon Python 3.6 any time soon.
We raised the minimum version for h5py from 2.8.0 to 2.9.0, fixed some compatibility issue with Django 2.1 and 2.2 and fixed several Python 3.7 deprecation warnings. Finally we removed the external dependency from the mock module since it is included in the standard library since Python 3.3.
Deprecations/removals#
For years the engine has been able to import ground motion fields and hazard curves in CSV format and NRML format, with the NRML format deprecated. Now finally the NRML importers have been removed.
There was an old deprecated GMF exporter in NRML format for scenario calculations. It has been finally deprecated. You should use the CSV exporter thas has been available for years instead.
We deprecated the XML disaggregation exporters in favor of the CSV exporters.
We removed the long time deprecated agg_loss_table
exporter since
now all the needed information is in the losses_by_event
exporter.
We switched officially the testing framework from nosetests to pytest.