Release notes v3.20 =================== Version 3.20 is the culmination of 3 months of work involving over 220 pull requests. It is aimed at users wanting the latest features, bug fixes and maximum performance. Users valuing stability may want to stay with the LTS release instead (currently at version 3.16.8). The complete set of changes is listed in the changelog: https://github.com/gem/oq-engine/blob/engine-3.20/debian/changelog A summary is given below. # New Hazard Models Last year we integrated the UCERF3 model inside the USA model by reimplementing it in terms of multifault sources. We recently realized that (non-intuitively) in the case of few intensity measure types the calculation was running out of memory, using more than 4 GB of RAM per core. Solving the issue required a lot of work (over 200 man-hours) on the classical calculator, including changing the internal storage of the multifault sources in HDF5-format, compressing the transferred data, transferring 32 bit rates instead of 64 bit probabilities, storing the rates more efficiently, changing the postprocessing phase producing the statistical hazard curves by taking advantage of the tiling functionality and more. Hower, not the memory usage of the classical calculator, depending on the calculation, is down from 0% to 50%. Moreover, we were able to add support for the 2022 revision of the New Zealand National Seismic Hazard Model ([NZ NSHM 2022](https://nshm.gns.cri.nz/)), which also features multifault sources. While the model had been implemented with the OpenQuake engine from the very beginning, its calculation was extremely challenging and required several tricks for it to run. It is only with engine 3.20 that the calculation runs out-of-the-box and efficiently. Since we improved the way the logic tree is stored in memory and we implemented a better algorithm for computing the means if the parameter `use_rates` is set (we measured a 133x speedup in a calculation with ~260,000 sites) we can now run calculations with millions of realizations. Therefore, it is quite possible to run the New Zealand model - which has "_only_" 979,776 realizations - on a single machine. Computing the quantiles is still impossible in practice, since you will run out of memory during the postprocessing phase. # hazardlib The major thing in hazardlib was a refactoring removing `**kwargs` from the signature of hundreds of GMPEs. As a consequence, now each GMPEs knows the arguments it requires and if there is a typo in the gmpe logic tree file a clear error is raised. Before, any mispelled parameter was silently ignored. In particular, we discovered that in the seismic hazard model for Europe, the parameter `theta6_adjustment` was mispelled as `theta_6_adjustment` and that went unnoticed for years ([#9486](https://github.com/gem/oq-engine/issues/9486)). Most sites are unaffected by the parameter, but some are. If you have an incorrect version of the EUR model now you will immediately get an error ```sh ValueError: FABATaperSFunc.__init__() got an unexpected keyword argument 'theta_6_adjustment' in file EUR/in/gmmLT.xml ``` that you can solve by renaming `theta_6_adjustment` -> `theta6_adjustment` in the file `gmmLT.xml`. We also fixed the passing of parameters in the `NRCan15SiteTerm`, without any impact on the results, since currently all models in the GEM mosaic do not require passing parameters to the underlying GMPE via the `NRCan15SiteTerm`. [Marco Pagani](https://github.com/mmpagani) added a new uncertainty in the logic tree processor, called moment `maxMagGRRelativeNoMoBalance`; an example of usage is in the test logictree/case_84. He also extended the `ChiouYoungs2014` class to accept many optional parameters, notably `use_hw`, `add_delta_c1`, `alpha_nm`, `stress_par_host`, `stress_par_target`, `delta_gamma_tab` as specified by Boore et al. (2022). [Fatemeh Alishahiha](https://github.com/FatemehAlsh) contributed a new class `AbrahamsonSilva1997Vertical` adding a vertical component to the classical Abrahamson Silva GMPE and also an entirely new class `GhasemiEtAl2009` implementing the Ghasemi et Al. GMPE for Iran. # Risk We saved a lot of memory and disk space in conditioned GMFs scenarios, making them also faster in many situations. This is a HUGE improvement since many calculations that before were impossible are now possible. We also improved the error checking for calculations with too many sites. We implemented a first version of Post-Loss Amplification (PLA). The feature is documented, but it is in the experimental stage for the moment. See https://github.com/gem/oq-engine/issues/9633 for more. We fixed the `avg_losses-stats` exporter in the case of a single realization for classical_risk calculation: [#9579](https://github.com/gem/oq-engine/issues/9579) # Bug fixes We fixed a bug when importing a file `gmf_data.csv`: in rare situations with filtered site collections one could end up with site IDs in not present in the site mesh. In the engine, longitude and latitude are rounded to 5 digits. However, sometimes they were rounded by using `numpy.round` and sometimes by using Python round. That causes surprises in rare situations, producing a different a different rounding depending if the sites were listed directly in the `job.ini` file or read from a `sites.csv` file. This has been fixed. We fixed a long standing bug, so that the full logic tree object could not be properly serialized in the datastore in some cases, i.e. when modifying `simpleFaultGeometryAbsolute`, `complexFaultGeometryAbsolute` and `characteristicFaultGeometryAbsolute`). The bug was a low priority since such features are not used in any hazard model in the mosaic, however now it has been finally fixed. Using some special characters in the branchID tags of the source model logic tree caused some tricky errors, as it was happening in the New Zealand model. We have solved the issue by raising an early error if any of the forbidden characters `.:;` is found. When using a magnitude-dependent maximum distance with a missing tectonic region type, the engine was giving a fake error. Now the engine simply ignores the missing tectonic region type if there are no sources associated to it, consistent with the behavior of version 3.16. The mixture-model feature (tested in classical/case_47) was introduced 4 years ago and nearly immediately broken by a refactoring since the test was not actually testing due to a typo. The problem has now been fixed and the feature is working as intended. There was an error when running scenarios with a ModifiableGMPE over a table-based GMPE, since the `mags_by_trt` dictionary was not passed properly. It is now fixed. Finally, we removed two error-prone caches for the gsim logic tree and the exposure, by avoiding the need for them. # New checks In the presence of millions of assets and events, calculating the average losses can send the server out of memory; there is now an early check warning the user of the problem and suggesting a workaround. If the user forgets to specify the `residents` field in the exposure `fieldMap`, there was a clear error message but only after computing the GMFs, i.e. too late. Now the error is raised before starting the calculation. When a required site parameter is not provided, the engine is now raising a clear error message instead of giving NAN results. There were rare situations where complex fault sources were deemed invalid even when correctly specified. This has been fixed in https://github.com/gem/oq-engine/pull/9596. If the user forgets to specify the gsim parameter or the gsim_logic_tree_file parameter in a scenario calculation, he could get a misleading error message. Now the message is very clear. We added a check to forbid having `individual_rlzs=true` and `collect_rlzs=true` at the same time. Before, `collect_rlzs` was automatically set for sampling calculations and overriding `individual_rlzs=true`, in a way very surprising for the final user. Now he gets an error such as ```InvalidFile: you cannot have individual_rlzs=true with collect_rlzs=true``` The `classical_risk` and `classical_damage` calculators are able to start from imported hazard curves stored as CSV files. Such files must contain probabilities, i.e. floats in the range 0 to 1. However, that was not checked, causing NaN values to be generated in the outputs. Now the user gets a clear error message at import time. # Aristotle project [Aristotle](https://www.globalquakemodel.org/proj/aristotle) is a project to provide Multi-Hazard advice to the European Research Coordination Centre in case of disasters. Currently, it is in a development/experimental status and it is meant to be tested but not trusted. To support the needs of the project, the WebUI has grown an APPLICATION_MODE="ARISTOTLE" which allows users to submit a ShakeMap ID and to produce the associated scenario risk outputs by using GEM's exposure, vulnerability functions and ground motion models. The users are automatically notified when the calculations are done (currently for a single ShakeMap ID the engine can perform multiple calculations, since the earthquake can affect countries with different taxonomy mappings). In ARISTOTLE mode, a couple of simple plots are generated: for the moment, one with the (geometric) average GMFs and one with the assets. They are used for debugging and are subject to changes in future versions of the tool. The procedure for downloading the USGS rupture parameters has been enhanced so that if the file "rupture.json" is missing (because the USGS has not generated it yet) the "finite-fault" parameters are used instead. Moreover, it is possible to upload a custom file `rupture_model.xml`, if the user possesses additional or different information than the USGS or is interested in trying alternative models. # `oq` commands We added a command `oq mosaic aristotle`, which is used to run multiple ARISTOTLE calculations in a batch in our automatic tests. We improved the commands `oq info imt` and `oq info gsim`: now it is possible to specify the IMT/GSIM and get information about it (i.e. the docstring of the corresponding class). We improved the command `oq info mfd`, which is now able to also print the docstring of the specified MFD class, and added a command `oq info msr` with similar features for the MSR classes. We improved the command `oq plot avg_gmf`, which is now also displaying country borders. Moreover, it is not showing the seismic stations in case of conditioned GMFs calculations, since they were confusing. We fixed the command `oq zip` that was not zipping the exposure.csv files. The command `oq show delta_loss` has been enhanced and documented in the manual. We now raise a clear `NotImplementedError` when trying to convert griddedSurfaces with the command `oq nrml to csv|gpkg`. # Documentation There was a lot of work on the documentation, in particular about Windows installations and event-based outputs, which were both severely outdated. Many features implemented years ago have been finally documented, including a description of all site parameters, a description of Gridded ruptures, an explanation of the disaggregation outputs and how to convert them into the traditional Bazzurro and Cornell view. A function `calc_gmf_simplified` has been added to explain how GMFs are computed. A demo ScenarioCase3 documenting the new feature `rupture_dict` (introduced in engine-3.19) has been added. # Other There was as usual some work for the [AELO](https://www.globalquakemodel.org/proj/aelo) project. In particular, in AELO mode, we changed the hazard curves and UHS exporters into a format more Excel-friendly, at user request. We added to the WebUI the ability to disable the warning about newer engine releases being available with a flag DISABLE_VERSION_WARNING in ``settings.py``. We added to the WebUI outputs page buttons to display ``avg_gmf`` plots for all the available IMTs. Finally, there were a couple of changes affecting development installations: 1. we introduced a maximum limit of 90 lines of code and 16 arguments per function/method. The limits are enforced by the tests every time a user makes a pull request to the engine repository. They are meant to avoid excessive degradation of the code base quality. 2. at the start of the WebUI a warning is printed if the installed dependencies are different from the expected ones, to point out possible problems while developing.