# SOM 1.x script porting guide

Porting computational scripts from SOM 1.x to SOM 2.0 means switching from
Python 2.7 to Python 3 and from TRIQS 1.4 to TRIQS 3.1. This guide covers
only the SOM-specific portion of changes that need to be made. Please, refer to
the official Python
porting guide to learn about
the general language changes introduced in Python 3, such as `print()`

becoming a function instead of a statement, and the new semantics of the integer
division. There is also a page about porting applications to TRIQS 3.0
provided by TRIQS’ developers.

## Python modules

Following a convention change for naming of TRIQS applications, the main Python module of SOM has been renamed.

```
### SOM 1.x ###
from pytriqs.applications.analytical_continuation.som import Som
```

```
### SOM 2.0 ###
from som import Som
```

Functions implementing the statistical analysis of ensembles of spectral functions are collected in a new module,

```
### SOM 2.0 ###
from som.spectral_stats import (spectral_integral,
spectral_avg,
spectral_disp,
spectral_corr)
```

## Construction of the `Som`

object

It is now possible to provide full covariance matrices as an alternative to estimated error bars upon construction of the

`Som`

object.### SOM 1.x ### cont = Som(g, error_bars, kind=kind, norms=norms)

### SOM 2.0 ### cont_eb = Som(g, error_bars, kind=kind, norms=norms) cont_cm = Som(g, cov_matrices, kind=kind, norms=norms, filtering_levels=1e-5)

The optional argument

`filtering_levels`

improves stability of the algorithm when the covariance matrices are used.When continuing fermionic Green’s functions, there is an option to enforce the particle-hole symmetry of the spectrum by passing

`kind="FermionGfSymm"`

instead of`kind="FermionGf"`

.Definition of the integral kernels for

`kind="BosonAutoCorr"`

has been changed: The spectral function \(A(\epsilon)\) is now defined on the whole energy axis instead of \(\epsilon\in[0;\infty[\), while the kernels gained an extra coefficient \(1/2\). It has been observed that the new definition makes the algorithm better reproduce results of the`BosonCorr`

kernels for the same input data. This change has an implication on scripting, both`BosonCorr`

and`BosonAutoCorr`

expect the same normalization constants in`norms`

from now on (with SOM 1.x one had to divide the constants by 2 for`BosonAutoCorr`

).If normalization constants for the

`BosonCorr`

or`BosonAutoCorr`

spectra are not known a priori, they can be estimated from the input data by calling a new utility function`estimate_boson_corr_spectrum_norms()`

.### SOM 2.0 ### from som import estimate_boson_corr_spectrum_norms # Given a correlator of boson-like operators $\chi$ defined on any # supported mesh, return a list of spectrum normalization constants # $\mathcal{N} = \pi \chi(i\Omega = 0)$. norms = estimate_boson_corr_spectrum_norms(chi) cont = Som(chi, error_bars, kind="BosonCorr", norms=norms)

## Deprecation of `Som.run()`

In order to accommodate for new features, method `Som.run()`

has been
declared deprecated, and its functionality has been split between a few new
methods.

### SOM 1.x ### cont.run(**params)### SOM 2.0 ### # Accumulate particular solutions. cont.accumulate(**acc_params) # Compute the final solution using the procedure from SOM 1.x. cont.compute_final_solution(**fs_params) # or # Compute the final solution using the Consistent Constraints procedure # new to SOM 2.0. cont.compute_final_solution_cc(**fscc_params)

Passing `cc_update=True`

to `Som.accumulate()`

will enable the
Consistent constraints update that may speed up search for
better particular solutions. A bunch of `Som.accumulate()`

’s parameters
named `cc_update_*`

give a means to fine-tune behavior of the CC updates.

Calling `Som.accumulate()`

multiple times will incrementally extend the
pool of accumulated particular solutions. `Som.clear()`

will remove
all accumulated solutions.

In SOM 1.x, `Som.run()`

was selecting good particular solutions based on
a criterion established by parameter `adjust_l_good_d`

. With SOM 2.0,
selection of good particular solutions is performed as part of algorithms
implemented in `Som.compute_final_solution()`

and
`Som.compute_final_solution_cc()`

.
They both accept arguments `good_chi_rel`

and `good_chi_abs`

, and
select good solution based on values of the
“goodness of fit” \(\chi^2\)-functional associated
with those solutions. A good solution \(A_j\) must simultaneously satisfy
\(\chi[A_j] \leq\) `good_chi_abs`

and
\(\chi[A_j] \leq \min_{j'}(\chi[A_{j'}])\times\) `good_chi_rel`

.

`Som.compute_final_solution_cc()`

constructs
the final solution using a sophisticated iterative
optimization procedure with many adjustable parameters. It can result in a
smoother spectral function, which can optionally be biased towards a
user-provided default model.

Automatic adjustment of the number of global updates per solution (\(F\)),
which used to be one of `Som.run()`

’s features, is now available as method
`Som.adjust_f()`

.

```
### SOM 2.0 ###
# Adjust the number of global updates.
f = cont.adjust_f(energy_window=(-5, 5))
# Accumulate particular solutions.
cont.accumulate(energy_window=(-5, 5), f=f, **acc_params)
```

## Post-processing of spectral functions

Due to changes in the TRIQS Green’s function library, it is no longer possible
to use the `g << cont`

syntax. Furthermore, information about the high
frequency expansion (tail) coefficients has been separated from Green’s function
container objects. The following snippets show the updated syntax for recovering
the real-frequency versions of observables, reconstructing the imaginary
time/Matsubara frequency/Legendre coefficient data and computing the tail.

```
### SOM 1.x ###
# Recover the real-frequency counterpart of 'g' and its tail.
g_w = GfReFreq(window=energy_window, n_points=n_w, indices=g.indices)
g_w << cont
# Reconstruct the input quantity from the computed spectral function.
g_rec = g.copy()
g_rec << cont
```

```
### SOM 2.0 ###
from som import fill_refreq, compute_tail, reconstruct
# Recover the real-frequency counterpart of 'g'.
g_w = GfReFreq(window=energy_window, n_points=n_w, indices=g.indices)
fill_refreq(g_w, cont)
# Compute the tail of 'g_w'.
tail = compute_tail(tail_max_order, cont)
# Reconstruct an observable from the computed spectral function.
g_rec = g.copy()
reconstruct(g_rec, cont)
```

By default, `fill_refreq()`

uses binning, which can be
disabled by passing `with_binning=False`

.

## Direct access to spectral functions

A few new attributes added to `Som`

give access to the accumulated
particular solutions, the final solution and their respective values of the
\(\chi^2\)-functional.

```
### SOM 2.0 ###
# Extract a list of pairs (accumulated particular solution, its \chi^2) for
# the 0-th diagonal component of the observable.
# This list is local to the calling MPI rank.
part_sols_with_chi2 = cont.particular_solutions(0)
# Minimum of \chi^2 over all accumulated particular solutions
# on all MPI ranks.
chi2_min = cont.objf_min
# List of final solutions, one element per diagonal component of
# the observable.
final_sols = cont.solutions
# List of \chi^2 values for the final solutions, one element per diagonal
# component of the observable.
chi2_final = cont.objf_list
```

All solutions extracted this way are instances of a new class
`Configuration`

, which is a collection of `Rectangle`

’s.
Configurations (spectral functions) can be iterated over, evaluated at a given
value of energy, stored to/loaded from an
HDF5 archive.