# Ring Corrections¶

The following documentation has been extracted automatically from the comments found in the source code. Discard Parameters. object variable.

class Parameters_module.Parameters

The input variables are read from the input file. The input file is written with python syntax. The Input file is interpreted as python after a preprocessing The preprocessing was introduced at the time of HST-> PYHST transition to maintaing compatibility with:

• NO/YES meaning 0/1

• items containing FILE in their name can be initialized without using the “” which are otherwise necessary for strings

The input file has to set (some of) the following variables. To setup easily an input file you are suggested to start from one of the examples given in the doc.

DOUBLEFFCORRECTION_ONTHEFLY = 0

This parameter is similar to DOUBLEFFCORRECTION, but the double flat field is computed on the fly. Mind that if DOUBLEFFCORRECTION_ONTHEFLY > 0, then we should have DOUBLEFFCORRECTION = 0. In the current version, this parameter does not work for helical tomography.

If DOUBLEFFCORRECTION_ONTHEFLY is not zero, all the projections are averaged. A file “projectionsmean.edf” is generated. This file is used as a double flat-field correction.

If FF2_SIGMA > 0, the average is high-pass filtered, where the filter is a complementary Gaussian function of STD FF2_SIGMA. A file “projectionsmean_filt.edf” is generated. This filtered average is used as a double flat field instead of the plain average.

DO_RING_FILTER = 0

When this option is on (1) a filtering is applied to the sinogramme trying to remove ring artefacts. This options was previously named DO_SINO_FILTER in pyhst1. The old names for this option are still compatible.

FF2_SIGMA = 0.0

This parameter is relevant for DOUBLEFFCORRECTION_ONTHEFLY > 0. If FF2_SIGMA > 0, the average of the projections is high-pass filtered, where the filter is a complementary Gaussian function of STD FF2_SIGMA. This filtered average is used as a double flat field instead of the plain average.

FW_FILTERPARAM = 0.0

If not null, The “row sum” (explained above) is filtered to only keep the high frequencies. The high pass filter has the form 1-exp(-nu/FW_FILTERPARAM) where mu = 0, …, 0.5 is the frequency vector normlized to 0.5. The Python equivalent code is:

Rowsum = sino.sum(axis=0) Rowsum_filtered = np.fft.irfft(np.fft.rfft(Rowsum)*(1-np.exp(-nu/FW_FILTERPARAM))) sino -= Rowsum_filtered/FW_SCALING

The higher FW_FILTERPARAM, the more low frequencies are kept. A good value is 0.01.

FW_LEVELS = 0

Wavelets decomposition levels for the Fourier-Wavelet destriping algorithm. 0 means that the de-striper is disabled.

FW_SCALING = 0.0

If not null, the following process is applied on the sinogram. The sum of the sinogram along the columns is computed. This “sum line”, divided by FW_SCALING, is then substracted from each sinogram row. The Python equivalent code is:

Rowsum = sino.sum(axis=0) sino -= Rowsum/FW_SCALING

If the Munch filter is enabled (FW_LEVELS > 0), this process is done before the Munch filter.

FW_SIGMA = 1.0

Gaussian std for the Fourier-Wavelets dampening factor

FW_WNAME = 'db15'

Wavelet name for the Fourier-Wavelets sinogram de-striping algorithm

RING_FILTER = ''
This variable is a string and is meaningful when DO_RING_FILTER=1
• RING_FILTER = “RING_Filter”

in this case the sinogram is averaged over all the projections. A high-band pass filter is applied to the average and the result is substracted from all the projections. The details of the frequencies filtering are specified through variable RING_FILTER_PARA

• RING_FILTER = “RING_Filter_THRESHOLDED”

This case is similar to the previous one. But the averaging is done not on the sinogram itself, instead we reconstruct first the slice, we threshold the most intense part of the slice, and the thresholded part of the slice is projected out from the sinogram before averaging.

• RING_FILTER = “RING_Filter_SG”

A Savitsky-Golay filtering by Dominique Bernard. But the documentation still needs to be written

RING_FILTER_PARA = {}
• A typical setup in case of RING_FILTER = “RING_Filter”

ar = numpy.ones(1300,'f')
ar[0]=0.0
RING_FILTER_PARA = {"FILTER": ar}


in this case one suppose that the sinogram has 1300 pixels. The FFT has therefore 1300 frequencie and the ar array must provide all the factors to the pass or not these frequencies. In the above case one lets all the frequencies except the fundamental.

Other forms of filtering can be customized using numpy arrays

ar = numpy.ones(1300,'f')
ar[0]=0.0
xx=numpy.arange(600-2)
ar[2:600]=1.0/(1+numpy.exp((2-xx)/5.0)   )


the frequency layout is the same as in the original HST code : ar[0] the fundamental, ar[1] the highest frequency. Then two by two the sin and cos with increasing frequency.

• in the RING_FILTER = “RING_Filter” case the RING_FILTER_PARA dictionary must be completed with the threshold value

RING_FILTER_PARA = {"FILTER": ar, "threshold":0.15 }


*The following items are operative only with iterative methods

class Parameters_module.Parameters

The input variables are read from the input file. The input file is written with python syntax. The Input file is interpreted as python after a preprocessing The preprocessing was introduced at the time of HST-> PYHST transition to maintaing compatibility with:

• NO/YES meaning 0/1

• items containing FILE in their name can be initialized without using the “” which are otherwise necessary for strings

The input file has to set (some of) the following variables. To setup easily an input file you are suggested to start from one of the examples given in the doc.

DO_DUMP_HRINGS = 0

For debugging iterative rings corrections : if 1 dumps at each iteration the corrections on a raw file rings.dat

INTERVALS_HRINGS = array([ 0, 10000000], dtype=int32)

A flat list of intervals where the rings correction are kept. For difficult cases it may be useful to restrain them.

ITER_RING_BETA = 0.0

L1 penalisation of rings correction

ITER_RING_HEIGHT = 0.0

Maximum height for rings correction, let it to zero if you want no rings correction. or very high value if you want them conpletely free.

ITER_RING_SIZE = 0.0

(for Dictionary Learning only) estimated width of the rings

RING_ALPHA = 1.0

Variable change in rings