diff --git a/index.html b/index.html index ee32a9c208..90cc3af5bc 100644 --- a/index.html +++ b/index.html @@ -3,10 +3,10 @@ Redirecting… - - - + + +

Redirecting…

- Click here if you are not redirected. + Click here if you are not redirected. diff --git a/nightly/.buildinfo b/nightly/.buildinfo index 46246c5741..980c786bb2 100644 --- a/nightly/.buildinfo +++ b/nightly/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 17c7ce2270d5a12a22ac5195c0f8f926 -tags: 645f666f9bcd5a90fca523b33c5a78b7 +config: 4fef15476c9cbea3e15a3601839769e4 +tags: d77d1c0d9ca2f4c8421862c7c5a0d620 diff --git a/nightly/.doctrees/developer_guide.doctree b/nightly/.doctrees/developer_guide.doctree index 8807d47368..b56302c007 100644 Binary files a/nightly/.doctrees/developer_guide.doctree and b/nightly/.doctrees/developer_guide.doctree differ diff --git a/nightly/.doctrees/environment.pickle b/nightly/.doctrees/environment.pickle index c7f3c5727c..9fbf4ba721 100644 Binary files a/nightly/.doctrees/environment.pickle and b/nightly/.doctrees/environment.pickle differ diff --git a/nightly/.doctrees/framework.doctree b/nightly/.doctrees/framework.doctree index 8b43750fc5..5510fdf58e 100644 Binary files a/nightly/.doctrees/framework.doctree and b/nightly/.doctrees/framework.doctree differ diff --git a/nightly/.doctrees/index.doctree b/nightly/.doctrees/index.doctree index 3019465ad9..ce0dff3019 100644 Binary files a/nightly/.doctrees/index.doctree and b/nightly/.doctrees/index.doctree differ diff --git a/nightly/.doctrees/introduction.doctree b/nightly/.doctrees/introduction.doctree index 317c52260e..a9ea608efb 100644 Binary files a/nightly/.doctrees/introduction.doctree and b/nightly/.doctrees/introduction.doctree differ diff --git a/nightly/.doctrees/io.doctree b/nightly/.doctrees/io.doctree index 0828f4a2f8..047dcbfe6b 100644 Binary files a/nightly/.doctrees/io.doctree and b/nightly/.doctrees/io.doctree differ diff --git a/nightly/.doctrees/optimisation.doctree b/nightly/.doctrees/optimisation.doctree index f564ff3010..fc3145cd35 100644 Binary files a/nightly/.doctrees/optimisation.doctree and b/nightly/.doctrees/optimisation.doctree differ diff --git a/nightly/.doctrees/plugins.doctree b/nightly/.doctrees/plugins.doctree index fe3b5e9107..37aa741e53 100644 Binary files a/nightly/.doctrees/plugins.doctree and b/nightly/.doctrees/plugins.doctree differ diff --git a/nightly/.doctrees/processors.doctree b/nightly/.doctrees/processors.doctree index 592fb7baf4..dd22ac203f 100644 Binary files a/nightly/.doctrees/processors.doctree and b/nightly/.doctrees/processors.doctree differ diff --git a/nightly/.doctrees/recon.doctree b/nightly/.doctrees/recon.doctree index 9e5ec95129..c55a2cf58d 100644 Binary files a/nightly/.doctrees/recon.doctree and b/nightly/.doctrees/recon.doctree differ diff --git a/nightly/.doctrees/utilities.doctree b/nightly/.doctrees/utilities.doctree index 3ff5a3ab4c..1992ed08e7 100644 Binary files a/nightly/.doctrees/utilities.doctree and b/nightly/.doctrees/utilities.doctree differ diff --git a/nightly/_modules/cil/framework/BlockDataContainer.html b/nightly/_modules/cil/framework/BlockDataContainer/index.html similarity index 79% rename from nightly/_modules/cil/framework/BlockDataContainer.html rename to nightly/_modules/cil/framework/BlockDataContainer/index.html index 7181b33032..203e545ced 100644 --- a/nightly/_modules/cil/framework/BlockDataContainer.html +++ b/nightly/_modules/cil/framework/BlockDataContainer/index.html @@ -1,196 +1,440 @@ + - + + + cil.framework.BlockDataContainer — CIL 23.1.0 documentation - + + + + + - - + + + - - - - + + + + + - - - + + + - - - - - - - - - - - + + - - + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.framework.BlockDataContainer

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -216,7 +460,7 @@ 

Source code for cil.framework.BlockDataContainer

import functools from cil.utilities.multiprocessing import NUM_THREADS -
[docs]class BlockDataContainer(object): +
[docs]class BlockDataContainer(object): '''Class to hold DataContainers as column vector Provides basic algebra between BlockDataContainer's, DataContainer's and @@ -278,11 +522,11 @@

Source code for cil.framework.BlockDataContainer

.format(n_elements, len(args))) -
[docs] def __iter__(self): +
[docs] def __iter__(self): '''BlockDataContainer is Iterable''' self.index=0 return self
-
[docs] def next(self): +
[docs] def next(self): '''python2 backwards compatibility''' return self.__next__()
def __next__(self): @@ -293,7 +537,7 @@

Source code for cil.framework.BlockDataContainer

self.index+=1 return out -
[docs] def is_compatible(self, other): +
[docs] def is_compatible(self, other): '''basic check if the size of the 2 objects fit''' if isinstance(other, Number): @@ -327,7 +571,7 @@

Source code for cil.framework.BlockDataContainer

def __getitem__(self, row): return self.get_item(row) -
[docs] def add(self, other, *args, **kwargs): +
[docs] def add(self, other, *args, **kwargs): '''Algebra: add method of BlockDataContainer with number/DataContainer or BlockDataContainer :param: other (number, DataContainer or subclasses or BlockDataContainer @@ -338,7 +582,7 @@

Source code for cil.framework.BlockDataContainer

self.binary_operations(BlockDataContainer.ADD, other, *args, **kwargs) else: return self.binary_operations(BlockDataContainer.ADD, other, *args, **kwargs)
-
[docs] def subtract(self, other, *args, **kwargs): +
[docs] def subtract(self, other, *args, **kwargs): '''Algebra: subtract method of BlockDataContainer with number/DataContainer or BlockDataContainer :param: other (number, DataContainer or subclasses or BlockDataContainer @@ -349,7 +593,7 @@

Source code for cil.framework.BlockDataContainer

self.binary_operations(BlockDataContainer.SUBTRACT, other, *args, **kwargs) else: return self.binary_operations(BlockDataContainer.SUBTRACT, other, *args, **kwargs)
-
[docs] def multiply(self, other, *args, **kwargs): +
[docs] def multiply(self, other, *args, **kwargs): '''Algebra: multiply method of BlockDataContainer with number/DataContainer or BlockDataContainer :param: other (number, DataContainer or subclasses or BlockDataContainer) @@ -360,7 +604,7 @@

Source code for cil.framework.BlockDataContainer

self.binary_operations(BlockDataContainer.MULTIPLY, other, *args, **kwargs) else: return self.binary_operations(BlockDataContainer.MULTIPLY, other, *args, **kwargs)
-
[docs] def divide(self, other, *args, **kwargs): +
[docs] def divide(self, other, *args, **kwargs): '''Algebra: divide method of BlockDataContainer with number/DataContainer or BlockDataContainer :param: other (number, DataContainer or subclasses or BlockDataContainer) @@ -371,7 +615,7 @@

Source code for cil.framework.BlockDataContainer

self.binary_operations(BlockDataContainer.DIVIDE, other, *args, **kwargs) else: return self.binary_operations(BlockDataContainer.DIVIDE, other, *args, **kwargs)
-
[docs] def power(self, other, *args, **kwargs): +
[docs] def power(self, other, *args, **kwargs): '''Algebra: power method of BlockDataContainer with number/DataContainer or BlockDataContainer :param: other (number, DataContainer or subclasses or BlockDataContainer @@ -382,7 +626,7 @@

Source code for cil.framework.BlockDataContainer

self.binary_operations(BlockDataContainer.POWER, other, *args, **kwargs) else: return self.binary_operations(BlockDataContainer.POWER, other, *args, **kwargs)
-
[docs] def maximum(self, other, *args, **kwargs): +
[docs] def maximum(self, other, *args, **kwargs): '''Algebra: power method of BlockDataContainer with number/DataContainer or BlockDataContainer :param: other (number, DataContainer or subclasses or BlockDataContainer) @@ -393,7 +637,7 @@

Source code for cil.framework.BlockDataContainer

self.binary_operations(BlockDataContainer.MAXIMUM, other, *args, **kwargs) else: return self.binary_operations(BlockDataContainer.MAXIMUM, other, *args, **kwargs)
-
[docs] def minimum(self, other, *args, **kwargs): +
[docs] def minimum(self, other, *args, **kwargs): '''Algebra: power method of BlockDataContainer with number/DataContainer or BlockDataContainer :param: other (number, DataContainer or subclasses or BlockDataContainer) @@ -405,7 +649,7 @@

Source code for cil.framework.BlockDataContainer

else: return self.binary_operations(BlockDataContainer.MINIMUM, other, *args, **kwargs)
-
[docs] def sapyb(self, a, y, b, out, num_threads = NUM_THREADS): +
[docs] def sapyb(self, a, y, b, out, num_threads = NUM_THREADS): r'''performs axpby element-wise on the BlockDataContainer containers Does the operation .. math:: a*x+b*y and stores the result in out, where x is self @@ -434,13 +678,13 @@

Source code for cil.framework.BlockDataContainer

self.binary_operations(BlockDataContainer.SAPYB, y, **kwargs)
-
[docs] def axpby(self, a, b, y, out, dtype=numpy.float32, num_threads = NUM_THREADS): +
[docs] def axpby(self, a, b, y, out, dtype=numpy.float32, num_threads = NUM_THREADS): '''Deprecated method. Alias of sapyb''' return self.sapyb(a,y,b,out,num_threads)
-
[docs] def binary_operations(self, operation, other, *args, **kwargs): +
[docs] def binary_operations(self, operation, other, *args, **kwargs): '''Algebra: generic method of algebric operation with BlockDataContainer with number/DataContainer or BlockDataContainer Provides commutativity with DataContainer and subclasses, i.e. this @@ -593,7 +837,7 @@

Source code for cil.framework.BlockDataContainer

## unary operations -
[docs] def unary_operations(self, operation, *args, **kwargs ): +
[docs] def unary_operations(self, operation, *args, **kwargs ): '''Unary operation on BlockDataContainer: generic method of unary operation with BlockDataContainer: abs, sign, sqrt and conjugate @@ -669,7 +913,7 @@

Source code for cil.framework.BlockDataContainer

else: return ValueError('Not implemented') -
[docs] def copy(self): +
[docs] def copy(self): '''alias of clone''' return self.clone()
def clone(self): @@ -704,7 +948,7 @@

Source code for cil.framework.BlockDataContainer

def __pow__(self, other): return self.power(other) # reverse operand -
[docs] def __radd__(self, other): +
[docs] def __radd__(self, other): '''Reverse addition to make sure that this method is called rather than the __mul__ of a numpy array @@ -714,7 +958,7 @@

Source code for cil.framework.BlockDataContainer

return self + other
# __radd__ -
[docs] def __rsub__(self, other): +
[docs] def __rsub__(self, other): '''Reverse subtraction to make sure that this method is called rather than the __mul__ of a numpy array @@ -724,7 +968,7 @@

Source code for cil.framework.BlockDataContainer

return (-1 * self) + other
# __rsub__ -
[docs] def __rmul__(self, other): +
[docs] def __rmul__(self, other): '''Reverse multiplication to make sure that this method is called rather than the __mul__ of a numpy array @@ -734,7 +978,7 @@

Source code for cil.framework.BlockDataContainer

return self * other
# __rmul__ -
[docs] def __rdiv__(self, other): +
[docs] def __rdiv__(self, other): '''Reverse division to make sure that this method is called rather than the __mul__ of a numpy array @@ -743,7 +987,7 @@

Source code for cil.framework.BlockDataContainer

''' return pow(self / other, -1)
# __rdiv__ -
[docs] def __rtruediv__(self, other): +
[docs] def __rtruediv__(self, other): '''Reverse truedivision to make sure that this method is called rather than the __mul__ of a numpy array @@ -752,7 +996,7 @@

Source code for cil.framework.BlockDataContainer

''' return self.__rdiv__(other)
-
[docs] def __rpow__(self, other): +
[docs] def __rpow__(self, other): '''Reverse power to make sure that this method is called rather than the __mul__ of a numpy array @@ -761,7 +1005,7 @@

Source code for cil.framework.BlockDataContainer

''' return other.power(self)
-
[docs] def __iadd__(self, other): +
[docs] def __iadd__(self, other): '''Inline addition''' if isinstance (other, BlockDataContainer): for el,ot in zip(self.containers, other.containers): @@ -777,7 +1021,7 @@

Source code for cil.framework.BlockDataContainer

return self
# __iadd__ -
[docs] def __isub__(self, other): +
[docs] def __isub__(self, other): '''Inline subtraction''' if isinstance (other, BlockDataContainer): for el,ot in zip(self.containers, other.containers): @@ -793,7 +1037,7 @@

Source code for cil.framework.BlockDataContainer

return self
# __isub__ -
[docs] def __imul__(self, other): +
[docs] def __imul__(self, other): '''Inline multiplication''' if isinstance (other, BlockDataContainer): for el,ot in zip(self.containers, other.containers): @@ -809,7 +1053,7 @@

Source code for cil.framework.BlockDataContainer

return self
# __imul__ -
[docs] def __idiv__(self, other): +
[docs] def __idiv__(self, other): '''Inline division''' if isinstance (other, BlockDataContainer): for el,ot in zip(self.containers, other.containers): @@ -824,11 +1068,11 @@

Source code for cil.framework.BlockDataContainer

el /= ot return self
# __rdiv__ -
[docs] def __itruediv__(self, other): +
[docs] def __itruediv__(self, other): '''Inline truedivision''' return self.__idiv__(other)
-
[docs] def __neg__(self): +
[docs] def __neg__(self): """ Return - self """ return -1 * self
@@ -843,37 +1087,59 @@

Source code for cil.framework.BlockDataContainer

-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/framework/BlockGeometry.html b/nightly/_modules/cil/framework/BlockGeometry.html deleted file mode 100644 index 679abf16ce..0000000000 --- a/nightly/_modules/cil/framework/BlockGeometry.html +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - - - cil.framework.BlockGeometry — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.framework.BlockGeometry

-# -*- coding: utf-8 -*-
-#  Copyright 2019 United Kingdom Research and Innovation
-#  Copyright 2019 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-import functools
-from cil.framework.BlockDataContainer import BlockDataContainer
-
-
[docs]class BlockGeometry(object): - - RANDOM = 'random' - RANDOM_INT = 'random_int' - - @property - def dtype(self): - return tuple(i.dtype for i in self.geometries) - - '''Class to hold Geometry as column vector''' - #__array_priority__ = 1 - def __init__(self, *args, **kwargs): - '''''' - self.geometries = args - self.index = 0 - shape = (len(args),1) - self.shape = shape - - n_elements = functools.reduce(lambda x,y: x*y, shape, 1) - if len(args) != n_elements: - raise ValueError( - 'Dimension and size do not match: expected {} got {}' - .format(n_elements, len(args))) - -
[docs] def get_item(self, index): - '''returns the Geometry in the BlockGeometry located at position index''' - return self.geometries[index]
- -
[docs] def allocate(self, value=0, **kwargs): - - '''Allocates a BlockDataContainer according to geometries contained in the BlockGeometry''' - - symmetry = kwargs.get('symmetry',False) - containers = [geom.allocate(value, **kwargs) for geom in self.geometries] - - if symmetry == True: - - # for 2x2 - # [ ig11, ig12\ - # ig21, ig22] - - # Row-wise Order - - if len(containers)==4: - containers[1]=containers[2] - - # for 3x3 - # [ ig11, ig12, ig13\ - # ig21, ig22, ig23\ - # ig31, ig32, ig33] - - elif len(containers)==9: - containers[1]=containers[3] - containers[2]=containers[6] - containers[5]=containers[7] - - # for 4x4 - # [ ig11, ig12, ig13, ig14\ - # ig21, ig22, ig23, ig24\ c - # ig31, ig32, ig33, ig34 - # ig41, ig42, ig43, ig44] - - elif len(containers) == 16: - containers[1]=containers[4] - containers[2]=containers[8] - containers[3]=containers[12] - containers[6]=containers[9] - containers[7]=containers[10] - containers[11]=containers[15] - - return BlockDataContainer(*containers)
- - def __iter__(self): - '''BlockGeometry is an iterable''' - return self - - def __next__(self): - '''BlockGeometry is an iterable''' - if self.index < len(self.geometries): - result = self.geometries[self.index] - self.index += 1 - return result - else: - self.index = 0 - raise StopIteration
-
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/framework/BlockGeometry/index.html b/nightly/_modules/cil/framework/BlockGeometry/index.html new file mode 100644 index 0000000000..91e97412d4 --- /dev/null +++ b/nightly/_modules/cil/framework/BlockGeometry/index.html @@ -0,0 +1,603 @@ + + + + + + + + + + + cil.framework.BlockGeometry — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.framework.BlockGeometry

+# -*- coding: utf-8 -*-
+#  Copyright 2019 United Kingdom Research and Innovation
+#  Copyright 2019 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+import functools
+from cil.framework.BlockDataContainer import BlockDataContainer
+
+
[docs]class BlockGeometry(object): + + RANDOM = 'random' + RANDOM_INT = 'random_int' + + @property + def dtype(self): + return tuple(i.dtype for i in self.geometries) + + '''Class to hold Geometry as column vector''' + #__array_priority__ = 1 + def __init__(self, *args, **kwargs): + '''''' + self.geometries = args + self.index = 0 + shape = (len(args),1) + self.shape = shape + + n_elements = functools.reduce(lambda x,y: x*y, shape, 1) + if len(args) != n_elements: + raise ValueError( + 'Dimension and size do not match: expected {} got {}' + .format(n_elements, len(args))) + +
[docs] def get_item(self, index): + '''returns the Geometry in the BlockGeometry located at position index''' + return self.geometries[index]
+ +
[docs] def allocate(self, value=0, **kwargs): + + '''Allocates a BlockDataContainer according to geometries contained in the BlockGeometry''' + + symmetry = kwargs.get('symmetry',False) + containers = [geom.allocate(value, **kwargs) for geom in self.geometries] + + if symmetry == True: + + # for 2x2 + # [ ig11, ig12\ + # ig21, ig22] + + # Row-wise Order + + if len(containers)==4: + containers[1]=containers[2] + + # for 3x3 + # [ ig11, ig12, ig13\ + # ig21, ig22, ig23\ + # ig31, ig32, ig33] + + elif len(containers)==9: + containers[1]=containers[3] + containers[2]=containers[6] + containers[5]=containers[7] + + # for 4x4 + # [ ig11, ig12, ig13, ig14\ + # ig21, ig22, ig23, ig24\ c + # ig31, ig32, ig33, ig34 + # ig41, ig42, ig43, ig44] + + elif len(containers) == 16: + containers[1]=containers[4] + containers[2]=containers[8] + containers[3]=containers[12] + containers[6]=containers[9] + containers[7]=containers[10] + containers[11]=containers[15] + + return BlockDataContainer(*containers)
+ + def __iter__(self): + '''BlockGeometry is an iterable''' + return self + + def __next__(self): + '''BlockGeometry is an iterable''' + if self.index < len(self.geometries): + result = self.geometries[self.index] + self.index += 1 + return result + else: + self.index = 0 + raise StopIteration
+
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/cil/framework/framework.html b/nightly/_modules/cil/framework/framework/index.html similarity index 95% rename from nightly/_modules/cil/framework/framework.html rename to nightly/_modules/cil/framework/framework/index.html index 1399909061..f593d66bbb 100644 --- a/nightly/_modules/cil/framework/framework.html +++ b/nightly/_modules/cil/framework/framework/index.html @@ -1,196 +1,440 @@ + - + + + cil.framework.framework — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.framework.framework

 # -*- coding: utf-8 -*-
 #  Copyright 2018 United Kingdom Research and Innovation
@@ -435,7 +679,7 @@ 

Source code for cil.framework.framework

     
     return msg.format(*args )
 
-
[docs]class ImageGeometry(object): +
[docs]class ImageGeometry(object): RANDOM = 'random' RANDOM_INT = 'random_int' CHANNEL = 'channel' @@ -581,7 +825,7 @@

Source code for cil.framework.framework

         self.dtype = kwargs.get('dtype', numpy.float32)
 
 
-
[docs] def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y=None): +
[docs] def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y=None): ''' Returns a new ImageGeometry of a single slice of in the requested direction. ''' @@ -638,11 +882,11 @@

Source code for cil.framework.framework

         else:
             return 0
         
-
[docs] def clone(self): +
[docs] def clone(self): '''returns a copy of the ImageGeometry''' return copy.deepcopy(self)
-
[docs] def copy(self): +
[docs] def copy(self): '''alias of clone''' return self.clone()
@@ -661,7 +905,7 @@

Source code for cil.framework.framework

             repres += "center : x{0},y{1}\n".format(self.center_x, self.center_y)
 
         return repres
-
[docs] def allocate(self, value=0, **kwargs): +
[docs] def allocate(self, value=0, **kwargs): '''allocates an ImageData according to the size expressed in the instance :param value: accepts numbers to allocate an uniform array, or a string as 'random' or 'random_int' to create a random array or None. @@ -2251,7 +2495,7 @@

Source code for cil.framework.framework

         return False
 
 
-
[docs]class AcquisitionGeometry(object): +
[docs]class AcquisitionGeometry(object): """This class holds the AcquisitionGeometry of the system. Please initialise the AcquisitionGeometry using the using the static methods: @@ -2583,7 +2827,7 @@

Source code for cil.framework.framework

         self.set_centre_of_rotation(offset_x_y0, 'pixels', angle, 'radian')
 
 
-
[docs] def set_angles(self, angles, initial_angle=0, angle_unit='degree'): +
[docs] def set_angles(self, angles, initial_angle=0, angle_unit='degree'): r'''This method configures the angular information of an AcquisitionGeometry object. :param angles: The angular positions of the acquisition data @@ -2598,7 +2842,7 @@

Source code for cil.framework.framework

         self.config.angles = Angles(angles, initial_angle, angle_unit)
         return self
-
[docs] def set_panel(self, num_pixels, pixel_size=(1,1), origin='bottom-left'): +
[docs] def set_panel(self, num_pixels, pixel_size=(1,1), origin='bottom-left'): r'''This method configures the panel information of an AcquisitionGeometry object. @@ -2614,7 +2858,7 @@

Source code for cil.framework.framework

         self.config.panel = Panel(num_pixels, pixel_size, origin, self.config.system._dimension)
         return self
-
[docs] def set_channels(self, num_channels=1, channel_labels=None): +
[docs] def set_channels(self, num_channels=1, channel_labels=None): r'''This method configures the channel information of an AcquisitionGeometry object. :param num_channels: The number of channels of data @@ -2627,7 +2871,7 @@

Source code for cil.framework.framework

         self.config.channels = Channels(num_channels, channel_labels)
         return self
-
[docs] def set_labels(self, labels=None): +
[docs] def set_labels(self, labels=None): r'''This method configures the dimension labels of an AcquisitionGeometry object. :param labels: The order of the dimensions describing the data.\ @@ -2640,7 +2884,7 @@

Source code for cil.framework.framework

         self.dimension_labels = labels
         return self
-
[docs] @staticmethod +
[docs] @staticmethod def create_Parallel2D(ray_direction=[0, 1], detector_position=[0, 0], detector_direction_x=[1, 0], rotation_axis_position=[0, 0], units='units distance'): r'''This creates the AcquisitionGeometry for a parallel beam 2D tomographic system @@ -2662,7 +2906,7 @@

Source code for cil.framework.framework

         AG.config.system = Parallel2D(ray_direction, detector_position, detector_direction_x, rotation_axis_position, units)
         return AG    
-
[docs] @staticmethod +
[docs] @staticmethod def create_Cone2D(source_position, detector_position, detector_direction_x=[1,0], rotation_axis_position=[0,0], units='units distance'): r'''This creates the AcquisitionGeometry for a cone beam 2D tomographic system @@ -2684,7 +2928,7 @@

Source code for cil.framework.framework

         AG.config.system = Cone2D(source_position, detector_position, detector_direction_x, rotation_axis_position, units)
         return AG   
-
[docs] @staticmethod +
[docs] @staticmethod def create_Parallel3D(ray_direction=[0,1,0], detector_position=[0,0,0], detector_direction_x=[1,0,0], detector_direction_y=[0,0,1], rotation_axis_position=[0,0,0], rotation_axis_direction=[0,0,1], units='units distance'): r'''This creates the AcquisitionGeometry for a parallel beam 3D tomographic system @@ -2710,7 +2954,7 @@

Source code for cil.framework.framework

         AG.config.system = Parallel3D(ray_direction, detector_position, detector_direction_x, detector_direction_y, rotation_axis_position, rotation_axis_direction, units)
         return AG            
-
[docs] @staticmethod +
[docs] @staticmethod def create_Cone3D(source_position, detector_position, detector_direction_x=[1,0,0], detector_direction_y=[0,0,1], rotation_axis_position=[0,0,0], rotation_axis_direction=[0,0,1], units='units distance'): r'''This creates the AcquisitionGeometry for a cone beam 3D tomographic system @@ -2771,7 +3015,7 @@

Source code for cil.framework.framework

         AG_2D.config.panel.pixel_size[1] = abs(self.config.system.detector.direction_y[2]) * self.config.panel.pixel_size[1]
         return AG_2D
 
-
[docs] def get_ImageGeometry(self, resolution=1.0): +
[docs] def get_ImageGeometry(self, resolution=1.0): '''returns a default configured ImageGeometry object based on the AcquisitionGeomerty''' num_voxel_xy = int(numpy.ceil(self.config.panel.num_pixels[0] * resolution)) @@ -2790,7 +3034,7 @@

Source code for cil.framework.framework

         return str(self.config)
 
 
-
[docs] def get_slice(self, channel=None, angle=None, vertical=None, horizontal=None): +
[docs] def get_slice(self, channel=None, angle=None, vertical=None, horizontal=None): ''' Returns a new AcquisitionGeometry of a single slice of in the requested direction. Will only return reconstructable geometries. ''' @@ -2815,7 +3059,7 @@

Source code for cil.framework.framework

 
         return geometry_new
-
[docs] def allocate(self, value=0, **kwargs): +
[docs] def allocate(self, value=0, **kwargs): '''allocates an AcquisitionData according to the size expressed in the instance :param value: accepts numbers to allocate an uniform array, or a string as 'random' or 'random_int' to create a random array or None. @@ -2859,7 +3103,7 @@

Source code for cil.framework.framework

         
         return out
-
[docs]class DataContainer(object): +
[docs]class DataContainer(object): '''Generic class to hold data Data is currently held in a numpy arrays''' @@ -2957,7 +3201,7 @@

Source code for cil.framework.framework

             raise ValueError('Unknown dimension {0}. Should be one of {1}'.format(dimension_label,
                              self.dimension_labels))
     
-
[docs] def get_dimension_axis(self, dimension_label): +
[docs] def get_dimension_axis(self, dimension_label): """ Returns the axis index of the DataContainer array if the specified dimension_label(s) match any dimension_labels of the DataContainer or their indices @@ -2984,13 +3228,13 @@

Source code for cil.framework.framework

                             self.dimension_labels, 0, self.ndim))
-
[docs] def as_array(self): +
[docs] def as_array(self): '''Returns the pointer to the array. ''' return self.array
-
[docs] def get_slice(self, **kw): +
[docs] def get_slice(self, **kw): ''' Returns a new DataContainer containing a single slice in the requested direction. \ Pass keyword arguments <dimension label>=index @@ -3018,7 +3262,7 @@

Source code for cil.framework.framework

         else:
             return VectorData(new_array, dimension_labels=dimension_labels_list)
-
[docs] def reorder(self, order=None): +
[docs] def reorder(self, order=None): ''' reorders the data in memory as requested. @@ -3055,7 +3299,7 @@

Source code for cil.framework.framework

         else:
             self.geometry.set_labels(dimension_labels_new)
-
[docs] def fill(self, array, **dimension): +
[docs] def fill(self, array, **dimension): '''fills the internal data array with the DataContainer, numpy array or number provided :param array: number, numpy array or DataContainer to copy into the DataContainer @@ -3212,7 +3456,7 @@

Source code for cil.framework.framework

             repres += "Representation: \n{0}\n".format(self.array)
         return repres
         
-
[docs] def get_data_axes_order(self,new_order=None): +
[docs] def get_data_axes_order(self,new_order=None): '''returns the axes label of self as a list If new_order is None returns the labels of the axes as a sorted-by-key list. @@ -3236,11 +3480,11 @@

Source code for cil.framework.framework

                 raise ValueError('Expecting {0} axes, got {2}'\
                                  .format(len(self.shape),len(new_order)))
-
[docs] def clone(self): +
[docs] def clone(self): '''returns a copy of DataContainer''' return copy.deepcopy(self)
-
[docs] def copy(self): +
[docs] def copy(self): '''alias of clone''' return self.clone()
@@ -3337,7 +3581,7 @@

Source code for cil.framework.framework

         return self.pixel_wise_binary(numpy.minimum, x2=x2, out=out, *args, **kwargs)
 
 
-
[docs] def sapyb(self, a, y, b, out=None, num_threads=NUM_THREADS): +
[docs] def sapyb(self, a, y, b, out=None, num_threads=NUM_THREADS): '''performs a*self + b * y. Can be done in-place Parameters @@ -3527,27 +3771,27 @@

Source code for cil.framework.framework

     def conjugate(self, *args,  **kwargs):
         return self.pixel_wise_unary(numpy.conjugate, *args,  **kwargs)
 
-
[docs] def exp(self, *args, **kwargs): +
[docs] def exp(self, *args, **kwargs): '''Applies exp pixel-wise to the DataContainer''' return self.pixel_wise_unary(numpy.exp, *args, **kwargs)
-
[docs] def log(self, *args, **kwargs): +
[docs] def log(self, *args, **kwargs): '''Applies log pixel-wise to the DataContainer''' return self.pixel_wise_unary(numpy.log, *args, **kwargs)
## reductions -
[docs] def squared_norm(self, **kwargs): +
[docs] def squared_norm(self, **kwargs): '''return the squared euclidean norm of the DataContainer viewed as a vector''' #shape = self.shape #size = reduce(lambda x,y:x*y, shape, 1) #y = numpy.reshape(self.as_array(), (size, )) return self.dot(self)
#return self.dot(self) -
[docs] def norm(self, **kwargs): +
[docs] def norm(self, **kwargs): '''return the euclidean norm of the DataContainer viewed as a vector''' return numpy.sqrt(self.squared_norm(**kwargs))
-
[docs] def dot(self, other, *args, **kwargs): +
[docs] def dot(self, other, *args, **kwargs): '''returns the inner product of 2 DataContainers viewed as vectors. Suitable for real and complex data. For complex data, the dot method returns a.dot(b.conjugate()) ''' @@ -3613,7 +3857,7 @@

Source code for cil.framework.framework

 
             reduction_function(self.as_array(), out=out_arr, axis=axis,  *args, **kwargs)
 
-
[docs] def sum(self, axis=None, out=None, *args, **kwargs): +
[docs] def sum(self, axis=None, out=None, *args, **kwargs): """ Returns the sum of values in the DataContainer @@ -3645,7 +3889,7 @@

Source code for cil.framework.framework

 
         return self._directional_reduction_unary(numpy.sum, axis=axis, out=out, *args, **kwargs)
-
[docs] def min(self, axis=None, out=None, *args, **kwargs): +
[docs] def min(self, axis=None, out=None, *args, **kwargs): """ Returns the minimum pixel value in the DataContainer @@ -3668,7 +3912,7 @@

Source code for cil.framework.framework

         """
         return self._directional_reduction_unary(numpy.min, axis=axis, out=out, *args, **kwargs)
-
[docs] def max(self, axis=None, out=None, *args, **kwargs): +
[docs] def max(self, axis=None, out=None, *args, **kwargs): """ Returns the maximum pixel value in the DataContainer @@ -3691,7 +3935,7 @@

Source code for cil.framework.framework

         """
         return self._directional_reduction_unary(numpy.max, axis=axis, out=out, *args, **kwargs)
-
[docs] def mean(self, axis=None, out=None, *args, **kwargs): +
[docs] def mean(self, axis=None, out=None, *args, **kwargs): """ Returns the mean pixel value of the DataContainer @@ -3761,7 +4005,7 @@

Source code for cil.framework.framework

             return self.as_array()!=other.as_array()
         return self.as_array()!=other      
-
[docs]class ImageData(DataContainer): +
[docs]class ImageData(DataContainer): '''DataContainer for holding 2D or 3D DataContainer''' __container_priority__ = 1 @@ -3817,7 +4061,7 @@

Source code for cil.framework.framework

         super(ImageData, self).__init__(array, deep_copy, geometry=geometry, **kwargs)
                                
 
-
[docs] def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y=None, force=False): +
[docs] def get_slice(self,channel=None, vertical=None, horizontal_x=None, horizontal_y=None, force=False): ''' Returns a new ImageData of a single slice of in the requested direction. ''' @@ -3850,7 +4094,7 @@

Source code for cil.framework.framework

             return ImageData(out.array, deep_copy=False, geometry=geometry_new, suppress_warning=True)                            
-
[docs] def apply_circular_mask(self, radius=0.99, in_place=True): +
[docs] def apply_circular_mask(self, radius=0.99, in_place=True): """ Apply a circular mask to the horizontal_x and horizontal_y slices. Values outside this mask will be set to zero. @@ -3932,7 +4176,7 @@

Source code for cil.framework.framework

             return image_data_out
-
[docs]class AcquisitionData(DataContainer, Partitioner): +
[docs]class AcquisitionData(DataContainer, Partitioner): '''DataContainer for holding 2D or 3D sinogram''' __container_priority__ = 1 @@ -3983,7 +4227,7 @@

Source code for cil.framework.framework

         super(AcquisitionData, self).__init__(array, deep_copy, geometry=geometry,**kwargs)
   
 
-
[docs] def get_slice(self,channel=None, angle=None, vertical=None, horizontal=None, force=False): +
[docs] def get_slice(self,channel=None, angle=None, vertical=None, horizontal=None, force=False): ''' Returns a new dataset of a single slice of in the requested direction. \ ''' @@ -4016,7 +4260,7 @@

Source code for cil.framework.framework

         else:
             return AcquisitionData(out.array, deep_copy=False, geometry=geometry_new, suppress_warning=True)
-
[docs]class Processor(object): +
[docs]class Processor(object): '''Defines a generic DataContainer processor @@ -4055,7 +4299,7 @@

Source code for cil.framework.framework

         else:
             raise KeyError('Attribute {0} not found'.format(name))
     
-
[docs] def set_input(self, dataset): +
[docs] def set_input(self, dataset): """ Set the input data to the processor @@ -4076,7 +4320,7 @@

Source code for cil.framework.framework

                             .format(type(dataset), DataContainer))
-
[docs] def check_input(self, dataset): +
[docs] def check_input(self, dataset): '''Checks parameters of the input DataContainer Should raise an Error if the DataContainer does not match expectation, e.g. @@ -4084,7 +4328,7 @@

Source code for cil.framework.framework

         '''
         raise NotImplementedError('Implement basic checks for input DataContainer')
-
[docs] def get_output(self, out=None): +
[docs] def get_output(self, out=None): """ Runs the configured processor and returns the processed data @@ -4120,7 +4364,7 @@

Source code for cil.framework.framework

             raise TypeError("Input type mismatch: got {0} expecting {1}"\
                             .format(type(processor), DataProcessor))
         
-
[docs] def get_input(self): +
[docs] def get_input(self): '''returns the input DataContainer It is useful in the case the user has provided a DataProcessor as @@ -4149,7 +4393,7 @@

Source code for cil.framework.framework

         return out
-
[docs]class DataProcessor(Processor): +
[docs]class DataProcessor(Processor): '''Basically an alias of Processor Class''' pass
@@ -4277,7 +4521,7 @@

Source code for cil.framework.framework

         return y
     
 
-
[docs]class VectorData(DataContainer): +
[docs]class VectorData(DataContainer): '''DataContainer to contain 1D array''' @property @@ -4416,7 +4660,7 @@

Source code for cil.framework.framework

                 raise ValueError('Value {} unknown'.format(value))
         return out
 
-
[docs]class DataOrder(): +
[docs]class DataOrder(): ENGINES = ['astra','tigre','cil'] @@ -4470,37 +4714,59 @@

Source code for cil.framework.framework

         
 
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/io/NEXUSDataReader.html b/nightly/_modules/cil/io/NEXUSDataReader/index.html similarity index 74% rename from nightly/_modules/cil/io/NEXUSDataReader.html rename to nightly/_modules/cil/io/NEXUSDataReader/index.html index 8a7babc683..80b1596ee9 100644 --- a/nightly/_modules/cil/io/NEXUSDataReader.html +++ b/nightly/_modules/cil/io/NEXUSDataReader/index.html @@ -1,196 +1,440 @@ + - + + + cil.io.NEXUSDataReader — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.io.NEXUSDataReader

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -223,7 +467,7 @@ 

Source code for cil.io.NEXUSDataReader

     h5pyAvailable = False
 
 
-
[docs]class NEXUSDataReader(object): +
[docs]class NEXUSDataReader(object): """ Create a reader for NeXus files. @@ -241,7 +485,7 @@

Source code for cil.io.NEXUSDataReader

         if self.file_name is not None:
             self.set_up(file_name = self.file_name)
             
-
[docs] def set_up(self, +
[docs] def set_up(self, file_name = None): """ Initialise reader. @@ -281,7 +525,7 @@

Source code for cil.io.NEXUSDataReader

             
         return dimension_labels
 
-
[docs] def get_geometry(self): +
[docs] def get_geometry(self): """ Parse NEXUS file and return acquisition or reconstructed volume parameters, depending on file type. @@ -422,7 +666,7 @@

Source code for cil.io.NEXUSDataReader

 
         return self._geometry
-
[docs] def get_data_scale(self): +
[docs] def get_data_scale(self): """ Parse NEXUS file and return the scale factor applied to compress the dataset. @@ -442,7 +686,7 @@

Source code for cil.io.NEXUSDataReader

 
         return scale
-
[docs] def get_data_offset(self): +
[docs] def get_data_offset(self): """ Parse NEXUS file and return the offset factor applied to compress the dataset. @@ -490,7 +734,7 @@

Source code for cil.io.NEXUSDataReader

 
         return output
         
-
[docs] def read_as_original(self): +
[docs] def read_as_original(self): """ Returns the compressed data from the file. @@ -507,7 +751,7 @@

Source code for cil.io.NEXUSDataReader

         return self.__read_as(dtype)
-
[docs] def read(self): +
[docs] def read(self): """ Returns the uncompressed data as numpy.float32. @@ -529,7 +773,7 @@

Source code for cil.io.NEXUSDataReader

         return output
-
[docs] def load_data(self): +
[docs] def load_data(self): """ Alias of `read`. @@ -553,37 +797,59 @@

Source code for cil.io.NEXUSDataReader

             # return True
 
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/io/NEXUSDataWriter.html b/nightly/_modules/cil/io/NEXUSDataWriter/index.html similarity index 74% rename from nightly/_modules/cil/io/NEXUSDataWriter.html rename to nightly/_modules/cil/io/NEXUSDataWriter/index.html index 53899fb6da..7025923cdf 100644 --- a/nightly/_modules/cil/io/NEXUSDataWriter.html +++ b/nightly/_modules/cil/io/NEXUSDataWriter/index.html @@ -1,196 +1,440 @@ + - + + + cil.io.NEXUSDataWriter — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.io.NEXUSDataWriter

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -225,7 +469,7 @@ 

Source code for cil.io.NEXUSDataWriter

     h5pyAvailable = False
 
 
-
[docs]class NEXUSDataWriter(object): +
[docs]class NEXUSDataWriter(object): ''' Create a writer for NEXUS files. Parameters @@ -247,7 +491,7 @@

Source code for cil.io.NEXUSDataWriter

         if ((data is not None) and (file_name is not None)):
             self.set_up(data = data, file_name = file_name, compression=compression)
         
-
[docs] def set_up(self, +
[docs] def set_up(self, data = None, file_name = None, compression = None): @@ -293,7 +537,7 @@

Source code for cil.io.NEXUSDataWriter

         if (h5pyAvailable == False):
             raise Exception('h5py is not available, cannot write NEXUS files.')
-
[docs] def write(self): +
[docs] def write(self): ''' write dataset to disk @@ -427,37 +671,59 @@

Source code for cil.io.NEXUSDataWriter

                 ds_data.attrs['channel_spacing'] = self.data.geometry.channel_spacing
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/io/NikonDataReader.html b/nightly/_modules/cil/io/NikonDataReader/index.html similarity index 80% rename from nightly/_modules/cil/io/NikonDataReader.html rename to nightly/_modules/cil/io/NikonDataReader/index.html index cc5c500ebd..1f8d914b13 100644 --- a/nightly/_modules/cil/io/NikonDataReader.html +++ b/nightly/_modules/cil/io/NikonDataReader/index.html @@ -1,196 +1,440 @@ + - + + + cil.io.NikonDataReader — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.io.NikonDataReader

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -218,7 +462,7 @@ 

Source code for cil.io.NikonDataReader

 import os
     
         
-
[docs]class NikonDataReader(object): +
[docs]class NikonDataReader(object): '''Basic reader for xtekct files Parameters @@ -519,14 +763,14 @@

Source code for cil.io.NikonDataReader

         
             self._ag.set_labels(labels=['angle', 'vertical', 'horizontal'])
 
-
[docs] def get_geometry(self): +
[docs] def get_geometry(self): ''' Return AcquisitionGeometry object ''' return self._ag
-
[docs] def get_roi(self): +
[docs] def get_roi(self): '''returns the roi''' roi = self._roi_par[:] if self._ag.dimension == '2D': @@ -538,7 +782,7 @@

Source code for cil.io.NikonDataReader

             roidict['axis_{}'.format(i)] = tuple(el)
         return roidict
-
[docs] def read(self): +
[docs] def read(self): ''' Reads projections and returns AcquisitionData with corresponding geometry, @@ -567,42 +811,64 @@

Source code for cil.io.NikonDataReader

         
         return ad
-
[docs] def load_projections(self): +
[docs] def load_projections(self): '''alias of read for backward compatibility''' return self.read()
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/io/RAWFileWriter.html b/nightly/_modules/cil/io/RAWFileWriter/index.html similarity index 58% rename from nightly/_modules/cil/io/RAWFileWriter.html rename to nightly/_modules/cil/io/RAWFileWriter/index.html index 354e46fa1e..a901b89334 100644 --- a/nightly/_modules/cil/io/RAWFileWriter.html +++ b/nightly/_modules/cil/io/RAWFileWriter/index.html @@ -1,196 +1,440 @@ + - + + + cil.io.RAWFileWriter — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.io.RAWFileWriter

 # -*- coding: utf-8 -*-
 #  Copyright 2023 United Kingdom Research and Innovation
@@ -248,7 +492,7 @@ 

Source code for cil.io.RAWFileWriter

     return d.shape, False, d.dtype.str
 
 
-
[docs]class RAWFileWriter(object): +
[docs]class RAWFileWriter(object): ''' Writer to write DataContainer (or subclass AcquisitionData, ImageData) to disk as a binary blob @@ -345,7 +589,7 @@

Source code for cil.io.RAWFileWriter

             data, compression)
         self.compression = compression
 
-
[docs] def write(self): +
[docs] def write(self): '''Write data to disk''' if not os.path.isdir(self.dir_name): os.mkdir(self.dir_name) @@ -383,37 +627,59 @@

Source code for cil.io.RAWFileWriter

             config.write(configfile)
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/io/TIFF.html b/nightly/_modules/cil/io/TIFF/index.html similarity index 85% rename from nightly/_modules/cil/io/TIFF.html rename to nightly/_modules/cil/io/TIFF/index.html index 1064e34a8f..be07698f5d 100644 --- a/nightly/_modules/cil/io/TIFF.html +++ b/nightly/_modules/cil/io/TIFF/index.html @@ -1,196 +1,440 @@ + - + + + cil.io.TIFF — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.io.TIFF

 # -*- coding: utf-8 -*-
 #  Copyright 2020 United Kingdom Research and Innovation
@@ -245,7 +489,7 @@ 

Source code for cil.io.TIFF

     d = {'scale': scale, 'offset': offset}
     utilities.save_dict_to_file(txt, d)
 
-
[docs]class TIFFWriter(object): +
[docs]class TIFFWriter(object): '''Write a DataSet to disk as a TIFF file or stack of TIFF files @@ -321,7 +565,7 @@

Source code for cil.io.TIFF

         self.compression        = compression
 
     
-
[docs] def write(self): +
[docs] def write(self): '''Write data to disk''' if not os.path.isdir(self.dir_name): os.mkdir(self.dir_name) @@ -382,7 +626,7 @@

Source code for cil.io.TIFF

         return zero_padding_string
-
[docs]class TIFFStackReader(object): +
[docs]class TIFFStackReader(object): ''' Basic TIFF reader which loops through all tiff files in a specific @@ -587,7 +831,7 @@

Source code for cil.io.TIFF

             raise ValueError("Unsupported type {}. Expected any of 1 L I I;16 F.".format(mode))
         return dtype
 
-
[docs] def read(self): +
[docs] def read(self): ''' Reads images and return numpy array @@ -737,7 +981,7 @@

Source code for cil.io.TIFF

             raise TypeError("Unsupported Geometry type. Expected ImageGeometry or AcquisitionGeometry, got {}"\
                 .format(type(geometry)))
 
-
[docs] def read_as_ImageData(self, image_geometry): +
[docs] def read_as_ImageData(self, image_geometry): '''reads the TIFF stack as an ImageData with the provided geometry Notice that the data will be reshaped to what requested in the geometry but there is @@ -746,7 +990,7 @@

Source code for cil.io.TIFF

         leads to sensible data.
         '''
         return self._read_as(image_geometry)
-
[docs] def read_as_AcquisitionData(self, acquisition_geometry): +
[docs] def read_as_AcquisitionData(self, acquisition_geometry): '''reads the TIFF stack as an AcquisitionData with the provided geometry Notice that the data will be reshaped to what requested in the geometry but there is @@ -756,7 +1000,7 @@

Source code for cil.io.TIFF

         '''
         return self._read_as(acquisition_geometry)
-
[docs] def read_scale_offset(self): +
[docs] def read_scale_offset(self): '''Reads the scale and offset from a json file in the same folder as the tiff stack This is a courtesy method that will work only if the tiff stack is saved with the TIFFWriter @@ -773,7 +1017,7 @@

Source code for cil.io.TIFF

 
         return (d['scale'], d['offset'])
-
[docs] def read_rescaled(self, scale=None, offset=None): +
[docs] def read_rescaled(self, scale=None, offset=None): '''Reads the TIFF stack and rescales it with the provided scale and offset, or with the ones in the json file if not provided This is a courtesy method that will work only if the tiff stack is saved with the TIFFWriter @@ -801,37 +1045,59 @@

Source code for cil.io.TIFF

         return data
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/io/ZEISSDataReader.html b/nightly/_modules/cil/io/ZEISSDataReader/index.html similarity index 74% rename from nightly/_modules/cil/io/ZEISSDataReader.html rename to nightly/_modules/cil/io/ZEISSDataReader/index.html index 061f6f3d8f..ea5ca4d434 100644 --- a/nightly/_modules/cil/io/ZEISSDataReader.html +++ b/nightly/_modules/cil/io/ZEISSDataReader/index.html @@ -1,196 +1,440 @@ + - + + + cil.io.ZEISSDataReader — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.io.ZEISSDataReader

 # -*- coding: utf-8 -*-
 #  Copyright 2022 United Kingdom Research and Innovation
@@ -226,7 +470,7 @@ 

Source code for cil.io.ZEISSDataReader

 
 logger = logging.getLogger(__name__)
 
-
[docs]class ZEISSDataReader(object): +
[docs]class ZEISSDataReader(object): ''' Create a reader for ZEISS files @@ -266,7 +510,7 @@

Source code for cil.io.ZEISSDataReader

             self.set_up(file_name, roi = roi)
 
 
-
[docs] def set_up(self, +
[docs] def set_up(self, file_name, roi = None): '''Set up the reader @@ -396,7 +640,7 @@

Source code for cil.io.ZEISSDataReader

 
         return metadata
     
-
[docs] def slice_metadata(self,metadata): +
[docs] def slice_metadata(self,metadata): ''' Slices metadata to configure geometry before reading data ''' @@ -450,7 +694,7 @@

Source code for cil.io.ZEISSDataReader

                                     voxel_num_z=slices,
                                     voxel_size_z=voxel_size)
 
-
[docs] def read(self): +
[docs] def read(self): ''' Reads projections and return Acquisition (TXRM) or Image (TXM) Data container ''' @@ -476,13 +720,13 @@

Source code for cil.io.ZEISSDataReader

             return ig_data
-
[docs] def get_geometry(self): +
[docs] def get_geometry(self): ''' Return Acquisition (TXRM) or Image (TXM) Geometry object ''' return self._geometry
-
[docs] def get_metadata(self): +
[docs] def get_metadata(self): '''return the metadata of the file''' return self._metadata
@@ -496,37 +740,59 @@

Source code for cil.io.ZEISSDataReader

         super().__init__(**kwargs)
 
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/io/utilities.html b/nightly/_modules/cil/io/utilities/index.html similarity index 69% rename from nightly/_modules/cil/io/utilities.html rename to nightly/_modules/cil/io/utilities/index.html index fb97428467..b102aa2317 100644 --- a/nightly/_modules/cil/io/utilities.html +++ b/nightly/_modules/cil/io/utilities/index.html @@ -1,196 +1,440 @@ + - + + + cil.io.utilities — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.io.utilities

 # -*- coding: utf-8 -*-
 #  Copyright 2023 United Kingdom Research and Innovation
@@ -353,7 +597,7 @@ 

Source code for cil.io.utilities

         tmp = tmp.astype(dtype)
     return tmp
 
-
[docs]class HDF5_utilities(object): +
[docs]class HDF5_utilities(object): """ Utility methods to read in from a generic HDF5 file and extract the relevant data @@ -384,7 +628,7 @@

Source code for cil.io.utilities

                     print(sep+'\t', '-', key, ':', obj.attrs[key])
 
 
-
[docs] @staticmethod +
[docs] @staticmethod def print_metadata(filename, group='/', depth=-1): """ Prints the file metadata @@ -402,7 +646,7 @@

Source code for cil.io.utilities

             HDF5_utilities._descend_obj(f[group], depth=depth)
-
[docs] @staticmethod +
[docs] @staticmethod def get_dataset_metadata(filename, dset_path): """ Returns the dataset metadata as a dictionary @@ -441,7 +685,7 @@

Source code for cil.io.utilities

 
 
 
-
[docs] @staticmethod +
[docs] @staticmethod def read(filename, dset_path, source_sel=None, dtype=np.float32): """ Reads a dataset entry and returns a numpy array with the requested data @@ -485,7 +729,7 @@

Source code for cil.io.utilities

         return arr 
-
[docs] @staticmethod +
[docs] @staticmethod def read_to(filename, dset_path, out, source_sel=None, dest_sel=None): """ Reads a dataset entry and directly fills a numpy array with the requested data @@ -520,37 +764,59 @@

Source code for cil.io.utilities

             dset.read_direct(out, source_sel, dest_sel)
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/algorithms/ADMM.html b/nightly/_modules/cil/optimisation/algorithms/ADMM/index.html similarity index 51% rename from nightly/_modules/cil/optimisation/algorithms/ADMM.html rename to nightly/_modules/cil/optimisation/algorithms/ADMM/index.html index cf38be4d67..3e300a4e27 100644 --- a/nightly/_modules/cil/optimisation/algorithms/ADMM.html +++ b/nightly/_modules/cil/optimisation/algorithms/ADMM/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.algorithms.ADMM — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.algorithms.ADMM

 # -*- coding: utf-8 -*-
 #  Copyright 2020 United Kingdom Research and Innovation
@@ -215,7 +459,7 @@ 

Source code for cil.optimisation.algorithms.ADMM

import warnings import logging -
[docs]class LADMM(Algorithm): +
[docs]class LADMM(Algorithm): ''' LADMM is the Linearized Alternating Direction Method of Multipliers (LADMM) @@ -257,7 +501,7 @@

Source code for cil.optimisation.algorithms.ADMM

self.set_up(f = f, g = g, operator = operator, tau = tau,\ sigma = sigma, initial=initial) -
[docs] def set_up(self, f, g, operator, tau = None, sigma=1., \ +
[docs] def set_up(self, f, g, operator, tau = None, sigma=1., \ initial=None): logging.info("{} setting up".format(self.__class__.__name__, )) @@ -292,7 +536,7 @@

Source code for cil.optimisation.algorithms.ADMM

logging.info("{} configured".format(self.__class__.__name__, ))
-
[docs] def update(self): +
[docs] def update(self): self.tmp_dir += self.u self.tmp_dir -= self.z @@ -315,42 +559,64 @@

Source code for cil.optimisation.algorithms.ADMM

# update self.u -= self.z
-
[docs] def update_objective(self): +
[docs] def update_objective(self): self.loss.append(self.f(self.x) + self.g(self.operator.direct(self.x)) )
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/algorithms/Algorithm.html b/nightly/_modules/cil/optimisation/algorithms/Algorithm/index.html similarity index 73% rename from nightly/_modules/cil/optimisation/algorithms/Algorithm.html rename to nightly/_modules/cil/optimisation/algorithms/Algorithm/index.html index 647b5e0b83..483cc0607d 100644 --- a/nightly/_modules/cil/optimisation/algorithms/Algorithm.html +++ b/nightly/_modules/cil/optimisation/algorithms/Algorithm/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.algorithms.Algorithm — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.algorithms.Algorithm

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -216,7 +460,7 @@ 

Source code for cil.optimisation.algorithms.Algorithm

import logging import numpy as np -
[docs]class Algorithm(object): +
[docs]class Algorithm(object): '''Base class for iterative algorithms provides the minimal infrastructure. @@ -261,14 +505,14 @@

Source code for cil.optimisation.algorithms.Algorithm

self.logger = None self.__set_up_logger(kwargs.get('log_file', None)) -
[docs] def set_up(self, *args, **kwargs): +
[docs] def set_up(self, *args, **kwargs): '''Set up the algorithm''' raise NotImplementedError()
-
[docs] def update(self): +
[docs] def update(self): '''A single iteration of the algorithm''' raise NotImplementedError()
-
[docs] def should_stop(self): +
[docs] def should_stop(self): '''default stopping criterion: number of iterations The user can change this in concrete implementation of iterative algorithms.''' @@ -283,14 +527,14 @@

Source code for cil.optimisation.algorithms.Algorithm

self.logger.setLevel(logging.INFO) self.logger.addHandler(handler) -
[docs] def max_iteration_stop_criterion(self): +
[docs] def max_iteration_stop_criterion(self): '''default stop criterion for iterative algorithm: max_iteration reached''' return self.iteration > self.max_iteration
def __iter__(self): '''Algorithm is an iterable''' return self -
[docs] def next(self): +
[docs] def next(self): '''Algorithm is an iterable python2 backwards compatibility''' @@ -341,7 +585,7 @@

Source code for cil.optimisation.algorithms.Algorithm

""" pass -
[docs] def get_output(self): +
[docs] def get_output(self): " Returns the current solution. " return self.x
@@ -349,7 +593,7 @@

Source code for cil.optimisation.algorithms.Algorithm

def _provable_convergence_condition(self): raise NotImplementedError(" Convergence criterion is not implemented for this algorithm. ") -
[docs] def is_provably_convergent(self): +
[docs] def is_provably_convergent(self): """ Check if the algorithm is convergent based on the provable convergence criterion. """ return self._provable_convergence_condition()
@@ -358,7 +602,7 @@

Source code for cil.optimisation.algorithms.Algorithm

def solution(self): return self.get_output() -
[docs] def get_last_loss(self, **kwargs): +
[docs] def get_last_loss(self, **kwargs): '''Returns the last stored value of the loss function if update_objective_interval is 1 it is the value of the objective at the current @@ -379,11 +623,11 @@

Source code for cil.optimisation.algorithms.Algorithm

return [ objective, np.nan, np.nan] else: return objective
-
[docs] def get_last_objective(self, **kwargs): +
[docs] def get_last_objective(self, **kwargs): '''alias to get_last_loss''' return self.get_last_loss(**kwargs)
-
[docs] def update_objective(self): +
[docs] def update_objective(self): '''calculates the objective with the current solution''' raise NotImplementedError()
@@ -430,7 +674,7 @@

Source code for cil.optimisation.algorithms.Algorithm

else: raise ValueError('Update objective interval must be an integer >= 0') -
[docs] def run(self, iterations=None, verbose=1, callback=None, **kwargs): +
[docs] def run(self, iterations=None, verbose=1, callback=None, **kwargs): '''run n iterations and update the user with the callback if specified :param iterations: number of iterations to run. If not set the algorithm will @@ -500,7 +744,7 @@

Source code for cil.optimisation.algorithms.Algorithm

self.logger.info(out)
-
[docs] def verbose_output(self, verbose=False): +
[docs] def verbose_output(self, verbose=False): '''Creates a nice tabulated output''' timing = self.timing if len (timing) == 0: @@ -572,37 +816,59 @@

Source code for cil.optimisation.algorithms.Algorithm

return out
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/algorithms/CGLS.html b/nightly/_modules/cil/optimisation/algorithms/CGLS/index.html similarity index 54% rename from nightly/_modules/cil/optimisation/algorithms/CGLS.html rename to nightly/_modules/cil/optimisation/algorithms/CGLS/index.html index c3c7e0472d..310939392a 100644 --- a/nightly/_modules/cil/optimisation/algorithms/CGLS.html +++ b/nightly/_modules/cil/optimisation/algorithms/CGLS/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.algorithms.CGLS — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.algorithms.CGLS

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -216,7 +460,7 @@ 

Source code for cil.optimisation.algorithms.CGLS

import warnings import logging -
[docs]class CGLS(Algorithm): +
[docs]class CGLS(Algorithm): r'''Conjugate Gradient Least Squares algorithm @@ -253,7 +497,7 @@

Source code for cil.optimisation.algorithms.CGLS

if initial is not None and operator is not None and data is not None: self.set_up(initial=initial, operator=operator, data=data, tolerance=tolerance) -
[docs] def set_up(self, initial, operator, data, tolerance=1e-6): +
[docs] def set_up(self, initial, operator, data, tolerance=1e-6): '''initialisation of the algorithm :param operator: Linear operator for the inverse problem @@ -284,7 +528,7 @@

Source code for cil.optimisation.algorithms.CGLS

-
[docs] def update(self): +
[docs] def update(self): '''single iteration''' self.operator.direct(self.p, out=self.q) @@ -308,17 +552,17 @@

Source code for cil.optimisation.algorithms.CGLS

self.normx = self.x.norm()
-
[docs] def update_objective(self): +
[docs] def update_objective(self): a = self.r.squared_norm() if a is numpy.nan: raise StopIteration() self.loss.append(a)
-
[docs] def should_stop(self): +
[docs] def should_stop(self): '''stopping criterion''' return self.flag() or self.max_iteration_stop_criterion()
-
[docs] def flag(self): +
[docs] def flag(self): '''returns whether the tolerance has been reached''' flag = (self.norms <= self.norms0 * self.tolerance) or (self.normx * self.tolerance >= 1) @@ -332,37 +576,59 @@

Source code for cil.optimisation.algorithms.CGLS

-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/algorithms/FISTA.html b/nightly/_modules/cil/optimisation/algorithms/FISTA/index.html similarity index 63% rename from nightly/_modules/cil/optimisation/algorithms/FISTA.html rename to nightly/_modules/cil/optimisation/algorithms/FISTA/index.html index d3ac6e8b5a..8a4e0ec10a 100644 --- a/nightly/_modules/cil/optimisation/algorithms/FISTA.html +++ b/nightly/_modules/cil/optimisation/algorithms/FISTA/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.algorithms.FISTA — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.algorithms.FISTA

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -220,7 +464,7 @@ 

Source code for cil.optimisation.algorithms.FISTA

[docs]class ISTA(Algorithm): +
[docs]class ISTA(Algorithm): r"""Iterative Shrinkage-Thresholding Algorithm, see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a`. @@ -295,7 +539,7 @@

Source code for cil.optimisation.algorithms.FISTA

return self._step_size # Set default step size -
[docs] def set_step_size(self, step_size): +
[docs] def set_step_size(self, step_size): """ Set default step size. """ @@ -312,13 +556,13 @@

Source code for cil.optimisation.algorithms.FISTA

else: self._step_size = step_size
-
[docs] def __init__(self, initial, f, g, step_size = None, **kwargs): +
[docs] def __init__(self, initial, f, g, step_size = None, **kwargs): super(ISTA, self).__init__(**kwargs) self._step_size = None self.set_up(initial=initial, f=f, g=g, step_size=step_size, **kwargs)
-
[docs] def set_up(self, initial, f, g, step_size, **kwargs): +
[docs] def set_up(self, initial, f, g, step_size, **kwargs): """ Set up of the algorithm """ @@ -349,7 +593,7 @@

Source code for cil.optimisation.algorithms.FISTA

logging.info("{} configured".format(self.__class__.__name__, ))
-
[docs] def update(self): +
[docs] def update(self): r"""Performs a single iteration of ISTA @@ -371,11 +615,11 @@

Source code for cil.optimisation.algorithms.FISTA

self.x_old = self.x self.x = tmp -
[docs] def get_output(self): +
[docs] def get_output(self): " Returns the current solution. " return self.x_old
-
[docs] def update_objective(self): +
[docs] def update_objective(self): """ Updates the objective .. math:: f(x) + g(x) @@ -384,7 +628,7 @@

Source code for cil.optimisation.algorithms.FISTA

self.loss.append( self.f(self.x_old) + self.g(self.x_old) )
-
[docs]class FISTA(ISTA): +
[docs]class FISTA(ISTA): r"""Fast Iterative Shrinkage-Thresholding Algorithm, see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a`. @@ -447,7 +691,7 @@

Source code for cil.optimisation.algorithms.FISTA

""" -
[docs] def set_step_size(self, step_size): +
[docs] def set_step_size(self, step_size): """Set the default step size """ @@ -469,13 +713,13 @@

Source code for cil.optimisation.algorithms.FISTA

def _provable_convergence_condition(self): return self.step_size <= 1./self.f.L -
[docs] def __init__(self, initial, f, g, step_size = None, **kwargs): +
[docs] def __init__(self, initial, f, g, step_size = None, **kwargs): self.y = initial.copy() self.t = 1 super(FISTA, self).__init__(initial=initial, f=f, g=g, step_size=step_size, **kwargs)
-
[docs] def update(self): +
[docs] def update(self): r"""Performs a single iteration of FISTA @@ -520,37 +764,59 @@

Source code for cil.optimisation.algorithms.FISTA

-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/algorithms/GD.html b/nightly/_modules/cil/optimisation/algorithms/GD/index.html similarity index 57% rename from nightly/_modules/cil/optimisation/algorithms/GD.html rename to nightly/_modules/cil/optimisation/algorithms/GD/index.html index ff22097831..5e42ca3149 100644 --- a/nightly/_modules/cil/optimisation/algorithms/GD.html +++ b/nightly/_modules/cil/optimisation/algorithms/GD/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.algorithms.GD — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.algorithms.GD

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -216,7 +460,7 @@ 

Source code for cil.optimisation.algorithms.GD

import warnings import logging -

[docs]class GD(Algorithm): +
[docs]class GD(Algorithm): ''' Gradient Descent algorithm @@ -250,7 +494,7 @@

Source code for cil.optimisation.algorithms.GD

if initial is not None and objective_function is not None : self.set_up(initial=initial, objective_function=objective_function, step_size=step_size) -

[docs] def set_up(self, initial, objective_function, step_size): +
[docs] def set_up(self, initial, objective_function, step_size): '''initialisation of the algorithm :param initial: initial guess @@ -280,7 +524,7 @@

Source code for cil.optimisation.algorithms.GD

self.configured = True logging.info("{} configured".format(self.__class__.__name__, ))

-
[docs] def update(self): +
[docs] def update(self): '''Single iteration''' self.objective_function.gradient(self.x, out=self.x_update) @@ -292,10 +536,10 @@

Source code for cil.optimisation.algorithms.GD

self.x.sapyb(1.0, self.x_update, -self.step_size, out=self.x)

-
[docs] def update_objective(self): +
[docs] def update_objective(self): self.loss.append(self.objective_function(self.x))
-
[docs] def armijo_rule(self): +
[docs] def armijo_rule(self): '''Applies the Armijo rule to calculate the step size (step_size) https://projecteuclid.org/download/pdf_1/euclid.pjm/1102995080 @@ -355,7 +599,7 @@

Source code for cil.optimisation.algorithms.GD

self.kmax = numpy.ceil (2 * numpy.log10(alpha) / numpy.log10(2)) self.k = 0 -

[docs] def should_stop(self): +
[docs] def should_stop(self): return self.max_iteration_stop_criterion() or \ numpy.isclose(self.get_last_objective(), 0., rtol=self.rtol, atol=self.atol, equal_nan=False)
@@ -363,37 +607,59 @@

Source code for cil.optimisation.algorithms.GD

-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/algorithms/PDHG.html b/nightly/_modules/cil/optimisation/algorithms/PDHG/index.html similarity index 76% rename from nightly/_modules/cil/optimisation/algorithms/PDHG.html rename to nightly/_modules/cil/optimisation/algorithms/PDHG/index.html index 72da941f8a..2af09139ff 100644 --- a/nightly/_modules/cil/optimisation/algorithms/PDHG.html +++ b/nightly/_modules/cil/optimisation/algorithms/PDHG/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.algorithms.PDHG — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.algorithms.PDHG

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -220,7 +464,7 @@ 

Source code for cil.optimisation.algorithms.PDHG

-
[docs]class PDHG(Algorithm): +
[docs]class PDHG(Algorithm): r"""Primal Dual Hybrid Gradient (PDHG) algorithm, see :cite:`CP2011`, :cite:`EZXC2010`. @@ -452,7 +696,7 @@

Source code for cil.optimisation.algorithms.PDHG

return self._gamma_fconj -
[docs] def set_gamma_g(self, value): +
[docs] def set_gamma_g(self, value): '''Set the value of the strongly convex constant for function `g` Parameters @@ -473,7 +717,7 @@

Source code for cil.optimisation.algorithms.PDHG

raise ValueError("Positive float is expected for the strongly convex constant of function g, {} is passed".format(value))
-
[docs] def set_gamma_fconj(self, value): +
[docs] def set_gamma_fconj(self, value): '''Set the value of the strongly convex constant for the convex conjugate of function `f` Parameters @@ -494,7 +738,7 @@

Source code for cil.optimisation.algorithms.PDHG

raise ValueError("Positive float is expected for the strongly convex constant of the convex conjugate of function f, {} is passed".format(value))
-
[docs] def set_up(self, f, g, operator, tau=None, sigma=None, initial=None, **kwargs): +
[docs] def set_up(self, f, g, operator, tau=None, sigma=None, initial=None, **kwargs): """Initialisation of the algorithm Parameters @@ -556,12 +800,12 @@

Source code for cil.optimisation.algorithms.PDHG

self.x = tmp -
[docs] def get_output(self): +
[docs] def get_output(self): " Returns the current solution. " return self.x_old
-
[docs] def update(self): +
[docs] def update(self): r""" Performs a single iteration of the PDHG algorithm """ @@ -589,7 +833,7 @@

Source code for cil.optimisation.algorithms.PDHG

self.update_step_sizes()
-
[docs] def check_convergence(self): +
[docs] def check_convergence(self): """ Check whether convergence criterion for PDHG is satisfied with scalar values of tau and sigma Returns @@ -607,7 +851,7 @@

Source code for cil.optimisation.algorithms.PDHG

return False
-
[docs] def set_step_sizes(self, sigma=None, tau=None): +
[docs] def set_step_sizes(self, sigma=None, tau=None): """ Sets sigma and tau step-sizes for the PDHG algorithm. The step sizes can be either scalar or array-objects. Parameters @@ -652,7 +896,7 @@

Source code for cil.optimisation.algorithms.PDHG

raise NotImplementedError("If using arrays for sigma or tau both must arrays must be provided.")
-
[docs] def update_step_sizes(self): +
[docs] def update_step_sizes(self): r""" Updates step sizes in the cases of primal or dual acceleration using the strongly convexity property. The case where both functions are strongly convex is not available at the moment. """ @@ -670,7 +914,7 @@

Source code for cil.optimisation.algorithms.PDHG

self._tau /= self.theta
-
[docs] def update_objective(self): +
[docs] def update_objective(self): """ Evaluates the primal objective, the dual objective and the primal-dual gap. """ @@ -705,37 +949,59 @@

Source code for cil.optimisation.algorithms.PDHG

return [x[2] for x in self.loss]
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/algorithms/SIRT.html b/nightly/_modules/cil/optimisation/algorithms/SIRT/index.html similarity index 58% rename from nightly/_modules/cil/optimisation/algorithms/SIRT.html rename to nightly/_modules/cil/optimisation/algorithms/SIRT/index.html index 098fa3a406..82f0aefeee 100644 --- a/nightly/_modules/cil/optimisation/algorithms/SIRT.html +++ b/nightly/_modules/cil/optimisation/algorithms/SIRT/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.algorithms.SIRT — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.algorithms.SIRT

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -218,7 +462,7 @@ 

Source code for cil.optimisation.algorithms.SIRT

import numpy import logging -
[docs]class SIRT(Algorithm): +
[docs]class SIRT(Algorithm): r"""Simultaneous Iterative Reconstruction Technique, see :cite:`Kak2001`. @@ -289,7 +533,7 @@

Source code for cil.optimisation.algorithms.SIRT

self.set_up(initial=initial, operator=operator, data=data, lower=lower, upper=upper, constraint=constraint) -
[docs] def set_up(self, initial, operator, data, lower=None, upper=None, constraint=None): +
[docs] def set_up(self, initial, operator, data, lower=None, upper=None, constraint=None): """ Initialisation of the algorithm @@ -327,7 +571,7 @@

Source code for cil.optimisation.algorithms.SIRT

def D(self): return self._Dscaled / self._relaxation_parameter -
[docs] def set_relaxation_parameter(self, value=1.0): +
[docs] def set_relaxation_parameter(self, value=1.0): """Set the relaxation parameter :math:`\omega` Parameters @@ -375,7 +619,7 @@

Source code for cil.optimisation.algorithms.SIRT

datacontainer.fill(tmp) -
[docs] def update(self): +
[docs] def update(self): r""" Performs a single iteration of the SIRT algorithm @@ -397,7 +641,7 @@

Source code for cil.optimisation.algorithms.SIRT

# IndicatorBox allows inplace operation for proximal self.constraint.proximal(self.x, tau=1, out=self.x)
-
[docs] def update_objective(self): +
[docs] def update_objective(self): r"""Returns the objective .. math:: \|A x - b\|^{2} @@ -406,37 +650,59 @@

Source code for cil.optimisation.algorithms.SIRT

self.loss.append(self.r.squared_norm())
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/algorithms/SPDHG.html b/nightly/_modules/cil/optimisation/algorithms/SPDHG/index.html similarity index 67% rename from nightly/_modules/cil/optimisation/algorithms/SPDHG.html rename to nightly/_modules/cil/optimisation/algorithms/SPDHG/index.html index 392ce5f539..f98eebda7d 100644 --- a/nightly/_modules/cil/optimisation/algorithms/SPDHG.html +++ b/nightly/_modules/cil/optimisation/algorithms/SPDHG/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.algorithms.SPDHG — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.algorithms.SPDHG

 # -*- coding: utf-8 -*-
 #  Copyright 2020 United Kingdom Research and Innovation
@@ -217,7 +461,7 @@ 

Source code for cil.optimisation.algorithms.SPDHG

import warnings import logging -
[docs]class SPDHG(Algorithm): +
[docs]class SPDHG(Algorithm): r'''Stochastic Primal Dual Hybrid Gradient Problem: @@ -300,7 +544,7 @@

Source code for cil.optimisation.algorithms.SPDHG

initial=initial, prob=prob, gamma=gamma, norms=kwargs.get('norms', None)) -
[docs] def set_up(self, f, g, operator, tau=None, sigma=None, \ +
[docs] def set_up(self, f, g, operator, tau=None, sigma=None, \ initial=None, prob=None, gamma=1., norms=None): '''set-up of the algorithm @@ -373,7 +617,7 @@

Source code for cil.optimisation.algorithms.SPDHG

self.configured = True logging.info("{} configured".format(self.__class__.__name__, ))
-
[docs] def update(self): +
[docs] def update(self): # Gradient descent for the primal variable # x_tmp = x - tau * zbar self.x.sapyb(1., self.zbar, -self.tau, out=self.x_tmp) @@ -408,7 +652,7 @@

Source code for cil.optimisation.algorithms.SPDHG

# save previous iteration self.save_previous_iteration(i, y_k)
-
[docs] def update_objective(self): +
[docs] def update_objective(self): # p1 = self.f(self.operator.direct(self.x)) + self.g(self.x) p1 = 0. for i,op in enumerate(self.operator.operators): @@ -437,37 +681,59 @@

Source code for cil.optimisation.algorithms.SPDHG

self.y_old[index].fill(y_current)
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/BlockFunction.html b/nightly/_modules/cil/optimisation/functions/BlockFunction/index.html similarity index 60% rename from nightly/_modules/cil/optimisation/functions/BlockFunction.html rename to nightly/_modules/cil/optimisation/functions/BlockFunction/index.html index a116b06321..1330c2fa94 100644 --- a/nightly/_modules/cil/optimisation/functions/BlockFunction.html +++ b/nightly/_modules/cil/optimisation/functions/BlockFunction/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.functions.BlockFunction — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.functions.BlockFunction

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -215,7 +459,7 @@ 

Source code for cil.optimisation.functions.BlockFunction

from cil.framework import BlockDataContainer from numbers import Number -
[docs]class BlockFunction(Function): +
[docs]class BlockFunction(Function): r""" BlockFunction represents a *separable sum* function :math:`F` defined as @@ -236,7 +480,7 @@

Source code for cil.optimisation.functions.BlockFunction

""" -
[docs] def __init__(self, *functions): +
[docs] def __init__(self, *functions): super(BlockFunction, self).__init__() self.functions = functions @@ -254,7 +498,7 @@

Source code for cil.optimisation.functions.BlockFunction

break return tmp_L -
[docs] def __call__(self, x): +
[docs] def __call__(self, x): r""" Returns the value of the BlockFunction :math:`F` @@ -275,7 +519,7 @@

Source code for cil.optimisation.functions.BlockFunction

t += self.functions[i](x.get_item(i)) return t
-
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): r"""Returns the value of the convex conjugate of the BlockFunction at :math:`x^{*}`. @@ -294,7 +538,7 @@

Source code for cil.optimisation.functions.BlockFunction

t += self.functions[i].convex_conjugate(x.get_item(i)) return t
-
[docs] def proximal(self, x, tau, out = None): +
[docs] def proximal(self, x, tau, out = None): r"""Proximal operator of the BlockFunction at x: @@ -330,7 +574,7 @@

Source code for cil.optimisation.functions.BlockFunction

[docs] def gradient(self, x, out=None): +
[docs] def gradient(self, x, out=None): r"""Returns the value of the gradient of the BlockFunction function at x. @@ -351,7 +595,7 @@

Source code for cil.optimisation.functions.BlockFunction

return BlockDataContainer(*out)
-
[docs] def proximal_conjugate(self, x, tau, out = None): +
[docs] def proximal_conjugate(self, x, tau, out = None): r"""Proximal operator of the convex conjugate of BlockFunction at x: @@ -388,7 +632,7 @@

Source code for cil.optimisation.functions.BlockFunction

def __getitem__(self, row): return self.functions[row] -
[docs] def __rmul__(self, other): +
[docs] def __rmul__(self, other): '''Define multiplication with a scalar :param other: number @@ -403,37 +647,59 @@

Source code for cil.optimisation.functions.BlockFunction

+ + +
+ + + + +
+ + +
+ - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/Function.html b/nightly/_modules/cil/optimisation/functions/Function/index.html similarity index 77% rename from nightly/_modules/cil/optimisation/functions/Function.html rename to nightly/_modules/cil/optimisation/functions/Function/index.html index df912645c6..7cd0bff6f7 100644 --- a/nightly/_modules/cil/optimisation/functions/Function.html +++ b/nightly/_modules/cil/optimisation/functions/Function/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.functions.Function — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.functions.Function

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -218,7 +462,7 @@ 

Source code for cil.optimisation.functions.Function

from functools import reduce -
[docs]class Function(object): +
[docs]class Function(object): r""" Abstract class representing a function @@ -242,7 +486,7 @@

Source code for cil.optimisation.functions.Function

raise NotImplementedError -
[docs] def gradient(self, x, out=None): +
[docs] def gradient(self, x, out=None): r"""Returns the value of the gradient of function :math:`F` evaluated at :math:`x`, if it is differentiable .. math:: F'(x) @@ -260,7 +504,7 @@

Source code for cil.optimisation.functions.Function

""" raise NotImplementedError
-
[docs] def proximal(self, x, tau, out=None): +
[docs] def proximal(self, x, tau, out=None): r"""Returns the proximal operator of function :math:`\tau F` evaluated at x .. math:: \text{prox}_{\tau F}(x) = \underset{z}{\text{argmin}} \frac{1}{2}\|z - x\|^{2} + \tau F(z) @@ -280,7 +524,7 @@

Source code for cil.optimisation.functions.Function

""" raise NotImplementedError
-
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): r""" Evaluation of the function F* at x, where F* is the convex conjugate of function F, .. math:: F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x) @@ -296,7 +540,7 @@

Source code for cil.optimisation.functions.Function

""" raise NotImplementedError
-
[docs] def proximal_conjugate(self, x, tau, out=None): +
[docs] def proximal_conjugate(self, x, tau, out=None): r"""Returns the proximal operator of the convex conjugate of function :math:`\tau F` evaluated at :math:`x^{*}` .. math:: \text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*}) @@ -375,7 +619,7 @@

Source code for cil.optimisation.functions.Function

def __mul__(self, scalar): return self.__rmul__(scalar) -
[docs] def centered_at(self, center): +
[docs] def centered_at(self, center): """ Returns a translated function, namely if we have a function :math:`F(x)` the center is at the origin. TranslateFunction is :math:`F(x - b)` and the center is at point b. @@ -411,7 +655,7 @@

Source code for cil.optimisation.functions.Function

raise TypeError('The Lipschitz constant is a real positive number')
-
[docs]class SumFunction(Function): +
[docs]class SumFunction(Function): r"""SumFunction represents the sum of :math:`n\geq2` functions @@ -516,7 +760,7 @@

Source code for cil.optimisation.functions.Function

ret += f(x) return ret -
[docs] def gradient(self, x, out=None): +
[docs] def gradient(self, x, out=None): r"""Returns the value of the sum of the gradient of functions evaluated at :math:`x`, if all of them are differentiable. .. math:: (F'_{1} + F'_{2} + ... + F'_{n})(x) = F'_{1}(x) + F'_{2}(x) + ... + F'_{n}(x) @@ -567,7 +811,7 @@

Source code for cil.optimisation.functions.Function

return super(SumFunction, self).__add__(other)
-
[docs]class ScaledFunction(Function): +
[docs]class ScaledFunction(Function): r""" ScaledFunction represents the scalar multiplication with a Function. @@ -635,7 +879,7 @@

Source code for cil.optimisation.functions.Function

""" return self.scalar * self.function(x) -
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): r"""Returns the convex conjugate of the scaled function. .. math:: G^{*}(x^{*}) = \alpha F^{*}(\frac{x^{*}}{\alpha}) @@ -662,7 +906,7 @@

Source code for cil.optimisation.functions.Function

return self.scalar * val
-
[docs] def gradient(self, x, out=None): +
[docs] def gradient(self, x, out=None): r"""Returns the gradient of the scaled function evaluated at :math:`x`. .. math:: G'(x) = \alpha F'(x) @@ -684,7 +928,7 @@

Source code for cil.optimisation.functions.Function

self.function.gradient(x, out=out) out *= self.scalar
-
[docs] def proximal(self, x, tau, out=None): +
[docs] def proximal(self, x, tau, out=None): r"""Returns the proximal operator of the scaled function, evaluated at :math:`x`. .. math:: \text{prox}_{\tau G}(x) = \text{prox}_{(\tau\alpha) F}(x) @@ -705,7 +949,7 @@

Source code for cil.optimisation.functions.Function

return self.function.proximal(x, tau*self.scalar, out=out)
-
[docs] def proximal_conjugate(self, x, tau, out=None): +
[docs] def proximal_conjugate(self, x, tau, out=None): r"""This returns the proximal conjugate operator for the function at :math:`x`, :math:`\tau` Parameters @@ -742,7 +986,7 @@

Source code for cil.optimisation.functions.Function

return val
-
[docs]class SumScalarFunction(SumFunction): +
[docs]class SumScalarFunction(SumFunction): """ SumScalarFunction represents the sum a function with a scalar. @@ -765,7 +1009,7 @@

Source code for cil.optimisation.functions.Function

self.constant = constant self.function = function -
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): r""" Returns the convex conjugate of a :math:`(F+scalar)`, evaluated at :math:`x`. .. math:: (F+scalar)^{*}(x^{*}) = F^{*}(x^{*}) - scalar @@ -781,7 +1025,7 @@

Source code for cil.optimisation.functions.Function

""" return self.function.convex_conjugate(x) - self.constant
-
[docs] def proximal(self, x, tau, out=None): +
[docs] def proximal(self, x, tau, out=None): """ Returns the proximal operator of :math:`F+scalar` .. math:: \text{prox}_{\tau (F+scalar)}(x) = \text{prox}_{\tau F} @@ -816,7 +1060,7 @@

Source code for cil.optimisation.functions.Function

super(SumScalarFunction, self.__class__).L.fset(self, value)
-
[docs]class ConstantFunction(Function): +
[docs]class ConstantFunction(Function): r""" ConstantFunction: :math:`F(x) = constant, constant\in\mathbb{R}` @@ -830,7 +1074,7 @@

Source code for cil.optimisation.functions.Function

""" Returns the value of the function, :math:`F(x) = constant`""" return self.constant -
[docs] def gradient(self, x, out=None): +
[docs] def gradient(self, x, out=None): """ Returns the value of the gradient of the function, :math:`F'(x)=0` Parameters ---------- @@ -848,7 +1092,7 @@

Source code for cil.optimisation.functions.Function

else: out.fill(0)
-
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): r""" The convex conjugate of constant function :math:`F(x) = c\in\mathbb{R}` is .. math:: @@ -878,7 +1122,7 @@

Source code for cil.optimisation.functions.Function

""" return x.maximum(0).sum()
-
[docs] def proximal(self, x, tau, out=None): +
[docs] def proximal(self, x, tau, out=None): r"""Returns the proximal operator of the constant function, which is the same element, i.e., .. math:: \text{prox}_{\tau F}(x) = x @@ -923,7 +1167,7 @@

Source code for cil.optimisation.functions.Function

return ConstantFunction(constant)
-
[docs]class ZeroFunction(ConstantFunction): +
[docs]class ZeroFunction(ConstantFunction): """ ZeroFunction represents the zero function, :math:`F(x) = 0` """ @@ -932,7 +1176,7 @@

Source code for cil.optimisation.functions.Function

super(ZeroFunction, self).__init__(constant=0.)
-
[docs]class TranslateFunction(Function): +
[docs]class TranslateFunction(Function): r""" TranslateFunction represents the translation of function F with respect to the center b. @@ -987,7 +1231,7 @@

Source code for cil.optimisation.functions.Function

return val -
[docs] def gradient(self, x, out=None): +
[docs] def gradient(self, x, out=None): r"""Returns the gradient of the translated function. .. math:: G'(x) = F'(x - b) @@ -1020,7 +1264,7 @@

Source code for cil.optimisation.functions.Function

if out is None: return val
-
[docs] def proximal(self, x, tau, out=None): +
[docs] def proximal(self, x, tau, out=None): r"""Returns the proximal operator of the translated function. .. math:: \text{prox}_{\tau G}(x) = \text{prox}_{\tau F}(x-b) + b @@ -1057,7 +1301,7 @@

Source code for cil.optimisation.functions.Function

if out is None: return val
-
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): r"""Returns the convex conjugate of the translated function. .. math:: G^{*}(x^{*}) = F^{*}(x^{*}) + <x^{*}, b > @@ -1076,37 +1320,59 @@

Source code for cil.optimisation.functions.Function

+ + +
+ + + + +
+ + +
+ - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/IndicatorBox.html b/nightly/_modules/cil/optimisation/functions/IndicatorBox/index.html similarity index 78% rename from nightly/_modules/cil/optimisation/functions/IndicatorBox.html rename to nightly/_modules/cil/optimisation/functions/IndicatorBox/index.html index 29c039f649..e53f145c62 100644 --- a/nightly/_modules/cil/optimisation/functions/IndicatorBox.html +++ b/nightly/_modules/cil/optimisation/functions/IndicatorBox/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.functions.IndicatorBox — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.functions.IndicatorBox

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -218,7 +462,7 @@ 

Source code for cil.optimisation.functions.IndicatorBox

import logging -
[docs]class IndicatorBox(Function): +
[docs]class IndicatorBox(Function): r'''Indicator function for box constraint .. math:: @@ -310,7 +554,7 @@

Source code for cil.optimisation.functions.IndicatorBox

def suppress_evaluation(self): return self._suppress_evaluation -
[docs] def set_suppress_evaluation(self, value): +
[docs] def set_suppress_evaluation(self, value): '''Suppresses the evaluation of the function Parameters @@ -336,7 +580,7 @@

Source code for cil.optimisation.functions.IndicatorBox

return self.evaluate(x) return 0.0 -
[docs] def proximal(self, x, tau, out=None): +
[docs] def proximal(self, x, tau, out=None): r'''Proximal operator of IndicatorBox at x .. math:: prox_{\tau * f}(x) @@ -370,7 +614,7 @@

Source code for cil.optimisation.functions.IndicatorBox

if should_return: return out
-
[docs] def gradient(self, x): +
[docs] def gradient(self, x): '''IndicatorBox is not differentiable, so calling gradient will raise a ``ValueError``''' return ValueError('Not Differentiable')
@@ -384,7 +628,7 @@

Source code for cil.optimisation.functions.IndicatorBox

Defaults to the value set in the CIL multiprocessing module.''' return cil_mp.NUM_THREADS if self._num_threads is None else self._num_threads -
[docs] def set_num_threads(self, value): +
[docs] def set_num_threads(self, value): '''Set the optional number of threads parameter to use for the accelerated version. This is discarded if ``accelerated=False``.''' @@ -643,37 +887,59 @@

Source code for cil.optimisation.functions.IndicatorBox

acc[j] += arr[i]
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/KullbackLeibler.html b/nightly/_modules/cil/optimisation/functions/KullbackLeibler/index.html similarity index 84% rename from nightly/_modules/cil/optimisation/functions/KullbackLeibler.html rename to nightly/_modules/cil/optimisation/functions/KullbackLeibler/index.html index 13c8209e90..0679f574ce 100644 --- a/nightly/_modules/cil/optimisation/functions/KullbackLeibler.html +++ b/nightly/_modules/cil/optimisation/functions/KullbackLeibler/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.functions.KullbackLeibler — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.functions.KullbackLeibler

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -223,7 +467,7 @@ 

Source code for cil.optimisation.functions.KullbackLeibler

except ImportError as ie: has_numba = False -
[docs]class KullbackLeibler(Function): +
[docs]class KullbackLeibler(Function): r""" Kullback Leibler @@ -725,37 +969,59 @@

Source code for cil.optimisation.functions.KullbackLeibler

return out
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/L1Norm.html b/nightly/_modules/cil/optimisation/functions/L1Norm/index.html similarity index 67% rename from nightly/_modules/cil/optimisation/functions/L1Norm.html rename to nightly/_modules/cil/optimisation/functions/L1Norm/index.html index 08b085da2f..15d5050458 100644 --- a/nightly/_modules/cil/optimisation/functions/L1Norm.html +++ b/nightly/_modules/cil/optimisation/functions/L1Norm/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.functions.L1Norm — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.functions.L1Norm

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -262,7 +506,7 @@ 

Source code for cil.optimisation.functions.L1Norm

if should_return: return out -
[docs]class L1Norm(Function): +
[docs]class L1Norm(Function): r"""L1Norm function Consider the following cases: @@ -300,7 +544,7 @@

Source code for cil.optimisation.functions.L1Norm

""" return self.function(x) -
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): r"""Returns the value of the convex conjugate of the L1 Norm function at x. @@ -341,7 +585,7 @@

Source code for cil.optimisation.functions.L1Norm

""" return self.function.convex_conjugate(x)
-
[docs] def proximal(self, x, tau, out=None): +
[docs] def proximal(self, x, tau, out=None): r"""Returns the value of the proximal operator of the L1 Norm function at x with scaling parameter `tau`. @@ -464,7 +708,7 @@

Source code for cil.optimisation.functions.L1Norm

tau /= self.weight return ret -
[docs]class MixedL11Norm(Function): +
[docs]class MixedL11Norm(Function): r"""MixedL11Norm function @@ -496,7 +740,7 @@

Source code for cil.optimisation.functions.L1Norm

return x.abs().sum() -
[docs] def proximal(self, x, tau, out = None): +
[docs] def proximal(self, x, tau, out = None): r"""Returns the value of the proximal operator of the MixedL11Norm function at x. @@ -514,37 +758,59 @@

Source code for cil.optimisation.functions.L1Norm

return soft_shrinkage(x, tau, out = out)
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/L2NormSquared.html b/nightly/_modules/cil/optimisation/functions/L2NormSquared/index.html similarity index 59% rename from nightly/_modules/cil/optimisation/functions/L2NormSquared.html rename to nightly/_modules/cil/optimisation/functions/L2NormSquared/index.html index 10ed87480b..f24001418a 100644 --- a/nightly/_modules/cil/optimisation/functions/L2NormSquared.html +++ b/nightly/_modules/cil/optimisation/functions/L2NormSquared/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.functions.L2NormSquared — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.functions.L2NormSquared

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -216,7 +460,7 @@ 

Source code for cil.optimisation.functions.L2NormSquared

from cil.optimisation.operators import DiagonalOperator -
[docs]class L2NormSquared(Function): +
[docs]class L2NormSquared(Function): r""" L2NormSquared function: :math:`F(x) = \| x\|^{2}_{2} = \underset{i}{\sum}x_{i}^{2}` @@ -260,7 +504,7 @@

Source code for cil.optimisation.functions.L2NormSquared

# added for compatibility with SIRF return (y.norm()**2) -
[docs] def gradient(self, x, out=None): +
[docs] def gradient(self, x, out=None): r"""Returns the value of the gradient of the L2NormSquared function at x. Following cases are considered: @@ -278,7 +522,7 @@

Source code for cil.optimisation.functions.L2NormSquared

if out is None: return ret
-
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): r"""Returns the value of the convex conjugate of the L2NormSquared function at x. Consider the following cases: @@ -294,7 +538,7 @@

Source code for cil.optimisation.functions.L2NormSquared

return 0.25 * x.squared_norm() + tmp
-
[docs] def proximal(self, x, tau, out=None): +
[docs] def proximal(self, x, tau, out=None): r"""Returns the value of the proximal operator of the L2NormSquared function at x. @@ -316,7 +560,7 @@

Source code for cil.optimisation.functions.L2NormSquared

return ret
-
[docs]class WeightedL2NormSquared(Function): +
[docs]class WeightedL2NormSquared(Function): r""" WeightedL2NormSquared function: :math:`F(x) = \|x\|_{W,2}^2 = \Sigma_iw_ix_i^2 = \langle x, Wx\rangle = x^TWx` where :math:`W=\text{diag}(weight)` if `weight` is a `DataContainer` or :math:`W=\text{weight} I` if `weight` is a scalar. @@ -361,7 +605,7 @@

Source code for cil.optimisation.functions.L2NormSquared

y = (x - self.b).dot(self.tmp_space) return y -
[docs] def gradient(self, x, out=None): +
[docs] def gradient(self, x, out=None): r""" Returns the value of :math:`F'(x) = 2Wx` or, if `b` is defined, :math:`F'(x) = 2W(x-b)` where :math:`W=\text{diag}(weight)` if `weight` is a `DataContainer` or :math:`\text{weight}I` if `weight` is a scalar. @@ -382,7 +626,7 @@

Source code for cil.optimisation.functions.L2NormSquared

y = x - self.b return 2*self.weight*y
-
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): r"""Returns the value of the convex conjugate of the WeightedL2NormSquared function at x.""" tmp = 0 if self.b is not None: @@ -390,7 +634,7 @@

Source code for cil.optimisation.functions.L2NormSquared

return (1./4) * (x/self.weight.sqrt()).squared_norm() + tmp
-
[docs] def proximal(self, x, tau, out=None): +
[docs] def proximal(self, x, tau, out=None): r"""Returns the value of the proximal operator of the WeightedL2NormSquared function at x.""" if out is None: @@ -412,37 +656,59 @@

Source code for cil.optimisation.functions.L2NormSquared

x.divide((1+2*tau*self.weight), out=out)
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/LeastSquares.html b/nightly/_modules/cil/optimisation/functions/LeastSquares/index.html similarity index 58% rename from nightly/_modules/cil/optimisation/functions/LeastSquares.html rename to nightly/_modules/cil/optimisation/functions/LeastSquares/index.html index baf2e50cd5..2b98b42fa8 100644 --- a/nightly/_modules/cil/optimisation/functions/LeastSquares.html +++ b/nightly/_modules/cil/optimisation/functions/LeastSquares/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.functions.LeastSquares — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.functions.LeastSquares

 # -*- coding: utf-8 -*-
 #  Copyright 2018 United Kingdom Research and Innovation
@@ -219,7 +463,7 @@ 

Source code for cil.optimisation.functions.LeastSquares

import numpy as np -
[docs]class LeastSquares(Function): +
[docs]class LeastSquares(Function): r""" (Weighted) Least Squares function .. math:: F(x) = c\|Ax-b\|_2^2 @@ -275,7 +519,7 @@

Source code for cil.optimisation.functions.LeastSquares

wy = self.weight.multiply(y) return self.c * y.dot(wy) -
[docs] def gradient(self, x, out=None): +
[docs] def gradient(self, x, out=None): r""" Returns the value of the gradient of :math:`F(x)`: @@ -354,37 +598,59 @@

Source code for cil.optimisation.functions.LeastSquares

return LeastSquares(A=self.A, b=self.b, c=constant, weight=self.weight)
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/MixedL21Norm.html b/nightly/_modules/cil/optimisation/functions/MixedL21Norm/index.html similarity index 60% rename from nightly/_modules/cil/optimisation/functions/MixedL21Norm.html rename to nightly/_modules/cil/optimisation/functions/MixedL21Norm/index.html index 38125dda7d..0e9fac87b1 100644 --- a/nightly/_modules/cil/optimisation/functions/MixedL21Norm.html +++ b/nightly/_modules/cil/optimisation/functions/MixedL21Norm/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.functions.MixedL21Norm — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.functions.MixedL21Norm

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -285,7 +529,7 @@ 

Source code for cil.optimisation.functions.MixedL21Norm

return res -
[docs]class MixedL21Norm(Function): +
[docs]class MixedL21Norm(Function): """ MixedL21Norm function: :math:`F(x) = ||x||_{2,1} = \sum |x|_{2} = \sum \sqrt{ (x^{1})^{2} + (x^{2})^{2} + \dots}` @@ -311,7 +555,7 @@

Source code for cil.optimisation.functions.MixedL21Norm

return x.pnorm(p=2).sum() -
[docs] def convex_conjugate(self,x): +
[docs] def convex_conjugate(self,x): r"""Returns the value of the convex conjugate of the MixedL21Norm function at x. @@ -339,7 +583,7 @@

Source code for cil.optimisation.functions.MixedL21Norm

else: return np.inf
-
[docs] def proximal(self, x, tau, out=None): +
[docs] def proximal(self, x, tau, out=None): r"""Returns the value of the proximal operator of the MixedL21Norm function at x. @@ -374,7 +618,7 @@

Source code for cil.optimisation.functions.MixedL21Norm

if out is None: return res
-
[docs]class SmoothMixedL21Norm(Function): +
[docs]class SmoothMixedL21Norm(Function): """ SmoothMixedL21Norm function: :math:`F(x) = ||x||_{2,1} = \sum |x|_{2} = \sum \sqrt{ (x^{1})^{2} + (x^{2})^{2} + \epsilon^2 + \dots}` @@ -408,7 +652,7 @@

Source code for cil.optimisation.functions.MixedL21Norm

return (x.pnorm(2).power(2) + self.epsilon**2).sqrt().sum() -
[docs] def gradient(self, x, out=None): +
[docs] def gradient(self, x, out=None): r"""Returns the value of the gradient of the SmoothMixedL21Norm function at x. @@ -428,37 +672,59 @@

Source code for cil.optimisation.functions.MixedL21Norm

x.divide(denom, out=out)
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/OperatorCompositionFunction.html b/nightly/_modules/cil/optimisation/functions/OperatorCompositionFunction.html deleted file mode 100644 index e8fa11d56e..0000000000 --- a/nightly/_modules/cil/optimisation/functions/OperatorCompositionFunction.html +++ /dev/null @@ -1,313 +0,0 @@ - - - - - - - - cil.optimisation.functions.OperatorCompositionFunction — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.optimisation.functions.OperatorCompositionFunction

-# -*- coding: utf-8 -*-
-#  Copyright 2019 United Kingdom Research and Innovation
-#  Copyright 2019 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-from cil.optimisation.functions import Function
-from cil.optimisation.operators import Operator, ScaledOperator
-
-import warnings
-
-
[docs]class OperatorCompositionFunction(Function): - - """ Composition of a function with an operator as : :math:`(F \otimes A)(x) = F(Ax)` - - :parameter function: :code:`Function` F - :parameter operator: :code:`Operator` A - - - For general operator, we have no explicit formulas for convex_conjugate, - proximal and proximal_conjugate - - """ - - def __init__(self, function, operator): - '''creator - - :param A: operator - :type A: :code:`Operator` - :param f: function - :type f: :code:`Function` - ''' - - super(OperatorCompositionFunction, self).__init__() - - self.function = function - self.operator = operator - - @property - def L(self): - if self._L is None: - try: - self._L = self.function.L * (self.operator.norm() ** 2) - except ValueError as ve: - self._L = None - return self._L - - def __call__(self, x): - - """ Returns :math:`F(Ax)` - """ - - return self.function(self.operator.direct(x)) - -
[docs] def gradient(self, x, out=None): - - """ Return the gradient of F(Ax), - - ..math :: (F(Ax))' = A^{T}F'(Ax) - - """ - - tmp = self.operator.range_geometry().allocate() - self.operator.direct(x, out=tmp) - self.function.gradient(tmp, out=tmp) - if out is None: - return self.operator.adjoint(tmp) - else: - self.operator.adjoint(tmp, out=out)
- -
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/OperatorCompositionFunction/index.html b/nightly/_modules/cil/optimisation/functions/OperatorCompositionFunction/index.html new file mode 100644 index 0000000000..1ff80f8215 --- /dev/null +++ b/nightly/_modules/cil/optimisation/functions/OperatorCompositionFunction/index.html @@ -0,0 +1,579 @@ + + + + + + + + + + + cil.optimisation.functions.OperatorCompositionFunction — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.optimisation.functions.OperatorCompositionFunction

+# -*- coding: utf-8 -*-
+#  Copyright 2019 United Kingdom Research and Innovation
+#  Copyright 2019 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+from cil.optimisation.functions import Function
+from cil.optimisation.operators import Operator, ScaledOperator
+
+import warnings
+
+
[docs]class OperatorCompositionFunction(Function): + + """ Composition of a function with an operator as : :math:`(F \otimes A)(x) = F(Ax)` + + :parameter function: :code:`Function` F + :parameter operator: :code:`Operator` A + + + For general operator, we have no explicit formulas for convex_conjugate, + proximal and proximal_conjugate + + """ + + def __init__(self, function, operator): + '''creator + + :param A: operator + :type A: :code:`Operator` + :param f: function + :type f: :code:`Function` + ''' + + super(OperatorCompositionFunction, self).__init__() + + self.function = function + self.operator = operator + + @property + def L(self): + if self._L is None: + try: + self._L = self.function.L * (self.operator.norm() ** 2) + except ValueError as ve: + self._L = None + return self._L + + def __call__(self, x): + + """ Returns :math:`F(Ax)` + """ + + return self.function(self.operator.direct(x)) + +
[docs] def gradient(self, x, out=None): + + """ Return the gradient of F(Ax), + + ..math :: (F(Ax))' = A^{T}F'(Ax) + + """ + + tmp = self.operator.range_geometry().allocate() + self.operator.direct(x, out=tmp) + self.function.gradient(tmp, out=tmp) + if out is None: + return self.operator.adjoint(tmp) + else: + self.operator.adjoint(tmp, out=out)
+ +
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/Rosenbrock.html b/nightly/_modules/cil/optimisation/functions/Rosenbrock.html deleted file mode 100644 index b0c950e397..0000000000 --- a/nightly/_modules/cil/optimisation/functions/Rosenbrock.html +++ /dev/null @@ -1,301 +0,0 @@ - - - - - - - - cil.optimisation.functions.Rosenbrock — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.optimisation.functions.Rosenbrock

-# -*- coding: utf-8 -*-
-#  Copyright 2019 United Kingdom Research and Innovation
-#  Copyright 2019 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-import numpy
-from cil.optimisation.functions import Function
-from cil.framework import VectorData, VectorGeometry
-
-
[docs]class Rosenbrock(Function): - r'''Rosenbrock function - - .. math:: - - F(x,y) = (\alpha - x)^2 + \beta(y-x^2)^2 - - The function has a global minimum at .. math:: (x,y)=(\alpha, \alpha^2) - - ''' - def __init__(self, alpha, beta): - super(Rosenbrock, self).__init__() - - self.alpha = alpha - self.beta = beta - - def __call__(self, x): - if not isinstance(x, VectorData): - raise TypeError('Rosenbrock function works on VectorData only') - vec = x.as_array() - a = (self.alpha - vec[0]) - b = (vec[1] - (vec[0]*vec[0])) - return a * a + self.beta * b * b - -
[docs] def gradient(self, x, out=None): - r'''Gradient of the Rosenbrock function - - .. math:: - - \nabla f(x,y) = \left[ 2*((x-\alpha) - 2\beta x(y-x^2)) ; 2\beta (y - x^2) \right] - - ''' - if not isinstance(x, VectorData): - raise TypeError('Rosenbrock function works on VectorData only') - - vec = x.as_array() - a = (vec[0] - self.alpha) - b = (vec[1] - (vec[0]*vec[0])) - - res = numpy.empty_like(vec) - res[0] = 2 * ( a - 2 * self.beta * vec[0] * b) - res[1] = 2 * self.beta * b - - if out is not None: - out.fill (res) - else: - return VectorData(res)
- -
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/Rosenbrock/index.html b/nightly/_modules/cil/optimisation/functions/Rosenbrock/index.html new file mode 100644 index 0000000000..350b78bf3f --- /dev/null +++ b/nightly/_modules/cil/optimisation/functions/Rosenbrock/index.html @@ -0,0 +1,567 @@ + + + + + + + + + + + cil.optimisation.functions.Rosenbrock — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.optimisation.functions.Rosenbrock

+# -*- coding: utf-8 -*-
+#  Copyright 2019 United Kingdom Research and Innovation
+#  Copyright 2019 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+import numpy
+from cil.optimisation.functions import Function
+from cil.framework import VectorData, VectorGeometry
+
+
[docs]class Rosenbrock(Function): + r'''Rosenbrock function + + .. math:: + + F(x,y) = (\alpha - x)^2 + \beta(y-x^2)^2 + + The function has a global minimum at .. math:: (x,y)=(\alpha, \alpha^2) + + ''' + def __init__(self, alpha, beta): + super(Rosenbrock, self).__init__() + + self.alpha = alpha + self.beta = beta + + def __call__(self, x): + if not isinstance(x, VectorData): + raise TypeError('Rosenbrock function works on VectorData only') + vec = x.as_array() + a = (self.alpha - vec[0]) + b = (vec[1] - (vec[0]*vec[0])) + return a * a + self.beta * b * b + +
[docs] def gradient(self, x, out=None): + r'''Gradient of the Rosenbrock function + + .. math:: + + \nabla f(x,y) = \left[ 2*((x-\alpha) - 2\beta x(y-x^2)) ; 2\beta (y - x^2) \right] + + ''' + if not isinstance(x, VectorData): + raise TypeError('Rosenbrock function works on VectorData only') + + vec = x.as_array() + a = (vec[0] - self.alpha) + b = (vec[1] - (vec[0]*vec[0])) + + res = numpy.empty_like(vec) + res[0] = 2 * ( a - 2 * self.beta * vec[0] * b) + res[1] = 2 * self.beta * b + + if out is not None: + out.fill (res) + else: + return VectorData(res)
+ +
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/functions/TotalVariation.html b/nightly/_modules/cil/optimisation/functions/TotalVariation/index.html similarity index 72% rename from nightly/_modules/cil/optimisation/functions/TotalVariation.html rename to nightly/_modules/cil/optimisation/functions/TotalVariation/index.html index b39bd2a914..1d11bae35c 100644 --- a/nightly/_modules/cil/optimisation/functions/TotalVariation.html +++ b/nightly/_modules/cil/optimisation/functions/TotalVariation/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.functions.TotalVariation — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.functions.TotalVariation

 # -*- coding: utf-8 -*-
 #  Copyright 2020 United Kingdom Research and Innovation
@@ -221,7 +465,7 @@ 

Source code for cil.optimisation.functions.TotalVariation

import logging -
[docs]class TotalVariation(Function): +
[docs]class TotalVariation(Function): r""" Total variation Function @@ -452,7 +696,7 @@

Source code for cil.optimisation.functions.TotalVariation

return self.regularisation_parameter * self.func(self.gradient.direct(x)) + strongly_convex_term -
[docs] def proximal(self, x, tau, out=None): +
[docs] def proximal(self, x, tau, out=None): r""" Returns the proximal operator of the TotalVariation function at :code:`x` .""" if self.strong_convexity_constant > 0: @@ -559,11 +803,11 @@

Source code for cil.optimisation.functions.TotalVariation

if should_return: return out -
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): r""" Returns the value of convex conjugate of the TotalVariation function at :code:`x` .""" return 0.0
-
[docs] def calculate_Lipschitz(self): +
[docs] def calculate_Lipschitz(self): r""" Default value for the Lipschitz constant.""" # Compute the Lipschitz parameter from the operator if possible @@ -593,37 +837,59 @@

Source code for cil.optimisation.functions.TotalVariation

return self
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/BlockOperator.html b/nightly/_modules/cil/optimisation/operators/BlockOperator/index.html similarity index 74% rename from nightly/_modules/cil/optimisation/operators/BlockOperator.html rename to nightly/_modules/cil/optimisation/operators/BlockOperator/index.html index 6ab88343e8..ae9414ba09 100644 --- a/nightly/_modules/cil/optimisation/operators/BlockOperator.html +++ b/nightly/_modules/cil/optimisation/operators/BlockOperator/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.operators.BlockOperator — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.operators.BlockOperator

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -225,7 +469,7 @@ 

Source code for cil.optimisation.operators.BlockOperator

has_sirf = False -
[docs]class BlockOperator(Operator): +
[docs]class BlockOperator(Operator): r'''A Block matrix containing Operators Parameters @@ -270,7 +514,7 @@

Source code for cil.optimisation.operators.BlockOperator

''' __array_priority__ = 1 -
[docs] def __init__(self, *args, **kwargs): +
[docs] def __init__(self, *args, **kwargs): self.operators = args shape = kwargs.get('shape', None) @@ -295,7 +539,7 @@

Source code for cil.optimisation.operators.BlockOperator

# if not self.row_wise_compatible(): # raise ValueError('Operators in each row must have the same range') -
[docs] def column_wise_compatible(self): +
[docs] def column_wise_compatible(self): '''Operators in a Block should have the same domain per column''' rows, cols = self.shape compatible = True @@ -311,7 +555,7 @@

Source code for cil.optimisation.operators.BlockOperator

compatible = compatible and column_compatible return compatible
-
[docs] def row_wise_compatible(self): +
[docs] def row_wise_compatible(self): '''Operators in a Block should have the same range per row''' rows, cols = self.shape compatible = True @@ -329,7 +573,7 @@

Source code for cil.optimisation.operators.BlockOperator

return compatible
-
[docs] def get_item(self, row, col): +
[docs] def get_item(self, row, col): '''Returns the Operator at specified row and col Parameters ---------- @@ -348,16 +592,16 @@

Source code for cil.optimisation.operators.BlockOperator

index = row*self.shape[1]+col return self.operators[index]
-
[docs] def norm(self): +
[docs] def norm(self): '''Returns the Euclidean norm of the norms of the individual operators in the BlockOperators ''' return numpy.sqrt(numpy.sum(numpy.array(self.get_norms_as_list())**2))
-
[docs] def get_norms_as_list(self, ): +
[docs] def get_norms_as_list(self, ): '''Returns a list of the individual norms of the Operators in the BlockOperator ''' return [op.norm() for op in self.operators]
-
[docs] def set_norms(self, norms): +
[docs] def set_norms(self, norms): '''Uses the set_norm() function in Operator to set the norms of the operators in the BlockOperator from a list of custom values. Parameters @@ -373,7 +617,7 @@

Source code for cil.optimisation.operators.BlockOperator

for j, value in enumerate(norms): self.operators[j].set_norm(value)
-
[docs] def direct(self, x, out=None): +
[docs] def direct(self, x, out=None): '''Direct operation for the BlockOperator Note @@ -419,7 +663,7 @@

Source code for cil.optimisation.operators.BlockOperator

temp_out_row += tmp.get_item(row)
-
[docs] def adjoint(self, x, out=None): +
[docs] def adjoint(self, x, out=None): '''Adjoint operation for the BlockOperator Note @@ -483,11 +727,11 @@

Source code for cil.optimisation.operators.BlockOperator

x_b.get_item(row), )
-
[docs] def is_linear(self): +
[docs] def is_linear(self): '''Returns whether all the elements of the BlockOperator are linear''' return functools.reduce(lambda x, y: x and y.is_linear(), self.operators, True)
-
[docs] def get_output_shape(self, xshape, adjoint=False): +
[docs] def get_output_shape(self, xshape, adjoint=False): '''Returns the shape of the output BlockDataContainer Parameters ---------- @@ -516,7 +760,7 @@

Source code for cil.optimisation.operators.BlockOperator

'Incompatible shapes {} {}'.format((rows, cols), xshape)) return (rows, xcols)
-
[docs] def __rmul__(self, scalar): +
[docs] def __rmul__(self, scalar): '''Defines the left multiplication with a scalar. Returns a block operator with Scaled Operators inside. Parameters @@ -550,7 +794,7 @@

Source code for cil.optimisation.operators.BlockOperator

oplist.append(self.get_item(col, row)) return type(self)(*oplist, shape=newshape) -
[docs] def domain_geometry(self): +
[docs] def domain_geometry(self): '''Returns the domain of the BlockOperator If the shape of the BlockOperator is (N,1) the domain is a ImageGeometry or AcquisitionGeometry. @@ -572,7 +816,7 @@

Source code for cil.optimisation.operators.BlockOperator

# return BlockGeometry(*[el.domain_geometry() for el in self.operators], # shape=self.shape) -
[docs] def range_geometry(self): +
[docs] def range_geometry(self): '''Returns the range of the BlockOperator''' tmp = [] @@ -618,46 +862,68 @@

Source code for cil.optimisation.operators.BlockOperator

def size(self): return len(self.operators) -
[docs] def __getitem__(self, index): +
[docs] def __getitem__(self, index): '''Returns the index-th operator in the block irrespectively of it's shape''' return self.operators[index]
-
[docs] def get_as_list(self): +
[docs] def get_as_list(self): '''Returns the list of operators''' return self.operators
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/ChannelwiseOperator.html b/nightly/_modules/cil/optimisation/operators/ChannelwiseOperator/index.html similarity index 53% rename from nightly/_modules/cil/optimisation/operators/ChannelwiseOperator.html rename to nightly/_modules/cil/optimisation/operators/ChannelwiseOperator/index.html index 8307081463..e85b381652 100644 --- a/nightly/_modules/cil/optimisation/operators/ChannelwiseOperator.html +++ b/nightly/_modules/cil/optimisation/operators/ChannelwiseOperator/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.operators.ChannelwiseOperator — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.operators.ChannelwiseOperator

 # -*- coding: utf-8 -*-
 #  Copyright 2020 United Kingdom Research and Innovation
@@ -217,7 +461,7 @@ 

Source code for cil.optimisation.operators.ChannelwiseOperator

from cil.framework import ImageGeometry, AcquisitionGeometry, BlockGeometry -
[docs]class ChannelwiseOperator(LinearOperator): +
[docs]class ChannelwiseOperator(LinearOperator): r'''ChannelwiseOperator: takes in a single-channel operator op and the number of channels to be used, and creates a new multi-channel @@ -276,7 +520,7 @@

Source code for cil.optimisation.operators.ChannelwiseOperator

self.op = op self.channels = channels -
[docs] def direct(self,x,out=None): +
[docs] def direct(self,x,out=None): '''Returns D(x)''' @@ -295,7 +539,7 @@

Source code for cil.optimisation.operators.ChannelwiseOperator

self.op.direct(x.get_slice(channel=k),cury) out.fill(cury.as_array(),channel=k)
-
[docs] def adjoint(self,x, out=None): +
[docs] def adjoint(self,x, out=None): '''Returns D^{*}(y)''' @@ -314,7 +558,7 @@

Source code for cil.optimisation.operators.ChannelwiseOperator

self.op.adjoint(x.get_slice(channel=k),cury) out.fill(cury.as_array(),channel=k)
-
[docs] def calculate_norm(self, **kwargs): +
[docs] def calculate_norm(self, **kwargs): '''Evaluates operator norm of DiagonalOperator''' @@ -322,37 +566,59 @@

Source code for cil.optimisation.operators.ChannelwiseOperator

-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/DiagonalOperator.html b/nightly/_modules/cil/optimisation/operators/DiagonalOperator.html deleted file mode 100644 index 0bf709ef5a..0000000000 --- a/nightly/_modules/cil/optimisation/operators/DiagonalOperator.html +++ /dev/null @@ -1,313 +0,0 @@ - - - - - - - - cil.optimisation.operators.DiagonalOperator — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.optimisation.operators.DiagonalOperator

-# -*- coding: utf-8 -*-
-#  Copyright 2020 United Kingdom Research and Innovation
-#  Copyright 2020 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-import numpy as np
-from cil.framework import ImageData
-from cil.optimisation.operators import LinearOperator
-
-
[docs]class DiagonalOperator(LinearOperator): - - r"""DiagonalOperator - - Performs an element-wise multiplication, i.e., `Hadamard Product <https://en.wikipedia.org/wiki/Hadamard_product_(matrices)#:~:text=In%20mathematics%2C%20the%20Hadamard%20product,elements%20i%2C%20j%20of%20the>`_ - of a :class:`DataContainer` `x` and :class:`DataContainer` `diagonal`, `d` . - - .. math:: (D\circ x) = \sum_{i,j}^{M,N} D_{i,j} x_{i, j} - - In matrix-vector interpretation, if `D` is a :math:`M\times N` dense matrix and is flattened, we have a :math:`M*N \times M*N` vector. - A sparse diagonal matrix, i.e., :class:`DigaonalOperator` can be created if we add the vector above to the main diagonal. - If the :class:`DataContainer` `x` is also flattened, we have a :math:`M*N` vector. - Now, matrix-vector multiplcation is allowed and results to a :math:`(M*N,1)` vector. After reshaping we recover a :math:`M\times N` :class:`DataContainer`. - - Parameters - ---------- - diagonal : DataContainer - DataContainer with the same dimensions as the data to be operated on. - domain_geometry : ImageGeometry - Specifies the geometry of the operator domain. If 'None' will use the diagonal geometry directly. default=None . - - """ - - - def __init__(self, diagonal, domain_geometry=None): - - if domain_geometry is None: - domain_geometry = diagonal.geometry.copy() - - super(DiagonalOperator, self).__init__(domain_geometry=domain_geometry, - range_geometry=domain_geometry) - self.diagonal = diagonal - - -
[docs] def direct(self,x,out=None): - - "Returns :math:`D\circ x` " - - if out is None: - return self.diagonal * x - else: - self.diagonal.multiply(x,out=out)
- - -
[docs] def adjoint(self,x, out=None): - - "Returns :math:`D^*\circ x` " - - return self.diagonal.conjugate().multiply(x,out=out)
- - -
[docs] def calculate_norm(self, **kwargs): - - r""" Returns the operator norm of DiagonalOperator which is the :math:`\infty` norm of `diagonal` - - .. math:: \|D\|_{\infty} = \max_{i}\{|D_{i}|\} - - """ - - return self.diagonal.abs().max()
-
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/DiagonalOperator/index.html b/nightly/_modules/cil/optimisation/operators/DiagonalOperator/index.html new file mode 100644 index 0000000000..381aba69e8 --- /dev/null +++ b/nightly/_modules/cil/optimisation/operators/DiagonalOperator/index.html @@ -0,0 +1,579 @@ + + + + + + + + + + + cil.optimisation.operators.DiagonalOperator — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.optimisation.operators.DiagonalOperator

+# -*- coding: utf-8 -*-
+#  Copyright 2020 United Kingdom Research and Innovation
+#  Copyright 2020 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+import numpy as np
+from cil.framework import ImageData
+from cil.optimisation.operators import LinearOperator
+
+
[docs]class DiagonalOperator(LinearOperator): + + r"""DiagonalOperator + + Performs an element-wise multiplication, i.e., `Hadamard Product <https://en.wikipedia.org/wiki/Hadamard_product_(matrices)#:~:text=In%20mathematics%2C%20the%20Hadamard%20product,elements%20i%2C%20j%20of%20the>`_ + of a :class:`DataContainer` `x` and :class:`DataContainer` `diagonal`, `d` . + + .. math:: (D\circ x) = \sum_{i,j}^{M,N} D_{i,j} x_{i, j} + + In matrix-vector interpretation, if `D` is a :math:`M\times N` dense matrix and is flattened, we have a :math:`M*N \times M*N` vector. + A sparse diagonal matrix, i.e., :class:`DigaonalOperator` can be created if we add the vector above to the main diagonal. + If the :class:`DataContainer` `x` is also flattened, we have a :math:`M*N` vector. + Now, matrix-vector multiplcation is allowed and results to a :math:`(M*N,1)` vector. After reshaping we recover a :math:`M\times N` :class:`DataContainer`. + + Parameters + ---------- + diagonal : DataContainer + DataContainer with the same dimensions as the data to be operated on. + domain_geometry : ImageGeometry + Specifies the geometry of the operator domain. If 'None' will use the diagonal geometry directly. default=None . + + """ + + + def __init__(self, diagonal, domain_geometry=None): + + if domain_geometry is None: + domain_geometry = diagonal.geometry.copy() + + super(DiagonalOperator, self).__init__(domain_geometry=domain_geometry, + range_geometry=domain_geometry) + self.diagonal = diagonal + + +
[docs] def direct(self,x,out=None): + + "Returns :math:`D\circ x` " + + if out is None: + return self.diagonal * x + else: + self.diagonal.multiply(x,out=out)
+ + +
[docs] def adjoint(self,x, out=None): + + "Returns :math:`D^*\circ x` " + + return self.diagonal.conjugate().multiply(x,out=out)
+ + +
[docs] def calculate_norm(self, **kwargs): + + r""" Returns the operator norm of DiagonalOperator which is the :math:`\infty` norm of `diagonal` + + .. math:: \|D\|_{\infty} = \max_{i}\{|D_{i}|\} + + """ + + return self.diagonal.abs().max()
+
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/FiniteDifferenceOperator.html b/nightly/_modules/cil/optimisation/operators/FiniteDifferenceOperator/index.html similarity index 80% rename from nightly/_modules/cil/optimisation/operators/FiniteDifferenceOperator.html rename to nightly/_modules/cil/optimisation/operators/FiniteDifferenceOperator/index.html index dacd5e9d80..4b05e68c46 100644 --- a/nightly/_modules/cil/optimisation/operators/FiniteDifferenceOperator.html +++ b/nightly/_modules/cil/optimisation/operators/FiniteDifferenceOperator/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.operators.FiniteDifferenceOperator — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.operators.FiniteDifferenceOperator

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -215,7 +459,7 @@ 

Source code for cil.optimisation.operators.FiniteDifferenceOperator

from cil.optimisation.operators import LinearOperator -
[docs]class FiniteDifferenceOperator(LinearOperator): +
[docs]class FiniteDifferenceOperator(LinearOperator): r''' Computes forward/backward/centered finite differences of a DataContainer @@ -278,7 +522,7 @@

Source code for cil.optimisation.operators.FiniteDifferenceOperator

tmp[self.direction] = slice(start, stop, end) return tmp -
[docs] def direct(self, x, out = None): +
[docs] def direct(self, x, out = None): x_asarr = x.as_array() @@ -418,7 +662,7 @@

Source code for cil.optimisation.operators.FiniteDifferenceOperator

out.fill(outa)
-
[docs] def adjoint(self, x, out=None): +
[docs] def adjoint(self, x, out=None): # Adjoint operation defined as @@ -569,37 +813,59 @@

Source code for cil.optimisation.operators.FiniteDifferenceOperator

-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/GradientOperator.html b/nightly/_modules/cil/optimisation/operators/GradientOperator/index.html similarity index 80% rename from nightly/_modules/cil/optimisation/operators/GradientOperator.html rename to nightly/_modules/cil/optimisation/operators/GradientOperator/index.html index 3a741c9a64..a43b872948 100644 --- a/nightly/_modules/cil/optimisation/operators/GradientOperator.html +++ b/nightly/_modules/cil/optimisation/operators/GradientOperator/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.operators.GradientOperator — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.operators.GradientOperator

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -226,7 +470,7 @@ 

Source code for cil.optimisation.operators.GradientOperator

CORRELATION_SPACE = "Space" CORRELATION_SPACECHANNEL = "SpaceChannels" -
[docs]class GradientOperator(LinearOperator): +
[docs]class GradientOperator(LinearOperator): r""" Gradient Operator: Computes first-order forward/backward differences on @@ -311,7 +555,7 @@

Source code for cil.optimisation.operators.GradientOperator

range_geometry=self.operator.range_geometry()) -
[docs] def direct(self, x, out=None): +
[docs] def direct(self, x, out=None): """ Computes the first-order forward differences @@ -329,7 +573,7 @@

Source code for cil.optimisation.operators.GradientOperator

return self.operator.direct(x, out=out)
-
[docs] def adjoint(self, x, out=None): +
[docs] def adjoint(self, x, out=None): """ Computes the first-order backward differences @@ -349,7 +593,7 @@

Source code for cil.optimisation.operators.GradientOperator

return self.operator.adjoint(x, out=out)
-
[docs] def calculate_norm(self): +
[docs] def calculate_norm(self): r""" Returns the analytical norm of the GradientOperator. @@ -665,37 +909,59 @@

Source code for cil.optimisation.operators.GradientOperator

+ + +
+ + + + +
+ + +
+ - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/IdentityOperator.html b/nightly/_modules/cil/optimisation/operators/IdentityOperator.html deleted file mode 100644 index a34e54cf61..0000000000 --- a/nightly/_modules/cil/optimisation/operators/IdentityOperator.html +++ /dev/null @@ -1,315 +0,0 @@ - - - - - - - - cil.optimisation.operators.IdentityOperator — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.optimisation.operators.IdentityOperator

-# -*- coding: utf-8 -*-
-#  Copyright 2019 United Kingdom Research and Innovation
-#  Copyright 2019 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-from cil.optimisation.operators import LinearOperator
-import scipy.sparse as sp
-import numpy as np
-
-
-
[docs]class IdentityOperator(LinearOperator): - - '''IdentityOperator: Id: X -> Y, Id(x) = x\in Y - - X : gm_domain - Y : gm_range ( Default: Y = X ) - - ''' - - - def __init__(self, domain_geometry, range_geometry=None): - - - if range_geometry is None: - range_geometry = domain_geometry - - super(IdentityOperator, self).__init__(domain_geometry=domain_geometry, - range_geometry=range_geometry) - -
[docs] def direct(self,x,out=None): - - '''Returns Id(x)''' - - if out is None: - return x.copy() - else: - out.fill(x)
- -
[docs] def adjoint(self,x, out=None): - - '''Returns Id(x)''' - - - if out is None: - return x.copy() - else: - out.fill(x)
- -
[docs] def calculate_norm(self, **kwargs): - - '''Evaluates operator norm of IdentityOperator''' - - return 1.0
- - - ########################################################################### - ############### For preconditioning ###################################### - ########################################################################### - def matrix(self): - - return sp.eye(np.prod(self.gm_domain.shape)) - - def sum_abs_row(self): - - return self.gm_range.allocate(1) - - def sum_abs_col(self): - - return self.gm_domain.allocate(1)
- - -
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/IdentityOperator/index.html b/nightly/_modules/cil/optimisation/operators/IdentityOperator/index.html new file mode 100644 index 0000000000..032b560c16 --- /dev/null +++ b/nightly/_modules/cil/optimisation/operators/IdentityOperator/index.html @@ -0,0 +1,581 @@ + + + + + + + + + + + cil.optimisation.operators.IdentityOperator — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.optimisation.operators.IdentityOperator

+# -*- coding: utf-8 -*-
+#  Copyright 2019 United Kingdom Research and Innovation
+#  Copyright 2019 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+from cil.optimisation.operators import LinearOperator
+import scipy.sparse as sp
+import numpy as np
+
+
+
[docs]class IdentityOperator(LinearOperator): + + '''IdentityOperator: Id: X -> Y, Id(x) = x\in Y + + X : gm_domain + Y : gm_range ( Default: Y = X ) + + ''' + + + def __init__(self, domain_geometry, range_geometry=None): + + + if range_geometry is None: + range_geometry = domain_geometry + + super(IdentityOperator, self).__init__(domain_geometry=domain_geometry, + range_geometry=range_geometry) + +
[docs] def direct(self,x,out=None): + + '''Returns Id(x)''' + + if out is None: + return x.copy() + else: + out.fill(x)
+ +
[docs] def adjoint(self,x, out=None): + + '''Returns Id(x)''' + + + if out is None: + return x.copy() + else: + out.fill(x)
+ +
[docs] def calculate_norm(self, **kwargs): + + '''Evaluates operator norm of IdentityOperator''' + + return 1.0
+ + + ########################################################################### + ############### For preconditioning ###################################### + ########################################################################### + def matrix(self): + + return sp.eye(np.prod(self.gm_domain.shape)) + + def sum_abs_row(self): + + return self.gm_range.allocate(1) + + def sum_abs_col(self): + + return self.gm_domain.allocate(1)
+ + +
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/MaskOperator.html b/nightly/_modules/cil/optimisation/operators/MaskOperator.html deleted file mode 100644 index a201d1fb33..0000000000 --- a/nightly/_modules/cil/optimisation/operators/MaskOperator.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - - - cil.optimisation.operators.MaskOperator — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.optimisation.operators.MaskOperator

-# -*- coding: utf-8 -*-
-#  Copyright 2020 United Kingdom Research and Innovation
-#  Copyright 2020 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-import numpy as np
-
-from cil.optimisation.operators import DiagonalOperator
-
-
[docs]class MaskOperator(DiagonalOperator): - - r""" MaskOperator - - Parameters - ---------- - mask : DataContainer - Boolean array with the same dimensions as the data to be operated on. - domain_geometry : ImageGeometry - Specifies the geometry of the operator domain. If 'None' will use the mask geometry size and spacing as float32. default = None . - """ - - def __init__(self, mask, domain_geometry=None): - - #if domain_geometry is not specified assume float32 for domain_geometry data type - if domain_geometry is None: - domain_geometry = mask.geometry.copy() - domain_geometry.dtype = np.float32 - - super(MaskOperator, self).__init__(mask, domain_geometry) - self.mask = self.diagonal
- - - -
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/MaskOperator/index.html b/nightly/_modules/cil/optimisation/operators/MaskOperator/index.html new file mode 100644 index 0000000000..78201fe3f0 --- /dev/null +++ b/nightly/_modules/cil/optimisation/operators/MaskOperator/index.html @@ -0,0 +1,543 @@ + + + + + + + + + + + cil.optimisation.operators.MaskOperator — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.optimisation.operators.MaskOperator

+# -*- coding: utf-8 -*-
+#  Copyright 2020 United Kingdom Research and Innovation
+#  Copyright 2020 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+import numpy as np
+
+from cil.optimisation.operators import DiagonalOperator
+
+
[docs]class MaskOperator(DiagonalOperator): + + r""" MaskOperator + + Parameters + ---------- + mask : DataContainer + Boolean array with the same dimensions as the data to be operated on. + domain_geometry : ImageGeometry + Specifies the geometry of the operator domain. If 'None' will use the mask geometry size and spacing as float32. default = None . + """ + + def __init__(self, mask, domain_geometry=None): + + #if domain_geometry is not specified assume float32 for domain_geometry data type + if domain_geometry is None: + domain_geometry = mask.geometry.copy() + domain_geometry.dtype = np.float32 + + super(MaskOperator, self).__init__(mask, domain_geometry) + self.mask = self.diagonal
+ + + +
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/MatrixOperator.html b/nightly/_modules/cil/optimisation/operators/MatrixOperator.html deleted file mode 100644 index a48a573c11..0000000000 --- a/nightly/_modules/cil/optimisation/operators/MatrixOperator.html +++ /dev/null @@ -1,297 +0,0 @@ - - - - - - - - cil.optimisation.operators.MatrixOperator — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.optimisation.operators.MatrixOperator

-# -*- coding: utf-8 -*-
-#  Copyright 2019 United Kingdom Research and Innovation
-#  Copyright 2019 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-import numpy
-from scipy.sparse.linalg import svds
-from cil.framework import VectorGeometry
-from cil.optimisation.operators import LinearOperator
-
-
[docs]class MatrixOperator(LinearOperator): - """ Matrix wrapped into a LinearOperator - - :param: a numpy matrix - - """ - - def __init__(self,A): - '''creator - - :param A: numpy ndarray representing a matrix - ''' - self.A = A - M_A, N_A = self.A.shape - domain_geometry = VectorGeometry(N_A, dtype=A.dtype) - range_geometry = VectorGeometry(M_A, dtype=A.dtype) - self.s1 = None # Largest singular value, initially unknown - super(MatrixOperator, self).__init__(domain_geometry=domain_geometry, - range_geometry=range_geometry) - -
[docs] def direct(self,x, out=None): - - if out is None: - tmp = self.range_geometry().allocate() - tmp.fill(numpy.dot(self.A,x.as_array())) - return tmp - else: - # Below use of out is not working, see - # https://docs.scipy.org/doc/numpy/reference/generated/numpy.dot.html - # numpy.dot(self.A, x.as_array(), out = out.as_array()) - out.fill(numpy.dot(self.A, x.as_array()))
- -
[docs] def adjoint(self,x, out=None): - if out is None: - tmp = self.domain_geometry().allocate() - tmp.fill(numpy.dot(self.A.transpose(),x.as_array())) - return tmp - else: - out.fill(numpy.dot(self.A.transpose(),x.as_array()))
- - def size(self): - return self.A.shape
- -
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/MatrixOperator/index.html b/nightly/_modules/cil/optimisation/operators/MatrixOperator/index.html new file mode 100644 index 0000000000..c4b0060b13 --- /dev/null +++ b/nightly/_modules/cil/optimisation/operators/MatrixOperator/index.html @@ -0,0 +1,563 @@ + + + + + + + + + + + cil.optimisation.operators.MatrixOperator — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.optimisation.operators.MatrixOperator

+# -*- coding: utf-8 -*-
+#  Copyright 2019 United Kingdom Research and Innovation
+#  Copyright 2019 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+import numpy
+from scipy.sparse.linalg import svds
+from cil.framework import VectorGeometry
+from cil.optimisation.operators import LinearOperator
+
+
[docs]class MatrixOperator(LinearOperator): + """ Matrix wrapped into a LinearOperator + + :param: a numpy matrix + + """ + + def __init__(self,A): + '''creator + + :param A: numpy ndarray representing a matrix + ''' + self.A = A + M_A, N_A = self.A.shape + domain_geometry = VectorGeometry(N_A, dtype=A.dtype) + range_geometry = VectorGeometry(M_A, dtype=A.dtype) + self.s1 = None # Largest singular value, initially unknown + super(MatrixOperator, self).__init__(domain_geometry=domain_geometry, + range_geometry=range_geometry) + +
[docs] def direct(self,x, out=None): + + if out is None: + tmp = self.range_geometry().allocate() + tmp.fill(numpy.dot(self.A,x.as_array())) + return tmp + else: + # Below use of out is not working, see + # https://docs.scipy.org/doc/numpy/reference/generated/numpy.dot.html + # numpy.dot(self.A, x.as_array(), out = out.as_array()) + out.fill(numpy.dot(self.A, x.as_array()))
+ +
[docs] def adjoint(self,x, out=None): + if out is None: + tmp = self.domain_geometry().allocate() + tmp.fill(numpy.dot(self.A.transpose(),x.as_array())) + return tmp + else: + out.fill(numpy.dot(self.A.transpose(),x.as_array()))
+ + def size(self): + return self.A.shape
+ +
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/Operator.html b/nightly/_modules/cil/optimisation/operators/Operator/index.html similarity index 76% rename from nightly/_modules/cil/optimisation/operators/Operator.html rename to nightly/_modules/cil/optimisation/operators/Operator/index.html index b50fdf4fa8..107b846021 100644 --- a/nightly/_modules/cil/optimisation/operators/Operator.html +++ b/nightly/_modules/cil/optimisation/operators/Operator/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.operators.Operator — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.operators.Operator

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -217,7 +461,7 @@ 

Source code for cil.optimisation.operators.Operator

import logging -
[docs]class Operator(object): +
[docs]class Operator(object): """ Operator that maps from a space X -> Y @@ -237,15 +481,15 @@

Source code for cil.optimisation.operators.Operator

self._domain_geometry = domain_geometry self._range_geometry = kwargs.get('range_geometry', None) -
[docs] def is_linear(self): +
[docs] def is_linear(self): '''Returns if the operator is linear''' return False
-
[docs] def direct(self, x, out=None): +
[docs] def direct(self, x, out=None): '''Returns the application of the Operator on x''' raise NotImplementedError
-
[docs] def norm(self, **kwargs): +
[docs] def norm(self, **kwargs): '''Returns the norm of the Operator. On first call the norm will be calculated using the operator's calculate_norm method. Subsequent calls will return the cached norm. @@ -263,7 +507,7 @@

Source code for cil.optimisation.operators.Operator

return self._norm
-
[docs] def set_norm(self, norm=None): +
[docs] def set_norm(self, norm=None): '''Sets the norm of the operator to a custom value. Parameters @@ -289,7 +533,7 @@

Source code for cil.optimisation.operators.Operator

self._norm = norm
-
[docs] def calculate_norm(self): +
[docs] def calculate_norm(self): '''Returns the norm of the SumOperator. Note that this gives a NotImplementedError if the SumOperator is not linear.''' if self.is_linear(): @@ -297,11 +541,11 @@

Source code for cil.optimisation.operators.Operator

return NotImplementedError
-
[docs] def range_geometry(self): +
[docs] def range_geometry(self): '''Returns the range of the Operator: Y space''' return self._range_geometry
-
[docs] def domain_geometry(self): +
[docs] def domain_geometry(self): '''Returns the domain of the Operator: X space''' return self._domain_geometry
@@ -341,7 +585,7 @@

Source code for cil.optimisation.operators.Operator

return self + (-1) * other
-
[docs]class LinearOperator(Operator): +
[docs]class LinearOperator(Operator): """ Linear operator that maps from a space X <-> Y @@ -358,17 +602,17 @@

Source code for cil.optimisation.operators.Operator

def __init__(self, domain_geometry, **kwargs): super(LinearOperator, self).__init__(domain_geometry, **kwargs) -
[docs] def is_linear(self): +
[docs] def is_linear(self): '''Returns if the operator is linear''' return True
-
[docs] def adjoint(self, x, out=None): +
[docs] def adjoint(self, x, out=None): '''returns the adjoint/inverse operation only available to linear operators''' raise NotImplementedError
-
[docs] @staticmethod +
[docs] @staticmethod def PowerMethod(operator, max_iteration=10, initial=None, tolerance=1e-5, return_all=False, method='auto'): r"""Power method or Power iteration algorithm @@ -509,12 +753,12 @@

Source code for cil.optimisation.operators.Operator

else: return eig_new
-
[docs] def calculate_norm(self): +
[docs] def calculate_norm(self): r""" Returns the norm of the LinearOperator calculated by the PowerMethod with default values. """ return LinearOperator.PowerMethod(self, method="composed_with_adjoint")
-
[docs] @staticmethod +
[docs] @staticmethod def dot_test(operator, domain_init=None, range_init=None, tolerance=1e-6, **kwargs): r'''Does a dot linearity test on the operator Evaluates if the following equivalence holds @@ -571,7 +815,7 @@

Source code for cil.optimisation.operators.Operator

return False
-
[docs]class ScaledOperator(Operator): +
[docs]class ScaledOperator(Operator): '''ScaledOperator @@ -611,7 +855,7 @@

Source code for cil.optimisation.operators.Operator

self.scalar = scalar self.operator = operator -
[docs] def direct(self, x, out=None): +
[docs] def direct(self, x, out=None): '''direct method''' if out is None: tmp = self.operator.direct(x) @@ -621,7 +865,7 @@

Source code for cil.optimisation.operators.Operator

self.operator.direct(x, out=out) out *= self.scalar
-
[docs] def adjoint(self, x, out=None): +
[docs] def adjoint(self, x, out=None): '''adjoint method''' if self.operator.is_linear(): if out is None: @@ -634,11 +878,11 @@

Source code for cil.optimisation.operators.Operator

else: raise TypeError('Operator is not linear')
-
[docs] def norm(self, **kwargs): +
[docs] def norm(self, **kwargs): '''norm of the operator''' return numpy.abs(self.scalar) * self.operator.norm(**kwargs)
-
[docs] def is_linear(self): +
[docs] def is_linear(self): '''returns a `boolean` indicating whether the operator is linear ''' return self.operator.is_linear()
@@ -647,7 +891,7 @@

Source code for cil.optimisation.operators.Operator

################ SumOperator ########################################### ############################################################################### -
[docs]class SumOperator(Operator): +
[docs]class SumOperator(Operator): """Sums two operators. For example, `SumOperator(left, right).direct(x)` is equivalent to `left.direct(x)+right.direct(x)` @@ -679,7 +923,7 @@

Source code for cil.optimisation.operators.Operator

super(SumOperator, self).__init__(domain_geometry=self.operator1.domain_geometry(), range_geometry=self.operator1.range_geometry()) -
[docs] def direct(self, x, out=None): +
[docs] def direct(self, x, out=None): r"""Calls the sum operator Parameters @@ -695,7 +939,7 @@

Source code for cil.optimisation.operators.Operator

self.operator1.direct(x, out=out) out.add(self.operator2.direct(x), out=out)
-
[docs] def adjoint(self, x, out=None): +
[docs] def adjoint(self, x, out=None): r"""Calls the adjoint of the sum operator Parameters @@ -715,7 +959,7 @@

Source code for cil.optimisation.operators.Operator

else: raise ValueError('No adjoint operation with non-linear operators')
-
[docs] def is_linear(self): +
[docs] def is_linear(self): return self.linear_flag
@@ -724,7 +968,7 @@

Source code for cil.optimisation.operators.Operator

############################################################################### -
[docs]class CompositionOperator(Operator): +
[docs]class CompositionOperator(Operator): """Composes one or more operators. For example, `CompositionOperator(left, right).direct(x)` is equivalent to `left.direct(right.direct(x))` @@ -759,7 +1003,7 @@

Source code for cil.optimisation.operators.Operator

domain_geometry=self.operators[-1].domain_geometry(), range_geometry=self.operators[0].range_geometry()) -
[docs] def direct(self, x, out=None): +
[docs] def direct(self, x, out=None): """Calls the composition operator @@ -815,7 +1059,7 @@

Source code for cil.optimisation.operators.Operator

step = operator.direct(step) out.fill(step)
-
[docs] def adjoint(self, x, out=None): +
[docs] def adjoint(self, x, out=None): """Calls the adjoint of the composition operator Parameters @@ -866,43 +1110,65 @@

Source code for cil.optimisation.operators.Operator

else: raise ValueError('No adjoint operation with non-linear operators')
-
[docs] def is_linear(self): +
[docs] def is_linear(self): return self.linear_flag
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/SparseFiniteDifferenceOperator.html b/nightly/_modules/cil/optimisation/operators/SparseFiniteDifferenceOperator/index.html similarity index 55% rename from nightly/_modules/cil/optimisation/operators/SparseFiniteDifferenceOperator.html rename to nightly/_modules/cil/optimisation/operators/SparseFiniteDifferenceOperator/index.html index 290cc6ef4e..ce820072e1 100644 --- a/nightly/_modules/cil/optimisation/operators/SparseFiniteDifferenceOperator.html +++ b/nightly/_modules/cil/optimisation/operators/SparseFiniteDifferenceOperator/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.operators.SparseFiniteDifferenceOperator — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.operators.SparseFiniteDifferenceOperator

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -216,7 +460,7 @@ 

Source code for cil.optimisation.operators.SparseFiniteDifferenceOperatorfrom cil.framework import ImageData from cil.optimisation.operators import Operator -
[docs]class SparseFiniteDifferenceOperator(Operator): +
[docs]class SparseFiniteDifferenceOperator(Operator): '''Create Sparse Matrices for the Finite Difference Operator''' @@ -260,7 +504,7 @@

Source code for cil.optimisation.operators.SparseFiniteDifferenceOperatordef T(self): return self.matrix().T -
[docs] def direct(self, x): +
[docs] def direct(self, x): x_asarr = x.as_array() res = np.reshape( self.matrix() * x_asarr.flatten('F'), self.domain_geometry().shape, 'F') @@ -302,37 +546,59 @@

Source code for cil.optimisation.operators.SparseFiniteDifferenceOperatorprint(cols.as_array())

-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/SymmetrisedGradientOperator.html b/nightly/_modules/cil/optimisation/operators/SymmetrisedGradientOperator/index.html similarity index 57% rename from nightly/_modules/cil/optimisation/operators/SymmetrisedGradientOperator.html rename to nightly/_modules/cil/optimisation/operators/SymmetrisedGradientOperator/index.html index 5ba19a5b81..093a060ed6 100644 --- a/nightly/_modules/cil/optimisation/operators/SymmetrisedGradientOperator.html +++ b/nightly/_modules/cil/optimisation/operators/SymmetrisedGradientOperator/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.operators.SymmetrisedGradientOperator — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.operators.SymmetrisedGradientOperator

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -216,7 +460,7 @@ 

Source code for cil.optimisation.operators.SymmetrisedGradientOperator

< from cil.optimisation.operators import FiniteDifferenceOperator -
[docs]class SymmetrisedGradientOperator(LinearOperator): +
[docs]class SymmetrisedGradientOperator(LinearOperator): r''' The symmetrised gradient is the operator, :math:`E`, defined by :math:`E: V \rightarrow W` where `V` is `BlockGeometry` and `W` is the range of the Symmetrised Gradient and @@ -280,7 +524,7 @@

Source code for cil.optimisation.operators.SymmetrisedGradientOperator

< range_geometry=BlockGeometry(*tmp_gm)) -
[docs] def direct(self, x, out=None): +
[docs] def direct(self, x, out=None): r'''Returns :math:`E(v) = 0.5 * ( \nabla v + (\nabla v)^{T} )` @@ -318,7 +562,7 @@

Source code for cil.optimisation.operators.SymmetrisedGradientOperator

< out.fill( 0.5 * (out + out1) )
-
[docs] def adjoint(self, x, out=None): +
[docs] def adjoint(self, x, out=None): r'''Returns the adjoint of the symmetrised gradient operator Parameters: @@ -360,37 +604,59 @@

Source code for cil.optimisation.operators.SymmetrisedGradientOperator

<
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/ZeroOperator.html b/nightly/_modules/cil/optimisation/operators/ZeroOperator.html deleted file mode 100644 index 0cb5770df1..0000000000 --- a/nightly/_modules/cil/optimisation/operators/ZeroOperator.html +++ /dev/null @@ -1,305 +0,0 @@ - - - - - - - - cil.optimisation.operators.ZeroOperator — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.optimisation.operators.ZeroOperator

-# -*- coding: utf-8 -*-
-#  Copyright 2019 United Kingdom Research and Innovation
-#  Copyright 2019 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-import numpy as np
-from cil.framework import ImageData
-from cil.optimisation.operators import LinearOperator
-
-
[docs]class ZeroOperator(LinearOperator): - - r'''ZeroOperator: O: X -> Y, maps any element of :math:`x\in X` into the zero element :math:`\in Y, O(x) = O_{Y}` - - :param gm_domain: domain of the operator - :param gm_range: range of the operator, default: same as domain - - - Note: - - .. math:: - - O^{*}: Y^{*} -> X^{*} \text{(Adjoint)} - - < O(x), y > = < x, O^{*}(y) > - - ''' - - def __init__(self, domain_geometry, range_geometry=None): - if range_geometry is None: - range_geometry = domain_geometry.clone() - super(ZeroOperator, self).__init__(domain_geometry=domain_geometry, - range_geometry=range_geometry) - - - -
[docs] def direct(self,x,out=None): - - '''Returns O(x)''' - - - if out is None: - return self.range_geometry().allocate(value=0) - else: - out.fill(self.range_geometry().allocate(value=0))
- -
[docs] def adjoint(self,x, out=None): - - '''Returns O^{*}(y)''' - - if out is None: - return self.domain_geometry().allocate(value=0) - else: - out.fill(self.domain_geometry().allocate(value=0))
- -
[docs] def calculate_norm(self, **kwargs): - - '''Evaluates operator norm of ZeroOperator''' - - return 0
- - -
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/operators/ZeroOperator/index.html b/nightly/_modules/cil/optimisation/operators/ZeroOperator/index.html new file mode 100644 index 0000000000..31bd2251dd --- /dev/null +++ b/nightly/_modules/cil/optimisation/operators/ZeroOperator/index.html @@ -0,0 +1,571 @@ + + + + + + + + + + + cil.optimisation.operators.ZeroOperator — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.optimisation.operators.ZeroOperator

+# -*- coding: utf-8 -*-
+#  Copyright 2019 United Kingdom Research and Innovation
+#  Copyright 2019 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+import numpy as np
+from cil.framework import ImageData
+from cil.optimisation.operators import LinearOperator
+
+
[docs]class ZeroOperator(LinearOperator): + + r'''ZeroOperator: O: X -> Y, maps any element of :math:`x\in X` into the zero element :math:`\in Y, O(x) = O_{Y}` + + :param gm_domain: domain of the operator + :param gm_range: range of the operator, default: same as domain + + + Note: + + .. math:: + + O^{*}: Y^{*} -> X^{*} \text{(Adjoint)} + + < O(x), y > = < x, O^{*}(y) > + + ''' + + def __init__(self, domain_geometry, range_geometry=None): + if range_geometry is None: + range_geometry = domain_geometry.clone() + super(ZeroOperator, self).__init__(domain_geometry=domain_geometry, + range_geometry=range_geometry) + + + +
[docs] def direct(self,x,out=None): + + '''Returns O(x)''' + + + if out is None: + return self.range_geometry().allocate(value=0) + else: + out.fill(self.range_geometry().allocate(value=0))
+ +
[docs] def adjoint(self,x, out=None): + + '''Returns O^{*}(y)''' + + if out is None: + return self.domain_geometry().allocate(value=0) + else: + out.fill(self.domain_geometry().allocate(value=0))
+ +
[docs] def calculate_norm(self, **kwargs): + + '''Evaluates operator norm of ZeroOperator''' + + return 0
+ + +
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/cil/optimisation/utilities/sampler.html b/nightly/_modules/cil/optimisation/utilities/sampler/index.html similarity index 78% rename from nightly/_modules/cil/optimisation/utilities/sampler.html rename to nightly/_modules/cil/optimisation/utilities/sampler/index.html index 840a7d8b10..62dee7012d 100644 --- a/nightly/_modules/cil/optimisation/utilities/sampler.html +++ b/nightly/_modules/cil/optimisation/utilities/sampler/index.html @@ -1,196 +1,440 @@ + - + + + cil.optimisation.utilities.sampler — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.optimisation.utilities.sampler

 # -*- coding: utf-8 -*-
 #   This work is part of the Core Imaging Library (CIL) developed by CCPi
@@ -216,7 +460,7 @@ 

Source code for cil.optimisation.utilities.sampler

import time import numbers -
[docs]class Sampler(): +
[docs]class Sampler(): # TODO: Work out how to make the examples testable """ Initialises a sampler that returns and then increments indices from a sequence defined by a function. @@ -347,7 +591,7 @@

Source code for cil.optimisation.utilities.sampler

def current_iter_number(self): return self._iteration_number -
[docs] def next(self): +
[docs] def next(self): """ Returns a sample from the list of indices `{0, 1, …, N-1}, where N is the number of indices and increments the sampler. """ @@ -360,7 +604,7 @@

Source code for cil.optimisation.utilities.sampler

def __next__(self): return self.next() -
[docs] def get_samples(self, num_samples): +
[docs] def get_samples(self, num_samples): """ Generates a list of the first num_samples output by the sampler. Calling this does not increment the sampler index or affect the behaviour of the sampler . @@ -392,7 +636,7 @@

Source code for cil.optimisation.utilities.sampler

repres += "Probability weights : {} \n".format(self._prob_weights) return repres -
[docs] @staticmethod +
[docs] @staticmethod def sequential(num_indices): """ Instantiates a sampler that outputs sequential indices. @@ -462,7 +706,7 @@

Source code for cil.optimisation.utilities.sampler

return row_number + stride*column_number -
[docs] @staticmethod +
[docs] @staticmethod def staggered(num_indices, stride): """ Instantiates a sampler which outputs in a staggered order. @@ -512,7 +756,7 @@

Source code for cil.optimisation.utilities.sampler

return sampler
-
[docs] @staticmethod +
[docs] @staticmethod def random_with_replacement(num_indices, prob=None, seed=None): """ Instantiates a sampler which outputs an index between 0 - num_indices with a given probability. @@ -557,7 +801,7 @@

Source code for cil.optimisation.utilities.sampler

) return sampler
-
[docs] @staticmethod +
[docs] @staticmethod def random_without_replacement(num_indices, seed=None): """ Instantiates a sampler which outputs an index between 0 - num_indices. Once sampled the index will not be sampled again until all indices have been returned. @@ -591,7 +835,7 @@

Source code for cil.optimisation.utilities.sampler

) return sampler
-
[docs] @staticmethod +
[docs] @staticmethod def from_function(num_indices, function, prob_weights=None): """ Instantiate a sampler that wraps a function for index selection. @@ -742,7 +986,7 @@

Source code for cil.optimisation.utilities.sampler

return index -
[docs] @staticmethod +
[docs] @staticmethod def herman_meyer(num_indices): """ Instantiates a sampler which outputs in a Herman Meyer order. @@ -809,7 +1053,7 @@

Source code for cil.optimisation.utilities.sampler

return sampler
-
[docs]class SamplerRandom(Sampler): +
[docs]class SamplerRandom(Sampler): """ The user is recommended to not instantiate this class directly but instead use one of the static methods in the parent Sampler class that will return instances of different samplers. @@ -884,7 +1128,7 @@

Source code for cil.optimisation.utilities.sampler

out = self._sampling_list[location] return out -
[docs] def get_samples(self, num_samples): +
[docs] def get_samples(self, num_samples): """ Generates a list of the first num_samples output by the sampler. Calling this does not increment the sampler index or affect the behaviour of the sampler . @@ -919,37 +1163,59 @@

Source code for cil.optimisation.utilities.sampler

return repres
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/plugins/TomoPhantom.html b/nightly/_modules/cil/plugins/TomoPhantom/index.html similarity index 63% rename from nightly/_modules/cil/plugins/TomoPhantom.html rename to nightly/_modules/cil/plugins/TomoPhantom/index.html index 8769235999..9509ee2455 100644 --- a/nightly/_modules/cil/plugins/TomoPhantom.html +++ b/nightly/_modules/cil/plugins/TomoPhantom/index.html @@ -1,196 +1,440 @@ + - + + + cil.plugins.TomoPhantom — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.plugins.TomoPhantom

 # -*- coding: utf-8 -*-
 #  Copyright 2021 United Kingdom Research and Innovation
@@ -308,7 +552,7 @@ 

Source code for cil.plugins.TomoPhantom

     else:
         raise ValueError('Unsupported dimensionality. Expected 2 or 3, got {}'.format(dims))
 
-
[docs]def get_ImageData(num_model, geometry): +
[docs]def get_ImageData(num_model, geometry): '''Returns an ImageData relative to geometry with the model num_model from tomophantom :param num_model: model number @@ -390,37 +634,59 @@

Source code for cil.plugins.TomoPhantom

     return im_data
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/plugins/astra/operators/ProjectionOperator.html b/nightly/_modules/cil/plugins/astra/operators/ProjectionOperator.html deleted file mode 100644 index cb7e8c6acd..0000000000 --- a/nightly/_modules/cil/plugins/astra/operators/ProjectionOperator.html +++ /dev/null @@ -1,419 +0,0 @@ - - - - - - - - cil.plugins.astra.operators.ProjectionOperator — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.plugins.astra.operators.ProjectionOperator

-# -*- coding: utf-8 -*-
-#  Copyright 2020 United Kingdom Research and Innovation
-#  Copyright 2020 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-from cil.framework import DataOrder
-from cil.optimisation.operators import LinearOperator, ChannelwiseOperator
-from cil.framework.BlockGeometry import BlockGeometry
-from cil.optimisation.operators import BlockOperator
-from cil.plugins.astra.operators import AstraProjector3D
-from cil.plugins.astra.operators import AstraProjector2D
-import logging
-
-
-
[docs]class ProjectionOperator(LinearOperator): - """ - ProjectionOperator configures and calls appropriate ASTRA Projectors for your dataset. - - Parameters - ---------- - - image_geometry : ``ImageGeometry``, default used if None - A description of the area/volume to reconstruct - - acquisition_geometry : ``AcquisitionGeometry``, ``BlockGeometry`` - A description of the acquisition data. If passed a BlockGeometry it will return a BlockOperator. - - device : string, default='gpu' - 'gpu' will run on a compatible CUDA capable device using the ASTRA 3D CUDA Projectors, 'cpu' will run on CPU using the ASTRA 2D CPU Projectors - - Example - ------- - >>> from cil.plugins.astra import ProjectionOperator - >>> PO = ProjectionOperator(image.geometry, data.geometry) - >>> forward_projection = PO.direct(image) - >>> backward_projection = PO.adjoint(data) - - Notes - ----- - For multichannel data the ProjectionOperator will broadcast across all channels. - """ - def __new__(cls, image_geometry=None, acquisition_geometry=None, \ - device='gpu', **kwargs): - if isinstance(acquisition_geometry, BlockGeometry): - logging.info("BlockOperator is returned.") - - K = [] - for ag in acquisition_geometry: - K.append( - ProjectionOperator_ag(image_geometry=image_geometry, acquisition_geometry=ag, \ - device=device, **kwargs) - ) - return BlockOperator(*K) - else: - logging.info("Standard Operator is returned.") - return super(ProjectionOperator, - cls).__new__(ProjectionOperator_ag)
- - -class ProjectionOperator_ag(ProjectionOperator): - """ - ProjectionOperator configures and calls appropriate ASTRA Projectors for your dataset. - - Parameters - ---------- - - image_geometry : ImageGeometry, default used if None - A description of the area/volume to reconstruct - - acquisition_geometry : AcquisitionGeometry - A description of the acquisition data - - device : string, default='gpu' - 'gpu' will run on a compatible CUDA capable device using the ASTRA 3D CUDA Projectors, 'cpu' will run on CPU using the ASTRA 2D CPU Projectors - - Example - ------- - >>> from cil.plugins.astra import ProjectionOperator - >>> PO = ProjectionOperator(image.geometry, data.geometry) - >>> forward_projection = PO.direct(image) - >>> backward_projection = PO.adjoint(data) - - Notes - ----- - For multichannel data the ProjectionOperator will broadcast across all channels. - """ - - def __init__(self, - image_geometry=None, - acquisition_geometry=None, - device='gpu'): - - if acquisition_geometry is None: - raise TypeError( - "Please specify an acquisition_geometry to configure this operator" - ) - - if image_geometry is None: - image_geometry = acquisition_geometry.get_ImageGeometry() - - super(ProjectionOperator_ag, - self).__init__(domain_geometry=image_geometry, - range_geometry=acquisition_geometry) - - DataOrder.check_order_for_engine('astra', image_geometry) - DataOrder.check_order_for_engine('astra', acquisition_geometry) - - self.volume_geometry = image_geometry - self.sinogram_geometry = acquisition_geometry - - sinogram_geometry_sc = acquisition_geometry.get_slice(channel=0) - volume_geometry_sc = image_geometry.get_slice(channel=0) - - if device == 'gpu': - operator = AstraProjector3D(volume_geometry_sc, - sinogram_geometry_sc) - elif self.sinogram_geometry.dimension == '2D': - operator = AstraProjector2D(volume_geometry_sc, - sinogram_geometry_sc, - device=device) - else: - raise NotImplementedError("Cannot process 3D data without a GPU") - - if acquisition_geometry.channels > 1: - operator_full = ChannelwiseOperator( - operator, self.sinogram_geometry.channels, dimension='prepend') - self.operator = operator_full - else: - self.operator = operator - - def direct(self, IM, out=None): - '''Applies the direct of the operator i.e. the forward projection. - - Parameters - ---------- - IM : ImageData - The image/volume to be projected. - - out : DataContainer, optional - Fills the referenced DataContainer with the processed data and suppresses the return - - Returns - ------- - DataContainer - The processed data. Suppressed if `out` is passed - ''' - - return self.operator.direct(IM, out=out) - - def adjoint(self, DATA, out=None): - '''Applies the adjoint of the operator, i.e. the backward projection. - - Parameters - ---------- - DATA : AcquisitionData - The projections/sinograms to be projected. - - out : DataContainer, optional - Fills the referenced DataContainer with the processed data and suppresses the return - - Returns - ------- - DataContainer - The processed data. Suppressed if `out` is passed - ''' - return self.operator.adjoint(DATA, out=out) - - def calculate_norm(self): - return self.operator.norm() - - def domain_geometry(self): - return self.volume_geometry - - def range_geometry(self): - return self.sinogram_geometry -
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/plugins/astra/processors/FBP.html b/nightly/_modules/cil/plugins/astra/processors/FBP.html deleted file mode 100644 index ca29fa747b..0000000000 --- a/nightly/_modules/cil/plugins/astra/processors/FBP.html +++ /dev/null @@ -1,354 +0,0 @@ - - - - - - - - cil.plugins.astra.processors.FBP — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.plugins.astra.processors.FBP

-# -*- coding: utf-8 -*-
-#  Copyright 2019 United Kingdom Research and Innovation
-#  Copyright 2019 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-from cil.framework import DataProcessor
-from cil.framework import DataOrder
-from cil.plugins.astra.processors.FBP_Flexible import FBP_Flexible
-from cil.plugins.astra.processors.FDK_Flexible import FDK_Flexible
-from cil.plugins.astra.processors.FBP_Flexible import FBP_CPU
-import logging
-
-
[docs]class FBP(DataProcessor): - - """ - FBP configures and calls an appropriate ASTRA FBP or FDK algorithm for your dataset. - - The best results will be on data with circular trajectories of a 2PI angular range and equally spaced small angular steps. - - Parameters - ---------- - image_geometry : ImageGeometry, default used if None - A description of the area/volume to reconstruct - - acquisition_geometry : AcquisitionGeometry - A description of the acquisition data - - device : string, default='gpu' - 'gpu' will run on a compatible CUDA capable device using the ASTRA FDK_CUDA algorithm - 'cpu' will run on CPU using the ASTRA FBP algorithm - see Notes for limitations - - - Example - ------- - >>> from cil.plugins.astra import FBP - >>> fbp = FBP(image_geometry, data.geometry) - >>> fbp.set_input(data) - >>> reconstruction = fbp.get_ouput() - - - Notes - ----- - A CPU version is provided for simple 2D parallel-beam geometries only, any offsets and rotations in the acquisition geometry will be ignored. - - This uses the ram-lak filter only. - - """ - - - def __init__(self, image_geometry=None, acquisition_geometry=None, device='gpu', **kwargs): - - - sinogram_geometry = kwargs.get('sinogram_geometry', None) - volume_geometry = kwargs.get('volume_geometry', None) - - if sinogram_geometry is not None: - acquisition_geometry = sinogram_geometry - logging.warning("sinogram_geometry has been deprecated. Please use acquisition_geometry instead.") - - if acquisition_geometry is None: - raise TypeError("Please specify an acquisition_geometry to configure this processor") - - if volume_geometry is not None: - image_geometry = volume_geometry - logging.warning("volume_geometry has been deprecated. Please use image_geometry instead.") - - if image_geometry is None: - image_geometry = acquisition_geometry.get_ImageGeometry() - - DataOrder.check_order_for_engine('astra', image_geometry) - DataOrder.check_order_for_engine('astra', acquisition_geometry) - - if device == 'gpu': - if acquisition_geometry.geom_type == 'parallel': - processor = FBP_Flexible(image_geometry, acquisition_geometry) - else: - processor = FDK_Flexible(image_geometry, acquisition_geometry) - - else: - UserWarning("ASTRA back-projector running on CPU will not make use of enhanced geometry parameters") - - if acquisition_geometry.geom_type == 'cone': - raise NotImplementedError("Cannot process cone-beam data without a GPU") - - if acquisition_geometry.dimension == '2D': - processor = FBP_CPU(image_geometry, acquisition_geometry) - else: - raise NotImplementedError("Cannot process 3D data without a GPU") - - if acquisition_geometry.channels > 1: - raise NotImplementedError("Cannot process multi-channel data") - #processor_full = ChannelwiseProcessor(processor, self.acquisition_geometry.channels, dimension='prepend') - #self.processor = operator_full - - super(FBP, self).__init__( image_geometry=image_geometry, acquisition_geometry=acquisition_geometry, device=device, processor=processor) - -
[docs] def set_input(self, dataset): - return self.processor.set_input(dataset)
- - def get_input(self): - return self.processor.get_input() - -
[docs] def get_output(self, out=None): - return self.processor.get_output(out=out)
- - def check_input(self, dataset): - return self.processor.check_input(dataset) - - def process(self, out=None): - return self.processor.process(out=out)
-
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/plugins/ccpi_regularisation/functions/regularisers.html b/nightly/_modules/cil/plugins/ccpi_regularisation/functions/regularisers/index.html similarity index 73% rename from nightly/_modules/cil/plugins/ccpi_regularisation/functions/regularisers.html rename to nightly/_modules/cil/plugins/ccpi_regularisation/functions/regularisers/index.html index 5e728009e8..3a46071114 100644 --- a/nightly/_modules/cil/plugins/ccpi_regularisation/functions/regularisers.html +++ b/nightly/_modules/cil/plugins/ccpi_regularisation/functions/regularisers/index.html @@ -1,196 +1,440 @@ + - + + + cil.plugins.ccpi_regularisation.functions.regularisers — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

 # -*- coding: utf-8 -*-
 #  Copyright 2020 United Kingdom Research and Innovation
@@ -325,7 +569,7 @@ 

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< return 0.0 -
[docs]class FGP_TV(TV_Base): +
[docs]class FGP_TV(TV_Base): r""" Fast Gradient Projection Total Variation (FGP_TV) @@ -467,9 +711,9 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< if len(input.shape) > 3: raise ValueError('{} cannot work on more than 3D. Got {}'.format(self.__class__.__name__, input.geometry.length))
-
[docs]class TGV(RegulariserFunction): +
[docs]class TGV(RegulariserFunction): -
[docs] def __init__(self, alpha=1, gamma=1, max_iteration=100, tolerance=0, device='cpu' , **kwargs): +
[docs] def __init__(self, alpha=1, gamma=1, max_iteration=100, tolerance=0, device='cpu' , **kwargs): '''Creator of Total Generalised Variation Function :param alpha: regularisation parameter @@ -495,7 +739,7 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< # raise ValueError('iter_TGV parameter has been superseded by num_iter. Use that instead.') self.num_iter = kwargs.get('iter_TGV')
-
[docs] def __call__(self,x): +
[docs] def __call__(self,x): warnings.warn("{}: the __call__ method is not implemented. Returning NaN.".format(self.__class__.__name__)) return np.nan
@property @@ -527,11 +771,11 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< # Stopping Criteria || u^k - u^(k-1) ||_{2} / || u^{k} ||_{2} return res, info -
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): warnings.warn("{}: the convex_conjugate method is not implemented. Returning NaN.".format(self.__class__.__name__)) return np.nan
-
[docs] def __rmul__(self, scalar): +
[docs] def __rmul__(self, scalar): '''Define the multiplication with a scalar this changes the regularisation parameter in the plugin''' @@ -553,7 +797,7 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< raise ValueError('{} cannot work on more than 3D. Got {}'.format(self.__class__.__name__, input.geometry.length))
-
[docs]class FGP_dTV(RegulariserFunction): +
[docs]class FGP_dTV(RegulariserFunction): '''Creator of FGP_dTV Function :param reference: reference image @@ -573,7 +817,7 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< :param device: determines if the code runs on CPU or GPU :type device: string, default 'cpu', can be 'gpu' if GPU is installed ''' -
[docs] def __init__(self, reference, alpha=1, max_iteration=100, +
[docs] def __init__(self, reference, alpha=1, max_iteration=100, tolerance=0, eta=0.01, isotropic=True, nonnegativity=True, device='cpu'): if isotropic == True: @@ -593,7 +837,7 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< self.reference = np.asarray(reference.as_array(), dtype=np.float32) self.eta = eta
-
[docs] def __call__(self,x): +
[docs] def __call__(self,x): warnings.warn("{}: the __call__ method is not implemented. Returning NaN.".format(self.__class__.__name__)) return np.nan
@@ -610,11 +854,11 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< self.device) return res, info -
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): warnings.warn("{}: the convex_conjugate method is not implemented. Returning NaN.".format(self.__class__.__name__)) return np.nan
-
[docs] def __rmul__(self, scalar): +
[docs] def __rmul__(self, scalar): '''Define the multiplication with a scalar this changes the regularisation parameter in the plugin''' @@ -628,9 +872,9 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< if len(input.shape) > 3: raise ValueError('{} cannot work on more than 3D. Got {}'.format(self.__class__.__name__, input.geometry.length))
-
[docs]class TNV(RegulariserFunction): +
[docs]class TNV(RegulariserFunction): -
[docs] def __init__(self,alpha=1, max_iteration=100, tolerance=0): +
[docs] def __init__(self,alpha=1, max_iteration=100, tolerance=0): '''Creator of TNV Function :param alpha: regularisation parameter @@ -645,7 +889,7 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< self.max_iteration = max_iteration self.tolerance = tolerance
-
[docs] def __call__(self,x): +
[docs] def __call__(self,x): warnings.warn("{}: the __call__ method is not implemented. Returning NaN.".format(self.__class__.__name__)) return np.nan
@@ -659,11 +903,11 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< self.tolerance) return res, [] -
[docs] def convex_conjugate(self, x): +
[docs] def convex_conjugate(self, x): warnings.warn("{}: the convex_conjugate method is not implemented. Returning NaN.".format(self.__class__.__name__)) return np.nan
-
[docs] def __rmul__(self, scalar): +
[docs] def __rmul__(self, scalar): '''Define the multiplication with a scalar this changes the regularisation parameter in the plugin''' @@ -673,7 +917,7 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

< self.alpha *= scalar return self
-
[docs] def check_input(self, input): +
[docs] def check_input(self, input): '''TNV requires 2D+channel data with the first dimension as the channel dimension''' if isinstance(input, DataContainer): DataOrder.check_order_for_engine('cil', input.geometry) @@ -688,37 +932,59 @@

Source code for cil.plugins.ccpi_regularisation.functions.regularisers

<
-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/plugins/tigre/FBP.html b/nightly/_modules/cil/plugins/tigre/FBP.html deleted file mode 100644 index 47e17b6b31..0000000000 --- a/nightly/_modules/cil/plugins/tigre/FBP.html +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - cil.plugins.tigre.FBP — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.plugins.tigre.FBP

-# -*- coding: utf-8 -*-
-#  Copyright 2021 United Kingdom Research and Innovation
-#  Copyright 2021 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-from cil.framework import DataProcessor, ImageData
-from cil.framework import DataOrder
-from cil.plugins.tigre import CIL2TIGREGeometry
-import logging
-import numpy as np
-
-try:
-    from tigre.algorithms import fdk, fbp
-except ModuleNotFoundError:
-    raise ModuleNotFoundError("This plugin requires the additional package TIGRE\n" +
-            "Please install it via conda as tigre from the ccpi channel")
-
-
[docs]class FBP(DataProcessor): - - '''FBP Filtered Back Projection is a reconstructor for 2D and 3D parallel and cone-beam geometries. - It is able to back-project circular trajectories with 2 PI angular range and equally spaced angular steps. - - This uses the ram-lak filter - This is provided for simple and offset parallel-beam geometries only - - acquisition_geometry : AcquisitionGeometry - A description of the acquisition data - - image_geometry : ImageGeometry, default used if None - A description of the area/volume to reconstruct - - Example - ------- - >>> from cil.plugins.tigre import FBP - >>> fbp = FBP(image_geometry, data.geometry) - >>> fbp.set_input(data) - >>> reconstruction = fbp.get_ouput() - - ''' - - def __init__(self, image_geometry=None, acquisition_geometry=None, **kwargs): - - - sinogram_geometry = kwargs.get('sinogram_geometry', None) - volume_geometry = kwargs.get('volume_geometry', None) - - if sinogram_geometry is not None: - acquisition_geometry = sinogram_geometry - logging.warning("sinogram_geometry has been deprecated. Please use acquisition_geometry instead.") - - if acquisition_geometry is None: - raise TypeError("Please specify an acquisition_geometry to configure this processor") - - if volume_geometry is not None: - image_geometry = volume_geometry - logging.warning("volume_geometry has been deprecated. Please use image_geometry instead.") - - if image_geometry is None: - image_geometry = acquisition_geometry.get_ImageGeometry() - - device = kwargs.get('device', 'gpu') - if device != 'gpu': - raise ValueError("TIGRE FBP is GPU only. Got device = {}".format(device)) - - DataOrder.check_order_for_engine('tigre', image_geometry) - DataOrder.check_order_for_engine('tigre', acquisition_geometry) - - tigre_geom, tigre_angles = CIL2TIGREGeometry.getTIGREGeometry(image_geometry,acquisition_geometry) - - super(FBP, self).__init__( image_geometry = image_geometry, acquisition_geometry = acquisition_geometry,\ - tigre_geom=tigre_geom, tigre_angles=tigre_angles) - - - def check_input(self, dataset): - - if self.acquisition_geometry.channels != 1: - raise ValueError("Expected input data to be single channel, got {0}"\ - .format(self.acquisition_geometry.channels)) - - DataOrder.check_order_for_engine('tigre', dataset.geometry) - return True - - def process(self, out=None): - - if self.tigre_geom.is2D: - data_temp = np.expand_dims(self.get_input().as_array(), axis=1) - - if self.acquisition_geometry.geom_type == 'cone': - arr_out = fdk(data_temp, self.tigre_geom, self.tigre_angles) - else: - arr_out = fbp(data_temp, self.tigre_geom, self.tigre_angles) - arr_out = np.squeeze(arr_out, axis=0) - else: - if self.acquisition_geometry.geom_type == 'cone': - arr_out = fdk(self.get_input().as_array(), self.tigre_geom, self.tigre_angles) - else: - arr_out = fbp(self.get_input().as_array(), self.tigre_geom, self.tigre_angles) - - if out is None: - out = ImageData(arr_out, deep_copy=False, geometry=self.image_geometry.copy(), suppress_warning=True) - return out - else: - out.fill(arr_out)
- -
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/plugins/tigre/ProjectionOperator.html b/nightly/_modules/cil/plugins/tigre/ProjectionOperator.html deleted file mode 100644 index 544f680042..0000000000 --- a/nightly/_modules/cil/plugins/tigre/ProjectionOperator.html +++ /dev/null @@ -1,487 +0,0 @@ - - - - - - - - cil.plugins.tigre.ProjectionOperator — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.plugins.tigre.ProjectionOperator

-# -*- coding: utf-8 -*-
-#  Copyright 2021 United Kingdom Research and Innovation
-#  Copyright 2021 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-from cil.framework import ImageData, AcquisitionData, AcquisitionGeometry
-from cil.framework import DataOrder
-from cil.framework.BlockGeometry import BlockGeometry
-from cil.optimisation.operators import BlockOperator
-from cil.optimisation.operators import LinearOperator
-from cil.plugins.tigre import CIL2TIGREGeometry
-import numpy as np
-import logging
-
-try:
-    from _Atb import _Atb_ext as Atb
-    from _Ax import _Ax_ext as Ax
-
-except ModuleNotFoundError:
-    raise ModuleNotFoundError(
-        "This plugin requires the additional package TIGRE\n" +
-        "Please install it via conda as tigre from the ccpi channel")
-
-try:
-    from tigre.utilities.gpu import GpuIds
-    has_gpu_sel = True
-except ModuleNotFoundError:
-    has_gpu_sel = False
-
-
-
[docs]class ProjectionOperator(LinearOperator): - """ - ProjectionOperator configures and calls TIGRE Projectors for your dataset. - - Please refer to the TIGRE documentation for futher descriptions - https://github.com/CERN/TIGRE - https://iopscience.iop.org/article/10.1088/2057-1976/2/5/055010 - - - Parameters - ---------- - - image_geometry : `ImageGeometry`, default used if None - A description of the area/volume to reconstruct - - acquisition_geometry :`AcquisitionGeometry`, `BlockGeometry` - A description of the acquisition data. If passed a BlockGeometry it will return a BlockOperator. - - direct_method : str, default 'interpolated' - The method used by the forward projector, 'Siddon' for ray-voxel intersection, 'interpolated' for interpolated projection - - adjoint_weights : str, default 'matched' - The weighting method used by the cone-beam backward projector, 'matched' for weights to approximately match the 'interpolated' forward projector, 'FDK' for FDK weights - - Example - ------- - >>> from cil.plugins.tigre import ProjectionOperator - >>> PO = ProjectionOperator(image.geometry, data.geometry) - >>> forward_projection = PO.direct(image) - >>> backward_projection = PO.adjoint(data) - - """ - def __new__(cls, image_geometry=None, acquisition_geometry=None, \ - direct_method='interpolated',adjoint_weights='matched', **kwargs): - if isinstance(acquisition_geometry, BlockGeometry): - logging.info("BlockOperator is returned.") - - K = [] - for ag in acquisition_geometry: - K.append( - ProjectionOperator_ag(image_geometry=image_geometry, acquisition_geometry=ag, \ - direct_method=direct_method, adjoint_weights=adjoint_weights, **kwargs) - ) - return BlockOperator(*K) - else: - logging.info("Standard Operator is returned.") - return super(ProjectionOperator, - cls).__new__(ProjectionOperator_ag)
- - -class ProjectionOperator_ag(ProjectionOperator): - '''TIGRE Projection Operator''' - - def __init__(self, - image_geometry=None, - acquisition_geometry=None, - direct_method='interpolated', - adjoint_weights='matched', - **kwargs): - """ - ProjectionOperator configures and calls TIGRE Projectors for your dataset. - - Please refer to the TIGRE documentation for futher descriptions - https://github.com/CERN/TIGRE - https://iopscience.iop.org/article/10.1088/2057-1976/2/5/055010 - - - Parameters - ---------- - - image_geometry : ImageGeometry, default used if None - A description of the area/volume to reconstruct - - acquisition_geometry : AcquisitionGeometry - A description of the acquisition data - - direct_method : str, default 'interpolated' - The method used by the forward projector, 'Siddon' for ray-voxel intersection, 'interpolated' for interpolated projection - - adjoint_weights : str, default 'matched' - The weighting method used by the cone-beam backward projector, 'matched' for weights to approximately match the 'interpolated' forward projector, 'FDK' for FDK weights - - Example - ------- - >>> from cil.plugins.tigre import ProjectionOperator - >>> PO = ProjectionOperator(image.geometry, data.geometry) - >>> forward_projection = PO.direct(image) - >>> backward_projection = PO.adjoint(data) - - """ - - acquisition_geometry_old = kwargs.get('aquisition_geometry', None) - - if acquisition_geometry_old is not None: - acquisition_geometry = acquisition_geometry_old - logging.warning( - "aquisition_geometry has been deprecated. Please use acquisition_geometry instead." - ) - - if acquisition_geometry is None: - raise TypeError( - "Please specify an acquisition_geometry to configure this operator" - ) - - if image_geometry == None: - image_geometry = acquisition_geometry.get_ImageGeometry() - - device = kwargs.get('device', 'gpu') - if device != 'gpu': - raise ValueError( - "TIGRE projectors are GPU only. Got device = {}".format( - device)) - - DataOrder.check_order_for_engine('tigre', image_geometry) - DataOrder.check_order_for_engine('tigre', acquisition_geometry) - - super(ProjectionOperator,self).__init__(domain_geometry=image_geometry,\ - range_geometry=acquisition_geometry) - - if direct_method not in ['interpolated', 'Siddon']: - raise ValueError( - "direct_method expected 'interpolated' or 'Siddon' got {}". - format(direct_method)) - - if adjoint_weights not in ['matched', 'FDK']: - raise ValueError( - "adjoint_weights expected 'matched' or 'FDK' got {}".format( - adjoint_weights)) - - self.method = {'direct': direct_method, 'adjoint': adjoint_weights} - - #set up TIGRE geometry - tigre_geom, tigre_angles = CIL2TIGREGeometry.getTIGREGeometry( - image_geometry, acquisition_geometry) - - tigre_geom.check_geo(tigre_angles) - tigre_geom.cast_to_single() - self.tigre_geom = tigre_geom - - #set up TIGRE GPU targets (from 2.2) - if has_gpu_sel: - self.gpuids = GpuIds() - - def __call_Ax(self, data): - if has_gpu_sel: - return Ax(data, self.tigre_geom, self.tigre_geom.angles, - self.method['direct'], self.tigre_geom.mode, self.gpuids) - else: - return Ax(data, self.tigre_geom, self.tigre_geom.angles, - self.method['direct'], self.tigre_geom.mode) - - def direct(self, x, out=None): - - data = x.as_array() - - if self.tigre_geom.is2D: - data_temp = np.expand_dims(data, axis=0) - arr_out = self.__call_Ax(data_temp) - arr_out = np.squeeze(arr_out, axis=1) - else: - arr_out = self.__call_Ax(data) - - #if single angle projection remove the dimension for CIL - if arr_out.shape[0] == 1: - arr_out = np.squeeze(arr_out, axis=0) - - if out is None: - out = AcquisitionData(arr_out, - deep_copy=False, - geometry=self._range_geometry.copy(), - suppress_warning=True) - return out - else: - out.fill(arr_out) - - def __call_Atb(self, data): - if has_gpu_sel: - return Atb(data, self.tigre_geom, self.tigre_geom.angles, - self.method['adjoint'], self.tigre_geom.mode, - self.gpuids) - else: - return Atb(data, self.tigre_geom, self.tigre_geom.angles, - self.method['adjoint'], self.tigre_geom.mode) - - def adjoint(self, x, out=None): - - data = x.as_array() - - #if single angle projection add the dimension in for TIGRE - if x.dimension_labels[0] != AcquisitionGeometry.ANGLE: - data = np.expand_dims(data, axis=0) - - if self.tigre_geom.is2D: - data = np.expand_dims(data, axis=1) - arr_out = self.__call_Atb(data) - arr_out = np.squeeze(arr_out, axis=0) - else: - arr_out = self.__call_Atb(data) - - if out is None: - out = ImageData(arr_out, - deep_copy=False, - geometry=self._domain_geometry.copy(), - suppress_warning=True) - return out - else: - out.fill(arr_out) - - def domain_geometry(self): - return self._domain_geometry - - def range_geometry(self): - return self._range_geometry -
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/processors/AbsorptionTransmissionConverter.html b/nightly/_modules/cil/processors/AbsorptionTransmissionConverter.html deleted file mode 100644 index fa60474270..0000000000 --- a/nightly/_modules/cil/processors/AbsorptionTransmissionConverter.html +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - - cil.processors.AbsorptionTransmissionConverter — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.processors.AbsorptionTransmissionConverter

-# -*- coding: utf-8 -*-
-#  Copyright 2021 United Kingdom Research and Innovation
-#  Copyright 2021 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-
-from cil.framework import DataProcessor, AcquisitionData, ImageData, DataContainer, AcquisitionGeometry, ImageGeometry
-import warnings
-import numpy
-
-
-
[docs]class AbsorptionTransmissionConverter(DataProcessor): - - '''Processor to convert from absorption measurements to transmission - - :param white_level: A float defining incidence intensity in the Beer-Lambert law. - :type white_level: float, optional - :return: returns AcquisitionData, ImageData or DataContainer depending on input data type - :rtype: AcquisitionData, ImageData or DataContainer - - Processor first multiplies data by -1, then calculates exponent - and scales result by white_level (default=1) - ''' - - def __init__(self, - white_level=1): - - kwargs = {'white_level': white_level} - - super(AbsorptionTransmissionConverter, self).__init__(**kwargs) - - def check_input(self, data): - - if not (issubclass(type(data), DataContainer)): - raise TypeError('Processor supports only following data types:\n' + - ' - ImageData\n - AcquisitionData\n' + - ' - DataContainer') - return True - - def process(self, out=None): - - data = self.get_input() - if out is None: - out = data.multiply(-1.0) - else: - data.multiply(-1.0, out=out) - - out.exp(out=out) - out.multiply(numpy.float32(self.white_level), out=out) - return out
-
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/processors/AbsorptionTransmissionConverter/index.html b/nightly/_modules/cil/processors/AbsorptionTransmissionConverter/index.html new file mode 100644 index 0000000000..d6efb5a588 --- /dev/null +++ b/nightly/_modules/cil/processors/AbsorptionTransmissionConverter/index.html @@ -0,0 +1,560 @@ + + + + + + + + + + + cil.processors.AbsorptionTransmissionConverter — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.processors.AbsorptionTransmissionConverter

+# -*- coding: utf-8 -*-
+#  Copyright 2021 United Kingdom Research and Innovation
+#  Copyright 2021 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+
+from cil.framework import DataProcessor, AcquisitionData, ImageData, DataContainer, AcquisitionGeometry, ImageGeometry
+import warnings
+import numpy
+
+
+
[docs]class AbsorptionTransmissionConverter(DataProcessor): + + '''Processor to convert from absorption measurements to transmission + + :param white_level: A float defining incidence intensity in the Beer-Lambert law. + :type white_level: float, optional + :return: returns AcquisitionData, ImageData or DataContainer depending on input data type + :rtype: AcquisitionData, ImageData or DataContainer + + Processor first multiplies data by -1, then calculates exponent + and scales result by white_level (default=1) + ''' + + def __init__(self, + white_level=1): + + kwargs = {'white_level': white_level} + + super(AbsorptionTransmissionConverter, self).__init__(**kwargs) + + def check_input(self, data): + + if not (issubclass(type(data), DataContainer)): + raise TypeError('Processor supports only following data types:\n' + + ' - ImageData\n - AcquisitionData\n' + + ' - DataContainer') + return True + + def process(self, out=None): + + data = self.get_input() + if out is None: + out = data.multiply(-1.0) + else: + data.multiply(-1.0, out=out) + + out.exp(out=out) + out.multiply(numpy.float32(self.white_level), out=out) + return out
+
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/cil/processors/Binner.html b/nightly/_modules/cil/processors/Binner/index.html similarity index 59% rename from nightly/_modules/cil/processors/Binner.html rename to nightly/_modules/cil/processors/Binner/index.html index 5d643574eb..0aadab16e3 100644 --- a/nightly/_modules/cil/processors/Binner.html +++ b/nightly/_modules/cil/processors/Binner/index.html @@ -1,196 +1,440 @@ + - + + + cil.processors.Binner — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.processors.Binner

 # -*- coding: utf-8 -*-
 #  Copyright 2021 United Kingdom Research and Innovation
@@ -224,7 +468,7 @@ 

Source code for cil.processors.Binner

 # so Binner has been implemented as a child of Slicer. This makes use
 # of commonality and redefines only the methods that differ. These methods
 # dictate the style of slicer
-
[docs]class Binner(Slicer): +
[docs]class Binner(Slicer): """This creates a Binner processor. @@ -381,37 +625,59 @@

Source code for cil.processors.Binner

 
 
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/processors/CentreOfRotationCorrector.html b/nightly/_modules/cil/processors/CentreOfRotationCorrector.html deleted file mode 100644 index ffa9bf4844..0000000000 --- a/nightly/_modules/cil/processors/CentreOfRotationCorrector.html +++ /dev/null @@ -1,374 +0,0 @@ - - - - - - - - cil.processors.CentreOfRotationCorrector — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.processors.CentreOfRotationCorrector

-# -*- coding: utf-8 -*-
-#  Copyright 2020 United Kingdom Research and Innovation
-#  Copyright 2020 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-from cil.framework import DataProcessor
-from cil.processors.CofR_xcorrelation import CofR_xcorrelation
-from cil.processors.CofR_image_sharpness import CofR_image_sharpness
-
-
-
[docs]class CentreOfRotationCorrector(DataProcessor): - """ - This class contains methods to create a CentreOfRotationCorrector processor using the desired algorithm. - """ - -
[docs] @staticmethod - def xcorrelation(slice_index='centre', projection_index=0, ang_tol=0.1): - r'''This creates a CentreOfRotationCorrector processor using the cross-correlation algorithm. - - For use on parallel-beam geometry it requires two projections 180 degree apart. - - Parameters - ---------- - - slice_index : int, str='centre', default='centre' - An integer defining the vertical slice to run the algorithm on. - - projection_index : int - An integer defining the first projection the algorithm will use. The second projection at 180 degrees will be located automatically. - - ang_tol : float, default=0.1 - The angular tolerance in degrees between the two input projections 180 degree gap - - Example - ------- - >>> from cil.processors import CentreOfRotationCorrector - >>> processor = CentreOfRotationCorrector.xcorrelation('centre') - >>> processor.set_input(data) - >>> data_centred = processor.get_ouput() - - Example - ------- - >>> from cil.processors import CentreOfRotationCorrector - >>> processor = CentreOfRotationCorrector.xcorrelation(slice_index=120) - >>> processor.set_input(data) - >>> processor.get_ouput(out=data) - - - Example - ------- - >>> from cil.processors import CentreOfRotationCorrector - >>> import logging - >>> logging.basicConfig(level=logging.WARNING) - >>> cil_log_level = logging.getLogger('cil.processors') - >>> cil_log_level.setLevel(logging.DEBUG) - - >>> processor = CentreOfRotationCorrector.xcorrelation(slice_index=120) - >>> processor.set_input(data) - >>> data_centred = processor.get_ouput() - - - Note - ---- - setting logging to 'debug' will give you more information about the algorithm progress - - - - ''' - processor = CofR_xcorrelation(slice_index, projection_index, ang_tol) - return processor
- - -
[docs] @staticmethod - def image_sharpness(slice_index='centre', backend='tigre', tolerance=0.005, search_range=None, initial_binning=None, **kwargs): - """This creates a CentreOfRotationCorrector processor. - - The processor will find the centre offset by maximising the sharpness of a reconstructed slice. - - Can be used on single slice parallel-beam, and centre slice cone beam geometry. For use only with datasets that can be reconstructed with FBP/FDK. - - Parameters - ---------- - - slice_index : int, str, default='centre' - An integer defining the vertical slice to run the algorithm on. The special case slice 'centre' is the default. - - backend : {'tigre', 'astra'} - The backend to use for the reconstruction - - tolerance : float, default=0.005 - The tolerance of the fit in pixels, the default is 1/200 of a pixel. This is a stopping criteria, not a statement of accuracy of the algorithm. - - search_range : int - The range in pixels to search either side of the panel centre. If `None` a quarter of the width of the panel is used. - - initial_binning : int - The size of the bins for the initial search. If `None` will bin the image to a step corresponding to <128 pixels. The fine search will be on unbinned data. - - Other Parameters - ---------------- - **kwargs : dict - FBP : The FBP class to use as the backend imported from `cil.plugins.[backend].FBP` - This has been deprecated please use 'backend' instead - - - Example - ------- - from cil.processors import CentreOfRotationCorrector - - processor = CentreOfRotationCorrector.image_sharpness('centre', 'tigre') - processor.set_input(data) - data_centred = processor.get_output() - - - Example - ------- - from cil.processors import CentreOfRotationCorrector - - processor = CentreOfRotationCorrector.image_sharpness(slice_index=120, 'astra') - processor.set_input(data) - processor.get_output(out=data) - - - Note - ---- - For best results data should be 360deg which leads to blurring with incorrect geometry. - This method is unreliable on half-scan data with 'tuning-fork' style artifacts. - - """ - processor = CofR_image_sharpness(slice_index=slice_index, backend=backend, tolerance=tolerance, search_range=search_range, initial_binning=initial_binning, **kwargs) - return processor
-
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/processors/CentreOfRotationCorrector/index.html b/nightly/_modules/cil/processors/CentreOfRotationCorrector/index.html new file mode 100644 index 0000000000..7931b9e5e6 --- /dev/null +++ b/nightly/_modules/cil/processors/CentreOfRotationCorrector/index.html @@ -0,0 +1,640 @@ + + + + + + + + + + + cil.processors.CentreOfRotationCorrector — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.processors.CentreOfRotationCorrector

+# -*- coding: utf-8 -*-
+#  Copyright 2020 United Kingdom Research and Innovation
+#  Copyright 2020 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+from cil.framework import DataProcessor
+from cil.processors.CofR_xcorrelation import CofR_xcorrelation
+from cil.processors.CofR_image_sharpness import CofR_image_sharpness
+
+
+
[docs]class CentreOfRotationCorrector(DataProcessor): + """ + This class contains methods to create a CentreOfRotationCorrector processor using the desired algorithm. + """ + +
[docs] @staticmethod + def xcorrelation(slice_index='centre', projection_index=0, ang_tol=0.1): + r'''This creates a CentreOfRotationCorrector processor using the cross-correlation algorithm. + + For use on parallel-beam geometry it requires two projections 180 degree apart. + + Parameters + ---------- + + slice_index : int, str='centre', default='centre' + An integer defining the vertical slice to run the algorithm on. + + projection_index : int + An integer defining the first projection the algorithm will use. The second projection at 180 degrees will be located automatically. + + ang_tol : float, default=0.1 + The angular tolerance in degrees between the two input projections 180 degree gap + + Example + ------- + >>> from cil.processors import CentreOfRotationCorrector + >>> processor = CentreOfRotationCorrector.xcorrelation('centre') + >>> processor.set_input(data) + >>> data_centred = processor.get_ouput() + + Example + ------- + >>> from cil.processors import CentreOfRotationCorrector + >>> processor = CentreOfRotationCorrector.xcorrelation(slice_index=120) + >>> processor.set_input(data) + >>> processor.get_ouput(out=data) + + + Example + ------- + >>> from cil.processors import CentreOfRotationCorrector + >>> import logging + >>> logging.basicConfig(level=logging.WARNING) + >>> cil_log_level = logging.getLogger('cil.processors') + >>> cil_log_level.setLevel(logging.DEBUG) + + >>> processor = CentreOfRotationCorrector.xcorrelation(slice_index=120) + >>> processor.set_input(data) + >>> data_centred = processor.get_ouput() + + + Note + ---- + setting logging to 'debug' will give you more information about the algorithm progress + + + + ''' + processor = CofR_xcorrelation(slice_index, projection_index, ang_tol) + return processor
+ + +
[docs] @staticmethod + def image_sharpness(slice_index='centre', backend='tigre', tolerance=0.005, search_range=None, initial_binning=None, **kwargs): + """This creates a CentreOfRotationCorrector processor. + + The processor will find the centre offset by maximising the sharpness of a reconstructed slice. + + Can be used on single slice parallel-beam, and centre slice cone beam geometry. For use only with datasets that can be reconstructed with FBP/FDK. + + Parameters + ---------- + + slice_index : int, str, default='centre' + An integer defining the vertical slice to run the algorithm on. The special case slice 'centre' is the default. + + backend : {'tigre', 'astra'} + The backend to use for the reconstruction + + tolerance : float, default=0.005 + The tolerance of the fit in pixels, the default is 1/200 of a pixel. This is a stopping criteria, not a statement of accuracy of the algorithm. + + search_range : int + The range in pixels to search either side of the panel centre. If `None` a quarter of the width of the panel is used. + + initial_binning : int + The size of the bins for the initial search. If `None` will bin the image to a step corresponding to <128 pixels. The fine search will be on unbinned data. + + Other Parameters + ---------------- + **kwargs : dict + FBP : The FBP class to use as the backend imported from `cil.plugins.[backend].FBP` - This has been deprecated please use 'backend' instead + + + Example + ------- + from cil.processors import CentreOfRotationCorrector + + processor = CentreOfRotationCorrector.image_sharpness('centre', 'tigre') + processor.set_input(data) + data_centred = processor.get_output() + + + Example + ------- + from cil.processors import CentreOfRotationCorrector + + processor = CentreOfRotationCorrector.image_sharpness(slice_index=120, 'astra') + processor.set_input(data) + processor.get_output(out=data) + + + Note + ---- + For best results data should be 360deg which leads to blurring with incorrect geometry. + This method is unreliable on half-scan data with 'tuning-fork' style artifacts. + + """ + processor = CofR_image_sharpness(slice_index=slice_index, backend=backend, tolerance=tolerance, search_range=search_range, initial_binning=initial_binning, **kwargs) + return processor
+
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/cil/processors/MaskGenerator.html b/nightly/_modules/cil/processors/MaskGenerator/index.html similarity index 79% rename from nightly/_modules/cil/processors/MaskGenerator.html rename to nightly/_modules/cil/processors/MaskGenerator/index.html index 077f6d8522..ec3d3ffe3c 100644 --- a/nightly/_modules/cil/processors/MaskGenerator.html +++ b/nightly/_modules/cil/processors/MaskGenerator/index.html @@ -1,196 +1,440 @@ + - + + + cil.processors.MaskGenerator — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.processors.MaskGenerator

 # -*- coding: utf-8 -*-
 #  Copyright 2021 United Kingdom Research and Innovation
@@ -216,12 +460,12 @@ 

Source code for cil.processors.MaskGenerator

import numpy
 from scipy import special, ndimage
 
-
[docs]class MaskGenerator(DataProcessor): +
[docs]class MaskGenerator(DataProcessor): r''' Processor to detect outliers and return a mask with 0 where outliers were detected, and 1 for other pixels. Please use the desiried method to configure a processor for your needs. ''' -
[docs] @staticmethod +
[docs] @staticmethod def special_values(nan=True, inf=True): r'''This creates a MaskGenerator processor which generates a mask for inf and/or nan values. @@ -244,7 +488,7 @@

Source code for cil.processors.MaskGenerator

return processor
-
[docs] @staticmethod +
[docs] @staticmethod def threshold(min_val=None, max_val=None): r'''This creates a MaskGenerator processor which generates a mask for values outside boundaries @@ -256,7 +500,7 @@

Source code for cil.processors.MaskGenerator

processor = MaskGenerator(mode='threshold', threshold_value=(min_val,max_val))
         return processor
-
[docs] @staticmethod +
[docs] @staticmethod def quantile(min_quantile=None, max_quantile=None): r'''This creates a MaskGenerator processor which generates a mask for values outside boundaries @@ -268,7 +512,7 @@

Source code for cil.processors.MaskGenerator

processor = MaskGenerator(mode='quantile', quantiles=(min_quantile,max_quantile))
         return processor
-
[docs] @staticmethod +
[docs] @staticmethod def mean(axis=None, threshold_factor=3, window=None): r'''This creates a MaskGenerator processor which generates a mask for values outside a multiple of standard-devaiations from the mean. @@ -288,7 +532,7 @@

Source code for cil.processors.MaskGenerator

return processor
-
[docs] @staticmethod +
[docs] @staticmethod def median(axis=None, threshold_factor=3, window=None): r'''This creates a MaskGenerator processor which generates a mask for values outside a multiple of median absolute deviation (MAD) from the mean. @@ -594,37 +838,59 @@

Source code for cil.processors.MaskGenerator

return (lower_val, upper_val)
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/processors/Masker.html b/nightly/_modules/cil/processors/Masker/index.html similarity index 70% rename from nightly/_modules/cil/processors/Masker.html rename to nightly/_modules/cil/processors/Masker/index.html index ed7b065628..ba84bb9dd2 100644 --- a/nightly/_modules/cil/processors/Masker.html +++ b/nightly/_modules/cil/processors/Masker/index.html @@ -1,196 +1,440 @@ + - + + + cil.processors.Masker — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.processors.Masker

 # -*- coding: utf-8 -*-
 #  Copyright 2021 United Kingdom Research and Innovation
@@ -216,12 +460,12 @@ 

Source code for cil.processors.Masker

 import numpy
 from scipy import interpolate
 
-
[docs]class Masker(DataProcessor): +
[docs]class Masker(DataProcessor): r''' Processor to fill missing values provided by mask. Please use the desiried method to configure a processor for your needs. ''' -
[docs] @staticmethod +
[docs] @staticmethod def value(mask=None, value=0): r'''This sets the masked values of the input data to the requested value. @@ -235,7 +479,7 @@

Source code for cil.processors.Masker

 
         return processor
-
[docs] @staticmethod +
[docs] @staticmethod def mean(mask=None, axis=None): r'''This sets the masked values of the input data to the mean of the unmasked values across the array or axis. @@ -249,7 +493,7 @@

Source code for cil.processors.Masker

 
         return processor
-
[docs] @staticmethod +
[docs] @staticmethod def median(mask=None, axis=None): r'''This sets the masked values of the input data to the median of the unmasked values across the array or axis. @@ -263,7 +507,7 @@

Source code for cil.processors.Masker

 
         return processor
-
[docs] @staticmethod +
[docs] @staticmethod def interpolate(mask=None, axis=None, method='linear'): r'''This operates over the specified axis and uses 1D interpolation over remaining flattened array to fill in missing vaues. @@ -450,37 +694,59 @@

Source code for cil.processors.Masker

             return out
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/processors/Normaliser.html b/nightly/_modules/cil/processors/Normaliser/index.html similarity index 56% rename from nightly/_modules/cil/processors/Normaliser.html rename to nightly/_modules/cil/processors/Normaliser/index.html index 9035391943..05d3419923 100644 --- a/nightly/_modules/cil/processors/Normaliser.html +++ b/nightly/_modules/cil/processors/Normaliser/index.html @@ -1,196 +1,440 @@ + - + + + cil.processors.Normaliser — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - + + + + + + + + + - - - - - - - - - - - + + - - + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.processors.Normaliser

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -215,7 +459,7 @@ 

Source code for cil.processors.Normaliser

  AcquisitionGeometry, ImageGeometry, ImageData
 import numpy
 
-
[docs]class Normaliser(Processor): +
[docs]class Normaliser(Processor): '''Normalisation based on flat and dark This processor read in a AcquisitionData and normalises it based on @@ -277,7 +521,7 @@

Source code for cil.processors.Normaliser

             c[ ~ numpy.isfinite( c )] = tolerance # set to not zero if 0/0 
         return c
     
-
[docs] @staticmethod +
[docs] @staticmethod def estimate_normalised_error(projection, flat, dark, delta_flat, delta_dark): '''returns the estimated relative error of the normalised projection @@ -318,37 +562,59 @@

Source code for cil.processors.Normaliser

     
 
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/processors/Padder.html b/nightly/_modules/cil/processors/Padder/index.html similarity index 82% rename from nightly/_modules/cil/processors/Padder.html rename to nightly/_modules/cil/processors/Padder/index.html index 710b93d4a2..6b8015ad8f 100644 --- a/nightly/_modules/cil/processors/Padder.html +++ b/nightly/_modules/cil/processors/Padder/index.html @@ -1,196 +1,440 @@ + - + + + cil.processors.Padder — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.processors.Padder

 # -*- coding: utf-8 -*-
 #  Copyright 2021 United Kingdom Research and Innovation
@@ -218,7 +462,7 @@ 

Source code for cil.processors.Padder

 import numpy as np
 import weakref
 
-
[docs]class Padder(DataProcessor): +
[docs]class Padder(DataProcessor): """ Processor to pad an array with a border, wrapping numpy.pad. See https://numpy.org/doc/stable/reference/generated/numpy.pad.html @@ -286,7 +530,7 @@

Source code for cil.processors.Padder

     """
 
 
-
[docs] @staticmethod +
[docs] @staticmethod def constant(pad_width=None, constant_values=0.0): """ Padder processor wrapping numpy.pad with mode `constant`. @@ -338,7 +582,7 @@

Source code for cil.processors.Padder

         return processor
-
[docs] @staticmethod +
[docs] @staticmethod def edge(pad_width=None): """ Padder processor wrapping numpy.pad with mode `edge`. @@ -380,7 +624,7 @@

Source code for cil.processors.Padder

         processor = Padder(pad_width=pad_width, mode='edge')
         return processor
-
[docs] @staticmethod +
[docs] @staticmethod def linear_ramp(pad_width=None, end_values=0.0): """Padder processor wrapping numpy.pad with mode `linear_ramp` @@ -431,7 +675,7 @@

Source code for cil.processors.Padder

         return processor
-
[docs] @staticmethod +
[docs] @staticmethod def reflect(pad_width=None): """ Padder processor wrapping numpy.pad with mode `reflect`. @@ -473,7 +717,7 @@

Source code for cil.processors.Padder

         return processor
-
[docs] @staticmethod +
[docs] @staticmethod def symmetric(pad_width=None): """ Padder processor wrapping numpy.pad with mode `symmetric`. @@ -517,7 +761,7 @@

Source code for cil.processors.Padder

         return processor
-
[docs] @staticmethod +
[docs] @staticmethod def wrap(pad_width=None): """ Padder processor wrapping numpy.pad with mode `wrap`. @@ -583,7 +827,7 @@

Source code for cil.processors.Padder

         super(Padder, self).__init__(**kwargs)
 
 
-
[docs] def set_input(self, dataset): +
[docs] def set_input(self, dataset): """ Set the input data to the processor @@ -863,37 +1107,59 @@

Source code for cil.processors.Padder

             out.array = self._process_data(data)
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/processors/RingRemover.html b/nightly/_modules/cil/processors/RingRemover/index.html similarity index 65% rename from nightly/_modules/cil/processors/RingRemover.html rename to nightly/_modules/cil/processors/RingRemover/index.html index af0aa950e7..2d5aa319b3 100644 --- a/nightly/_modules/cil/processors/RingRemover.html +++ b/nightly/_modules/cil/processors/RingRemover/index.html @@ -1,196 +1,440 @@ + - + + + cil.processors.RingRemover — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.processors.RingRemover

 # -*- coding: utf-8 -*-
 #  Copyright 2020 United Kingdom Research and Innovation
@@ -216,7 +460,7 @@ 

Source code for cil.processors.RingRemover

 import pywt
 from cil.framework import Processor, ImageData, AcquisitionData
 
-
[docs]class RingRemover(Processor): +
[docs]class RingRemover(Processor): ''' RingRemover Processor: Removes vertical stripes from a DataContainer(ImageData/AcquisitionData) @@ -394,37 +638,59 @@

Source code for cil.processors.RingRemover

         return nima
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/processors/Slicer.html b/nightly/_modules/cil/processors/Slicer/index.html similarity index 79% rename from nightly/_modules/cil/processors/Slicer.html rename to nightly/_modules/cil/processors/Slicer/index.html index 204451c7dc..906d164027 100644 --- a/nightly/_modules/cil/processors/Slicer.html +++ b/nightly/_modules/cil/processors/Slicer/index.html @@ -1,196 +1,440 @@ + - + + + cil.processors.Slicer — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.processors.Slicer

 # -*- coding: utf-8 -*-
 #  Copyright 2021 United Kingdom Research and Innovation
@@ -221,7 +465,7 @@ 

Source code for cil.processors.Slicer

 # so Binner has been implemented as a child of Slicer.  This makes use
 # of commonality and redefines only the methods that differ. These methods
 # dictate the style of slicer
-
[docs]class Slicer(DataProcessor): +
[docs]class Slicer(DataProcessor): """This creates a Slicer processor. @@ -298,7 +542,7 @@

Source code for cil.processors.Slicer

         super(Slicer, self).__init__(**kwargs)
     
 
-
[docs] def set_input(self, dataset): +
[docs] def set_input(self, dataset): """ Set the input data or geometry to the processor @@ -569,7 +813,7 @@

Source code for cil.processors.Slicer

         arr_in = dc_in.array.reshape(self._shape_in)
         dc_out.fill(np.squeeze(arr_in[slice_obj]))
 
-
[docs] def process(self, out=None): +
[docs] def process(self, out=None): """ Processes the input data @@ -623,37 +867,59 @@

Source code for cil.processors.Slicer

             return data_out
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/processors/TransmissionAbsorptionConverter.html b/nightly/_modules/cil/processors/TransmissionAbsorptionConverter.html deleted file mode 100644 index 6e18665b8e..0000000000 --- a/nightly/_modules/cil/processors/TransmissionAbsorptionConverter.html +++ /dev/null @@ -1,322 +0,0 @@ - - - - - - - - cil.processors.TransmissionAbsorptionConverter — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.processors.TransmissionAbsorptionConverter

-# -*- coding: utf-8 -*-
-#  Copyright 2021 United Kingdom Research and Innovation
-#  Copyright 2021 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-from cil.framework import DataProcessor, AcquisitionData, ImageData, DataContainer
-import warnings
-import numpy
-
-
-
[docs]class TransmissionAbsorptionConverter(DataProcessor): - - r'''Processor to convert from transmission measurements to absorption - based on the Beer-Lambert law - - :param white_level: A float defining incidence intensity in the Beer-Lambert law. - :type white_level: float, optional - :param min_intensity: A float defining some threshold to avoid 0 in log, is applied after normalisation by white_level - :type min_intensity: float, optional - :return: returns AcquisitionData, ImageData or DataContainer depending on input data type, return is suppressed if 'out' is passed - :rtype: AcquisitionData, ImageData or DataContainer - - Processor first divides by white_level (default=1) and then take negative logarithm. - Elements below threshold (after division by white_level) are set to threshold. - ''' - - def __init__(self, - min_intensity = 0.0, - white_level = 1.0 - ): - - kwargs = {'min_intensity': min_intensity, - 'white_level': white_level} - - super(TransmissionAbsorptionConverter, self).__init__(**kwargs) - - def check_input(self, data): - - if not (issubclass(type(data), DataContainer)): - raise TypeError('Processor supports only following data types:\n' + - ' - ImageData\n - AcquisitionData\n' + - ' - DataContainer') - - if data.min() <= 0 and self.min_intensity <= 0: - raise ValueError('Zero or negative values found in the dataset. Please use `min_intensity` to provide a clipping value.') - - return True - - def process(self, out=None): - - data = self.get_input() - - return_val = False - if out is None: - out = data.geometry.allocate(None) - return_val = True - - arr_in = data.as_array() - arr_out = out.as_array() - - #whitelevel - if self.white_level != 1: - numpy.divide(arr_in, self.white_level, out=arr_out) - arr_in = arr_out - - #threshold - if self.min_intensity > 0: - numpy.clip(arr_in, self.min_intensity, None, out=arr_out) - arr_in = arr_out - - #beer-lambert - numpy.log(arr_in,out=arr_out) - numpy.negative(arr_out,out=arr_out) - - out.fill(arr_out) - - if return_val: - return out
-
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/processors/TransmissionAbsorptionConverter/index.html b/nightly/_modules/cil/processors/TransmissionAbsorptionConverter/index.html new file mode 100644 index 0000000000..890c98fd8c --- /dev/null +++ b/nightly/_modules/cil/processors/TransmissionAbsorptionConverter/index.html @@ -0,0 +1,588 @@ + + + + + + + + + + + cil.processors.TransmissionAbsorptionConverter — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.processors.TransmissionAbsorptionConverter

+# -*- coding: utf-8 -*-
+#  Copyright 2021 United Kingdom Research and Innovation
+#  Copyright 2021 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+from cil.framework import DataProcessor, AcquisitionData, ImageData, DataContainer
+import warnings
+import numpy
+
+
+
[docs]class TransmissionAbsorptionConverter(DataProcessor): + + r'''Processor to convert from transmission measurements to absorption + based on the Beer-Lambert law + + :param white_level: A float defining incidence intensity in the Beer-Lambert law. + :type white_level: float, optional + :param min_intensity: A float defining some threshold to avoid 0 in log, is applied after normalisation by white_level + :type min_intensity: float, optional + :return: returns AcquisitionData, ImageData or DataContainer depending on input data type, return is suppressed if 'out' is passed + :rtype: AcquisitionData, ImageData or DataContainer + + Processor first divides by white_level (default=1) and then take negative logarithm. + Elements below threshold (after division by white_level) are set to threshold. + ''' + + def __init__(self, + min_intensity = 0.0, + white_level = 1.0 + ): + + kwargs = {'min_intensity': min_intensity, + 'white_level': white_level} + + super(TransmissionAbsorptionConverter, self).__init__(**kwargs) + + def check_input(self, data): + + if not (issubclass(type(data), DataContainer)): + raise TypeError('Processor supports only following data types:\n' + + ' - ImageData\n - AcquisitionData\n' + + ' - DataContainer') + + if data.min() <= 0 and self.min_intensity <= 0: + raise ValueError('Zero or negative values found in the dataset. Please use `min_intensity` to provide a clipping value.') + + return True + + def process(self, out=None): + + data = self.get_input() + + return_val = False + if out is None: + out = data.geometry.allocate(None) + return_val = True + + arr_in = data.as_array() + arr_out = out.as_array() + + #whitelevel + if self.white_level != 1: + numpy.divide(arr_in, self.white_level, out=arr_out) + arr_in = arr_out + + #threshold + if self.min_intensity > 0: + numpy.clip(arr_in, self.min_intensity, None, out=arr_out) + arr_in = arr_out + + #beer-lambert + numpy.log(arr_in,out=arr_out) + numpy.negative(arr_out,out=arr_out) + + out.fill(arr_out) + + if return_val: + return out
+
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/cil/recon/FBP.html b/nightly/_modules/cil/recon/FBP/index.html similarity index 83% rename from nightly/_modules/cil/recon/FBP.html rename to nightly/_modules/cil/recon/FBP/index.html index b8c99f7f10..aa93df61e6 100644 --- a/nightly/_modules/cil/recon/FBP.html +++ b/nightly/_modules/cil/recon/FBP/index.html @@ -1,196 +1,440 @@ + - + + + cil.recon.FBP — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.recon.FBP

 # -*- coding: utf-8 -*-
 #  Copyright 2021 United Kingdom Research and Innovation
@@ -511,7 +755,7 @@ 

Source code for cil.recon.FBP

         NotImplementedError
 
 
-
[docs]class FDK(GenericFilteredBackProjection): +
[docs]class FDK(GenericFilteredBackProjection): """ Creates an FDK reconstructor based on your cone-beam acquisition data using TIGRE as a backend. @@ -560,7 +804,7 @@

Source code for cil.recon.FBP

         self._weights = scaling * principal_ray_length / np.sqrt((principal_ray_length ** 2 + xx ** 2 + yy ** 2))
 
 
-
[docs] def run(self, out=None, verbose=1): +
[docs] def run(self, out=None, verbose=1): """ Runs the configured FDK recon and returns the reconstruction. @@ -610,7 +854,7 @@

Source code for cil.recon.FBP

 
         return repres   
-
[docs]class FBP(GenericFilteredBackProjection): +
[docs]class FBP(GenericFilteredBackProjection): """ Creates an FBP reconstructor based on your parallel-beam acquisition data. @@ -658,7 +902,7 @@

Source code for cil.recon.FBP

             raise TypeError("This reconstructor is for parallel-beam data only.")
 
 
-
[docs] def set_split_processing(self, slices_per_chunk=0): +
[docs] def set_split_processing(self, slices_per_chunk=0): """ Splits the processing in to chunks. Default, 0 will process the data in a single call. @@ -716,7 +960,7 @@

Source code for cil.recon.FBP

         return self.operator.adjoint(self.data_slice).array
 
 
-
[docs] def run(self, out=None, verbose=1): +
[docs] def run(self, out=None, verbose=1): """ Runs the configured FBP recon and returns the reconstruction @@ -816,7 +1060,7 @@

Source code for cil.recon.FBP

                 operator.adjoint(proj_filtered, out = out)
-
[docs] def reset(self): +
[docs] def reset(self): """ Resets all optional configuration parameters to their default values """ @@ -850,37 +1094,59 @@

Source code for cil.recon.FBP

 
 
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/utilities/dataexample.html b/nightly/_modules/cil/utilities/dataexample/index.html similarity index 80% rename from nightly/_modules/cil/utilities/dataexample.html rename to nightly/_modules/cil/utilities/dataexample/index.html index 8b52cd58c6..a0b868f595 100644 --- a/nightly/_modules/cil/utilities/dataexample.html +++ b/nightly/_modules/cil/utilities/dataexample/index.html @@ -1,196 +1,440 @@ + - + + + cil.utilities.dataexample — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.utilities.dataexample

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -268,8 +512,8 @@ 

Source code for cil.utilities.dataexample

     @classmethod
     def dfile(cls):
         return TestData.RAINBOW
-
[docs]class SYNCHROTRON_PARALLEL_BEAM_DATA(DATA): -
[docs] @classmethod +
[docs]class SYNCHROTRON_PARALLEL_BEAM_DATA(DATA): +
[docs] @classmethod def get(cls, **kwargs): ''' A DLS dataset @@ -289,8 +533,8 @@

Source code for cil.utilities.dataexample

         loader = NEXUSDataReader()
         loader.set_up(file_name=os.path.join(os.path.abspath(ddir), '24737_fd_normalised.nxs'))
         return loader.read()
-
[docs]class SIMULATED_PARALLEL_BEAM_DATA(DATA): -
[docs] @classmethod +
[docs]class SIMULATED_PARALLEL_BEAM_DATA(DATA): +
[docs] @classmethod def get(cls, **kwargs): ''' A simulated parallel-beam dataset generated from SIMULATED_SPHERE_VOLUME @@ -310,8 +554,8 @@

Source code for cil.utilities.dataexample

         loader = NEXUSDataReader()
         loader.set_up(file_name=os.path.join(os.path.abspath(ddir), 'sim_parallel_beam.nxs'))
         return loader.read()
-
[docs]class SIMULATED_CONE_BEAM_DATA(DATA): -
[docs] @classmethod +
[docs]class SIMULATED_CONE_BEAM_DATA(DATA): +
[docs] @classmethod def get(cls, **kwargs): ''' A cone-beam dataset generated from SIMULATED_SPHERE_VOLUME @@ -353,7 +597,7 @@

Source code for cil.utilities.dataexample

         loader.set_up(file_name=os.path.join(os.path.abspath(ddir), 'sim_volume.nxs'))
         return loader.read()
 
-
[docs]class TestData(object): +
[docs]class TestData(object): '''Class to return test data provides 6 dataset: @@ -376,7 +620,7 @@

Source code for cil.utilities.dataexample

     def __init__(self, **kwargs):
         self.data_dir = kwargs.get('data_dir', data_dir)
         
-
[docs] def load(self, which, size=None, scale=(0,1), **kwargs): +
[docs] def load(self, which, size=None, scale=(0,1), **kwargs): ''' Return a test data of the requested image @@ -470,7 +714,7 @@

Source code for cil.utilities.dataexample

         # print ("data.geometry", data.geometry)
         return data
-
[docs] @staticmethod +
[docs] @staticmethod def random_noise(image, mode='gaussian', seed=None, clip=True, **kwargs): '''Function to add noise to input image @@ -491,7 +735,7 @@

Source code for cil.utilities.dataexample

             return TestData.scikit_random_noise(image, mode=mode, seed=seed, clip=clip, 
                    **kwargs)
-
[docs] @staticmethod +
[docs] @staticmethod def scikit_random_noise(image, mode='gaussian', seed=None, clip=True, **kwargs): """ Function to add random noise of various types to a floating-point image. @@ -704,37 +948,59 @@

Source code for cil.utilities.dataexample

         return out
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/utilities/display.html b/nightly/_modules/cil/utilities/display/index.html similarity index 92% rename from nightly/_modules/cil/utilities/display.html rename to nightly/_modules/cil/utilities/display/index.html index a794ea6d8c..f9107c2097 100644 --- a/nightly/_modules/cil/utilities/display.html +++ b/nightly/_modules/cil/utilities/display/index.html @@ -1,196 +1,440 @@ + - + + + cil.utilities.display — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

Source code for cil.utilities.display

 # -*- coding: utf-8 -*-
 #  Copyright 2019 United Kingdom Research and Innovation
@@ -296,7 +540,7 @@ 

Source code for cil.utilities.display

             print("Unable to save image")
 
 
-
[docs]class show1D(show_base): +
[docs]class show1D(show_base): """ This creates and displays 1D plots of pixel values by slicing multi-dimensional data. @@ -575,7 +819,7 @@

Source code for cil.utilities.display

         return fig2
-
[docs]class show2D(show_base): +
[docs]class show2D(show_base): '''This plots 2D slices from cil DataContainer types. Plots 1 or more 2D plots in an (n x num_cols) matrix. @@ -1214,7 +1458,7 @@

Source code for cil.utilities.display

         self.handles.append(h0)
         self.labels.append(h0.get_label())
 
-
[docs]class show_geometry(show_base): +
[docs]class show_geometry(show_base): ''' Displays a schematic of the acquisition geometry for 2D geometries elevation and azimuthal cannot be changed @@ -1256,37 +1500,59 @@

Source code for cil.utilities.display

         self.figure = self.display.draw(elev=elevation, azim=azimuthal, view_distance=view_distance, grid=grid, figsize=figsize, fontsize=fontsize)
-
+
- -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_modules/cil/utilities/jupyter.html b/nightly/_modules/cil/utilities/jupyter.html deleted file mode 100644 index 5571f385a9..0000000000 --- a/nightly/_modules/cil/utilities/jupyter.html +++ /dev/null @@ -1,589 +0,0 @@ - - - - - - - - cil.utilities.jupyter — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.utilities.jupyter

-# -*- coding: utf-8 -*-
-#  Copyright 2019 United Kingdom Research and Innovation
-#  Copyright 2019 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-# Kyle Pidgeon (UKRI-STFC)
-
-try:
-    from ipywidgets import interactive_output
-    import ipywidgets as widgets
-except ImportError as ie:
-    raise ImportError(ie , "\n\n", 
-                      "islicer requires the additional package ipywidgets\n" +
-                      "Please install it via conda as ipywidgets from the conda-forge channel\n")
-
-from packaging import version
-if version.parse(widgets.__version__) >= version.parse('8'):
-    raise ImportError(f'{__name__} requires ipywidgets version < 8,'
-                      + f' found version {widgets.__version__}')
-
-import matplotlib.pyplot as plt
-from matplotlib import gridspec
-import numpy
-
-from IPython.display import HTML, display
-import random
-from cil.utilities.display import set_origin
-
-
-def display_slice(container, clim, direction, title, cmap, size, axis_labels, origin):
-
-
-    def get_slice_3D(x, minmax, roi_hdir, roi_vdir, equal_aspect):
-
-        if direction == 0:
-            img = container[x]
-            x_label = axis_labels[2]
-            y_label = axis_labels[1]
-
-        elif direction == 1:
-            img = container[:,x,:]
-            x_label = axis_labels[2]
-            y_label = axis_labels[0]
-
-        elif direction == 2:
-            img = container[:,:,x]
-            x_label = axis_labels[1]
-            y_label = axis_labels[0]
-
-        if size is None:
-            fig = plt.figure()
-        else:
-            fig = plt.figure(figsize=size)
-
-        dtitle = ''
-        if isinstance(title, (list, tuple)):
-            dtitle = title[x]
-        else:
-            dtitle = title
-
-        gs = gridspec.GridSpec(1, 2, figure=fig, width_ratios=(1,.05), height_ratios=(1,))
-        # image
-        ax = fig.add_subplot(gs[0, 0])
-        img, data_origin, _ = set_origin(img, origin)
-
-        aspect = 'equal'
-        if not equal_aspect:
-            aspect = (roi_hdir[1] - roi_hdir[0]) / (roi_vdir[1] - roi_vdir[0])
-
-        if 'right' in origin:
-            roi_hdir = roi_hdir[1], roi_hdir[0]
-        if 'upper' in origin:
-            roi_vdir = roi_vdir[1], roi_vdir[0]
-
-        aximg = ax.imshow(img, cmap=cmap, origin=data_origin, aspect=aspect)
-        cmin = clim[0] + (minmax[0] / 100)*(clim[1]-clim[0])
-        cmax = clim[0] + (minmax[1] / 100)*(clim[1]-clim[0])
-        aximg.set_clim((cmin, cmax))
-        ax.set_xlim(*roi_hdir)
-        ax.set_ylim(*roi_vdir)
-        ax.set_xlabel(x_label)
-        ax.set_ylabel(y_label)
-        ax.set_title(f'{dtitle} {x}')
-        # colorbar
-        ax = fig.add_subplot(gs[0, 1])
-        plt.colorbar(aximg, cax=ax)
-        plt.tight_layout()
-        plt.show(fig)
-
-    return get_slice_3D
-
-
-
[docs]def islicer(data, direction=0, title=None, slice_number=None, cmap='gray', - minmax=None, size=None, axis_labels=None, origin='lower-left', - play_interval=500): - """ - Creates an interactive slider that slices a 3D volume along an axis. - - Parameters - ---------- - data : DataContainer or numpy.ndarray - A 3-dimensional dataset from which 2-dimensional slices will be - shown - direction : int - Axis to slice on. Can be 0,1,2 or the axis label, default 0 - title : str, list of str or tuple of str, default='' - Title for the display - slice_number : int, optional - Start slice number (default is None, which results in the center - slice being shown initially) - cmap : str or matplotlib.colors.Colormap, default='gray' - Set the colour map - minmax : tuple - Colorbar (min, max) values, default None (uses the min, max of - values in `data`) - size : int or tuple, optional - Specify the figure size in inches. If `int` this specifies the - width, and scales the height in order to keep the standard - `matplotlib` aspect ratio, default None (use the default matplotlib - figure size) - axis_labels : list of str, optional - The axis labels to use for each of the 3 dimensions in the data - (default is None, resulting in labels extracted from the data, or - ['X','Y','Z'] if no labels are present) - origin : {'lower-left', 'upper-left', 'lower-right', 'upper-right'} - Sets the display origin - play_interval : int, default=500 - The interval of time (in ms) a slice is selected for when iterating - through a set of them - - Returns - ------- - box : ipywidgets.Box - The top-level widget container. - """ - - if axis_labels is None: - if hasattr(data, "dimension_labels"): - axis_labels = [*data.dimension_labels] - else: - axis_labels = ['X', 'Y', 'Z'] - - if isinstance (data, numpy.ndarray): - container = data - elif hasattr(data, "__getitem__"): - container = data - elif hasattr(data, "as_array"): - container = data.as_array() - - if not isinstance (direction, int): - if direction in data.dimension_labels: - direction = data.get_dimension_axis(direction) - - if slice_number is None: - slice_number = int(data.shape[direction]/2) - - if title is None: - title = "Direction {}: Slice".format(axis_labels[direction]) - - style = {'slider_width': '80%'} - layout = widgets.Layout(width='200px') - - slice_slider = widgets.IntSlider( - min=0, - max=data.shape[direction]-1, - step=1, - value=slice_number, - continuous_update=True, - layout=layout, - style=style, - ) - slice_selector_full = widgets.VBox([widgets.Label('Slice index (direction {})'.format(axis_labels[direction])), slice_slider]) - - - play_slices = widgets.Play( - min=0, - max=data.shape[direction]-1, - step=1, - interval=play_interval, - value=slice_number, - disabled=False, - ) - widgets.jslink((play_slices, 'value'), (slice_slider, 'value')) - - amax = container.max() - amin = container.min() - if minmax is None: - minmax = (amin, amax) - - if isinstance (size, (int, float)): - default_ratio = 6./8. - size = ( size , size * default_ratio ) - - min_max = widgets.IntRangeSlider( - value=[0, 100], - min=0, - max=100, - step=5, - disabled=False, - continuous_update=True, - orientation='horizontal', - readout=True, - layout=layout, - style=style, - ) - min_max_full = widgets.VBox([widgets.Label('Display window percent'), min_max]) - - dirs_remaining = [i for i in range(3) if i != direction] - h_dir, v_dir = dirs_remaining[1], dirs_remaining[0] - h_dir_size = container.shape[h_dir] - v_dir_size = container.shape[v_dir] - - roi_select_hdir = widgets.IntRangeSlider( - value=[0, h_dir_size-1], - min=0, - max=h_dir_size-1, - step=1, - disabled=False, - continuous_update=False, - orientation='horizontal', - readout=True, - readout_format='d', - layout=layout, - style=style, - ) - roi_select_hdir_full = widgets.VBox([widgets.Label(f'Range: {axis_labels[h_dir]}'), roi_select_hdir]) - - - roi_select_vdir = widgets.IntRangeSlider( - value=[0, v_dir_size-1], - min=0, - max=v_dir_size-1, - step=1, - disabled=False, - continuous_update=False, - orientation='horizontal', - readout=True, - readout_format='d', - layout=layout, - style=style, - ) - roi_select_vdir_full = widgets.VBox([widgets.Label(f'Range: {axis_labels[v_dir]}'), roi_select_vdir]) - - equal_aspect = widgets.Checkbox( - value=True, - description='Pixel aspect ratio = 1', - disabled=False, - indent=False, - layout=widgets.Layout(width='auto'), - ) - - box_layout = widgets.Layout( - display='flex', - flex_flow='column', - align_items='flex-start', - justify_content='center', - ) - selectors = widgets.Box([ - play_slices, - slice_selector_full, - min_max_full, - roi_select_hdir_full, - roi_select_vdir_full, - equal_aspect], - layout=box_layout) - - out = interactive_output( - display_slice( - container, - minmax, - direction, - title=title, - cmap=cmap, - size=size, - axis_labels=axis_labels, - origin=origin), - {'x': slice_slider, - 'minmax': min_max, - 'roi_hdir': roi_select_hdir, - 'roi_vdir': roi_select_vdir, - 'equal_aspect': equal_aspect}) - - box = widgets.HBox(children=[out, selectors], - layout=widgets.Layout( - display='flex', - justify_content='center')) - - return box
- - - - -# https://stackoverflow.com/questions/31517194/how-to-hide-one-specific-cell-input-or-output-in-ipython-notebook/52664156 - -def hide_toggle(for_next=False): - this_cell = """$('div.cell.code_cell.rendered.selected')""" - next_cell = this_cell + '.next()' - - toggle_text = 'Toggle show/hide' # text shown on toggle link - target_cell = this_cell # target cell to control with toggle - js_hide_current = '' # bit of JS to permanently hide code in current cell (only when toggling next cell) - - if for_next: - target_cell = next_cell - toggle_text += ' next cell' - js_hide_current = this_cell + '.find("div.input").hide();' - - js_f_name = 'code_toggle_{}'.format(str(random.randint(1,2**64))) - - html = """ - <script> - function {f_name}() {{ - {cell_selector}.find('div.input').toggle(); - }} - - {js_hide_current} - </script> - - <a href="javascript:{f_name}()">{toggle_text}</a> - """.format( - f_name=js_f_name, - cell_selector=target_cell, - js_hide_current=js_hide_current, - toggle_text=toggle_text - ) - - return HTML(html) -
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/utilities/quality_measures.html b/nightly/_modules/cil/utilities/quality_measures.html deleted file mode 100644 index 8d04111ad1..0000000000 --- a/nightly/_modules/cil/utilities/quality_measures.html +++ /dev/null @@ -1,351 +0,0 @@ - - - - - - - - cil.utilities.quality_measures — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - - - -
- -
- - - - - - -
- -
- -

Source code for cil.utilities.quality_measures

-# -*- coding: utf-8 -*-
-#  Copyright 2020 United Kingdom Research and Innovation
-#  Copyright 2020 The University of Manchester
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-# Authors:
-# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
-
-from cil.optimisation.functions import L2NormSquared, L1Norm
-from cil.framework import DataContainer
-import numpy as np
-
-
-
[docs]def mse(dc1, dc2, mask=None): - ''' Calculates the mean squared error of two images - - Parameters - ---------- - dc1: `DataContainer` - One image to be compared - dc2: `DataContainer` - Second image to be compared - mask: array or `DataContainer` with the same dimensions as the `dc1` and `dc2` - The pixelwise operation only considers values where the mask is True or NonZero. - - Returns - ------- - A number, the mean squared error of the two images - ''' - dc1 = dc1.as_array() - dc2 = dc2.as_array() - - if mask is not None: - - if isinstance(mask, DataContainer): - mask = mask.as_array() - - mask = mask.astype('bool') - dc1 = np.extract(mask, dc1) - dc2 = np.extract(mask, dc2) - return np.mean(((dc1 - dc2)**2))
- - -
[docs]def mae(dc1, dc2, mask=None): - ''' Calculates the Mean Absolute error of two images. - - Parameters - ---------- - dc1: `DataContainer` - One image to be compared - dc2: `DataContainer` - Second image to be compared - mask: array or `DataContainer` with the same dimensions as the `dc1` and `dc2` - The pixelwise operation only considers values where the mask is True or NonZero. - - - Returns - ------- - A number with the mean absolute error between the two images. - ''' - dc1 = dc1.as_array() - dc2 = dc2.as_array() - - if mask is not None: - - if isinstance(mask, DataContainer): - mask = mask.as_array() - - mask = mask.astype('bool') - dc1 = np.extract(mask, dc1) - dc2 = np.extract(mask, dc2) - - return np.mean(np.abs((dc1-dc2)))
- - -
[docs]def psnr(ground_truth, corrupted, data_range=None, mask=None): - ''' Calculates the Peak signal to noise ratio (PSNR) between the two images. - - Parameters - ---------- - ground_truth: `DataContainer` - The reference image - corrupted: `DataContainer` - The image to be evaluated - data_range: scalar value, default=None - PSNR scaling factor, the dynamic range of the images (i.e., the difference between the maximum the and minimum allowed values). We take the maximum value in the ground truth array. - mask: array or `DataContainer` with the same dimensions as the `dc1` and `dc2` - The pixelwise operation only considers values where the mask is True or NonZero.. - - Returns - ------- - A number, the peak signal to noise ration between the two images. - ''' - if data_range is None: - - if mask is None: - data_range = ground_truth.as_array().max() - - - else: - - if isinstance(mask, DataContainer): - mask = mask.as_array() - data_range = np.max(ground_truth.as_array(), - where=mask.astype('bool'), initial=-1e-8) - - tmp_mse = mse(ground_truth, corrupted, mask=mask) - - return 10 * np.log10((data_range ** 2) / tmp_mse)
- -
- -
- - - -
-
- -
- - -
-
- - - - - - \ No newline at end of file diff --git a/nightly/_modules/cil/utilities/quality_measures/index.html b/nightly/_modules/cil/utilities/quality_measures/index.html new file mode 100644 index 0000000000..650e649f08 --- /dev/null +++ b/nightly/_modules/cil/utilities/quality_measures/index.html @@ -0,0 +1,617 @@ + + + + + + + + + + + cil.utilities.quality_measures — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + + + + + + + + +
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + + + + +
+ +

Source code for cil.utilities.quality_measures

+# -*- coding: utf-8 -*-
+#  Copyright 2020 United Kingdom Research and Innovation
+#  Copyright 2020 The University of Manchester
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+# Authors:
+# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txt
+
+from cil.optimisation.functions import L2NormSquared, L1Norm
+from cil.framework import DataContainer
+import numpy as np
+
+
+
[docs]def mse(dc1, dc2, mask=None): + ''' Calculates the mean squared error of two images + + Parameters + ---------- + dc1: `DataContainer` + One image to be compared + dc2: `DataContainer` + Second image to be compared + mask: array or `DataContainer` with the same dimensions as the `dc1` and `dc2` + The pixelwise operation only considers values where the mask is True or NonZero. + + Returns + ------- + A number, the mean squared error of the two images + ''' + dc1 = dc1.as_array() + dc2 = dc2.as_array() + + if mask is not None: + + if isinstance(mask, DataContainer): + mask = mask.as_array() + + mask = mask.astype('bool') + dc1 = np.extract(mask, dc1) + dc2 = np.extract(mask, dc2) + return np.mean(((dc1 - dc2)**2))
+ + +
[docs]def mae(dc1, dc2, mask=None): + ''' Calculates the Mean Absolute error of two images. + + Parameters + ---------- + dc1: `DataContainer` + One image to be compared + dc2: `DataContainer` + Second image to be compared + mask: array or `DataContainer` with the same dimensions as the `dc1` and `dc2` + The pixelwise operation only considers values where the mask is True or NonZero. + + + Returns + ------- + A number with the mean absolute error between the two images. + ''' + dc1 = dc1.as_array() + dc2 = dc2.as_array() + + if mask is not None: + + if isinstance(mask, DataContainer): + mask = mask.as_array() + + mask = mask.astype('bool') + dc1 = np.extract(mask, dc1) + dc2 = np.extract(mask, dc2) + + return np.mean(np.abs((dc1-dc2)))
+ + +
[docs]def psnr(ground_truth, corrupted, data_range=None, mask=None): + ''' Calculates the Peak signal to noise ratio (PSNR) between the two images. + + Parameters + ---------- + ground_truth: `DataContainer` + The reference image + corrupted: `DataContainer` + The image to be evaluated + data_range: scalar value, default=None + PSNR scaling factor, the dynamic range of the images (i.e., the difference between the maximum the and minimum allowed values). We take the maximum value in the ground truth array. + mask: array or `DataContainer` with the same dimensions as the `dc1` and `dc2` + The pixelwise operation only considers values where the mask is True or NonZero.. + + Returns + ------- + A number, the peak signal to noise ration between the two images. + ''' + if data_range is None: + + if mask is None: + data_range = ground_truth.as_array().max() + + + else: + + if isinstance(mask, DataContainer): + mask = mask.as_array() + data_range = np.max(ground_truth.as_array(), + where=mask.astype('bool'), initial=-1e-8) + + tmp_mse = mse(ground_truth, corrupted, mask=mask) + + return 10 * np.log10((data_range ** 2) / tmp_mse)
+ +
+ +
+ + + +
+ +
+ +
+
+
+ +
+ +
+ +
+ + + + +
+ + +
+
+
+ + + + + + + + \ No newline at end of file diff --git a/nightly/_modules/index.html b/nightly/_modules/index.html index 6f93321027..ba267e9e14 100644 --- a/nightly/_modules/index.html +++ b/nightly/_modules/index.html @@ -1,293 +1,551 @@ + - + + + Overview: module code — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - + + + + + + + + + - + + - + - - - - - - - - + + + + + + - - - + + + + + + + + + + + + + +
+
+
+
+
+ + + +
+
+ +
+ + + + + + - -
- - +
+ + + + + - -
- -
- - - - - -
+
+ +
+ + +
+
+ +
+
+ +
+ +
+ + + + +
+ +
+ + +
+
+ + -
+ +
+

All modules for which code is available

-
+ - -
-
-
- + + + + + + + + + + + + - - \ No newline at end of file diff --git a/nightly/_static/basic.css b/nightly/_static/basic.css index 5d8ae085a1..d54be80678 100644 --- a/nightly/_static/basic.css +++ b/nightly/_static/basic.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -130,7 +130,7 @@ ul.search li a { font-weight: bold; } -ul.search li div.context { +ul.search li p.context { color: #888; margin: 2px 0 0 30px; text-align: left; @@ -508,6 +508,63 @@ table.hlist td { vertical-align: top; } +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + /* -- other body styles ----------------------------------------------------- */ @@ -634,14 +691,6 @@ dl.glossary dt { font-size: 1.1em; } -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - .versionmodified { font-style: italic; } @@ -682,8 +731,9 @@ dl.glossary dt { .classifier:before { font-style: normal; - margin: 0.5em; + margin: 0 0.5em; content: ":"; + display: inline-block; } abbr, acronym { @@ -707,6 +757,7 @@ span.pre { -ms-hyphens: none; -webkit-hyphens: none; hyphens: none; + white-space: nowrap; } div[class*="highlight-"] { @@ -770,8 +821,12 @@ div.code-block-caption code { table.highlighttable td.linenos, span.linenos, -div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ - user-select: none; +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ } div.code-block-caption span.caption-number { @@ -786,16 +841,6 @@ div.literal-block-wrapper { margin: 1em 0; } -code.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -code.descclassname { - background-color: transparent; -} - code.xref, a code { background-color: transparent; font-weight: bold; diff --git a/nightly/_static/doctools.js b/nightly/_static/doctools.js index 61ac9d266f..e1bfd708b7 100644 --- a/nightly/_static/doctools.js +++ b/nightly/_static/doctools.js @@ -4,7 +4,7 @@ * * Sphinx JavaScript utilities for all documentation. * - * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -154,9 +154,7 @@ var Documentation = { this.fixFirefoxAnchorBug(); this.highlightSearchWords(); this.initIndexTable(); - if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { - this.initOnKeyListeners(); - } + this.initOnKeyListeners(); }, /** @@ -264,6 +262,16 @@ var Documentation = { hideSearchWords : function() { $('#searchbox .highlight-link').fadeOut(300); $('span.highlighted').removeClass('highlighted'); + var url = new URL(window.location); + url.searchParams.delete('highlight'); + window.history.replaceState({}, '', url); + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar : function() { + $('input[name=q]').first().focus(); }, /** @@ -288,25 +296,54 @@ var Documentation = { }, initOnKeyListeners: function() { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + return; + $(document).keydown(function(event) { var activeElementType = document.activeElement.tagName; // don't navigate when in search box, textarea, dropdown or button if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' - && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey - && !event.shiftKey) { - switch (event.keyCode) { - case 37: // left - var prevHref = $('link[rel="prev"]').prop('href'); - if (prevHref) { - window.location.href = prevHref; - return false; - } - case 39: // right - var nextHref = $('link[rel="next"]').prop('href'); - if (nextHref) { - window.location.href = nextHref; - return false; - } + && activeElementType !== 'BUTTON') { + if (event.altKey || event.ctrlKey || event.metaKey) + return; + + if (!event.shiftKey) { + switch (event.key) { + case 'ArrowLeft': + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) + break; + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + break; + case 'ArrowRight': + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) + break; + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + break; + case 'Escape': + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + break; + Documentation.hideSearchWords(); + return false; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case '/': + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) + break; + Documentation.focusSearchBar(); + return false; } } }); diff --git a/nightly/_static/documentation_options.js b/nightly/_static/documentation_options.js index d68af519a8..5c7fa1b588 100644 --- a/nightly/_static/documentation_options.js +++ b/nightly/_static/documentation_options.js @@ -3,10 +3,12 @@ var DOCUMENTATION_OPTIONS = { VERSION: '23.1.0', LANGUAGE: 'en', COLLAPSE_INDEX: false, - BUILDER: 'html', + BUILDER: 'dirhtml', FILE_SUFFIX: '.html', LINK_SUFFIX: '.html', HAS_SOURCE: true, SOURCELINK_SUFFIX: '.txt', - NAVIGATION_WITH_KEYS: true + NAVIGATION_WITH_KEYS: true, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, }; \ No newline at end of file diff --git a/nightly/_static/language_data.js b/nightly/_static/language_data.js index 863704b310..ebe2f03bf0 100644 --- a/nightly/_static/language_data.js +++ b/nightly/_static/language_data.js @@ -5,7 +5,7 @@ * This script contains the language-specific data used by searchtools.js, * namely the list of stopwords, stemmer, scorer and splitter. * - * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ diff --git a/nightly/_static/pygments.css b/nightly/_static/pygments.css index 6110e9f1ad..997797f270 100644 --- a/nightly/_static/pygments.css +++ b/nightly/_static/pygments.css @@ -1,84 +1,152 @@ -pre { line-height: 125%; } -td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } -span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } -td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } -span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } -.highlight .hll { background-color: #ffffcc } -.highlight { background: #f8f8f8; } -.highlight .c { color: #8f5902; font-style: italic } /* Comment */ -.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ -.highlight .g { color: #000000 } /* Generic */ -.highlight .k { color: #204a87; font-weight: bold } /* Keyword */ -.highlight .l { color: #000000 } /* Literal */ -.highlight .n { color: #000000 } /* Name */ -.highlight .o { color: #ce5c00; font-weight: bold } /* Operator */ -.highlight .x { color: #000000 } /* Other */ -.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ -.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ -.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */ -.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ -.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ -.highlight .gd { color: #a40000 } /* Generic.Deleted */ -.highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ -.highlight .ges { color: #000000; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ -.highlight .gr { color: #ef2929 } /* Generic.Error */ -.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ -.highlight .gi { color: #00A000 } /* Generic.Inserted */ -.highlight .go { color: #000000; font-style: italic } /* Generic.Output */ -.highlight .gp { color: #8f5902 } /* Generic.Prompt */ -.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ -.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ -.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ -.highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ -.highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */ -.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ -.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ -.highlight .ld { color: #000000 } /* Literal.Date */ -.highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */ -.highlight .s { color: #4e9a06 } /* Literal.String */ -.highlight .na { color: #c4a000 } /* Name.Attribute */ -.highlight .nb { color: #204a87 } /* Name.Builtin */ -.highlight .nc { color: #000000 } /* Name.Class */ -.highlight .no { color: #000000 } /* Name.Constant */ -.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ -.highlight .ni { color: #ce5c00 } /* Name.Entity */ -.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #000000 } /* Name.Function */ -.highlight .nl { color: #f57900 } /* Name.Label */ -.highlight .nn { color: #000000 } /* Name.Namespace */ -.highlight .nx { color: #000000 } /* Name.Other */ -.highlight .py { color: #000000 } /* Name.Property */ -.highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */ -.highlight .nv { color: #000000 } /* Name.Variable */ -.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */ -.highlight .pm { color: #000000; font-weight: bold } /* Punctuation.Marker */ -.highlight .w { color: #f8f8f8 } /* Text.Whitespace */ -.highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */ -.highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */ -.highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */ -.highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */ -.highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */ -.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ -.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ -.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ -.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ -.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ -.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ -.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ -.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ -.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ -.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ -.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ -.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ -.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ -.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ -.highlight .fm { color: #000000 } /* Name.Function.Magic */ -.highlight .vc { color: #000000 } /* Name.Variable.Class */ -.highlight .vg { color: #000000 } /* Name.Variable.Global */ -.highlight .vi { color: #000000 } /* Name.Variable.Instance */ -.highlight .vm { color: #000000 } /* Name.Variable.Magic */ -.highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */ \ No newline at end of file +html[data-theme="light"] .highlight pre { line-height: 125%; } +html[data-theme="light"] .highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="light"] .highlight .hll { background-color: #7971292e } +html[data-theme="light"] .highlight { background: #fefefe; color: #545454 } +html[data-theme="light"] .highlight .c { color: #797129 } /* Comment */ +html[data-theme="light"] .highlight .err { color: #d91e18 } /* Error */ +html[data-theme="light"] .highlight .k { color: #7928a1 } /* Keyword */ +html[data-theme="light"] .highlight .l { color: #797129 } /* Literal */ +html[data-theme="light"] .highlight .n { color: #545454 } /* Name */ +html[data-theme="light"] .highlight .o { color: #008000 } /* Operator */ +html[data-theme="light"] .highlight .p { color: #545454 } /* Punctuation */ +html[data-theme="light"] .highlight .ch { color: #797129 } /* Comment.Hashbang */ +html[data-theme="light"] .highlight .cm { color: #797129 } /* Comment.Multiline */ +html[data-theme="light"] .highlight .cp { color: #797129 } /* Comment.Preproc */ +html[data-theme="light"] .highlight .cpf { color: #797129 } /* Comment.PreprocFile */ +html[data-theme="light"] .highlight .c1 { color: #797129 } /* Comment.Single */ +html[data-theme="light"] .highlight .cs { color: #797129 } /* Comment.Special */ +html[data-theme="light"] .highlight .gd { color: #007faa } /* Generic.Deleted */ +html[data-theme="light"] .highlight .ge { font-style: italic } /* Generic.Emph */ +html[data-theme="light"] .highlight .gh { color: #007faa } /* Generic.Heading */ +html[data-theme="light"] .highlight .gs { font-weight: bold } /* Generic.Strong */ +html[data-theme="light"] .highlight .gu { color: #007faa } /* Generic.Subheading */ +html[data-theme="light"] .highlight .kc { color: #7928a1 } /* Keyword.Constant */ +html[data-theme="light"] .highlight .kd { color: #7928a1 } /* Keyword.Declaration */ +html[data-theme="light"] .highlight .kn { color: #7928a1 } /* Keyword.Namespace */ +html[data-theme="light"] .highlight .kp { color: #7928a1 } /* Keyword.Pseudo */ +html[data-theme="light"] .highlight .kr { color: #7928a1 } /* Keyword.Reserved */ +html[data-theme="light"] .highlight .kt { color: #797129 } /* Keyword.Type */ +html[data-theme="light"] .highlight .ld { color: #797129 } /* Literal.Date */ +html[data-theme="light"] .highlight .m { color: #797129 } /* Literal.Number */ +html[data-theme="light"] .highlight .s { color: #008000 } /* Literal.String */ +html[data-theme="light"] .highlight .na { color: #797129 } /* Name.Attribute */ +html[data-theme="light"] .highlight .nb { color: #797129 } /* Name.Builtin */ +html[data-theme="light"] .highlight .nc { color: #007faa } /* Name.Class */ +html[data-theme="light"] .highlight .no { color: #007faa } /* Name.Constant */ +html[data-theme="light"] .highlight .nd { color: #797129 } /* Name.Decorator */ +html[data-theme="light"] .highlight .ni { color: #008000 } /* Name.Entity */ +html[data-theme="light"] .highlight .ne { color: #7928a1 } /* Name.Exception */ +html[data-theme="light"] .highlight .nf { color: #007faa } /* Name.Function */ +html[data-theme="light"] .highlight .nl { color: #797129 } /* Name.Label */ +html[data-theme="light"] .highlight .nn { color: #545454 } /* Name.Namespace */ +html[data-theme="light"] .highlight .nx { color: #545454 } /* Name.Other */ +html[data-theme="light"] .highlight .py { color: #007faa } /* Name.Property */ +html[data-theme="light"] .highlight .nt { color: #007faa } /* Name.Tag */ +html[data-theme="light"] .highlight .nv { color: #d91e18 } /* Name.Variable */ +html[data-theme="light"] .highlight .ow { color: #7928a1 } /* Operator.Word */ +html[data-theme="light"] .highlight .pm { color: #545454 } /* Punctuation.Marker */ +html[data-theme="light"] .highlight .w { color: #545454 } /* Text.Whitespace */ +html[data-theme="light"] .highlight .mb { color: #797129 } /* Literal.Number.Bin */ +html[data-theme="light"] .highlight .mf { color: #797129 } /* Literal.Number.Float */ +html[data-theme="light"] .highlight .mh { color: #797129 } /* Literal.Number.Hex */ +html[data-theme="light"] .highlight .mi { color: #797129 } /* Literal.Number.Integer */ +html[data-theme="light"] .highlight .mo { color: #797129 } /* Literal.Number.Oct */ +html[data-theme="light"] .highlight .sa { color: #008000 } /* Literal.String.Affix */ +html[data-theme="light"] .highlight .sb { color: #008000 } /* Literal.String.Backtick */ +html[data-theme="light"] .highlight .sc { color: #008000 } /* Literal.String.Char */ +html[data-theme="light"] .highlight .dl { color: #008000 } /* Literal.String.Delimiter */ +html[data-theme="light"] .highlight .sd { color: #008000 } /* Literal.String.Doc */ +html[data-theme="light"] .highlight .s2 { color: #008000 } /* Literal.String.Double */ +html[data-theme="light"] .highlight .se { color: #008000 } /* Literal.String.Escape */ +html[data-theme="light"] .highlight .sh { color: #008000 } /* Literal.String.Heredoc */ +html[data-theme="light"] .highlight .si { color: #008000 } /* Literal.String.Interpol */ +html[data-theme="light"] .highlight .sx { color: #008000 } /* Literal.String.Other */ +html[data-theme="light"] .highlight .sr { color: #d91e18 } /* Literal.String.Regex */ +html[data-theme="light"] .highlight .s1 { color: #008000 } /* Literal.String.Single */ +html[data-theme="light"] .highlight .ss { color: #007faa } /* Literal.String.Symbol */ +html[data-theme="light"] .highlight .bp { color: #797129 } /* Name.Builtin.Pseudo */ +html[data-theme="light"] .highlight .fm { color: #007faa } /* Name.Function.Magic */ +html[data-theme="light"] .highlight .vc { color: #d91e18 } /* Name.Variable.Class */ +html[data-theme="light"] .highlight .vg { color: #d91e18 } /* Name.Variable.Global */ +html[data-theme="light"] .highlight .vi { color: #d91e18 } /* Name.Variable.Instance */ +html[data-theme="light"] .highlight .vm { color: #797129 } /* Name.Variable.Magic */ +html[data-theme="light"] .highlight .il { color: #797129 } /* Literal.Number.Integer.Long */ +html[data-theme="dark"] .highlight pre { line-height: 125%; } +html[data-theme="dark"] .highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +html[data-theme="dark"] .highlight .hll { background-color: #ffd9002e } +html[data-theme="dark"] .highlight { background: #2b2b2b; color: #f8f8f2 } +html[data-theme="dark"] .highlight .c { color: #ffd900 } /* Comment */ +html[data-theme="dark"] .highlight .err { color: #ffa07a } /* Error */ +html[data-theme="dark"] .highlight .k { color: #dcc6e0 } /* Keyword */ +html[data-theme="dark"] .highlight .l { color: #ffd900 } /* Literal */ +html[data-theme="dark"] .highlight .n { color: #f8f8f2 } /* Name */ +html[data-theme="dark"] .highlight .o { color: #abe338 } /* Operator */ +html[data-theme="dark"] .highlight .p { color: #f8f8f2 } /* Punctuation */ +html[data-theme="dark"] .highlight .ch { color: #ffd900 } /* Comment.Hashbang */ +html[data-theme="dark"] .highlight .cm { color: #ffd900 } /* Comment.Multiline */ +html[data-theme="dark"] .highlight .cp { color: #ffd900 } /* Comment.Preproc */ +html[data-theme="dark"] .highlight .cpf { color: #ffd900 } /* Comment.PreprocFile */ +html[data-theme="dark"] .highlight .c1 { color: #ffd900 } /* Comment.Single */ +html[data-theme="dark"] .highlight .cs { color: #ffd900 } /* Comment.Special */ +html[data-theme="dark"] .highlight .gd { color: #00e0e0 } /* Generic.Deleted */ +html[data-theme="dark"] .highlight .ge { font-style: italic } /* Generic.Emph */ +html[data-theme="dark"] .highlight .gh { color: #00e0e0 } /* Generic.Heading */ +html[data-theme="dark"] .highlight .gs { font-weight: bold } /* Generic.Strong */ +html[data-theme="dark"] .highlight .gu { color: #00e0e0 } /* Generic.Subheading */ +html[data-theme="dark"] .highlight .kc { color: #dcc6e0 } /* Keyword.Constant */ +html[data-theme="dark"] .highlight .kd { color: #dcc6e0 } /* Keyword.Declaration */ +html[data-theme="dark"] .highlight .kn { color: #dcc6e0 } /* Keyword.Namespace */ +html[data-theme="dark"] .highlight .kp { color: #dcc6e0 } /* Keyword.Pseudo */ +html[data-theme="dark"] .highlight .kr { color: #dcc6e0 } /* Keyword.Reserved */ +html[data-theme="dark"] .highlight .kt { color: #ffd900 } /* Keyword.Type */ +html[data-theme="dark"] .highlight .ld { color: #ffd900 } /* Literal.Date */ +html[data-theme="dark"] .highlight .m { color: #ffd900 } /* Literal.Number */ +html[data-theme="dark"] .highlight .s { color: #abe338 } /* Literal.String */ +html[data-theme="dark"] .highlight .na { color: #ffd900 } /* Name.Attribute */ +html[data-theme="dark"] .highlight .nb { color: #ffd900 } /* Name.Builtin */ +html[data-theme="dark"] .highlight .nc { color: #00e0e0 } /* Name.Class */ +html[data-theme="dark"] .highlight .no { color: #00e0e0 } /* Name.Constant */ +html[data-theme="dark"] .highlight .nd { color: #ffd900 } /* Name.Decorator */ +html[data-theme="dark"] .highlight .ni { color: #abe338 } /* Name.Entity */ +html[data-theme="dark"] .highlight .ne { color: #dcc6e0 } /* Name.Exception */ +html[data-theme="dark"] .highlight .nf { color: #00e0e0 } /* Name.Function */ +html[data-theme="dark"] .highlight .nl { color: #ffd900 } /* Name.Label */ +html[data-theme="dark"] .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ +html[data-theme="dark"] .highlight .nx { color: #f8f8f2 } /* Name.Other */ +html[data-theme="dark"] .highlight .py { color: #00e0e0 } /* Name.Property */ +html[data-theme="dark"] .highlight .nt { color: #00e0e0 } /* Name.Tag */ +html[data-theme="dark"] .highlight .nv { color: #ffa07a } /* Name.Variable */ +html[data-theme="dark"] .highlight .ow { color: #dcc6e0 } /* Operator.Word */ +html[data-theme="dark"] .highlight .pm { color: #f8f8f2 } /* Punctuation.Marker */ +html[data-theme="dark"] .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ +html[data-theme="dark"] .highlight .mb { color: #ffd900 } /* Literal.Number.Bin */ +html[data-theme="dark"] .highlight .mf { color: #ffd900 } /* Literal.Number.Float */ +html[data-theme="dark"] .highlight .mh { color: #ffd900 } /* Literal.Number.Hex */ +html[data-theme="dark"] .highlight .mi { color: #ffd900 } /* Literal.Number.Integer */ +html[data-theme="dark"] .highlight .mo { color: #ffd900 } /* Literal.Number.Oct */ +html[data-theme="dark"] .highlight .sa { color: #abe338 } /* Literal.String.Affix */ +html[data-theme="dark"] .highlight .sb { color: #abe338 } /* Literal.String.Backtick */ +html[data-theme="dark"] .highlight .sc { color: #abe338 } /* Literal.String.Char */ +html[data-theme="dark"] .highlight .dl { color: #abe338 } /* Literal.String.Delimiter */ +html[data-theme="dark"] .highlight .sd { color: #abe338 } /* Literal.String.Doc */ +html[data-theme="dark"] .highlight .s2 { color: #abe338 } /* Literal.String.Double */ +html[data-theme="dark"] .highlight .se { color: #abe338 } /* Literal.String.Escape */ +html[data-theme="dark"] .highlight .sh { color: #abe338 } /* Literal.String.Heredoc */ +html[data-theme="dark"] .highlight .si { color: #abe338 } /* Literal.String.Interpol */ +html[data-theme="dark"] .highlight .sx { color: #abe338 } /* Literal.String.Other */ +html[data-theme="dark"] .highlight .sr { color: #ffa07a } /* Literal.String.Regex */ +html[data-theme="dark"] .highlight .s1 { color: #abe338 } /* Literal.String.Single */ +html[data-theme="dark"] .highlight .ss { color: #00e0e0 } /* Literal.String.Symbol */ +html[data-theme="dark"] .highlight .bp { color: #ffd900 } /* Name.Builtin.Pseudo */ +html[data-theme="dark"] .highlight .fm { color: #00e0e0 } /* Name.Function.Magic */ +html[data-theme="dark"] .highlight .vc { color: #ffa07a } /* Name.Variable.Class */ +html[data-theme="dark"] .highlight .vg { color: #ffa07a } /* Name.Variable.Global */ +html[data-theme="dark"] .highlight .vi { color: #ffa07a } /* Name.Variable.Instance */ +html[data-theme="dark"] .highlight .vm { color: #ffd900 } /* Name.Variable.Magic */ +html[data-theme="dark"] .highlight .il { color: #ffd900 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/nightly/_static/scripts/bootstrap.js b/nightly/_static/scripts/bootstrap.js new file mode 100644 index 0000000000..766173abab --- /dev/null +++ b/nightly/_static/scripts/bootstrap.js @@ -0,0 +1,3 @@ +/*! For license information please see bootstrap.js.LICENSE.txt */ +(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{afterMain:()=>w,afterRead:()=>b,afterWrite:()=>C,applyStyles:()=>$,arrow:()=>G,auto:()=>r,basePlacements:()=>a,beforeMain:()=>v,beforeRead:()=>m,beforeWrite:()=>A,bottom:()=>n,clippingParents:()=>h,computeStyles:()=>et,createPopper:()=>Dt,createPopperBase:()=>Lt,createPopperLite:()=>$t,detectOverflow:()=>mt,end:()=>c,eventListeners:()=>nt,flip:()=>_t,hide:()=>yt,left:()=>o,main:()=>y,modifierPhases:()=>T,offset:()=>wt,placements:()=>g,popper:()=>d,popperGenerator:()=>kt,popperOffsets:()=>At,preventOverflow:()=>Et,read:()=>_,reference:()=>f,right:()=>s,start:()=>l,top:()=>i,variationPlacements:()=>p,viewport:()=>u,write:()=>E});var i="top",n="bottom",s="right",o="left",r="auto",a=[i,n,s,o],l="start",c="end",h="clippingParents",u="viewport",d="popper",f="reference",p=a.reduce((function(t,e){return t.concat([e+"-"+l,e+"-"+c])}),[]),g=[].concat(a,[r]).reduce((function(t,e){return t.concat([e,e+"-"+l,e+"-"+c])}),[]),m="beforeRead",_="read",b="afterRead",v="beforeMain",y="main",w="afterMain",A="beforeWrite",E="write",C="afterWrite",T=[m,_,b,v,y,w,A,E,C];function O(t){return t?(t.nodeName||"").toLowerCase():null}function x(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function k(t){return t instanceof x(t).Element||t instanceof Element}function L(t){return t instanceof x(t).HTMLElement||t instanceof HTMLElement}function D(t){return"undefined"!=typeof ShadowRoot&&(t instanceof x(t).ShadowRoot||t instanceof ShadowRoot)}const $={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];L(s)&&O(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});L(n)&&O(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function S(t){return t.split("-")[0]}var I=Math.max,N=Math.min,P=Math.round;function j(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function M(){return!/^((?!chrome|android).)*safari/i.test(j())}function H(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&L(t)&&(s=t.offsetWidth>0&&P(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&P(n.height)/t.offsetHeight||1);var r=(k(t)?x(t):window).visualViewport,a=!M()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,u=n.height/o;return{width:h,height:u,top:c,right:l+h,bottom:c+u,left:l,x:l,y:c}}function W(t){var e=H(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function F(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&D(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function B(t){return x(t).getComputedStyle(t)}function z(t){return["table","td","th"].indexOf(O(t))>=0}function q(t){return((k(t)?t.ownerDocument:t.document)||window.document).documentElement}function R(t){return"html"===O(t)?t:t.assignedSlot||t.parentNode||(D(t)?t.host:null)||q(t)}function V(t){return L(t)&&"fixed"!==B(t).position?t.offsetParent:null}function K(t){for(var e=x(t),i=V(t);i&&z(i)&&"static"===B(i).position;)i=V(i);return i&&("html"===O(i)||"body"===O(i)&&"static"===B(i).position)?e:i||function(t){var e=/firefox/i.test(j());if(/Trident/i.test(j())&&L(t)&&"fixed"===B(t).position)return null;var i=R(t);for(D(i)&&(i=i.host);L(i)&&["html","body"].indexOf(O(i))<0;){var n=B(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Q(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function X(t,e,i){return I(t,N(e,i))}function Y(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function U(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const G={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,r=t.state,l=t.name,c=t.options,h=r.elements.arrow,u=r.modifiersData.popperOffsets,d=S(r.placement),f=Q(d),p=[o,s].indexOf(d)>=0?"height":"width";if(h&&u){var g=function(t,e){return Y("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:U(t,a))}(c.padding,r),m=W(h),_="y"===f?i:o,b="y"===f?n:s,v=r.rects.reference[p]+r.rects.reference[f]-u[f]-r.rects.popper[p],y=u[f]-r.rects.reference[f],w=K(h),A=w?"y"===f?w.clientHeight||0:w.clientWidth||0:0,E=v/2-y/2,C=g[_],T=A-m[p]-g[b],O=A/2-m[p]/2+E,x=X(C,O,T),k=f;r.modifiersData[l]=((e={})[k]=x,e.centerOffset=x-O,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&F(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function J(t){return t.split("-")[1]}var Z={top:"auto",right:"auto",bottom:"auto",left:"auto"};function tt(t){var e,r=t.popper,a=t.popperRect,l=t.placement,h=t.variation,u=t.offsets,d=t.position,f=t.gpuAcceleration,p=t.adaptive,g=t.roundOffsets,m=t.isFixed,_=u.x,b=void 0===_?0:_,v=u.y,y=void 0===v?0:v,w="function"==typeof g?g({x:b,y}):{x:b,y};b=w.x,y=w.y;var A=u.hasOwnProperty("x"),E=u.hasOwnProperty("y"),C=o,T=i,O=window;if(p){var k=K(r),L="clientHeight",D="clientWidth";k===x(r)&&"static"!==B(k=q(r)).position&&"absolute"===d&&(L="scrollHeight",D="scrollWidth"),(l===i||(l===o||l===s)&&h===c)&&(T=n,y-=(m&&k===O&&O.visualViewport?O.visualViewport.height:k[L])-a.height,y*=f?1:-1),l!==o&&(l!==i&&l!==n||h!==c)||(C=s,b-=(m&&k===O&&O.visualViewport?O.visualViewport.width:k[D])-a.width,b*=f?1:-1)}var $,S=Object.assign({position:d},p&&Z),I=!0===g?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:P(i*s)/s||0,y:P(n*s)/s||0}}({x:b,y},x(r)):{x:b,y};return b=I.x,y=I.y,f?Object.assign({},S,(($={})[T]=E?"0":"",$[C]=A?"0":"",$.transform=(O.devicePixelRatio||1)<=1?"translate("+b+"px, "+y+"px)":"translate3d("+b+"px, "+y+"px, 0)",$)):Object.assign({},S,((e={})[T]=E?y+"px":"",e[C]=A?b+"px":"",e.transform="",e))}const et={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:S(e.placement),variation:J(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,tt(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,tt(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var it={passive:!0};const nt={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=x(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,it)})),a&&l.addEventListener("resize",i.update,it),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,it)})),a&&l.removeEventListener("resize",i.update,it)}},data:{}};var st={left:"right",right:"left",bottom:"top",top:"bottom"};function ot(t){return t.replace(/left|right|bottom|top/g,(function(t){return st[t]}))}var rt={start:"end",end:"start"};function at(t){return t.replace(/start|end/g,(function(t){return rt[t]}))}function lt(t){var e=x(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ct(t){return H(q(t)).left+lt(t).scrollLeft}function ht(t){var e=B(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function ut(t){return["html","body","#document"].indexOf(O(t))>=0?t.ownerDocument.body:L(t)&&ht(t)?t:ut(R(t))}function dt(t,e){var i;void 0===e&&(e=[]);var n=ut(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=x(n),r=s?[o].concat(o.visualViewport||[],ht(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(dt(R(r)))}function ft(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function pt(t,e,i){return e===u?ft(function(t,e){var i=x(t),n=q(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=M();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+ct(t),y:l}}(t,i)):k(e)?function(t,e){var i=H(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):ft(function(t){var e,i=q(t),n=lt(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=I(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=I(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ct(t),l=-n.scrollTop;return"rtl"===B(s||i).direction&&(a+=I(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(q(t)))}function gt(t){var e,r=t.reference,a=t.element,h=t.placement,u=h?S(h):null,d=h?J(h):null,f=r.x+r.width/2-a.width/2,p=r.y+r.height/2-a.height/2;switch(u){case i:e={x:f,y:r.y-a.height};break;case n:e={x:f,y:r.y+r.height};break;case s:e={x:r.x+r.width,y:p};break;case o:e={x:r.x-a.width,y:p};break;default:e={x:r.x,y:r.y}}var g=u?Q(u):null;if(null!=g){var m="y"===g?"height":"width";switch(d){case l:e[g]=e[g]-(r[m]/2-a[m]/2);break;case c:e[g]=e[g]+(r[m]/2-a[m]/2)}}return e}function mt(t,e){void 0===e&&(e={});var o=e,r=o.placement,l=void 0===r?t.placement:r,c=o.strategy,p=void 0===c?t.strategy:c,g=o.boundary,m=void 0===g?h:g,_=o.rootBoundary,b=void 0===_?u:_,v=o.elementContext,y=void 0===v?d:v,w=o.altBoundary,A=void 0!==w&&w,E=o.padding,C=void 0===E?0:E,T=Y("number"!=typeof C?C:U(C,a)),x=y===d?f:d,D=t.rects.popper,$=t.elements[A?x:y],S=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=dt(R(t)),i=["absolute","fixed"].indexOf(B(t).position)>=0&&L(t)?K(t):t;return k(i)?e.filter((function(t){return k(t)&&F(t,i)&&"body"!==O(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=pt(t,i,n);return e.top=I(s.top,e.top),e.right=N(s.right,e.right),e.bottom=N(s.bottom,e.bottom),e.left=I(s.left,e.left),e}),pt(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(k($)?$:$.contextElement||q(t.elements.popper),m,b,p),P=H(t.elements.reference),j=gt({reference:P,element:D,strategy:"absolute",placement:l}),M=ft(Object.assign({},D,j)),W=y===d?M:P,z={top:S.top-W.top+T.top,bottom:W.bottom-S.bottom+T.bottom,left:S.left-W.left+T.left,right:W.right-S.right+T.right},V=t.modifiersData.offset;if(y===d&&V){var Q=V[l];Object.keys(z).forEach((function(t){var e=[s,n].indexOf(t)>=0?1:-1,o=[i,n].indexOf(t)>=0?"y":"x";z[t]+=Q[o]*e}))}return z}const _t={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,c=t.options,h=t.name;if(!e.modifiersData[h]._skip){for(var u=c.mainAxis,d=void 0===u||u,f=c.altAxis,m=void 0===f||f,_=c.fallbackPlacements,b=c.padding,v=c.boundary,y=c.rootBoundary,w=c.altBoundary,A=c.flipVariations,E=void 0===A||A,C=c.allowedAutoPlacements,T=e.options.placement,O=S(T),x=_||(O!==T&&E?function(t){if(S(t)===r)return[];var e=ot(t);return[at(t),e,at(e)]}(T):[ot(T)]),k=[T].concat(x).reduce((function(t,i){return t.concat(S(i)===r?function(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,l=i.flipVariations,c=i.allowedAutoPlacements,h=void 0===c?g:c,u=J(n),d=u?l?p:p.filter((function(t){return J(t)===u})):a,f=d.filter((function(t){return h.indexOf(t)>=0}));0===f.length&&(f=d);var m=f.reduce((function(e,i){return e[i]=mt(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[S(i)],e}),{});return Object.keys(m).sort((function(t,e){return m[t]-m[e]}))}(e,{placement:i,boundary:v,rootBoundary:y,padding:b,flipVariations:E,allowedAutoPlacements:C}):i)}),[]),L=e.rects.reference,D=e.rects.popper,$=new Map,I=!0,N=k[0],P=0;P=0,F=W?"width":"height",B=mt(e,{placement:j,boundary:v,rootBoundary:y,altBoundary:w,padding:b}),z=W?H?s:o:H?n:i;L[F]>D[F]&&(z=ot(z));var q=ot(z),R=[];if(d&&R.push(B[M]<=0),m&&R.push(B[z]<=0,B[q]<=0),R.every((function(t){return t}))){N=j,I=!1;break}$.set(j,R)}if(I)for(var V=function(t){var e=k.find((function(e){var i=$.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return N=e,"break"},K=E?3:1;K>0&&"break"!==V(K);K--);e.placement!==N&&(e.modifiersData[h]._skip=!0,e.placement=N,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function bt(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function vt(t){return[i,s,n,o].some((function(e){return t[e]>=0}))}const yt={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=mt(e,{elementContext:"reference"}),a=mt(e,{altBoundary:!0}),l=bt(r,n),c=bt(a,s,o),h=vt(l),u=vt(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:u},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":u})}},wt={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,n=t.options,r=t.name,a=n.offset,l=void 0===a?[0,0]:a,c=g.reduce((function(t,n){return t[n]=function(t,e,n){var r=S(t),a=[o,i].indexOf(r)>=0?-1:1,l="function"==typeof n?n(Object.assign({},e,{placement:t})):n,c=l[0],h=l[1];return c=c||0,h=(h||0)*a,[o,s].indexOf(r)>=0?{x:h,y:c}:{x:c,y:h}}(n,e.rects,l),t}),{}),h=c[e.placement],u=h.x,d=h.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=u,e.modifiersData.popperOffsets.y+=d),e.modifiersData[r]=c}},At={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=gt({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},Et={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,r=t.options,a=t.name,c=r.mainAxis,h=void 0===c||c,u=r.altAxis,d=void 0!==u&&u,f=r.boundary,p=r.rootBoundary,g=r.altBoundary,m=r.padding,_=r.tether,b=void 0===_||_,v=r.tetherOffset,y=void 0===v?0:v,w=mt(e,{boundary:f,rootBoundary:p,padding:m,altBoundary:g}),A=S(e.placement),E=J(e.placement),C=!E,T=Q(A),O="x"===T?"y":"x",x=e.modifiersData.popperOffsets,k=e.rects.reference,L=e.rects.popper,D="function"==typeof y?y(Object.assign({},e.rects,{placement:e.placement})):y,$="number"==typeof D?{mainAxis:D,altAxis:D}:Object.assign({mainAxis:0,altAxis:0},D),P=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,j={x:0,y:0};if(x){if(h){var M,H="y"===T?i:o,F="y"===T?n:s,B="y"===T?"height":"width",z=x[T],q=z+w[H],R=z-w[F],V=b?-L[B]/2:0,Y=E===l?k[B]:L[B],U=E===l?-L[B]:-k[B],G=e.elements.arrow,Z=b&&G?W(G):{width:0,height:0},tt=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},et=tt[H],it=tt[F],nt=X(0,k[B],Z[B]),st=C?k[B]/2-V-nt-et-$.mainAxis:Y-nt-et-$.mainAxis,ot=C?-k[B]/2+V+nt+it+$.mainAxis:U+nt+it+$.mainAxis,rt=e.elements.arrow&&K(e.elements.arrow),at=rt?"y"===T?rt.clientTop||0:rt.clientLeft||0:0,lt=null!=(M=null==P?void 0:P[T])?M:0,ct=z+ot-lt,ht=X(b?N(q,z+st-lt-at):q,z,b?I(R,ct):R);x[T]=ht,j[T]=ht-z}if(d){var ut,dt="x"===T?i:o,ft="x"===T?n:s,pt=x[O],gt="y"===O?"height":"width",_t=pt+w[dt],bt=pt-w[ft],vt=-1!==[i,o].indexOf(A),yt=null!=(ut=null==P?void 0:P[O])?ut:0,wt=vt?_t:pt-k[gt]-L[gt]-yt+$.altAxis,At=vt?pt+k[gt]+L[gt]-yt-$.altAxis:bt,Et=b&&vt?function(t,e,i){var n=X(t,e,i);return n>i?i:n}(wt,pt,At):X(b?wt:_t,pt,b?At:bt);x[O]=Et,j[O]=Et-pt}e.modifiersData[a]=j}},requiresIfExists:["offset"]};function Ct(t,e,i){void 0===i&&(i=!1);var n,s,o=L(e),r=L(e)&&function(t){var e=t.getBoundingClientRect(),i=P(e.width)/t.offsetWidth||1,n=P(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=q(e),l=H(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==O(e)||ht(a))&&(c=(n=e)!==x(n)&&L(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:lt(n)),L(e)?((h=H(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=ct(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function Tt(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var Ot={placement:"bottom",modifiers:[],strategy:"absolute"};function xt(){for(var t=arguments.length,e=new Array(t),i=0;i{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e},Nt=t=>{const e=It(t);return e&&document.querySelector(e)?e:null},Pt=t=>{const e=It(t);return e?document.querySelector(e):null},jt=t=>{t.dispatchEvent(new Event(St))},Mt=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),Ht=t=>Mt(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,Wt=t=>{if(!Mt(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},Ft=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),Bt=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?Bt(t.parentNode):null},zt=()=>{},qt=t=>{t.offsetHeight},Rt=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,Vt=[],Kt=()=>"rtl"===document.documentElement.dir,Qt=t=>{var e;e=()=>{const e=Rt();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(Vt.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of Vt)t()})),Vt.push(e)):e()},Xt=t=>{"function"==typeof t&&t()},Yt=(t,e,i=!0)=>{if(!i)return void Xt(t);const n=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let s=!1;const o=({target:i})=>{i===e&&(s=!0,e.removeEventListener(St,o),Xt(t))};e.addEventListener(St,o),setTimeout((()=>{s||jt(e)}),n)},Ut=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},Gt=/[^.]*(?=\..*)\.|.*/,Jt=/\..*/,Zt=/::\d+$/,te={};let ee=1;const ie={mouseenter:"mouseover",mouseleave:"mouseout"},ne=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function se(t,e){return e&&`${e}::${ee++}`||t.uidEvent||ee++}function oe(t){const e=se(t);return t.uidEvent=e,te[e]=te[e]||{},te[e]}function re(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function ae(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=ue(t);return ne.has(o)||(o=t),[n,s,o]}function le(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=ae(e,i,n);if(e in ie){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=oe(t),c=l[a]||(l[a]={}),h=re(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const u=se(r,e.replace(Gt,"")),d=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return fe(s,{delegateTarget:r}),n.oneOff&&de.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return fe(n,{delegateTarget:t}),i.oneOff&&de.off(t,n.type,e),e.apply(t,[n])}}(t,r);d.delegationSelector=o?i:null,d.callable=r,d.oneOff=s,d.uidEvent=u,c[u]=d,t.addEventListener(a,d,o)}function ce(t,e,i,n,s){const o=re(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function he(t,e,i,n){const s=e[i]||{};for(const o of Object.keys(s))if(o.includes(n)){const n=s[o];ce(t,e,i,n.callable,n.delegationSelector)}}function ue(t){return t=t.replace(Jt,""),ie[t]||t}const de={on(t,e,i,n){le(t,e,i,n,!1)},one(t,e,i,n){le(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=ae(e,i,n),a=r!==e,l=oe(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))he(t,l,i,e.slice(1));for(const i of Object.keys(c)){const n=i.replace(Zt,"");if(!a||e.includes(n)){const e=c[i];ce(t,l,r,e.callable,e.delegationSelector)}}}else{if(!Object.keys(c).length)return;ce(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=Rt();let s=null,o=!0,r=!0,a=!1;e!==ue(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());let l=new Event(e,{bubbles:o,cancelable:!0});return l=fe(l,i),a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function fe(t,e){for(const[i,n]of Object.entries(e||{}))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}const pe=new Map,ge={set(t,e,i){pe.has(t)||pe.set(t,new Map);const n=pe.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>pe.has(t)&&pe.get(t).get(e)||null,remove(t,e){if(!pe.has(t))return;const i=pe.get(t);i.delete(e),0===i.size&&pe.delete(t)}};function me(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function _e(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const be={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${_e(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${_e(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=me(t.dataset[n])}return e},getDataAttribute:(t,e)=>me(t.getAttribute(`data-bs-${_e(e)}`))};class ve{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=Mt(e)?be.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...Mt(e)?be.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const n of Object.keys(e)){const s=e[n],o=t[n],r=Mt(o)?"element":null==(i=o)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class ye extends ve{constructor(t,e){super(),(t=Ht(t))&&(this._element=t,this._config=this._getConfig(e),ge.set(this._element,this.constructor.DATA_KEY,this))}dispose(){ge.remove(this._element,this.constructor.DATA_KEY),de.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){Yt(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return ge.get(Ht(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.2.3"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const we=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;de.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),Ft(this))return;const s=Pt(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},Ae=".bs.alert",Ee=`close${Ae}`,Ce=`closed${Ae}`;class Te extends ye{static get NAME(){return"alert"}close(){if(de.trigger(this._element,Ee).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),de.trigger(this._element,Ce),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Te.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}we(Te,"close"),Qt(Te);const Oe='[data-bs-toggle="button"]';class xe extends ye{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=xe.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}de.on(document,"click.bs.button.data-api",Oe,(t=>{t.preventDefault();const e=t.target.closest(Oe);xe.getOrCreateInstance(e).toggle()})),Qt(xe);const ke={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!Ft(t)&&Wt(t)))}},Le=".bs.swipe",De=`touchstart${Le}`,$e=`touchmove${Le}`,Se=`touchend${Le}`,Ie=`pointerdown${Le}`,Ne=`pointerup${Le}`,Pe={endCallback:null,leftCallback:null,rightCallback:null},je={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class Me extends ve{constructor(t,e){super(),this._element=t,t&&Me.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return Pe}static get DefaultType(){return je}static get NAME(){return"swipe"}dispose(){de.off(this._element,Le)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),Xt(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&Xt(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(de.on(this._element,Ie,(t=>this._start(t))),de.on(this._element,Ne,(t=>this._end(t))),this._element.classList.add("pointer-event")):(de.on(this._element,De,(t=>this._start(t))),de.on(this._element,$e,(t=>this._move(t))),de.on(this._element,Se,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const He=".bs.carousel",We=".data-api",Fe="next",Be="prev",ze="left",qe="right",Re=`slide${He}`,Ve=`slid${He}`,Ke=`keydown${He}`,Qe=`mouseenter${He}`,Xe=`mouseleave${He}`,Ye=`dragstart${He}`,Ue=`load${He}${We}`,Ge=`click${He}${We}`,Je="carousel",Ze="active",ti=".active",ei=".carousel-item",ii=ti+ei,ni={ArrowLeft:qe,ArrowRight:ze},si={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},oi={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class ri extends ye{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=ke.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===Je&&this.cycle()}static get Default(){return si}static get DefaultType(){return oi}static get NAME(){return"carousel"}next(){this._slide(Fe)}nextWhenVisible(){!document.hidden&&Wt(this._element)&&this.next()}prev(){this._slide(Be)}pause(){this._isSliding&&jt(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?de.one(this._element,Ve,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void de.one(this._element,Ve,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?Fe:Be;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&de.on(this._element,Ke,(t=>this._keydown(t))),"hover"===this._config.pause&&(de.on(this._element,Qe,(()=>this.pause())),de.on(this._element,Xe,(()=>this._maybeEnableCycle()))),this._config.touch&&Me.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of ke.find(".carousel-item img",this._element))de.on(t,Ye,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(ze)),rightCallback:()=>this._slide(this._directionToOrder(qe)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new Me(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=ni[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=ke.findOne(ti,this._indicatorsElement);e.classList.remove(Ze),e.removeAttribute("aria-current");const i=ke.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(Ze),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===Fe,s=e||Ut(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>de.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(Re).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),qt(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(Ze),i.classList.remove(Ze,c,l),this._isSliding=!1,r(Ve)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return ke.findOne(ii,this._element)}_getItems(){return ke.find(ei,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return Kt()?t===ze?Be:Fe:t===ze?Fe:Be}_orderToDirection(t){return Kt()?t===Be?ze:qe:t===Be?qe:ze}static jQueryInterface(t){return this.each((function(){const e=ri.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}de.on(document,Ge,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=Pt(this);if(!e||!e.classList.contains(Je))return;t.preventDefault();const i=ri.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===be.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),de.on(window,Ue,(()=>{const t=ke.find('[data-bs-ride="carousel"]');for(const e of t)ri.getOrCreateInstance(e)})),Qt(ri);const ai=".bs.collapse",li=`show${ai}`,ci=`shown${ai}`,hi=`hide${ai}`,ui=`hidden${ai}`,di=`click${ai}.data-api`,fi="show",pi="collapse",gi="collapsing",mi=`:scope .${pi} .${pi}`,_i='[data-bs-toggle="collapse"]',bi={parent:null,toggle:!0},vi={parent:"(null|element)",toggle:"boolean"};class yi extends ye{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=ke.find(_i);for(const t of i){const e=Nt(t),i=ke.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return bi}static get DefaultType(){return vi}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>yi.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(de.trigger(this._element,li).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(pi),this._element.classList.add(gi),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(gi),this._element.classList.add(pi,fi),this._element.style[e]="",de.trigger(this._element,ci)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(de.trigger(this._element,hi).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,qt(this._element),this._element.classList.add(gi),this._element.classList.remove(pi,fi);for(const t of this._triggerArray){const e=Pt(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(gi),this._element.classList.add(pi),de.trigger(this._element,ui)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(fi)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=Ht(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(_i);for(const e of t){const t=Pt(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=ke.find(mi,this._config.parent);return ke.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=yi.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}de.on(document,di,_i,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=Nt(this),i=ke.find(e);for(const t of i)yi.getOrCreateInstance(t,{toggle:!1}).toggle()})),Qt(yi);const wi="dropdown",Ai=".bs.dropdown",Ei=".data-api",Ci="ArrowUp",Ti="ArrowDown",Oi=`hide${Ai}`,xi=`hidden${Ai}`,ki=`show${Ai}`,Li=`shown${Ai}`,Di=`click${Ai}${Ei}`,$i=`keydown${Ai}${Ei}`,Si=`keyup${Ai}${Ei}`,Ii="show",Ni='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',Pi=`${Ni}.${Ii}`,ji=".dropdown-menu",Mi=Kt()?"top-end":"top-start",Hi=Kt()?"top-start":"top-end",Wi=Kt()?"bottom-end":"bottom-start",Fi=Kt()?"bottom-start":"bottom-end",Bi=Kt()?"left-start":"right-start",zi=Kt()?"right-start":"left-start",qi={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},Ri={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"};class Vi extends ye{constructor(t,e){super(t,e),this._popper=null,this._parent=this._element.parentNode,this._menu=ke.next(this._element,ji)[0]||ke.prev(this._element,ji)[0]||ke.findOne(ji,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return qi}static get DefaultType(){return Ri}static get NAME(){return wi}toggle(){return this._isShown()?this.hide():this.show()}show(){if(Ft(this._element)||this._isShown())return;const t={relatedTarget:this._element};if(!de.trigger(this._element,ki,t).defaultPrevented){if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(".navbar-nav"))for(const t of[].concat(...document.body.children))de.on(t,"mouseover",zt);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Ii),this._element.classList.add(Ii),de.trigger(this._element,Li,t)}}hide(){if(Ft(this._element)||!this._isShown())return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){if(!de.trigger(this._element,Oi,t).defaultPrevented){if("ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))de.off(t,"mouseover",zt);this._popper&&this._popper.destroy(),this._menu.classList.remove(Ii),this._element.classList.remove(Ii),this._element.setAttribute("aria-expanded","false"),be.removeDataAttribute(this._menu,"popper"),de.trigger(this._element,xi,t)}}_getConfig(t){if("object"==typeof(t=super._getConfig(t)).reference&&!Mt(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${wi.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(){if(void 0===e)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let t=this._element;"parent"===this._config.reference?t=this._parent:Mt(this._config.reference)?t=Ht(this._config.reference):"object"==typeof this._config.reference&&(t=this._config.reference);const i=this._getPopperConfig();this._popper=Dt(t,this._menu,i)}_isShown(){return this._menu.classList.contains(Ii)}_getPlacement(){const t=this._parent;if(t.classList.contains("dropend"))return Bi;if(t.classList.contains("dropstart"))return zi;if(t.classList.contains("dropup-center"))return"top";if(t.classList.contains("dropdown-center"))return"bottom";const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?Hi:Mi:e?Fi:Wi}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(be.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=ke.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>Wt(t)));i.length&&Ut(i,e,t===Ti,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=Vi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=ke.find(Pi);for(const i of e){const e=Vi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ci,Ti].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ni)?this:ke.prev(this,Ni)[0]||ke.next(this,Ni)[0]||ke.findOne(Ni,t.delegateTarget.parentNode),o=Vi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}de.on(document,$i,Ni,Vi.dataApiKeydownHandler),de.on(document,$i,ji,Vi.dataApiKeydownHandler),de.on(document,Di,Vi.clearMenus),de.on(document,Si,Vi.clearMenus),de.on(document,Di,Ni,(function(t){t.preventDefault(),Vi.getOrCreateInstance(this).toggle()})),Qt(Vi);const Ki=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",Qi=".sticky-top",Xi="padding-right",Yi="margin-right";class Ui{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,Xi,(e=>e+t)),this._setElementAttributes(Ki,Xi,(e=>e+t)),this._setElementAttributes(Qi,Yi,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,Xi),this._resetElementAttributes(Ki,Xi),this._resetElementAttributes(Qi,Yi)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&be.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=be.getDataAttribute(t,e);null!==i?(be.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(Mt(t))e(t);else for(const i of ke.find(t,this._element))e(i)}}const Gi="backdrop",Ji="show",Zi=`mousedown.bs.${Gi}`,tn={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},en={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class nn extends ve{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return tn}static get DefaultType(){return en}static get NAME(){return Gi}show(t){if(!this._config.isVisible)return void Xt(t);this._append();const e=this._getElement();this._config.isAnimated&&qt(e),e.classList.add(Ji),this._emulateAnimation((()=>{Xt(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Ji),this._emulateAnimation((()=>{this.dispose(),Xt(t)}))):Xt(t)}dispose(){this._isAppended&&(de.off(this._element,Zi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=Ht(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),de.on(t,Zi,(()=>{Xt(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){Yt(t,this._getElement(),this._config.isAnimated)}}const sn=".bs.focustrap",on=`focusin${sn}`,rn=`keydown.tab${sn}`,an="backward",ln={autofocus:!0,trapElement:null},cn={autofocus:"boolean",trapElement:"element"};class hn extends ve{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return ln}static get DefaultType(){return cn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),de.off(document,sn),de.on(document,on,(t=>this._handleFocusin(t))),de.on(document,rn,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,de.off(document,sn))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=ke.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===an?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?an:"forward")}}const un=".bs.modal",dn=`hide${un}`,fn=`hidePrevented${un}`,pn=`hidden${un}`,gn=`show${un}`,mn=`shown${un}`,_n=`resize${un}`,bn=`click.dismiss${un}`,vn=`mousedown.dismiss${un}`,yn=`keydown.dismiss${un}`,wn=`click${un}.data-api`,An="modal-open",En="show",Cn="modal-static",Tn={backdrop:!0,focus:!0,keyboard:!0},On={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class xn extends ye{constructor(t,e){super(t,e),this._dialog=ke.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new Ui,this._addEventListeners()}static get Default(){return Tn}static get DefaultType(){return On}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||de.trigger(this._element,gn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(An),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(de.trigger(this._element,dn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(En),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){for(const t of[window,this._dialog])de.off(t,un);this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new nn({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new hn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=ke.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),qt(this._element),this._element.classList.add(En),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,de.trigger(this._element,mn,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){de.on(this._element,yn,(t=>{if("Escape"===t.key)return this._config.keyboard?(t.preventDefault(),void this.hide()):void this._triggerBackdropTransition()})),de.on(window,_n,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),de.on(this._element,vn,(t=>{de.one(this._element,bn,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(An),this._resetAdjustments(),this._scrollBar.reset(),de.trigger(this._element,pn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(de.trigger(this._element,fn).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(Cn)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(Cn),this._queueCallback((()=>{this._element.classList.remove(Cn),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=Kt()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=Kt()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=xn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}de.on(document,wn,'[data-bs-toggle="modal"]',(function(t){const e=Pt(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),de.one(e,gn,(t=>{t.defaultPrevented||de.one(e,pn,(()=>{Wt(this)&&this.focus()}))}));const i=ke.findOne(".modal.show");i&&xn.getInstance(i).hide(),xn.getOrCreateInstance(e).toggle(this)})),we(xn),Qt(xn);const kn=".bs.offcanvas",Ln=".data-api",Dn=`load${kn}${Ln}`,$n="show",Sn="showing",In="hiding",Nn=".offcanvas.show",Pn=`show${kn}`,jn=`shown${kn}`,Mn=`hide${kn}`,Hn=`hidePrevented${kn}`,Wn=`hidden${kn}`,Fn=`resize${kn}`,Bn=`click${kn}${Ln}`,zn=`keydown.dismiss${kn}`,qn={backdrop:!0,keyboard:!0,scroll:!1},Rn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class Vn extends ye{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return qn}static get DefaultType(){return Rn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||de.trigger(this._element,Pn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new Ui).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Sn),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add($n),this._element.classList.remove(Sn),de.trigger(this._element,jn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(de.trigger(this._element,Mn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(In),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove($n,In),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new Ui).reset(),de.trigger(this._element,Wn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new nn({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():de.trigger(this._element,Hn)}:null})}_initializeFocusTrap(){return new hn({trapElement:this._element})}_addEventListeners(){de.on(this._element,zn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():de.trigger(this._element,Hn))}))}static jQueryInterface(t){return this.each((function(){const e=Vn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}de.on(document,Bn,'[data-bs-toggle="offcanvas"]',(function(t){const e=Pt(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),Ft(this))return;de.one(e,Wn,(()=>{Wt(this)&&this.focus()}));const i=ke.findOne(Nn);i&&i!==e&&Vn.getInstance(i).hide(),Vn.getOrCreateInstance(e).toggle(this)})),de.on(window,Dn,(()=>{for(const t of ke.find(Nn))Vn.getOrCreateInstance(t).show()})),de.on(window,Fn,(()=>{for(const t of ke.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&Vn.getOrCreateInstance(t).hide()})),we(Vn),Qt(Vn);const Kn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Qn=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Xn=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Yn=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Kn.has(i)||Boolean(Qn.test(t.nodeValue)||Xn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Un={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Gn={allowList:Un,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},Jn={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Zn={entry:"(string|element|function|null)",selector:"(string|element)"};class ts extends ve{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Gn}static get DefaultType(){return Jn}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Zn)}_setContent(t,e,i){const n=ke.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?Mt(e)?this._putElementInTemplate(Ht(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Yn(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return"function"==typeof t?t(this):t}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const es=new Set(["sanitize","allowList","sanitizeFn"]),is="fade",ns="show",ss=".modal",os="hide.bs.modal",rs="hover",as="focus",ls={AUTO:"auto",TOP:"top",RIGHT:Kt()?"left":"right",BOTTOM:"bottom",LEFT:Kt()?"right":"left"},cs={allowList:Un,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,0],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},hs={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class us extends ye{constructor(t,i){if(void 0===e)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,i),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return cs}static get DefaultType(){return hs}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),de.off(this._element.closest(ss),os,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=de.trigger(this._element,this.constructor.eventName("show")),e=(Bt(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),de.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))de.on(t,"mouseover",zt);this._queueCallback((()=>{de.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!de.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(ns),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))de.off(t,"mouseover",zt);this._activeTrigger.click=!1,this._activeTrigger[as]=!1,this._activeTrigger[rs]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),de.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(is,ns),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(is),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new ts({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(is)}_isShown(){return this.tip&&this.tip.classList.contains(ns)}_createPopper(t){const e="function"==typeof this._config.placement?this._config.placement.call(this,t,this._element):this._config.placement,i=ls[e.toUpperCase()];return Dt(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return"function"==typeof t?t.call(this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)de.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===rs?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===rs?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");de.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?as:rs]=!0,e._enter()})),de.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?as:rs]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},de.on(this._element.closest(ss),os,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=be.getDataAttributes(this._element);for(const t of Object.keys(e))es.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:Ht(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}Qt(us);const ds={...us.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},fs={...us.DefaultType,content:"(null|string|element|function)"};class ps extends us{static get Default(){return ds}static get DefaultType(){return fs}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=ps.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}Qt(ps);const gs=".bs.scrollspy",ms=`activate${gs}`,_s=`click${gs}`,bs=`load${gs}.data-api`,vs="active",ys="[href]",ws=".nav-link",As=`${ws}, .nav-item > ${ws}, .list-group-item`,Es={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},Cs={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Ts extends ye{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return Es}static get DefaultType(){return Cs}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=Ht(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(de.off(this._config.target,_s),de.on(this._config.target,_s,ys,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=ke.find(ys,this._config.target);for(const e of t){if(!e.hash||Ft(e))continue;const t=ke.findOne(e.hash,this._element);Wt(t)&&(this._targetLinks.set(e.hash,e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(vs),this._activateParents(t),de.trigger(this._element,ms,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))ke.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(vs);else for(const e of ke.parents(t,".nav, .list-group"))for(const t of ke.prev(e,As))t.classList.add(vs)}_clearActiveClass(t){t.classList.remove(vs);const e=ke.find(`${ys}.${vs}`,t);for(const t of e)t.classList.remove(vs)}static jQueryInterface(t){return this.each((function(){const e=Ts.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}de.on(window,bs,(()=>{for(const t of ke.find('[data-bs-spy="scroll"]'))Ts.getOrCreateInstance(t)})),Qt(Ts);const Os=".bs.tab",xs=`hide${Os}`,ks=`hidden${Os}`,Ls=`show${Os}`,Ds=`shown${Os}`,$s=`click${Os}`,Ss=`keydown${Os}`,Is=`load${Os}`,Ns="ArrowLeft",Ps="ArrowRight",js="ArrowUp",Ms="ArrowDown",Hs="active",Ws="fade",Fs="show",Bs=":not(.dropdown-toggle)",zs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',qs=`.nav-link${Bs}, .list-group-item${Bs}, [role="tab"]${Bs}, ${zs}`,Rs=`.${Hs}[data-bs-toggle="tab"], .${Hs}[data-bs-toggle="pill"], .${Hs}[data-bs-toggle="list"]`;class Vs extends ye{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),de.on(this._element,Ss,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?de.trigger(e,xs,{relatedTarget:t}):null;de.trigger(t,Ls,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Hs),this._activate(Pt(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),de.trigger(t,Ds,{relatedTarget:e})):t.classList.add(Fs)}),t,t.classList.contains(Ws)))}_deactivate(t,e){t&&(t.classList.remove(Hs),t.blur(),this._deactivate(Pt(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),de.trigger(t,ks,{relatedTarget:e})):t.classList.remove(Fs)}),t,t.classList.contains(Ws)))}_keydown(t){if(![Ns,Ps,js,Ms].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=[Ps,Ms].includes(t.key),i=Ut(this._getChildren().filter((t=>!Ft(t))),t.target,e,!0);i&&(i.focus({preventScroll:!0}),Vs.getOrCreateInstance(i).show())}_getChildren(){return ke.find(qs,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=Pt(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`#${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=ke.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",Hs),n(".dropdown-menu",Fs),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Hs)}_getInnerElement(t){return t.matches(qs)?t:ke.findOne(qs,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Vs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}de.on(document,$s,zs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),Ft(this)||Vs.getOrCreateInstance(this).show()})),de.on(window,Is,(()=>{for(const t of ke.find(Rs))Vs.getOrCreateInstance(t)})),Qt(Vs);const Ks=".bs.toast",Qs=`mouseover${Ks}`,Xs=`mouseout${Ks}`,Ys=`focusin${Ks}`,Us=`focusout${Ks}`,Gs=`hide${Ks}`,Js=`hidden${Ks}`,Zs=`show${Ks}`,to=`shown${Ks}`,eo="hide",io="show",no="showing",so={animation:"boolean",autohide:"boolean",delay:"number"},oo={animation:!0,autohide:!0,delay:5e3};class ro extends ye{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return oo}static get DefaultType(){return so}static get NAME(){return"toast"}show(){de.trigger(this._element,Zs).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(eo),qt(this._element),this._element.classList.add(io,no),this._queueCallback((()=>{this._element.classList.remove(no),de.trigger(this._element,to),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(de.trigger(this._element,Gs).defaultPrevented||(this._element.classList.add(no),this._queueCallback((()=>{this._element.classList.add(eo),this._element.classList.remove(no,io),de.trigger(this._element,Js)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(io),super.dispose()}isShown(){return this._element.classList.contains(io)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){de.on(this._element,Qs,(t=>this._onInteraction(t,!0))),de.on(this._element,Xs,(t=>this._onInteraction(t,!1))),de.on(this._element,Ys,(t=>this._onInteraction(t,!0))),de.on(this._element,Us,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ro.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}var ao;we(ro),Qt(ro),ao=function(){[].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')).map((function(t){return new us(t,{delay:{show:500,hide:100}})}))},"loading"!=document.readyState?ao():document.addEventListener("DOMContentLoaded",ao)})(); +//# sourceMappingURL=bootstrap.js.map \ No newline at end of file diff --git a/nightly/_static/scripts/bootstrap.js.LICENSE.txt b/nightly/_static/scripts/bootstrap.js.LICENSE.txt new file mode 100644 index 0000000000..91ad10aa07 --- /dev/null +++ b/nightly/_static/scripts/bootstrap.js.LICENSE.txt @@ -0,0 +1,5 @@ +/*! + * Bootstrap v5.2.3 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ diff --git a/nightly/_static/scripts/bootstrap.js.map b/nightly/_static/scripts/bootstrap.js.map new file mode 100644 index 0000000000..d83e2f7cdd --- /dev/null +++ b/nightly/_static/scripts/bootstrap.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scripts/bootstrap.js","mappings":";mBACA,IAAIA,EAAsB,CCA1BA,EAAwB,CAACC,EAASC,KACjC,IAAI,IAAIC,KAAOD,EACXF,EAAoBI,EAAEF,EAAYC,KAASH,EAAoBI,EAAEH,EAASE,IAC5EE,OAAOC,eAAeL,EAASE,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,IAE1E,ECNDH,EAAwB,CAACS,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,GCClFV,EAAyBC,IACH,oBAAXa,QAA0BA,OAAOC,aAC1CV,OAAOC,eAAeL,EAASa,OAAOC,YAAa,CAAEC,MAAO,WAE7DX,OAAOC,eAAeL,EAAS,aAAc,CAAEe,OAAO,GAAO,ipBCLvD,IAAI,EAAM,MACNC,EAAS,SACTC,EAAQ,QACRC,EAAO,OACPC,EAAO,OACPC,EAAiB,CAAC,EAAKJ,EAAQC,EAAOC,GACtCG,EAAQ,QACRC,EAAM,MACNC,EAAkB,kBAClBC,EAAW,WACXC,EAAS,SACTC,EAAY,YACZC,EAAmCP,EAAeQ,QAAO,SAAUC,EAAKC,GACjF,OAAOD,EAAIE,OAAO,CAACD,EAAY,IAAMT,EAAOS,EAAY,IAAMR,GAChE,GAAG,IACQ,EAA0B,GAAGS,OAAOX,EAAgB,CAACD,IAAOS,QAAO,SAAUC,EAAKC,GAC3F,OAAOD,EAAIE,OAAO,CAACD,EAAWA,EAAY,IAAMT,EAAOS,EAAY,IAAMR,GAC3E,GAAG,IAEQU,EAAa,aACbC,EAAO,OACPC,EAAY,YAEZC,EAAa,aACbC,EAAO,OACPC,EAAY,YAEZC,EAAc,cACdC,EAAQ,QACRC,EAAa,aACbC,EAAiB,CAACT,EAAYC,EAAMC,EAAWC,EAAYC,EAAMC,EAAWC,EAAaC,EAAOC,GC9B5F,SAASE,EAAYC,GAClC,OAAOA,GAAWA,EAAQC,UAAY,IAAIC,cAAgB,IAC5D,CCFe,SAASC,EAAUC,GAChC,GAAY,MAARA,EACF,OAAOC,OAGT,GAAwB,oBAApBD,EAAKE,WAAkC,CACzC,IAAIC,EAAgBH,EAAKG,cACzB,OAAOA,GAAgBA,EAAcC,aAAwBH,MAC/D,CAEA,OAAOD,CACT,CCTA,SAASK,EAAUL,GAEjB,OAAOA,aADUD,EAAUC,GAAMM,SACIN,aAAgBM,OACvD,CAEA,SAASC,EAAcP,GAErB,OAAOA,aADUD,EAAUC,GAAMQ,aACIR,aAAgBQ,WACvD,CAEA,SAASC,EAAaT,GAEpB,MAA0B,oBAAfU,aAKJV,aADUD,EAAUC,GAAMU,YACIV,aAAgBU,WACvD,CCwDA,SACEC,KAAM,cACNC,SAAS,EACTC,MAAO,QACPC,GA5EF,SAAqBC,GACnB,IAAIC,EAAQD,EAAKC,MACjB3D,OAAO4D,KAAKD,EAAME,UAAUC,SAAQ,SAAUR,GAC5C,IAAIS,EAAQJ,EAAMK,OAAOV,IAAS,CAAC,EAC/BW,EAAaN,EAAMM,WAAWX,IAAS,CAAC,EACxCf,EAAUoB,EAAME,SAASP,GAExBJ,EAAcX,IAAaD,EAAYC,KAO5CvC,OAAOkE,OAAO3B,EAAQwB,MAAOA,GAC7B/D,OAAO4D,KAAKK,GAAYH,SAAQ,SAAUR,GACxC,IAAI3C,EAAQsD,EAAWX,IAET,IAAV3C,EACF4B,EAAQ4B,gBAAgBb,GAExBf,EAAQ6B,aAAad,GAAgB,IAAV3C,EAAiB,GAAKA,EAErD,IACF,GACF,EAoDE0D,OAlDF,SAAgBC,GACd,IAAIX,EAAQW,EAAMX,MACdY,EAAgB,CAClBlD,OAAQ,CACNmD,SAAUb,EAAMc,QAAQC,SACxB5D,KAAM,IACN6D,IAAK,IACLC,OAAQ,KAEVC,MAAO,CACLL,SAAU,YAEZlD,UAAW,CAAC,GASd,OAPAtB,OAAOkE,OAAOP,EAAME,SAASxC,OAAO0C,MAAOQ,EAAclD,QACzDsC,EAAMK,OAASO,EAEXZ,EAAME,SAASgB,OACjB7E,OAAOkE,OAAOP,EAAME,SAASgB,MAAMd,MAAOQ,EAAcM,OAGnD,WACL7E,OAAO4D,KAAKD,EAAME,UAAUC,SAAQ,SAAUR,GAC5C,IAAIf,EAAUoB,EAAME,SAASP,GACzBW,EAAaN,EAAMM,WAAWX,IAAS,CAAC,EAGxCS,EAFkB/D,OAAO4D,KAAKD,EAAMK,OAAOzD,eAAe+C,GAAQK,EAAMK,OAAOV,GAAQiB,EAAcjB,IAE7E9B,QAAO,SAAUuC,EAAOe,GAElD,OADAf,EAAMe,GAAY,GACXf,CACT,GAAG,CAAC,GAECb,EAAcX,IAAaD,EAAYC,KAI5CvC,OAAOkE,OAAO3B,EAAQwB,MAAOA,GAC7B/D,OAAO4D,KAAKK,GAAYH,SAAQ,SAAUiB,GACxCxC,EAAQ4B,gBAAgBY,EAC1B,IACF,GACF,CACF,EASEC,SAAU,CAAC,kBCjFE,SAASC,EAAiBvD,GACvC,OAAOA,EAAUwD,MAAM,KAAK,EAC9B,CCHO,IAAI,EAAMC,KAAKC,IACX,EAAMD,KAAKE,IACXC,EAAQH,KAAKG,MCFT,SAASC,IACtB,IAAIC,EAASC,UAAUC,cAEvB,OAAc,MAAVF,GAAkBA,EAAOG,QAAUC,MAAMC,QAAQL,EAAOG,QACnDH,EAAOG,OAAOG,KAAI,SAAUC,GACjC,OAAOA,EAAKC,MAAQ,IAAMD,EAAKE,OACjC,IAAGC,KAAK,KAGHT,UAAUU,SACnB,CCTe,SAASC,IACtB,OAAQ,iCAAiCC,KAAKd,IAChD,CCCe,SAASe,EAAsB/D,EAASgE,EAAcC,QAC9C,IAAjBD,IACFA,GAAe,QAGO,IAApBC,IACFA,GAAkB,GAGpB,IAAIC,EAAalE,EAAQ+D,wBACrBI,EAAS,EACTC,EAAS,EAETJ,GAAgBrD,EAAcX,KAChCmE,EAASnE,EAAQqE,YAAc,GAAItB,EAAMmB,EAAWI,OAAStE,EAAQqE,aAAmB,EACxFD,EAASpE,EAAQuE,aAAe,GAAIxB,EAAMmB,EAAWM,QAAUxE,EAAQuE,cAAoB,GAG7F,IACIE,GADOhE,EAAUT,GAAWG,EAAUH,GAAWK,QAC3BoE,eAEtBC,GAAoBb,KAAsBI,EAC1CU,GAAKT,EAAW3F,MAAQmG,GAAoBD,EAAiBA,EAAeG,WAAa,IAAMT,EAC/FU,GAAKX,EAAW9B,KAAOsC,GAAoBD,EAAiBA,EAAeK,UAAY,IAAMV,EAC7FE,EAAQJ,EAAWI,MAAQH,EAC3BK,EAASN,EAAWM,OAASJ,EACjC,MAAO,CACLE,MAAOA,EACPE,OAAQA,EACRpC,IAAKyC,EACLvG,MAAOqG,EAAIL,EACXjG,OAAQwG,EAAIL,EACZjG,KAAMoG,EACNA,EAAGA,EACHE,EAAGA,EAEP,CCrCe,SAASE,EAAc/E,GACpC,IAAIkE,EAAaH,EAAsB/D,GAGnCsE,EAAQtE,EAAQqE,YAChBG,EAASxE,EAAQuE,aAUrB,OARI3B,KAAKoC,IAAId,EAAWI,MAAQA,IAAU,IACxCA,EAAQJ,EAAWI,OAGjB1B,KAAKoC,IAAId,EAAWM,OAASA,IAAW,IAC1CA,EAASN,EAAWM,QAGf,CACLG,EAAG3E,EAAQ4E,WACXC,EAAG7E,EAAQ8E,UACXR,MAAOA,EACPE,OAAQA,EAEZ,CCvBe,SAASS,EAASC,EAAQC,GACvC,IAAIC,EAAWD,EAAME,aAAeF,EAAME,cAE1C,GAAIH,EAAOD,SAASE,GAClB,OAAO,EAEJ,GAAIC,GAAYvE,EAAauE,GAAW,CACzC,IAAIE,EAAOH,EAEX,EAAG,CACD,GAAIG,GAAQJ,EAAOK,WAAWD,GAC5B,OAAO,EAITA,EAAOA,EAAKE,YAAcF,EAAKG,IACjC,OAASH,EACX,CAGF,OAAO,CACT,CCrBe,SAAS,EAAiBtF,GACvC,OAAOG,EAAUH,GAAS0F,iBAAiB1F,EAC7C,CCFe,SAAS2F,EAAe3F,GACrC,MAAO,CAAC,QAAS,KAAM,MAAM4F,QAAQ7F,EAAYC,KAAa,CAChE,CCFe,SAAS6F,EAAmB7F,GAEzC,QAASS,EAAUT,GAAWA,EAAQO,cACtCP,EAAQ8F,WAAazF,OAAOyF,UAAUC,eACxC,CCFe,SAASC,EAAchG,GACpC,MAA6B,SAAzBD,EAAYC,GACPA,EAMPA,EAAQiG,cACRjG,EAAQwF,aACR3E,EAAab,GAAWA,EAAQyF,KAAO,OAEvCI,EAAmB7F,EAGvB,CCVA,SAASkG,EAAoBlG,GAC3B,OAAKW,EAAcX,IACoB,UAAvC,EAAiBA,GAASiC,SAInBjC,EAAQmG,aAHN,IAIX,CAwCe,SAASC,EAAgBpG,GAItC,IAHA,IAAIK,EAASF,EAAUH,GACnBmG,EAAeD,EAAoBlG,GAEhCmG,GAAgBR,EAAeQ,IAA6D,WAA5C,EAAiBA,GAAclE,UACpFkE,EAAeD,EAAoBC,GAGrC,OAAIA,IAA+C,SAA9BpG,EAAYoG,IAA0D,SAA9BpG,EAAYoG,IAAwE,WAA5C,EAAiBA,GAAclE,UAC3H5B,EAGF8F,GAhDT,SAA4BnG,GAC1B,IAAIqG,EAAY,WAAWvC,KAAKd,KAGhC,GAFW,WAAWc,KAAKd,MAEfrC,EAAcX,IAII,UAFX,EAAiBA,GAEnBiC,SACb,OAAO,KAIX,IAAIqE,EAAcN,EAAchG,GAMhC,IAJIa,EAAayF,KACfA,EAAcA,EAAYb,MAGrB9E,EAAc2F,IAAgB,CAAC,OAAQ,QAAQV,QAAQ7F,EAAYuG,IAAgB,GAAG,CAC3F,IAAIC,EAAM,EAAiBD,GAI3B,GAAsB,SAAlBC,EAAIC,WAA4C,SAApBD,EAAIE,aAA0C,UAAhBF,EAAIG,UAAiF,IAA1D,CAAC,YAAa,eAAed,QAAQW,EAAII,aAAsBN,GAAgC,WAAnBE,EAAII,YAA2BN,GAAaE,EAAIK,QAAyB,SAAfL,EAAIK,OACjO,OAAON,EAEPA,EAAcA,EAAYd,UAE9B,CAEA,OAAO,IACT,CAgByBqB,CAAmB7G,IAAYK,CACxD,CCpEe,SAASyG,EAAyB3H,GAC/C,MAAO,CAAC,MAAO,UAAUyG,QAAQzG,IAAc,EAAI,IAAM,GAC3D,CCDO,SAAS4H,EAAOjE,EAAK1E,EAAOyE,GACjC,OAAO,EAAQC,EAAK,EAAQ1E,EAAOyE,GACrC,CCFe,SAASmE,EAAmBC,GACzC,OAAOxJ,OAAOkE,OAAO,CAAC,ECDf,CACLS,IAAK,EACL9D,MAAO,EACPD,OAAQ,EACRE,KAAM,GDHuC0I,EACjD,CEHe,SAASC,EAAgB9I,EAAOiD,GAC7C,OAAOA,EAAKpC,QAAO,SAAUkI,EAAS5J,GAEpC,OADA4J,EAAQ5J,GAAOa,EACR+I,CACT,GAAG,CAAC,EACN,CCuFA,SACEpG,KAAM,QACNC,SAAS,EACTC,MAAO,OACPC,GA9EF,SAAeC,GACb,IAAIiG,EAEAhG,EAAQD,EAAKC,MACbL,EAAOI,EAAKJ,KACZmB,EAAUf,EAAKe,QACfmF,EAAejG,EAAME,SAASgB,MAC9BgF,EAAgBlG,EAAMmG,cAAcD,cACpCE,EAAgB9E,EAAiBtB,EAAMjC,WACvCsI,EAAOX,EAAyBU,GAEhCE,EADa,CAACnJ,EAAMD,GAAOsH,QAAQ4B,IAAkB,EAClC,SAAW,QAElC,GAAKH,GAAiBC,EAAtB,CAIA,IAAIL,EAxBgB,SAAyBU,EAASvG,GAItD,OAAO4F,EAAsC,iBAH7CW,EAA6B,mBAAZA,EAAyBA,EAAQlK,OAAOkE,OAAO,CAAC,EAAGP,EAAMwG,MAAO,CAC/EzI,UAAWiC,EAAMjC,aACbwI,GACkDA,EAAUT,EAAgBS,EAASlJ,GAC7F,CAmBsBoJ,CAAgB3F,EAAQyF,QAASvG,GACjD0G,EAAY/C,EAAcsC,GAC1BU,EAAmB,MAATN,EAAe,EAAMlJ,EAC/ByJ,EAAmB,MAATP,EAAepJ,EAASC,EAClC2J,EAAU7G,EAAMwG,MAAM7I,UAAU2I,GAAOtG,EAAMwG,MAAM7I,UAAU0I,GAAQH,EAAcG,GAAQrG,EAAMwG,MAAM9I,OAAO4I,GAC9GQ,EAAYZ,EAAcG,GAAQrG,EAAMwG,MAAM7I,UAAU0I,GACxDU,EAAoB/B,EAAgBiB,GACpCe,EAAaD,EAA6B,MAATV,EAAeU,EAAkBE,cAAgB,EAAIF,EAAkBG,aAAe,EAAI,EAC3HC,EAAoBN,EAAU,EAAIC,EAAY,EAG9CpF,EAAMmE,EAAcc,GACpBlF,EAAMuF,EAAaN,EAAUJ,GAAOT,EAAce,GAClDQ,EAASJ,EAAa,EAAIN,EAAUJ,GAAO,EAAIa,EAC/CE,EAAS1B,EAAOjE,EAAK0F,EAAQ3F,GAE7B6F,EAAWjB,EACfrG,EAAMmG,cAAcxG,KAASqG,EAAwB,CAAC,GAAyBsB,GAAYD,EAAQrB,EAAsBuB,aAAeF,EAASD,EAAQpB,EAnBzJ,CAoBF,EA4CEtF,OA1CF,SAAgBC,GACd,IAAIX,EAAQW,EAAMX,MAEdwH,EADU7G,EAAMG,QACWlC,QAC3BqH,OAAoC,IAArBuB,EAA8B,sBAAwBA,EAErD,MAAhBvB,IAKwB,iBAAjBA,IACTA,EAAejG,EAAME,SAASxC,OAAO+J,cAAcxB,MAahDpC,EAAS7D,EAAME,SAASxC,OAAQuI,KAQrCjG,EAAME,SAASgB,MAAQ+E,EACzB,EASE5E,SAAU,CAAC,iBACXqG,iBAAkB,CAAC,oBCnGN,SAASC,EAAa5J,GACnC,OAAOA,EAAUwD,MAAM,KAAK,EAC9B,CCOA,IAAIqG,EAAa,CACf5G,IAAK,OACL9D,MAAO,OACPD,OAAQ,OACRE,KAAM,QAeD,SAAS0K,GAAYlH,GAC1B,IAAImH,EAEApK,EAASiD,EAAMjD,OACfqK,EAAapH,EAAMoH,WACnBhK,EAAY4C,EAAM5C,UAClBiK,EAAYrH,EAAMqH,UAClBC,EAAUtH,EAAMsH,QAChBpH,EAAWF,EAAME,SACjBqH,EAAkBvH,EAAMuH,gBACxBC,EAAWxH,EAAMwH,SACjBC,EAAezH,EAAMyH,aACrBC,EAAU1H,EAAM0H,QAChBC,EAAaL,EAAQ1E,EACrBA,OAAmB,IAAf+E,EAAwB,EAAIA,EAChCC,EAAaN,EAAQxE,EACrBA,OAAmB,IAAf8E,EAAwB,EAAIA,EAEhCC,EAAgC,mBAAjBJ,EAA8BA,EAAa,CAC5D7E,EAAGA,EACHE,IACG,CACHF,EAAGA,EACHE,GAGFF,EAAIiF,EAAMjF,EACVE,EAAI+E,EAAM/E,EACV,IAAIgF,EAAOR,EAAQrL,eAAe,KAC9B8L,EAAOT,EAAQrL,eAAe,KAC9B+L,EAAQxL,EACRyL,EAAQ,EACRC,EAAM5J,OAEV,GAAIkJ,EAAU,CACZ,IAAIpD,EAAeC,EAAgBtH,GAC/BoL,EAAa,eACbC,EAAY,cAEZhE,IAAiBhG,EAAUrB,IAGmB,WAA5C,EAFJqH,EAAeN,EAAmB/G,IAECmD,UAAsC,aAAbA,IAC1DiI,EAAa,eACbC,EAAY,gBAOZhL,IAAc,IAAQA,IAAcZ,GAAQY,IAAcb,IAAU8K,IAAczK,KACpFqL,EAAQ3L,EAGRwG,IAFc4E,GAAWtD,IAAiB8D,GAAOA,EAAIxF,eAAiBwF,EAAIxF,eAAeD,OACzF2B,EAAa+D,IACEf,EAAW3E,OAC1BK,GAAKyE,EAAkB,GAAK,GAG1BnK,IAAcZ,IAASY,IAAc,GAAOA,IAAcd,GAAW+K,IAAczK,KACrFoL,EAAQzL,EAGRqG,IAFc8E,GAAWtD,IAAiB8D,GAAOA,EAAIxF,eAAiBwF,EAAIxF,eAAeH,MACzF6B,EAAagE,IACEhB,EAAW7E,MAC1BK,GAAK2E,EAAkB,GAAK,EAEhC,CAEA,IAgBMc,EAhBFC,EAAe5M,OAAOkE,OAAO,CAC/BM,SAAUA,GACTsH,GAAYP,GAEXsB,GAAyB,IAAjBd,EAlFd,SAA2BrI,EAAM8I,GAC/B,IAAItF,EAAIxD,EAAKwD,EACTE,EAAI1D,EAAK0D,EACT0F,EAAMN,EAAIO,kBAAoB,EAClC,MAAO,CACL7F,EAAG5B,EAAM4B,EAAI4F,GAAOA,GAAO,EAC3B1F,EAAG9B,EAAM8B,EAAI0F,GAAOA,GAAO,EAE/B,CA0EsCE,CAAkB,CACpD9F,EAAGA,EACHE,GACC1E,EAAUrB,IAAW,CACtB6F,EAAGA,EACHE,GAMF,OAHAF,EAAI2F,EAAM3F,EACVE,EAAIyF,EAAMzF,EAENyE,EAGK7L,OAAOkE,OAAO,CAAC,EAAG0I,IAAeD,EAAiB,CAAC,GAAkBJ,GAASF,EAAO,IAAM,GAAIM,EAAeL,GAASF,EAAO,IAAM,GAAIO,EAAe5D,WAAayD,EAAIO,kBAAoB,IAAM,EAAI,aAAe7F,EAAI,OAASE,EAAI,MAAQ,eAAiBF,EAAI,OAASE,EAAI,SAAUuF,IAG5R3M,OAAOkE,OAAO,CAAC,EAAG0I,IAAenB,EAAkB,CAAC,GAAmBc,GAASF,EAAOjF,EAAI,KAAO,GAAIqE,EAAgBa,GAASF,EAAOlF,EAAI,KAAO,GAAIuE,EAAgB1C,UAAY,GAAI0C,GAC9L,CAuDA,UACEnI,KAAM,gBACNC,SAAS,EACTC,MAAO,cACPC,GAzDF,SAAuBwJ,GACrB,IAAItJ,EAAQsJ,EAAMtJ,MACdc,EAAUwI,EAAMxI,QAChByI,EAAwBzI,EAAQoH,gBAChCA,OAA4C,IAA1BqB,GAA0CA,EAC5DC,EAAoB1I,EAAQqH,SAC5BA,OAAiC,IAAtBqB,GAAsCA,EACjDC,EAAwB3I,EAAQsH,aAChCA,OAAyC,IAA1BqB,GAA0CA,EAYzDR,EAAe,CACjBlL,UAAWuD,EAAiBtB,EAAMjC,WAClCiK,UAAWL,EAAa3H,EAAMjC,WAC9BL,OAAQsC,EAAME,SAASxC,OACvBqK,WAAY/H,EAAMwG,MAAM9I,OACxBwK,gBAAiBA,EACjBG,QAAoC,UAA3BrI,EAAMc,QAAQC,UAGgB,MAArCf,EAAMmG,cAAcD,gBACtBlG,EAAMK,OAAO3C,OAASrB,OAAOkE,OAAO,CAAC,EAAGP,EAAMK,OAAO3C,OAAQmK,GAAYxL,OAAOkE,OAAO,CAAC,EAAG0I,EAAc,CACvGhB,QAASjI,EAAMmG,cAAcD,cAC7BrF,SAAUb,EAAMc,QAAQC,SACxBoH,SAAUA,EACVC,aAAcA,OAIe,MAA7BpI,EAAMmG,cAAcjF,QACtBlB,EAAMK,OAAOa,MAAQ7E,OAAOkE,OAAO,CAAC,EAAGP,EAAMK,OAAOa,MAAO2G,GAAYxL,OAAOkE,OAAO,CAAC,EAAG0I,EAAc,CACrGhB,QAASjI,EAAMmG,cAAcjF,MAC7BL,SAAU,WACVsH,UAAU,EACVC,aAAcA,OAIlBpI,EAAMM,WAAW5C,OAASrB,OAAOkE,OAAO,CAAC,EAAGP,EAAMM,WAAW5C,OAAQ,CACnE,wBAAyBsC,EAAMjC,WAEnC,EAQE2L,KAAM,CAAC,GChLT,IAAIC,GAAU,CACZA,SAAS,GAsCX,UACEhK,KAAM,iBACNC,SAAS,EACTC,MAAO,QACPC,GAAI,WAAe,EACnBY,OAxCF,SAAgBX,GACd,IAAIC,EAAQD,EAAKC,MACb4J,EAAW7J,EAAK6J,SAChB9I,EAAUf,EAAKe,QACf+I,EAAkB/I,EAAQgJ,OAC1BA,OAA6B,IAApBD,GAAoCA,EAC7CE,EAAkBjJ,EAAQkJ,OAC1BA,OAA6B,IAApBD,GAAoCA,EAC7C9K,EAASF,EAAUiB,EAAME,SAASxC,QAClCuM,EAAgB,GAAGjM,OAAOgC,EAAMiK,cAActM,UAAWqC,EAAMiK,cAAcvM,QAYjF,OAVIoM,GACFG,EAAc9J,SAAQ,SAAU+J,GAC9BA,EAAaC,iBAAiB,SAAUP,EAASQ,OAAQT,GAC3D,IAGEK,GACF/K,EAAOkL,iBAAiB,SAAUP,EAASQ,OAAQT,IAG9C,WACDG,GACFG,EAAc9J,SAAQ,SAAU+J,GAC9BA,EAAaG,oBAAoB,SAAUT,EAASQ,OAAQT,GAC9D,IAGEK,GACF/K,EAAOoL,oBAAoB,SAAUT,EAASQ,OAAQT,GAE1D,CACF,EASED,KAAM,CAAC,GC/CT,IAAIY,GAAO,CACTnN,KAAM,QACND,MAAO,OACPD,OAAQ,MACR+D,IAAK,UAEQ,SAASuJ,GAAqBxM,GAC3C,OAAOA,EAAUyM,QAAQ,0BAA0B,SAAUC,GAC3D,OAAOH,GAAKG,EACd,GACF,CCVA,IAAI,GAAO,CACTnN,MAAO,MACPC,IAAK,SAEQ,SAASmN,GAA8B3M,GACpD,OAAOA,EAAUyM,QAAQ,cAAc,SAAUC,GAC/C,OAAO,GAAKA,EACd,GACF,CCPe,SAASE,GAAgB3L,GACtC,IAAI6J,EAAM9J,EAAUC,GAGpB,MAAO,CACL4L,WAHe/B,EAAIgC,YAInBC,UAHcjC,EAAIkC,YAKtB,CCNe,SAASC,GAAoBpM,GAQ1C,OAAO+D,EAAsB8B,EAAmB7F,IAAUzB,KAAOwN,GAAgB/L,GAASgM,UAC5F,CCXe,SAASK,GAAerM,GAErC,IAAIsM,EAAoB,EAAiBtM,GACrCuM,EAAWD,EAAkBC,SAC7BC,EAAYF,EAAkBE,UAC9BC,EAAYH,EAAkBG,UAElC,MAAO,6BAA6B3I,KAAKyI,EAAWE,EAAYD,EAClE,CCLe,SAASE,GAAgBtM,GACtC,MAAI,CAAC,OAAQ,OAAQ,aAAawF,QAAQ7F,EAAYK,KAAU,EAEvDA,EAAKG,cAAcoM,KAGxBhM,EAAcP,IAASiM,GAAejM,GACjCA,EAGFsM,GAAgB1G,EAAc5F,GACvC,CCJe,SAASwM,GAAkB5M,EAAS6M,GACjD,IAAIC,OAES,IAATD,IACFA,EAAO,IAGT,IAAIvB,EAAeoB,GAAgB1M,GAC/B+M,EAASzB,KAAqE,OAAlDwB,EAAwB9M,EAAQO,oBAAyB,EAASuM,EAAsBH,MACpH1C,EAAM9J,EAAUmL,GAChB0B,EAASD,EAAS,CAAC9C,GAAK7K,OAAO6K,EAAIxF,gBAAkB,GAAI4H,GAAef,GAAgBA,EAAe,IAAMA,EAC7G2B,EAAcJ,EAAKzN,OAAO4N,GAC9B,OAAOD,EAASE,EAChBA,EAAY7N,OAAOwN,GAAkB5G,EAAcgH,IACrD,CCzBe,SAASE,GAAiBC,GACvC,OAAO1P,OAAOkE,OAAO,CAAC,EAAGwL,EAAM,CAC7B5O,KAAM4O,EAAKxI,EACXvC,IAAK+K,EAAKtI,EACVvG,MAAO6O,EAAKxI,EAAIwI,EAAK7I,MACrBjG,OAAQ8O,EAAKtI,EAAIsI,EAAK3I,QAE1B,CCqBA,SAAS4I,GAA2BpN,EAASqN,EAAgBlL,GAC3D,OAAOkL,IAAmBxO,EAAWqO,GCzBxB,SAAyBlN,EAASmC,GAC/C,IAAI8H,EAAM9J,EAAUH,GAChBsN,EAAOzH,EAAmB7F,GAC1ByE,EAAiBwF,EAAIxF,eACrBH,EAAQgJ,EAAKhF,YACb9D,EAAS8I,EAAKjF,aACd1D,EAAI,EACJE,EAAI,EAER,GAAIJ,EAAgB,CAClBH,EAAQG,EAAeH,MACvBE,EAASC,EAAeD,OACxB,IAAI+I,EAAiB1J,KAEjB0J,IAAmBA,GAA+B,UAAbpL,KACvCwC,EAAIF,EAAeG,WACnBC,EAAIJ,EAAeK,UAEvB,CAEA,MAAO,CACLR,MAAOA,EACPE,OAAQA,EACRG,EAAGA,EAAIyH,GAAoBpM,GAC3B6E,EAAGA,EAEP,CDDwD2I,CAAgBxN,EAASmC,IAAa1B,EAAU4M,GAdxG,SAAoCrN,EAASmC,GAC3C,IAAIgL,EAAOpJ,EAAsB/D,GAAS,EAAoB,UAAbmC,GASjD,OARAgL,EAAK/K,IAAM+K,EAAK/K,IAAMpC,EAAQyN,UAC9BN,EAAK5O,KAAO4O,EAAK5O,KAAOyB,EAAQ0N,WAChCP,EAAK9O,OAAS8O,EAAK/K,IAAMpC,EAAQqI,aACjC8E,EAAK7O,MAAQ6O,EAAK5O,KAAOyB,EAAQsI,YACjC6E,EAAK7I,MAAQtE,EAAQsI,YACrB6E,EAAK3I,OAASxE,EAAQqI,aACtB8E,EAAKxI,EAAIwI,EAAK5O,KACd4O,EAAKtI,EAAIsI,EAAK/K,IACP+K,CACT,CAG0HQ,CAA2BN,EAAgBlL,GAAY+K,GEtBlK,SAAyBlN,GACtC,IAAI8M,EAEAQ,EAAOzH,EAAmB7F,GAC1B4N,EAAY7B,GAAgB/L,GAC5B2M,EAA0D,OAAlDG,EAAwB9M,EAAQO,oBAAyB,EAASuM,EAAsBH,KAChGrI,EAAQ,EAAIgJ,EAAKO,YAAaP,EAAKhF,YAAaqE,EAAOA,EAAKkB,YAAc,EAAGlB,EAAOA,EAAKrE,YAAc,GACvG9D,EAAS,EAAI8I,EAAKQ,aAAcR,EAAKjF,aAAcsE,EAAOA,EAAKmB,aAAe,EAAGnB,EAAOA,EAAKtE,aAAe,GAC5G1D,GAAKiJ,EAAU5B,WAAaI,GAAoBpM,GAChD6E,GAAK+I,EAAU1B,UAMnB,MAJiD,QAA7C,EAAiBS,GAAQW,GAAMS,YACjCpJ,GAAK,EAAI2I,EAAKhF,YAAaqE,EAAOA,EAAKrE,YAAc,GAAKhE,GAGrD,CACLA,MAAOA,EACPE,OAAQA,EACRG,EAAGA,EACHE,EAAGA,EAEP,CFCkMmJ,CAAgBnI,EAAmB7F,IACrO,CG1Be,SAASiO,GAAe9M,GACrC,IAOIkI,EAPAtK,EAAYoC,EAAKpC,UACjBiB,EAAUmB,EAAKnB,QACfb,EAAYgC,EAAKhC,UACjBqI,EAAgBrI,EAAYuD,EAAiBvD,GAAa,KAC1DiK,EAAYjK,EAAY4J,EAAa5J,GAAa,KAClD+O,EAAUnP,EAAU4F,EAAI5F,EAAUuF,MAAQ,EAAItE,EAAQsE,MAAQ,EAC9D6J,EAAUpP,EAAU8F,EAAI9F,EAAUyF,OAAS,EAAIxE,EAAQwE,OAAS,EAGpE,OAAQgD,GACN,KAAK,EACH6B,EAAU,CACR1E,EAAGuJ,EACHrJ,EAAG9F,EAAU8F,EAAI7E,EAAQwE,QAE3B,MAEF,KAAKnG,EACHgL,EAAU,CACR1E,EAAGuJ,EACHrJ,EAAG9F,EAAU8F,EAAI9F,EAAUyF,QAE7B,MAEF,KAAKlG,EACH+K,EAAU,CACR1E,EAAG5F,EAAU4F,EAAI5F,EAAUuF,MAC3BO,EAAGsJ,GAEL,MAEF,KAAK5P,EACH8K,EAAU,CACR1E,EAAG5F,EAAU4F,EAAI3E,EAAQsE,MACzBO,EAAGsJ,GAEL,MAEF,QACE9E,EAAU,CACR1E,EAAG5F,EAAU4F,EACbE,EAAG9F,EAAU8F,GAInB,IAAIuJ,EAAW5G,EAAgBV,EAAyBU,GAAiB,KAEzE,GAAgB,MAAZ4G,EAAkB,CACpB,IAAI1G,EAAmB,MAAb0G,EAAmB,SAAW,QAExC,OAAQhF,GACN,KAAK1K,EACH2K,EAAQ+E,GAAY/E,EAAQ+E,IAAarP,EAAU2I,GAAO,EAAI1H,EAAQ0H,GAAO,GAC7E,MAEF,KAAK/I,EACH0K,EAAQ+E,GAAY/E,EAAQ+E,IAAarP,EAAU2I,GAAO,EAAI1H,EAAQ0H,GAAO,GAKnF,CAEA,OAAO2B,CACT,CC3De,SAASgF,GAAejN,EAAOc,QAC5B,IAAZA,IACFA,EAAU,CAAC,GAGb,IAAIoM,EAAWpM,EACXqM,EAAqBD,EAASnP,UAC9BA,OAAmC,IAAvBoP,EAAgCnN,EAAMjC,UAAYoP,EAC9DC,EAAoBF,EAASnM,SAC7BA,OAAiC,IAAtBqM,EAA+BpN,EAAMe,SAAWqM,EAC3DC,EAAoBH,EAASI,SAC7BA,OAAiC,IAAtBD,EAA+B7P,EAAkB6P,EAC5DE,EAAwBL,EAASM,aACjCA,OAAyC,IAA1BD,EAAmC9P,EAAW8P,EAC7DE,EAAwBP,EAASQ,eACjCA,OAA2C,IAA1BD,EAAmC/P,EAAS+P,EAC7DE,EAAuBT,EAASU,YAChCA,OAAuC,IAAzBD,GAA0CA,EACxDE,EAAmBX,EAAS3G,QAC5BA,OAA+B,IAArBsH,EAA8B,EAAIA,EAC5ChI,EAAgBD,EAAsC,iBAAZW,EAAuBA,EAAUT,EAAgBS,EAASlJ,IACpGyQ,EAAaJ,IAAmBhQ,EAASC,EAAYD,EACrDqK,EAAa/H,EAAMwG,MAAM9I,OACzBkB,EAAUoB,EAAME,SAAS0N,EAAcE,EAAaJ,GACpDK,EJkBS,SAAyBnP,EAAS0O,EAAUE,EAAczM,GACvE,IAAIiN,EAAmC,oBAAbV,EAlB5B,SAA4B1O,GAC1B,IAAIpB,EAAkBgO,GAAkB5G,EAAchG,IAElDqP,EADoB,CAAC,WAAY,SAASzJ,QAAQ,EAAiB5F,GAASiC,WAAa,GACnDtB,EAAcX,GAAWoG,EAAgBpG,GAAWA,EAE9F,OAAKS,EAAU4O,GAKRzQ,EAAgBgI,QAAO,SAAUyG,GACtC,OAAO5M,EAAU4M,IAAmBpI,EAASoI,EAAgBgC,IAAmD,SAAhCtP,EAAYsN,EAC9F,IANS,EAOX,CAK6DiC,CAAmBtP,GAAW,GAAGZ,OAAOsP,GAC/F9P,EAAkB,GAAGQ,OAAOgQ,EAAqB,CAACR,IAClDW,EAAsB3Q,EAAgB,GACtC4Q,EAAe5Q,EAAgBK,QAAO,SAAUwQ,EAASpC,GAC3D,IAAIF,EAAOC,GAA2BpN,EAASqN,EAAgBlL,GAK/D,OAJAsN,EAAQrN,IAAM,EAAI+K,EAAK/K,IAAKqN,EAAQrN,KACpCqN,EAAQnR,MAAQ,EAAI6O,EAAK7O,MAAOmR,EAAQnR,OACxCmR,EAAQpR,OAAS,EAAI8O,EAAK9O,OAAQoR,EAAQpR,QAC1CoR,EAAQlR,KAAO,EAAI4O,EAAK5O,KAAMkR,EAAQlR,MAC/BkR,CACT,GAAGrC,GAA2BpN,EAASuP,EAAqBpN,IAK5D,OAJAqN,EAAalL,MAAQkL,EAAalR,MAAQkR,EAAajR,KACvDiR,EAAahL,OAASgL,EAAanR,OAASmR,EAAapN,IACzDoN,EAAa7K,EAAI6K,EAAajR,KAC9BiR,EAAa3K,EAAI2K,EAAapN,IACvBoN,CACT,CInC2BE,CAAgBjP,EAAUT,GAAWA,EAAUA,EAAQ2P,gBAAkB9J,EAAmBzE,EAAME,SAASxC,QAAS4P,EAAUE,EAAczM,GACjKyN,EAAsB7L,EAAsB3C,EAAME,SAASvC,WAC3DuI,EAAgB2G,GAAe,CACjClP,UAAW6Q,EACX5P,QAASmJ,EACThH,SAAU,WACVhD,UAAWA,IAET0Q,EAAmB3C,GAAiBzP,OAAOkE,OAAO,CAAC,EAAGwH,EAAY7B,IAClEwI,EAAoBhB,IAAmBhQ,EAAS+Q,EAAmBD,EAGnEG,EAAkB,CACpB3N,IAAK+M,EAAmB/M,IAAM0N,EAAkB1N,IAAM6E,EAAc7E,IACpE/D,OAAQyR,EAAkBzR,OAAS8Q,EAAmB9Q,OAAS4I,EAAc5I,OAC7EE,KAAM4Q,EAAmB5Q,KAAOuR,EAAkBvR,KAAO0I,EAAc1I,KACvED,MAAOwR,EAAkBxR,MAAQ6Q,EAAmB7Q,MAAQ2I,EAAc3I,OAExE0R,EAAa5O,EAAMmG,cAAckB,OAErC,GAAIqG,IAAmBhQ,GAAUkR,EAAY,CAC3C,IAAIvH,EAASuH,EAAW7Q,GACxB1B,OAAO4D,KAAK0O,GAAiBxO,SAAQ,SAAUhE,GAC7C,IAAI0S,EAAW,CAAC3R,EAAOD,GAAQuH,QAAQrI,IAAQ,EAAI,GAAK,EACpDkK,EAAO,CAAC,EAAKpJ,GAAQuH,QAAQrI,IAAQ,EAAI,IAAM,IACnDwS,EAAgBxS,IAAQkL,EAAOhB,GAAQwI,CACzC,GACF,CAEA,OAAOF,CACT,CCyEA,UACEhP,KAAM,OACNC,SAAS,EACTC,MAAO,OACPC,GA5HF,SAAcC,GACZ,IAAIC,EAAQD,EAAKC,MACbc,EAAUf,EAAKe,QACfnB,EAAOI,EAAKJ,KAEhB,IAAIK,EAAMmG,cAAcxG,GAAMmP,MAA9B,CAoCA,IAhCA,IAAIC,EAAoBjO,EAAQkM,SAC5BgC,OAAsC,IAAtBD,GAAsCA,EACtDE,EAAmBnO,EAAQoO,QAC3BC,OAAoC,IAArBF,GAAqCA,EACpDG,EAA8BtO,EAAQuO,mBACtC9I,EAAUzF,EAAQyF,QAClB+G,EAAWxM,EAAQwM,SACnBE,EAAe1M,EAAQ0M,aACvBI,EAAc9M,EAAQ8M,YACtB0B,EAAwBxO,EAAQyO,eAChCA,OAA2C,IAA1BD,GAA0CA,EAC3DE,EAAwB1O,EAAQ0O,sBAChCC,EAAqBzP,EAAMc,QAAQ/C,UACnCqI,EAAgB9E,EAAiBmO,GAEjCJ,EAAqBD,IADHhJ,IAAkBqJ,GACqCF,EAjC/E,SAAuCxR,GACrC,GAAIuD,EAAiBvD,KAAeX,EAClC,MAAO,GAGT,IAAIsS,EAAoBnF,GAAqBxM,GAC7C,MAAO,CAAC2M,GAA8B3M,GAAY2R,EAAmBhF,GAA8BgF,GACrG,CA0B6IC,CAA8BF,GAA3E,CAAClF,GAAqBkF,KAChHG,EAAa,CAACH,GAAoBzR,OAAOqR,GAAoBxR,QAAO,SAAUC,EAAKC,GACrF,OAAOD,EAAIE,OAAOsD,EAAiBvD,KAAeX,ECvCvC,SAA8B4C,EAAOc,QAClC,IAAZA,IACFA,EAAU,CAAC,GAGb,IAAIoM,EAAWpM,EACX/C,EAAYmP,EAASnP,UACrBuP,EAAWJ,EAASI,SACpBE,EAAeN,EAASM,aACxBjH,EAAU2G,EAAS3G,QACnBgJ,EAAiBrC,EAASqC,eAC1BM,EAAwB3C,EAASsC,sBACjCA,OAAkD,IAA1BK,EAAmC,EAAgBA,EAC3E7H,EAAYL,EAAa5J,GACzB6R,EAAa5H,EAAYuH,EAAiB3R,EAAsBA,EAAoB4H,QAAO,SAAUzH,GACvG,OAAO4J,EAAa5J,KAAeiK,CACrC,IAAK3K,EACDyS,EAAoBF,EAAWpK,QAAO,SAAUzH,GAClD,OAAOyR,EAAsBhL,QAAQzG,IAAc,CACrD,IAEiC,IAA7B+R,EAAkBC,SACpBD,EAAoBF,GAQtB,IAAII,EAAYF,EAAkBjS,QAAO,SAAUC,EAAKC,GAOtD,OANAD,EAAIC,GAAakP,GAAejN,EAAO,CACrCjC,UAAWA,EACXuP,SAAUA,EACVE,aAAcA,EACdjH,QAASA,IACRjF,EAAiBvD,IACbD,CACT,GAAG,CAAC,GACJ,OAAOzB,OAAO4D,KAAK+P,GAAWC,MAAK,SAAUC,EAAGC,GAC9C,OAAOH,EAAUE,GAAKF,EAAUG,EAClC,GACF,CDH6DC,CAAqBpQ,EAAO,CACnFjC,UAAWA,EACXuP,SAAUA,EACVE,aAAcA,EACdjH,QAASA,EACTgJ,eAAgBA,EAChBC,sBAAuBA,IACpBzR,EACP,GAAG,IACCsS,EAAgBrQ,EAAMwG,MAAM7I,UAC5BoK,EAAa/H,EAAMwG,MAAM9I,OACzB4S,EAAY,IAAIC,IAChBC,GAAqB,EACrBC,EAAwBb,EAAW,GAE9Bc,EAAI,EAAGA,EAAId,EAAWG,OAAQW,IAAK,CAC1C,IAAI3S,EAAY6R,EAAWc,GAEvBC,EAAiBrP,EAAiBvD,GAElC6S,EAAmBjJ,EAAa5J,KAAeT,EAC/CuT,EAAa,CAAC,EAAK5T,GAAQuH,QAAQmM,IAAmB,EACtDrK,EAAMuK,EAAa,QAAU,SAC7B1F,EAAW8B,GAAejN,EAAO,CACnCjC,UAAWA,EACXuP,SAAUA,EACVE,aAAcA,EACdI,YAAaA,EACbrH,QAASA,IAEPuK,EAAoBD,EAAaD,EAAmB1T,EAAQC,EAAOyT,EAAmB3T,EAAS,EAE/FoT,EAAc/J,GAAOyB,EAAWzB,KAClCwK,EAAoBvG,GAAqBuG,IAG3C,IAAIC,EAAmBxG,GAAqBuG,GACxCE,EAAS,GAUb,GARIhC,GACFgC,EAAOC,KAAK9F,EAASwF,IAAmB,GAGtCxB,GACF6B,EAAOC,KAAK9F,EAAS2F,IAAsB,EAAG3F,EAAS4F,IAAqB,GAG1EC,EAAOE,OAAM,SAAUC,GACzB,OAAOA,CACT,IAAI,CACFV,EAAwB1S,EACxByS,GAAqB,EACrB,KACF,CAEAF,EAAUc,IAAIrT,EAAWiT,EAC3B,CAEA,GAAIR,EAqBF,IAnBA,IAEIa,EAAQ,SAAeC,GACzB,IAAIC,EAAmB3B,EAAW4B,MAAK,SAAUzT,GAC/C,IAAIiT,EAASV,EAAU9T,IAAIuB,GAE3B,GAAIiT,EACF,OAAOA,EAAOS,MAAM,EAAGH,GAAIJ,OAAM,SAAUC,GACzC,OAAOA,CACT,GAEJ,IAEA,GAAII,EAEF,OADAd,EAAwBc,EACjB,OAEX,EAESD,EAnBY/B,EAAiB,EAAI,EAmBZ+B,EAAK,GAGpB,UAFFD,EAAMC,GADmBA,KAOpCtR,EAAMjC,YAAc0S,IACtBzQ,EAAMmG,cAAcxG,GAAMmP,OAAQ,EAClC9O,EAAMjC,UAAY0S,EAClBzQ,EAAM0R,OAAQ,EA5GhB,CA8GF,EAQEhK,iBAAkB,CAAC,UACnBgC,KAAM,CACJoF,OAAO,IE7IX,SAAS6C,GAAexG,EAAUY,EAAM6F,GAQtC,YAPyB,IAArBA,IACFA,EAAmB,CACjBrO,EAAG,EACHE,EAAG,IAIA,CACLzC,IAAKmK,EAASnK,IAAM+K,EAAK3I,OAASwO,EAAiBnO,EACnDvG,MAAOiO,EAASjO,MAAQ6O,EAAK7I,MAAQ0O,EAAiBrO,EACtDtG,OAAQkO,EAASlO,OAAS8O,EAAK3I,OAASwO,EAAiBnO,EACzDtG,KAAMgO,EAAShO,KAAO4O,EAAK7I,MAAQ0O,EAAiBrO,EAExD,CAEA,SAASsO,GAAsB1G,GAC7B,MAAO,CAAC,EAAKjO,EAAOD,EAAQE,GAAM2U,MAAK,SAAUC,GAC/C,OAAO5G,EAAS4G,IAAS,CAC3B,GACF,CA+BA,UACEpS,KAAM,OACNC,SAAS,EACTC,MAAO,OACP6H,iBAAkB,CAAC,mBACnB5H,GAlCF,SAAcC,GACZ,IAAIC,EAAQD,EAAKC,MACbL,EAAOI,EAAKJ,KACZ0Q,EAAgBrQ,EAAMwG,MAAM7I,UAC5BoK,EAAa/H,EAAMwG,MAAM9I,OACzBkU,EAAmB5R,EAAMmG,cAAc6L,gBACvCC,EAAoBhF,GAAejN,EAAO,CAC5C0N,eAAgB,cAEdwE,EAAoBjF,GAAejN,EAAO,CAC5C4N,aAAa,IAEXuE,EAA2BR,GAAeM,EAAmB5B,GAC7D+B,EAAsBT,GAAeO,EAAmBnK,EAAY6J,GACpES,EAAoBR,GAAsBM,GAC1CG,EAAmBT,GAAsBO,GAC7CpS,EAAMmG,cAAcxG,GAAQ,CAC1BwS,yBAA0BA,EAC1BC,oBAAqBA,EACrBC,kBAAmBA,EACnBC,iBAAkBA,GAEpBtS,EAAMM,WAAW5C,OAASrB,OAAOkE,OAAO,CAAC,EAAGP,EAAMM,WAAW5C,OAAQ,CACnE,+BAAgC2U,EAChC,sBAAuBC,GAE3B,GCJA,IACE3S,KAAM,SACNC,SAAS,EACTC,MAAO,OACPwB,SAAU,CAAC,iBACXvB,GA5BF,SAAgBa,GACd,IAAIX,EAAQW,EAAMX,MACdc,EAAUH,EAAMG,QAChBnB,EAAOgB,EAAMhB,KACb4S,EAAkBzR,EAAQuG,OAC1BA,OAA6B,IAApBkL,EAA6B,CAAC,EAAG,GAAKA,EAC/C7I,EAAO,UAAkB,SAAU5L,EAAKC,GAE1C,OADAD,EAAIC,GA5BD,SAAiCA,EAAWyI,EAAOa,GACxD,IAAIjB,EAAgB9E,EAAiBvD,GACjCyU,EAAiB,CAACrV,EAAM,GAAKqH,QAAQ4B,IAAkB,GAAK,EAAI,EAEhErG,EAAyB,mBAAXsH,EAAwBA,EAAOhL,OAAOkE,OAAO,CAAC,EAAGiG,EAAO,CACxEzI,UAAWA,KACPsJ,EACFoL,EAAW1S,EAAK,GAChB2S,EAAW3S,EAAK,GAIpB,OAFA0S,EAAWA,GAAY,EACvBC,GAAYA,GAAY,GAAKF,EACtB,CAACrV,EAAMD,GAAOsH,QAAQ4B,IAAkB,EAAI,CACjD7C,EAAGmP,EACHjP,EAAGgP,GACD,CACFlP,EAAGkP,EACHhP,EAAGiP,EAEP,CASqBC,CAAwB5U,EAAWiC,EAAMwG,MAAOa,GAC1DvJ,CACT,GAAG,CAAC,GACA8U,EAAwBlJ,EAAK1J,EAAMjC,WACnCwF,EAAIqP,EAAsBrP,EAC1BE,EAAImP,EAAsBnP,EAEW,MAArCzD,EAAMmG,cAAcD,gBACtBlG,EAAMmG,cAAcD,cAAc3C,GAAKA,EACvCvD,EAAMmG,cAAcD,cAAczC,GAAKA,GAGzCzD,EAAMmG,cAAcxG,GAAQ+J,CAC9B,GC1BA,IACE/J,KAAM,gBACNC,SAAS,EACTC,MAAO,OACPC,GApBF,SAAuBC,GACrB,IAAIC,EAAQD,EAAKC,MACbL,EAAOI,EAAKJ,KAKhBK,EAAMmG,cAAcxG,GAAQkN,GAAe,CACzClP,UAAWqC,EAAMwG,MAAM7I,UACvBiB,QAASoB,EAAMwG,MAAM9I,OACrBqD,SAAU,WACVhD,UAAWiC,EAAMjC,WAErB,EAQE2L,KAAM,CAAC,GCgHT,IACE/J,KAAM,kBACNC,SAAS,EACTC,MAAO,OACPC,GA/HF,SAAyBC,GACvB,IAAIC,EAAQD,EAAKC,MACbc,EAAUf,EAAKe,QACfnB,EAAOI,EAAKJ,KACZoP,EAAoBjO,EAAQkM,SAC5BgC,OAAsC,IAAtBD,GAAsCA,EACtDE,EAAmBnO,EAAQoO,QAC3BC,OAAoC,IAArBF,GAAsCA,EACrD3B,EAAWxM,EAAQwM,SACnBE,EAAe1M,EAAQ0M,aACvBI,EAAc9M,EAAQ8M,YACtBrH,EAAUzF,EAAQyF,QAClBsM,EAAkB/R,EAAQgS,OAC1BA,OAA6B,IAApBD,GAAoCA,EAC7CE,EAAwBjS,EAAQkS,aAChCA,OAAyC,IAA1BD,EAAmC,EAAIA,EACtD5H,EAAW8B,GAAejN,EAAO,CACnCsN,SAAUA,EACVE,aAAcA,EACdjH,QAASA,EACTqH,YAAaA,IAEXxH,EAAgB9E,EAAiBtB,EAAMjC,WACvCiK,EAAYL,EAAa3H,EAAMjC,WAC/BkV,GAAmBjL,EACnBgF,EAAWtH,EAAyBU,GACpC8I,ECrCY,MDqCSlC,ECrCH,IAAM,IDsCxB9G,EAAgBlG,EAAMmG,cAAcD,cACpCmK,EAAgBrQ,EAAMwG,MAAM7I,UAC5BoK,EAAa/H,EAAMwG,MAAM9I,OACzBwV,EAA4C,mBAAjBF,EAA8BA,EAAa3W,OAAOkE,OAAO,CAAC,EAAGP,EAAMwG,MAAO,CACvGzI,UAAWiC,EAAMjC,aACbiV,EACFG,EAA2D,iBAAtBD,EAAiC,CACxElG,SAAUkG,EACVhE,QAASgE,GACP7W,OAAOkE,OAAO,CAChByM,SAAU,EACVkC,QAAS,GACRgE,GACCE,EAAsBpT,EAAMmG,cAAckB,OAASrH,EAAMmG,cAAckB,OAAOrH,EAAMjC,WAAa,KACjG2L,EAAO,CACTnG,EAAG,EACHE,EAAG,GAGL,GAAKyC,EAAL,CAIA,GAAI8I,EAAe,CACjB,IAAIqE,EAEAC,EAAwB,MAAbtG,EAAmB,EAAM7P,EACpCoW,EAAuB,MAAbvG,EAAmB/P,EAASC,EACtCoJ,EAAmB,MAAb0G,EAAmB,SAAW,QACpC3F,EAASnB,EAAc8G,GACvBtL,EAAM2F,EAAS8D,EAASmI,GACxB7R,EAAM4F,EAAS8D,EAASoI,GACxBC,EAAWV,GAAU/K,EAAWzB,GAAO,EAAI,EAC3CmN,EAASzL,IAAc1K,EAAQ+S,EAAc/J,GAAOyB,EAAWzB,GAC/DoN,EAAS1L,IAAc1K,GAASyK,EAAWzB,IAAQ+J,EAAc/J,GAGjEL,EAAejG,EAAME,SAASgB,MAC9BwF,EAAYoM,GAAU7M,EAAetC,EAAcsC,GAAgB,CACrE/C,MAAO,EACPE,OAAQ,GAENuQ,GAAqB3T,EAAMmG,cAAc,oBAAsBnG,EAAMmG,cAAc,oBAAoBI,QxBhFtG,CACLvF,IAAK,EACL9D,MAAO,EACPD,OAAQ,EACRE,KAAM,GwB6EFyW,GAAkBD,GAAmBL,GACrCO,GAAkBF,GAAmBJ,GAMrCO,GAAWnO,EAAO,EAAG0K,EAAc/J,GAAMI,EAAUJ,IACnDyN,GAAYd,EAAkB5C,EAAc/J,GAAO,EAAIkN,EAAWM,GAAWF,GAAkBT,EAA4BnG,SAAWyG,EAASK,GAAWF,GAAkBT,EAA4BnG,SACxMgH,GAAYf,GAAmB5C,EAAc/J,GAAO,EAAIkN,EAAWM,GAAWD,GAAkBV,EAA4BnG,SAAW0G,EAASI,GAAWD,GAAkBV,EAA4BnG,SACzMjG,GAAoB/G,EAAME,SAASgB,OAAS8D,EAAgBhF,EAAME,SAASgB,OAC3E+S,GAAelN,GAAiC,MAAbiG,EAAmBjG,GAAkBsF,WAAa,EAAItF,GAAkBuF,YAAc,EAAI,EAC7H4H,GAAwH,OAAjGb,EAA+C,MAAvBD,OAA8B,EAASA,EAAoBpG,IAAqBqG,EAAwB,EAEvJc,GAAY9M,EAAS2M,GAAYE,GACjCE,GAAkBzO,EAAOmN,EAAS,EAAQpR,EAF9B2F,EAAS0M,GAAYG,GAAsBD,IAEKvS,EAAK2F,EAAQyL,EAAS,EAAQrR,EAAK0S,IAAa1S,GAChHyE,EAAc8G,GAAYoH,GAC1B1K,EAAKsD,GAAYoH,GAAkB/M,CACrC,CAEA,GAAI8H,EAAc,CAChB,IAAIkF,GAEAC,GAAyB,MAAbtH,EAAmB,EAAM7P,EAErCoX,GAAwB,MAAbvH,EAAmB/P,EAASC,EAEvCsX,GAAUtO,EAAcgJ,GAExBuF,GAAmB,MAAZvF,EAAkB,SAAW,QAEpCwF,GAAOF,GAAUrJ,EAASmJ,IAE1BK,GAAOH,GAAUrJ,EAASoJ,IAE1BK,IAAuD,IAAxC,CAAC,EAAKzX,GAAMqH,QAAQ4B,GAEnCyO,GAAyH,OAAjGR,GAAgD,MAAvBjB,OAA8B,EAASA,EAAoBlE,IAAoBmF,GAAyB,EAEzJS,GAAaF,GAAeF,GAAOF,GAAUnE,EAAcoE,IAAQ1M,EAAW0M,IAAQI,GAAuB1B,EAA4BjE,QAEzI6F,GAAaH,GAAeJ,GAAUnE,EAAcoE,IAAQ1M,EAAW0M,IAAQI,GAAuB1B,EAA4BjE,QAAUyF,GAE5IK,GAAmBlC,GAAU8B,G1BzH9B,SAAwBlT,EAAK1E,EAAOyE,GACzC,IAAIwT,EAAItP,EAAOjE,EAAK1E,EAAOyE,GAC3B,OAAOwT,EAAIxT,EAAMA,EAAMwT,CACzB,C0BsHoDC,CAAeJ,GAAYN,GAASO,IAAcpP,EAAOmN,EAASgC,GAAaJ,GAAMF,GAAS1B,EAASiC,GAAaJ,IAEpKzO,EAAcgJ,GAAW8F,GACzBtL,EAAKwF,GAAW8F,GAAmBR,EACrC,CAEAxU,EAAMmG,cAAcxG,GAAQ+J,CAvE5B,CAwEF,EAQEhC,iBAAkB,CAAC,WE1HN,SAASyN,GAAiBC,EAAyBrQ,EAAcsD,QAC9D,IAAZA,IACFA,GAAU,GAGZ,ICnBoCrJ,ECJOJ,EFuBvCyW,EAA0B9V,EAAcwF,GACxCuQ,EAAuB/V,EAAcwF,IAf3C,SAAyBnG,GACvB,IAAImN,EAAOnN,EAAQ+D,wBACfI,EAASpB,EAAMoK,EAAK7I,OAAStE,EAAQqE,aAAe,EACpDD,EAASrB,EAAMoK,EAAK3I,QAAUxE,EAAQuE,cAAgB,EAC1D,OAAkB,IAAXJ,GAA2B,IAAXC,CACzB,CAU4DuS,CAAgBxQ,GACtEJ,EAAkBF,EAAmBM,GACrCgH,EAAOpJ,EAAsByS,EAAyBE,EAAsBjN,GAC5EyB,EAAS,CACXc,WAAY,EACZE,UAAW,GAET7C,EAAU,CACZ1E,EAAG,EACHE,EAAG,GAkBL,OAfI4R,IAA4BA,IAA4BhN,MACxB,SAA9B1J,EAAYoG,IAChBkG,GAAetG,MACbmF,GCnCgC9K,EDmCT+F,KClCdhG,EAAUC,IAAUO,EAAcP,GCJxC,CACL4L,YAFyChM,EDQbI,GCNR4L,WACpBE,UAAWlM,EAAQkM,WDGZH,GAAgB3L,IDoCnBO,EAAcwF,KAChBkD,EAAUtF,EAAsBoC,GAAc,IACtCxB,GAAKwB,EAAauH,WAC1BrE,EAAQxE,GAAKsB,EAAasH,WACjB1H,IACTsD,EAAQ1E,EAAIyH,GAAoBrG,KAI7B,CACLpB,EAAGwI,EAAK5O,KAAO2M,EAAOc,WAAa3C,EAAQ1E,EAC3CE,EAAGsI,EAAK/K,IAAM8I,EAAOgB,UAAY7C,EAAQxE,EACzCP,MAAO6I,EAAK7I,MACZE,OAAQ2I,EAAK3I,OAEjB,CGvDA,SAASoS,GAAMC,GACb,IAAItT,EAAM,IAAIoO,IACVmF,EAAU,IAAIC,IACdC,EAAS,GAKb,SAAS3F,EAAK4F,GACZH,EAAQI,IAAID,EAASlW,MACN,GAAG3B,OAAO6X,EAASxU,UAAY,GAAIwU,EAASnO,kBAAoB,IACtEvH,SAAQ,SAAU4V,GACzB,IAAKL,EAAQM,IAAID,GAAM,CACrB,IAAIE,EAAc9T,EAAI3F,IAAIuZ,GAEtBE,GACFhG,EAAKgG,EAET,CACF,IACAL,EAAO3E,KAAK4E,EACd,CAQA,OAzBAJ,EAAUtV,SAAQ,SAAU0V,GAC1B1T,EAAIiP,IAAIyE,EAASlW,KAAMkW,EACzB,IAiBAJ,EAAUtV,SAAQ,SAAU0V,GACrBH,EAAQM,IAAIH,EAASlW,OAExBsQ,EAAK4F,EAET,IACOD,CACT,CClBA,IAEIM,GAAkB,CACpBnY,UAAW,SACX0X,UAAW,GACX1U,SAAU,YAGZ,SAASoV,KACP,IAAK,IAAI1B,EAAO2B,UAAUrG,OAAQsG,EAAO,IAAIpU,MAAMwS,GAAO6B,EAAO,EAAGA,EAAO7B,EAAM6B,IAC/ED,EAAKC,GAAQF,UAAUE,GAGzB,OAAQD,EAAKvE,MAAK,SAAUlT,GAC1B,QAASA,GAAoD,mBAAlCA,EAAQ+D,sBACrC,GACF,CAEO,SAAS4T,GAAgBC,QACL,IAArBA,IACFA,EAAmB,CAAC,GAGtB,IAAIC,EAAoBD,EACpBE,EAAwBD,EAAkBE,iBAC1CA,OAA6C,IAA1BD,EAAmC,GAAKA,EAC3DE,EAAyBH,EAAkBI,eAC3CA,OAA4C,IAA3BD,EAAoCV,GAAkBU,EAC3E,OAAO,SAAsBjZ,EAAWD,EAAQoD,QAC9B,IAAZA,IACFA,EAAU+V,GAGZ,IC/C6B/W,EAC3BgX,ED8CE9W,EAAQ,CACVjC,UAAW,SACXgZ,iBAAkB,GAClBjW,QAASzE,OAAOkE,OAAO,CAAC,EAAG2V,GAAiBW,GAC5C1Q,cAAe,CAAC,EAChBjG,SAAU,CACRvC,UAAWA,EACXD,OAAQA,GAEV4C,WAAY,CAAC,EACbD,OAAQ,CAAC,GAEP2W,EAAmB,GACnBC,GAAc,EACdrN,EAAW,CACb5J,MAAOA,EACPkX,WAAY,SAAoBC,GAC9B,IAAIrW,EAAsC,mBAArBqW,EAAkCA,EAAiBnX,EAAMc,SAAWqW,EACzFC,IACApX,EAAMc,QAAUzE,OAAOkE,OAAO,CAAC,EAAGsW,EAAgB7W,EAAMc,QAASA,GACjEd,EAAMiK,cAAgB,CACpBtM,UAAW0B,EAAU1B,GAAa6N,GAAkB7N,GAAaA,EAAU4Q,eAAiB/C,GAAkB7N,EAAU4Q,gBAAkB,GAC1I7Q,OAAQ8N,GAAkB9N,IAI5B,IEzE4B+X,EAC9B4B,EFwEMN,EDvCG,SAAwBtB,GAErC,IAAIsB,EAAmBvB,GAAMC,GAE7B,OAAO/W,EAAeb,QAAO,SAAUC,EAAK+B,GAC1C,OAAO/B,EAAIE,OAAO+Y,EAAiBvR,QAAO,SAAUqQ,GAClD,OAAOA,EAAShW,QAAUA,CAC5B,IACF,GAAG,GACL,CC8B+ByX,EEzEK7B,EFyEsB,GAAGzX,OAAO2Y,EAAkB3W,EAAMc,QAAQ2U,WExE9F4B,EAAS5B,EAAU5X,QAAO,SAAUwZ,EAAQE,GAC9C,IAAIC,EAAWH,EAAOE,EAAQ5X,MAK9B,OAJA0X,EAAOE,EAAQ5X,MAAQ6X,EAAWnb,OAAOkE,OAAO,CAAC,EAAGiX,EAAUD,EAAS,CACrEzW,QAASzE,OAAOkE,OAAO,CAAC,EAAGiX,EAAS1W,QAASyW,EAAQzW,SACrD4I,KAAMrN,OAAOkE,OAAO,CAAC,EAAGiX,EAAS9N,KAAM6N,EAAQ7N,QAC5C6N,EACEF,CACT,GAAG,CAAC,GAEGhb,OAAO4D,KAAKoX,GAAQlV,KAAI,SAAUhG,GACvC,OAAOkb,EAAOlb,EAChB,MFsGM,OAvCA6D,EAAM+W,iBAAmBA,EAAiBvR,QAAO,SAAUiS,GACzD,OAAOA,EAAE7X,OACX,IAoJFI,EAAM+W,iBAAiB5W,SAAQ,SAAUqI,GACvC,IAAI7I,EAAO6I,EAAM7I,KACb+X,EAAgBlP,EAAM1H,QACtBA,OAA4B,IAAlB4W,EAA2B,CAAC,EAAIA,EAC1ChX,EAAS8H,EAAM9H,OAEnB,GAAsB,mBAAXA,EAAuB,CAChC,IAAIiX,EAAYjX,EAAO,CACrBV,MAAOA,EACPL,KAAMA,EACNiK,SAAUA,EACV9I,QAASA,IAKXkW,EAAiB/F,KAAK0G,GAFT,WAAmB,EAGlC,CACF,IAjIS/N,EAASQ,QAClB,EAMAwN,YAAa,WACX,IAAIX,EAAJ,CAIA,IAAIY,EAAkB7X,EAAME,SACxBvC,EAAYka,EAAgBla,UAC5BD,EAASma,EAAgBna,OAG7B,GAAKyY,GAAiBxY,EAAWD,GAAjC,CASAsC,EAAMwG,MAAQ,CACZ7I,UAAWwX,GAAiBxX,EAAWqH,EAAgBtH,GAAoC,UAA3BsC,EAAMc,QAAQC,UAC9ErD,OAAQiG,EAAcjG,IAOxBsC,EAAM0R,OAAQ,EACd1R,EAAMjC,UAAYiC,EAAMc,QAAQ/C,UAKhCiC,EAAM+W,iBAAiB5W,SAAQ,SAAU0V,GACvC,OAAO7V,EAAMmG,cAAc0P,EAASlW,MAAQtD,OAAOkE,OAAO,CAAC,EAAGsV,EAASnM,KACzE,IAGA,IAFA,IAESoO,EAAQ,EAAGA,EAAQ9X,EAAM+W,iBAAiBhH,OAAQ+H,IAUzD,IAAoB,IAAhB9X,EAAM0R,MAAV,CAMA,IAAIqG,EAAwB/X,EAAM+W,iBAAiBe,GAC/ChY,EAAKiY,EAAsBjY,GAC3BkY,EAAyBD,EAAsBjX,QAC/CoM,OAAsC,IAA3B8K,EAAoC,CAAC,EAAIA,EACpDrY,EAAOoY,EAAsBpY,KAEf,mBAAPG,IACTE,EAAQF,EAAG,CACTE,MAAOA,EACPc,QAASoM,EACTvN,KAAMA,EACNiK,SAAUA,KACN5J,EAdR,MAHEA,EAAM0R,OAAQ,EACdoG,GAAS,CAnCb,CAbA,CAmEF,EAGA1N,QClM2BtK,EDkMV,WACf,OAAO,IAAImY,SAAQ,SAAUC,GAC3BtO,EAASgO,cACTM,EAAQlY,EACV,GACF,ECrMG,WAUL,OATK8W,IACHA,EAAU,IAAImB,SAAQ,SAAUC,GAC9BD,QAAQC,UAAUC,MAAK,WACrBrB,OAAUsB,EACVF,EAAQpY,IACV,GACF,KAGKgX,CACT,GD2LIuB,QAAS,WACPjB,IACAH,GAAc,CAChB,GAGF,IAAKd,GAAiBxY,EAAWD,GAK/B,OAAOkM,EAmCT,SAASwN,IACPJ,EAAiB7W,SAAQ,SAAUL,GACjC,OAAOA,GACT,IACAkX,EAAmB,EACrB,CAEA,OAvCApN,EAASsN,WAAWpW,GAASqX,MAAK,SAAUnY,IACrCiX,GAAenW,EAAQwX,eAC1BxX,EAAQwX,cAActY,EAE1B,IAmCO4J,CACT,CACF,CACO,IAAI2O,GAA4BhC,KGrPnC,GAA4BA,GAAgB,CAC9CI,iBAFqB,CAAC6B,GAAgB,GAAe,GAAe,EAAa,GAAQ,GAAM,GAAiB,EAAO,MCJrH,GAA4BjC,GAAgB,CAC9CI,iBAFqB,CAAC6B,GAAgB,GAAe,GAAe,KCQtE,MAEMC,GAAiB,gBAsBjBC,GAAc9Z,IAClB,IAAI+Z,EAAW/Z,EAAQga,aAAa,kBAEpC,IAAKD,GAAyB,MAAbA,EAAkB,CACjC,IAAIE,EAAgBja,EAAQga,aAAa,QAKzC,IAAKC,IAAkBA,EAAcC,SAAS,OAASD,EAAcE,WAAW,KAC9E,OAAO,KAILF,EAAcC,SAAS,OAASD,EAAcE,WAAW,OAC3DF,EAAgB,IAAIA,EAActX,MAAM,KAAK,MAG/CoX,EAAWE,GAAmC,MAAlBA,EAAwBA,EAAcG,OAAS,IAC7E,CAEA,OAAOL,CAAQ,EAGXM,GAAyBra,IAC7B,MAAM+Z,EAAWD,GAAY9Z,GAE7B,OAAI+Z,GACKjU,SAAS+C,cAAckR,GAAYA,EAGrC,IAAI,EAGPO,GAAyBta,IAC7B,MAAM+Z,EAAWD,GAAY9Z,GAC7B,OAAO+Z,EAAWjU,SAAS+C,cAAckR,GAAY,IAAI,EA0BrDQ,GAAuBva,IAC3BA,EAAQwa,cAAc,IAAIC,MAAMZ,IAAgB,EAG5C,GAAYa,MACXA,GAA4B,iBAAXA,UAIO,IAAlBA,EAAOC,SAChBD,EAASA,EAAO,SAGgB,IAApBA,EAAOE,UAGjBC,GAAaH,GAEb,GAAUA,GACLA,EAAOC,OAASD,EAAO,GAAKA,EAGf,iBAAXA,GAAuBA,EAAOvJ,OAAS,EACzCrL,SAAS+C,cAAc6R,GAGzB,KAGHI,GAAY9a,IAChB,IAAK,GAAUA,IAAgD,IAApCA,EAAQ+a,iBAAiB5J,OAClD,OAAO,EAGT,MAAM6J,EAAgF,YAA7DtV,iBAAiB1F,GAASib,iBAAiB,cAE9DC,EAAgBlb,EAAQmb,QAAQ,uBAEtC,IAAKD,EACH,OAAOF,EAGT,GAAIE,IAAkBlb,EAAS,CAC7B,MAAMob,EAAUpb,EAAQmb,QAAQ,WAEhC,GAAIC,GAAWA,EAAQ5V,aAAe0V,EACpC,OAAO,EAGT,GAAgB,OAAZE,EACF,OAAO,CAEX,CAEA,OAAOJ,CAAgB,EAGnBK,GAAarb,IACZA,GAAWA,EAAQ4a,WAAaU,KAAKC,gBAItCvb,EAAQwb,UAAUvW,SAAS,mBAIC,IAArBjF,EAAQyb,SACVzb,EAAQyb,SAGVzb,EAAQ0b,aAAa,aAAoD,UAArC1b,EAAQga,aAAa,aAG5D2B,GAAiB3b,IACrB,IAAK8F,SAASC,gBAAgB6V,aAC5B,OAAO,KAIT,GAAmC,mBAAxB5b,EAAQqF,YAA4B,CAC7C,MAAMwW,EAAO7b,EAAQqF,cACrB,OAAOwW,aAAgB/a,WAAa+a,EAAO,IAC7C,CAEA,OAAI7b,aAAmBc,WACdd,EAIJA,EAAQwF,WAINmW,GAAe3b,EAAQwF,YAHrB,IAGgC,EAGrCsW,GAAO,OAWPC,GAAS/b,IACbA,EAAQuE,YAAY,EAGhByX,GAAY,IACZ3b,OAAO4b,SAAWnW,SAAS6G,KAAK+O,aAAa,qBACxCrb,OAAO4b,OAGT,KAGHC,GAA4B,GAmB5BC,GAAQ,IAAuC,QAAjCrW,SAASC,gBAAgBqW,IAEvCC,GAAqBC,IAnBAC,QAoBN,KACjB,MAAMC,EAAIR,KAGV,GAAIQ,EAAG,CACL,MAAMzb,EAAOub,EAAOG,KACdC,EAAqBF,EAAEtb,GAAGH,GAChCyb,EAAEtb,GAAGH,GAAQub,EAAOK,gBACpBH,EAAEtb,GAAGH,GAAM6b,YAAcN,EAEzBE,EAAEtb,GAAGH,GAAM8b,WAAa,KACtBL,EAAEtb,GAAGH,GAAQ2b,EACNJ,EAAOK,gBAElB,GAjC0B,YAAxB7W,SAASgX,YAENZ,GAA0B/K,QAC7BrL,SAASyF,iBAAiB,oBAAoB,KAC5C,IAAK,MAAMgR,KAAYL,GACrBK,GACF,IAIJL,GAA0B7J,KAAKkK,IAE/BA,GAsBA,EAGEQ,GAAUR,IACU,mBAAbA,GACTA,GACF,EAGIS,GAAyB,CAACT,EAAUU,EAAmBC,GAAoB,KAC/E,IAAKA,EAEH,YADAH,GAAQR,GAIV,MACMY,EAnMiCnd,KACvC,IAAKA,EACH,OAAO,EAIT,IAAI,mBACFod,EAAkB,gBAClBC,GACEhd,OAAOqF,iBAAiB1F,GAC5B,MAAMsd,EAA0BC,OAAOC,WAAWJ,GAC5CK,EAAuBF,OAAOC,WAAWH,GAE/C,OAAKC,GAA4BG,GAKjCL,EAAqBA,EAAmBza,MAAM,KAAK,GACnD0a,EAAkBA,EAAgB1a,MAAM,KAAK,GAjFf,KAkFtB4a,OAAOC,WAAWJ,GAAsBG,OAAOC,WAAWH,KANzD,CAMoG,EA+KpFK,CAAiCT,GADlC,EAExB,IAAIU,GAAS,EAEb,MAAMC,EAAU,EACd5Q,aAEIA,IAAWiQ,IAIfU,GAAS,EACTV,EAAkBxR,oBAAoBoO,GAAgB+D,GACtDb,GAAQR,GAAS,EAGnBU,EAAkB1R,iBAAiBsO,GAAgB+D,GACnDC,YAAW,KACJF,GACHpD,GAAqB0C,EACvB,GACCE,EAAiB,EAahBW,GAAuB,CAACjR,EAAMkR,EAAeC,EAAeC,KAChE,MAAMC,EAAarR,EAAKsE,OACxB,IAAI+H,EAAQrM,EAAKjH,QAAQmY,GAGzB,OAAe,IAAX7E,GACM8E,GAAiBC,EAAiBpR,EAAKqR,EAAa,GAAKrR,EAAK,IAGxEqM,GAAS8E,EAAgB,GAAK,EAE1BC,IACF/E,GAASA,EAAQgF,GAAcA,GAG1BrR,EAAKjK,KAAKC,IAAI,EAAGD,KAAKE,IAAIoW,EAAOgF,EAAa,KAAI,EAarDC,GAAiB,qBACjBC,GAAiB,OACjBC,GAAgB,SAChBC,GAAgB,CAAC,EAEvB,IAAIC,GAAW,EACf,MAAMC,GAAe,CACnBC,WAAY,YACZC,WAAY,YAERC,GAAe,IAAI5H,IAAI,CAAC,QAAS,WAAY,UAAW,YAAa,cAAe,aAAc,iBAAkB,YAAa,WAAY,YAAa,cAAe,YAAa,UAAW,WAAY,QAAS,oBAAqB,aAAc,YAAa,WAAY,cAAe,cAAe,cAAe,YAAa,eAAgB,gBAAiB,eAAgB,gBAAiB,aAAc,QAAS,OAAQ,SAAU,QAAS,SAAU,SAAU,UAAW,WAAY,OAAQ,SAAU,eAAgB,SAAU,OAAQ,mBAAoB,mBAAoB,QAAS,QAAS,WAK/lB,SAAS6H,GAAa5e,EAAS6e,GAC7B,OAAOA,GAAO,GAAGA,MAAQN,QAAgBve,EAAQue,UAAYA,IAC/D,CAEA,SAASO,GAAiB9e,GACxB,MAAM6e,EAAMD,GAAa5e,GAGzB,OAFAA,EAAQue,SAAWM,EACnBP,GAAcO,GAAOP,GAAcO,IAAQ,CAAC,EACrCP,GAAcO,EACvB,CA0CA,SAASE,GAAYC,EAAQC,EAAUC,EAAqB,MAC1D,OAAOzhB,OAAO0hB,OAAOH,GAAQpM,MAAKwM,GAASA,EAAMH,WAAaA,GAAYG,EAAMF,qBAAuBA,GACzG,CAEA,SAASG,GAAoBC,EAAmB1B,EAAS2B,GACvD,MAAMC,EAAiC,iBAAZ5B,EAErBqB,EAAWO,EAAcD,EAAqB3B,GAAW2B,EAC/D,IAAIE,EAAYC,GAAaJ,GAM7B,OAJKX,GAAavH,IAAIqI,KACpBA,EAAYH,GAGP,CAACE,EAAaP,EAAUQ,EACjC,CAEA,SAASE,GAAW3f,EAASsf,EAAmB1B,EAAS2B,EAAoBK,GAC3E,GAAiC,iBAAtBN,IAAmCtf,EAC5C,OAGF,IAAKwf,EAAaP,EAAUQ,GAAaJ,GAAoBC,EAAmB1B,EAAS2B,GAGzF,GAAID,KAAqBd,GAAc,CACrC,MAAMqB,EAAe3e,GACZ,SAAUke,GACf,IAAKA,EAAMU,eAAiBV,EAAMU,gBAAkBV,EAAMW,iBAAmBX,EAAMW,eAAe9a,SAASma,EAAMU,eAC/G,OAAO5e,EAAGjD,KAAK+hB,KAAMZ,EAEzB,EAGFH,EAAWY,EAAaZ,EAC1B,CAEA,MAAMD,EAASF,GAAiB9e,GAC1BigB,EAAWjB,EAAOS,KAAeT,EAAOS,GAAa,CAAC,GACtDS,EAAmBnB,GAAYkB,EAAUhB,EAAUO,EAAc5B,EAAU,MAEjF,GAAIsC,EAEF,YADAA,EAAiBN,OAASM,EAAiBN,QAAUA,GAIvD,MAAMf,EAAMD,GAAaK,EAAUK,EAAkB1T,QAAQuS,GAAgB,KACvEjd,EAAKse,EAzEb,SAAoCxf,EAAS+Z,EAAU7Y,GACrD,OAAO,SAAS0c,EAAQwB,GACtB,MAAMe,EAAcngB,EAAQogB,iBAAiBrG,GAE7C,IAAK,IAAI,OACP/M,GACEoS,EAAOpS,GAAUA,IAAWgT,KAAMhT,EAASA,EAAOxH,WACpD,IAAK,MAAM6a,KAAcF,EACvB,GAAIE,IAAerT,EAYnB,OARAsT,GAAWlB,EAAO,CAChBW,eAAgB/S,IAGd4Q,EAAQgC,QACVW,GAAaC,IAAIxgB,EAASof,EAAMqB,KAAM1G,EAAU7Y,GAG3CA,EAAGwf,MAAM1T,EAAQ,CAACoS,GAG/B,CACF,CAiD2BuB,CAA2B3gB,EAAS4d,EAASqB,GAvFxE,SAA0Bjf,EAASkB,GACjC,OAAO,SAAS0c,EAAQwB,GAStB,OARAkB,GAAWlB,EAAO,CAChBW,eAAgB/f,IAGd4d,EAAQgC,QACVW,GAAaC,IAAIxgB,EAASof,EAAMqB,KAAMvf,GAGjCA,EAAGwf,MAAM1gB,EAAS,CAACof,GAC5B,CACF,CA2EoFwB,CAAiB5gB,EAASif,GAC5G/d,EAAGge,mBAAqBM,EAAc5B,EAAU,KAChD1c,EAAG+d,SAAWA,EACd/d,EAAG0e,OAASA,EACZ1e,EAAGqd,SAAWM,EACdoB,EAASpB,GAAO3d,EAChBlB,EAAQuL,iBAAiBkU,EAAWve,EAAIse,EAC1C,CAEA,SAASqB,GAAc7gB,EAASgf,EAAQS,EAAW7B,EAASsB,GAC1D,MAAMhe,EAAK6d,GAAYC,EAAOS,GAAY7B,EAASsB,GAE9Che,IAILlB,EAAQyL,oBAAoBgU,EAAWve,EAAI4f,QAAQ5B,WAC5CF,EAAOS,GAAWve,EAAGqd,UAC9B,CAEA,SAASwC,GAAyB/gB,EAASgf,EAAQS,EAAWuB,GAC5D,MAAMC,EAAoBjC,EAAOS,IAAc,CAAC,EAEhD,IAAK,MAAMyB,KAAczjB,OAAO4D,KAAK4f,GACnC,GAAIC,EAAWhH,SAAS8G,GAAY,CAClC,MAAM5B,EAAQ6B,EAAkBC,GAChCL,GAAc7gB,EAASgf,EAAQS,EAAWL,EAAMH,SAAUG,EAAMF,mBAClE,CAEJ,CAEA,SAASQ,GAAaN,GAGpB,OADAA,EAAQA,EAAMxT,QAAQwS,GAAgB,IAC/BI,GAAaY,IAAUA,CAChC,CAEA,MAAMmB,GAAe,CACnBY,GAAGnhB,EAASof,EAAOxB,EAAS2B,GAC1BI,GAAW3f,EAASof,EAAOxB,EAAS2B,GAAoB,EAC1D,EAEA6B,IAAIphB,EAASof,EAAOxB,EAAS2B,GAC3BI,GAAW3f,EAASof,EAAOxB,EAAS2B,GAAoB,EAC1D,EAEAiB,IAAIxgB,EAASsf,EAAmB1B,EAAS2B,GACvC,GAAiC,iBAAtBD,IAAmCtf,EAC5C,OAGF,MAAOwf,EAAaP,EAAUQ,GAAaJ,GAAoBC,EAAmB1B,EAAS2B,GACrF8B,EAAc5B,IAAcH,EAC5BN,EAASF,GAAiB9e,GAC1BihB,EAAoBjC,EAAOS,IAAc,CAAC,EAC1C6B,EAAchC,EAAkBnF,WAAW,KAEjD,QAAwB,IAAb8E,EAAX,CAUA,GAAIqC,EACF,IAAK,MAAMC,KAAgB9jB,OAAO4D,KAAK2d,GACrC+B,GAAyB/gB,EAASgf,EAAQuC,EAAcjC,EAAkBzM,MAAM,IAIpF,IAAK,MAAM2O,KAAe/jB,OAAO4D,KAAK4f,GAAoB,CACxD,MAAMC,EAAaM,EAAY5V,QAAQyS,GAAe,IAEtD,IAAKgD,GAAe/B,EAAkBpF,SAASgH,GAAa,CAC1D,MAAM9B,EAAQ6B,EAAkBO,GAChCX,GAAc7gB,EAASgf,EAAQS,EAAWL,EAAMH,SAAUG,EAAMF,mBAClE,CACF,CAfA,KARA,CAEE,IAAKzhB,OAAO4D,KAAK4f,GAAmB9P,OAClC,OAGF0P,GAAc7gB,EAASgf,EAAQS,EAAWR,EAAUO,EAAc5B,EAAU,KAE9E,CAgBF,EAEA6D,QAAQzhB,EAASof,EAAO3H,GACtB,GAAqB,iBAAV2H,IAAuBpf,EAChC,OAAO,KAGT,MAAMwc,EAAIR,KAGV,IAAI0F,EAAc,KACdC,GAAU,EACVC,GAAiB,EACjBC,GAAmB,EAJHzC,IADFM,GAAaN,IAOZ5C,IACjBkF,EAAclF,EAAE/B,MAAM2E,EAAO3H,GAC7B+E,EAAExc,GAASyhB,QAAQC,GACnBC,GAAWD,EAAYI,uBACvBF,GAAkBF,EAAYK,gCAC9BF,EAAmBH,EAAYM,sBAGjC,IAAIC,EAAM,IAAIxH,MAAM2E,EAAO,CACzBuC,UACAO,YAAY,IAgBd,OAdAD,EAAM3B,GAAW2B,EAAKxK,GAElBoK,GACFI,EAAIE,iBAGFP,GACF5hB,EAAQwa,cAAcyH,GAGpBA,EAAIJ,kBAAoBH,GAC1BA,EAAYS,iBAGPF,CACT,GAIF,SAAS3B,GAAWziB,EAAKukB,GACvB,IAAK,MAAO7kB,EAAKa,KAAUX,OAAO4kB,QAAQD,GAAQ,CAAC,GACjD,IACEvkB,EAAIN,GAAOa,CACb,CAAE,MAAOkkB,GACP7kB,OAAOC,eAAeG,EAAKN,EAAK,CAC9BglB,cAAc,EAEd3kB,IAAG,IACMQ,GAIb,CAGF,OAAOP,CACT,CAYA,MAAM2kB,GAAa,IAAI7Q,IACjB8Q,GAAO,CACXjQ,IAAIxS,EAASzC,EAAKyN,GACXwX,GAAWpL,IAAIpX,IAClBwiB,GAAWhQ,IAAIxS,EAAS,IAAI2R,KAG9B,MAAM+Q,EAAcF,GAAW5kB,IAAIoC,GAG9B0iB,EAAYtL,IAAI7Z,IAA6B,IAArBmlB,EAAYC,KAMzCD,EAAYlQ,IAAIjV,EAAKyN,GAJnB4X,QAAQC,MAAM,+EAA+Exf,MAAMyf,KAAKJ,EAAYrhB,QAAQ,MAKhI,EAEAzD,IAAG,CAACoC,EAASzC,IACPilB,GAAWpL,IAAIpX,IACVwiB,GAAW5kB,IAAIoC,GAASpC,IAAIL,IAG9B,KAGTwlB,OAAO/iB,EAASzC,GACd,IAAKilB,GAAWpL,IAAIpX,GAClB,OAGF,MAAM0iB,EAAcF,GAAW5kB,IAAIoC,GACnC0iB,EAAYM,OAAOzlB,GAEM,IAArBmlB,EAAYC,MACdH,GAAWQ,OAAOhjB,EAEtB,GAUF,SAASijB,GAAc7kB,GACrB,GAAc,SAAVA,EACF,OAAO,EAGT,GAAc,UAAVA,EACF,OAAO,EAGT,GAAIA,IAAUmf,OAAOnf,GAAOkC,WAC1B,OAAOid,OAAOnf,GAGhB,GAAc,KAAVA,GAA0B,SAAVA,EAClB,OAAO,KAGT,GAAqB,iBAAVA,EACT,OAAOA,EAGT,IACE,OAAO8kB,KAAKC,MAAMC,mBAAmBhlB,GACvC,CAAE,MAAOkkB,GACP,OAAOlkB,CACT,CACF,CAEA,SAASilB,GAAiB9lB,GACxB,OAAOA,EAAIqO,QAAQ,UAAU0X,GAAO,IAAIA,EAAIpjB,iBAC9C,CAEA,MAAMqjB,GAAc,CAClBC,iBAAiBxjB,EAASzC,EAAKa,GAC7B4B,EAAQ6B,aAAa,WAAWwhB,GAAiB9lB,KAAQa,EAC3D,EAEAqlB,oBAAoBzjB,EAASzC,GAC3ByC,EAAQ4B,gBAAgB,WAAWyhB,GAAiB9lB,KACtD,EAEAmmB,kBAAkB1jB,GAChB,IAAKA,EACH,MAAO,CAAC,EAGV,MAAM0B,EAAa,CAAC,EACdiiB,EAASlmB,OAAO4D,KAAKrB,EAAQ4jB,SAAShd,QAAOrJ,GAAOA,EAAI4c,WAAW,QAAU5c,EAAI4c,WAAW,cAElG,IAAK,MAAM5c,KAAOomB,EAAQ,CACxB,IAAIE,EAAUtmB,EAAIqO,QAAQ,MAAO,IACjCiY,EAAUA,EAAQC,OAAO,GAAG5jB,cAAgB2jB,EAAQhR,MAAM,EAAGgR,EAAQ1S,QACrEzP,EAAWmiB,GAAWZ,GAAcjjB,EAAQ4jB,QAAQrmB,GACtD,CAEA,OAAOmE,CACT,EAEAqiB,iBAAgB,CAAC/jB,EAASzC,IACjB0lB,GAAcjjB,EAAQga,aAAa,WAAWqJ,GAAiB9lB,QAe1E,MAAMymB,GAEOC,qBACT,MAAO,CAAC,CACV,CAEWC,yBACT,MAAO,CAAC,CACV,CAEWzH,kBACT,MAAM,IAAI0H,MAAM,sEAClB,CAEAC,WAAWC,GAMT,OALAA,EAASrE,KAAKsE,gBAAgBD,GAC9BA,EAASrE,KAAKuE,kBAAkBF,GAEhCrE,KAAKwE,iBAAiBH,GAEfA,CACT,CAEAE,kBAAkBF,GAChB,OAAOA,CACT,CAEAC,gBAAgBD,EAAQrkB,GACtB,MAAMykB,EAAa,GAAUzkB,GAAWujB,GAAYQ,iBAAiB/jB,EAAS,UAAY,CAAC,EAE3F,MAAO,IAAKggB,KAAK0E,YAAYT,WACD,iBAAfQ,EAA0BA,EAAa,CAAC,KAC/C,GAAUzkB,GAAWujB,GAAYG,kBAAkB1jB,GAAW,CAAC,KAC7C,iBAAXqkB,EAAsBA,EAAS,CAAC,EAE/C,CAEAG,iBAAiBH,EAAQM,EAAc3E,KAAK0E,YAAYR,aACtD,IAAK,MAAM3hB,KAAY9E,OAAO4D,KAAKsjB,GAAc,CAC/C,MAAMC,EAAgBD,EAAYpiB,GAC5BnE,EAAQimB,EAAO9hB,GACfsiB,EAAY,GAAUzmB,GAAS,UA1uBrCsc,OADSA,EA2uB+Ctc,GAzuBnD,GAAGsc,IAGLjd,OAAOM,UAAUuC,SAASrC,KAAKyc,GAAQoK,MAAM,eAAe,GAAG5kB,cAwuBlE,IAAK,IAAI6kB,OAAOH,GAAe9gB,KAAK+gB,GAClC,MAAM,IAAIG,UAAU,GAAGhF,KAAK0E,YAAYjI,KAAKwI,0BAA0B1iB,qBAA4BsiB,yBAAiCD,MAExI,CAhvBWlK,KAivBb,EAmBF,MAAMwK,WAAsBlB,GAC1BU,YAAY1kB,EAASqkB,GACnBc,SACAnlB,EAAU6a,GAAW7a,MAMrBggB,KAAKoF,SAAWplB,EAChBggB,KAAKqF,QAAUrF,KAAKoE,WAAWC,GAC/B5B,GAAKjQ,IAAIwN,KAAKoF,SAAUpF,KAAK0E,YAAYY,SAAUtF,MACrD,CAGAuF,UACE9C,GAAKM,OAAO/C,KAAKoF,SAAUpF,KAAK0E,YAAYY,UAC5C/E,GAAaC,IAAIR,KAAKoF,SAAUpF,KAAK0E,YAAYc,WAEjD,IAAK,MAAMC,KAAgBhoB,OAAOioB,oBAAoB1F,MACpDA,KAAKyF,GAAgB,IAEzB,CAEAE,eAAepJ,EAAUvc,EAAS4lB,GAAa,GAC7C5I,GAAuBT,EAAUvc,EAAS4lB,EAC5C,CAEAxB,WAAWC,GAMT,OALAA,EAASrE,KAAKsE,gBAAgBD,EAAQrE,KAAKoF,UAC3Cf,EAASrE,KAAKuE,kBAAkBF,GAEhCrE,KAAKwE,iBAAiBH,GAEfA,CACT,CAGAwB,mBAAmB7lB,GACjB,OAAOyiB,GAAK7kB,IAAIid,GAAW7a,GAAUggB,KAAKsF,SAC5C,CAEAO,2BAA2B7lB,EAASqkB,EAAS,CAAC,GAC5C,OAAOrE,KAAK8F,YAAY9lB,IAAY,IAAIggB,KAAKhgB,EAA2B,iBAAXqkB,EAAsBA,EAAS,KAC9F,CAEW0B,qBACT,MApDY,OAqDd,CAEWT,sBACT,MAAO,MAAMtF,KAAKvD,MACpB,CAEW+I,uBACT,MAAO,IAAIxF,KAAKsF,UAClB,CAEAO,iBAAiB9kB,GACf,MAAO,GAAGA,IAAOif,KAAKwF,WACxB,EAWF,MAAMQ,GAAuB,CAACC,EAAWC,EAAS,UAChD,MAAMC,EAAa,gBAAgBF,EAAUT,YACvCzkB,EAAOklB,EAAUxJ,KACvB8D,GAAaY,GAAGrb,SAAUqgB,EAAY,qBAAqBplB,OAAU,SAAUqe,GAK7E,GAJI,CAAC,IAAK,QAAQlF,SAAS8F,KAAKoG,UAC9BhH,EAAM+C,iBAGJ9G,GAAW2E,MACb,OAGF,MAAMhT,EAASsN,GAAuB0F,OAASA,KAAK7E,QAAQ,IAAIpa,KAC/CklB,EAAUI,oBAAoBrZ,GAEtCkZ,IACX,GAAE,EAeEI,GAAc,YACdC,GAAc,QAAQD,KACtBE,GAAe,SAASF,KAO9B,MAAMG,WAAcvB,GAEPzI,kBACT,MAdW,OAeb,CAGAiK,QAGE,GAFmBnG,GAAakB,QAAQzB,KAAKoF,SAAUmB,IAExC1E,iBACb,OAGF7B,KAAKoF,SAAS5J,UAAUuH,OAnBF,QAqBtB,MAAM6C,EAAa5F,KAAKoF,SAAS5J,UAAUvW,SAtBrB,QAwBtB+a,KAAK2F,gBAAe,IAAM3F,KAAK2G,mBAAmB3G,KAAKoF,SAAUQ,EACnE,CAGAe,kBACE3G,KAAKoF,SAASrC,SAEdxC,GAAakB,QAAQzB,KAAKoF,SAAUoB,IACpCxG,KAAKuF,SACP,CAGAM,uBAAuBxB,GACrB,OAAOrE,KAAK4G,MAAK,WACf,MAAM9b,EAAO2b,GAAMJ,oBAAoBrG,MAEvC,GAAsB,iBAAXqE,EAAX,CAIA,QAAqB7K,IAAjB1O,EAAKuZ,IAAyBA,EAAOlK,WAAW,MAAmB,gBAAXkK,EAC1D,MAAM,IAAIW,UAAU,oBAAoBX,MAG1CvZ,EAAKuZ,GAAQrE,KANb,CAOF,GACF,EAQFgG,GAAqBS,GAAO,SAK5BpK,GAAmBoK,IAYnB,MAKMI,GAAyB,4BAM/B,MAAMC,WAAe5B,GAERzI,kBACT,MAdW,QAeb,CAGAsK,SAEE/G,KAAKoF,SAASvjB,aAAa,eAAgBme,KAAKoF,SAAS5J,UAAUuL,OAhB3C,UAiB1B,CAGAlB,uBAAuBxB,GACrB,OAAOrE,KAAK4G,MAAK,WACf,MAAM9b,EAAOgc,GAAOT,oBAAoBrG,MAEzB,WAAXqE,GACFvZ,EAAKuZ,IAET,GACF,EAQF9D,GAAaY,GAAGrb,SAlCe,2BAkCmB+gB,IAAwBzH,IACxEA,EAAM+C,iBACN,MAAM6E,EAAS5H,EAAMpS,OAAOmO,QAAQ0L,IACvBC,GAAOT,oBAAoBW,GACnCD,QAAQ,IAMf1K,GAAmByK,IAYnB,MAAMG,GAAiB,CACrBrU,KAAI,CAACmH,EAAU/Z,EAAU8F,SAASC,kBACzB,GAAG3G,UAAUsB,QAAQ3C,UAAUqiB,iBAAiBniB,KAAK+B,EAAS+Z,IAGvEmN,QAAO,CAACnN,EAAU/Z,EAAU8F,SAASC,kBAC5BrF,QAAQ3C,UAAU8K,cAAc5K,KAAK+B,EAAS+Z,GAGvDoN,SAAQ,CAACnnB,EAAS+Z,IACT,GAAG3a,UAAUY,EAAQmnB,UAAUvgB,QAAOzB,GAASA,EAAMiiB,QAAQrN,KAGtEsN,QAAQrnB,EAAS+Z,GACf,MAAMsN,EAAU,GAChB,IAAIC,EAAWtnB,EAAQwF,WAAW2V,QAAQpB,GAE1C,KAAOuN,GACLD,EAAQhV,KAAKiV,GACbA,EAAWA,EAAS9hB,WAAW2V,QAAQpB,GAGzC,OAAOsN,CACT,EAEAE,KAAKvnB,EAAS+Z,GACZ,IAAIyN,EAAWxnB,EAAQynB,uBAEvB,KAAOD,GAAU,CACf,GAAIA,EAASJ,QAAQrN,GACnB,MAAO,CAACyN,GAGVA,EAAWA,EAASC,sBACtB,CAEA,MAAO,EACT,EAGAniB,KAAKtF,EAAS+Z,GACZ,IAAIzU,EAAOtF,EAAQ0nB,mBAEnB,KAAOpiB,GAAM,CACX,GAAIA,EAAK8hB,QAAQrN,GACf,MAAO,CAACzU,GAGVA,EAAOA,EAAKoiB,kBACd,CAEA,MAAO,EACT,EAEAC,kBAAkB3nB,GAChB,MAAM4nB,EAAa,CAAC,IAAK,SAAU,QAAS,WAAY,SAAU,UAAW,aAAc,4BAA4BrkB,KAAIwW,GAAY,GAAGA,2BAAiCpW,KAAK,KAChL,OAAOqc,KAAKpN,KAAKgV,EAAY5nB,GAAS4G,QAAOihB,IAAOxM,GAAWwM,IAAO/M,GAAU+M,IAClF,GAeIC,GAAc,YACdC,GAAmB,aAAaD,KAChCE,GAAkB,YAAYF,KAC9BG,GAAiB,WAAWH,KAC5BI,GAAoB,cAAcJ,KAClCK,GAAkB,YAAYL,KAK9BM,GAAY,CAChBC,YAAa,KACbC,aAAc,KACdC,cAAe,MAEXC,GAAgB,CACpBH,YAAa,kBACbC,aAAc,kBACdC,cAAe,mBAMjB,MAAME,WAAczE,GAClBU,YAAY1kB,EAASqkB,GACnBc,QACAnF,KAAKoF,SAAWplB,EAEXA,GAAYyoB,GAAMC,gBAIvB1I,KAAKqF,QAAUrF,KAAKoE,WAAWC,GAC/BrE,KAAK2I,QAAU,EACf3I,KAAK4I,sBAAwB9H,QAAQzgB,OAAOwoB,cAE5C7I,KAAK8I,cACP,CAGW7E,qBACT,OAAOmE,EACT,CAEWlE,yBACT,OAAOsE,EACT,CAEW/L,kBACT,MAnDW,OAoDb,CAGA8I,UACEhF,GAAaC,IAAIR,KAAKoF,SAAU0C,GAClC,CAGAiB,OAAO3J,GACAY,KAAK4I,sBAKN5I,KAAKgJ,wBAAwB5J,KAC/BY,KAAK2I,QAAUvJ,EAAM6J,SALrBjJ,KAAK2I,QAAUvJ,EAAM8J,QAAQ,GAAGD,OAOpC,CAEAE,KAAK/J,GACCY,KAAKgJ,wBAAwB5J,KAC/BY,KAAK2I,QAAUvJ,EAAM6J,QAAUjJ,KAAK2I,SAGtC3I,KAAKoJ,eAELrM,GAAQiD,KAAKqF,QAAQgD,YACvB,CAEAgB,MAAMjK,GACJY,KAAK2I,QAAUvJ,EAAM8J,SAAW9J,EAAM8J,QAAQ/X,OAAS,EAAI,EAAIiO,EAAM8J,QAAQ,GAAGD,QAAUjJ,KAAK2I,OACjG,CAEAS,eACE,MAAME,EAAY1mB,KAAKoC,IAAIgb,KAAK2I,SAEhC,GAAIW,GA9EgB,GA+ElB,OAGF,MAAMvb,EAAYub,EAAYtJ,KAAK2I,QACnC3I,KAAK2I,QAAU,EAEV5a,GAILgP,GAAQhP,EAAY,EAAIiS,KAAKqF,QAAQkD,cAAgBvI,KAAKqF,QAAQiD,aACpE,CAEAQ,cACM9I,KAAK4I,uBACPrI,GAAaY,GAAGnB,KAAKoF,SAAU8C,IAAmB9I,GAASY,KAAK+I,OAAO3J,KACvEmB,GAAaY,GAAGnB,KAAKoF,SAAU+C,IAAiB/I,GAASY,KAAKmJ,KAAK/J,KAEnEY,KAAKoF,SAAS5J,UAAUtE,IAlGG,mBAoG3BqJ,GAAaY,GAAGnB,KAAKoF,SAAU2C,IAAkB3I,GAASY,KAAK+I,OAAO3J,KACtEmB,GAAaY,GAAGnB,KAAKoF,SAAU4C,IAAiB5I,GAASY,KAAKqJ,MAAMjK,KACpEmB,GAAaY,GAAGnB,KAAKoF,SAAU6C,IAAgB7I,GAASY,KAAKmJ,KAAK/J,KAEtE,CAEA4J,wBAAwB5J,GACtB,OAAOY,KAAK4I,wBA5GS,QA4GiBxJ,EAAMmK,aA7GrB,UA6GyDnK,EAAMmK,YACxF,CAGA1D,qBACE,MAAO,iBAAkB/f,SAASC,iBAAmB7C,UAAUsmB,eAAiB,CAClF,EAcF,MAEMC,GAAc,eACdC,GAAiB,YAKjBC,GAAa,OACbC,GAAa,OACbC,GAAiB,OACjBC,GAAkB,QAClBC,GAAc,QAAQN,KACtBO,GAAa,OAAOP,KACpBQ,GAAkB,UAAUR,KAC5BS,GAAqB,aAAaT,KAClCU,GAAqB,aAAaV,KAClCW,GAAmB,YAAYX,KAC/BY,GAAwB,OAAOZ,KAAcC,KAC7CY,GAAyB,QAAQb,KAAcC,KAC/Ca,GAAsB,WACtBC,GAAsB,SAMtBC,GAAkB,UAClBC,GAAgB,iBAChBC,GAAuBF,GAAkBC,GAKzCE,GAAmB,CACvB,UAAoBd,GACpB,WAAqBD,IAEjBgB,GAAY,CAChBC,SAAU,IACVC,UAAU,EACVC,MAAO,QACPC,MAAM,EACNC,OAAO,EACPC,MAAM,GAEFC,GAAgB,CACpBN,SAAU,mBAEVC,SAAU,UACVC,MAAO,mBACPC,KAAM,mBACNC,MAAO,UACPC,KAAM,WAMR,MAAME,WAAiBnG,GACrBR,YAAY1kB,EAASqkB,GACnBc,MAAMnlB,EAASqkB,GACfrE,KAAKsL,UAAY,KACjBtL,KAAKuL,eAAiB,KACtBvL,KAAKwL,YAAa,EAClBxL,KAAKyL,aAAe,KACpBzL,KAAK0L,aAAe,KACpB1L,KAAK2L,mBAAqB1E,GAAeC,QApCjB,uBAoC8ClH,KAAKoF,UAE3EpF,KAAK4L,qBAED5L,KAAKqF,QAAQ4F,OAASV,IACxBvK,KAAK6L,OAET,CAGW5H,qBACT,OAAO4G,EACT,CAEW3G,yBACT,OAAOkH,EACT,CAEW3O,kBACT,MAtFW,UAuFb,CAGAnX,OACE0a,KAAK8L,OAAOnC,GACd,CAEAoC,mBAIOjmB,SAASkmB,QAAUlR,GAAUkF,KAAKoF,WACrCpF,KAAK1a,MAET,CAEAiiB,OACEvH,KAAK8L,OAAOlC,GACd,CAEAoB,QACMhL,KAAKwL,YACPjR,GAAqByF,KAAKoF,UAG5BpF,KAAKiM,gBACP,CAEAJ,QACE7L,KAAKiM,iBAELjM,KAAKkM,kBAELlM,KAAKsL,UAAYa,aAAY,IAAMnM,KAAK+L,mBAAmB/L,KAAKqF,QAAQyF,SAC1E,CAEAsB,oBACOpM,KAAKqF,QAAQ4F,OAIdjL,KAAKwL,WACPjL,GAAaa,IAAIpB,KAAKoF,SAAU4E,IAAY,IAAMhK,KAAK6L,UAIzD7L,KAAK6L,QACP,CAEAQ,GAAGnT,GACD,MAAMoT,EAAQtM,KAAKuM,YAEnB,GAAIrT,EAAQoT,EAAMnb,OAAS,GAAK+H,EAAQ,EACtC,OAGF,GAAI8G,KAAKwL,WAEP,YADAjL,GAAaa,IAAIpB,KAAKoF,SAAU4E,IAAY,IAAMhK,KAAKqM,GAAGnT,KAI5D,MAAMsT,EAAcxM,KAAKyM,cAAczM,KAAK0M,cAE5C,GAAIF,IAAgBtT,EAClB,OAGF,MAAMtC,EAAQsC,EAAQsT,EAAc7C,GAAaC,GAEjD5J,KAAK8L,OAAOlV,EAAO0V,EAAMpT,GAC3B,CAEAqM,UACMvF,KAAK0L,cACP1L,KAAK0L,aAAanG,UAGpBJ,MAAMI,SACR,CAGAhB,kBAAkBF,GAEhB,OADAA,EAAOsI,gBAAkBtI,EAAOyG,SACzBzG,CACT,CAEAuH,qBACM5L,KAAKqF,QAAQ0F,UACfxK,GAAaY,GAAGnB,KAAKoF,SAAU6E,IAAiB7K,GAASY,KAAK4M,SAASxN,KAG9C,UAAvBY,KAAKqF,QAAQ2F,QACfzK,GAAaY,GAAGnB,KAAKoF,SAAU8E,IAAoB,IAAMlK,KAAKgL,UAC9DzK,GAAaY,GAAGnB,KAAKoF,SAAU+E,IAAoB,IAAMnK,KAAKoM,uBAG5DpM,KAAKqF,QAAQ6F,OAASzC,GAAMC,eAC9B1I,KAAK6M,yBAET,CAEAA,0BACE,IAAK,MAAMC,KAAO7F,GAAerU,KA/JX,qBA+JmCoN,KAAKoF,UAC5D7E,GAAaY,GAAG2L,EAAK1C,IAAkBhL,GAASA,EAAM+C,mBAGxD,MAqBM4K,EAAc,CAClBzE,aAAc,IAAMtI,KAAK8L,OAAO9L,KAAKgN,kBAAkBnD,KACvDtB,cAAe,IAAMvI,KAAK8L,OAAO9L,KAAKgN,kBAAkBlD,KACxDzB,YAxBkB,KACS,UAAvBrI,KAAKqF,QAAQ2F,QAWjBhL,KAAKgL,QAEDhL,KAAKyL,cACPwB,aAAajN,KAAKyL,cAGpBzL,KAAKyL,aAAe5N,YAAW,IAAMmC,KAAKoM,qBA7MjB,IA6M+DpM,KAAKqF,QAAQyF,UAAS,GAQhH9K,KAAK0L,aAAe,IAAIjD,GAAMzI,KAAKoF,SAAU2H,EAC/C,CAEAH,SAASxN,GACP,GAAI,kBAAkBtb,KAAKsb,EAAMpS,OAAOoZ,SACtC,OAGF,MAAMrY,EAAY6c,GAAiBxL,EAAM7hB,KAErCwQ,IACFqR,EAAM+C,iBAENnC,KAAK8L,OAAO9L,KAAKgN,kBAAkBjf,IAEvC,CAEA0e,cAAczsB,GACZ,OAAOggB,KAAKuM,YAAY3mB,QAAQ5F,EAClC,CAEAktB,2BAA2BhU,GACzB,IAAK8G,KAAK2L,mBACR,OAGF,MAAMwB,EAAkBlG,GAAeC,QAAQuD,GAAiBzK,KAAK2L,oBACrEwB,EAAgB3R,UAAUuH,OAAOyH,IACjC2C,EAAgBvrB,gBAAgB,gBAChC,MAAMwrB,EAAqBnG,GAAeC,QAAQ,sBAAsBhO,MAAW8G,KAAK2L,oBAEpFyB,IACFA,EAAmB5R,UAAUtE,IAAIsT,IACjC4C,EAAmBvrB,aAAa,eAAgB,QAEpD,CAEAqqB,kBACE,MAAMlsB,EAAUggB,KAAKuL,gBAAkBvL,KAAK0M,aAE5C,IAAK1sB,EACH,OAGF,MAAMqtB,EAAkB9P,OAAO+P,SAASttB,EAAQga,aAAa,oBAAqB,IAClFgG,KAAKqF,QAAQyF,SAAWuC,GAAmBrN,KAAKqF,QAAQsH,eAC1D,CAEAb,OAAOlV,EAAO5W,EAAU,MACtB,GAAIggB,KAAKwL,WACP,OAGF,MAAMzN,EAAgBiC,KAAK0M,aAErBa,EAAS3W,IAAU+S,GACnB6D,EAAcxtB,GAAW8d,GAAqBkC,KAAKuM,YAAaxO,EAAewP,EAAQvN,KAAKqF,QAAQ8F,MAE1G,GAAIqC,IAAgBzP,EAClB,OAGF,MAAM0P,EAAmBzN,KAAKyM,cAAce,GAEtCE,EAAeC,GACZpN,GAAakB,QAAQzB,KAAKoF,SAAUuI,EAAW,CACpD7N,cAAe0N,EACfzf,UAAWiS,KAAK4N,kBAAkBhX,GAClCkM,KAAM9C,KAAKyM,cAAc1O,GACzBsO,GAAIoB,IAMR,GAFmBC,EAAa3D,IAEjBlI,iBACb,OAGF,IAAK9D,IAAkByP,EAGrB,OAGF,MAAMK,EAAY/M,QAAQd,KAAKsL,WAC/BtL,KAAKgL,QACLhL,KAAKwL,YAAa,EAElBxL,KAAKkN,2BAA2BO,GAEhCzN,KAAKuL,eAAiBiC,EACtB,MAAMM,EAAuBP,EA/RR,sBADF,oBAiSbQ,EAAiBR,EA/RH,qBACA,qBA+RpBC,EAAYhS,UAAUtE,IAAI6W,GAC1BhS,GAAOyR,GACPzP,EAAcvC,UAAUtE,IAAI4W,GAC5BN,EAAYhS,UAAUtE,IAAI4W,GAU1B9N,KAAK2F,gBARoB,KACvB6H,EAAYhS,UAAUuH,OAAO+K,EAAsBC,GACnDP,EAAYhS,UAAUtE,IAAIsT,IAC1BzM,EAAcvC,UAAUuH,OAAOyH,GAAqBuD,EAAgBD,GACpE9N,KAAKwL,YAAa,EAClBkC,EAAa1D,GAAW,GAGYjM,EAAeiC,KAAKgO,eAEtDH,GACF7N,KAAK6L,OAET,CAEAmC,cACE,OAAOhO,KAAKoF,SAAS5J,UAAUvW,SAxTV,QAyTvB,CAEAynB,aACE,OAAOzF,GAAeC,QAAQyD,GAAsB3K,KAAKoF,SAC3D,CAEAmH,YACE,OAAOtF,GAAerU,KAAK8X,GAAe1K,KAAKoF,SACjD,CAEA6G,iBACMjM,KAAKsL,YACP2C,cAAcjO,KAAKsL,WACnBtL,KAAKsL,UAAY,KAErB,CAEA0B,kBAAkBjf,GAChB,OAAIoO,KACKpO,IAAc8b,GAAiBD,GAAaD,GAG9C5b,IAAc8b,GAAiBF,GAAaC,EACrD,CAEAgE,kBAAkBhX,GAChB,OAAIuF,KACKvF,IAAUgT,GAAaC,GAAiBC,GAG1ClT,IAAUgT,GAAaE,GAAkBD,EAClD,CAGAhE,uBAAuBxB,GACrB,OAAOrE,KAAK4G,MAAK,WACf,MAAM9b,EAAOugB,GAAShF,oBAAoBrG,KAAMqE,GAEhD,GAAsB,iBAAXA,GAKX,GAAsB,iBAAXA,EAAqB,CAC9B,QAAqB7K,IAAjB1O,EAAKuZ,IAAyBA,EAAOlK,WAAW,MAAmB,gBAAXkK,EAC1D,MAAM,IAAIW,UAAU,oBAAoBX,MAG1CvZ,EAAKuZ,IACP,OAVEvZ,EAAKuhB,GAAGhI,EAWZ,GACF,EAQF9D,GAAaY,GAAGrb,SAAUwkB,GA1WE,uCA0W2C,SAAUlL,GAC/E,MAAMpS,EAASsN,GAAuB0F,MAEtC,IAAKhT,IAAWA,EAAOwO,UAAUvW,SAASslB,IACxC,OAGFnL,EAAM+C,iBACN,MAAM+L,EAAW7C,GAAShF,oBAAoBrZ,GACxCmhB,EAAanO,KAAKhG,aAAa,oBAErC,OAAImU,GACFD,EAAS7B,GAAG8B,QAEZD,EAAS9B,qBAKyC,SAAhD7I,GAAYQ,iBAAiB/D,KAAM,UACrCkO,EAAS5oB,YAET4oB,EAAS9B,sBAKX8B,EAAS3G,YAET2G,EAAS9B,oBACX,IACA7L,GAAaY,GAAG9gB,OAAQgqB,IAAuB,KAC7C,MAAM+D,EAAYnH,GAAerU,KAzYR,6BA2YzB,IAAK,MAAMsb,KAAYE,EACrB/C,GAAShF,oBAAoB6H,EAC/B,IAMF7R,GAAmBgP,IAYnB,MAEMgD,GAAc,eAEdC,GAAe,OAAOD,KACtBE,GAAgB,QAAQF,KACxBG,GAAe,OAAOH,KACtBI,GAAiB,SAASJ,KAC1BK,GAAyB,QAAQL,cACjCM,GAAoB,OACpBC,GAAsB,WACtBC,GAAwB,aAExBC,GAA6B,WAAWF,OAAwBA,KAKhEG,GAAyB,8BACzBC,GAAY,CAChB9pB,OAAQ,KACR6hB,QAAQ,GAEJkI,GAAgB,CACpB/pB,OAAQ,iBACR6hB,OAAQ,WAMV,MAAMmI,WAAiBhK,GACrBR,YAAY1kB,EAASqkB,GACnBc,MAAMnlB,EAASqkB,GACfrE,KAAKmP,kBAAmB,EACxBnP,KAAKoP,cAAgB,GACrB,MAAMC,EAAapI,GAAerU,KAAKmc,IAEvC,IAAK,MAAMO,KAAQD,EAAY,CAC7B,MAAMtV,EAAWM,GAAuBiV,GAClCC,EAAgBtI,GAAerU,KAAKmH,GAAUnT,QAAO4oB,GAAgBA,IAAiBxP,KAAKoF,WAEhF,OAAbrL,GAAqBwV,EAAcpe,QACrC6O,KAAKoP,cAAc/c,KAAKid,EAE5B,CAEAtP,KAAKyP,sBAEAzP,KAAKqF,QAAQngB,QAChB8a,KAAK0P,0BAA0B1P,KAAKoP,cAAepP,KAAK2P,YAGtD3P,KAAKqF,QAAQ0B,QACf/G,KAAK+G,QAET,CAGW9C,qBACT,OAAO+K,EACT,CAEW9K,yBACT,OAAO+K,EACT,CAEWxS,kBACT,MApEW,UAqEb,CAGAsK,SACM/G,KAAK2P,WACP3P,KAAK4P,OAEL5P,KAAK6P,MAET,CAEAA,OACE,GAAI7P,KAAKmP,kBAAoBnP,KAAK2P,WAChC,OAGF,IAAIG,EAAiB,GAQrB,GANI9P,KAAKqF,QAAQngB,SACf4qB,EAAiB9P,KAAK+P,uBAvEH,wCAuE4CnpB,QAAO5G,GAAWA,IAAYggB,KAAKoF,WAAU7hB,KAAIvD,GAAWkvB,GAAS7I,oBAAoBrmB,EAAS,CAC/J+mB,QAAQ,OAIR+I,EAAe3e,QAAU2e,EAAe,GAAGX,iBAC7C,OAKF,GAFmB5O,GAAakB,QAAQzB,KAAKoF,SAAUkJ,IAExCzM,iBACb,OAGF,IAAK,MAAMmO,KAAkBF,EAC3BE,EAAeJ,OAGjB,MAAMK,EAAYjQ,KAAKkQ,gBAEvBlQ,KAAKoF,SAAS5J,UAAUuH,OAAO6L,IAE/B5O,KAAKoF,SAAS5J,UAAUtE,IAAI2X,IAE5B7O,KAAKoF,SAAS5jB,MAAMyuB,GAAa,EAEjCjQ,KAAK0P,0BAA0B1P,KAAKoP,eAAe,GAEnDpP,KAAKmP,kBAAmB,EAExB,MAYMgB,EAAa,SADUF,EAAU,GAAGhL,cAAgBgL,EAAUpd,MAAM,KAG1EmN,KAAK2F,gBAdY,KACf3F,KAAKmP,kBAAmB,EAExBnP,KAAKoF,SAAS5J,UAAUuH,OAAO8L,IAE/B7O,KAAKoF,SAAS5J,UAAUtE,IAAI0X,GAAqBD,IAEjD3O,KAAKoF,SAAS5jB,MAAMyuB,GAAa,GACjC1P,GAAakB,QAAQzB,KAAKoF,SAAUmJ,GAAc,GAMtBvO,KAAKoF,UAAU,GAE7CpF,KAAKoF,SAAS5jB,MAAMyuB,GAAa,GAAGjQ,KAAKoF,SAAS+K,MACpD,CAEAP,OACE,GAAI5P,KAAKmP,mBAAqBnP,KAAK2P,WACjC,OAKF,GAFmBpP,GAAakB,QAAQzB,KAAKoF,SAAUoJ,IAExC3M,iBACb,OAGF,MAAMoO,EAAYjQ,KAAKkQ,gBAEvBlQ,KAAKoF,SAAS5jB,MAAMyuB,GAAa,GAAGjQ,KAAKoF,SAASrhB,wBAAwBksB,OAC1ElU,GAAOiE,KAAKoF,UAEZpF,KAAKoF,SAAS5J,UAAUtE,IAAI2X,IAE5B7O,KAAKoF,SAAS5J,UAAUuH,OAAO6L,GAAqBD,IAEpD,IAAK,MAAMlN,KAAWzB,KAAKoP,cAAe,CACxC,MAAMpvB,EAAUsa,GAAuBmH,GAEnCzhB,IAAYggB,KAAK2P,SAAS3vB,IAC5BggB,KAAK0P,0BAA0B,CAACjO,IAAU,EAE9C,CAEAzB,KAAKmP,kBAAmB,EAYxBnP,KAAKoF,SAAS5jB,MAAMyuB,GAAa,GAEjCjQ,KAAK2F,gBAZY,KACf3F,KAAKmP,kBAAmB,EAExBnP,KAAKoF,SAAS5J,UAAUuH,OAAO8L,IAE/B7O,KAAKoF,SAAS5J,UAAUtE,IAAI0X,IAE5BrO,GAAakB,QAAQzB,KAAKoF,SAAUqJ,GAAe,GAKvBzO,KAAKoF,UAAU,EAC/C,CAEAuK,SAAS3vB,EAAUggB,KAAKoF,UACtB,OAAOplB,EAAQwb,UAAUvW,SAAS0pB,GACpC,CAGApK,kBAAkBF,GAIhB,OAHAA,EAAO0C,OAASjG,QAAQuD,EAAO0C,QAE/B1C,EAAOnf,OAAS2V,GAAWwJ,EAAOnf,QAC3Bmf,CACT,CAEA6L,gBACE,OAAOlQ,KAAKoF,SAAS5J,UAAUvW,SAtLL,uBAChB,QACC,QAqLb,CAEAwqB,sBACE,IAAKzP,KAAKqF,QAAQngB,OAChB,OAGF,MAAMiiB,EAAWnH,KAAK+P,uBAAuBhB,IAE7C,IAAK,MAAM/uB,KAAWmnB,EAAU,CAC9B,MAAMiJ,EAAW9V,GAAuBta,GAEpCowB,GACFpQ,KAAK0P,0BAA0B,CAAC1vB,GAAUggB,KAAK2P,SAASS,GAE5D,CACF,CAEAL,uBAAuBhW,GACrB,MAAMoN,EAAWF,GAAerU,KAAKkc,GAA4B9O,KAAKqF,QAAQngB,QAE9E,OAAO+hB,GAAerU,KAAKmH,EAAUiG,KAAKqF,QAAQngB,QAAQ0B,QAAO5G,IAAYmnB,EAASjN,SAASla,IACjG,CAEA0vB,0BAA0BW,EAAcC,GACtC,GAAKD,EAAalf,OAIlB,IAAK,MAAMnR,KAAWqwB,EACpBrwB,EAAQwb,UAAUuL,OAvNK,aAuNyBuJ,GAChDtwB,EAAQ6B,aAAa,gBAAiByuB,EAE1C,CAGAzK,uBAAuBxB,GACrB,MAAMgB,EAAU,CAAC,EAMjB,MAJsB,iBAAXhB,GAAuB,YAAYvgB,KAAKugB,KACjDgB,EAAQ0B,QAAS,GAGZ/G,KAAK4G,MAAK,WACf,MAAM9b,EAAOokB,GAAS7I,oBAAoBrG,KAAMqF,GAEhD,GAAsB,iBAAXhB,EAAqB,CAC9B,QAA4B,IAAjBvZ,EAAKuZ,GACd,MAAM,IAAIW,UAAU,oBAAoBX,MAG1CvZ,EAAKuZ,IACP,CACF,GACF,EAQF9D,GAAaY,GAAGrb,SAAU4oB,GAAwBK,IAAwB,SAAU3P,IAErD,MAAzBA,EAAMpS,OAAOoZ,SAAmBhH,EAAMW,gBAAmD,MAAjCX,EAAMW,eAAeqG,UAC/EhH,EAAM+C,iBAGR,MAAMpI,EAAWM,GAAuB2F,MAClCuQ,EAAmBtJ,GAAerU,KAAKmH,GAE7C,IAAK,MAAM/Z,KAAWuwB,EACpBrB,GAAS7I,oBAAoBrmB,EAAS,CACpC+mB,QAAQ,IACPA,QAEP,IAKA1K,GAAmB6S,IAYnB,MAAMsB,GAAS,WAETC,GAAc,eACdC,GAAiB,YAGjBC,GAAiB,UACjBC,GAAmB,YAGnBC,GAAe,OAAOJ,KACtBK,GAAiB,SAASL,KAC1BM,GAAe,OAAON,KACtBO,GAAgB,QAAQP,KACxBQ,GAAyB,QAAQR,KAAcC,KAC/CQ,GAAyB,UAAUT,KAAcC,KACjDS,GAAuB,QAAQV,KAAcC,KAC7CU,GAAoB,OAMpBC,GAAyB,4DACzBC,GAA6B,GAAGD,MAA0BD,KAC1DG,GAAgB,iBAIhBC,GAAgBrV,KAAU,UAAY,YACtCsV,GAAmBtV,KAAU,YAAc,UAC3CuV,GAAmBvV,KAAU,aAAe,eAC5CwV,GAAsBxV,KAAU,eAAiB,aACjDyV,GAAkBzV,KAAU,aAAe,cAC3C0V,GAAiB1V,KAAU,cAAgB,aAG3C2V,GAAY,CAChBC,WAAW,EACXrjB,SAAU,kBACVsjB,QAAS,UACTvpB,OAAQ,CAAC,EAAG,GACZwpB,aAAc,KACdlzB,UAAW,UAEPmzB,GAAgB,CACpBH,UAAW,mBACXrjB,SAAU,mBACVsjB,QAAS,SACTvpB,OAAQ,0BACRwpB,aAAc,yBACdlzB,UAAW,2BAMb,MAAMozB,WAAiBjN,GACrBR,YAAY1kB,EAASqkB,GACnBc,MAAMnlB,EAASqkB,GACfrE,KAAKoS,QAAU,KACfpS,KAAKqS,QAAUrS,KAAKoF,SAAS5f,WAG7Bwa,KAAKsS,MAAQrL,GAAe3hB,KAAK0a,KAAKoF,SAAUmM,IAAe,IAAMtK,GAAeM,KAAKvH,KAAKoF,SAAUmM,IAAe,IAAMtK,GAAeC,QAAQqK,GAAevR,KAAKqS,SACxKrS,KAAKuS,UAAYvS,KAAKwS,eACxB,CAGWvO,qBACT,OAAO6N,EACT,CAEW5N,yBACT,OAAOgO,EACT,CAEWzV,kBACT,OAAO+T,EACT,CAGAzJ,SACE,OAAO/G,KAAK2P,WAAa3P,KAAK4P,OAAS5P,KAAK6P,MAC9C,CAEAA,OACE,GAAIxU,GAAW2E,KAAKoF,WAAapF,KAAK2P,WACpC,OAGF,MAAM7P,EAAgB,CACpBA,cAAeE,KAAKoF,UAItB,IAFkB7E,GAAakB,QAAQzB,KAAKoF,SAAU2L,GAAcjR,GAEtD+B,iBAAd,CAUA,GANA7B,KAAKyS,gBAMD,iBAAkB3sB,SAASC,kBAAoBia,KAAKqS,QAAQlX,QA/ExC,eAgFtB,IAAK,MAAMnb,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAKwa,UAC/C5G,GAAaY,GAAGnhB,EAAS,YAAa8b,IAI1CkE,KAAKoF,SAASsN,QAEd1S,KAAKoF,SAASvjB,aAAa,iBAAiB,GAE5Cme,KAAKsS,MAAM9W,UAAUtE,IAAIka,IAEzBpR,KAAKoF,SAAS5J,UAAUtE,IAAIka,IAE5B7Q,GAAakB,QAAQzB,KAAKoF,SAAU4L,GAAelR,EAtBnD,CAuBF,CAEA8P,OACE,GAAIvU,GAAW2E,KAAKoF,YAAcpF,KAAK2P,WACrC,OAGF,MAAM7P,EAAgB,CACpBA,cAAeE,KAAKoF,UAGtBpF,KAAK2S,cAAc7S,EACrB,CAEAyF,UACMvF,KAAKoS,SACPpS,KAAKoS,QAAQ3Y,UAGf0L,MAAMI,SACR,CAEA/Z,SACEwU,KAAKuS,UAAYvS,KAAKwS,gBAElBxS,KAAKoS,SACPpS,KAAKoS,QAAQ5mB,QAEjB,CAGAmnB,cAAc7S,GAGZ,IAFkBS,GAAakB,QAAQzB,KAAKoF,SAAUyL,GAAc/Q,GAEtD+B,iBAAd,CAMA,GAAI,iBAAkB/b,SAASC,gBAC7B,IAAK,MAAM/F,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAKwa,UAC/C5G,GAAaC,IAAIxgB,EAAS,YAAa8b,IAIvCkE,KAAKoS,SACPpS,KAAKoS,QAAQ3Y,UAGfuG,KAAKsS,MAAM9W,UAAUuH,OAAOqO,IAE5BpR,KAAKoF,SAAS5J,UAAUuH,OAAOqO,IAE/BpR,KAAKoF,SAASvjB,aAAa,gBAAiB,SAE5C0hB,GAAYE,oBAAoBzD,KAAKsS,MAAO,UAC5C/R,GAAakB,QAAQzB,KAAKoF,SAAU0L,GAAgBhR,EArBpD,CAsBF,CAEAsE,WAAWC,GAGT,GAAgC,iBAFhCA,EAASc,MAAMf,WAAWC,IAERtlB,YAA2B,GAAUslB,EAAOtlB,YAAgE,mBAA3CslB,EAAOtlB,UAAUgF,sBAElG,MAAM,IAAIihB,UAAU,GAAGwL,GAAOvL,+GAGhC,OAAOZ,CACT,CAEAoO,gBACE,QAAsB,IAAX,EACT,MAAM,IAAIzN,UAAU,gEAGtB,IAAI4N,EAAmB5S,KAAKoF,SAEG,WAA3BpF,KAAKqF,QAAQtmB,UACf6zB,EAAmB5S,KAAKqS,QACf,GAAUrS,KAAKqF,QAAQtmB,WAChC6zB,EAAmB/X,GAAWmF,KAAKqF,QAAQtmB,WACA,iBAA3BihB,KAAKqF,QAAQtmB,YAC7B6zB,EAAmB5S,KAAKqF,QAAQtmB,WAGlC,MAAMkzB,EAAejS,KAAK6S,mBAE1B7S,KAAKoS,QAAU,GAAoBQ,EAAkB5S,KAAKsS,MAAOL,EACnE,CAEAtC,WACE,OAAO3P,KAAKsS,MAAM9W,UAAUvW,SAASmsB,GACvC,CAEA0B,gBACE,MAAMC,EAAiB/S,KAAKqS,QAE5B,GAAIU,EAAevX,UAAUvW,SAxMN,WAyMrB,OAAO2sB,GAGT,GAAImB,EAAevX,UAAUvW,SA3MJ,aA4MvB,OAAO4sB,GAGT,GAAIkB,EAAevX,UAAUvW,SA9MA,iBA+M3B,MAjMsB,MAoMxB,GAAI8tB,EAAevX,UAAUvW,SAjNE,mBAkN7B,MApMyB,SAwM3B,MAAM+tB,EAAkF,QAA1EttB,iBAAiBsa,KAAKsS,OAAOrX,iBAAiB,iBAAiBb,OAE7E,OAAI2Y,EAAevX,UAAUvW,SA5NP,UA6Nb+tB,EAAQvB,GAAmBD,GAG7BwB,EAAQrB,GAAsBD,EACvC,CAEAc,gBACE,OAAkD,OAA3CxS,KAAKoF,SAASjK,QA5ND,UA6NtB,CAEA8X,aACE,MAAM,OACJxqB,GACEuX,KAAKqF,QAET,MAAsB,iBAAX5c,EACFA,EAAO9F,MAAM,KAAKY,KAAInF,GAASmf,OAAO+P,SAASlvB,EAAO,MAGzC,mBAAXqK,EACFyqB,GAAczqB,EAAOyqB,EAAYlT,KAAKoF,UAGxC3c,CACT,CAEAoqB,mBACE,MAAMM,EAAwB,CAC5Bh0B,UAAW6gB,KAAK8S,gBAChBjc,UAAW,CAAC,CACV9V,KAAM,kBACNmB,QAAS,CACPwM,SAAUsR,KAAKqF,QAAQ3W,WAExB,CACD3N,KAAM,SACNmB,QAAS,CACPuG,OAAQuX,KAAKiT,iBAcnB,OATIjT,KAAKuS,WAAsC,WAAzBvS,KAAKqF,QAAQ2M,WACjCzO,GAAYC,iBAAiBxD,KAAKsS,MAAO,SAAU,UAEnDa,EAAsBtc,UAAY,CAAC,CACjC9V,KAAM,cACNC,SAAS,KAIN,IAAKmyB,KAC+B,mBAA9BnT,KAAKqF,QAAQ4M,aAA8BjS,KAAKqF,QAAQ4M,aAAakB,GAAyBnT,KAAKqF,QAAQ4M,aAE1H,CAEAmB,iBAAgB,IACd71B,EAAG,OACHyP,IAEA,MAAMsf,EAAQrF,GAAerU,KA/QF,8DA+Q+BoN,KAAKsS,OAAO1rB,QAAO5G,GAAW8a,GAAU9a,KAE7FssB,EAAMnb,QAMX2M,GAAqBwO,EAAOtf,EAAQzP,IAAQqzB,IAAmBtE,EAAMpS,SAASlN,IAAS0lB,OACzF,CAGA7M,uBAAuBxB,GACrB,OAAOrE,KAAK4G,MAAK,WACf,MAAM9b,EAAOqnB,GAAS9L,oBAAoBrG,KAAMqE,GAEhD,GAAsB,iBAAXA,EAAX,CAIA,QAA4B,IAAjBvZ,EAAKuZ,GACd,MAAM,IAAIW,UAAU,oBAAoBX,MAG1CvZ,EAAKuZ,IANL,CAOF,GACF,CAEAwB,kBAAkBzG,GAChB,GAhUuB,IAgUnBA,EAAM4H,QAAgD,UAAf5H,EAAMqB,MAnUnC,QAmUuDrB,EAAM7hB,IACzE,OAGF,MAAM81B,EAAcpM,GAAerU,KAAK0e,IAExC,IAAK,MAAMvK,KAAUsM,EAAa,CAChC,MAAMC,EAAUnB,GAASrM,YAAYiB,GAErC,IAAKuM,IAAyC,IAA9BA,EAAQjO,QAAQ0M,UAC9B,SAGF,MAAMwB,EAAenU,EAAMmU,eACrBC,EAAeD,EAAarZ,SAASoZ,EAAQhB,OAEnD,GAAIiB,EAAarZ,SAASoZ,EAAQlO,WAA2C,WAA9BkO,EAAQjO,QAAQ0M,YAA2ByB,GAA8C,YAA9BF,EAAQjO,QAAQ0M,WAA2ByB,EACnJ,SAIF,GAAIF,EAAQhB,MAAMrtB,SAASma,EAAMpS,UAA2B,UAAfoS,EAAMqB,MAxVvC,QAwV2DrB,EAAM7hB,KAAqB,qCAAqCuG,KAAKsb,EAAMpS,OAAOoZ,UACvJ,SAGF,MAAMtG,EAAgB,CACpBA,cAAewT,EAAQlO,UAGN,UAAfhG,EAAMqB,OACRX,EAAcqG,WAAa/G,GAG7BkU,EAAQX,cAAc7S,EACxB,CACF,CAEA+F,6BAA6BzG,GAG3B,MAAMqU,EAAU,kBAAkB3vB,KAAKsb,EAAMpS,OAAOoZ,SAC9CsN,EA7WW,WA6WKtU,EAAM7hB,IACtBo2B,EAAkB,CAAChD,GAAgBC,IAAkB1W,SAASkF,EAAM7hB,KAE1E,IAAKo2B,IAAoBD,EACvB,OAGF,GAAID,IAAYC,EACd,OAGFtU,EAAM+C,iBAEN,MAAMyR,EAAkB5T,KAAKoH,QAAQiK,IAA0BrR,KAAOiH,GAAeM,KAAKvH,KAAMqR,IAAwB,IAAMpK,GAAe3hB,KAAK0a,KAAMqR,IAAwB,IAAMpK,GAAeC,QAAQmK,GAAwBjS,EAAMW,eAAeva,YACpPwF,EAAWmnB,GAAS9L,oBAAoBuN,GAE9C,GAAID,EAMF,OALAvU,EAAMyU,kBACN7oB,EAAS6kB,YAET7kB,EAASooB,gBAAgBhU,GAKvBpU,EAAS2kB,aAEXvQ,EAAMyU,kBACN7oB,EAAS4kB,OACTgE,EAAgBlB,QAEpB,EAQFnS,GAAaY,GAAGrb,SAAUorB,GAAwBG,GAAwBc,GAAS2B,uBACnFvT,GAAaY,GAAGrb,SAAUorB,GAAwBK,GAAeY,GAAS2B,uBAC1EvT,GAAaY,GAAGrb,SAAUmrB,GAAwBkB,GAAS4B,YAC3DxT,GAAaY,GAAGrb,SAAUqrB,GAAsBgB,GAAS4B,YACzDxT,GAAaY,GAAGrb,SAAUmrB,GAAwBI,IAAwB,SAAUjS,GAClFA,EAAM+C,iBACNgQ,GAAS9L,oBAAoBrG,MAAM+G,QACrC,IAKA1K,GAAmB8V,IAYnB,MAAM6B,GAAyB,oDACzBC,GAA0B,cAC1BC,GAAmB,gBACnBC,GAAkB,eAKxB,MAAMC,GACJ1P,cACE1E,KAAKoF,SAAWtf,SAAS6G,IAC3B,CAGA0nB,WAEE,MAAMC,EAAgBxuB,SAASC,gBAAgBuC,YAC/C,OAAO1F,KAAKoC,IAAI3E,OAAOk0B,WAAaD,EACtC,CAEA1E,OACE,MAAMtrB,EAAQ0b,KAAKqU,WAEnBrU,KAAKwU,mBAGLxU,KAAKyU,sBAAsBzU,KAAKoF,SAAU8O,IAAkBQ,GAAmBA,EAAkBpwB,IAGjG0b,KAAKyU,sBAAsBT,GAAwBE,IAAkBQ,GAAmBA,EAAkBpwB,IAE1G0b,KAAKyU,sBAAsBR,GAAyBE,IAAiBO,GAAmBA,EAAkBpwB,GAC5G,CAEAwO,QACEkN,KAAK2U,wBAAwB3U,KAAKoF,SAAU,YAE5CpF,KAAK2U,wBAAwB3U,KAAKoF,SAAU8O,IAE5ClU,KAAK2U,wBAAwBX,GAAwBE,IAErDlU,KAAK2U,wBAAwBV,GAAyBE,GACxD,CAEAS,gBACE,OAAO5U,KAAKqU,WAAa,CAC3B,CAGAG,mBACExU,KAAK6U,sBAAsB7U,KAAKoF,SAAU,YAE1CpF,KAAKoF,SAAS5jB,MAAM+K,SAAW,QACjC,CAEAkoB,sBAAsB1a,EAAU+a,EAAevY,GAC7C,MAAMwY,EAAiB/U,KAAKqU,WAa5BrU,KAAKgV,2BAA2Bjb,GAXH/Z,IAC3B,GAAIA,IAAYggB,KAAKoF,UAAY/kB,OAAOk0B,WAAav0B,EAAQsI,YAAcysB,EACzE,OAGF/U,KAAK6U,sBAAsB70B,EAAS80B,GAEpC,MAAMJ,EAAkBr0B,OAAOqF,iBAAiB1F,GAASib,iBAAiB6Z,GAC1E90B,EAAQwB,MAAMyzB,YAAYH,EAAe,GAAGvY,EAASgB,OAAOC,WAAWkX,QAAsB,GAIjG,CAEAG,sBAAsB70B,EAAS80B,GAC7B,MAAMI,EAAcl1B,EAAQwB,MAAMyZ,iBAAiB6Z,GAE/CI,GACF3R,GAAYC,iBAAiBxjB,EAAS80B,EAAeI,EAEzD,CAEAP,wBAAwB5a,EAAU+a,GAahC9U,KAAKgV,2BAA2Bjb,GAZH/Z,IAC3B,MAAM5B,EAAQmlB,GAAYQ,iBAAiB/jB,EAAS80B,GAEtC,OAAV12B,GAKJmlB,GAAYE,oBAAoBzjB,EAAS80B,GACzC90B,EAAQwB,MAAMyzB,YAAYH,EAAe12B,IALvC4B,EAAQwB,MAAM2zB,eAAeL,EAKgB,GAInD,CAEAE,2BAA2Bjb,EAAUqb,GACnC,GAAI,GAAUrb,GACZqb,EAASrb,QAIX,IAAK,MAAMsb,KAAOpO,GAAerU,KAAKmH,EAAUiG,KAAKoF,UACnDgQ,EAASC,EAEb,EAcF,MAAMC,GAAS,WAETC,GAAoB,OACpBC,GAAkB,gBAAgBF,KAClCG,GAAY,CAChBC,UAAW,iBACXC,cAAe,KACf/P,YAAY,EACZ9K,WAAW,EAEX8a,YAAa,QAGTC,GAAgB,CACpBH,UAAW,SACXC,cAAe,kBACf/P,WAAY,UACZ9K,UAAW,UACX8a,YAAa,oBAMf,MAAME,WAAiB9R,GACrBU,YAAYL,GACVc,QACAnF,KAAKqF,QAAUrF,KAAKoE,WAAWC,GAC/BrE,KAAK+V,aAAc,EACnB/V,KAAKoF,SAAW,IAClB,CAGWnB,qBACT,OAAOwR,EACT,CAEWvR,yBACT,OAAO2R,EACT,CAEWpZ,kBACT,OAAO6Y,EACT,CAGAzF,KAAKtT,GACH,IAAKyD,KAAKqF,QAAQvK,UAEhB,YADAiC,GAAQR,GAIVyD,KAAKgW,UAEL,MAAMh2B,EAAUggB,KAAKiW,cAEjBjW,KAAKqF,QAAQO,YACf7J,GAAO/b,GAGTA,EAAQwb,UAAUtE,IAAIqe,IAEtBvV,KAAKkW,mBAAkB,KACrBnZ,GAAQR,EAAS,GAErB,CAEAqT,KAAKrT,GACEyD,KAAKqF,QAAQvK,WAKlBkF,KAAKiW,cAAcza,UAAUuH,OAAOwS,IAEpCvV,KAAKkW,mBAAkB,KACrBlW,KAAKuF,UACLxI,GAAQR,EAAS,KARjBQ,GAAQR,EAUZ,CAEAgJ,UACOvF,KAAK+V,cAIVxV,GAAaC,IAAIR,KAAKoF,SAAUoQ,IAEhCxV,KAAKoF,SAASrC,SAEd/C,KAAK+V,aAAc,EACrB,CAGAE,cACE,IAAKjW,KAAKoF,SAAU,CAClB,MAAM+Q,EAAWrwB,SAASswB,cAAc,OACxCD,EAAST,UAAY1V,KAAKqF,QAAQqQ,UAE9B1V,KAAKqF,QAAQO,YACfuQ,EAAS3a,UAAUtE,IAnGD,QAsGpB8I,KAAKoF,SAAW+Q,CAClB,CAEA,OAAOnW,KAAKoF,QACd,CAEAb,kBAAkBF,GAGhB,OADAA,EAAOuR,YAAc/a,GAAWwJ,EAAOuR,aAChCvR,CACT,CAEA2R,UACE,GAAIhW,KAAK+V,YACP,OAGF,MAAM/1B,EAAUggB,KAAKiW,cAErBjW,KAAKqF,QAAQuQ,YAAYS,OAAOr2B,GAEhCugB,GAAaY,GAAGnhB,EAASw1B,IAAiB,KACxCzY,GAAQiD,KAAKqF,QAAQsQ,cAAc,IAErC3V,KAAK+V,aAAc,CACrB,CAEAG,kBAAkB3Z,GAChBS,GAAuBT,EAAUyD,KAAKiW,cAAejW,KAAKqF,QAAQO,WACpE,EAcF,MAEM0Q,GAAc,gBACdC,GAAkB,UAAUD,KAC5BE,GAAoB,cAAcF,KAGlCG,GAAmB,WACnBC,GAAY,CAChBC,WAAW,EACXC,YAAa,MAGTC,GAAgB,CACpBF,UAAW,UACXC,YAAa,WAMf,MAAME,WAAkB9S,GACtBU,YAAYL,GACVc,QACAnF,KAAKqF,QAAUrF,KAAKoE,WAAWC,GAC/BrE,KAAK+W,WAAY,EACjB/W,KAAKgX,qBAAuB,IAC9B,CAGW/S,qBACT,OAAOyS,EACT,CAEWxS,yBACT,OAAO2S,EACT,CAEWpa,kBACT,MAvCW,WAwCb,CAGAwa,WACMjX,KAAK+W,YAIL/W,KAAKqF,QAAQsR,WACf3W,KAAKqF,QAAQuR,YAAYlE,QAG3BnS,GAAaC,IAAI1a,SAAUwwB,IAE3B/V,GAAaY,GAAGrb,SAAUywB,IAAiBnX,GAASY,KAAKkX,eAAe9X,KACxEmB,GAAaY,GAAGrb,SAAU0wB,IAAmBpX,GAASY,KAAKmX,eAAe/X,KAC1EY,KAAK+W,WAAY,EACnB,CAEAK,aACOpX,KAAK+W,YAIV/W,KAAK+W,WAAY,EACjBxW,GAAaC,IAAI1a,SAAUwwB,IAC7B,CAGAY,eAAe9X,GACb,MAAM,YACJwX,GACE5W,KAAKqF,QAET,GAAIjG,EAAMpS,SAAWlH,UAAYsZ,EAAMpS,SAAW4pB,GAAeA,EAAY3xB,SAASma,EAAMpS,QAC1F,OAGF,MAAM1L,EAAW2lB,GAAeU,kBAAkBiP,GAE1B,IAApBt1B,EAAS6P,OACXylB,EAAYlE,QACH1S,KAAKgX,uBAAyBP,GACvCn1B,EAASA,EAAS6P,OAAS,GAAGuhB,QAE9BpxB,EAAS,GAAGoxB,OAEhB,CAEAyE,eAAe/X,GApFD,QAqFRA,EAAM7hB,MAIVyiB,KAAKgX,qBAAuB5X,EAAMiY,SAAWZ,GAxFzB,UAyFtB,EAcF,MAEMa,GAAc,YAGdC,GAAe,OAAOD,KACtBE,GAAyB,gBAAgBF,KACzCG,GAAiB,SAASH,KAC1BI,GAAe,OAAOJ,KACtBK,GAAgB,QAAQL,KACxBM,GAAiB,SAASN,KAC1BO,GAAsB,gBAAgBP,KACtCQ,GAA0B,oBAAoBR,KAC9CS,GAA0B,kBAAkBT,KAC5CU,GAAyB,QAAQV,cACjCW,GAAkB,aAElBC,GAAoB,OACpBC,GAAoB,eAKpBC,GAAY,CAChBjC,UAAU,EACVzD,OAAO,EACP3H,UAAU,GAENsN,GAAgB,CACpBlC,SAAU,mBACVzD,MAAO,UACP3H,SAAU,WAMZ,MAAMuN,WAAcpT,GAClBR,YAAY1kB,EAASqkB,GACnBc,MAAMnlB,EAASqkB,GACfrE,KAAKuY,QAAUtR,GAAeC,QApBV,gBAoBmClH,KAAKoF,UAC5DpF,KAAKwY,UAAYxY,KAAKyY,sBACtBzY,KAAK0Y,WAAa1Y,KAAK2Y,uBACvB3Y,KAAK2P,UAAW,EAChB3P,KAAKmP,kBAAmB,EACxBnP,KAAK4Y,WAAa,IAAIxE,GAEtBpU,KAAK4L,oBACP,CAGW3H,qBACT,OAAOmU,EACT,CAEWlU,yBACT,OAAOmU,EACT,CAEW5b,kBACT,MA5DW,OA6Db,CAGAsK,OAAOjH,GACL,OAAOE,KAAK2P,SAAW3P,KAAK4P,OAAS5P,KAAK6P,KAAK/P,EACjD,CAEA+P,KAAK/P,GACCE,KAAK2P,UAAY3P,KAAKmP,kBAIR5O,GAAakB,QAAQzB,KAAKoF,SAAUsS,GAAc,CAClE5X,kBAGY+B,mBAId7B,KAAK2P,UAAW,EAChB3P,KAAKmP,kBAAmB,EAExBnP,KAAK4Y,WAAWhJ,OAEhB9pB,SAAS6G,KAAK6O,UAAUtE,IAAI+gB,IAE5BjY,KAAK6Y,gBAEL7Y,KAAKwY,UAAU3I,MAAK,IAAM7P,KAAK8Y,aAAahZ,KAC9C,CAEA8P,OACO5P,KAAK2P,WAAY3P,KAAKmP,mBAIT5O,GAAakB,QAAQzB,KAAKoF,SAAUmS,IAExC1V,mBAId7B,KAAK2P,UAAW,EAChB3P,KAAKmP,kBAAmB,EAExBnP,KAAK0Y,WAAWtB,aAEhBpX,KAAKoF,SAAS5J,UAAUuH,OAAOmV,IAE/BlY,KAAK2F,gBAAe,IAAM3F,KAAK+Y,cAAc/Y,KAAKoF,SAAUpF,KAAKgO,gBACnE,CAEAzI,UACE,IAAK,MAAMyT,IAAe,CAAC34B,OAAQ2f,KAAKuY,SACtChY,GAAaC,IAAIwY,EAAa1B,IAGhCtX,KAAKwY,UAAUjT,UAEfvF,KAAK0Y,WAAWtB,aAEhBjS,MAAMI,SACR,CAEA0T,eACEjZ,KAAK6Y,eACP,CAGAJ,sBACE,OAAO,IAAI3C,GAAS,CAClBhb,UAAWgG,QAAQd,KAAKqF,QAAQ8Q,UAEhCvQ,WAAY5F,KAAKgO,eAErB,CAEA2K,uBACE,OAAO,IAAI7B,GAAU,CACnBF,YAAa5W,KAAKoF,UAEtB,CAEA0T,aAAahZ,GAENha,SAAS6G,KAAK1H,SAAS+a,KAAKoF,WAC/Btf,SAAS6G,KAAK0pB,OAAOrW,KAAKoF,UAG5BpF,KAAKoF,SAAS5jB,MAAMwwB,QAAU,QAE9BhS,KAAKoF,SAASxjB,gBAAgB,eAE9Boe,KAAKoF,SAASvjB,aAAa,cAAc,GAEzCme,KAAKoF,SAASvjB,aAAa,OAAQ,UAEnCme,KAAKoF,SAASlZ,UAAY,EAC1B,MAAMgtB,EAAYjS,GAAeC,QA3IT,cA2IsClH,KAAKuY,SAE/DW,IACFA,EAAUhtB,UAAY,GAGxB6P,GAAOiE,KAAKoF,UAEZpF,KAAKoF,SAAS5J,UAAUtE,IAAIghB,IAa5BlY,KAAK2F,gBAXsB,KACrB3F,KAAKqF,QAAQqN,OACf1S,KAAK0Y,WAAWzB,WAGlBjX,KAAKmP,kBAAmB,EACxB5O,GAAakB,QAAQzB,KAAKoF,SAAUuS,GAAe,CACjD7X,iBACA,GAGoCE,KAAKuY,QAASvY,KAAKgO,cAC7D,CAEApC,qBACErL,GAAaY,GAAGnB,KAAKoF,SAAU2S,IAAyB3Y,IACtD,GAtLe,WAsLXA,EAAM7hB,IAIV,OAAIyiB,KAAKqF,QAAQ0F,UACf3L,EAAM+C,sBACNnC,KAAK4P,aAIP5P,KAAKmZ,4BAA4B,IAEnC5Y,GAAaY,GAAG9gB,OAAQu3B,IAAgB,KAClC5X,KAAK2P,WAAa3P,KAAKmP,kBACzBnP,KAAK6Y,eACP,IAEFtY,GAAaY,GAAGnB,KAAKoF,SAAU0S,IAAyB1Y,IAEtDmB,GAAaa,IAAIpB,KAAKoF,SAAUyS,IAAqBuB,IAC/CpZ,KAAKoF,WAAahG,EAAMpS,QAAUgT,KAAKoF,WAAagU,EAAOpsB,SAIjC,WAA1BgT,KAAKqF,QAAQ8Q,SAMbnW,KAAKqF,QAAQ8Q,UACfnW,KAAK4P,OANL5P,KAAKmZ,6BAOP,GACA,GAEN,CAEAJ,aACE/Y,KAAKoF,SAAS5jB,MAAMwwB,QAAU,OAE9BhS,KAAKoF,SAASvjB,aAAa,eAAe,GAE1Cme,KAAKoF,SAASxjB,gBAAgB,cAE9Boe,KAAKoF,SAASxjB,gBAAgB,QAE9Boe,KAAKmP,kBAAmB,EAExBnP,KAAKwY,UAAU5I,MAAK,KAClB9pB,SAAS6G,KAAK6O,UAAUuH,OAAOkV,IAE/BjY,KAAKqZ,oBAELrZ,KAAK4Y,WAAW9lB,QAEhByN,GAAakB,QAAQzB,KAAKoF,SAAUqS,GAAe,GAEvD,CAEAzJ,cACE,OAAOhO,KAAKoF,SAAS5J,UAAUvW,SAtOT,OAuOxB,CAEAk0B,6BAGE,GAFkB5Y,GAAakB,QAAQzB,KAAKoF,SAAUoS,IAExC3V,iBACZ,OAGF,MAAMyX,EAAqBtZ,KAAKoF,SAAStX,aAAehI,SAASC,gBAAgBsC,aAC3EkxB,EAAmBvZ,KAAKoF,SAAS5jB,MAAMiL,UAEpB,WAArB8sB,GAAiCvZ,KAAKoF,SAAS5J,UAAUvW,SAASkzB,MAIjEmB,IACHtZ,KAAKoF,SAAS5jB,MAAMiL,UAAY,UAGlCuT,KAAKoF,SAAS5J,UAAUtE,IAAIihB,IAE5BnY,KAAK2F,gBAAe,KAClB3F,KAAKoF,SAAS5J,UAAUuH,OAAOoV,IAE/BnY,KAAK2F,gBAAe,KAClB3F,KAAKoF,SAAS5jB,MAAMiL,UAAY8sB,CAAgB,GAC/CvZ,KAAKuY,QAAQ,GACfvY,KAAKuY,SAERvY,KAAKoF,SAASsN,QAChB,CAMAmG,gBACE,MAAMS,EAAqBtZ,KAAKoF,SAAStX,aAAehI,SAASC,gBAAgBsC,aAE3E0sB,EAAiB/U,KAAK4Y,WAAWvE,WAEjCmF,EAAoBzE,EAAiB,EAE3C,GAAIyE,IAAsBF,EAAoB,CAC5C,MAAM/2B,EAAW4Z,KAAU,cAAgB,eAC3C6D,KAAKoF,SAAS5jB,MAAMe,GAAY,GAAGwyB,KACrC,CAEA,IAAKyE,GAAqBF,EAAoB,CAC5C,MAAM/2B,EAAW4Z,KAAU,eAAiB,cAC5C6D,KAAKoF,SAAS5jB,MAAMe,GAAY,GAAGwyB,KACrC,CACF,CAEAsE,oBACErZ,KAAKoF,SAAS5jB,MAAMi4B,YAAc,GAClCzZ,KAAKoF,SAAS5jB,MAAMk4B,aAAe,EACrC,CAGA7T,uBAAuBxB,EAAQvE,GAC7B,OAAOE,KAAK4G,MAAK,WACf,MAAM9b,EAAOwtB,GAAMjS,oBAAoBrG,KAAMqE,GAE7C,GAAsB,iBAAXA,EAAX,CAIA,QAA4B,IAAjBvZ,EAAKuZ,GACd,MAAM,IAAIW,UAAU,oBAAoBX,MAG1CvZ,EAAKuZ,GAAQvE,EANb,CAOF,GACF,EAQFS,GAAaY,GAAGrb,SAAUkyB,GApTK,4BAoT2C,SAAU5Y,GAClF,MAAMpS,EAASsN,GAAuB0F,MAElC,CAAC,IAAK,QAAQ9F,SAAS8F,KAAKoG,UAC9BhH,EAAM+C,iBAGR5B,GAAaa,IAAIpU,EAAQ0qB,IAAciC,IACjCA,EAAU9X,kBAKdtB,GAAaa,IAAIpU,EAAQyqB,IAAgB,KACnC3c,GAAUkF,OACZA,KAAK0S,OACP,GACA,IAGJ,MAAMkH,EAAc3S,GAAeC,QA3Ub,eA6UlB0S,GACFtB,GAAMxS,YAAY8T,GAAahK,OAGpB0I,GAAMjS,oBAAoBrZ,GAClC+Z,OAAO/G,KACd,IACAgG,GAAqBsS,IAKrBjc,GAAmBic,IAYnB,MAEMuB,GAAc,gBACdC,GAAiB,YACjBC,GAAwB,OAAOF,KAAcC,KAE7CE,GAAoB,OACpBC,GAAuB,UACvBC,GAAoB,SAEpBC,GAAgB,kBAChBC,GAAe,OAAOP,KACtBQ,GAAgB,QAAQR,KACxBS,GAAe,OAAOT,KACtBU,GAAuB,gBAAgBV,KACvCW,GAAiB,SAASX,KAC1BY,GAAe,SAASZ,KACxBa,GAAyB,QAAQb,KAAcC,KAC/Ca,GAAwB,kBAAkBd,KAE1Ce,GAAY,CAChBzE,UAAU,EACVpL,UAAU,EACV7f,QAAQ,GAEJ2vB,GAAgB,CACpB1E,SAAU,mBACVpL,SAAU,UACV7f,OAAQ,WAMV,MAAM4vB,WAAkB5V,GACtBR,YAAY1kB,EAASqkB,GACnBc,MAAMnlB,EAASqkB,GACfrE,KAAK2P,UAAW,EAChB3P,KAAKwY,UAAYxY,KAAKyY,sBACtBzY,KAAK0Y,WAAa1Y,KAAK2Y,uBAEvB3Y,KAAK4L,oBACP,CAGW3H,qBACT,OAAO2W,EACT,CAEW1W,yBACT,OAAO2W,EACT,CAEWpe,kBACT,MAtDW,WAuDb,CAGAsK,OAAOjH,GACL,OAAOE,KAAK2P,SAAW3P,KAAK4P,OAAS5P,KAAK6P,KAAK/P,EACjD,CAEA+P,KAAK/P,GACCE,KAAK2P,UAISpP,GAAakB,QAAQzB,KAAKoF,SAAUgV,GAAc,CAClEta,kBAGY+B,mBAId7B,KAAK2P,UAAW,EAEhB3P,KAAKwY,UAAU3I,OAEV7P,KAAKqF,QAAQna,SAChB,IAAIkpB,IAAkBxE,OAGxB5P,KAAKoF,SAASvjB,aAAa,cAAc,GAEzCme,KAAKoF,SAASvjB,aAAa,OAAQ,UAEnCme,KAAKoF,SAAS5J,UAAUtE,IAAI+iB,IAgB5Bja,KAAK2F,gBAdoB,KAClB3F,KAAKqF,QAAQna,SAAU8U,KAAKqF,QAAQ8Q,UACvCnW,KAAK0Y,WAAWzB,WAGlBjX,KAAKoF,SAAS5J,UAAUtE,IAAI8iB,IAE5Bha,KAAKoF,SAAS5J,UAAUuH,OAAOkX,IAE/B1Z,GAAakB,QAAQzB,KAAKoF,SAAUiV,GAAe,CACjDva,iBACA,GAGkCE,KAAKoF,UAAU,GACvD,CAEAwK,OACO5P,KAAK2P,WAIQpP,GAAakB,QAAQzB,KAAKoF,SAAUkV,IAExCzY,mBAId7B,KAAK0Y,WAAWtB,aAEhBpX,KAAKoF,SAAS2V,OAEd/a,KAAK2P,UAAW,EAEhB3P,KAAKoF,SAAS5J,UAAUtE,IAAIgjB,IAE5Bla,KAAKwY,UAAU5I,OAgBf5P,KAAK2F,gBAdoB,KACvB3F,KAAKoF,SAAS5J,UAAUuH,OAAOiX,GAAmBE,IAElDla,KAAKoF,SAASxjB,gBAAgB,cAE9Boe,KAAKoF,SAASxjB,gBAAgB,QAEzBoe,KAAKqF,QAAQna,SAChB,IAAIkpB,IAAkBthB,QAGxByN,GAAakB,QAAQzB,KAAKoF,SAAUoV,GAAe,GAGfxa,KAAKoF,UAAU,IACvD,CAEAG,UACEvF,KAAKwY,UAAUjT,UAEfvF,KAAK0Y,WAAWtB,aAEhBjS,MAAMI,SACR,CAGAkT,sBACE,MAUM3d,EAAYgG,QAAQd,KAAKqF,QAAQ8Q,UACvC,OAAO,IAAIL,GAAS,CAClBJ,UA7JsB,qBA8JtB5a,YACA8K,YAAY,EACZgQ,YAAa5V,KAAKoF,SAAS5f,WAC3BmwB,cAAe7a,EAhBK,KACU,WAA1BkF,KAAKqF,QAAQ8Q,SAKjBnW,KAAK4P,OAJHrP,GAAakB,QAAQzB,KAAKoF,SAAUmV,GAI3B,EAUgC,MAE/C,CAEA5B,uBACE,OAAO,IAAI7B,GAAU,CACnBF,YAAa5W,KAAKoF,UAEtB,CAEAwG,qBACErL,GAAaY,GAAGnB,KAAKoF,SAAUuV,IAAuBvb,IAhLvC,WAiLTA,EAAM7hB,MAILyiB,KAAKqF,QAAQ0F,SAKlB/K,KAAK4P,OAJHrP,GAAakB,QAAQzB,KAAKoF,SAAUmV,IAI3B,GAEf,CAGA1U,uBAAuBxB,GACrB,OAAOrE,KAAK4G,MAAK,WACf,MAAM9b,EAAOgwB,GAAUzU,oBAAoBrG,KAAMqE,GAEjD,GAAsB,iBAAXA,EAAX,CAIA,QAAqB7K,IAAjB1O,EAAKuZ,IAAyBA,EAAOlK,WAAW,MAAmB,gBAAXkK,EAC1D,MAAM,IAAIW,UAAU,oBAAoBX,MAG1CvZ,EAAKuZ,GAAQrE,KANb,CAOF,GACF,EAQFO,GAAaY,GAAGrb,SAAU40B,GAvMK,gCAuM2C,SAAUtb,GAClF,MAAMpS,EAASsN,GAAuB0F,MAMtC,GAJI,CAAC,IAAK,QAAQ9F,SAAS8F,KAAKoG,UAC9BhH,EAAM+C,iBAGJ9G,GAAW2E,MACb,OAGFO,GAAaa,IAAIpU,EAAQwtB,IAAgB,KAEnC1f,GAAUkF,OACZA,KAAK0S,OACP,IAGF,MAAMkH,EAAc3S,GAAeC,QAAQiT,IAEvCP,GAAeA,IAAgB5sB,GACjC8tB,GAAUhV,YAAY8T,GAAahK,OAGxBkL,GAAUzU,oBAAoBrZ,GACtC+Z,OAAO/G,KACd,IACAO,GAAaY,GAAG9gB,OAAQ05B,IAAuB,KAC7C,IAAK,MAAMhgB,KAAYkN,GAAerU,KAAKunB,IACzCW,GAAUzU,oBAAoBtM,GAAU8V,MAC1C,IAEFtP,GAAaY,GAAG9gB,OAAQo6B,IAAc,KACpC,IAAK,MAAMz6B,KAAWinB,GAAerU,KAAK,gDACG,UAAvClN,iBAAiB1F,GAASiC,UAC5B64B,GAAUzU,oBAAoBrmB,GAAS4vB,MAE3C,IAEF5J,GAAqB8U,IAKrBze,GAAmBye,IAQnB,MAAME,GAAgB,IAAIjkB,IAAI,CAAC,aAAc,OAAQ,OAAQ,WAAY,WAAY,SAAU,MAAO,eAQhGkkB,GAAmB,iEAOnBC,GAAmB,qIAEnBC,GAAmB,CAAC34B,EAAW44B,KACnC,MAAMC,EAAgB74B,EAAUvC,SAASC,cAEzC,OAAIk7B,EAAqBlhB,SAASmhB,IAC5BL,GAAc5jB,IAAIikB,IACbva,QAAQma,GAAiBn3B,KAAKtB,EAAU84B,YAAcJ,GAAiBp3B,KAAKtB,EAAU84B,YAO1FF,EAAqBx0B,QAAO20B,GAAkBA,aAA0BxW,SAAQ7R,MAAKsoB,GAASA,EAAM13B,KAAKu3B,IAAe,EAG3HI,GAAmB,CAEvB,IAAK,CAAC,QAAS,MAAO,KAAM,OAAQ,OAjCP,kBAkC7BnqB,EAAG,CAAC,SAAU,OAAQ,QAAS,OAC/BoqB,KAAM,GACNnqB,EAAG,GACHoqB,GAAI,GACJC,IAAK,GACLC,KAAM,GACNC,IAAK,GACLC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJC,GAAI,GACJxqB,EAAG,GACHgb,IAAK,CAAC,MAAO,SAAU,MAAO,QAAS,QAAS,UAChDyP,GAAI,GACJC,GAAI,GACJC,EAAG,GACHC,IAAK,GACLC,EAAG,GACHC,MAAO,GACPC,KAAM,GACNC,IAAK,GACLC,IAAK,GACLC,OAAQ,GACRC,EAAG,GACHC,GAAI,IA+CAC,GAAY,CAChBC,UAAW3B,GACX4B,QAAS,CAAC,EAEVC,WAAY,GACZhwB,MAAM,EACNiwB,UAAU,EACVC,WAAY,KACZC,SAAU,eAENC,GAAgB,CACpBN,UAAW,SACXC,QAAS,SACTC,WAAY,oBACZhwB,KAAM,UACNiwB,SAAU,UACVC,WAAY,kBACZC,SAAU,UAENE,GAAqB,CACzBC,MAAO,iCACP7jB,SAAU,oBAMZ,MAAM8jB,WAAwB7Z,GAC5BU,YAAYL,GACVc,QACAnF,KAAKqF,QAAUrF,KAAKoE,WAAWC,EACjC,CAGWJ,qBACT,OAAOkZ,EACT,CAEWjZ,yBACT,OAAOwZ,EACT,CAEWjhB,kBACT,MA5CW,iBA6Cb,CAGAqhB,aACE,OAAOrgC,OAAO0hB,OAAOa,KAAKqF,QAAQgY,SAAS95B,KAAI8gB,GAAUrE,KAAK+d,yBAAyB1Z,KAASzd,OAAOka,QACzG,CAEAkd,aACE,OAAOhe,KAAK8d,aAAa3sB,OAAS,CACpC,CAEA8sB,cAAcZ,GAMZ,OALArd,KAAKke,cAAcb,GAEnBrd,KAAKqF,QAAQgY,QAAU,IAAKrd,KAAKqF,QAAQgY,WACpCA,GAEErd,IACT,CAEAme,SACE,MAAMC,EAAkBt4B,SAASswB,cAAc,OAC/CgI,EAAgBC,UAAYre,KAAKse,eAAete,KAAKqF,QAAQoY,UAE7D,IAAK,MAAO1jB,EAAUwkB,KAAS9gC,OAAO4kB,QAAQrC,KAAKqF,QAAQgY,SACzDrd,KAAKwe,YAAYJ,EAAiBG,EAAMxkB,GAG1C,MAAM0jB,EAAWW,EAAgBjX,SAAS,GAEpCmW,EAAatd,KAAK+d,yBAAyB/d,KAAKqF,QAAQiY,YAM9D,OAJIA,GACFG,EAASjiB,UAAUtE,OAAOomB,EAAW36B,MAAM,MAGtC86B,CACT,CAGAjZ,iBAAiBH,GACfc,MAAMX,iBAAiBH,GAEvBrE,KAAKke,cAAc7Z,EAAOgZ,QAC5B,CAEAa,cAAcO,GACZ,IAAK,MAAO1kB,EAAUsjB,KAAY5/B,OAAO4kB,QAAQoc,GAC/CtZ,MAAMX,iBAAiB,CACrBzK,WACA6jB,MAAOP,GACNM,GAEP,CAEAa,YAAYf,EAAUJ,EAAStjB,GAC7B,MAAM2kB,EAAkBzX,GAAeC,QAAQnN,EAAU0jB,GAEpDiB,KAILrB,EAAUrd,KAAK+d,yBAAyBV,IAOpC,GAAUA,GACZrd,KAAK2e,sBAAsB9jB,GAAWwiB,GAAUqB,GAK9C1e,KAAKqF,QAAQ/X,KACfoxB,EAAgBL,UAAYre,KAAKse,eAAejB,GAIlDqB,EAAgBE,YAAcvB,EAf5BqB,EAAgB3b,SAgBpB,CAEAub,eAAeG,GACb,OAAOze,KAAKqF,QAAQkY,SA7KxB,SAAsBsB,EAAYzB,EAAW0B,GAC3C,IAAKD,EAAW1tB,OACd,OAAO0tB,EAGT,GAAIC,GAAgD,mBAArBA,EAC7B,OAAOA,EAAiBD,GAG1B,MACME,GADY,IAAI1+B,OAAO2+B,WACKC,gBAAgBJ,EAAY,aACxDv9B,EAAW,GAAGlC,UAAU2/B,EAAgBpyB,KAAKyT,iBAAiB,MAEpE,IAAK,MAAMpgB,KAAWsB,EAAU,CAC9B,MAAM49B,EAAcl/B,EAAQC,SAASC,cAErC,IAAKzC,OAAO4D,KAAK+7B,GAAWljB,SAASglB,GAAc,CACjDl/B,EAAQ+iB,SACR,QACF,CAEA,MAAMoc,EAAgB,GAAG//B,UAAUY,EAAQ0B,YACrC09B,EAAoB,GAAGhgC,OAAOg+B,EAAU,MAAQ,GAAIA,EAAU8B,IAAgB,IAEpF,IAAK,MAAM18B,KAAa28B,EACjBhE,GAAiB34B,EAAW48B,IAC/Bp/B,EAAQ4B,gBAAgBY,EAAUvC,SAGxC,CAEA,OAAO8+B,EAAgBpyB,KAAK0xB,SAC9B,CA6ImCgB,CAAaZ,EAAKze,KAAKqF,QAAQ+X,UAAWpd,KAAKqF,QAAQmY,YAAciB,CACtG,CAEAV,yBAAyBU,GACvB,MAAsB,mBAARA,EAAqBA,EAAIze,MAAQye,CACjD,CAEAE,sBAAsB3+B,EAAS0+B,GAC7B,GAAI1e,KAAKqF,QAAQ/X,KAGf,OAFAoxB,EAAgBL,UAAY,QAC5BK,EAAgBrI,OAAOr2B,GAIzB0+B,EAAgBE,YAAc5+B,EAAQ4+B,WACxC,EAcF,MACMU,GAAwB,IAAIvoB,IAAI,CAAC,WAAY,YAAa,eAC1DwoB,GAAoB,OAEpBC,GAAoB,OAEpBC,GAAiB,SACjBC,GAAmB,gBACnBC,GAAgB,QAChBC,GAAgB,QAahBC,GAAgB,CACpBC,KAAM,OACNC,IAAK,MACLC,MAAO7jB,KAAU,OAAS,QAC1B8jB,OAAQ,SACRC,KAAM/jB,KAAU,QAAU,QAEtBgkB,GAAY,CAChB/C,UAAW3B,GACX2E,WAAW,EACX1xB,SAAU,kBACV2xB,WAAW,EACXC,YAAa,GACbC,MAAO,EACP9vB,mBAAoB,CAAC,MAAO,QAAS,SAAU,QAC/CnD,MAAM,EACN7E,OAAQ,CAAC,EAAG,GACZtJ,UAAW,MACX8yB,aAAc,KACdsL,UAAU,EACVC,WAAY,KACZzjB,UAAU,EACV0jB,SAAU,+GACV+C,MAAO,GACP/e,QAAS,eAELgf,GAAgB,CACpBrD,UAAW,SACXgD,UAAW,UACX1xB,SAAU,mBACV2xB,UAAW,2BACXC,YAAa,oBACbC,MAAO,kBACP9vB,mBAAoB,QACpBnD,KAAM,UACN7E,OAAQ,0BACRtJ,UAAW,oBACX8yB,aAAc,yBACdsL,SAAU,UACVC,WAAY,kBACZzjB,SAAU,mBACV0jB,SAAU,SACV+C,MAAO,4BACP/e,QAAS,UAMX,MAAMif,WAAgBxb,GACpBR,YAAY1kB,EAASqkB,GACnB,QAAsB,IAAX,EACT,MAAM,IAAIW,UAAU,+DAGtBG,MAAMnlB,EAASqkB,GAEfrE,KAAK2gB,YAAa,EAClB3gB,KAAK4gB,SAAW,EAChB5gB,KAAK6gB,WAAa,KAClB7gB,KAAK8gB,eAAiB,CAAC,EACvB9gB,KAAKoS,QAAU,KACfpS,KAAK+gB,iBAAmB,KACxB/gB,KAAKghB,YAAc,KAEnBhhB,KAAKihB,IAAM,KAEXjhB,KAAKkhB,gBAEAlhB,KAAKqF,QAAQtL,UAChBiG,KAAKmhB,WAET,CAGWld,qBACT,OAAOkc,EACT,CAEWjc,yBACT,OAAOuc,EACT,CAEWhkB,kBACT,MA1GW,SA2Gb,CAGA2kB,SACEphB,KAAK2gB,YAAa,CACpB,CAEAU,UACErhB,KAAK2gB,YAAa,CACpB,CAEAW,gBACEthB,KAAK2gB,YAAc3gB,KAAK2gB,UAC1B,CAEA5Z,SACO/G,KAAK2gB,aAIV3gB,KAAK8gB,eAAeS,OAASvhB,KAAK8gB,eAAeS,MAE7CvhB,KAAK2P,WACP3P,KAAKwhB,SAKPxhB,KAAKyhB,SACP,CAEAlc,UACE0H,aAAajN,KAAK4gB,UAClBrgB,GAAaC,IAAIR,KAAKoF,SAASjK,QAAQskB,IAAiBC,GAAkB1f,KAAK0hB,mBAE3E1hB,KAAKoF,SAASpL,aAAa,2BAC7BgG,KAAKoF,SAASvjB,aAAa,QAASme,KAAKoF,SAASpL,aAAa,2BAGjEgG,KAAK2hB,iBAELxc,MAAMI,SACR,CAEAsK,OACE,GAAoC,SAAhC7P,KAAKoF,SAAS5jB,MAAMwwB,QACtB,MAAM,IAAI7N,MAAM,uCAGlB,IAAMnE,KAAK4hB,mBAAoB5hB,KAAK2gB,WAClC,OAGF,MAAMhH,EAAYpZ,GAAakB,QAAQzB,KAAKoF,SAAUpF,KAAK0E,YAAYiJ,UAlJtD,SAqJXkU,GAFalmB,GAAeqE,KAAKoF,WAELpF,KAAKoF,SAAS7kB,cAAcwF,iBAAiBd,SAAS+a,KAAKoF,UAE7F,GAAIuU,EAAU9X,mBAAqBggB,EACjC,OAIF7hB,KAAK2hB,iBAEL,MAAMV,EAAMjhB,KAAK8hB,iBAEjB9hB,KAAKoF,SAASvjB,aAAa,mBAAoBo/B,EAAIjnB,aAAa,OAEhE,MAAM,UACJqmB,GACErgB,KAAKqF,QAaT,GAXKrF,KAAKoF,SAAS7kB,cAAcwF,gBAAgBd,SAAS+a,KAAKihB,OAC7DZ,EAAUhK,OAAO4K,GACjB1gB,GAAakB,QAAQzB,KAAKoF,SAAUpF,KAAK0E,YAAYiJ,UAtKpC,cAyKnB3N,KAAKoS,QAAUpS,KAAKyS,cAAcwO,GAClCA,EAAIzlB,UAAUtE,IAAIsoB,IAKd,iBAAkB15B,SAASC,gBAC7B,IAAK,MAAM/F,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAKwa,UAC/C5G,GAAaY,GAAGnhB,EAAS,YAAa8b,IAc1CkE,KAAK2F,gBAVY,KACfpF,GAAakB,QAAQzB,KAAKoF,SAAUpF,KAAK0E,YAAYiJ,UAvLrC,WAyLQ,IAApB3N,KAAK6gB,YACP7gB,KAAKwhB,SAGPxhB,KAAK6gB,YAAa,CAAK,GAGK7gB,KAAKihB,IAAKjhB,KAAKgO,cAC/C,CAEA4B,OACE,GAAK5P,KAAK2P,aAIQpP,GAAakB,QAAQzB,KAAKoF,SAAUpF,KAAK0E,YAAYiJ,UA3MtD,SA6MH9L,iBAAd,CASA,GALY7B,KAAK8hB,iBAEbtmB,UAAUuH,OAAOyc,IAGjB,iBAAkB15B,SAASC,gBAC7B,IAAK,MAAM/F,IAAW,GAAGZ,UAAU0G,SAAS6G,KAAKwa,UAC/C5G,GAAaC,IAAIxgB,EAAS,YAAa8b,IAI3CkE,KAAK8gB,eAA4B,OAAI,EACrC9gB,KAAK8gB,eAAelB,KAAiB,EACrC5f,KAAK8gB,eAAenB,KAAiB,EACrC3f,KAAK6gB,WAAa,KAgBlB7gB,KAAK2F,gBAdY,KACX3F,KAAK+hB,yBAIJ/hB,KAAK6gB,YACR7gB,KAAK2hB,iBAGP3hB,KAAKoF,SAASxjB,gBAAgB,oBAE9B2e,GAAakB,QAAQzB,KAAKoF,SAAUpF,KAAK0E,YAAYiJ,UA3OpC,WA2O8D,GAGnD3N,KAAKihB,IAAKjhB,KAAKgO,cAhC7C,CAiCF,CAEAxiB,SACMwU,KAAKoS,SACPpS,KAAKoS,QAAQ5mB,QAEjB,CAGAo2B,iBACE,OAAO9gB,QAAQd,KAAKgiB,YACtB,CAEAF,iBAKE,OAJK9hB,KAAKihB,MACRjhB,KAAKihB,IAAMjhB,KAAKiiB,kBAAkBjiB,KAAKghB,aAAehhB,KAAKkiB,2BAGtDliB,KAAKihB,GACd,CAEAgB,kBAAkB5E,GAChB,MAAM4D,EAAMjhB,KAAKmiB,oBAAoB9E,GAASc,SAG9C,IAAK8C,EACH,OAAO,KAGTA,EAAIzlB,UAAUuH,OAAOwc,GAAmBC,IAExCyB,EAAIzlB,UAAUtE,IAAI,MAAM8I,KAAK0E,YAAYjI,aACzC,MAAM2lB,EA92HKC,KACb,GACEA,GAAUz/B,KAAK0/B,MAlBH,IAkBS1/B,KAAK2/B,gBACnBz8B,SAAS08B,eAAeH,IAEjC,OAAOA,CAAM,EAy2HGI,CAAOziB,KAAK0E,YAAYjI,MAAMnc,WAO5C,OANA2gC,EAAIp/B,aAAa,KAAMugC,GAEnBpiB,KAAKgO,eACPiT,EAAIzlB,UAAUtE,IAAIqoB,IAGb0B,CACT,CAEAyB,WAAWrF,GACTrd,KAAKghB,YAAc3D,EAEfrd,KAAK2P,aACP3P,KAAK2hB,iBAEL3hB,KAAK6P,OAET,CAEAsS,oBAAoB9E,GAYlB,OAXIrd,KAAK+gB,iBACP/gB,KAAK+gB,iBAAiB9C,cAAcZ,GAEpCrd,KAAK+gB,iBAAmB,IAAIlD,GAAgB,IAAK7d,KAAKqF,QAGpDgY,UACAC,WAAYtd,KAAK+d,yBAAyB/d,KAAKqF,QAAQib,eAIpDtgB,KAAK+gB,gBACd,CAEAmB,yBACE,MAAO,CACL,iBAA0BliB,KAAKgiB,YAEnC,CAEAA,YACE,OAAOhiB,KAAK+d,yBAAyB/d,KAAKqF,QAAQmb,QAAUxgB,KAAKoF,SAASpL,aAAa,yBACzF,CAGA2oB,6BAA6BvjB,GAC3B,OAAOY,KAAK0E,YAAY2B,oBAAoBjH,EAAMW,eAAgBC,KAAK4iB,qBACzE,CAEA5U,cACE,OAAOhO,KAAKqF,QAAQ+a,WAAapgB,KAAKihB,KAAOjhB,KAAKihB,IAAIzlB,UAAUvW,SAASs6B,GAC3E,CAEA5P,WACE,OAAO3P,KAAKihB,KAAOjhB,KAAKihB,IAAIzlB,UAAUvW,SAASu6B,GACjD,CAEA/M,cAAcwO,GACZ,MAAM9hC,EAA8C,mBAA3B6gB,KAAKqF,QAAQlmB,UAA2B6gB,KAAKqF,QAAQlmB,UAAUlB,KAAK+hB,KAAMihB,EAAKjhB,KAAKoF,UAAYpF,KAAKqF,QAAQlmB,UAChI0jC,EAAahD,GAAc1gC,EAAU8lB,eAC3C,OAAO,GAAoBjF,KAAKoF,SAAU6b,EAAKjhB,KAAK6S,iBAAiBgQ,GACvE,CAEA5P,aACE,MAAM,OACJxqB,GACEuX,KAAKqF,QAET,MAAsB,iBAAX5c,EACFA,EAAO9F,MAAM,KAAKY,KAAInF,GAASmf,OAAO+P,SAASlvB,EAAO,MAGzC,mBAAXqK,EACFyqB,GAAczqB,EAAOyqB,EAAYlT,KAAKoF,UAGxC3c,CACT,CAEAs1B,yBAAyBU,GACvB,MAAsB,mBAARA,EAAqBA,EAAIxgC,KAAK+hB,KAAKoF,UAAYqZ,CAC/D,CAEA5L,iBAAiBgQ,GACf,MAAM1P,EAAwB,CAC5Bh0B,UAAW0jC,EACXhsB,UAAW,CAAC,CACV9V,KAAM,OACNmB,QAAS,CACPuO,mBAAoBuP,KAAKqF,QAAQ5U,qBAElC,CACD1P,KAAM,SACNmB,QAAS,CACPuG,OAAQuX,KAAKiT,eAEd,CACDlyB,KAAM,kBACNmB,QAAS,CACPwM,SAAUsR,KAAKqF,QAAQ3W,WAExB,CACD3N,KAAM,QACNmB,QAAS,CACPlC,QAAS,IAAIggB,KAAK0E,YAAYjI,eAE/B,CACD1b,KAAM,kBACNC,SAAS,EACTC,MAAO,aACPC,GAAI4J,IAGFkV,KAAK8hB,iBAAiBjgC,aAAa,wBAAyBiJ,EAAK1J,MAAMjC,UAAU,KAIvF,MAAO,IAAKg0B,KAC+B,mBAA9BnT,KAAKqF,QAAQ4M,aAA8BjS,KAAKqF,QAAQ4M,aAAakB,GAAyBnT,KAAKqF,QAAQ4M,aAE1H,CAEAiP,gBACE,MAAM4B,EAAW9iB,KAAKqF,QAAQ5D,QAAQ9e,MAAM,KAE5C,IAAK,MAAM8e,KAAWqhB,EACpB,GAAgB,UAAZrhB,EACFlB,GAAaY,GAAGnB,KAAKoF,SAAUpF,KAAK0E,YAAYiJ,UA3YlC,SA2Y4D3N,KAAKqF,QAAQtL,UAAUqF,IAC/EY,KAAK2iB,6BAA6BvjB,GAE1C2H,QAAQ,SAEb,GAtZU,WAsZNtF,EAA4B,CACrC,MAAMshB,EAAUthB,IAAYke,GAAgB3f,KAAK0E,YAAYiJ,UA9Y5C,cA8Y0E3N,KAAK0E,YAAYiJ,UAhZ5F,WAiZVqV,EAAWvhB,IAAYke,GAAgB3f,KAAK0E,YAAYiJ,UA9Y7C,cA8Y2E3N,KAAK0E,YAAYiJ,UAhZ5F,YAiZjBpN,GAAaY,GAAGnB,KAAKoF,SAAU2d,EAAS/iB,KAAKqF,QAAQtL,UAAUqF,IAC7D,MAAMkU,EAAUtT,KAAK2iB,6BAA6BvjB,GAElDkU,EAAQwN,eAA8B,YAAf1hB,EAAMqB,KAAqBmf,GAAgBD,KAAiB,EAEnFrM,EAAQmO,QAAQ,IAElBlhB,GAAaY,GAAGnB,KAAKoF,SAAU4d,EAAUhjB,KAAKqF,QAAQtL,UAAUqF,IAC9D,MAAMkU,EAAUtT,KAAK2iB,6BAA6BvjB,GAElDkU,EAAQwN,eAA8B,aAAf1hB,EAAMqB,KAAsBmf,GAAgBD,IAAiBrM,EAAQlO,SAASngB,SAASma,EAAMU,eAEpHwT,EAAQkO,QAAQ,GAEpB,CAGFxhB,KAAK0hB,kBAAoB,KACnB1hB,KAAKoF,UACPpF,KAAK4P,MACP,EAGFrP,GAAaY,GAAGnB,KAAKoF,SAASjK,QAAQskB,IAAiBC,GAAkB1f,KAAK0hB,kBAChF,CAEAP,YACE,MAAMX,EAAQxgB,KAAKoF,SAASpL,aAAa,SAEpCwmB,IAIAxgB,KAAKoF,SAASpL,aAAa,eAAkBgG,KAAKoF,SAASwZ,YAAYxkB,QAC1E4F,KAAKoF,SAASvjB,aAAa,aAAc2+B,GAG3CxgB,KAAKoF,SAASvjB,aAAa,yBAA0B2+B,GAGrDxgB,KAAKoF,SAASxjB,gBAAgB,SAChC,CAEA6/B,SACMzhB,KAAK2P,YAAc3P,KAAK6gB,WAC1B7gB,KAAK6gB,YAAa,GAIpB7gB,KAAK6gB,YAAa,EAElB7gB,KAAKijB,aAAY,KACXjjB,KAAK6gB,YACP7gB,KAAK6P,MACP,GACC7P,KAAKqF,QAAQkb,MAAM1Q,MACxB,CAEA2R,SACMxhB,KAAK+hB,yBAIT/hB,KAAK6gB,YAAa,EAElB7gB,KAAKijB,aAAY,KACVjjB,KAAK6gB,YACR7gB,KAAK4P,MACP,GACC5P,KAAKqF,QAAQkb,MAAM3Q,MACxB,CAEAqT,YAAYrlB,EAASslB,GACnBjW,aAAajN,KAAK4gB,UAClB5gB,KAAK4gB,SAAW/iB,WAAWD,EAASslB,EACtC,CAEAnB,uBACE,OAAOtkC,OAAO0hB,OAAOa,KAAK8gB,gBAAgB5mB,UAAS,EACrD,CAEAkK,WAAWC,GACT,MAAM8e,EAAiB5f,GAAYG,kBAAkB1D,KAAKoF,UAE1D,IAAK,MAAMge,KAAiB3lC,OAAO4D,KAAK8hC,GAClC7D,GAAsBloB,IAAIgsB,WACrBD,EAAeC,GAY1B,OARA/e,EAAS,IAAK8e,KACU,iBAAX9e,GAAuBA,EAASA,EAAS,CAAC,GAEvDA,EAASrE,KAAKsE,gBAAgBD,GAC9BA,EAASrE,KAAKuE,kBAAkBF,GAEhCrE,KAAKwE,iBAAiBH,GAEfA,CACT,CAEAE,kBAAkBF,GAkBhB,OAjBAA,EAAOgc,WAAiC,IAArBhc,EAAOgc,UAAsBv6B,SAAS6G,KAAOkO,GAAWwJ,EAAOgc,WAEtD,iBAAjBhc,EAAOkc,QAChBlc,EAAOkc,MAAQ,CACb1Q,KAAMxL,EAAOkc,MACb3Q,KAAMvL,EAAOkc,QAIW,iBAAjBlc,EAAOmc,QAChBnc,EAAOmc,MAAQnc,EAAOmc,MAAMlgC,YAGA,iBAAnB+jB,EAAOgZ,UAChBhZ,EAAOgZ,QAAUhZ,EAAOgZ,QAAQ/8B,YAG3B+jB,CACT,CAEAue,qBACE,MAAMve,EAAS,CAAC,EAEhB,IAAK,MAAM9mB,KAAOyiB,KAAKqF,QACjBrF,KAAK0E,YAAYT,QAAQ1mB,KAASyiB,KAAKqF,QAAQ9nB,KACjD8mB,EAAO9mB,GAAOyiB,KAAKqF,QAAQ9nB,IAS/B,OALA8mB,EAAOtK,UAAW,EAClBsK,EAAO5C,QAAU,SAIV4C,CACT,CAEAsd,iBACM3hB,KAAKoS,UACPpS,KAAKoS,QAAQ3Y,UAEbuG,KAAKoS,QAAU,MAGbpS,KAAKihB,MACPjhB,KAAKihB,IAAIle,SACT/C,KAAKihB,IAAM,KAEf,CAGApb,uBAAuBxB,GACrB,OAAOrE,KAAK4G,MAAK,WACf,MAAM9b,EAAO41B,GAAQra,oBAAoBrG,KAAMqE,GAE/C,GAAsB,iBAAXA,EAAX,CAIA,QAA4B,IAAjBvZ,EAAKuZ,GACd,MAAM,IAAIW,UAAU,oBAAoBX,MAG1CvZ,EAAKuZ,IANL,CAOF,GACF,EAQFhI,GAAmBqkB,IAYnB,MAGM2C,GAAY,IAAK3C,GAAQzc,QAC7BoZ,QAAS,GACT50B,OAAQ,CAAC,EAAG,GACZtJ,UAAW,QACXs+B,SAAU,8IACVhc,QAAS,SAEL6hB,GAAgB,IAAK5C,GAAQxc,YACjCmZ,QAAS,kCAMX,MAAMkG,WAAgB7C,GAETzc,qBACT,OAAOof,EACT,CAEWnf,yBACT,OAAOof,EACT,CAEW7mB,kBACT,MA5BW,SA6Bb,CAGAmlB,iBACE,OAAO5hB,KAAKgiB,aAAehiB,KAAKwjB,aAClC,CAGAtB,yBACE,MAAO,CACL,kBAAkBliB,KAAKgiB,YACvB,gBAAoBhiB,KAAKwjB,cAE7B,CAEAA,cACE,OAAOxjB,KAAK+d,yBAAyB/d,KAAKqF,QAAQgY,QACpD,CAGAxX,uBAAuBxB,GACrB,OAAOrE,KAAK4G,MAAK,WACf,MAAM9b,EAAOy4B,GAAQld,oBAAoBrG,KAAMqE,GAE/C,GAAsB,iBAAXA,EAAX,CAIA,QAA4B,IAAjBvZ,EAAKuZ,GACd,MAAM,IAAIW,UAAU,oBAAoBX,MAG1CvZ,EAAKuZ,IANL,CAOF,GACF,EAQFhI,GAAmBknB,IAYnB,MAEME,GAAc,gBAEdC,GAAiB,WAAWD,KAC5BE,GAAc,QAAQF,KACtBG,GAAwB,OAAOH,cAE/BI,GAAsB,SAEtBC,GAAwB,SAExBC,GAAqB,YAGrBC,GAAsB,GAAGD,mBAA+CA,uBAGxEE,GAAY,CAChBx7B,OAAQ,KAERy7B,WAAY,eACZC,cAAc,EACdn3B,OAAQ,KACRo3B,UAAW,CAAC,GAAK,GAAK,IAElBC,GAAgB,CACpB57B,OAAQ,gBAERy7B,WAAY,SACZC,aAAc,UACdn3B,OAAQ,UACRo3B,UAAW,SAMb,MAAME,WAAkBpf,GACtBR,YAAY1kB,EAASqkB,GACnBc,MAAMnlB,EAASqkB,GAEfrE,KAAKukB,aAAe,IAAI5yB,IACxBqO,KAAKwkB,oBAAsB,IAAI7yB,IAC/BqO,KAAKykB,aAA6D,YAA9C/+B,iBAAiBsa,KAAKoF,UAAU3Y,UAA0B,KAAOuT,KAAKoF,SAC1FpF,KAAK0kB,cAAgB,KACrB1kB,KAAK2kB,UAAY,KACjB3kB,KAAK4kB,oBAAsB,CACzBC,gBAAiB,EACjBC,gBAAiB,GAEnB9kB,KAAK+kB,SACP,CAGW9gB,qBACT,OAAOggB,EACT,CAEW/f,yBACT,OAAOmgB,EACT,CAEW5nB,kBACT,MAhEW,WAiEb,CAGAsoB,UACE/kB,KAAKglB,mCAELhlB,KAAKilB,2BAEDjlB,KAAK2kB,UACP3kB,KAAK2kB,UAAUO,aAEfllB,KAAK2kB,UAAY3kB,KAAKmlB,kBAGxB,IAAK,MAAMC,KAAWplB,KAAKwkB,oBAAoBrlB,SAC7Ca,KAAK2kB,UAAUU,QAAQD,EAE3B,CAEA7f,UACEvF,KAAK2kB,UAAUO,aAEf/f,MAAMI,SACR,CAGAhB,kBAAkBF,GAUhB,OARAA,EAAOrX,OAAS6N,GAAWwJ,EAAOrX,SAAWlH,SAAS6G,KAEtD0X,EAAO6f,WAAa7f,EAAO5b,OAAS,GAAG4b,EAAO5b,oBAAsB4b,EAAO6f,WAE3C,iBAArB7f,EAAO+f,YAChB/f,EAAO+f,UAAY/f,EAAO+f,UAAUzhC,MAAM,KAAKY,KAAInF,GAASmf,OAAOC,WAAWpf,MAGzEimB,CACT,CAEA4gB,2BACOjlB,KAAKqF,QAAQ8e,eAKlB5jB,GAAaC,IAAIR,KAAKqF,QAAQrY,OAAQ22B,IACtCpjB,GAAaY,GAAGnB,KAAKqF,QAAQrY,OAAQ22B,GAAaG,IAAuB1kB,IACvE,MAAMkmB,EAAoBtlB,KAAKwkB,oBAAoB5mC,IAAIwhB,EAAMpS,OAAOtB,MAEpE,GAAI45B,EAAmB,CACrBlmB,EAAM+C,iBACN,MAAMtG,EAAOmE,KAAKykB,cAAgBpkC,OAC5BmE,EAAS8gC,EAAkBxgC,UAAYkb,KAAKoF,SAAStgB,UAE3D,GAAI+W,EAAK0pB,SAKP,YAJA1pB,EAAK0pB,SAAS,CACZnjC,IAAKoC,EACLghC,SAAU,WAMd3pB,EAAK3P,UAAY1H,CACnB,KAEJ,CAEA2gC,kBACE,MAAMjjC,EAAU,CACd2Z,KAAMmE,KAAKykB,aACXL,UAAWpkB,KAAKqF,QAAQ+e,UACxBF,WAAYlkB,KAAKqF,QAAQ6e,YAE3B,OAAO,IAAIuB,sBAAqBpjB,GAAWrC,KAAK0lB,kBAAkBrjB,IAAUngB,EAC9E,CAGAwjC,kBAAkBrjB,GAChB,MAAMsjB,EAAgB/H,GAAS5d,KAAKukB,aAAa3mC,IAAI,IAAIggC,EAAM5wB,OAAO44B,MAEhE3O,EAAW2G,IACf5d,KAAK4kB,oBAAoBC,gBAAkBjH,EAAM5wB,OAAOlI,UAExDkb,KAAK6lB,SAASF,EAAc/H,GAAO,EAG/BkH,GAAmB9kB,KAAKykB,cAAgB3+B,SAASC,iBAAiBmG,UAClE45B,EAAkBhB,GAAmB9kB,KAAK4kB,oBAAoBE,gBACpE9kB,KAAK4kB,oBAAoBE,gBAAkBA,EAE3C,IAAK,MAAMlH,KAASvb,EAAS,CAC3B,IAAKub,EAAMmI,eAAgB,CACzB/lB,KAAK0kB,cAAgB,KAErB1kB,KAAKgmB,kBAAkBL,EAAc/H,IAErC,QACF,CAEA,MAAMqI,EAA2BrI,EAAM5wB,OAAOlI,WAAakb,KAAK4kB,oBAAoBC,gBAEpF,GAAIiB,GAAmBG,GAGrB,GAFAhP,EAAS2G,IAEJkH,EACH,YAOCgB,GAAoBG,GACvBhP,EAAS2G,EAEb,CACF,CAEAoH,mCACEhlB,KAAKukB,aAAe,IAAI5yB,IACxBqO,KAAKwkB,oBAAsB,IAAI7yB,IAC/B,MAAMu0B,EAAcjf,GAAerU,KAAKkxB,GAAuB9jB,KAAKqF,QAAQrY,QAE5E,IAAK,MAAMm5B,KAAUD,EAAa,CAEhC,IAAKC,EAAOz6B,MAAQ2P,GAAW8qB,GAC7B,SAGF,MAAMb,EAAoBre,GAAeC,QAAQif,EAAOz6B,KAAMsU,KAAKoF,UAE/DtK,GAAUwqB,KACZtlB,KAAKukB,aAAa/xB,IAAI2zB,EAAOz6B,KAAMy6B,GAEnCnmB,KAAKwkB,oBAAoBhyB,IAAI2zB,EAAOz6B,KAAM45B,GAE9C,CACF,CAEAO,SAAS74B,GACHgT,KAAK0kB,gBAAkB13B,IAI3BgT,KAAKgmB,kBAAkBhmB,KAAKqF,QAAQrY,QAEpCgT,KAAK0kB,cAAgB13B,EACrBA,EAAOwO,UAAUtE,IAAI2sB,IAErB7jB,KAAKomB,iBAAiBp5B,GAEtBuT,GAAakB,QAAQzB,KAAKoF,SAAUse,GAAgB,CAClD5jB,cAAe9S,IAEnB,CAEAo5B,iBAAiBp5B,GAEf,GAAIA,EAAOwO,UAAUvW,SAzNQ,iBA0N3BgiB,GAAeC,QAhNc,mBAgNsBla,EAAOmO,QAjNtC,cAiNkEK,UAAUtE,IAAI2sB,SAItG,IAAK,MAAMwC,KAAapf,GAAeI,QAAQra,EA1NnB,qBA6N1B,IAAK,MAAMxJ,KAAQyjB,GAAeM,KAAK8e,EAAWrC,IAChDxgC,EAAKgY,UAAUtE,IAAI2sB,GAGzB,CAEAmC,kBAAkB9gC,GAChBA,EAAOsW,UAAUuH,OAAO8gB,IACxB,MAAMyC,EAAcrf,GAAerU,KAAK,GAAGkxB,MAAyBD,KAAuB3+B,GAE3F,IAAK,MAAM9E,KAAQkmC,EACjBlmC,EAAKob,UAAUuH,OAAO8gB,GAE1B,CAGAhe,uBAAuBxB,GACrB,OAAOrE,KAAK4G,MAAK,WACf,MAAM9b,EAAOw5B,GAAUje,oBAAoBrG,KAAMqE,GAEjD,GAAsB,iBAAXA,EAAX,CAIA,QAAqB7K,IAAjB1O,EAAKuZ,IAAyBA,EAAOlK,WAAW,MAAmB,gBAAXkK,EAC1D,MAAM,IAAIW,UAAU,oBAAoBX,MAG1CvZ,EAAKuZ,IANL,CAOF,GACF,EAQF9D,GAAaY,GAAG9gB,OAAQujC,IAAuB,KAC7C,IAAK,MAAM2C,KAAOtf,GAAerU,KAtQT,0BAuQtB0xB,GAAUje,oBAAoBkgB,EAChC,IAMFlqB,GAAmBioB,IAYnB,MAEMkC,GAAc,UACdC,GAAe,OAAOD,KACtBE,GAAiB,SAASF,KAC1BG,GAAe,OAAOH,KACtBI,GAAgB,QAAQJ,KACxBK,GAAuB,QAAQL,KAC/BM,GAAgB,UAAUN,KAC1BO,GAAsB,OAAOP,KAC7BQ,GAAiB,YACjBC,GAAkB,aAClBC,GAAe,UACfC,GAAiB,YACjBC,GAAoB,SACpBC,GAAoB,OACpBC,GAAoB,OAIpBC,GAA+B,yBAI/BC,GAAuB,2EAEvBC,GAAsB,YAHOF,uBAAiDA,mBAA6CA,OAG/EC,KAC5CE,GAA8B,IAAIN,8BAA6CA,+BAA8CA,4BAKnI,MAAMO,WAAYziB,GAChBR,YAAY1kB,GACVmlB,MAAMnlB,GACNggB,KAAKqS,QAAUrS,KAAKoF,SAASjK,QAdN,uCAgBlB6E,KAAKqS,UAMVrS,KAAK4nB,sBAAsB5nB,KAAKqS,QAASrS,KAAK6nB,gBAE9CtnB,GAAaY,GAAGnB,KAAKoF,SAAU0hB,IAAe1nB,GAASY,KAAK4M,SAASxN,KACvE,CAGW3C,kBACT,MAlDW,KAmDb,CAGAoT,OAEE,MAAMiY,EAAY9nB,KAAKoF,SAEvB,GAAIpF,KAAK+nB,cAAcD,GACrB,OAIF,MAAME,EAAShoB,KAAKioB,iBAEdC,EAAYF,EAASznB,GAAakB,QAAQumB,EAAQvB,GAAc,CACpE3mB,cAAegoB,IACZ,KACavnB,GAAakB,QAAQqmB,EAAWnB,GAAc,CAC9D7mB,cAAekoB,IAGHnmB,kBAAoBqmB,GAAaA,EAAUrmB,mBAIzD7B,KAAKmoB,YAAYH,EAAQF,GAEzB9nB,KAAKooB,UAAUN,EAAWE,GAC5B,CAGAI,UAAUpoC,EAASqoC,GACZroC,IAILA,EAAQwb,UAAUtE,IAAIkwB,IAEtBpnB,KAAKooB,UAAU9tB,GAAuBta,IAmBtCggB,KAAK2F,gBAhBY,KACsB,QAAjC3lB,EAAQga,aAAa,SAKzBha,EAAQ4B,gBAAgB,YACxB5B,EAAQ6B,aAAa,iBAAiB,GAEtCme,KAAKsoB,gBAAgBtoC,GAAS,GAE9BugB,GAAakB,QAAQzhB,EAAS4mC,GAAe,CAC3C9mB,cAAeuoB,KAVfroC,EAAQwb,UAAUtE,IAAIowB,GAWtB,GAG0BtnC,EAASA,EAAQwb,UAAUvW,SAASoiC,KACpE,CAEAc,YAAYnoC,EAASqoC,GACdroC,IAILA,EAAQwb,UAAUuH,OAAOqkB,IACzBpnC,EAAQ+6B,OAER/a,KAAKmoB,YAAY7tB,GAAuBta,IAmBxCggB,KAAK2F,gBAhBY,KACsB,QAAjC3lB,EAAQga,aAAa,SAKzBha,EAAQ6B,aAAa,iBAAiB,GACtC7B,EAAQ6B,aAAa,WAAY,MAEjCme,KAAKsoB,gBAAgBtoC,GAAS,GAE9BugB,GAAakB,QAAQzhB,EAAS0mC,GAAgB,CAC5C5mB,cAAeuoB,KAVfroC,EAAQwb,UAAUuH,OAAOukB,GAWzB,GAG0BtnC,EAASA,EAAQwb,UAAUvW,SAASoiC,KACpE,CAEAza,SAASxN,GACP,IAAK,CAAC4nB,GAAgBC,GAAiBC,GAAcC,IAAgBjtB,SAASkF,EAAM7hB,KAClF,OAGF6hB,EAAMyU,kBAENzU,EAAM+C,iBACN,MAAMoL,EAAS,CAAC0Z,GAAiBE,IAAgBjtB,SAASkF,EAAM7hB,KAC1DgrC,EAAoBzqB,GAAqBkC,KAAK6nB,eAAejhC,QAAO5G,IAAYqb,GAAWrb,KAAWof,EAAMpS,OAAQugB,GAAQ,GAE9Hgb,IACFA,EAAkB7V,MAAM,CACtB8V,eAAe,IAEjBb,GAAIthB,oBAAoBkiB,GAAmB1Y,OAE/C,CAEAgY,eAEE,OAAO5gB,GAAerU,KAAK60B,GAAqBznB,KAAKqS,QACvD,CAEA4V,iBACE,OAAOjoB,KAAK6nB,eAAej1B,MAAKzN,GAAS6a,KAAK+nB,cAAc5iC,MAAW,IACzE,CAEAyiC,sBAAsB1iC,EAAQiiB,GAC5BnH,KAAKyoB,yBAAyBvjC,EAAQ,OAAQ,WAE9C,IAAK,MAAMC,KAASgiB,EAClBnH,KAAK0oB,6BAA6BvjC,EAEtC,CAEAujC,6BAA6BvjC,GAC3BA,EAAQ6a,KAAK2oB,iBAAiBxjC,GAE9B,MAAMyjC,EAAW5oB,KAAK+nB,cAAc5iC,GAE9B0jC,EAAY7oB,KAAK8oB,iBAAiB3jC,GAExCA,EAAMtD,aAAa,gBAAiB+mC,GAEhCC,IAAc1jC,GAChB6a,KAAKyoB,yBAAyBI,EAAW,OAAQ,gBAG9CD,GACHzjC,EAAMtD,aAAa,WAAY,MAGjCme,KAAKyoB,yBAAyBtjC,EAAO,OAAQ,OAG7C6a,KAAK+oB,mCAAmC5jC,EAC1C,CAEA4jC,mCAAmC5jC,GACjC,MAAM6H,EAASsN,GAAuBnV,GAEjC6H,IAILgT,KAAKyoB,yBAAyBz7B,EAAQ,OAAQ,YAE1C7H,EAAMygC,IACR5lB,KAAKyoB,yBAAyBz7B,EAAQ,kBAAmB,IAAI7H,EAAMygC,MAEvE,CAEA0C,gBAAgBtoC,EAASgpC,GACvB,MAAMH,EAAY7oB,KAAK8oB,iBAAiB9oC,GAExC,IAAK6oC,EAAUrtB,UAAUvW,SAxMN,YAyMjB,OAGF,MAAM8hB,EAAS,CAAChN,EAAU2b,KACxB,MAAM11B,EAAUinB,GAAeC,QAAQnN,EAAU8uB,GAE7C7oC,GACFA,EAAQwb,UAAUuL,OAAO2O,EAAWsT,EACtC,EAGFjiB,EAnN6B,mBAmNIqgB,IACjCrgB,EAnN2B,iBAmNIugB,IAC/BuB,EAAUhnC,aAAa,gBAAiBmnC,EAC1C,CAEAP,yBAAyBzoC,EAASwC,EAAWpE,GACtC4B,EAAQ0b,aAAalZ,IACxBxC,EAAQ6B,aAAaW,EAAWpE,EAEpC,CAEA2pC,cAAczY,GACZ,OAAOA,EAAK9T,UAAUvW,SAASmiC,GACjC,CAGAuB,iBAAiBrZ,GACf,OAAOA,EAAKlI,QAAQqgB,IAAuBnY,EAAOrI,GAAeC,QAAQugB,GAAqBnY,EAChG,CAGAwZ,iBAAiBxZ,GACf,OAAOA,EAAKnU,QArOO,gCAqOoBmU,CACzC,CAGAzJ,uBAAuBxB,GACrB,OAAOrE,KAAK4G,MAAK,WACf,MAAM9b,EAAO68B,GAAIthB,oBAAoBrG,MAErC,GAAsB,iBAAXqE,EAAX,CAIA,QAAqB7K,IAAjB1O,EAAKuZ,IAAyBA,EAAOlK,WAAW,MAAmB,gBAAXkK,EAC1D,MAAM,IAAIW,UAAU,oBAAoBX,MAG1CvZ,EAAKuZ,IANL,CAOF,GACF,EAQF9D,GAAaY,GAAGrb,SAAU+gC,GAAsBW,IAAsB,SAAUpoB,GAC1E,CAAC,IAAK,QAAQlF,SAAS8F,KAAKoG,UAC9BhH,EAAM+C,iBAGJ9G,GAAW2E,OAIf2nB,GAAIthB,oBAAoBrG,MAAM6P,MAChC,IAKAtP,GAAaY,GAAG9gB,OAAQ0mC,IAAqB,KAC3C,IAAK,MAAM/mC,KAAWinB,GAAerU,KAAK80B,IACxCC,GAAIthB,oBAAoBrmB,EAC1B,IAMFqc,GAAmBsrB,IAYnB,MAEMniB,GAAY,YACZyjB,GAAkB,YAAYzjB,KAC9B0jB,GAAiB,WAAW1jB,KAC5B2jB,GAAgB,UAAU3jB,KAC1B4jB,GAAiB,WAAW5jB,KAC5B6jB,GAAa,OAAO7jB,KACpB8jB,GAAe,SAAS9jB,KACxB+jB,GAAa,OAAO/jB,KACpBgkB,GAAc,QAAQhkB,KAEtBikB,GAAkB,OAElBC,GAAkB,OAClBC,GAAqB,UACrBzlB,GAAc,CAClBkc,UAAW,UACXwJ,SAAU,UACVrJ,MAAO,UAEHtc,GAAU,CACdmc,WAAW,EACXwJ,UAAU,EACVrJ,MAAO,KAMT,MAAMsJ,WAAc3kB,GAClBR,YAAY1kB,EAASqkB,GACnBc,MAAMnlB,EAASqkB,GACfrE,KAAK4gB,SAAW,KAChB5gB,KAAK8pB,sBAAuB,EAC5B9pB,KAAK+pB,yBAA0B,EAE/B/pB,KAAKkhB,eACP,CAGWjd,qBACT,OAAOA,EACT,CAEWC,yBACT,OAAOA,EACT,CAEWzH,kBACT,MAlDS,OAmDX,CAGAoT,OACoBtP,GAAakB,QAAQzB,KAAKoF,SAAUmkB,IAExC1nB,mBAId7B,KAAKgqB,gBAEDhqB,KAAKqF,QAAQ+a,WACfpgB,KAAKoF,SAAS5J,UAAUtE,IArDN,QAgEpB8I,KAAKoF,SAAS5J,UAAUuH,OAAO0mB,IAG/B1tB,GAAOiE,KAAKoF,UAEZpF,KAAKoF,SAAS5J,UAAUtE,IAAIwyB,GAAiBC,IAE7C3pB,KAAK2F,gBAfY,KACf3F,KAAKoF,SAAS5J,UAAUuH,OAAO4mB,IAE/BppB,GAAakB,QAAQzB,KAAKoF,SAAUokB,IAEpCxpB,KAAKiqB,oBAAoB,GAUGjqB,KAAKoF,SAAUpF,KAAKqF,QAAQ+a,WAC5D,CAEAxQ,OACO5P,KAAKkqB,YAIQ3pB,GAAakB,QAAQzB,KAAKoF,SAAUikB,IAExCxnB,mBAad7B,KAAKoF,SAAS5J,UAAUtE,IAAIyyB,IAE5B3pB,KAAK2F,gBAXY,KACf3F,KAAKoF,SAAS5J,UAAUtE,IAAIuyB,IAG5BzpB,KAAKoF,SAAS5J,UAAUuH,OAAO4mB,GAAoBD,IAEnDnpB,GAAakB,QAAQzB,KAAKoF,SAAUkkB,GAAa,GAKrBtpB,KAAKoF,SAAUpF,KAAKqF,QAAQ+a,YAC5D,CAEA7a,UACEvF,KAAKgqB,gBAEDhqB,KAAKkqB,WACPlqB,KAAKoF,SAAS5J,UAAUuH,OAAO2mB,IAGjCvkB,MAAMI,SACR,CAEA2kB,UACE,OAAOlqB,KAAKoF,SAAS5J,UAAUvW,SAASykC,GAC1C,CAGAO,qBACOjqB,KAAKqF,QAAQukB,WAId5pB,KAAK8pB,sBAAwB9pB,KAAK+pB,0BAItC/pB,KAAK4gB,SAAW/iB,YAAW,KACzBmC,KAAK4P,MAAM,GACV5P,KAAKqF,QAAQkb,QAClB,CAEA4J,eAAe/qB,EAAOgrB,GACpB,OAAQhrB,EAAMqB,MACZ,IAAK,YACL,IAAK,WAEDT,KAAK8pB,qBAAuBM,EAC5B,MAGJ,IAAK,UACL,IAAK,WAEDpqB,KAAK+pB,wBAA0BK,EAKrC,GAAIA,EAGF,YAFApqB,KAAKgqB,gBAKP,MAAMxc,EAAcpO,EAAMU,cAEtBE,KAAKoF,WAAaoI,GAAexN,KAAKoF,SAASngB,SAASuoB,IAI5DxN,KAAKiqB,oBACP,CAEA/I,gBACE3gB,GAAaY,GAAGnB,KAAKoF,SAAU6jB,IAAiB7pB,GAASY,KAAKmqB,eAAe/qB,GAAO,KACpFmB,GAAaY,GAAGnB,KAAKoF,SAAU8jB,IAAgB9pB,GAASY,KAAKmqB,eAAe/qB,GAAO,KACnFmB,GAAaY,GAAGnB,KAAKoF,SAAU+jB,IAAe/pB,GAASY,KAAKmqB,eAAe/qB,GAAO,KAClFmB,GAAaY,GAAGnB,KAAKoF,SAAUgkB,IAAgBhqB,GAASY,KAAKmqB,eAAe/qB,GAAO,IACrF,CAEA4qB,gBACE/c,aAAajN,KAAK4gB,UAClB5gB,KAAK4gB,SAAW,IAClB,CAGA/a,uBAAuBxB,GACrB,OAAOrE,KAAK4G,MAAK,WACf,MAAM9b,EAAO++B,GAAMxjB,oBAAoBrG,KAAMqE,GAE7C,GAAsB,iBAAXA,EAAqB,CAC9B,QAA4B,IAAjBvZ,EAAKuZ,GACd,MAAM,IAAIW,UAAU,oBAAoBX,MAG1CvZ,EAAKuZ,GAAQrE,KACf,CACF,GACF,ECxjKK,IAAuBzD,GDgkK9ByJ,GAAqB6jB,IAKrBxtB,GAAmBwtB,ICrkKWttB,GCK9B,WAC2B,GAAG1J,MAAM5U,KAChC6H,SAASsa,iBAAiB,+BAET7c,KAAI,SAAU8mC,GAC/B,OAAO,IAAI3J,GAAQ2J,EAAkB,CAAE9J,MAAO,CAAE1Q,KAAM,IAAKD,KAAM,MACnE,GACF,EDX6B,WAAvB9pB,SAASgX,WAAyBP,KACjCzW,SAASyF,iBAAiB,mBAAoBgR","sources":["webpack://pydata_sphinx_theme/webpack/bootstrap","webpack://pydata_sphinx_theme/webpack/runtime/define property getters","webpack://pydata_sphinx_theme/webpack/runtime/hasOwnProperty shorthand","webpack://pydata_sphinx_theme/webpack/runtime/make namespace object","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/enums.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getNodeName.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/instanceOf.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/applyStyles.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getBasePlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/math.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/userAgent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/contains.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isTableElement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getParentNode.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/within.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/mergePaddingObject.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getFreshSideObject.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/expandToHashMap.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/arrow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getVariation.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/computeStyles.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/eventListeners.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getOppositePlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/rectToClientRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/computeOffsets.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/detectOverflow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/flip.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/hide.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/offset.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/popperOffsets.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/modifiers/preventOverflow.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/getAltAxis.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/orderModifiers.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/createPopper.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/debounce.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/utils/mergeByName.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/popper.js","webpack://pydata_sphinx_theme/./node_modules/@popperjs/core/lib/popper-lite.js","webpack://pydata_sphinx_theme/./node_modules/bootstrap/dist/js/bootstrap.esm.js","webpack://pydata_sphinx_theme/./src/pydata_sphinx_theme/assets/scripts/mixin.js","webpack://pydata_sphinx_theme/./src/pydata_sphinx_theme/assets/scripts/bootstrap.js"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export var top = 'top';\nexport var bottom = 'bottom';\nexport var right = 'right';\nexport var left = 'left';\nexport var auto = 'auto';\nexport var basePlacements = [top, bottom, right, left];\nexport var start = 'start';\nexport var end = 'end';\nexport var clippingParents = 'clippingParents';\nexport var viewport = 'viewport';\nexport var popper = 'popper';\nexport var reference = 'reference';\nexport var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {\n return acc.concat([placement + \"-\" + start, placement + \"-\" + end]);\n}, []);\nexport var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {\n return acc.concat([placement, placement + \"-\" + start, placement + \"-\" + end]);\n}, []); // modifiers that need to read the DOM\n\nexport var beforeRead = 'beforeRead';\nexport var read = 'read';\nexport var afterRead = 'afterRead'; // pure-logic modifiers\n\nexport var beforeMain = 'beforeMain';\nexport var main = 'main';\nexport var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)\n\nexport var beforeWrite = 'beforeWrite';\nexport var write = 'write';\nexport var afterWrite = 'afterWrite';\nexport var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];","export default function getNodeName(element) {\n return element ? (element.nodeName || '').toLowerCase() : null;\n}","export default function getWindow(node) {\n if (node == null) {\n return window;\n }\n\n if (node.toString() !== '[object Window]') {\n var ownerDocument = node.ownerDocument;\n return ownerDocument ? ownerDocument.defaultView || window : window;\n }\n\n return node;\n}","import getWindow from \"./getWindow.js\";\n\nfunction isElement(node) {\n var OwnElement = getWindow(node).Element;\n return node instanceof OwnElement || node instanceof Element;\n}\n\nfunction isHTMLElement(node) {\n var OwnElement = getWindow(node).HTMLElement;\n return node instanceof OwnElement || node instanceof HTMLElement;\n}\n\nfunction isShadowRoot(node) {\n // IE 11 has no ShadowRoot\n if (typeof ShadowRoot === 'undefined') {\n return false;\n }\n\n var OwnElement = getWindow(node).ShadowRoot;\n return node instanceof OwnElement || node instanceof ShadowRoot;\n}\n\nexport { isElement, isHTMLElement, isShadowRoot };","import getNodeName from \"../dom-utils/getNodeName.js\";\nimport { isHTMLElement } from \"../dom-utils/instanceOf.js\"; // This modifier takes the styles prepared by the `computeStyles` modifier\n// and applies them to the HTMLElements such as popper and arrow\n\nfunction applyStyles(_ref) {\n var state = _ref.state;\n Object.keys(state.elements).forEach(function (name) {\n var style = state.styles[name] || {};\n var attributes = state.attributes[name] || {};\n var element = state.elements[name]; // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n } // Flow doesn't support to extend this property, but it's the most\n // effective way to apply styles to an HTMLElement\n // $FlowFixMe[cannot-write]\n\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (name) {\n var value = attributes[name];\n\n if (value === false) {\n element.removeAttribute(name);\n } else {\n element.setAttribute(name, value === true ? '' : value);\n }\n });\n });\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state;\n var initialStyles = {\n popper: {\n position: state.options.strategy,\n left: '0',\n top: '0',\n margin: '0'\n },\n arrow: {\n position: 'absolute'\n },\n reference: {}\n };\n Object.assign(state.elements.popper.style, initialStyles.popper);\n state.styles = initialStyles;\n\n if (state.elements.arrow) {\n Object.assign(state.elements.arrow.style, initialStyles.arrow);\n }\n\n return function () {\n Object.keys(state.elements).forEach(function (name) {\n var element = state.elements[name];\n var attributes = state.attributes[name] || {};\n var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them\n\n var style = styleProperties.reduce(function (style, property) {\n style[property] = '';\n return style;\n }, {}); // arrow is optional + virtual elements\n\n if (!isHTMLElement(element) || !getNodeName(element)) {\n return;\n }\n\n Object.assign(element.style, style);\n Object.keys(attributes).forEach(function (attribute) {\n element.removeAttribute(attribute);\n });\n });\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'applyStyles',\n enabled: true,\n phase: 'write',\n fn: applyStyles,\n effect: effect,\n requires: ['computeStyles']\n};","import { auto } from \"../enums.js\";\nexport default function getBasePlacement(placement) {\n return placement.split('-')[0];\n}","export var max = Math.max;\nexport var min = Math.min;\nexport var round = Math.round;","export default function getUAString() {\n var uaData = navigator.userAgentData;\n\n if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {\n return uaData.brands.map(function (item) {\n return item.brand + \"/\" + item.version;\n }).join(' ');\n }\n\n return navigator.userAgent;\n}","import getUAString from \"../utils/userAgent.js\";\nexport default function isLayoutViewport() {\n return !/^((?!chrome|android).)*safari/i.test(getUAString());\n}","import { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport { round } from \"../utils/math.js\";\nimport getWindow from \"./getWindow.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getBoundingClientRect(element, includeScale, isFixedStrategy) {\n if (includeScale === void 0) {\n includeScale = false;\n }\n\n if (isFixedStrategy === void 0) {\n isFixedStrategy = false;\n }\n\n var clientRect = element.getBoundingClientRect();\n var scaleX = 1;\n var scaleY = 1;\n\n if (includeScale && isHTMLElement(element)) {\n scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;\n scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;\n }\n\n var _ref = isElement(element) ? getWindow(element) : window,\n visualViewport = _ref.visualViewport;\n\n var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;\n var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;\n var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;\n var width = clientRect.width / scaleX;\n var height = clientRect.height / scaleY;\n return {\n width: width,\n height: height,\n top: y,\n right: x + width,\n bottom: y + height,\n left: x,\n x: x,\n y: y\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\"; // Returns the layout rect of an element relative to its offsetParent. Layout\n// means it doesn't take into account transforms.\n\nexport default function getLayoutRect(element) {\n var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.\n // Fixes https://github.com/popperjs/popper-core/issues/1223\n\n var width = element.offsetWidth;\n var height = element.offsetHeight;\n\n if (Math.abs(clientRect.width - width) <= 1) {\n width = clientRect.width;\n }\n\n if (Math.abs(clientRect.height - height) <= 1) {\n height = clientRect.height;\n }\n\n return {\n x: element.offsetLeft,\n y: element.offsetTop,\n width: width,\n height: height\n };\n}","import { isShadowRoot } from \"./instanceOf.js\";\nexport default function contains(parent, child) {\n var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method\n\n if (parent.contains(child)) {\n return true;\n } // then fallback to custom implementation with Shadow DOM support\n else if (rootNode && isShadowRoot(rootNode)) {\n var next = child;\n\n do {\n if (next && parent.isSameNode(next)) {\n return true;\n } // $FlowFixMe[prop-missing]: need a better way to handle this...\n\n\n next = next.parentNode || next.host;\n } while (next);\n } // Give up, the result is false\n\n\n return false;\n}","import getWindow from \"./getWindow.js\";\nexport default function getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}","import getNodeName from \"./getNodeName.js\";\nexport default function isTableElement(element) {\n return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;\n}","import { isElement } from \"./instanceOf.js\";\nexport default function getDocumentElement(element) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]\n element.document) || window.document).documentElement;\n}","import getNodeName from \"./getNodeName.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport { isShadowRoot } from \"./instanceOf.js\";\nexport default function getParentNode(element) {\n if (getNodeName(element) === 'html') {\n return element;\n }\n\n return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle\n // $FlowFixMe[incompatible-return]\n // $FlowFixMe[prop-missing]\n element.assignedSlot || // step into the shadow DOM of the parent of a slotted node\n element.parentNode || ( // DOM Element detected\n isShadowRoot(element) ? element.host : null) || // ShadowRoot detected\n // $FlowFixMe[incompatible-call]: HTMLElement is a Node\n getDocumentElement(element) // fallback\n\n );\n}","import getWindow from \"./getWindow.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isHTMLElement, isShadowRoot } from \"./instanceOf.js\";\nimport isTableElement from \"./isTableElement.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getUAString from \"../utils/userAgent.js\";\n\nfunction getTrueOffsetParent(element) {\n if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837\n getComputedStyle(element).position === 'fixed') {\n return null;\n }\n\n return element.offsetParent;\n} // `.offsetParent` reports `null` for fixed elements, while absolute elements\n// return the containing block\n\n\nfunction getContainingBlock(element) {\n var isFirefox = /firefox/i.test(getUAString());\n var isIE = /Trident/i.test(getUAString());\n\n if (isIE && isHTMLElement(element)) {\n // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport\n var elementCss = getComputedStyle(element);\n\n if (elementCss.position === 'fixed') {\n return null;\n }\n }\n\n var currentNode = getParentNode(element);\n\n if (isShadowRoot(currentNode)) {\n currentNode = currentNode.host;\n }\n\n while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {\n var css = getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that\n // create a containing block.\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n\n if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {\n return currentNode;\n } else {\n currentNode = currentNode.parentNode;\n }\n }\n\n return null;\n} // Gets the closest ancestor positioned element. Handles some edge cases,\n// such as table ancestors and cross browser bugs.\n\n\nexport default function getOffsetParent(element) {\n var window = getWindow(element);\n var offsetParent = getTrueOffsetParent(element);\n\n while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === 'static') {\n offsetParent = getTrueOffsetParent(offsetParent);\n }\n\n if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle(offsetParent).position === 'static')) {\n return window;\n }\n\n return offsetParent || getContainingBlock(element) || window;\n}","export default function getMainAxisFromPlacement(placement) {\n return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';\n}","import { max as mathMax, min as mathMin } from \"./math.js\";\nexport function within(min, value, max) {\n return mathMax(min, mathMin(value, max));\n}\nexport function withinMaxClamp(min, value, max) {\n var v = within(min, value, max);\n return v > max ? max : v;\n}","import getFreshSideObject from \"./getFreshSideObject.js\";\nexport default function mergePaddingObject(paddingObject) {\n return Object.assign({}, getFreshSideObject(), paddingObject);\n}","export default function getFreshSideObject() {\n return {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n };\n}","export default function expandToHashMap(value, keys) {\n return keys.reduce(function (hashMap, key) {\n hashMap[key] = value;\n return hashMap;\n }, {});\n}","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport contains from \"../dom-utils/contains.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport { within } from \"../utils/within.js\";\nimport mergePaddingObject from \"../utils/mergePaddingObject.js\";\nimport expandToHashMap from \"../utils/expandToHashMap.js\";\nimport { left, right, basePlacements, top, bottom } from \"../enums.js\";\nimport { isHTMLElement } from \"../dom-utils/instanceOf.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar toPaddingObject = function toPaddingObject(padding, state) {\n padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {\n placement: state.placement\n })) : padding;\n return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n};\n\nfunction arrow(_ref) {\n var _state$modifiersData$;\n\n var state = _ref.state,\n name = _ref.name,\n options = _ref.options;\n var arrowElement = state.elements.arrow;\n var popperOffsets = state.modifiersData.popperOffsets;\n var basePlacement = getBasePlacement(state.placement);\n var axis = getMainAxisFromPlacement(basePlacement);\n var isVertical = [left, right].indexOf(basePlacement) >= 0;\n var len = isVertical ? 'height' : 'width';\n\n if (!arrowElement || !popperOffsets) {\n return;\n }\n\n var paddingObject = toPaddingObject(options.padding, state);\n var arrowRect = getLayoutRect(arrowElement);\n var minProp = axis === 'y' ? top : left;\n var maxProp = axis === 'y' ? bottom : right;\n var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];\n var startDiff = popperOffsets[axis] - state.rects.reference[axis];\n var arrowOffsetParent = getOffsetParent(arrowElement);\n var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;\n var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is\n // outside of the popper bounds\n\n var min = paddingObject[minProp];\n var max = clientSize - arrowRect[len] - paddingObject[maxProp];\n var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;\n var offset = within(min, center, max); // Prevents breaking syntax highlighting...\n\n var axisProp = axis;\n state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);\n}\n\nfunction effect(_ref2) {\n var state = _ref2.state,\n options = _ref2.options;\n var _options$element = options.element,\n arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;\n\n if (arrowElement == null) {\n return;\n } // CSS selector\n\n\n if (typeof arrowElement === 'string') {\n arrowElement = state.elements.popper.querySelector(arrowElement);\n\n if (!arrowElement) {\n return;\n }\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n if (!isHTMLElement(arrowElement)) {\n console.error(['Popper: \"arrow\" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' '));\n }\n }\n\n if (!contains(state.elements.popper, arrowElement)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(['Popper: \"arrow\" modifier\\'s `element` must be a child of the popper', 'element.'].join(' '));\n }\n\n return;\n }\n\n state.elements.arrow = arrowElement;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'arrow',\n enabled: true,\n phase: 'main',\n fn: arrow,\n effect: effect,\n requires: ['popperOffsets'],\n requiresIfExists: ['preventOverflow']\n};","export default function getVariation(placement) {\n return placement.split('-')[1];\n}","import { top, left, right, bottom, end } from \"../enums.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport getWindow from \"../dom-utils/getWindow.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getComputedStyle from \"../dom-utils/getComputedStyle.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport { round } from \"../utils/math.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar unsetSides = {\n top: 'auto',\n right: 'auto',\n bottom: 'auto',\n left: 'auto'\n}; // Round the offsets to the nearest suitable subpixel based on the DPR.\n// Zooming can change the DPR, but it seems to report a value that will\n// cleanly divide the values into the appropriate subpixels.\n\nfunction roundOffsetsByDPR(_ref, win) {\n var x = _ref.x,\n y = _ref.y;\n var dpr = win.devicePixelRatio || 1;\n return {\n x: round(x * dpr) / dpr || 0,\n y: round(y * dpr) / dpr || 0\n };\n}\n\nexport function mapToStyles(_ref2) {\n var _Object$assign2;\n\n var popper = _ref2.popper,\n popperRect = _ref2.popperRect,\n placement = _ref2.placement,\n variation = _ref2.variation,\n offsets = _ref2.offsets,\n position = _ref2.position,\n gpuAcceleration = _ref2.gpuAcceleration,\n adaptive = _ref2.adaptive,\n roundOffsets = _ref2.roundOffsets,\n isFixed = _ref2.isFixed;\n var _offsets$x = offsets.x,\n x = _offsets$x === void 0 ? 0 : _offsets$x,\n _offsets$y = offsets.y,\n y = _offsets$y === void 0 ? 0 : _offsets$y;\n\n var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({\n x: x,\n y: y\n }) : {\n x: x,\n y: y\n };\n\n x = _ref3.x;\n y = _ref3.y;\n var hasX = offsets.hasOwnProperty('x');\n var hasY = offsets.hasOwnProperty('y');\n var sideX = left;\n var sideY = top;\n var win = window;\n\n if (adaptive) {\n var offsetParent = getOffsetParent(popper);\n var heightProp = 'clientHeight';\n var widthProp = 'clientWidth';\n\n if (offsetParent === getWindow(popper)) {\n offsetParent = getDocumentElement(popper);\n\n if (getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {\n heightProp = 'scrollHeight';\n widthProp = 'scrollWidth';\n }\n } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it\n\n\n offsetParent = offsetParent;\n\n if (placement === top || (placement === left || placement === right) && variation === end) {\n sideY = bottom;\n var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]\n offsetParent[heightProp];\n y -= offsetY - popperRect.height;\n y *= gpuAcceleration ? 1 : -1;\n }\n\n if (placement === left || (placement === top || placement === bottom) && variation === end) {\n sideX = right;\n var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]\n offsetParent[widthProp];\n x -= offsetX - popperRect.width;\n x *= gpuAcceleration ? 1 : -1;\n }\n }\n\n var commonStyles = Object.assign({\n position: position\n }, adaptive && unsetSides);\n\n var _ref4 = roundOffsets === true ? roundOffsetsByDPR({\n x: x,\n y: y\n }, getWindow(popper)) : {\n x: x,\n y: y\n };\n\n x = _ref4.x;\n y = _ref4.y;\n\n if (gpuAcceleration) {\n var _Object$assign;\n\n return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? \"translate(\" + x + \"px, \" + y + \"px)\" : \"translate3d(\" + x + \"px, \" + y + \"px, 0)\", _Object$assign));\n }\n\n return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + \"px\" : '', _Object$assign2[sideX] = hasX ? x + \"px\" : '', _Object$assign2.transform = '', _Object$assign2));\n}\n\nfunction computeStyles(_ref5) {\n var state = _ref5.state,\n options = _ref5.options;\n var _options$gpuAccelerat = options.gpuAcceleration,\n gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,\n _options$adaptive = options.adaptive,\n adaptive = _options$adaptive === void 0 ? true : _options$adaptive,\n _options$roundOffsets = options.roundOffsets,\n roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;\n\n if (process.env.NODE_ENV !== \"production\") {\n var transitionProperty = getComputedStyle(state.elements.popper).transitionProperty || '';\n\n if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) {\n return transitionProperty.indexOf(property) >= 0;\n })) {\n console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: \"transform\", \"top\", \"right\", \"bottom\", \"left\".', '\\n\\n', 'Disable the \"computeStyles\" modifier\\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\\n\\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' '));\n }\n }\n\n var commonStyles = {\n placement: getBasePlacement(state.placement),\n variation: getVariation(state.placement),\n popper: state.elements.popper,\n popperRect: state.rects.popper,\n gpuAcceleration: gpuAcceleration,\n isFixed: state.options.strategy === 'fixed'\n };\n\n if (state.modifiersData.popperOffsets != null) {\n state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.popperOffsets,\n position: state.options.strategy,\n adaptive: adaptive,\n roundOffsets: roundOffsets\n })));\n }\n\n if (state.modifiersData.arrow != null) {\n state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {\n offsets: state.modifiersData.arrow,\n position: 'absolute',\n adaptive: false,\n roundOffsets: roundOffsets\n })));\n }\n\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-placement': state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'computeStyles',\n enabled: true,\n phase: 'beforeWrite',\n fn: computeStyles,\n data: {}\n};","import getWindow from \"../dom-utils/getWindow.js\"; // eslint-disable-next-line import/no-unused-modules\n\nvar passive = {\n passive: true\n};\n\nfunction effect(_ref) {\n var state = _ref.state,\n instance = _ref.instance,\n options = _ref.options;\n var _options$scroll = options.scroll,\n scroll = _options$scroll === void 0 ? true : _options$scroll,\n _options$resize = options.resize,\n resize = _options$resize === void 0 ? true : _options$resize;\n var window = getWindow(state.elements.popper);\n var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);\n\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.addEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.addEventListener('resize', instance.update, passive);\n }\n\n return function () {\n if (scroll) {\n scrollParents.forEach(function (scrollParent) {\n scrollParent.removeEventListener('scroll', instance.update, passive);\n });\n }\n\n if (resize) {\n window.removeEventListener('resize', instance.update, passive);\n }\n };\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'eventListeners',\n enabled: true,\n phase: 'write',\n fn: function fn() {},\n effect: effect,\n data: {}\n};","var hash = {\n left: 'right',\n right: 'left',\n bottom: 'top',\n top: 'bottom'\n};\nexport default function getOppositePlacement(placement) {\n return placement.replace(/left|right|bottom|top/g, function (matched) {\n return hash[matched];\n });\n}","var hash = {\n start: 'end',\n end: 'start'\n};\nexport default function getOppositeVariationPlacement(placement) {\n return placement.replace(/start|end/g, function (matched) {\n return hash[matched];\n });\n}","import getWindow from \"./getWindow.js\";\nexport default function getWindowScroll(node) {\n var win = getWindow(node);\n var scrollLeft = win.pageXOffset;\n var scrollTop = win.pageYOffset;\n return {\n scrollLeft: scrollLeft,\n scrollTop: scrollTop\n };\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nexport default function getWindowScrollBarX(element) {\n // If has a CSS width greater than the viewport, then this will be\n // incorrect for RTL.\n // Popper 1 is broken in this case and never had a bug report so let's assume\n // it's not an issue. I don't think anyone ever specifies width on \n // anyway.\n // Browsers where the left scrollbar doesn't cause an issue report `0` for\n // this (e.g. Edge 2019, IE11, Safari)\n return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;\n}","import getComputedStyle from \"./getComputedStyle.js\";\nexport default function isScrollParent(element) {\n // Firefox wants us to check `-x` and `-y` variations as well\n var _getComputedStyle = getComputedStyle(element),\n overflow = _getComputedStyle.overflow,\n overflowX = _getComputedStyle.overflowX,\n overflowY = _getComputedStyle.overflowY;\n\n return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);\n}","import getParentNode from \"./getParentNode.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nexport default function getScrollParent(node) {\n if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {\n // $FlowFixMe[incompatible-return]: assume body is always available\n return node.ownerDocument.body;\n }\n\n if (isHTMLElement(node) && isScrollParent(node)) {\n return node;\n }\n\n return getScrollParent(getParentNode(node));\n}","import getScrollParent from \"./getScrollParent.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport getWindow from \"./getWindow.js\";\nimport isScrollParent from \"./isScrollParent.js\";\n/*\ngiven a DOM element, return the list of all scroll parents, up the list of ancesors\nuntil we get to the top window object. This list is what we attach scroll listeners\nto, because if any of these parent elements scroll, we'll need to re-calculate the\nreference element's position.\n*/\n\nexport default function listScrollParents(element, list) {\n var _element$ownerDocumen;\n\n if (list === void 0) {\n list = [];\n }\n\n var scrollParent = getScrollParent(element);\n var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);\n var win = getWindow(scrollParent);\n var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;\n var updatedList = list.concat(target);\n return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here\n updatedList.concat(listScrollParents(getParentNode(target)));\n}","export default function rectToClientRect(rect) {\n return Object.assign({}, rect, {\n left: rect.x,\n top: rect.y,\n right: rect.x + rect.width,\n bottom: rect.y + rect.height\n });\n}","import { viewport } from \"../enums.js\";\nimport getViewportRect from \"./getViewportRect.js\";\nimport getDocumentRect from \"./getDocumentRect.js\";\nimport listScrollParents from \"./listScrollParents.js\";\nimport getOffsetParent from \"./getOffsetParent.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport { isElement, isHTMLElement } from \"./instanceOf.js\";\nimport getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getParentNode from \"./getParentNode.js\";\nimport contains from \"./contains.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport rectToClientRect from \"../utils/rectToClientRect.js\";\nimport { max, min } from \"../utils/math.js\";\n\nfunction getInnerBoundingClientRect(element, strategy) {\n var rect = getBoundingClientRect(element, false, strategy === 'fixed');\n rect.top = rect.top + element.clientTop;\n rect.left = rect.left + element.clientLeft;\n rect.bottom = rect.top + element.clientHeight;\n rect.right = rect.left + element.clientWidth;\n rect.width = element.clientWidth;\n rect.height = element.clientHeight;\n rect.x = rect.left;\n rect.y = rect.top;\n return rect;\n}\n\nfunction getClientRectFromMixedType(element, clippingParent, strategy) {\n return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));\n} // A \"clipping parent\" is an overflowable container with the characteristic of\n// clipping (or hiding) overflowing elements with a position different from\n// `initial`\n\n\nfunction getClippingParents(element) {\n var clippingParents = listScrollParents(getParentNode(element));\n var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle(element).position) >= 0;\n var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;\n\n if (!isElement(clipperElement)) {\n return [];\n } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414\n\n\n return clippingParents.filter(function (clippingParent) {\n return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';\n });\n} // Gets the maximum area that the element is visible in due to any number of\n// clipping parents\n\n\nexport default function getClippingRect(element, boundary, rootBoundary, strategy) {\n var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);\n var clippingParents = [].concat(mainClippingParents, [rootBoundary]);\n var firstClippingParent = clippingParents[0];\n var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {\n var rect = getClientRectFromMixedType(element, clippingParent, strategy);\n accRect.top = max(rect.top, accRect.top);\n accRect.right = min(rect.right, accRect.right);\n accRect.bottom = min(rect.bottom, accRect.bottom);\n accRect.left = max(rect.left, accRect.left);\n return accRect;\n }, getClientRectFromMixedType(element, firstClippingParent, strategy));\n clippingRect.width = clippingRect.right - clippingRect.left;\n clippingRect.height = clippingRect.bottom - clippingRect.top;\n clippingRect.x = clippingRect.left;\n clippingRect.y = clippingRect.top;\n return clippingRect;\n}","import getWindow from \"./getWindow.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport isLayoutViewport from \"./isLayoutViewport.js\";\nexport default function getViewportRect(element, strategy) {\n var win = getWindow(element);\n var html = getDocumentElement(element);\n var visualViewport = win.visualViewport;\n var width = html.clientWidth;\n var height = html.clientHeight;\n var x = 0;\n var y = 0;\n\n if (visualViewport) {\n width = visualViewport.width;\n height = visualViewport.height;\n var layoutViewport = isLayoutViewport();\n\n if (layoutViewport || !layoutViewport && strategy === 'fixed') {\n x = visualViewport.offsetLeft;\n y = visualViewport.offsetTop;\n }\n }\n\n return {\n width: width,\n height: height,\n x: x + getWindowScrollBarX(element),\n y: y\n };\n}","import getDocumentElement from \"./getDocumentElement.js\";\nimport getComputedStyle from \"./getComputedStyle.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getWindowScroll from \"./getWindowScroll.js\";\nimport { max } from \"../utils/math.js\"; // Gets the entire size of the scrollable document area, even extending outside\n// of the `` and `` rect bounds if horizontally scrollable\n\nexport default function getDocumentRect(element) {\n var _element$ownerDocumen;\n\n var html = getDocumentElement(element);\n var winScroll = getWindowScroll(element);\n var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;\n var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);\n var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);\n var x = -winScroll.scrollLeft + getWindowScrollBarX(element);\n var y = -winScroll.scrollTop;\n\n if (getComputedStyle(body || html).direction === 'rtl') {\n x += max(html.clientWidth, body ? body.clientWidth : 0) - width;\n }\n\n return {\n width: width,\n height: height,\n x: x,\n y: y\n };\n}","import getBasePlacement from \"./getBasePlacement.js\";\nimport getVariation from \"./getVariation.js\";\nimport getMainAxisFromPlacement from \"./getMainAxisFromPlacement.js\";\nimport { top, right, bottom, left, start, end } from \"../enums.js\";\nexport default function computeOffsets(_ref) {\n var reference = _ref.reference,\n element = _ref.element,\n placement = _ref.placement;\n var basePlacement = placement ? getBasePlacement(placement) : null;\n var variation = placement ? getVariation(placement) : null;\n var commonX = reference.x + reference.width / 2 - element.width / 2;\n var commonY = reference.y + reference.height / 2 - element.height / 2;\n var offsets;\n\n switch (basePlacement) {\n case top:\n offsets = {\n x: commonX,\n y: reference.y - element.height\n };\n break;\n\n case bottom:\n offsets = {\n x: commonX,\n y: reference.y + reference.height\n };\n break;\n\n case right:\n offsets = {\n x: reference.x + reference.width,\n y: commonY\n };\n break;\n\n case left:\n offsets = {\n x: reference.x - element.width,\n y: commonY\n };\n break;\n\n default:\n offsets = {\n x: reference.x,\n y: reference.y\n };\n }\n\n var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;\n\n if (mainAxis != null) {\n var len = mainAxis === 'y' ? 'height' : 'width';\n\n switch (variation) {\n case start:\n offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);\n break;\n\n case end:\n offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);\n break;\n\n default:\n }\n }\n\n return offsets;\n}","import getClippingRect from \"../dom-utils/getClippingRect.js\";\nimport getDocumentElement from \"../dom-utils/getDocumentElement.js\";\nimport getBoundingClientRect from \"../dom-utils/getBoundingClientRect.js\";\nimport computeOffsets from \"./computeOffsets.js\";\nimport rectToClientRect from \"./rectToClientRect.js\";\nimport { clippingParents, reference, popper, bottom, top, right, basePlacements, viewport } from \"../enums.js\";\nimport { isElement } from \"../dom-utils/instanceOf.js\";\nimport mergePaddingObject from \"./mergePaddingObject.js\";\nimport expandToHashMap from \"./expandToHashMap.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport default function detectOverflow(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n _options$placement = _options.placement,\n placement = _options$placement === void 0 ? state.placement : _options$placement,\n _options$strategy = _options.strategy,\n strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,\n _options$boundary = _options.boundary,\n boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,\n _options$rootBoundary = _options.rootBoundary,\n rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,\n _options$elementConte = _options.elementContext,\n elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,\n _options$altBoundary = _options.altBoundary,\n altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,\n _options$padding = _options.padding,\n padding = _options$padding === void 0 ? 0 : _options$padding;\n var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));\n var altContext = elementContext === popper ? reference : popper;\n var popperRect = state.rects.popper;\n var element = state.elements[altBoundary ? altContext : elementContext];\n var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);\n var referenceClientRect = getBoundingClientRect(state.elements.reference);\n var popperOffsets = computeOffsets({\n reference: referenceClientRect,\n element: popperRect,\n strategy: 'absolute',\n placement: placement\n });\n var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));\n var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect\n // 0 or negative = within the clipping rect\n\n var overflowOffsets = {\n top: clippingClientRect.top - elementClientRect.top + paddingObject.top,\n bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,\n left: clippingClientRect.left - elementClientRect.left + paddingObject.left,\n right: elementClientRect.right - clippingClientRect.right + paddingObject.right\n };\n var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element\n\n if (elementContext === popper && offsetData) {\n var offset = offsetData[placement];\n Object.keys(overflowOffsets).forEach(function (key) {\n var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;\n var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';\n overflowOffsets[key] += offset[axis] * multiply;\n });\n }\n\n return overflowOffsets;\n}","import getOppositePlacement from \"../utils/getOppositePlacement.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getOppositeVariationPlacement from \"../utils/getOppositeVariationPlacement.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport computeAutoPlacement from \"../utils/computeAutoPlacement.js\";\nimport { bottom, top, start, right, left, auto } from \"../enums.js\";\nimport getVariation from \"../utils/getVariation.js\"; // eslint-disable-next-line import/no-unused-modules\n\nfunction getExpandedFallbackPlacements(placement) {\n if (getBasePlacement(placement) === auto) {\n return [];\n }\n\n var oppositePlacement = getOppositePlacement(placement);\n return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];\n}\n\nfunction flip(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n\n if (state.modifiersData[name]._skip) {\n return;\n }\n\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,\n specifiedFallbackPlacements = options.fallbackPlacements,\n padding = options.padding,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n _options$flipVariatio = options.flipVariations,\n flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,\n allowedAutoPlacements = options.allowedAutoPlacements;\n var preferredPlacement = state.options.placement;\n var basePlacement = getBasePlacement(preferredPlacement);\n var isBasePlacement = basePlacement === preferredPlacement;\n var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));\n var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {\n return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n flipVariations: flipVariations,\n allowedAutoPlacements: allowedAutoPlacements\n }) : placement);\n }, []);\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var checksMap = new Map();\n var makeFallbackChecks = true;\n var firstFittingPlacement = placements[0];\n\n for (var i = 0; i < placements.length; i++) {\n var placement = placements[i];\n\n var _basePlacement = getBasePlacement(placement);\n\n var isStartVariation = getVariation(placement) === start;\n var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;\n var len = isVertical ? 'width' : 'height';\n var overflow = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n altBoundary: altBoundary,\n padding: padding\n });\n var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;\n\n if (referenceRect[len] > popperRect[len]) {\n mainVariationSide = getOppositePlacement(mainVariationSide);\n }\n\n var altVariationSide = getOppositePlacement(mainVariationSide);\n var checks = [];\n\n if (checkMainAxis) {\n checks.push(overflow[_basePlacement] <= 0);\n }\n\n if (checkAltAxis) {\n checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);\n }\n\n if (checks.every(function (check) {\n return check;\n })) {\n firstFittingPlacement = placement;\n makeFallbackChecks = false;\n break;\n }\n\n checksMap.set(placement, checks);\n }\n\n if (makeFallbackChecks) {\n // `2` may be desired in some cases – research later\n var numberOfChecks = flipVariations ? 3 : 1;\n\n var _loop = function _loop(_i) {\n var fittingPlacement = placements.find(function (placement) {\n var checks = checksMap.get(placement);\n\n if (checks) {\n return checks.slice(0, _i).every(function (check) {\n return check;\n });\n }\n });\n\n if (fittingPlacement) {\n firstFittingPlacement = fittingPlacement;\n return \"break\";\n }\n };\n\n for (var _i = numberOfChecks; _i > 0; _i--) {\n var _ret = _loop(_i);\n\n if (_ret === \"break\") break;\n }\n }\n\n if (state.placement !== firstFittingPlacement) {\n state.modifiersData[name]._skip = true;\n state.placement = firstFittingPlacement;\n state.reset = true;\n }\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'flip',\n enabled: true,\n phase: 'main',\n fn: flip,\n requiresIfExists: ['offset'],\n data: {\n _skip: false\n }\n};","import getVariation from \"./getVariation.js\";\nimport { variationPlacements, basePlacements, placements as allPlacements } from \"../enums.js\";\nimport detectOverflow from \"./detectOverflow.js\";\nimport getBasePlacement from \"./getBasePlacement.js\";\nexport default function computeAutoPlacement(state, options) {\n if (options === void 0) {\n options = {};\n }\n\n var _options = options,\n placement = _options.placement,\n boundary = _options.boundary,\n rootBoundary = _options.rootBoundary,\n padding = _options.padding,\n flipVariations = _options.flipVariations,\n _options$allowedAutoP = _options.allowedAutoPlacements,\n allowedAutoPlacements = _options$allowedAutoP === void 0 ? allPlacements : _options$allowedAutoP;\n var variation = getVariation(placement);\n var placements = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {\n return getVariation(placement) === variation;\n }) : basePlacements;\n var allowedPlacements = placements.filter(function (placement) {\n return allowedAutoPlacements.indexOf(placement) >= 0;\n });\n\n if (allowedPlacements.length === 0) {\n allowedPlacements = placements;\n\n if (process.env.NODE_ENV !== \"production\") {\n console.error(['Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, \"auto\" cannot be used to allow \"bottom-start\".', 'Use \"auto-start\" instead.'].join(' '));\n }\n } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...\n\n\n var overflows = allowedPlacements.reduce(function (acc, placement) {\n acc[placement] = detectOverflow(state, {\n placement: placement,\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding\n })[getBasePlacement(placement)];\n return acc;\n }, {});\n return Object.keys(overflows).sort(function (a, b) {\n return overflows[a] - overflows[b];\n });\n}","import { top, bottom, left, right } from \"../enums.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\n\nfunction getSideOffsets(overflow, rect, preventedOffsets) {\n if (preventedOffsets === void 0) {\n preventedOffsets = {\n x: 0,\n y: 0\n };\n }\n\n return {\n top: overflow.top - rect.height - preventedOffsets.y,\n right: overflow.right - rect.width + preventedOffsets.x,\n bottom: overflow.bottom - rect.height + preventedOffsets.y,\n left: overflow.left - rect.width - preventedOffsets.x\n };\n}\n\nfunction isAnySideFullyClipped(overflow) {\n return [top, right, bottom, left].some(function (side) {\n return overflow[side] >= 0;\n });\n}\n\nfunction hide(_ref) {\n var state = _ref.state,\n name = _ref.name;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var preventedOffsets = state.modifiersData.preventOverflow;\n var referenceOverflow = detectOverflow(state, {\n elementContext: 'reference'\n });\n var popperAltOverflow = detectOverflow(state, {\n altBoundary: true\n });\n var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);\n var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);\n var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);\n var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);\n state.modifiersData[name] = {\n referenceClippingOffsets: referenceClippingOffsets,\n popperEscapeOffsets: popperEscapeOffsets,\n isReferenceHidden: isReferenceHidden,\n hasPopperEscaped: hasPopperEscaped\n };\n state.attributes.popper = Object.assign({}, state.attributes.popper, {\n 'data-popper-reference-hidden': isReferenceHidden,\n 'data-popper-escaped': hasPopperEscaped\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'hide',\n enabled: true,\n phase: 'main',\n requiresIfExists: ['preventOverflow'],\n fn: hide\n};","import getBasePlacement from \"../utils/getBasePlacement.js\";\nimport { top, left, right, placements } from \"../enums.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport function distanceAndSkiddingToXY(placement, rects, offset) {\n var basePlacement = getBasePlacement(placement);\n var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;\n\n var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {\n placement: placement\n })) : offset,\n skidding = _ref[0],\n distance = _ref[1];\n\n skidding = skidding || 0;\n distance = (distance || 0) * invertDistance;\n return [left, right].indexOf(basePlacement) >= 0 ? {\n x: distance,\n y: skidding\n } : {\n x: skidding,\n y: distance\n };\n}\n\nfunction offset(_ref2) {\n var state = _ref2.state,\n options = _ref2.options,\n name = _ref2.name;\n var _options$offset = options.offset,\n offset = _options$offset === void 0 ? [0, 0] : _options$offset;\n var data = placements.reduce(function (acc, placement) {\n acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);\n return acc;\n }, {});\n var _data$state$placement = data[state.placement],\n x = _data$state$placement.x,\n y = _data$state$placement.y;\n\n if (state.modifiersData.popperOffsets != null) {\n state.modifiersData.popperOffsets.x += x;\n state.modifiersData.popperOffsets.y += y;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'offset',\n enabled: true,\n phase: 'main',\n requires: ['popperOffsets'],\n fn: offset\n};","import computeOffsets from \"../utils/computeOffsets.js\";\n\nfunction popperOffsets(_ref) {\n var state = _ref.state,\n name = _ref.name;\n // Offsets are the actual position the popper needs to have to be\n // properly positioned near its reference element\n // This is the most basic placement, and will be adjusted by\n // the modifiers in the next step\n state.modifiersData[name] = computeOffsets({\n reference: state.rects.reference,\n element: state.rects.popper,\n strategy: 'absolute',\n placement: state.placement\n });\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'popperOffsets',\n enabled: true,\n phase: 'read',\n fn: popperOffsets,\n data: {}\n};","import { top, left, right, bottom, start } from \"../enums.js\";\nimport getBasePlacement from \"../utils/getBasePlacement.js\";\nimport getMainAxisFromPlacement from \"../utils/getMainAxisFromPlacement.js\";\nimport getAltAxis from \"../utils/getAltAxis.js\";\nimport { within, withinMaxClamp } from \"../utils/within.js\";\nimport getLayoutRect from \"../dom-utils/getLayoutRect.js\";\nimport getOffsetParent from \"../dom-utils/getOffsetParent.js\";\nimport detectOverflow from \"../utils/detectOverflow.js\";\nimport getVariation from \"../utils/getVariation.js\";\nimport getFreshSideObject from \"../utils/getFreshSideObject.js\";\nimport { min as mathMin, max as mathMax } from \"../utils/math.js\";\n\nfunction preventOverflow(_ref) {\n var state = _ref.state,\n options = _ref.options,\n name = _ref.name;\n var _options$mainAxis = options.mainAxis,\n checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,\n _options$altAxis = options.altAxis,\n checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,\n boundary = options.boundary,\n rootBoundary = options.rootBoundary,\n altBoundary = options.altBoundary,\n padding = options.padding,\n _options$tether = options.tether,\n tether = _options$tether === void 0 ? true : _options$tether,\n _options$tetherOffset = options.tetherOffset,\n tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;\n var overflow = detectOverflow(state, {\n boundary: boundary,\n rootBoundary: rootBoundary,\n padding: padding,\n altBoundary: altBoundary\n });\n var basePlacement = getBasePlacement(state.placement);\n var variation = getVariation(state.placement);\n var isBasePlacement = !variation;\n var mainAxis = getMainAxisFromPlacement(basePlacement);\n var altAxis = getAltAxis(mainAxis);\n var popperOffsets = state.modifiersData.popperOffsets;\n var referenceRect = state.rects.reference;\n var popperRect = state.rects.popper;\n var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {\n placement: state.placement\n })) : tetherOffset;\n var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {\n mainAxis: tetherOffsetValue,\n altAxis: tetherOffsetValue\n } : Object.assign({\n mainAxis: 0,\n altAxis: 0\n }, tetherOffsetValue);\n var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;\n var data = {\n x: 0,\n y: 0\n };\n\n if (!popperOffsets) {\n return;\n }\n\n if (checkMainAxis) {\n var _offsetModifierState$;\n\n var mainSide = mainAxis === 'y' ? top : left;\n var altSide = mainAxis === 'y' ? bottom : right;\n var len = mainAxis === 'y' ? 'height' : 'width';\n var offset = popperOffsets[mainAxis];\n var min = offset + overflow[mainSide];\n var max = offset - overflow[altSide];\n var additive = tether ? -popperRect[len] / 2 : 0;\n var minLen = variation === start ? referenceRect[len] : popperRect[len];\n var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go\n // outside the reference bounds\n\n var arrowElement = state.elements.arrow;\n var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {\n width: 0,\n height: 0\n };\n var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();\n var arrowPaddingMin = arrowPaddingObject[mainSide];\n var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want\n // to include its full size in the calculation. If the reference is small\n // and near the edge of a boundary, the popper can overflow even if the\n // reference is not overflowing as well (e.g. virtual elements with no\n // width or height)\n\n var arrowLen = within(0, referenceRect[len], arrowRect[len]);\n var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;\n var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;\n var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);\n var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;\n var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;\n var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;\n var tetherMax = offset + maxOffset - offsetModifierValue;\n var preventedOffset = within(tether ? mathMin(min, tetherMin) : min, offset, tether ? mathMax(max, tetherMax) : max);\n popperOffsets[mainAxis] = preventedOffset;\n data[mainAxis] = preventedOffset - offset;\n }\n\n if (checkAltAxis) {\n var _offsetModifierState$2;\n\n var _mainSide = mainAxis === 'x' ? top : left;\n\n var _altSide = mainAxis === 'x' ? bottom : right;\n\n var _offset = popperOffsets[altAxis];\n\n var _len = altAxis === 'y' ? 'height' : 'width';\n\n var _min = _offset + overflow[_mainSide];\n\n var _max = _offset - overflow[_altSide];\n\n var isOriginSide = [top, left].indexOf(basePlacement) !== -1;\n\n var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;\n\n var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;\n\n var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;\n\n var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);\n\n popperOffsets[altAxis] = _preventedOffset;\n data[altAxis] = _preventedOffset - _offset;\n }\n\n state.modifiersData[name] = data;\n} // eslint-disable-next-line import/no-unused-modules\n\n\nexport default {\n name: 'preventOverflow',\n enabled: true,\n phase: 'main',\n fn: preventOverflow,\n requiresIfExists: ['offset']\n};","export default function getAltAxis(axis) {\n return axis === 'x' ? 'y' : 'x';\n}","import getBoundingClientRect from \"./getBoundingClientRect.js\";\nimport getNodeScroll from \"./getNodeScroll.js\";\nimport getNodeName from \"./getNodeName.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getWindowScrollBarX from \"./getWindowScrollBarX.js\";\nimport getDocumentElement from \"./getDocumentElement.js\";\nimport isScrollParent from \"./isScrollParent.js\";\nimport { round } from \"../utils/math.js\";\n\nfunction isElementScaled(element) {\n var rect = element.getBoundingClientRect();\n var scaleX = round(rect.width) / element.offsetWidth || 1;\n var scaleY = round(rect.height) / element.offsetHeight || 1;\n return scaleX !== 1 || scaleY !== 1;\n} // Returns the composite rect of an element relative to its offsetParent.\n// Composite means it takes into account transforms as well as layout.\n\n\nexport default function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {\n if (isFixed === void 0) {\n isFixed = false;\n }\n\n var isOffsetParentAnElement = isHTMLElement(offsetParent);\n var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);\n var documentElement = getDocumentElement(offsetParent);\n var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);\n var scroll = {\n scrollLeft: 0,\n scrollTop: 0\n };\n var offsets = {\n x: 0,\n y: 0\n };\n\n if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078\n isScrollParent(documentElement)) {\n scroll = getNodeScroll(offsetParent);\n }\n\n if (isHTMLElement(offsetParent)) {\n offsets = getBoundingClientRect(offsetParent, true);\n offsets.x += offsetParent.clientLeft;\n offsets.y += offsetParent.clientTop;\n } else if (documentElement) {\n offsets.x = getWindowScrollBarX(documentElement);\n }\n }\n\n return {\n x: rect.left + scroll.scrollLeft - offsets.x,\n y: rect.top + scroll.scrollTop - offsets.y,\n width: rect.width,\n height: rect.height\n };\n}","import getWindowScroll from \"./getWindowScroll.js\";\nimport getWindow from \"./getWindow.js\";\nimport { isHTMLElement } from \"./instanceOf.js\";\nimport getHTMLElementScroll from \"./getHTMLElementScroll.js\";\nexport default function getNodeScroll(node) {\n if (node === getWindow(node) || !isHTMLElement(node)) {\n return getWindowScroll(node);\n } else {\n return getHTMLElementScroll(node);\n }\n}","export default function getHTMLElementScroll(element) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n}","import { modifierPhases } from \"../enums.js\"; // source: https://stackoverflow.com/questions/49875255\n\nfunction order(modifiers) {\n var map = new Map();\n var visited = new Set();\n var result = [];\n modifiers.forEach(function (modifier) {\n map.set(modifier.name, modifier);\n }); // On visiting object, check for its dependencies and visit them recursively\n\n function sort(modifier) {\n visited.add(modifier.name);\n var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);\n requires.forEach(function (dep) {\n if (!visited.has(dep)) {\n var depModifier = map.get(dep);\n\n if (depModifier) {\n sort(depModifier);\n }\n }\n });\n result.push(modifier);\n }\n\n modifiers.forEach(function (modifier) {\n if (!visited.has(modifier.name)) {\n // check for visited object\n sort(modifier);\n }\n });\n return result;\n}\n\nexport default function orderModifiers(modifiers) {\n // order based on dependencies\n var orderedModifiers = order(modifiers); // order based on phase\n\n return modifierPhases.reduce(function (acc, phase) {\n return acc.concat(orderedModifiers.filter(function (modifier) {\n return modifier.phase === phase;\n }));\n }, []);\n}","import getCompositeRect from \"./dom-utils/getCompositeRect.js\";\nimport getLayoutRect from \"./dom-utils/getLayoutRect.js\";\nimport listScrollParents from \"./dom-utils/listScrollParents.js\";\nimport getOffsetParent from \"./dom-utils/getOffsetParent.js\";\nimport getComputedStyle from \"./dom-utils/getComputedStyle.js\";\nimport orderModifiers from \"./utils/orderModifiers.js\";\nimport debounce from \"./utils/debounce.js\";\nimport validateModifiers from \"./utils/validateModifiers.js\";\nimport uniqueBy from \"./utils/uniqueBy.js\";\nimport getBasePlacement from \"./utils/getBasePlacement.js\";\nimport mergeByName from \"./utils/mergeByName.js\";\nimport detectOverflow from \"./utils/detectOverflow.js\";\nimport { isElement } from \"./dom-utils/instanceOf.js\";\nimport { auto } from \"./enums.js\";\nvar INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.';\nvar INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.';\nvar DEFAULT_OPTIONS = {\n placement: 'bottom',\n modifiers: [],\n strategy: 'absolute'\n};\n\nfunction areValidElements() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return !args.some(function (element) {\n return !(element && typeof element.getBoundingClientRect === 'function');\n });\n}\n\nexport function popperGenerator(generatorOptions) {\n if (generatorOptions === void 0) {\n generatorOptions = {};\n }\n\n var _generatorOptions = generatorOptions,\n _generatorOptions$def = _generatorOptions.defaultModifiers,\n defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,\n _generatorOptions$def2 = _generatorOptions.defaultOptions,\n defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;\n return function createPopper(reference, popper, options) {\n if (options === void 0) {\n options = defaultOptions;\n }\n\n var state = {\n placement: 'bottom',\n orderedModifiers: [],\n options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),\n modifiersData: {},\n elements: {\n reference: reference,\n popper: popper\n },\n attributes: {},\n styles: {}\n };\n var effectCleanupFns = [];\n var isDestroyed = false;\n var instance = {\n state: state,\n setOptions: function setOptions(setOptionsAction) {\n var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;\n cleanupModifierEffects();\n state.options = Object.assign({}, defaultOptions, state.options, options);\n state.scrollParents = {\n reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],\n popper: listScrollParents(popper)\n }; // Orders the modifiers based on their dependencies and `phase`\n // properties\n\n var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers\n\n state.orderedModifiers = orderedModifiers.filter(function (m) {\n return m.enabled;\n }); // Validate the provided modifiers so that the consumer will get warned\n // if one of the modifiers is invalid for any reason\n\n if (process.env.NODE_ENV !== \"production\") {\n var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function (_ref) {\n var name = _ref.name;\n return name;\n });\n validateModifiers(modifiers);\n\n if (getBasePlacement(state.options.placement) === auto) {\n var flipModifier = state.orderedModifiers.find(function (_ref2) {\n var name = _ref2.name;\n return name === 'flip';\n });\n\n if (!flipModifier) {\n console.error(['Popper: \"auto\" placements require the \"flip\" modifier be', 'present and enabled to work.'].join(' '));\n }\n }\n\n var _getComputedStyle = getComputedStyle(popper),\n marginTop = _getComputedStyle.marginTop,\n marginRight = _getComputedStyle.marginRight,\n marginBottom = _getComputedStyle.marginBottom,\n marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can\n // cause bugs with positioning, so we'll warn the consumer\n\n\n if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) {\n return parseFloat(margin);\n })) {\n console.warn(['Popper: CSS \"margin\" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' '));\n }\n }\n\n runModifierEffects();\n return instance.update();\n },\n // Sync update – it will always be executed, even if not necessary. This\n // is useful for low frequency updates where sync behavior simplifies the\n // logic.\n // For high frequency updates (e.g. `resize` and `scroll` events), always\n // prefer the async Popper#update method\n forceUpdate: function forceUpdate() {\n if (isDestroyed) {\n return;\n }\n\n var _state$elements = state.elements,\n reference = _state$elements.reference,\n popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements\n // anymore\n\n if (!areValidElements(reference, popper)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(INVALID_ELEMENT_ERROR);\n }\n\n return;\n } // Store the reference and popper rects to be read by modifiers\n\n\n state.rects = {\n reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),\n popper: getLayoutRect(popper)\n }; // Modifiers have the ability to reset the current update cycle. The\n // most common use case for this is the `flip` modifier changing the\n // placement, which then needs to re-run all the modifiers, because the\n // logic was previously ran for the previous placement and is therefore\n // stale/incorrect\n\n state.reset = false;\n state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier\n // is filled with the initial data specified by the modifier. This means\n // it doesn't persist and is fresh on each update.\n // To ensure persistent data, use `${name}#persistent`\n\n state.orderedModifiers.forEach(function (modifier) {\n return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);\n });\n var __debug_loops__ = 0;\n\n for (var index = 0; index < state.orderedModifiers.length; index++) {\n if (process.env.NODE_ENV !== \"production\") {\n __debug_loops__ += 1;\n\n if (__debug_loops__ > 100) {\n console.error(INFINITE_LOOP_ERROR);\n break;\n }\n }\n\n if (state.reset === true) {\n state.reset = false;\n index = -1;\n continue;\n }\n\n var _state$orderedModifie = state.orderedModifiers[index],\n fn = _state$orderedModifie.fn,\n _state$orderedModifie2 = _state$orderedModifie.options,\n _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,\n name = _state$orderedModifie.name;\n\n if (typeof fn === 'function') {\n state = fn({\n state: state,\n options: _options,\n name: name,\n instance: instance\n }) || state;\n }\n }\n },\n // Async and optimistically optimized update – it will not be executed if\n // not necessary (debounced to run at most once-per-tick)\n update: debounce(function () {\n return new Promise(function (resolve) {\n instance.forceUpdate();\n resolve(state);\n });\n }),\n destroy: function destroy() {\n cleanupModifierEffects();\n isDestroyed = true;\n }\n };\n\n if (!areValidElements(reference, popper)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.error(INVALID_ELEMENT_ERROR);\n }\n\n return instance;\n }\n\n instance.setOptions(options).then(function (state) {\n if (!isDestroyed && options.onFirstUpdate) {\n options.onFirstUpdate(state);\n }\n }); // Modifiers have the ability to execute arbitrary code before the first\n // update cycle runs. They will be executed in the same order as the update\n // cycle. This is useful when a modifier adds some persistent data that\n // other modifiers need to use, but the modifier is run after the dependent\n // one.\n\n function runModifierEffects() {\n state.orderedModifiers.forEach(function (_ref3) {\n var name = _ref3.name,\n _ref3$options = _ref3.options,\n options = _ref3$options === void 0 ? {} : _ref3$options,\n effect = _ref3.effect;\n\n if (typeof effect === 'function') {\n var cleanupFn = effect({\n state: state,\n name: name,\n instance: instance,\n options: options\n });\n\n var noopFn = function noopFn() {};\n\n effectCleanupFns.push(cleanupFn || noopFn);\n }\n });\n }\n\n function cleanupModifierEffects() {\n effectCleanupFns.forEach(function (fn) {\n return fn();\n });\n effectCleanupFns = [];\n }\n\n return instance;\n };\n}\nexport var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules\n\nexport { detectOverflow };","export default function debounce(fn) {\n var pending;\n return function () {\n if (!pending) {\n pending = new Promise(function (resolve) {\n Promise.resolve().then(function () {\n pending = undefined;\n resolve(fn());\n });\n });\n }\n\n return pending;\n };\n}","export default function mergeByName(modifiers) {\n var merged = modifiers.reduce(function (merged, current) {\n var existing = merged[current.name];\n merged[current.name] = existing ? Object.assign({}, existing, current, {\n options: Object.assign({}, existing.options, current.options),\n data: Object.assign({}, existing.data, current.data)\n }) : current;\n return merged;\n }, {}); // IE11 does not support Object.values\n\n return Object.keys(merged).map(function (key) {\n return merged[key];\n });\n}","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nimport offset from \"./modifiers/offset.js\";\nimport flip from \"./modifiers/flip.js\";\nimport preventOverflow from \"./modifiers/preventOverflow.js\";\nimport arrow from \"./modifiers/arrow.js\";\nimport hide from \"./modifiers/hide.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles, offset, flip, preventOverflow, arrow, hide];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow }; // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper as createPopperLite } from \"./popper-lite.js\"; // eslint-disable-next-line import/no-unused-modules\n\nexport * from \"./modifiers/index.js\";","import { popperGenerator, detectOverflow } from \"./createPopper.js\";\nimport eventListeners from \"./modifiers/eventListeners.js\";\nimport popperOffsets from \"./modifiers/popperOffsets.js\";\nimport computeStyles from \"./modifiers/computeStyles.js\";\nimport applyStyles from \"./modifiers/applyStyles.js\";\nvar defaultModifiers = [eventListeners, popperOffsets, computeStyles, applyStyles];\nvar createPopper = /*#__PURE__*/popperGenerator({\n defaultModifiers: defaultModifiers\n}); // eslint-disable-next-line import/no-unused-modules\n\nexport { createPopper, popperGenerator, defaultModifiers, detectOverflow };","/*!\n * Bootstrap v5.2.3 (https://getbootstrap.com/)\n * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\nimport * as Popper from '@popperjs/core';\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\nconst MAX_UID = 1000000;\nconst MILLISECONDS_MULTIPLIER = 1000;\nconst TRANSITION_END = 'transitionend'; // Shout-out Angus Croll (https://goo.gl/pxwQGp)\n\nconst toType = object => {\n if (object === null || object === undefined) {\n return `${object}`;\n }\n\n return Object.prototype.toString.call(object).match(/\\s([a-z]+)/i)[1].toLowerCase();\n};\n/**\n * Public Util API\n */\n\n\nconst getUID = prefix => {\n do {\n prefix += Math.floor(Math.random() * MAX_UID);\n } while (document.getElementById(prefix));\n\n return prefix;\n};\n\nconst getSelector = element => {\n let selector = element.getAttribute('data-bs-target');\n\n if (!selector || selector === '#') {\n let hrefAttribute = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,\n // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n // `document.querySelector` will rightfully complain it is invalid.\n // See https://github.com/twbs/bootstrap/issues/32273\n\n if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {\n return null;\n } // Just in case some CMS puts out a full URL with the anchor appended\n\n\n if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {\n hrefAttribute = `#${hrefAttribute.split('#')[1]}`;\n }\n\n selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null;\n }\n\n return selector;\n};\n\nconst getSelectorFromElement = element => {\n const selector = getSelector(element);\n\n if (selector) {\n return document.querySelector(selector) ? selector : null;\n }\n\n return null;\n};\n\nconst getElementFromSelector = element => {\n const selector = getSelector(element);\n return selector ? document.querySelector(selector) : null;\n};\n\nconst getTransitionDurationFromElement = element => {\n if (!element) {\n return 0;\n } // Get transition-duration of the element\n\n\n let {\n transitionDuration,\n transitionDelay\n } = window.getComputedStyle(element);\n const floatTransitionDuration = Number.parseFloat(transitionDuration);\n const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found\n\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0;\n } // If multiple durations are defined, take the first\n\n\n transitionDuration = transitionDuration.split(',')[0];\n transitionDelay = transitionDelay.split(',')[0];\n return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;\n};\n\nconst triggerTransitionEnd = element => {\n element.dispatchEvent(new Event(TRANSITION_END));\n};\n\nconst isElement = object => {\n if (!object || typeof object !== 'object') {\n return false;\n }\n\n if (typeof object.jquery !== 'undefined') {\n object = object[0];\n }\n\n return typeof object.nodeType !== 'undefined';\n};\n\nconst getElement = object => {\n // it's a jQuery object or a node element\n if (isElement(object)) {\n return object.jquery ? object[0] : object;\n }\n\n if (typeof object === 'string' && object.length > 0) {\n return document.querySelector(object);\n }\n\n return null;\n};\n\nconst isVisible = element => {\n if (!isElement(element) || element.getClientRects().length === 0) {\n return false;\n }\n\n const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'; // Handle `details` element as its content may falsie appear visible when it is closed\n\n const closedDetails = element.closest('details:not([open])');\n\n if (!closedDetails) {\n return elementIsVisible;\n }\n\n if (closedDetails !== element) {\n const summary = element.closest('summary');\n\n if (summary && summary.parentNode !== closedDetails) {\n return false;\n }\n\n if (summary === null) {\n return false;\n }\n }\n\n return elementIsVisible;\n};\n\nconst isDisabled = element => {\n if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n return true;\n }\n\n if (element.classList.contains('disabled')) {\n return true;\n }\n\n if (typeof element.disabled !== 'undefined') {\n return element.disabled;\n }\n\n return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';\n};\n\nconst findShadowRoot = element => {\n if (!document.documentElement.attachShadow) {\n return null;\n } // Can find the shadow root otherwise it'll return the document\n\n\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode();\n return root instanceof ShadowRoot ? root : null;\n }\n\n if (element instanceof ShadowRoot) {\n return element;\n } // when we don't find a shadow root\n\n\n if (!element.parentNode) {\n return null;\n }\n\n return findShadowRoot(element.parentNode);\n};\n\nconst noop = () => {};\n/**\n * Trick to restart an element's animation\n *\n * @param {HTMLElement} element\n * @return void\n *\n * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n */\n\n\nconst reflow = element => {\n element.offsetHeight; // eslint-disable-line no-unused-expressions\n};\n\nconst getjQuery = () => {\n if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n return window.jQuery;\n }\n\n return null;\n};\n\nconst DOMContentLoadedCallbacks = [];\n\nconst onDOMContentLoaded = callback => {\n if (document.readyState === 'loading') {\n // add listener on the first call when the document is in loading state\n if (!DOMContentLoadedCallbacks.length) {\n document.addEventListener('DOMContentLoaded', () => {\n for (const callback of DOMContentLoadedCallbacks) {\n callback();\n }\n });\n }\n\n DOMContentLoadedCallbacks.push(callback);\n } else {\n callback();\n }\n};\n\nconst isRTL = () => document.documentElement.dir === 'rtl';\n\nconst defineJQueryPlugin = plugin => {\n onDOMContentLoaded(() => {\n const $ = getjQuery();\n /* istanbul ignore if */\n\n if ($) {\n const name = plugin.NAME;\n const JQUERY_NO_CONFLICT = $.fn[name];\n $.fn[name] = plugin.jQueryInterface;\n $.fn[name].Constructor = plugin;\n\n $.fn[name].noConflict = () => {\n $.fn[name] = JQUERY_NO_CONFLICT;\n return plugin.jQueryInterface;\n };\n }\n });\n};\n\nconst execute = callback => {\n if (typeof callback === 'function') {\n callback();\n }\n};\n\nconst executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n if (!waitForTransition) {\n execute(callback);\n return;\n }\n\n const durationPadding = 5;\n const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;\n let called = false;\n\n const handler = ({\n target\n }) => {\n if (target !== transitionElement) {\n return;\n }\n\n called = true;\n transitionElement.removeEventListener(TRANSITION_END, handler);\n execute(callback);\n };\n\n transitionElement.addEventListener(TRANSITION_END, handler);\n setTimeout(() => {\n if (!called) {\n triggerTransitionEnd(transitionElement);\n }\n }, emulatedDuration);\n};\n/**\n * Return the previous/next element of a list.\n *\n * @param {array} list The list of elements\n * @param activeElement The active element\n * @param shouldGetNext Choose to get next or previous element\n * @param isCycleAllowed\n * @return {Element|elem} The proper element\n */\n\n\nconst getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n const listLength = list.length;\n let index = list.indexOf(activeElement); // if the element does not exist in the list return an element\n // depending on the direction and if cycle is allowed\n\n if (index === -1) {\n return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];\n }\n\n index += shouldGetNext ? 1 : -1;\n\n if (isCycleAllowed) {\n index = (index + listLength) % listLength;\n }\n\n return list[Math.max(0, Math.min(index, listLength - 1))];\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): dom/event-handler.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst namespaceRegex = /[^.]*(?=\\..*)\\.|.*/;\nconst stripNameRegex = /\\..*/;\nconst stripUidRegex = /::\\d+$/;\nconst eventRegistry = {}; // Events storage\n\nlet uidEvent = 1;\nconst customEvents = {\n mouseenter: 'mouseover',\n mouseleave: 'mouseout'\n};\nconst nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);\n/**\n * Private methods\n */\n\nfunction makeEventUid(element, uid) {\n return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;\n}\n\nfunction getElementEvents(element) {\n const uid = makeEventUid(element);\n element.uidEvent = uid;\n eventRegistry[uid] = eventRegistry[uid] || {};\n return eventRegistry[uid];\n}\n\nfunction bootstrapHandler(element, fn) {\n return function handler(event) {\n hydrateObj(event, {\n delegateTarget: element\n });\n\n if (handler.oneOff) {\n EventHandler.off(element, event.type, fn);\n }\n\n return fn.apply(element, [event]);\n };\n}\n\nfunction bootstrapDelegationHandler(element, selector, fn) {\n return function handler(event) {\n const domElements = element.querySelectorAll(selector);\n\n for (let {\n target\n } = event; target && target !== this; target = target.parentNode) {\n for (const domElement of domElements) {\n if (domElement !== target) {\n continue;\n }\n\n hydrateObj(event, {\n delegateTarget: target\n });\n\n if (handler.oneOff) {\n EventHandler.off(element, event.type, selector, fn);\n }\n\n return fn.apply(target, [event]);\n }\n }\n };\n}\n\nfunction findHandler(events, callable, delegationSelector = null) {\n return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector);\n}\n\nfunction normalizeParameters(originalTypeEvent, handler, delegationFunction) {\n const isDelegated = typeof handler === 'string'; // todo: tooltip passes `false` instead of selector, so we need to check\n\n const callable = isDelegated ? delegationFunction : handler || delegationFunction;\n let typeEvent = getTypeEvent(originalTypeEvent);\n\n if (!nativeEvents.has(typeEvent)) {\n typeEvent = originalTypeEvent;\n }\n\n return [isDelegated, callable, typeEvent];\n}\n\nfunction addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n\n let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n\n if (originalTypeEvent in customEvents) {\n const wrapFunction = fn => {\n return function (event) {\n if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {\n return fn.call(this, event);\n }\n };\n };\n\n callable = wrapFunction(callable);\n }\n\n const events = getElementEvents(element);\n const handlers = events[typeEvent] || (events[typeEvent] = {});\n const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);\n\n if (previousFunction) {\n previousFunction.oneOff = previousFunction.oneOff && oneOff;\n return;\n }\n\n const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));\n const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable);\n fn.delegationSelector = isDelegated ? handler : null;\n fn.callable = callable;\n fn.oneOff = oneOff;\n fn.uidEvent = uid;\n handlers[uid] = fn;\n element.addEventListener(typeEvent, fn, isDelegated);\n}\n\nfunction removeHandler(element, events, typeEvent, handler, delegationSelector) {\n const fn = findHandler(events[typeEvent], handler, delegationSelector);\n\n if (!fn) {\n return;\n }\n\n element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));\n delete events[typeEvent][fn.uidEvent];\n}\n\nfunction removeNamespacedHandlers(element, events, typeEvent, namespace) {\n const storeElementEvent = events[typeEvent] || {};\n\n for (const handlerKey of Object.keys(storeElementEvent)) {\n if (handlerKey.includes(namespace)) {\n const event = storeElementEvent[handlerKey];\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n}\n\nfunction getTypeEvent(event) {\n // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n event = event.replace(stripNameRegex, '');\n return customEvents[event] || event;\n}\n\nconst EventHandler = {\n on(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, false);\n },\n\n one(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, true);\n },\n\n off(element, originalTypeEvent, handler, delegationFunction) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n\n const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);\n const inNamespace = typeEvent !== originalTypeEvent;\n const events = getElementEvents(element);\n const storeElementEvent = events[typeEvent] || {};\n const isNamespace = originalTypeEvent.startsWith('.');\n\n if (typeof callable !== 'undefined') {\n // Simplest case: handler is passed, remove that listener ONLY.\n if (!Object.keys(storeElementEvent).length) {\n return;\n }\n\n removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);\n return;\n }\n\n if (isNamespace) {\n for (const elementEvent of Object.keys(events)) {\n removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));\n }\n }\n\n for (const keyHandlers of Object.keys(storeElementEvent)) {\n const handlerKey = keyHandlers.replace(stripUidRegex, '');\n\n if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n const event = storeElementEvent[keyHandlers];\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n },\n\n trigger(element, event, args) {\n if (typeof event !== 'string' || !element) {\n return null;\n }\n\n const $ = getjQuery();\n const typeEvent = getTypeEvent(event);\n const inNamespace = event !== typeEvent;\n let jQueryEvent = null;\n let bubbles = true;\n let nativeDispatch = true;\n let defaultPrevented = false;\n\n if (inNamespace && $) {\n jQueryEvent = $.Event(event, args);\n $(element).trigger(jQueryEvent);\n bubbles = !jQueryEvent.isPropagationStopped();\n nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();\n defaultPrevented = jQueryEvent.isDefaultPrevented();\n }\n\n let evt = new Event(event, {\n bubbles,\n cancelable: true\n });\n evt = hydrateObj(evt, args);\n\n if (defaultPrevented) {\n evt.preventDefault();\n }\n\n if (nativeDispatch) {\n element.dispatchEvent(evt);\n }\n\n if (evt.defaultPrevented && jQueryEvent) {\n jQueryEvent.preventDefault();\n }\n\n return evt;\n }\n\n};\n\nfunction hydrateObj(obj, meta) {\n for (const [key, value] of Object.entries(meta || {})) {\n try {\n obj[key] = value;\n } catch (_unused) {\n Object.defineProperty(obj, key, {\n configurable: true,\n\n get() {\n return value;\n }\n\n });\n }\n }\n\n return obj;\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\nconst elementMap = new Map();\nconst Data = {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map());\n }\n\n const instanceMap = elementMap.get(element); // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);\n return;\n }\n\n instanceMap.set(key, instance);\n },\n\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null;\n }\n\n return null;\n },\n\n remove(element, key) {\n if (!elementMap.has(element)) {\n return;\n }\n\n const instanceMap = elementMap.get(element);\n instanceMap.delete(key); // free up element references if there are no instances left for an element\n\n if (instanceMap.size === 0) {\n elementMap.delete(element);\n }\n }\n\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\nfunction normalizeData(value) {\n if (value === 'true') {\n return true;\n }\n\n if (value === 'false') {\n return false;\n }\n\n if (value === Number(value).toString()) {\n return Number(value);\n }\n\n if (value === '' || value === 'null') {\n return null;\n }\n\n if (typeof value !== 'string') {\n return value;\n }\n\n try {\n return JSON.parse(decodeURIComponent(value));\n } catch (_unused) {\n return value;\n }\n}\n\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);\n}\n\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);\n },\n\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);\n },\n\n getDataAttributes(element) {\n if (!element) {\n return {};\n }\n\n const attributes = {};\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'));\n\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '');\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);\n attributes[pureKey] = normalizeData(element.dataset[key]);\n }\n\n return attributes;\n },\n\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));\n }\n\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/config.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Class definition\n */\n\nclass Config {\n // Getters\n static get Default() {\n return {};\n }\n\n static get DefaultType() {\n return {};\n }\n\n static get NAME() {\n throw new Error('You have to implement the static method \"NAME\", for each component!');\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config);\n config = this._configAfterMerge(config);\n\n this._typeCheckConfig(config);\n\n return config;\n }\n\n _configAfterMerge(config) {\n return config;\n }\n\n _mergeConfigObj(config, element) {\n const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse\n\n return { ...this.constructor.Default,\n ...(typeof jsonConfig === 'object' ? jsonConfig : {}),\n ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),\n ...(typeof config === 'object' ? config : {})\n };\n }\n\n _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {\n for (const property of Object.keys(configTypes)) {\n const expectedTypes = configTypes[property];\n const value = config[property];\n const valueType = isElement(value) ? 'element' : toType(value);\n\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`);\n }\n }\n }\n\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst VERSION = '5.2.3';\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super();\n element = getElement(element);\n\n if (!element) {\n return;\n }\n\n this._element = element;\n this._config = this._getConfig(config);\n Data.set(this._element, this.constructor.DATA_KEY, this);\n } // Public\n\n\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY);\n EventHandler.off(this._element, this.constructor.EVENT_KEY);\n\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null;\n }\n }\n\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated);\n }\n\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element);\n config = this._configAfterMerge(config);\n\n this._typeCheckConfig(config);\n\n return config;\n } // Static\n\n\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY);\n }\n\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);\n }\n\n static get VERSION() {\n return VERSION;\n }\n\n static get DATA_KEY() {\n return `bs.${this.NAME}`;\n }\n\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`;\n }\n\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`;\n }\n\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/component-functions.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst enableDismissTrigger = (component, method = 'hide') => {\n const clickEvent = `click.dismiss${component.EVENT_KEY}`;\n const name = component.NAME;\n EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n\n if (isDisabled(this)) {\n return;\n }\n\n const target = getElementFromSelector(this) || this.closest(`.${name}`);\n const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n\n instance[method]();\n });\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$f = 'alert';\nconst DATA_KEY$a = 'bs.alert';\nconst EVENT_KEY$b = `.${DATA_KEY$a}`;\nconst EVENT_CLOSE = `close${EVENT_KEY$b}`;\nconst EVENT_CLOSED = `closed${EVENT_KEY$b}`;\nconst CLASS_NAME_FADE$5 = 'fade';\nconst CLASS_NAME_SHOW$8 = 'show';\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME$f;\n } // Public\n\n\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);\n\n if (closeEvent.defaultPrevented) {\n return;\n }\n\n this._element.classList.remove(CLASS_NAME_SHOW$8);\n\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);\n\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated);\n } // Private\n\n\n _destroyElement() {\n this._element.remove();\n\n EventHandler.trigger(this._element, EVENT_CLOSED);\n this.dispose();\n } // Static\n\n\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Alert.getOrCreateInstance(this);\n\n if (typeof config !== 'string') {\n return;\n }\n\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n\n data[config](this);\n });\n }\n\n}\n/**\n * Data API implementation\n */\n\n\nenableDismissTrigger(Alert, 'close');\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$e = 'button';\nconst DATA_KEY$9 = 'bs.button';\nconst EVENT_KEY$a = `.${DATA_KEY$9}`;\nconst DATA_API_KEY$6 = '.data-api';\nconst CLASS_NAME_ACTIVE$3 = 'active';\nconst SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle=\"button\"]';\nconst EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME$e;\n } // Public\n\n\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));\n } // Static\n\n\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Button.getOrCreateInstance(this);\n\n if (config === 'toggle') {\n data[config]();\n }\n });\n }\n\n}\n/**\n * Data API implementation\n */\n\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {\n event.preventDefault();\n const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);\n const data = Button.getOrCreateInstance(button);\n data.toggle();\n});\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst SelectorEngine = {\n find(selector, element = document.documentElement) {\n return [].concat(...Element.prototype.querySelectorAll.call(element, selector));\n },\n\n findOne(selector, element = document.documentElement) {\n return Element.prototype.querySelector.call(element, selector);\n },\n\n children(element, selector) {\n return [].concat(...element.children).filter(child => child.matches(selector));\n },\n\n parents(element, selector) {\n const parents = [];\n let ancestor = element.parentNode.closest(selector);\n\n while (ancestor) {\n parents.push(ancestor);\n ancestor = ancestor.parentNode.closest(selector);\n }\n\n return parents;\n },\n\n prev(element, selector) {\n let previous = element.previousElementSibling;\n\n while (previous) {\n if (previous.matches(selector)) {\n return [previous];\n }\n\n previous = previous.previousElementSibling;\n }\n\n return [];\n },\n\n // TODO: this is now unused; remove later along with prev()\n next(element, selector) {\n let next = element.nextElementSibling;\n\n while (next) {\n if (next.matches(selector)) {\n return [next];\n }\n\n next = next.nextElementSibling;\n }\n\n return [];\n },\n\n focusableChildren(element) {\n const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable=\"true\"]'].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(',');\n return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));\n }\n\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/swipe.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$d = 'swipe';\nconst EVENT_KEY$9 = '.bs.swipe';\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`;\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`;\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`;\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`;\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`;\nconst POINTER_TYPE_TOUCH = 'touch';\nconst POINTER_TYPE_PEN = 'pen';\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event';\nconst SWIPE_THRESHOLD = 40;\nconst Default$c = {\n endCallback: null,\n leftCallback: null,\n rightCallback: null\n};\nconst DefaultType$c = {\n endCallback: '(function|null)',\n leftCallback: '(function|null)',\n rightCallback: '(function|null)'\n};\n/**\n * Class definition\n */\n\nclass Swipe extends Config {\n constructor(element, config) {\n super();\n this._element = element;\n\n if (!element || !Swipe.isSupported()) {\n return;\n }\n\n this._config = this._getConfig(config);\n this._deltaX = 0;\n this._supportPointerEvents = Boolean(window.PointerEvent);\n\n this._initEvents();\n } // Getters\n\n\n static get Default() {\n return Default$c;\n }\n\n static get DefaultType() {\n return DefaultType$c;\n }\n\n static get NAME() {\n return NAME$d;\n } // Public\n\n\n dispose() {\n EventHandler.off(this._element, EVENT_KEY$9);\n } // Private\n\n\n _start(event) {\n if (!this._supportPointerEvents) {\n this._deltaX = event.touches[0].clientX;\n return;\n }\n\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX;\n }\n }\n\n _end(event) {\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX - this._deltaX;\n }\n\n this._handleSwipe();\n\n execute(this._config.endCallback);\n }\n\n _move(event) {\n this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX;\n }\n\n _handleSwipe() {\n const absDeltaX = Math.abs(this._deltaX);\n\n if (absDeltaX <= SWIPE_THRESHOLD) {\n return;\n }\n\n const direction = absDeltaX / this._deltaX;\n this._deltaX = 0;\n\n if (!direction) {\n return;\n }\n\n execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback);\n }\n\n _initEvents() {\n if (this._supportPointerEvents) {\n EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event));\n EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event));\n\n this._element.classList.add(CLASS_NAME_POINTER_EVENT);\n } else {\n EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event));\n EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event));\n EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event));\n }\n }\n\n _eventIsPointerPenTouch(event) {\n return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);\n } // Static\n\n\n static isSupported() {\n return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;\n }\n\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$c = 'carousel';\nconst DATA_KEY$8 = 'bs.carousel';\nconst EVENT_KEY$8 = `.${DATA_KEY$8}`;\nconst DATA_API_KEY$5 = '.data-api';\nconst ARROW_LEFT_KEY$1 = 'ArrowLeft';\nconst ARROW_RIGHT_KEY$1 = 'ArrowRight';\nconst TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch\n\nconst ORDER_NEXT = 'next';\nconst ORDER_PREV = 'prev';\nconst DIRECTION_LEFT = 'left';\nconst DIRECTION_RIGHT = 'right';\nconst EVENT_SLIDE = `slide${EVENT_KEY$8}`;\nconst EVENT_SLID = `slid${EVENT_KEY$8}`;\nconst EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`;\nconst EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`;\nconst EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`;\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`;\nconst EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`;\nconst EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;\nconst CLASS_NAME_CAROUSEL = 'carousel';\nconst CLASS_NAME_ACTIVE$2 = 'active';\nconst CLASS_NAME_SLIDE = 'slide';\nconst CLASS_NAME_END = 'carousel-item-end';\nconst CLASS_NAME_START = 'carousel-item-start';\nconst CLASS_NAME_NEXT = 'carousel-item-next';\nconst CLASS_NAME_PREV = 'carousel-item-prev';\nconst SELECTOR_ACTIVE = '.active';\nconst SELECTOR_ITEM = '.carousel-item';\nconst SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM;\nconst SELECTOR_ITEM_IMG = '.carousel-item img';\nconst SELECTOR_INDICATORS = '.carousel-indicators';\nconst SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';\nconst SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]';\nconst KEY_TO_DIRECTION = {\n [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT,\n [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT\n};\nconst Default$b = {\n interval: 5000,\n keyboard: true,\n pause: 'hover',\n ride: false,\n touch: true,\n wrap: true\n};\nconst DefaultType$b = {\n interval: '(number|boolean)',\n // TODO:v6 remove boolean support\n keyboard: 'boolean',\n pause: '(string|boolean)',\n ride: '(boolean|string)',\n touch: 'boolean',\n wrap: 'boolean'\n};\n/**\n * Class definition\n */\n\nclass Carousel extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._interval = null;\n this._activeElement = null;\n this._isSliding = false;\n this.touchTimeout = null;\n this._swipeHelper = null;\n this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);\n\n this._addEventListeners();\n\n if (this._config.ride === CLASS_NAME_CAROUSEL) {\n this.cycle();\n }\n } // Getters\n\n\n static get Default() {\n return Default$b;\n }\n\n static get DefaultType() {\n return DefaultType$b;\n }\n\n static get NAME() {\n return NAME$c;\n } // Public\n\n\n next() {\n this._slide(ORDER_NEXT);\n }\n\n nextWhenVisible() {\n // FIXME TODO use `document.visibilityState`\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden && isVisible(this._element)) {\n this.next();\n }\n }\n\n prev() {\n this._slide(ORDER_PREV);\n }\n\n pause() {\n if (this._isSliding) {\n triggerTransitionEnd(this._element);\n }\n\n this._clearInterval();\n }\n\n cycle() {\n this._clearInterval();\n\n this._updateInterval();\n\n this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval);\n }\n\n _maybeEnableCycle() {\n if (!this._config.ride) {\n return;\n }\n\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.cycle());\n return;\n }\n\n this.cycle();\n }\n\n to(index) {\n const items = this._getItems();\n\n if (index > items.length - 1 || index < 0) {\n return;\n }\n\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.to(index));\n return;\n }\n\n const activeIndex = this._getItemIndex(this._getActive());\n\n if (activeIndex === index) {\n return;\n }\n\n const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;\n\n this._slide(order, items[index]);\n }\n\n dispose() {\n if (this._swipeHelper) {\n this._swipeHelper.dispose();\n }\n\n super.dispose();\n } // Private\n\n\n _configAfterMerge(config) {\n config.defaultInterval = config.interval;\n return config;\n }\n\n _addEventListeners() {\n if (this._config.keyboard) {\n EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event));\n }\n\n if (this._config.pause === 'hover') {\n EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause());\n EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle());\n }\n\n if (this._config.touch && Swipe.isSupported()) {\n this._addTouchEventListeners();\n }\n }\n\n _addTouchEventListeners() {\n for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {\n EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault());\n }\n\n const endCallBack = () => {\n if (this._config.pause !== 'hover') {\n return;\n } // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n\n this.pause();\n\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout);\n }\n\n this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval);\n };\n\n const swipeConfig = {\n leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),\n rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),\n endCallback: endCallBack\n };\n this._swipeHelper = new Swipe(this._element, swipeConfig);\n }\n\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return;\n }\n\n const direction = KEY_TO_DIRECTION[event.key];\n\n if (direction) {\n event.preventDefault();\n\n this._slide(this._directionToOrder(direction));\n }\n }\n\n _getItemIndex(element) {\n return this._getItems().indexOf(element);\n }\n\n _setActiveIndicatorElement(index) {\n if (!this._indicatorsElement) {\n return;\n }\n\n const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement);\n activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);\n activeIndicator.removeAttribute('aria-current');\n const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to=\"${index}\"]`, this._indicatorsElement);\n\n if (newActiveIndicator) {\n newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2);\n newActiveIndicator.setAttribute('aria-current', 'true');\n }\n }\n\n _updateInterval() {\n const element = this._activeElement || this._getActive();\n\n if (!element) {\n return;\n }\n\n const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);\n this._config.interval = elementInterval || this._config.defaultInterval;\n }\n\n _slide(order, element = null) {\n if (this._isSliding) {\n return;\n }\n\n const activeElement = this._getActive();\n\n const isNext = order === ORDER_NEXT;\n const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap);\n\n if (nextElement === activeElement) {\n return;\n }\n\n const nextElementIndex = this._getItemIndex(nextElement);\n\n const triggerEvent = eventName => {\n return EventHandler.trigger(this._element, eventName, {\n relatedTarget: nextElement,\n direction: this._orderToDirection(order),\n from: this._getItemIndex(activeElement),\n to: nextElementIndex\n });\n };\n\n const slideEvent = triggerEvent(EVENT_SLIDE);\n\n if (slideEvent.defaultPrevented) {\n return;\n }\n\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n // todo: change tests that use empty divs to avoid this check\n return;\n }\n\n const isCycling = Boolean(this._interval);\n this.pause();\n this._isSliding = true;\n\n this._setActiveIndicatorElement(nextElementIndex);\n\n this._activeElement = nextElement;\n const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;\n const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;\n nextElement.classList.add(orderClassName);\n reflow(nextElement);\n activeElement.classList.add(directionalClassName);\n nextElement.classList.add(directionalClassName);\n\n const completeCallBack = () => {\n nextElement.classList.remove(directionalClassName, orderClassName);\n nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);\n this._isSliding = false;\n triggerEvent(EVENT_SLID);\n };\n\n this._queueCallback(completeCallBack, activeElement, this._isAnimated());\n\n if (isCycling) {\n this.cycle();\n }\n }\n\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_SLIDE);\n }\n\n _getActive() {\n return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n }\n\n _getItems() {\n return SelectorEngine.find(SELECTOR_ITEM, this._element);\n }\n\n _clearInterval() {\n if (this._interval) {\n clearInterval(this._interval);\n this._interval = null;\n }\n }\n\n _directionToOrder(direction) {\n if (isRTL()) {\n return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;\n }\n\n return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;\n }\n\n _orderToDirection(order) {\n if (isRTL()) {\n return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;\n }\n\n return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;\n } // Static\n\n\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Carousel.getOrCreateInstance(this, config);\n\n if (typeof config === 'number') {\n data.to(config);\n return;\n }\n\n if (typeof config === 'string') {\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n\n data[config]();\n }\n });\n }\n\n}\n/**\n * Data API implementation\n */\n\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) {\n const target = getElementFromSelector(this);\n\n if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n return;\n }\n\n event.preventDefault();\n const carousel = Carousel.getOrCreateInstance(target);\n const slideIndex = this.getAttribute('data-bs-slide-to');\n\n if (slideIndex) {\n carousel.to(slideIndex);\n\n carousel._maybeEnableCycle();\n\n return;\n }\n\n if (Manipulator.getDataAttribute(this, 'slide') === 'next') {\n carousel.next();\n\n carousel._maybeEnableCycle();\n\n return;\n }\n\n carousel.prev();\n\n carousel._maybeEnableCycle();\n});\nEventHandler.on(window, EVENT_LOAD_DATA_API$3, () => {\n const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);\n\n for (const carousel of carousels) {\n Carousel.getOrCreateInstance(carousel);\n }\n});\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Carousel);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$b = 'collapse';\nconst DATA_KEY$7 = 'bs.collapse';\nconst EVENT_KEY$7 = `.${DATA_KEY$7}`;\nconst DATA_API_KEY$4 = '.data-api';\nconst EVENT_SHOW$6 = `show${EVENT_KEY$7}`;\nconst EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`;\nconst EVENT_HIDE$6 = `hide${EVENT_KEY$7}`;\nconst EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`;\nconst EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`;\nconst CLASS_NAME_SHOW$7 = 'show';\nconst CLASS_NAME_COLLAPSE = 'collapse';\nconst CLASS_NAME_COLLAPSING = 'collapsing';\nconst CLASS_NAME_COLLAPSED = 'collapsed';\nconst CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;\nconst CLASS_NAME_HORIZONTAL = 'collapse-horizontal';\nconst WIDTH = 'width';\nconst HEIGHT = 'height';\nconst SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';\nconst SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle=\"collapse\"]';\nconst Default$a = {\n parent: null,\n toggle: true\n};\nconst DefaultType$a = {\n parent: '(null|element)',\n toggle: 'boolean'\n};\n/**\n * Class definition\n */\n\nclass Collapse extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._isTransitioning = false;\n this._triggerArray = [];\n const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);\n\n for (const elem of toggleList) {\n const selector = getSelectorFromElement(elem);\n const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element);\n\n if (selector !== null && filterElement.length) {\n this._triggerArray.push(elem);\n }\n }\n\n this._initializeChildren();\n\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());\n }\n\n if (this._config.toggle) {\n this.toggle();\n }\n } // Getters\n\n\n static get Default() {\n return Default$a;\n }\n\n static get DefaultType() {\n return DefaultType$a;\n }\n\n static get NAME() {\n return NAME$b;\n } // Public\n\n\n toggle() {\n if (this._isShown()) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n show() {\n if (this._isTransitioning || this._isShown()) {\n return;\n }\n\n let activeChildren = []; // find active children\n\n if (this._config.parent) {\n activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, {\n toggle: false\n }));\n }\n\n if (activeChildren.length && activeChildren[0]._isTransitioning) {\n return;\n }\n\n const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6);\n\n if (startEvent.defaultPrevented) {\n return;\n }\n\n for (const activeInstance of activeChildren) {\n activeInstance.hide();\n }\n\n const dimension = this._getDimension();\n\n this._element.classList.remove(CLASS_NAME_COLLAPSE);\n\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n\n this._element.style[dimension] = 0;\n\n this._addAriaAndCollapsedClass(this._triggerArray, true);\n\n this._isTransitioning = true;\n\n const complete = () => {\n this._isTransitioning = false;\n\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n\n this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n\n this._element.style[dimension] = '';\n EventHandler.trigger(this._element, EVENT_SHOWN$6);\n };\n\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);\n const scrollSize = `scroll${capitalizedDimension}`;\n\n this._queueCallback(complete, this._element, true);\n\n this._element.style[dimension] = `${this._element[scrollSize]}px`;\n }\n\n hide() {\n if (this._isTransitioning || !this._isShown()) {\n return;\n }\n\n const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6);\n\n if (startEvent.defaultPrevented) {\n return;\n }\n\n const dimension = this._getDimension();\n\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;\n reflow(this._element);\n\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n\n this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n\n for (const trigger of this._triggerArray) {\n const element = getElementFromSelector(trigger);\n\n if (element && !this._isShown(element)) {\n this._addAriaAndCollapsedClass([trigger], false);\n }\n }\n\n this._isTransitioning = true;\n\n const complete = () => {\n this._isTransitioning = false;\n\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n\n this._element.classList.add(CLASS_NAME_COLLAPSE);\n\n EventHandler.trigger(this._element, EVENT_HIDDEN$6);\n };\n\n this._element.style[dimension] = '';\n\n this._queueCallback(complete, this._element, true);\n }\n\n _isShown(element = this._element) {\n return element.classList.contains(CLASS_NAME_SHOW$7);\n } // Private\n\n\n _configAfterMerge(config) {\n config.toggle = Boolean(config.toggle); // Coerce string values\n\n config.parent = getElement(config.parent);\n return config;\n }\n\n _getDimension() {\n return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;\n }\n\n _initializeChildren() {\n if (!this._config.parent) {\n return;\n }\n\n const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4);\n\n for (const element of children) {\n const selected = getElementFromSelector(element);\n\n if (selected) {\n this._addAriaAndCollapsedClass([element], this._isShown(selected));\n }\n }\n }\n\n _getFirstLevelChildren(selector) {\n const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent); // remove children if greater depth\n\n return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element));\n }\n\n _addAriaAndCollapsedClass(triggerArray, isOpen) {\n if (!triggerArray.length) {\n return;\n }\n\n for (const element of triggerArray) {\n element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);\n element.setAttribute('aria-expanded', isOpen);\n }\n } // Static\n\n\n static jQueryInterface(config) {\n const _config = {};\n\n if (typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false;\n }\n\n return this.each(function () {\n const data = Collapse.getOrCreateInstance(this, _config);\n\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n\n data[config]();\n }\n });\n }\n\n}\n/**\n * Data API implementation\n */\n\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {\n // preventDefault only for elements (which change the URL) not inside the collapsible element\n if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {\n event.preventDefault();\n }\n\n const selector = getSelectorFromElement(this);\n const selectorElements = SelectorEngine.find(selector);\n\n for (const element of selectorElements) {\n Collapse.getOrCreateInstance(element, {\n toggle: false\n }).toggle();\n }\n});\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Collapse);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$a = 'dropdown';\nconst DATA_KEY$6 = 'bs.dropdown';\nconst EVENT_KEY$6 = `.${DATA_KEY$6}`;\nconst DATA_API_KEY$3 = '.data-api';\nconst ESCAPE_KEY$2 = 'Escape';\nconst TAB_KEY$1 = 'Tab';\nconst ARROW_UP_KEY$1 = 'ArrowUp';\nconst ARROW_DOWN_KEY$1 = 'ArrowDown';\nconst RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button\n\nconst EVENT_HIDE$5 = `hide${EVENT_KEY$6}`;\nconst EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`;\nconst EVENT_SHOW$5 = `show${EVENT_KEY$6}`;\nconst EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`;\nconst EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst CLASS_NAME_SHOW$6 = 'show';\nconst CLASS_NAME_DROPUP = 'dropup';\nconst CLASS_NAME_DROPEND = 'dropend';\nconst CLASS_NAME_DROPSTART = 'dropstart';\nconst CLASS_NAME_DROPUP_CENTER = 'dropup-center';\nconst CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';\nconst SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle=\"dropdown\"]:not(.disabled):not(:disabled)';\nconst SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`;\nconst SELECTOR_MENU = '.dropdown-menu';\nconst SELECTOR_NAVBAR = '.navbar';\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav';\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';\nconst PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';\nconst PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';\nconst PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';\nconst PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';\nconst PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';\nconst PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';\nconst PLACEMENT_TOPCENTER = 'top';\nconst PLACEMENT_BOTTOMCENTER = 'bottom';\nconst Default$9 = {\n autoClose: true,\n boundary: 'clippingParents',\n display: 'dynamic',\n offset: [0, 2],\n popperConfig: null,\n reference: 'toggle'\n};\nconst DefaultType$9 = {\n autoClose: '(boolean|string)',\n boundary: '(string|element)',\n display: 'string',\n offset: '(array|string|function)',\n popperConfig: '(null|object|function)',\n reference: '(string|element|object)'\n};\n/**\n * Class definition\n */\n\nclass Dropdown extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._popper = null;\n this._parent = this._element.parentNode; // dropdown wrapper\n // todo: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.2/forms/input-group/\n\n this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent);\n this._inNavbar = this._detectNavbar();\n } // Getters\n\n\n static get Default() {\n return Default$9;\n }\n\n static get DefaultType() {\n return DefaultType$9;\n }\n\n static get NAME() {\n return NAME$a;\n } // Public\n\n\n toggle() {\n return this._isShown() ? this.hide() : this.show();\n }\n\n show() {\n if (isDisabled(this._element) || this._isShown()) {\n return;\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n };\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget);\n\n if (showEvent.defaultPrevented) {\n return;\n }\n\n this._createPopper(); // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n\n if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop);\n }\n }\n\n this._element.focus();\n\n this._element.setAttribute('aria-expanded', true);\n\n this._menu.classList.add(CLASS_NAME_SHOW$6);\n\n this._element.classList.add(CLASS_NAME_SHOW$6);\n\n EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget);\n }\n\n hide() {\n if (isDisabled(this._element) || !this._isShown()) {\n return;\n }\n\n const relatedTarget = {\n relatedTarget: this._element\n };\n\n this._completeHide(relatedTarget);\n }\n\n dispose() {\n if (this._popper) {\n this._popper.destroy();\n }\n\n super.dispose();\n }\n\n update() {\n this._inNavbar = this._detectNavbar();\n\n if (this._popper) {\n this._popper.update();\n }\n } // Private\n\n\n _completeHide(relatedTarget) {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget);\n\n if (hideEvent.defaultPrevented) {\n return;\n } // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n\n\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop);\n }\n }\n\n if (this._popper) {\n this._popper.destroy();\n }\n\n this._menu.classList.remove(CLASS_NAME_SHOW$6);\n\n this._element.classList.remove(CLASS_NAME_SHOW$6);\n\n this._element.setAttribute('aria-expanded', 'false');\n\n Manipulator.removeDataAttribute(this._menu, 'popper');\n EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget);\n }\n\n _getConfig(config) {\n config = super._getConfig(config);\n\n if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {\n // Popper virtual elements require a getBoundingClientRect method\n throw new TypeError(`${NAME$a.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`);\n }\n\n return config;\n }\n\n _createPopper() {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)');\n }\n\n let referenceElement = this._element;\n\n if (this._config.reference === 'parent') {\n referenceElement = this._parent;\n } else if (isElement(this._config.reference)) {\n referenceElement = getElement(this._config.reference);\n } else if (typeof this._config.reference === 'object') {\n referenceElement = this._config.reference;\n }\n\n const popperConfig = this._getPopperConfig();\n\n this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig);\n }\n\n _isShown() {\n return this._menu.classList.contains(CLASS_NAME_SHOW$6);\n }\n\n _getPlacement() {\n const parentDropdown = this._parent;\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n return PLACEMENT_RIGHT;\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n return PLACEMENT_LEFT;\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {\n return PLACEMENT_TOPCENTER;\n }\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {\n return PLACEMENT_BOTTOMCENTER;\n } // We need to trim the value because custom properties can also include spaces\n\n\n const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';\n\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;\n }\n\n return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;\n }\n\n _detectNavbar() {\n return this._element.closest(SELECTOR_NAVBAR) !== null;\n }\n\n _getOffset() {\n const {\n offset\n } = this._config;\n\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10));\n }\n\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element);\n }\n\n return offset;\n }\n\n _getPopperConfig() {\n const defaultBsPopperConfig = {\n placement: this._getPlacement(),\n modifiers: [{\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n }, {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }]\n }; // Disable Popper if we have a static display or Dropdown is in Navbar\n\n if (this._inNavbar || this._config.display === 'static') {\n Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // todo:v6 remove\n\n defaultBsPopperConfig.modifiers = [{\n name: 'applyStyles',\n enabled: false\n }];\n }\n\n return { ...defaultBsPopperConfig,\n ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n };\n }\n\n _selectMenuItem({\n key,\n target\n }) {\n const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element));\n\n if (!items.length) {\n return;\n } // if target isn't included in items (e.g. when expanding the dropdown)\n // allow cycling to get the last item in case key equals ARROW_UP_KEY\n\n\n getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();\n } // Static\n\n\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Dropdown.getOrCreateInstance(this, config);\n\n if (typeof config !== 'string') {\n return;\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n\n data[config]();\n });\n }\n\n static clearMenus(event) {\n if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {\n return;\n }\n\n const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);\n\n for (const toggle of openToggles) {\n const context = Dropdown.getInstance(toggle);\n\n if (!context || context._config.autoClose === false) {\n continue;\n }\n\n const composedPath = event.composedPath();\n const isMenuTarget = composedPath.includes(context._menu);\n\n if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {\n continue;\n } // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n\n\n if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n continue;\n }\n\n const relatedTarget = {\n relatedTarget: context._element\n };\n\n if (event.type === 'click') {\n relatedTarget.clickEvent = event;\n }\n\n context._completeHide(relatedTarget);\n }\n }\n\n static dataApiKeydownHandler(event) {\n // If not an UP | DOWN | ESCAPE key => not a dropdown command\n // If input/textarea && if key is other than ESCAPE => not a dropdown command\n const isInput = /input|textarea/i.test(event.target.tagName);\n const isEscapeEvent = event.key === ESCAPE_KEY$2;\n const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key);\n\n if (!isUpOrDownEvent && !isEscapeEvent) {\n return;\n }\n\n if (isInput && !isEscapeEvent) {\n return;\n }\n\n event.preventDefault(); // todo: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.2/forms/input-group/\n\n const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3, event.delegateTarget.parentNode);\n const instance = Dropdown.getOrCreateInstance(getToggleButton);\n\n if (isUpOrDownEvent) {\n event.stopPropagation();\n instance.show();\n\n instance._selectMenuItem(event);\n\n return;\n }\n\n if (instance._isShown()) {\n // else is escape and we check if it is shown\n event.stopPropagation();\n instance.hide();\n getToggleButton.focus();\n }\n }\n\n}\n/**\n * Data API implementation\n */\n\n\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {\n event.preventDefault();\n Dropdown.getOrCreateInstance(this).toggle();\n});\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Dropdown);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/scrollBar.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';\nconst SELECTOR_STICKY_CONTENT = '.sticky-top';\nconst PROPERTY_PADDING = 'padding-right';\nconst PROPERTY_MARGIN = 'margin-right';\n/**\n * Class definition\n */\n\nclass ScrollBarHelper {\n constructor() {\n this._element = document.body;\n } // Public\n\n\n getWidth() {\n // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n const documentWidth = document.documentElement.clientWidth;\n return Math.abs(window.innerWidth - documentWidth);\n }\n\n hide() {\n const width = this.getWidth();\n\n this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width\n\n\n this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n\n\n this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);\n\n this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);\n }\n\n reset() {\n this._resetElementAttributes(this._element, 'overflow');\n\n this._resetElementAttributes(this._element, PROPERTY_PADDING);\n\n this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);\n\n this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);\n }\n\n isOverflowing() {\n return this.getWidth() > 0;\n } // Private\n\n\n _disableOverFlow() {\n this._saveInitialAttribute(this._element, 'overflow');\n\n this._element.style.overflow = 'hidden';\n }\n\n _setElementAttributes(selector, styleProperty, callback) {\n const scrollbarWidth = this.getWidth();\n\n const manipulationCallBack = element => {\n if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n return;\n }\n\n this._saveInitialAttribute(element, styleProperty);\n\n const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);\n element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);\n };\n\n this._applyManipulationCallback(selector, manipulationCallBack);\n }\n\n _saveInitialAttribute(element, styleProperty) {\n const actualValue = element.style.getPropertyValue(styleProperty);\n\n if (actualValue) {\n Manipulator.setDataAttribute(element, styleProperty, actualValue);\n }\n }\n\n _resetElementAttributes(selector, styleProperty) {\n const manipulationCallBack = element => {\n const value = Manipulator.getDataAttribute(element, styleProperty); // We only want to remove the property if the value is `null`; the value can also be zero\n\n if (value === null) {\n element.style.removeProperty(styleProperty);\n return;\n }\n\n Manipulator.removeDataAttribute(element, styleProperty);\n element.style.setProperty(styleProperty, value);\n };\n\n this._applyManipulationCallback(selector, manipulationCallBack);\n }\n\n _applyManipulationCallback(selector, callBack) {\n if (isElement(selector)) {\n callBack(selector);\n return;\n }\n\n for (const sel of SelectorEngine.find(selector, this._element)) {\n callBack(sel);\n }\n }\n\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/backdrop.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$9 = 'backdrop';\nconst CLASS_NAME_FADE$4 = 'fade';\nconst CLASS_NAME_SHOW$5 = 'show';\nconst EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`;\nconst Default$8 = {\n className: 'modal-backdrop',\n clickCallback: null,\n isAnimated: false,\n isVisible: true,\n // if false, we use the backdrop helper without adding any element to the dom\n rootElement: 'body' // give the choice to place backdrop under different elements\n\n};\nconst DefaultType$8 = {\n className: 'string',\n clickCallback: '(function|null)',\n isAnimated: 'boolean',\n isVisible: 'boolean',\n rootElement: '(element|string)'\n};\n/**\n * Class definition\n */\n\nclass Backdrop extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n this._isAppended = false;\n this._element = null;\n } // Getters\n\n\n static get Default() {\n return Default$8;\n }\n\n static get DefaultType() {\n return DefaultType$8;\n }\n\n static get NAME() {\n return NAME$9;\n } // Public\n\n\n show(callback) {\n if (!this._config.isVisible) {\n execute(callback);\n return;\n }\n\n this._append();\n\n const element = this._getElement();\n\n if (this._config.isAnimated) {\n reflow(element);\n }\n\n element.classList.add(CLASS_NAME_SHOW$5);\n\n this._emulateAnimation(() => {\n execute(callback);\n });\n }\n\n hide(callback) {\n if (!this._config.isVisible) {\n execute(callback);\n return;\n }\n\n this._getElement().classList.remove(CLASS_NAME_SHOW$5);\n\n this._emulateAnimation(() => {\n this.dispose();\n execute(callback);\n });\n }\n\n dispose() {\n if (!this._isAppended) {\n return;\n }\n\n EventHandler.off(this._element, EVENT_MOUSEDOWN);\n\n this._element.remove();\n\n this._isAppended = false;\n } // Private\n\n\n _getElement() {\n if (!this._element) {\n const backdrop = document.createElement('div');\n backdrop.className = this._config.className;\n\n if (this._config.isAnimated) {\n backdrop.classList.add(CLASS_NAME_FADE$4);\n }\n\n this._element = backdrop;\n }\n\n return this._element;\n }\n\n _configAfterMerge(config) {\n // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n config.rootElement = getElement(config.rootElement);\n return config;\n }\n\n _append() {\n if (this._isAppended) {\n return;\n }\n\n const element = this._getElement();\n\n this._config.rootElement.append(element);\n\n EventHandler.on(element, EVENT_MOUSEDOWN, () => {\n execute(this._config.clickCallback);\n });\n this._isAppended = true;\n }\n\n _emulateAnimation(callback) {\n executeAfterTransition(callback, this._getElement(), this._config.isAnimated);\n }\n\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$8 = 'focustrap';\nconst DATA_KEY$5 = 'bs.focustrap';\nconst EVENT_KEY$5 = `.${DATA_KEY$5}`;\nconst EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`;\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`;\nconst TAB_KEY = 'Tab';\nconst TAB_NAV_FORWARD = 'forward';\nconst TAB_NAV_BACKWARD = 'backward';\nconst Default$7 = {\n autofocus: true,\n trapElement: null // The element to trap focus inside of\n\n};\nconst DefaultType$7 = {\n autofocus: 'boolean',\n trapElement: 'element'\n};\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n this._isActive = false;\n this._lastTabNavDirection = null;\n } // Getters\n\n\n static get Default() {\n return Default$7;\n }\n\n static get DefaultType() {\n return DefaultType$7;\n }\n\n static get NAME() {\n return NAME$8;\n } // Public\n\n\n activate() {\n if (this._isActive) {\n return;\n }\n\n if (this._config.autofocus) {\n this._config.trapElement.focus();\n }\n\n EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop\n\n EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event));\n EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));\n this._isActive = true;\n }\n\n deactivate() {\n if (!this._isActive) {\n return;\n }\n\n this._isActive = false;\n EventHandler.off(document, EVENT_KEY$5);\n } // Private\n\n\n _handleFocusin(event) {\n const {\n trapElement\n } = this._config;\n\n if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n return;\n }\n\n const elements = SelectorEngine.focusableChildren(trapElement);\n\n if (elements.length === 0) {\n trapElement.focus();\n } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n elements[elements.length - 1].focus();\n } else {\n elements[0].focus();\n }\n }\n\n _handleKeydown(event) {\n if (event.key !== TAB_KEY) {\n return;\n }\n\n this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;\n }\n\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$7 = 'modal';\nconst DATA_KEY$4 = 'bs.modal';\nconst EVENT_KEY$4 = `.${DATA_KEY$4}`;\nconst DATA_API_KEY$2 = '.data-api';\nconst ESCAPE_KEY$1 = 'Escape';\nconst EVENT_HIDE$4 = `hide${EVENT_KEY$4}`;\nconst EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`;\nconst EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`;\nconst EVENT_SHOW$4 = `show${EVENT_KEY$4}`;\nconst EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`;\nconst EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`;\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`;\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`;\nconst EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`;\nconst EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`;\nconst CLASS_NAME_OPEN = 'modal-open';\nconst CLASS_NAME_FADE$3 = 'fade';\nconst CLASS_NAME_SHOW$4 = 'show';\nconst CLASS_NAME_STATIC = 'modal-static';\nconst OPEN_SELECTOR$1 = '.modal.show';\nconst SELECTOR_DIALOG = '.modal-dialog';\nconst SELECTOR_MODAL_BODY = '.modal-body';\nconst SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle=\"modal\"]';\nconst Default$6 = {\n backdrop: true,\n focus: true,\n keyboard: true\n};\nconst DefaultType$6 = {\n backdrop: '(boolean|string)',\n focus: 'boolean',\n keyboard: 'boolean'\n};\n/**\n * Class definition\n */\n\nclass Modal extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);\n this._backdrop = this._initializeBackDrop();\n this._focustrap = this._initializeFocusTrap();\n this._isShown = false;\n this._isTransitioning = false;\n this._scrollBar = new ScrollBarHelper();\n\n this._addEventListeners();\n } // Getters\n\n\n static get Default() {\n return Default$6;\n }\n\n static get DefaultType() {\n return DefaultType$6;\n }\n\n static get NAME() {\n return NAME$7;\n } // Public\n\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget);\n }\n\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return;\n }\n\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, {\n relatedTarget\n });\n\n if (showEvent.defaultPrevented) {\n return;\n }\n\n this._isShown = true;\n this._isTransitioning = true;\n\n this._scrollBar.hide();\n\n document.body.classList.add(CLASS_NAME_OPEN);\n\n this._adjustDialog();\n\n this._backdrop.show(() => this._showElement(relatedTarget));\n }\n\n hide() {\n if (!this._isShown || this._isTransitioning) {\n return;\n }\n\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4);\n\n if (hideEvent.defaultPrevented) {\n return;\n }\n\n this._isShown = false;\n this._isTransitioning = true;\n\n this._focustrap.deactivate();\n\n this._element.classList.remove(CLASS_NAME_SHOW$4);\n\n this._queueCallback(() => this._hideModal(), this._element, this._isAnimated());\n }\n\n dispose() {\n for (const htmlElement of [window, this._dialog]) {\n EventHandler.off(htmlElement, EVENT_KEY$4);\n }\n\n this._backdrop.dispose();\n\n this._focustrap.deactivate();\n\n super.dispose();\n }\n\n handleUpdate() {\n this._adjustDialog();\n } // Private\n\n\n _initializeBackDrop() {\n return new Backdrop({\n isVisible: Boolean(this._config.backdrop),\n // 'static' option will be translated to true, and booleans will keep their value,\n isAnimated: this._isAnimated()\n });\n }\n\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n });\n }\n\n _showElement(relatedTarget) {\n // try to append dynamic modal\n if (!document.body.contains(this._element)) {\n document.body.append(this._element);\n }\n\n this._element.style.display = 'block';\n\n this._element.removeAttribute('aria-hidden');\n\n this._element.setAttribute('aria-modal', true);\n\n this._element.setAttribute('role', 'dialog');\n\n this._element.scrollTop = 0;\n const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);\n\n if (modalBody) {\n modalBody.scrollTop = 0;\n }\n\n reflow(this._element);\n\n this._element.classList.add(CLASS_NAME_SHOW$4);\n\n const transitionComplete = () => {\n if (this._config.focus) {\n this._focustrap.activate();\n }\n\n this._isTransitioning = false;\n EventHandler.trigger(this._element, EVENT_SHOWN$4, {\n relatedTarget\n });\n };\n\n this._queueCallback(transitionComplete, this._dialog, this._isAnimated());\n }\n\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {\n if (event.key !== ESCAPE_KEY$1) {\n return;\n }\n\n if (this._config.keyboard) {\n event.preventDefault();\n this.hide();\n return;\n }\n\n this._triggerBackdropTransition();\n });\n EventHandler.on(window, EVENT_RESIZE$1, () => {\n if (this._isShown && !this._isTransitioning) {\n this._adjustDialog();\n }\n });\n EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {\n // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks\n EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {\n if (this._element !== event.target || this._element !== event2.target) {\n return;\n }\n\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition();\n\n return;\n }\n\n if (this._config.backdrop) {\n this.hide();\n }\n });\n });\n }\n\n _hideModal() {\n this._element.style.display = 'none';\n\n this._element.setAttribute('aria-hidden', true);\n\n this._element.removeAttribute('aria-modal');\n\n this._element.removeAttribute('role');\n\n this._isTransitioning = false;\n\n this._backdrop.hide(() => {\n document.body.classList.remove(CLASS_NAME_OPEN);\n\n this._resetAdjustments();\n\n this._scrollBar.reset();\n\n EventHandler.trigger(this._element, EVENT_HIDDEN$4);\n });\n }\n\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_FADE$3);\n }\n\n _triggerBackdropTransition() {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1);\n\n if (hideEvent.defaultPrevented) {\n return;\n }\n\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n const initialOverflowY = this._element.style.overflowY; // return if the following background transition hasn't yet completed\n\n if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {\n return;\n }\n\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden';\n }\n\n this._element.classList.add(CLASS_NAME_STATIC);\n\n this._queueCallback(() => {\n this._element.classList.remove(CLASS_NAME_STATIC);\n\n this._queueCallback(() => {\n this._element.style.overflowY = initialOverflowY;\n }, this._dialog);\n }, this._dialog);\n\n this._element.focus();\n }\n /**\n * The following methods are used to handle overflowing modals\n */\n\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n\n const scrollbarWidth = this._scrollBar.getWidth();\n\n const isBodyOverflowing = scrollbarWidth > 0;\n\n if (isBodyOverflowing && !isModalOverflowing) {\n const property = isRTL() ? 'paddingLeft' : 'paddingRight';\n this._element.style[property] = `${scrollbarWidth}px`;\n }\n\n if (!isBodyOverflowing && isModalOverflowing) {\n const property = isRTL() ? 'paddingRight' : 'paddingLeft';\n this._element.style[property] = `${scrollbarWidth}px`;\n }\n }\n\n _resetAdjustments() {\n this._element.style.paddingLeft = '';\n this._element.style.paddingRight = '';\n } // Static\n\n\n static jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n const data = Modal.getOrCreateInstance(this, config);\n\n if (typeof config !== 'string') {\n return;\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n\n data[config](relatedTarget);\n });\n }\n\n}\n/**\n * Data API implementation\n */\n\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {\n const target = getElementFromSelector(this);\n\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n\n EventHandler.one(target, EVENT_SHOW$4, showEvent => {\n if (showEvent.defaultPrevented) {\n // only register focus restorer if modal will actually get shown\n return;\n }\n\n EventHandler.one(target, EVENT_HIDDEN$4, () => {\n if (isVisible(this)) {\n this.focus();\n }\n });\n }); // avoid conflict when clicking modal toggler while another one is open\n\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1);\n\n if (alreadyOpen) {\n Modal.getInstance(alreadyOpen).hide();\n }\n\n const data = Modal.getOrCreateInstance(target);\n data.toggle(this);\n});\nenableDismissTrigger(Modal);\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Modal);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): offcanvas.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$6 = 'offcanvas';\nconst DATA_KEY$3 = 'bs.offcanvas';\nconst EVENT_KEY$3 = `.${DATA_KEY$3}`;\nconst DATA_API_KEY$1 = '.data-api';\nconst EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`;\nconst ESCAPE_KEY = 'Escape';\nconst CLASS_NAME_SHOW$3 = 'show';\nconst CLASS_NAME_SHOWING$1 = 'showing';\nconst CLASS_NAME_HIDING = 'hiding';\nconst CLASS_NAME_BACKDROP = 'offcanvas-backdrop';\nconst OPEN_SELECTOR = '.offcanvas.show';\nconst EVENT_SHOW$3 = `show${EVENT_KEY$3}`;\nconst EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`;\nconst EVENT_HIDE$3 = `hide${EVENT_KEY$3}`;\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`;\nconst EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`;\nconst EVENT_RESIZE = `resize${EVENT_KEY$3}`;\nconst EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`;\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`;\nconst SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle=\"offcanvas\"]';\nconst Default$5 = {\n backdrop: true,\n keyboard: true,\n scroll: false\n};\nconst DefaultType$5 = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n scroll: 'boolean'\n};\n/**\n * Class definition\n */\n\nclass Offcanvas extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._isShown = false;\n this._backdrop = this._initializeBackDrop();\n this._focustrap = this._initializeFocusTrap();\n\n this._addEventListeners();\n } // Getters\n\n\n static get Default() {\n return Default$5;\n }\n\n static get DefaultType() {\n return DefaultType$5;\n }\n\n static get NAME() {\n return NAME$6;\n } // Public\n\n\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget);\n }\n\n show(relatedTarget) {\n if (this._isShown) {\n return;\n }\n\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {\n relatedTarget\n });\n\n if (showEvent.defaultPrevented) {\n return;\n }\n\n this._isShown = true;\n\n this._backdrop.show();\n\n if (!this._config.scroll) {\n new ScrollBarHelper().hide();\n }\n\n this._element.setAttribute('aria-modal', true);\n\n this._element.setAttribute('role', 'dialog');\n\n this._element.classList.add(CLASS_NAME_SHOWING$1);\n\n const completeCallBack = () => {\n if (!this._config.scroll || this._config.backdrop) {\n this._focustrap.activate();\n }\n\n this._element.classList.add(CLASS_NAME_SHOW$3);\n\n this._element.classList.remove(CLASS_NAME_SHOWING$1);\n\n EventHandler.trigger(this._element, EVENT_SHOWN$3, {\n relatedTarget\n });\n };\n\n this._queueCallback(completeCallBack, this._element, true);\n }\n\n hide() {\n if (!this._isShown) {\n return;\n }\n\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);\n\n if (hideEvent.defaultPrevented) {\n return;\n }\n\n this._focustrap.deactivate();\n\n this._element.blur();\n\n this._isShown = false;\n\n this._element.classList.add(CLASS_NAME_HIDING);\n\n this._backdrop.hide();\n\n const completeCallback = () => {\n this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING);\n\n this._element.removeAttribute('aria-modal');\n\n this._element.removeAttribute('role');\n\n if (!this._config.scroll) {\n new ScrollBarHelper().reset();\n }\n\n EventHandler.trigger(this._element, EVENT_HIDDEN$3);\n };\n\n this._queueCallback(completeCallback, this._element, true);\n }\n\n dispose() {\n this._backdrop.dispose();\n\n this._focustrap.deactivate();\n\n super.dispose();\n } // Private\n\n\n _initializeBackDrop() {\n const clickCallback = () => {\n if (this._config.backdrop === 'static') {\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n return;\n }\n\n this.hide();\n }; // 'static' option will be translated to true, and booleans will keep their value\n\n\n const isVisible = Boolean(this._config.backdrop);\n return new Backdrop({\n className: CLASS_NAME_BACKDROP,\n isVisible,\n isAnimated: true,\n rootElement: this._element.parentNode,\n clickCallback: isVisible ? clickCallback : null\n });\n }\n\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n });\n }\n\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n if (event.key !== ESCAPE_KEY) {\n return;\n }\n\n if (!this._config.keyboard) {\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n return;\n }\n\n this.hide();\n });\n } // Static\n\n\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Offcanvas.getOrCreateInstance(this, config);\n\n if (typeof config !== 'string') {\n return;\n }\n\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n\n data[config](this);\n });\n }\n\n}\n/**\n * Data API implementation\n */\n\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {\n const target = getElementFromSelector(this);\n\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n\n if (isDisabled(this)) {\n return;\n }\n\n EventHandler.one(target, EVENT_HIDDEN$3, () => {\n // focus on trigger when it is closed\n if (isVisible(this)) {\n this.focus();\n }\n }); // avoid conflict when clicking a toggler of an offcanvas, while another is open\n\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);\n\n if (alreadyOpen && alreadyOpen !== target) {\n Offcanvas.getInstance(alreadyOpen).hide();\n }\n\n const data = Offcanvas.getOrCreateInstance(target);\n data.toggle(this);\n});\nEventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {\n for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {\n Offcanvas.getOrCreateInstance(selector).show();\n }\n});\nEventHandler.on(window, EVENT_RESIZE, () => {\n for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {\n if (getComputedStyle(element).position !== 'fixed') {\n Offcanvas.getOrCreateInstance(element).hide();\n }\n }\n});\nenableDismissTrigger(Offcanvas);\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Offcanvas);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\nconst uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i;\n/**\n * A pattern that recognizes a commonly useful subset of URLs that are safe.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts\n */\n\nconst SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;\n/**\n * A pattern that matches safe data URLs. Only matches image, video and audio types.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts\n */\n\nconst DATA_URL_PATTERN = /^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[\\d+/a-z]+=*$/i;\n\nconst allowedAttribute = (attribute, allowedAttributeList) => {\n const attributeName = attribute.nodeName.toLowerCase();\n\n if (allowedAttributeList.includes(attributeName)) {\n if (uriAttributes.has(attributeName)) {\n return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue));\n }\n\n return true;\n } // Check if a regular expression validates the attribute.\n\n\n return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName));\n};\n\nconst DefaultAllowlist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n};\nfunction sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {\n if (!unsafeHtml.length) {\n return unsafeHtml;\n }\n\n if (sanitizeFunction && typeof sanitizeFunction === 'function') {\n return sanitizeFunction(unsafeHtml);\n }\n\n const domParser = new window.DOMParser();\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');\n const elements = [].concat(...createdDocument.body.querySelectorAll('*'));\n\n for (const element of elements) {\n const elementName = element.nodeName.toLowerCase();\n\n if (!Object.keys(allowList).includes(elementName)) {\n element.remove();\n continue;\n }\n\n const attributeList = [].concat(...element.attributes);\n const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);\n\n for (const attribute of attributeList) {\n if (!allowedAttribute(attribute, allowedAttributes)) {\n element.removeAttribute(attribute.nodeName);\n }\n }\n }\n\n return createdDocument.body.innerHTML;\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): util/template-factory.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$5 = 'TemplateFactory';\nconst Default$4 = {\n allowList: DefaultAllowlist,\n content: {},\n // { selector : text , selector2 : text2 , }\n extraClass: '',\n html: false,\n sanitize: true,\n sanitizeFn: null,\n template: '
'\n};\nconst DefaultType$4 = {\n allowList: 'object',\n content: 'object',\n extraClass: '(string|function)',\n html: 'boolean',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n template: 'string'\n};\nconst DefaultContentType = {\n entry: '(string|element|function|null)',\n selector: '(string|element)'\n};\n/**\n * Class definition\n */\n\nclass TemplateFactory extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n } // Getters\n\n\n static get Default() {\n return Default$4;\n }\n\n static get DefaultType() {\n return DefaultType$4;\n }\n\n static get NAME() {\n return NAME$5;\n } // Public\n\n\n getContent() {\n return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean);\n }\n\n hasContent() {\n return this.getContent().length > 0;\n }\n\n changeContent(content) {\n this._checkContent(content);\n\n this._config.content = { ...this._config.content,\n ...content\n };\n return this;\n }\n\n toHtml() {\n const templateWrapper = document.createElement('div');\n templateWrapper.innerHTML = this._maybeSanitize(this._config.template);\n\n for (const [selector, text] of Object.entries(this._config.content)) {\n this._setContent(templateWrapper, text, selector);\n }\n\n const template = templateWrapper.children[0];\n\n const extraClass = this._resolvePossibleFunction(this._config.extraClass);\n\n if (extraClass) {\n template.classList.add(...extraClass.split(' '));\n }\n\n return template;\n } // Private\n\n\n _typeCheckConfig(config) {\n super._typeCheckConfig(config);\n\n this._checkContent(config.content);\n }\n\n _checkContent(arg) {\n for (const [selector, content] of Object.entries(arg)) {\n super._typeCheckConfig({\n selector,\n entry: content\n }, DefaultContentType);\n }\n }\n\n _setContent(template, content, selector) {\n const templateElement = SelectorEngine.findOne(selector, template);\n\n if (!templateElement) {\n return;\n }\n\n content = this._resolvePossibleFunction(content);\n\n if (!content) {\n templateElement.remove();\n return;\n }\n\n if (isElement(content)) {\n this._putElementInTemplate(getElement(content), templateElement);\n\n return;\n }\n\n if (this._config.html) {\n templateElement.innerHTML = this._maybeSanitize(content);\n return;\n }\n\n templateElement.textContent = content;\n }\n\n _maybeSanitize(arg) {\n return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg;\n }\n\n _resolvePossibleFunction(arg) {\n return typeof arg === 'function' ? arg(this) : arg;\n }\n\n _putElementInTemplate(element, templateElement) {\n if (this._config.html) {\n templateElement.innerHTML = '';\n templateElement.append(element);\n return;\n }\n\n templateElement.textContent = element.textContent;\n }\n\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$4 = 'tooltip';\nconst DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);\nconst CLASS_NAME_FADE$2 = 'fade';\nconst CLASS_NAME_MODAL = 'modal';\nconst CLASS_NAME_SHOW$2 = 'show';\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner';\nconst SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;\nconst EVENT_MODAL_HIDE = 'hide.bs.modal';\nconst TRIGGER_HOVER = 'hover';\nconst TRIGGER_FOCUS = 'focus';\nconst TRIGGER_CLICK = 'click';\nconst TRIGGER_MANUAL = 'manual';\nconst EVENT_HIDE$2 = 'hide';\nconst EVENT_HIDDEN$2 = 'hidden';\nconst EVENT_SHOW$2 = 'show';\nconst EVENT_SHOWN$2 = 'shown';\nconst EVENT_INSERTED = 'inserted';\nconst EVENT_CLICK$1 = 'click';\nconst EVENT_FOCUSIN$1 = 'focusin';\nconst EVENT_FOCUSOUT$1 = 'focusout';\nconst EVENT_MOUSEENTER = 'mouseenter';\nconst EVENT_MOUSELEAVE = 'mouseleave';\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: isRTL() ? 'left' : 'right',\n BOTTOM: 'bottom',\n LEFT: isRTL() ? 'right' : 'left'\n};\nconst Default$3 = {\n allowList: DefaultAllowlist,\n animation: true,\n boundary: 'clippingParents',\n container: false,\n customClass: '',\n delay: 0,\n fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n html: false,\n offset: [0, 0],\n placement: 'top',\n popperConfig: null,\n sanitize: true,\n sanitizeFn: null,\n selector: false,\n template: '
' + '
' + '
' + '
',\n title: '',\n trigger: 'hover focus'\n};\nconst DefaultType$3 = {\n allowList: 'object',\n animation: 'boolean',\n boundary: '(string|element)',\n container: '(string|element|boolean)',\n customClass: '(string|function)',\n delay: '(number|object)',\n fallbackPlacements: 'array',\n html: 'boolean',\n offset: '(array|string|function)',\n placement: '(string|function)',\n popperConfig: '(null|object|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n selector: '(string|boolean)',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string'\n};\n/**\n * Class definition\n */\n\nclass Tooltip extends BaseComponent {\n constructor(element, config) {\n if (typeof Popper === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)');\n }\n\n super(element, config); // Private\n\n this._isEnabled = true;\n this._timeout = 0;\n this._isHovered = null;\n this._activeTrigger = {};\n this._popper = null;\n this._templateFactory = null;\n this._newContent = null; // Protected\n\n this.tip = null;\n\n this._setListeners();\n\n if (!this._config.selector) {\n this._fixTitle();\n }\n } // Getters\n\n\n static get Default() {\n return Default$3;\n }\n\n static get DefaultType() {\n return DefaultType$3;\n }\n\n static get NAME() {\n return NAME$4;\n } // Public\n\n\n enable() {\n this._isEnabled = true;\n }\n\n disable() {\n this._isEnabled = false;\n }\n\n toggleEnabled() {\n this._isEnabled = !this._isEnabled;\n }\n\n toggle() {\n if (!this._isEnabled) {\n return;\n }\n\n this._activeTrigger.click = !this._activeTrigger.click;\n\n if (this._isShown()) {\n this._leave();\n\n return;\n }\n\n this._enter();\n }\n\n dispose() {\n clearTimeout(this._timeout);\n EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n\n if (this._element.getAttribute('data-bs-original-title')) {\n this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'));\n }\n\n this._disposePopper();\n\n super.dispose();\n }\n\n show() {\n if (this._element.style.display === 'none') {\n throw new Error('Please use show on visible elements');\n }\n\n if (!(this._isWithContent() && this._isEnabled)) {\n return;\n }\n\n const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2));\n const shadowRoot = findShadowRoot(this._element);\n\n const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element);\n\n if (showEvent.defaultPrevented || !isInTheDom) {\n return;\n } // todo v6 remove this OR make it optional\n\n\n this._disposePopper();\n\n const tip = this._getTipElement();\n\n this._element.setAttribute('aria-describedby', tip.getAttribute('id'));\n\n const {\n container\n } = this._config;\n\n if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n container.append(tip);\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED));\n }\n\n this._popper = this._createPopper(tip);\n tip.classList.add(CLASS_NAME_SHOW$2); // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop);\n }\n }\n\n const complete = () => {\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2));\n\n if (this._isHovered === false) {\n this._leave();\n }\n\n this._isHovered = false;\n };\n\n this._queueCallback(complete, this.tip, this._isAnimated());\n }\n\n hide() {\n if (!this._isShown()) {\n return;\n }\n\n const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2));\n\n if (hideEvent.defaultPrevented) {\n return;\n }\n\n const tip = this._getTipElement();\n\n tip.classList.remove(CLASS_NAME_SHOW$2); // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop);\n }\n }\n\n this._activeTrigger[TRIGGER_CLICK] = false;\n this._activeTrigger[TRIGGER_FOCUS] = false;\n this._activeTrigger[TRIGGER_HOVER] = false;\n this._isHovered = null; // it is a trick to support manual triggering\n\n const complete = () => {\n if (this._isWithActiveTrigger()) {\n return;\n }\n\n if (!this._isHovered) {\n this._disposePopper();\n }\n\n this._element.removeAttribute('aria-describedby');\n\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2));\n };\n\n this._queueCallback(complete, this.tip, this._isAnimated());\n }\n\n update() {\n if (this._popper) {\n this._popper.update();\n }\n } // Protected\n\n\n _isWithContent() {\n return Boolean(this._getTitle());\n }\n\n _getTipElement() {\n if (!this.tip) {\n this.tip = this._createTipElement(this._newContent || this._getContentForTemplate());\n }\n\n return this.tip;\n }\n\n _createTipElement(content) {\n const tip = this._getTemplateFactory(content).toHtml(); // todo: remove this check on v6\n\n\n if (!tip) {\n return null;\n }\n\n tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2); // todo: on v6 the following can be achieved with CSS only\n\n tip.classList.add(`bs-${this.constructor.NAME}-auto`);\n const tipId = getUID(this.constructor.NAME).toString();\n tip.setAttribute('id', tipId);\n\n if (this._isAnimated()) {\n tip.classList.add(CLASS_NAME_FADE$2);\n }\n\n return tip;\n }\n\n setContent(content) {\n this._newContent = content;\n\n if (this._isShown()) {\n this._disposePopper();\n\n this.show();\n }\n }\n\n _getTemplateFactory(content) {\n if (this._templateFactory) {\n this._templateFactory.changeContent(content);\n } else {\n this._templateFactory = new TemplateFactory({ ...this._config,\n // the `content` var has to be after `this._config`\n // to override config.content in case of popover\n content,\n extraClass: this._resolvePossibleFunction(this._config.customClass)\n });\n }\n\n return this._templateFactory;\n }\n\n _getContentForTemplate() {\n return {\n [SELECTOR_TOOLTIP_INNER]: this._getTitle()\n };\n }\n\n _getTitle() {\n return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title');\n } // Private\n\n\n _initializeOnDelegatedTarget(event) {\n return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());\n }\n\n _isAnimated() {\n return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2);\n }\n\n _isShown() {\n return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2);\n }\n\n _createPopper(tip) {\n const placement = typeof this._config.placement === 'function' ? this._config.placement.call(this, tip, this._element) : this._config.placement;\n const attachment = AttachmentMap[placement.toUpperCase()];\n return Popper.createPopper(this._element, tip, this._getPopperConfig(attachment));\n }\n\n _getOffset() {\n const {\n offset\n } = this._config;\n\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10));\n }\n\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element);\n }\n\n return offset;\n }\n\n _resolvePossibleFunction(arg) {\n return typeof arg === 'function' ? arg.call(this._element) : arg;\n }\n\n _getPopperConfig(attachment) {\n const defaultBsPopperConfig = {\n placement: attachment,\n modifiers: [{\n name: 'flip',\n options: {\n fallbackPlacements: this._config.fallbackPlacements\n }\n }, {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }, {\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n }, {\n name: 'arrow',\n options: {\n element: `.${this.constructor.NAME}-arrow`\n }\n }, {\n name: 'preSetPlacement',\n enabled: true,\n phase: 'beforeMain',\n fn: data => {\n // Pre-set Popper's placement attribute in order to read the arrow sizes properly.\n // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement\n this._getTipElement().setAttribute('data-popper-placement', data.state.placement);\n }\n }]\n };\n return { ...defaultBsPopperConfig,\n ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)\n };\n }\n\n _setListeners() {\n const triggers = this._config.trigger.split(' ');\n\n for (const trigger of triggers) {\n if (trigger === 'click') {\n EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n\n context.toggle();\n });\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1);\n const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1);\n EventHandler.on(this._element, eventIn, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n\n context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;\n\n context._enter();\n });\n EventHandler.on(this._element, eventOut, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n\n context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);\n\n context._leave();\n });\n }\n }\n\n this._hideModalHandler = () => {\n if (this._element) {\n this.hide();\n }\n };\n\n EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n }\n\n _fixTitle() {\n const title = this._element.getAttribute('title');\n\n if (!title) {\n return;\n }\n\n if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {\n this._element.setAttribute('aria-label', title);\n }\n\n this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility\n\n\n this._element.removeAttribute('title');\n }\n\n _enter() {\n if (this._isShown() || this._isHovered) {\n this._isHovered = true;\n return;\n }\n\n this._isHovered = true;\n\n this._setTimeout(() => {\n if (this._isHovered) {\n this.show();\n }\n }, this._config.delay.show);\n }\n\n _leave() {\n if (this._isWithActiveTrigger()) {\n return;\n }\n\n this._isHovered = false;\n\n this._setTimeout(() => {\n if (!this._isHovered) {\n this.hide();\n }\n }, this._config.delay.hide);\n }\n\n _setTimeout(handler, timeout) {\n clearTimeout(this._timeout);\n this._timeout = setTimeout(handler, timeout);\n }\n\n _isWithActiveTrigger() {\n return Object.values(this._activeTrigger).includes(true);\n }\n\n _getConfig(config) {\n const dataAttributes = Manipulator.getDataAttributes(this._element);\n\n for (const dataAttribute of Object.keys(dataAttributes)) {\n if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {\n delete dataAttributes[dataAttribute];\n }\n }\n\n config = { ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n };\n config = this._mergeConfigObj(config);\n config = this._configAfterMerge(config);\n\n this._typeCheckConfig(config);\n\n return config;\n }\n\n _configAfterMerge(config) {\n config.container = config.container === false ? document.body : getElement(config.container);\n\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n };\n }\n\n if (typeof config.title === 'number') {\n config.title = config.title.toString();\n }\n\n if (typeof config.content === 'number') {\n config.content = config.content.toString();\n }\n\n return config;\n }\n\n _getDelegateConfig() {\n const config = {};\n\n for (const key in this._config) {\n if (this.constructor.Default[key] !== this._config[key]) {\n config[key] = this._config[key];\n }\n }\n\n config.selector = false;\n config.trigger = 'manual'; // In the future can be replaced with:\n // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n // `Object.fromEntries(keysWithDifferentValues)`\n\n return config;\n }\n\n _disposePopper() {\n if (this._popper) {\n this._popper.destroy();\n\n this._popper = null;\n }\n\n if (this.tip) {\n this.tip.remove();\n this.tip = null;\n }\n } // Static\n\n\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Tooltip.getOrCreateInstance(this, config);\n\n if (typeof config !== 'string') {\n return;\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n\n data[config]();\n });\n }\n\n}\n/**\n * jQuery\n */\n\n\ndefineJQueryPlugin(Tooltip);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$3 = 'popover';\nconst SELECTOR_TITLE = '.popover-header';\nconst SELECTOR_CONTENT = '.popover-body';\nconst Default$2 = { ...Tooltip.Default,\n content: '',\n offset: [0, 8],\n placement: 'right',\n template: '
' + '
' + '

' + '
' + '
',\n trigger: 'click'\n};\nconst DefaultType$2 = { ...Tooltip.DefaultType,\n content: '(null|string|element|function)'\n};\n/**\n * Class definition\n */\n\nclass Popover extends Tooltip {\n // Getters\n static get Default() {\n return Default$2;\n }\n\n static get DefaultType() {\n return DefaultType$2;\n }\n\n static get NAME() {\n return NAME$3;\n } // Overrides\n\n\n _isWithContent() {\n return this._getTitle() || this._getContent();\n } // Private\n\n\n _getContentForTemplate() {\n return {\n [SELECTOR_TITLE]: this._getTitle(),\n [SELECTOR_CONTENT]: this._getContent()\n };\n }\n\n _getContent() {\n return this._resolvePossibleFunction(this._config.content);\n } // Static\n\n\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Popover.getOrCreateInstance(this, config);\n\n if (typeof config !== 'string') {\n return;\n }\n\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n\n data[config]();\n });\n }\n\n}\n/**\n * jQuery\n */\n\n\ndefineJQueryPlugin(Popover);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap (v5.2.3): scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n/**\n * Constants\n */\n\nconst NAME$2 = 'scrollspy';\nconst DATA_KEY$2 = 'bs.scrollspy';\nconst EVENT_KEY$2 = `.${DATA_KEY$2}`;\nconst DATA_API_KEY = '.data-api';\nconst EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;\nconst EVENT_CLICK = `click${EVENT_KEY$2}`;\nconst EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`;\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';\nconst CLASS_NAME_ACTIVE$1 = 'active';\nconst SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]';\nconst SELECTOR_TARGET_LINKS = '[href]';\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';\nconst SELECTOR_NAV_LINKS = '.nav-link';\nconst SELECTOR_NAV_ITEMS = '.nav-item';\nconst SELECTOR_LIST_ITEMS = '.list-group-item';\nconst SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;\nconst SELECTOR_DROPDOWN = '.dropdown';\nconst SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';\nconst Default$1 = {\n offset: null,\n // TODO: v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: '0px 0px -25%',\n smoothScroll: false,\n target: null,\n threshold: [0.1, 0.5, 1]\n};\nconst DefaultType$1 = {\n offset: '(number|null)',\n // TODO v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: 'string',\n smoothScroll: 'boolean',\n target: 'element',\n threshold: 'array'\n};\n/**\n * Class definition\n */\n\nclass ScrollSpy extends BaseComponent {\n constructor(element, config) {\n super(element, config); // this._element is the observablesContainer and config.target the menu links wrapper\n\n this._targetLinks = new Map();\n this._observableSections = new Map();\n this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;\n this._activeTarget = null;\n this._observer = null;\n this._previousScrollData = {\n visibleEntryTop: 0,\n parentScrollTop: 0\n };\n this.refresh(); // initialize\n } // Getters\n\n\n static get Default() {\n return Default$1;\n }\n\n static get DefaultType() {\n return DefaultType$1;\n }\n\n static get NAME() {\n return NAME$2;\n } // Public\n\n\n refresh() {\n this._initializeTargetsAndObservables();\n\n this._maybeEnableSmoothScroll();\n\n if (this._observer) {\n this._observer.disconnect();\n } else {\n this._observer = this._getNewObserver();\n }\n\n for (const section of this._observableSections.values()) {\n this._observer.observe(section);\n }\n }\n\n dispose() {\n this._observer.disconnect();\n\n super.dispose();\n } // Private\n\n\n _configAfterMerge(config) {\n // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case\n config.target = getElement(config.target) || document.body; // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only\n\n config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;\n\n if (typeof config.threshold === 'string') {\n config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));\n }\n\n return config;\n }\n\n _maybeEnableSmoothScroll() {\n if (!this._config.smoothScroll) {\n return;\n } // unregister any previous listeners\n\n\n EventHandler.off(this._config.target, EVENT_CLICK);\n EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {\n const observableSection = this._observableSections.get(event.target.hash);\n\n if (observableSection) {\n event.preventDefault();\n const root = this._rootElement || window;\n const height = observableSection.offsetTop - this._element.offsetTop;\n\n if (root.scrollTo) {\n root.scrollTo({\n top: height,\n behavior: 'smooth'\n });\n return;\n } // Chrome 60 doesn't support `scrollTo`\n\n\n root.scrollTop = height;\n }\n });\n }\n\n _getNewObserver() {\n const options = {\n root: this._rootElement,\n threshold: this._config.threshold,\n rootMargin: this._config.rootMargin\n };\n return new IntersectionObserver(entries => this._observerCallback(entries), options);\n } // The logic of selection\n\n\n _observerCallback(entries) {\n const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);\n\n const activate = entry => {\n this._previousScrollData.visibleEntryTop = entry.target.offsetTop;\n\n this._process(targetElement(entry));\n };\n\n const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;\n const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;\n this._previousScrollData.parentScrollTop = parentScrollTop;\n\n for (const entry of entries) {\n if (!entry.isIntersecting) {\n this._activeTarget = null;\n\n this._clearActiveClass(targetElement(entry));\n\n continue;\n }\n\n const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; // if we are scrolling down, pick the bigger offsetTop\n\n if (userScrollsDown && entryIsLowerThanPrevious) {\n activate(entry); // if parent isn't scrolled, let's keep the first visible item, breaking the iteration\n\n if (!parentScrollTop) {\n return;\n }\n\n continue;\n } // if we are scrolling up, pick the smallest offsetTop\n\n\n if (!userScrollsDown && !entryIsLowerThanPrevious) {\n activate(entry);\n }\n }\n }\n\n _initializeTargetsAndObservables() {\n this._targetLinks = new Map();\n this._observableSections = new Map();\n const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target);\n\n for (const anchor of targetLinks) {\n // ensure that the anchor has an id and is not disabled\n if (!anchor.hash || isDisabled(anchor)) {\n continue;\n }\n\n const observableSection = SelectorEngine.findOne(anchor.hash, this._element); // ensure that the observableSection exists & is visible\n\n if (isVisible(observableSection)) {\n this._targetLinks.set(anchor.hash, anchor);\n\n this._observableSections.set(anchor.hash, observableSection);\n }\n }\n }\n\n _process(target) {\n if (this._activeTarget === target) {\n return;\n }\n\n this._clearActiveClass(this._config.target);\n\n this._activeTarget = target;\n target.classList.add(CLASS_NAME_ACTIVE$1);\n\n this._activateParents(target);\n\n EventHandler.trigger(this._element, EVENT_ACTIVATE, {\n relatedTarget: target\n });\n }\n\n _activateParents(target) {\n // Activate dropdown parents\n if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1);\n return;\n }\n\n for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {\n // Set triggered links parents as active\n // With both
-
+

Algorithms#

A number of generic algorithm implementations are provided including Gradient Descent (GD), Conjugate Gradient Least Squares (CGLS), @@ -497,11 +538,11 @@

AlgorithmsAlgorithm provides the infrastructure to continue iteration, to access the values of the objective function in subsequent iterations, the time for each iteration, and to provide a nice print to screen of the status of the optimisation.

-
+

Base class#

-
-class cil.optimisation.algorithms.Algorithm(**kwargs)[source]#
+
+class cil.optimisation.algorithms.Algorithm(**kwargs)[source]#

Base class for iterative algorithms

provides the minimal infrastructure.

Algorithms are iterables so can be easily run in a for loop. They will @@ -513,98 +554,98 @@

Base classrun method will stop when the stopping criterion is met.

-
-set_up(*args, **kwargs)[source]#
+
+set_up(*args, **kwargs)[source]#

Set up the algorithm

-
-update()[source]#
+
+update()[source]#

A single iteration of the algorithm

-
-should_stop()[source]#
+
+should_stop()[source]#

default stopping criterion: number of iterations

The user can change this in concrete implementation of iterative algorithms.

-
-max_iteration_stop_criterion()[source]#
+
+max_iteration_stop_criterion()[source]#

default stop criterion for iterative algorithm: max_iteration reached

-
-next()[source]#
+
+next()[source]#

Algorithm is an iterable

python2 backwards compatibility

-
-get_output()[source]#
+
+get_output()[source]#

Returns the current solution.

-
-is_provably_convergent()[source]#
+
+is_provably_convergent()[source]#

Check if the algorithm is convergent based on the provable convergence criterion.

-
-get_last_loss(**kwargs)[source]#
+
+get_last_loss(**kwargs)[source]#

Returns the last stored value of the loss function

if update_objective_interval is 1 it is the value of the objective at the current iteration. If update_objective_interval > 1 it is the last stored value.

-
-get_last_objective(**kwargs)[source]#
+
+get_last_objective(**kwargs)[source]#

alias to get_last_loss

-
-update_objective()[source]#
+
+update_objective()[source]#

calculates the objective with the current solution

-
-
-property iterations#
+
+
+property iterations#

returns the iterations at which the objective has been evaluated

-
-
-property loss#
+
+
+property loss#

returns the list of the values of the objective during the iteration

The length of this list may be shorter than the number of iterations run when the update_objective_interval > 1

-
-
-property objective#
+
+
+property objective#

alias of loss

-
-
-property max_iteration#
+
+
+property max_iteration#

gets the maximum number of iterations

-
-run(iterations=None, verbose=1, callback=None, **kwargs)[source]#
+
+run(iterations=None, verbose=1, callback=None, **kwargs)[source]#

run n iterations and update the user with the callback if specified

Parameters
@@ -624,23 +665,23 @@

Base class -
-verbose_output(verbose=False)[source]#
+
+verbose_output(verbose=False)[source]#

Creates a nice tabulated output

-

-
+

+

GD#

-
-class cil.optimisation.algorithms.GD(initial=None, objective_function=None, step_size=None, **kwargs)[source]#
+
+class cil.optimisation.algorithms.GD(initial=None, objective_function=None, step_size=None, **kwargs)[source]#

Gradient Descent algorithm

-
-set_up(initial, objective_function, step_size)[source]#
+
+set_up(initial, objective_function, step_size)[source]#

initialisation of the algorithm

Parameters
@@ -654,20 +695,20 @@

GD#<

-
-update()[source]#
+
+update()[source]#

Single iteration

-
-update_objective()[source]#
+
+update_objective()[source]#

calculates the objective with the current solution

-
-armijo_rule()[source]#
+
+armijo_rule()[source]#

Applies the Armijo rule to calculate the step size (step_size)

https://projecteuclid.org/download/pdf_1/euclid.pjm/1102995080

The Armijo rule runs a while loop to find the appropriate step_size by starting @@ -691,73 +732,73 @@

GD#<

-
-get_last_loss(**kwargs)#
+
+get_last_loss(**kwargs)#

Returns the last stored value of the loss function

if update_objective_interval is 1 it is the value of the objective at the current iteration. If update_objective_interval > 1 it is the last stored value.

-
-get_last_objective(**kwargs)#
+
+get_last_objective(**kwargs)#

alias to get_last_loss

-
-get_output()#
+
+get_output()#

Returns the current solution.

-
-is_provably_convergent()#
+
+is_provably_convergent()#

Check if the algorithm is convergent based on the provable convergence criterion.

-
-
-property iterations#
+
+
+property iterations#

returns the iterations at which the objective has been evaluated

-
-
-property loss#
+
+
+property loss#

returns the list of the values of the objective during the iteration

The length of this list may be shorter than the number of iterations run when the update_objective_interval > 1

-
-
-property max_iteration#
+
+
+property max_iteration#

gets the maximum number of iterations

-
-max_iteration_stop_criterion()#
+
+max_iteration_stop_criterion()#

default stop criterion for iterative algorithm: max_iteration reached

-
-next()#
+
+next()#

Algorithm is an iterable

python2 backwards compatibility

-
-
-property objective#
+
+
+property objective#

alias of loss

-
-run(iterations=None, verbose=1, callback=None, **kwargs)#
+
+run(iterations=None, verbose=1, callback=None, **kwargs)#

run n iterations and update the user with the callback if specified

Parameters
@@ -777,26 +818,26 @@

GD#<

-
-verbose_output(verbose=False)#
+
+verbose_output(verbose=False)#

Creates a nice tabulated output

-
-should_stop()[source]#
+
+should_stop()[source]#

default stopping criterion: number of iterations

The user can change this in concrete implementation of iterative algorithms.

-
-
+ +

CGLS#

-
-class cil.optimisation.algorithms.CGLS(initial=None, operator=None, data=None, tolerance=1e-06, **kwargs)[source]#
+
+class cil.optimisation.algorithms.CGLS(initial=None, operator=None, data=None, tolerance=1e-06, **kwargs)[source]#

Conjugate Gradient Least Squares algorithm

Problem:

@@ -816,8 +857,8 @@

CGLS#<

-
-set_up(initial, operator, data, tolerance=1e-06)[source]#
+
+set_up(initial, operator, data, tolerance=1e-06)[source]#

initialisation of the algorithm

Parameters
@@ -832,97 +873,97 @@

CGLS#<

-
-update()[source]#
+
+update()[source]#

single iteration

-
-update_objective()[source]#
+
+update_objective()[source]#

calculates the objective with the current solution

-
-should_stop()[source]#
+
+should_stop()[source]#

stopping criterion

-
-flag()[source]#
+
+flag()[source]#

returns whether the tolerance has been reached

-
-get_last_loss(**kwargs)#
+
+get_last_loss(**kwargs)#

Returns the last stored value of the loss function

if update_objective_interval is 1 it is the value of the objective at the current iteration. If update_objective_interval > 1 it is the last stored value.

-
-get_last_objective(**kwargs)#
+
+get_last_objective(**kwargs)#

alias to get_last_loss

-
-get_output()#
+
+get_output()#

Returns the current solution.

-
-is_provably_convergent()#
+
+is_provably_convergent()#

Check if the algorithm is convergent based on the provable convergence criterion.

-
-
-property iterations#
+
+
+property iterations#

returns the iterations at which the objective has been evaluated

-
-
-property loss#
+
+
+property loss#

returns the list of the values of the objective during the iteration

The length of this list may be shorter than the number of iterations run when the update_objective_interval > 1

-
-
-property max_iteration#
+
+
+property max_iteration#

gets the maximum number of iterations

-
-max_iteration_stop_criterion()#
+
+max_iteration_stop_criterion()#

default stop criterion for iterative algorithm: max_iteration reached

-
-next()#
+
+next()#

Algorithm is an iterable

python2 backwards compatibility

-
-
-property objective#
+
+
+property objective#

alias of loss

-
-run(iterations=None, verbose=1, callback=None, **kwargs)#
+
+run(iterations=None, verbose=1, callback=None, **kwargs)#

run n iterations and update the user with the callback if specified

Parameters
@@ -942,19 +983,19 @@

CGLS#<

-
-verbose_output(verbose=False)#
+
+verbose_output(verbose=False)#

Creates a nice tabulated output

-
-
+ +

SIRT#

-
-class cil.optimisation.algorithms.SIRT(initial, operator, data, lower=None, upper=None, constraint=None, **kwargs)[source]#
+
+class cil.optimisation.algorithms.SIRT(initial, operator, data, lower=None, upper=None, constraint=None, **kwargs)[source]#

Simultaneous Iterative Reconstruction Technique, see [7].

Simultaneous Iterative Reconstruction Technique (SIRT) solves the following problem

@@ -972,9 +1013,9 @@

SIRT#<
Parameters
    -
  • initial (DataContainer, default = None) – Starting point of the algorithm, default value = Zero DataContainer

  • +
  • initial (DataContainer, default = None) – Starting point of the algorithm, default value = Zero DataContainer

  • operator (LinearOperator) – The operator A.

  • -
  • data (DataContainer) – The data b.

  • +
  • data (DataContainer) – The data b.

  • lower (float, default = None) – Lower bound constraint

  • upper (float, default = None) – Upper bound constraint

  • constraint (Function, default = None) – A function with proximal method, e.g., IndicatorBox function and IndicatorBox.proximal(), @@ -1003,14 +1044,14 @@

    SIRT#<

-
-set_up(initial, operator, data, lower=None, upper=None, constraint=None)[source]#
+
+set_up(initial, operator, data, lower=None, upper=None, constraint=None)[source]#

Initialisation of the algorithm

-
-set_relaxation_parameter(value=1.0)[source]#
+
+set_relaxation_parameter(value=1.0)[source]#

Set the relaxation parameter \(\omega\)

Parameters
@@ -1020,89 +1061,89 @@

SIRT#<

-
-update()[source]#
+
+update()[source]#

Performs a single iteration of the SIRT algorithm

\[x^{k+1} = \mathrm{proj}_{C}( x^{k} + \omega * D ( A^{T} ( M * (b - Ax) ) ) )\]
-
-update_objective()[source]#
+
+update_objective()[source]#

Returns the objective

\[\|A x - b\|^{2}\]
-
-get_last_loss(**kwargs)#
+
+get_last_loss(**kwargs)#

Returns the last stored value of the loss function

if update_objective_interval is 1 it is the value of the objective at the current iteration. If update_objective_interval > 1 it is the last stored value.

-
-get_last_objective(**kwargs)#
+
+get_last_objective(**kwargs)#

alias to get_last_loss

-
-get_output()#
+
+get_output()#

Returns the current solution.

-
-is_provably_convergent()#
+
+is_provably_convergent()#

Check if the algorithm is convergent based on the provable convergence criterion.

-
-
-property iterations#
+
+
+property iterations#

returns the iterations at which the objective has been evaluated

-
-
-property loss#
+
+
+property loss#

returns the list of the values of the objective during the iteration

The length of this list may be shorter than the number of iterations run when the update_objective_interval > 1

-
-
-property max_iteration#
+
+
+property max_iteration#

gets the maximum number of iterations

-
-max_iteration_stop_criterion()#
+
+max_iteration_stop_criterion()#

default stop criterion for iterative algorithm: max_iteration reached

-
-next()#
+
+next()#

Algorithm is an iterable

python2 backwards compatibility

-
-
-property objective#
+
+
+property objective#

alias of loss

-
-run(iterations=None, verbose=1, callback=None, **kwargs)#
+
+run(iterations=None, verbose=1, callback=None, **kwargs)#

run n iterations and update the user with the callback if specified

Parameters
@@ -1122,26 +1163,26 @@

SIRT#<

-
-should_stop()#
+
+should_stop()#

default stopping criterion: number of iterations

The user can change this in concrete implementation of iterative algorithms.

-
-verbose_output(verbose=False)#
+
+verbose_output(verbose=False)#

Creates a nice tabulated output

- -
+ +

ISTA#

-
-class cil.optimisation.algorithms.ISTA(initial, f, g, step_size=None, **kwargs)[source]#
+
+class cil.optimisation.algorithms.ISTA(initial, f, g, step_size=None, **kwargs)[source]#

Iterative Shrinkage-Thresholding Algorithm, see [1], [2].

Iterative Shrinkage-Thresholding Algorithm (ISTA)

@@ -1162,7 +1203,7 @@

ISTA#<
Parameters
    -
  • initial (DataContainer) – Initial guess of ISTA.

  • +
  • initial (DataContainer) – Initial guess of ISTA.

  • f (Function) – Differentiable function. If None is passed, the algorithm will use the ZeroFunction.

  • g (Function or None) – Convex function with simple proximal operator. If None is passed, the algorithm will use the ZeroFunction.

  • step_size (positive float, default = None) – Step size for the gradient step of ISTA. @@ -1191,14 +1232,14 @@

    ISTA#<

    FISTA, GD

-
-set_step_size(step_size)[source]#
+
+set_step_size(step_size)[source]#

Set default step size.

-
-__init__(initial, f, g, step_size=None, **kwargs)[source]#
+
+__init__(initial, f, g, step_size=None, **kwargs)[source]#

Constructor

Set the minimal number of parameters:

@@ -1213,165 +1254,164 @@

ISTA#<

-
-set_up(initial, f, g, step_size, **kwargs)[source]#
+
+set_up(initial, f, g, step_size, **kwargs)[source]#

Set up of the algorithm

-
-update()[source]#
+
+update()[source]#

Performs a single iteration of ISTA

\[x_{k+1} = \mathrm{prox}_{\alpha g}(x_{k} - \alpha\nabla f(x_{k}))\]
-
-get_output()[source]#
+
+get_output()[source]#

Returns the current solution.

-
-update_objective()[source]#
+
+update_objective()[source]#

Updates the objective

\[f(x) + g(x)\]
-
-__delattr__(name, /)#
+
+__delattr__(name, /)#

Implement delattr(self, name).

-
-__dir__()#
+
+__dir__()#

Default dir() implementation.

-
-__eq__(value, /)#
+
+__eq__(value, /)#

Return self==value.

-
-__format__(format_spec, /)#
+
+__format__(format_spec, /)#

Default object formatter.

-
-__ge__(value, /)#
+
+__ge__(value, /)#

Return self>=value.

-
-__getattribute__(name, /)#
+
+__getattribute__(name, /)#

Return getattr(self, name).

-
-__gt__(value, /)#
+
+__gt__(value, /)#

Return self>value.

-
-__hash__()#
+
+__hash__()#

Return hash(self).

-
-__init_subclass__()#
+
+__init_subclass__()#

This method is called when a class is subclassed.

The default implementation does nothing. It may be overridden to extend subclasses.

-
-__iter__()#
+
+__iter__()#

Algorithm is an iterable

-
-__le__(value, /)#
+
+__le__(value, /)#

Return self<=value.

-
-__lt__(value, /)#
+
+__lt__(value, /)#

Return self<value.

-
-__ne__(value, /)#
+
+__ne__(value, /)#

Return self!=value.

-
-__new__(**kwargs)#
-

Create and return a new object. See help(type) for accurate signature.

-
+
+__new__(**kwargs)#
+
-
-__next__()#
+
+__next__()#

Algorithm is an iterable

calling this method triggers update and update_objective

-
-__reduce__()#
+
+__reduce__()#

Helper for pickle.

-
-__reduce_ex__(protocol, /)#
+
+__reduce_ex__(protocol, /)#

Helper for pickle.

-
-__repr__()#
+
+__repr__()#

Return repr(self).

-
-__setattr__(name, value, /)#
+
+__setattr__(name, value, /)#

Implement setattr(self, name, value).

-
-__sizeof__()#
+
+__sizeof__()#

Size of object in memory, in bytes.

-
-__str__()#
+
+__str__()#

Return str(self).

-
-__subclasshook__()#
+
+__subclasshook__()#

Abstract classes can override this to customize issubclass().

This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns @@ -1380,73 +1420,73 @@

ISTA#<

-
-__weakref__#
+
+__weakref__#

list of weak references to the object (if defined)

-
-get_last_loss(**kwargs)#
+
+get_last_loss(**kwargs)#

Returns the last stored value of the loss function

if update_objective_interval is 1 it is the value of the objective at the current iteration. If update_objective_interval > 1 it is the last stored value.

-
-get_last_objective(**kwargs)#
+
+get_last_objective(**kwargs)#

alias to get_last_loss

-
-is_provably_convergent()#
+
+is_provably_convergent()#

Check if the algorithm is convergent based on the provable convergence criterion.

-
-
-property iterations#
+
+
+property iterations#

returns the iterations at which the objective has been evaluated

-
-
-property loss#
+
+
+property loss#

returns the list of the values of the objective during the iteration

The length of this list may be shorter than the number of iterations run when the update_objective_interval > 1

-
-
-property max_iteration#
+
+
+property max_iteration#

gets the maximum number of iterations

-
-max_iteration_stop_criterion()#
+
+max_iteration_stop_criterion()#

default stop criterion for iterative algorithm: max_iteration reached

-
-next()#
+
+next()#

Algorithm is an iterable

python2 backwards compatibility

-
-
-property objective#
+
+
+property objective#

alias of loss

-
-run(iterations=None, verbose=1, callback=None, **kwargs)#
+
+run(iterations=None, verbose=1, callback=None, **kwargs)#

run n iterations and update the user with the callback if specified

Parameters
@@ -1466,26 +1506,26 @@

ISTA#<

-
-should_stop()#
+
+should_stop()#

default stopping criterion: number of iterations

The user can change this in concrete implementation of iterative algorithms.

-
-verbose_output(verbose=False)#
+
+verbose_output(verbose=False)#

Creates a nice tabulated output

-
-
+ +

FISTA#

-
-class cil.optimisation.algorithms.FISTA(initial, f, g, step_size=None, **kwargs)[source]#
+
+class cil.optimisation.algorithms.FISTA(initial, f, g, step_size=None, **kwargs)[source]#

Fast Iterative Shrinkage-Thresholding Algorithm, see [1], [2].

Fast Iterative Shrinkage-Thresholding Algorithm (FISTA)

@@ -1503,7 +1543,7 @@

FISTA
Parameters
    -
  • initial (DataContainer) – Starting point of the algorithm

  • +
  • initial (DataContainer) – Starting point of the algorithm

  • f (Function) – Differentiable function. If None is passed, the algorithm will use the ZeroFunction.

  • g (Function or None) – Convex function with simple proximal operator. If None is passed, the algorithm will use the ZeroFunction.

  • step_size (positive float, default = None) – Step size for the gradient step of FISTA. @@ -1529,17 +1569,17 @@

    FISTA

-
-set_step_size(step_size)[source]#
+
+set_step_size(step_size)[source]#

Set the default step size

-
-__init__(initial, f, g, step_size=None, **kwargs)[source]#
+
+__init__(initial, f, g, step_size=None, **kwargs)[source]#

Constructor

Set the minimal number of parameters:

@@ -1554,8 +1594,8 @@

FISTA

-
-update()[source]#
+
+update()[source]#

Performs a single iteration of FISTA

\[\begin{split}\begin{cases} @@ -1566,137 +1606,136 @@

FISTA

-
-__delattr__(name, /)#
+
+__delattr__(name, /)#

Implement delattr(self, name).

-
-__dir__()#
+
+__dir__()#

Default dir() implementation.

-
-__eq__(value, /)#
+
+__eq__(value, /)#

Return self==value.

-
-__format__(format_spec, /)#
+
+__format__(format_spec, /)#

Default object formatter.

-
-__ge__(value, /)#
+
+__ge__(value, /)#

Return self>=value.

-
-__getattribute__(name, /)#
+
+__getattribute__(name, /)#

Return getattr(self, name).

-
-__gt__(value, /)#
+
+__gt__(value, /)#

Return self>value.

-
-__hash__()#
+
+__hash__()#

Return hash(self).

-
-__init_subclass__()#
+
+__init_subclass__()#

This method is called when a class is subclassed.

The default implementation does nothing. It may be overridden to extend subclasses.

-
-__iter__()#
+
+__iter__()#

Algorithm is an iterable

-
-__le__(value, /)#
+
+__le__(value, /)#

Return self<=value.

-
-__lt__(value, /)#
+
+__lt__(value, /)#

Return self<value.

-
-__ne__(value, /)#
+
+__ne__(value, /)#

Return self!=value.

-
-__new__(**kwargs)#
-

Create and return a new object. See help(type) for accurate signature.

-
+
+__new__(**kwargs)#
+
-
-__next__()#
+
+__next__()#

Algorithm is an iterable

calling this method triggers update and update_objective

-
-__reduce__()#
+
+__reduce__()#

Helper for pickle.

-
-__reduce_ex__(protocol, /)#
+
+__reduce_ex__(protocol, /)#

Helper for pickle.

-
-__repr__()#
+
+__repr__()#

Return repr(self).

-
-__setattr__(name, value, /)#
+
+__setattr__(name, value, /)#

Implement setattr(self, name, value).

-
-__sizeof__()#
+
+__sizeof__()#

Size of object in memory, in bytes.

-
-__str__()#
+
+__str__()#

Return str(self).

-
-__subclasshook__()#
+
+__subclasshook__()#

Abstract classes can override this to customize issubclass().

This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns @@ -1705,79 +1744,79 @@

FISTA

-
-__weakref__#
+
+__weakref__#

list of weak references to the object (if defined)

-
-get_last_loss(**kwargs)#
+
+get_last_loss(**kwargs)#

Returns the last stored value of the loss function

if update_objective_interval is 1 it is the value of the objective at the current iteration. If update_objective_interval > 1 it is the last stored value.

-
-get_last_objective(**kwargs)#
+
+get_last_objective(**kwargs)#

alias to get_last_loss

-
-get_output()#
+
+get_output()#

Returns the current solution.

-
-is_provably_convergent()#
+
+is_provably_convergent()#

Check if the algorithm is convergent based on the provable convergence criterion.

-
-
-property iterations#
+
+
+property iterations#

returns the iterations at which the objective has been evaluated

-
-
-property loss#
+
+
+property loss#

returns the list of the values of the objective during the iteration

The length of this list may be shorter than the number of iterations run when the update_objective_interval > 1

-
-
-property max_iteration#
+
+
+property max_iteration#

gets the maximum number of iterations

-
-max_iteration_stop_criterion()#
+
+max_iteration_stop_criterion()#

default stop criterion for iterative algorithm: max_iteration reached

-
-next()#
+
+next()#

Algorithm is an iterable

python2 backwards compatibility

-
-
-property objective#
+
+
+property objective#

alias of loss

-
-run(iterations=None, verbose=1, callback=None, **kwargs)#
+
+run(iterations=None, verbose=1, callback=None, **kwargs)#

run n iterations and update the user with the callback if specified

Parameters
@@ -1797,40 +1836,40 @@

FISTA

-
-set_up(initial, f, g, step_size, **kwargs)#
+
+set_up(initial, f, g, step_size, **kwargs)#

Set up of the algorithm

-
-should_stop()#
+
+should_stop()#

default stopping criterion: number of iterations

The user can change this in concrete implementation of iterative algorithms.

-
-update_objective()#
+
+update_objective()#

Updates the objective

\[f(x) + g(x)\]
-
-verbose_output(verbose=False)#
+
+verbose_output(verbose=False)#

Creates a nice tabulated output

-
-
+ +

PDHG#

-
-class cil.optimisation.algorithms.PDHG(f, g, operator, tau=None, sigma=None, initial=None, **kwargs)[source]#
+
+class cil.optimisation.algorithms.PDHG(f, g, operator, tau=None, sigma=None, initial=None, **kwargs)[source]#

Primal Dual Hybrid Gradient (PDHG) algorithm, see [3], [4].

Parameters
@@ -1840,7 +1879,7 @@

PDHG#<
  • operator (LinearOperator) – A Linear Operator.

  • sigma (positive float, or np.ndarray, DataContainer, BlockDataContainer, optional, default=None) – Step size for the dual problem.

  • tau (positive float, or np.ndarray, DataContainer, BlockDataContainer, optional, default=None) – Step size for the primal problem.

  • -
  • initial (DataContainer, optional, default=None) – Initial point for the PDHG algorithm.

  • +
  • initial (DataContainer, optional, default=None) – Initial point for the PDHG algorithm.

  • gamma_g (positive float, optional, default=None) – Strongly convex constant if the function g is strongly convex. Allows primal acceleration of the PDHG algorithm.

  • gamma_fconj (positive float, optional, default=None) – Strongly convex constant if the convex conjugate of f is strongly convex. Allows dual acceleration of the PDHG algorithm.

  • **kwargs

    Keyward arguments used from the base class Algorithm.

    @@ -1966,8 +2005,8 @@

    PDHG#<

    Implement acceleration of PDHG when both functions are strongly convex.

  • -
    -set_gamma_g(value)[source]#
    +
    +set_gamma_g(value)[source]#

    Set the value of the strongly convex constant for function g

    Parameters
    @@ -1977,8 +2016,8 @@

    PDHG#<

    -
    -set_gamma_fconj(value)[source]#
    +
    +set_gamma_fconj(value)[source]#

    Set the value of the strongly convex constant for the convex conjugate of function f

    Parameters
    @@ -1988,8 +2027,8 @@

    PDHG#<

    -
    -set_up(f, g, operator, tau=None, sigma=None, initial=None, **kwargs)[source]#
    +
    +set_up(f, g, operator, tau=None, sigma=None, initial=None, **kwargs)[source]#

    Initialisation of the algorithm

    Parameters
    @@ -1999,7 +2038,7 @@

    PDHG#<
  • operator (LinearOperator) – A Linear Operator.

  • sigma (positive float, or np.ndarray, DataContainer, BlockDataContainer, optional, default=None) – Step size for the dual problem.

  • tau (positive float, or np.ndarray, DataContainer, BlockDataContainer, optional, default=None) – Step size for the primal problem.

  • -
  • initial (DataContainer, optional, default=None) – Initial point for the PDHG algorithm.

  • +
  • initial (DataContainer, optional, default=None) – Initial point for the PDHG algorithm.

  • theta (Relaxation parameter, Number, default 1.0) –

  • @@ -2007,20 +2046,20 @@

    PDHG#<

    -
    -get_output()[source]#
    +
    +get_output()[source]#

    Returns the current solution.

    -
    -update()[source]#
    +
    +update()[source]#

    Performs a single iteration of the PDHG algorithm

    -
    -check_convergence()[source]#
    +
    +check_convergence()[source]#

    Check whether convergence criterion for PDHG is satisfied with scalar values of tau and sigma

    Returns
    @@ -2033,8 +2072,8 @@

    PDHG#<

    -
    -set_step_sizes(sigma=None, tau=None)[source]#
    +
    +set_step_sizes(sigma=None, tau=None)[source]#

    Sets sigma and tau step-sizes for the PDHG algorithm. The step sizes can be either scalar or array-objects.

    Parameters
    @@ -2049,79 +2088,79 @@

    PDHG#<

    -
    -update_step_sizes()[source]#
    +
    +update_step_sizes()[source]#

    Updates step sizes in the cases of primal or dual acceleration using the strongly convexity property. The case where both functions are strongly convex is not available at the moment.

    -
    -update_objective()[source]#
    +
    +update_objective()[source]#

    Evaluates the primal objective, the dual objective and the primal-dual gap.

    -
    -
    -property objective#
    +
    +
    +property objective#

    alias of loss

    -
    -get_last_loss(**kwargs)#
    +
    +get_last_loss(**kwargs)#

    Returns the last stored value of the loss function

    if update_objective_interval is 1 it is the value of the objective at the current iteration. If update_objective_interval > 1 it is the last stored value.

    -
    -get_last_objective(**kwargs)#
    +
    +get_last_objective(**kwargs)#

    alias to get_last_loss

    -
    -is_provably_convergent()#
    +
    +is_provably_convergent()#

    Check if the algorithm is convergent based on the provable convergence criterion.

    -
    -
    -property iterations#
    +
    +
    +property iterations#

    returns the iterations at which the objective has been evaluated

    -
    -
    -property loss#
    +
    +
    +property loss#

    returns the list of the values of the objective during the iteration

    The length of this list may be shorter than the number of iterations run when the update_objective_interval > 1

    -
    -
    -property max_iteration#
    +
    +
    +property max_iteration#

    gets the maximum number of iterations

    -
    -max_iteration_stop_criterion()#
    +
    +max_iteration_stop_criterion()#

    default stop criterion for iterative algorithm: max_iteration reached

    -
    -next()#
    +
    +next()#

    Algorithm is an iterable

    python2 backwards compatibility

    -
    -run(iterations=None, verbose=1, callback=None, **kwargs)#
    +
    +run(iterations=None, verbose=1, callback=None, **kwargs)#

    run n iterations and update the user with the callback if specified

    Parameters
    @@ -2141,26 +2180,26 @@

    PDHG#<

    -
    -should_stop()#
    +
    +should_stop()#

    default stopping criterion: number of iterations

    The user can change this in concrete implementation of iterative algorithms.

    -
    -verbose_output(verbose=False)#
    +
    +verbose_output(verbose=False)#

    Creates a nice tabulated output

    - -
    + +

    LADMM#

    -
    -class cil.optimisation.algorithms.LADMM(f=None, g=None, operator=None, tau=None, sigma=1.0, initial=None, **kwargs)[source]#
    +
    +class cil.optimisation.algorithms.LADMM(f=None, g=None, operator=None, tau=None, sigma=1.0, initial=None, **kwargs)[source]#

    LADMM is the Linearized Alternating Direction Method of Multipliers (LADMM)

    General form of ADMM : min_{x} f(x) + g(y), subject to Ax + By = b

    Case: A = Id, B = -K, b = 0 ==> min_x f(Kx) + g(x)

    @@ -2174,91 +2213,91 @@

    LADMM

    u^{k} = u^{k-1} + Ax^{k} - z^{k}

    -
    -set_up(f, g, operator, tau=None, sigma=1.0, initial=None)[source]#
    +
    +set_up(f, g, operator, tau=None, sigma=1.0, initial=None)[source]#

    Set up the algorithm

    -
    -update()[source]#
    +
    +update()[source]#

    A single iteration of the algorithm

    -
    -update_objective()[source]#
    +
    +update_objective()[source]#

    calculates the objective with the current solution

    -
    -get_last_loss(**kwargs)#
    +
    +get_last_loss(**kwargs)#

    Returns the last stored value of the loss function

    if update_objective_interval is 1 it is the value of the objective at the current iteration. If update_objective_interval > 1 it is the last stored value.

    -
    -get_last_objective(**kwargs)#
    +
    +get_last_objective(**kwargs)#

    alias to get_last_loss

    -
    -get_output()#
    +
    +get_output()#

    Returns the current solution.

    -
    -is_provably_convergent()#
    +
    +is_provably_convergent()#

    Check if the algorithm is convergent based on the provable convergence criterion.

    -
    -
    -property iterations#
    +
    +
    +property iterations#

    returns the iterations at which the objective has been evaluated

    -
    -
    -property loss#
    +
    +
    +property loss#

    returns the list of the values of the objective during the iteration

    The length of this list may be shorter than the number of iterations run when the update_objective_interval > 1

    -
    -
    -property max_iteration#
    +
    +
    +property max_iteration#

    gets the maximum number of iterations

    -
    -max_iteration_stop_criterion()#
    +
    +max_iteration_stop_criterion()#

    default stop criterion for iterative algorithm: max_iteration reached

    -
    -next()#
    +
    +next()#

    Algorithm is an iterable

    python2 backwards compatibility

    -
    -
    -property objective#
    +
    +
    +property objective#

    alias of loss

    -
    -run(iterations=None, verbose=1, callback=None, **kwargs)#
    +
    +run(iterations=None, verbose=1, callback=None, **kwargs)#

    run n iterations and update the user with the callback if specified

    Parameters
    @@ -2278,26 +2317,26 @@

    LADMM

    -
    -should_stop()#
    +
    +should_stop()#

    default stopping criterion: number of iterations

    The user can change this in concrete implementation of iterative algorithms.

    -
    -verbose_output(verbose=False)#
    +
    +verbose_output(verbose=False)#

    Creates a nice tabulated output

    - -
    + +

    SPDHG#

    -
    -class cil.optimisation.algorithms.SPDHG(f=None, g=None, operator=None, tau=None, sigma=None, initial=None, prob=None, gamma=1.0, **kwargs)[source]#
    +
    +class cil.optimisation.algorithms.SPDHG(f=None, g=None, operator=None, tau=None, sigma=None, initial=None, prob=None, gamma=1.0, **kwargs)[source]#

    Stochastic Primal Dual Hybrid Gradient

    Problem:

    @@ -2310,7 +2349,7 @@

    SPDHG
  • operator (BlockOperator) – BlockOperator must contain Linear Operators

  • tau (positive float, optional, default=None) – Step size parameter for Primal problem

  • sigma (list of positive float, optional, default=None) – List of Step size parameters for Dual problem

  • -
  • initial (DataContainer, optional, default=None) – Initial point for the SPDHG algorithm

  • +
  • initial (DataContainer, optional, default=None) – Initial point for the SPDHG algorithm

  • prob (list of floats, optional, default=None) – List of probabilities. If None each subset will have probability = 1/number of subsets

  • gamma (float) – parameter controlling the trade-off between the primal and dual step sizes

  • **kwargs

  • @@ -2319,7 +2358,7 @@

    SPDHG

    Example

    -

    Example of usage: See https://github.com/vais-ral/CIL-Demos/blob/master/Tomography/Simulated/Single%20Channel/PDHG_vs_SPDHG.py

    +

    Example of usage: See vais-ral/CIL-Demos

    Note

    Convergence is guaranteed provided that [2, eq. (12)]:

    @@ -2350,8 +2389,8 @@

    SPDHG Matthias J Ehrhardt, Pawel Markiewicz and Carola-Bibiane Schönlieb, Physics in Medicine & Biology, Volume 64, Number 22, 2019.

    -
    -set_up(f, g, operator, tau=None, sigma=None, initial=None, prob=None, gamma=1.0, norms=None)[source]#
    +
    +set_up(f, g, operator, tau=None, sigma=None, initial=None, prob=None, gamma=1.0, norms=None)[source]#

    set-up of the algorithm :param f: Each must be a convex function with a “simple” proximal method of its conjugate :type f: BlockFunction @@ -2375,85 +2414,85 @@

    SPDHG

    -
    -update()[source]#
    +
    +update()[source]#

    A single iteration of the algorithm

    -
    -update_objective()[source]#
    +
    +update_objective()[source]#

    calculates the objective with the current solution

    -
    -
    -property objective#
    +
    +
    +property objective#

    alias of loss

    -
    -get_last_loss(**kwargs)#
    +
    +get_last_loss(**kwargs)#

    Returns the last stored value of the loss function

    if update_objective_interval is 1 it is the value of the objective at the current iteration. If update_objective_interval > 1 it is the last stored value.

    -
    -get_last_objective(**kwargs)#
    +
    +get_last_objective(**kwargs)#

    alias to get_last_loss

    -
    -get_output()#
    +
    +get_output()#

    Returns the current solution.

    -
    -is_provably_convergent()#
    +
    +is_provably_convergent()#

    Check if the algorithm is convergent based on the provable convergence criterion.

    -
    -
    -property iterations#
    +
    +
    +property iterations#

    returns the iterations at which the objective has been evaluated

    -
    -
    -property loss#
    +
    +
    +property loss#

    returns the list of the values of the objective during the iteration

    The length of this list may be shorter than the number of iterations run when the update_objective_interval > 1

    -
    -
    -property max_iteration#
    +
    +
    +property max_iteration#

    gets the maximum number of iterations

    -
    -max_iteration_stop_criterion()#
    +
    +max_iteration_stop_criterion()#

    default stop criterion for iterative algorithm: max_iteration reached

    -
    -next()#
    +
    +next()#

    Algorithm is an iterable

    python2 backwards compatibility

    -
    -run(iterations=None, verbose=1, callback=None, **kwargs)#
    +
    +run(iterations=None, verbose=1, callback=None, **kwargs)#

    run n iterations and update the user with the callback if specified

    Parameters
    @@ -2473,23 +2512,23 @@

    SPDHG

    -
    -should_stop()#
    +
    +should_stop()#

    default stopping criterion: number of iterations

    The user can change this in concrete implementation of iterative algorithms.

    -
    -verbose_output(verbose=False)#
    +
    +verbose_output(verbose=False)#

    Creates a nice tabulated output

    -

    -
    -
    + + +

    Operators#

    The two most important methods are direct and adjoint methods that describe the result of applying the operator, and its @@ -2497,38 +2536,38 @@

    OperatorsDataContainer object or subclass hereof. An important special case is to represent the tomographic forward and backprojection operations.

    -
    +

    Operator base classes#

    All operators extend the Operator class. A special class is the LinearOperator which represents an operator for which the adjoint operation is defined. A ScaledOperator represents the multiplication of any operator with a scalar.

    -
    -class cil.optimisation.operators.Operator(domain_geometry, **kwargs)[source]#
    +
    +class cil.optimisation.operators.Operator(domain_geometry, **kwargs)[source]#

    Operator that maps from a space X -> Y

    Parameters
    -
    -is_linear()[source]#
    +
    +is_linear()[source]#

    Returns if the operator is linear

    -
    -direct(x, out=None)[source]#
    +
    +direct(x, out=None)[source]#

    Returns the application of the Operator on x

    -
    -norm(**kwargs)[source]#
    +
    +norm(**kwargs)[source]#

    Returns the norm of the Operator. On first call the norm will be calculated using the operator’s calculate_norm method. Subsequent calls will return the cached norm.

    @@ -2542,8 +2581,8 @@

    Operator base classes

    -
    -set_norm(norm=None)[source]#
    +
    +set_norm(norm=None)[source]#

    Sets the norm of the operator to a custom value.

    Parameters
    @@ -2558,53 +2597,53 @@

    Operator base classes

    -
    -calculate_norm()[source]#
    +
    +calculate_norm()[source]#

    Returns the norm of the SumOperator. Note that this gives a NotImplementedError if the SumOperator is not linear.

    -
    -range_geometry()[source]#
    +
    +range_geometry()[source]#

    Returns the range of the Operator: Y space

    -
    -domain_geometry()[source]#
    +
    +domain_geometry()[source]#

    Returns the domain of the Operator: X space

    -
    -class cil.optimisation.operators.LinearOperator(domain_geometry, **kwargs)[source]#
    +
    +class cil.optimisation.operators.LinearOperator(domain_geometry, **kwargs)[source]#

    Linear operator that maps from a space X <-> Y

    Parameters
    -
    -is_linear()[source]#
    +
    +is_linear()[source]#

    Returns if the operator is linear

    -
    -adjoint(x, out=None)[source]#
    +
    +adjoint(x, out=None)[source]#

    returns the adjoint/inverse operation

    only available to linear operators

    -
    -static PowerMethod(operator, max_iteration=10, initial=None, tolerance=1e-05, return_all=False, method='auto')[source]#
    +
    +static PowerMethod(operator, max_iteration=10, initial=None, tolerance=1e-05, return_all=False, method='auto')[source]#

    Power method or Power iteration algorithm

    The Power method computes the largest (dominant) eigenvalue of a matrix in magnitude, e.g., absolute value in the real case and modulus in the complex case.

    @@ -2613,7 +2652,7 @@

    Operator base classes
    • operator (LinearOperator) –

    • max_iteration (positive:int, default=10) – Number of iterations for the Power method algorithm.

    • -
    • initial (DataContainer, default = None) – Starting point for the Power method.

    • +
    • initial (DataContainer, default = None) – Starting point for the Power method.

    • tolerance (positive:float, default = 1e-5) – Stopping criterion for the Power method. Check if two consecutive eigenvalue evaluations are below the tolerance.

    • return_all (boolean, default = False) – Toggles the verbosity of the return

    • method (string one of “auto”, “composed_with_adjoint” and “direct_only”, default = “auto”) – The default auto lets the code choose the method, this can be specified with “direct_only” or “composed_with_adjoint”

    • @@ -2657,14 +2696,14 @@

      Operator base classes

    -
    -calculate_norm()[source]#
    +
    +calculate_norm()[source]#

    Returns the norm of the LinearOperator calculated by the PowerMethod with default values.

    -
    -static dot_test(operator, domain_init=None, range_init=None, tolerance=1e-06, **kwargs)[source]#
    +
    +static dot_test(operator, domain_init=None, range_init=None, tolerance=1e-06, **kwargs)[source]#

    Does a dot linearity test on the operator Evaluates if the following equivalence holds .. math:

    @@ -2679,14 +2718,11 @@

    Operator base classes

    domain_init – optional initialisation container in the operator domain

  • seed (int, default = 1) – Seed random generator

  • tolerance (float, default 1e-6) – Check if the following expression is below the tolerance

  • -
  • math:: (.) – |Ax\times y - y \times A^Tx|/(|A||x||y| + 1e-12) < tolerance

  • +
  • math:: (..) – |Ax\times y - y \times A^Tx|/(|A||x||y| + 1e-12) < tolerance

  • -
    Returns
    -

    -
    -
    Return type
    -

    boolean, True if the test is passed.

    +
    Return type
    +

    boolean, True if the test is passed.

    @@ -2694,8 +2730,8 @@

    Operator base classes

    -
    -class cil.optimisation.operators.ScaledOperator(operator, scalar, **kwargs)[source]#
    +
    +class cil.optimisation.operators.ScaledOperator(operator, scalar, **kwargs)[source]#

    A class to represent the scalar multiplication of an Operator with a scalar. It holds an operator and a scalar. Basically it returns the multiplication of the result of direct and adjoint of the operator with the scalar. @@ -2717,34 +2753,34 @@

    Operator base classes

    -
    -direct(x, out=None)[source]#
    +
    +direct(x, out=None)[source]#

    direct method

    -
    -adjoint(x, out=None)[source]#
    +
    +adjoint(x, out=None)[source]#

    adjoint method

    -
    -norm(**kwargs)[source]#
    +
    +norm(**kwargs)[source]#

    norm of the operator

    -
    -is_linear()[source]#
    +
    +is_linear()[source]#

    returns a boolean indicating whether the operator is linear

    -
    -class cil.optimisation.operators.CompositionOperator(*operators, **kwargs)[source]#
    +
    +class cil.optimisation.operators.CompositionOperator(*operators, **kwargs)[source]#

    Composes one or more operators. For example, CompositionOperator(left, right).direct(x) is equivalent to left.direct(right.direct(x))

    @@ -2753,44 +2789,44 @@

    Operator base classes

    -
    -direct(x, out=None)[source]#
    +
    +direct(x, out=None)[source]#

    Calls the composition operator

    Parameters
    -
    -adjoint(x, out=None)[source]#
    +
    +adjoint(x, out=None)[source]#

    Calls the adjoint of the composition operator

    Parameters
    -
    -is_linear()[source]#
    +
    +is_linear()[source]#

    Returns if the operator is linear

    -
    -class cil.optimisation.operators.DiagonalOperator(diagonal, domain_geometry=None)[source]#
    +
    +class cil.optimisation.operators.DiagonalOperator(diagonal, domain_geometry=None)[source]#

    Performs an element-wise multiplication, i.e., Hadamard Product of a DataContainer x and DataContainer diagonal, d .

    @@ -2802,26 +2838,26 @@

    Operator base classes
    Parameters
      -
    • diagonal (DataContainer) – DataContainer with the same dimensions as the data to be operated on.

    • -
    • domain_geometry (ImageGeometry) – Specifies the geometry of the operator domain. If ‘None’ will use the diagonal geometry directly. default=None .

    • +
    • diagonal (DataContainer) – DataContainer with the same dimensions as the data to be operated on.

    • +
    • domain_geometry (ImageGeometry) – Specifies the geometry of the operator domain. If ‘None’ will use the diagonal geometry directly. default=None .

    -
    -direct(x, out=None)[source]#
    +
    +direct(x, out=None)[source]#

    Returns \(D\circ x\)

    -
    -adjoint(x, out=None)[source]#
    +
    +adjoint(x, out=None)[source]#

    Returns \(D^*\circ x\)

    -
    -calculate_norm(**kwargs)[source]#
    +
    +calculate_norm(**kwargs)[source]#

    Returns the operator norm of DiagonalOperator which is the \(\infty\) norm of diagonal

    \[\|D\|_{\infty} = \max_{i}\{|D_{i}|\}\]
    @@ -2830,8 +2866,8 @@

    Operator base classes

    -
    -class cil.optimisation.operators.ChannelwiseOperator(op, channels, dimension='prepend')[source]#
    +
    +class cil.optimisation.operators.ChannelwiseOperator(op, channels, dimension='prepend')[source]#

    ChannelwiseOperator: takes in a single-channel operator op and the number of channels to be used, and creates a new multi-channel ChannelwiseOperator, which will apply the operator op independently on @@ -2853,28 +2889,28 @@

    Operator base classes
    -
    -direct(x, out=None)[source]#
    +
    +direct(x, out=None)[source]#

    Returns D(x)

    -
    -adjoint(x, out=None)[source]#
    +
    +adjoint(x, out=None)[source]#

    Returns D^{*}(y)

    -
    -calculate_norm(**kwargs)[source]#
    +
    +calculate_norm(**kwargs)[source]#

    Evaluates operator norm of DiagonalOperator

    -
    -class cil.optimisation.operators.SumOperator(operator1, operator2)[source]#
    +
    +class cil.optimisation.operators.SumOperator(operator1, operator2)[source]#

    Sums two operators. For example, SumOperator(left, right).direct(x) is equivalent to left.direct(x)+right.direct(x)

    @@ -2890,74 +2926,74 @@

    Operator base classesBoth operators must have the same domain and range.

    -
    -direct(x, out=None)[source]#
    +
    +direct(x, out=None)[source]#

    Calls the sum operator

    Parameters
    -
    -adjoint(x, out=None)[source]#
    +
    +adjoint(x, out=None)[source]#

    Calls the adjoint of the sum operator

    Parameters
    -
    -is_linear()[source]#
    +
    +is_linear()[source]#

    Returns if the operator is linear

    - -
    + +

    Trivial operators#

    Trivial operators are the following.

    -
    -class cil.optimisation.operators.IdentityOperator(domain_geometry, range_geometry=None)[source]#
    +
    +class cil.optimisation.operators.IdentityOperator(domain_geometry, range_geometry=None)[source]#

    IdentityOperator: Id: X -> Y, Id(x) = xin Y

    X : gm_domain Y : gm_range ( Default: Y = X )

    -
    -direct(x, out=None)[source]#
    +
    +direct(x, out=None)[source]#

    Returns Id(x)

    -
    -adjoint(x, out=None)[source]#
    +
    +adjoint(x, out=None)[source]#

    Returns Id(x)

    -
    -calculate_norm(**kwargs)[source]#
    +
    +calculate_norm(**kwargs)[source]#

    Evaluates operator norm of IdentityOperator

    -
    -class cil.optimisation.operators.ZeroOperator(domain_geometry, range_geometry=None)[source]#
    +
    +class cil.optimisation.operators.ZeroOperator(domain_geometry, range_geometry=None)[source]#

    ZeroOperator: O: X -> Y, maps any element of \(x\in X\) into the zero element \(\in Y, O(x) = O_{Y}\)

    Parameters
    @@ -2971,28 +3007,28 @@

    Trivial operators \[ \begin{align}\begin{aligned}O^{*}: Y^{*} -> X^{*} \text{(Adjoint)}\\< O(x), y > = < x, O^{*}(y) >\end{aligned}\end{align} \]

    -
    -direct(x, out=None)[source]#
    +
    +direct(x, out=None)[source]#

    Returns O(x)

    -
    -adjoint(x, out=None)[source]#
    +
    +adjoint(x, out=None)[source]#

    Returns O^{*}(y)

    -
    -calculate_norm(**kwargs)[source]#
    +
    +calculate_norm(**kwargs)[source]#

    Evaluates operator norm of ZeroOperator

    -
    -class cil.optimisation.operators.MatrixOperator(A)[source]#
    +
    +class cil.optimisation.operators.MatrixOperator(A)[source]#

    Matrix wrapped into a LinearOperator

    Param
    @@ -3000,14 +3036,14 @@

    Trivial operators -
    -direct(x, out=None)[source]#
    +
    +direct(x, out=None)[source]#

    Returns the application of the Operator on x

    -
    -adjoint(x, out=None)[source]#
    +
    +adjoint(x, out=None)[source]#

    returns the adjoint/inverse operation

    only available to linear operators

    @@ -3015,30 +3051,30 @@

    Trivial operators -
    -class cil.optimisation.operators.MaskOperator(mask, domain_geometry=None)[source]#
    +
    +class cil.optimisation.operators.MaskOperator(mask, domain_geometry=None)[source]#
    Parameters
      -
    • mask (DataContainer) – Boolean array with the same dimensions as the data to be operated on.

    • -
    • domain_geometry (ImageGeometry) – Specifies the geometry of the operator domain. If ‘None’ will use the mask geometry size and spacing as float32. default = None .

    • +
    • mask (DataContainer) – Boolean array with the same dimensions as the data to be operated on.

    • +
    • domain_geometry (ImageGeometry) – Specifies the geometry of the operator domain. If ‘None’ will use the mask geometry size and spacing as float32. default = None .

    - -
    + +

    GradientOperator#

    -
    -class cil.optimisation.operators.GradientOperator(domain_geometry, method='forward', bnd_cond='Neumann', **kwargs)[source]#
    +
    +class cil.optimisation.operators.GradientOperator(domain_geometry, method='forward', bnd_cond='Neumann', **kwargs)[source]#

    Gradient Operator: Computes first-order forward/backward differences on 2D, 3D, 4D ImageData under Neumann/Periodic boundary conditions

    Parameters
    + +

    Functions#

    A Function represents a mathematical function of one or more inputs and is intended to accept DataContainers as input as well as any @@ -3242,11 +3278,11 @@

    Functionsproximal should return the proximal operator evaluated at an input point. The function value is evaluated by calling the function itself, e.g. f(x) for a Function f and input point x.

    -
    +

    Base classes#

    -
    -class cil.optimisation.functions.Function(L=None)[source]#
    +
    +class cil.optimisation.functions.Function(L=None)[source]#

    Abstract class representing a function

    Parameters
    @@ -3258,72 +3294,63 @@

    Base classes\(\|f'(x) - f'(y)\| \leq L \|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Returns the value of the gradient of function \(F\) evaluated at \(x\), if it is differentiable

    \[F'(x)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the gradient of the function at x or None if out

    +
    Return type
    +

    DataContainer, the value of the gradient of the function at x or None if out

    -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Returns the proximal operator of function \(\tau F\) evaluated at x

    \[\text{prox}_{\tau F}(x) = \underset{z}{\text{argmin}} \frac{1}{2}\|z - x\|^{2} + \tau F(z)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    -
    -convex_conjugate(x)[source]#
    +
    +convex_conjugate(x)[source]#

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    \[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    Parameters
    -

    x (DataContainer) –

    +

    x (DataContainer) –

    -
    Returns
    -

    -
    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    -
    -proximal_conjugate(x, tau, out=None)[source]#
    +
    +proximal_conjugate(x, tau, out=None)[source]#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -3333,43 +3360,37 @@

    Base classes
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    -
    -centered_at(center)[source]#
    +
    +centered_at(center)[source]#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    @@ -3377,8 +3398,8 @@

    Base classes -
    -class cil.optimisation.functions.SumFunction(*functions)[source]#
    +
    +class cil.optimisation.functions.SumFunction(*functions)[source]#

    SumFunction represents the sum of \(n\geq2\) functions

    \[(F_{1} + F_{2} + ... + F_{n})(\cdot) = F_{1}(\cdot) + F_{2}(\cdot) + ... + F_{n}(\cdot)\]
    @@ -3405,18 +3426,18 @@

    Base classes
    >>> F = SumFunction(*[L2NormSquared(b=i) for i in range(50)])
     
    -
    -
    -property L#
    +
    +
    +property L#

    Returns the Lipschitz constant for the SumFunction

    \[L = \sum_{i} L_{i}\]

    where \(L_{i}\) is the Lipschitz constant of the smooth function \(F_{i}\).

    -
    -
    -property Lmax#
    +
    +
    +property Lmax#

    Returns the maximum Lipschitz constant for the SumFunction

    \[L = \max_{i}\{L_{i}\}\]
    @@ -3424,92 +3445,80 @@

    Base classes -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Returns the value of the sum of the gradient of functions evaluated at \(x\), if all of them are differentiable.

    \[(F'_{1} + F'_{2} + ... + F'_{n})(x) = F'_{1}(x) + F'_{2}(x) + ... + F'_{n}(x)\]
    Parameters
      -
    • x (DataContainer) – Point to evaluate the gradient at.

    • +
    • x (DataContainer) – Point to evaluate the gradient at.

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the sum of the gradients evaluated at point \(x\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the sum of the gradients evaluated at point \(x\) or None if out.

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -convex_conjugate(x)#
    +
    +convex_conjugate(x)#

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    \[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    Parameters
    -

    x (DataContainer) –

    +

    x (DataContainer) –

    -
    Returns
    -

    -
    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    -
    -proximal(x, tau, out=None)#
    +
    +proximal(x, tau, out=None)#

    Returns the proximal operator of function \(\tau F\) evaluated at x

    \[\text{prox}_{\tau F}(x) = \underset{z}{\text{argmin}} \frac{1}{2}\|z - x\|^{2} + \tau F(z)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -3519,16 +3528,13 @@

    Base classes
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    @@ -3536,8 +3542,8 @@

    Base classes -
    -class cil.optimisation.functions.ScaledFunction(function, scalar)[source]#
    +
    +class cil.optimisation.functions.ScaledFunction(function, scalar)[source]#

    ScaledFunction represents the scalar multiplication with a Function.

    Let a function F then and a scalar \(\alpha\).

    If \(G(x) = \alpha F(x)\) then:

    @@ -3547,114 +3553,99 @@

    Base classes\(G^{*}(x^{*}) = \alpha F^{*}(\frac{x^{*}}{\alpha})\) ( convex_conjugate method )

  • \(\text{prox}_{\tau G}(x) = \text{prox}_{(\tau\alpha) F}(x)\) ( proximal method )

  • -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -convex_conjugate(x)[source]#
    +
    +convex_conjugate(x)[source]#

    Returns the convex conjugate of the scaled function.

    \[G^{*}(x^{*}) = \alpha F^{*}(\frac{x^{*}}{\alpha})\]
    Parameters
    -

    x (DataContainer) –

    -
    -
    Returns
    -

    +

    x (DataContainer) –

    -
    Return type
    -

    The value of the convex conjugate of the scaled function.

    +
    Return type
    +

    The value of the convex conjugate of the scaled function.

    -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Returns the gradient of the scaled function evaluated at \(x\).

    \[G'(x) = \alpha F'(x)\]
    Parameters
      -
    • x (DataContainer) – Point to evaluate the gradient at.

    • +
    • x (DataContainer) – Point to evaluate the gradient at.

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the gradient of the scaled function evaluated at \(x\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the gradient of the scaled function evaluated at \(x\) or None if out.

    -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Returns the proximal operator of the scaled function, evaluated at \(x\).

    \[\text{prox}_{\tau G}(x) = \text{prox}_{(\tau\alpha) F}(x)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the proximal operator of the scaled function evaluated at \(x\) with scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the proximal operator of the scaled function evaluated at \(x\) with scalar \(\tau\) or None if out.

    -
    -proximal_conjugate(x, tau, out=None)[source]#
    +
    +proximal_conjugate(x, tau, out=None)[source]#

    This returns the proximal conjugate operator for the function at \(x\), \(\tau\)

    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the proximal conjugate operator for the function evaluated at \(x\) and \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the proximal conjugate operator for the function evaluated at \(x\) and \(\tau\) or None if out.

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    +

    center (DataContainer) – The point to center the function at.

    -
    Returns
    -

    -
    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    @@ -3662,8 +3653,8 @@

    Base classes -
    -class cil.optimisation.functions.SumScalarFunction(function, constant)[source]#
    +
    +class cil.optimisation.functions.SumScalarFunction(function, constant)[source]#

    SumScalarFunction represents the sum a function with a scalar.

    \[(F + scalar)(x) = F(x) + scalar\]
    @@ -3675,59 +3666,53 @@

    Base classes -
    -convex_conjugate(x)[source]#
    +
    +convex_conjugate(x)[source]#

    Returns the convex conjugate of a \((F+scalar)\), evaluated at \(x\).

    \[(F+scalar)^{*}(x^{*}) = F^{*}(x^{*}) - scalar\]
    Parameters
    -

    x (DataContainer) –

    -
    -
    Returns
    -

    +

    x (DataContainer) –

    -
    Return type
    -

    The value of the convex conjugate evaluated at \(x\).

    +
    Return type
    +

    The value of the convex conjugate evaluated at \(x\).

    -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Returns the proximal operator of \(F+scalar\)

    \[ext{prox}_{ au (F+scalar)}(x) = ext{prox}_{ au F}\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the evaluation of the proximal operator evaluated at \(x\) and :math:` au` or None if out.

    +
    Return type
    +

    DataContainer, the evaluation of the proximal operator evaluated at \(x\) and :math:` au` or None if out.

    -
    -
    -property L#
    +
    +
    +property L#

    Returns the Lipschitz constant for the SumFunction

    \[L = \sum_{i} L_{i}\]

    where \(L_{i}\) is the Lipschitz constant of the smooth function \(F_{i}\).

    -
    -
    -property Lmax#
    +
    +
    +property Lmax#

    Returns the maximum Lipschitz constant for the SumFunction

    \[L = \max_{i}\{L_{i}\}\]
    @@ -3735,50 +3720,44 @@

    Base classes -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    +

    center (DataContainer) – The point to center the function at.

    -
    Returns
    -

    -
    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -gradient(x, out=None)#
    +
    +gradient(x, out=None)#

    Returns the value of the sum of the gradient of functions evaluated at \(x\), if all of them are differentiable.

    \[(F'_{1} + F'_{2} + ... + F'_{n})(x) = F'_{1}(x) + F'_{2}(x) + ... + F'_{n}(x)\]
    Parameters
      -
    • x (DataContainer) – Point to evaluate the gradient at.

    • +
    • x (DataContainer) – Point to evaluate the gradient at.

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the sum of the gradients evaluated at point \(x\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the sum of the gradients evaluated at point \(x\) or None if out.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -3788,16 +3767,13 @@

    Base classes
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    @@ -3805,8 +3781,8 @@

    Base classes -
    -class cil.optimisation.functions.TranslateFunction(function, center)[source]#
    +
    +class cil.optimisation.functions.TranslateFunction(function, center)[source]#

    TranslateFunction represents the translation of function F with respect to the center b.

    Let a function F and consider \(G(x) = F(x - center)\).

    Function F is centered at 0, whereas G is centered at point b.

    @@ -3817,36 +3793,33 @@

    Base classes\(G^{*}(x^{*}) = F^{*}(x^{*}) + <x^{*}, b >\) ( convex_conjugate method )

  • \(\text{prox}_{\tau G}(x) = \text{prox}_{\tau F}(x - b) + b\) ( proximal method )

  • -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -3856,114 +3829,99 @@

    Base classes
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Returns the gradient of the translated function.

    \[G'(x) = F'(x - b)\]
    Parameters
      -
    • x (DataContainer) – Point to evaluate the gradient at.

    • +
    • x (DataContainer) – Point to evaluate the gradient at.

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the gradient of the translated function evaluated at \(x\) or None if out.

    +
    Return type
    +

    DataContainer, the gradient of the translated function evaluated at \(x\) or None if out.

    -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Returns the proximal operator of the translated function.

    \[\text{prox}_{\tau G}(x) = \text{prox}_{\tau F}(x-b) + b\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the proximal operator of the translated function at \(x\) and \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the proximal operator of the translated function at \(x\) and \(\tau\) or None if out.

    -
    -convex_conjugate(x)[source]#
    +
    +convex_conjugate(x)[source]#

    Returns the convex conjugate of the translated function.

    \[G^{*}(x^{*}) = F^{*}(x^{*}) + <x^{*}, b >\]
    Parameters
    -

    x (DataContainer) –

    +

    x (DataContainer) –

    -
    Returns
    -

    -
    -
    Return type
    -

    The value of the convex conjugate of the translated function at \(x\).

    +
    Return type
    +

    The value of the convex conjugate of the translated function at \(x\).

    - -
    + +

    Simple functions#

    -
    -class cil.optimisation.functions.ConstantFunction(constant=0)[source]#
    +
    +class cil.optimisation.functions.ConstantFunction(constant=0)[source]#

    ConstantFunction: \(F(x) = constant, constant\in\mathbb{R}\)

    -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Returns the value of the gradient of the function, \(F'(x)=0\) :param x: Point to evaluate the gradient at. :type x: DataContainer :param out: :type out: return DataContainer, if None a new DataContainer is returned, default None.

    -
    Returns
    -

    -
    -
    Return type
    -

    A DataContainer of zeros, the same size as \(x\) or None if out

    +
    Return type
    +

    A DataContainer of zeros, the same size as \(x\) or None if out

    -
    -convex_conjugate(x)[source]#
    +
    +convex_conjugate(x)[source]#

    The convex conjugate of constant function \(F(x) = c\in\mathbb{R}\) is

    \[\begin{split}F(x^{*}) @@ -3980,70 +3938,61 @@

    Simple functions
    Parameters
    -

    x (DataContainer) –

    +

    x (DataContainer) –

    -
    Returns
    -

    -
    -
    Return type
    -

    The maximum of x and 0, summed over the entries of x.

    +
    Return type
    +

    The maximum of x and 0, summed over the entries of x.

    -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Returns the proximal operator of the constant function, which is the same element, i.e.,

    \[\text{prox}_{\tau F}(x) = x\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, equal to \(x\) or None if out.

    +
    Return type
    +

    DataContainer, equal to \(x\) or None if out.

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -4053,16 +4002,13 @@

    Simple functions
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    @@ -4070,39 +4016,36 @@

    Simple functions -
    -class cil.optimisation.functions.ZeroFunction[source]#
    +
    +class cil.optimisation.functions.ZeroFunction[source]#

    ZeroFunction represents the zero function, \(F(x) = 0\)

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -convex_conjugate(x)#
    +
    +convex_conjugate(x)#

    The convex conjugate of constant function \(F(x) = c\in\mathbb{R}\) is

    \[\begin{split}F(x^{*}) @@ -4119,61 +4062,52 @@

    Simple functions
    Parameters
    -

    x (DataContainer) –

    -
    -
    Returns
    -

    +

    x (DataContainer) –

    -
    Return type
    -

    The maximum of x and 0, summed over the entries of x.

    +
    Return type
    +

    The maximum of x and 0, summed over the entries of x.

    -
    -gradient(x, out=None)#
    +
    +gradient(x, out=None)#

    Returns the value of the gradient of the function, \(F'(x)=0\) :param x: Point to evaluate the gradient at. :type x: DataContainer :param out: :type out: return DataContainer, if None a new DataContainer is returned, default None.

    -
    Returns
    -

    -
    -
    Return type
    -

    A DataContainer of zeros, the same size as \(x\) or None if out

    +
    Return type
    +

    A DataContainer of zeros, the same size as \(x\) or None if out

    -
    -proximal(x, tau, out=None)#
    +
    +proximal(x, tau, out=None)#

    Returns the proximal operator of the constant function, which is the same element, i.e.,

    \[\text{prox}_{\tau F}(x) = x\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, equal to \(x\) or None if out.

    +
    Return type
    +

    DataContainer, equal to \(x\) or None if out.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -4183,16 +4117,13 @@

    Simple functions
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    @@ -4200,94 +4131,85 @@

    Simple functions -
    -class cil.optimisation.functions.Rosenbrock(alpha, beta)[source]#
    +
    +class cil.optimisation.functions.Rosenbrock(alpha, beta)[source]#

    Rosenbrock function

    \[\]

    F(x,y) = (alpha - x)^2 + beta(y-x^2)^2

    The function has a global minimum at .. math:: (x,y)=(alpha, alpha^2)

    -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Gradient of the Rosenbrock function

    \[\]

    nabla f(x,y) = left[ 2*((x-alpha) - 2beta x(y-x^2)) ; 2beta (y - x^2) right]

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    +

    center (DataContainer) – The point to center the function at.

    -
    Returns
    -

    -
    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -convex_conjugate(x)#
    +
    +convex_conjugate(x)#

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    \[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    Parameters
    -

    x (DataContainer) –

    +

    x (DataContainer) –

    -
    Returns
    -

    -
    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    -
    -proximal(x, tau, out=None)#
    +
    +proximal(x, tau, out=None)#

    Returns the proximal operator of function \(\tau F\) evaluated at x

    \[\text{prox}_{\tau F}(x) = \underset{z}{\text{argmin}} \frac{1}{2}\|z - x\|^{2} + \tau F(z)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -4297,24 +4219,21 @@

    Simple functions
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    - -
    + +

    Composition of operator and a function#

    This class allows the user to write a function which does the following:

    @@ -4324,8 +4243,8 @@

    Composition of operator and a function \[F(x) = || Ax - b ||^2_2\]

    -
    -class cil.optimisation.functions.OperatorCompositionFunction(function, operator)[source]#
    +
    +class cil.optimisation.functions.OperatorCompositionFunction(function, operator)[source]#

    Composition of a function with an operator as : \((F \otimes A)(x) = F(Ax)\)

    @@ -4339,85 +4258,76 @@

    Composition of operator and a function -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Return the gradient of F(Ax),

    ..math :: (F(Ax))’ = A^{T}F’(Ax)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -convex_conjugate(x)#
    +
    +convex_conjugate(x)#

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    \[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    Parameters
    -

    x (DataContainer) –

    -
    -
    Returns
    -

    +

    x (DataContainer) –

    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    -
    -proximal(x, tau, out=None)#
    +
    +proximal(x, tau, out=None)#

    Returns the proximal operator of function \(\tau F\) evaluated at x

    \[\text{prox}_{\tau F}(x) = \underset{z}{\text{argmin}} \frac{1}{2}\|z - x\|^{2} + \tau F(z)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -4427,28 +4337,25 @@

    Composition of operator and a function
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    -
    -
    + +

    Indicator box#

    -
    -class cil.optimisation.functions.IndicatorBox(lower=None, upper=None, accelerated=True)[source]#
    +
    +class cil.optimisation.functions.IndicatorBox(lower=None, upper=None, accelerated=True)[source]#

    Indicator function for box constraint

    @@ -4460,8 +4367,8 @@

    Indicator box
    Parameters
      -
    • lower (float, DataContainer or numpy array, default None) – Lower bound. If set to None, it is equivalent to -np.inf.

    • -
    • upper (float, DataContainer or numpy array, default None) – Upper bound. If set to None, it is equivalent to np.inf.

    • +
    • lower (float, DataContainer or numpy array, default None) – Lower bound. If set to None, it is equivalent to -np.inf.

    • +
    • upper (float, DataContainer or numpy array, default None) – Upper bound. If set to None, it is equivalent to np.inf.

    • accelerated (bool, default True) – Specifies whether to use the accelerated version or not, using numba or numpy backends respectively.

    @@ -4493,8 +4400,8 @@

    Indicator box -
    -set_suppress_evaluation(value)[source]#
    +
    +set_suppress_evaluation(value)[source]#

    Suppresses the evaluation of the function

    Parameters
    @@ -4504,17 +4411,17 @@

    Indicator box -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Proximal operator of IndicatorBox at x

    \[prox_{\tau * f}(x)\]
    Parameters
      -
    • x (DataContainer) – Input to the proximal operator

    • +
    • x (DataContainer) – Input to the proximal operator

    • tau (float) – Step size. Notice it is ignored in IndicatorBox

    • -
    • out (DataContainer, optional) – Output of the proximal operator. If not provided, a new DataContainer is created.

    • +
    • out (DataContainer, optional) – Output of the proximal operator. If not provided, a new DataContainer is created.

    @@ -4525,74 +4432,68 @@

    Indicator box -
    -gradient(x)[source]#
    +
    +gradient(x)[source]#

    IndicatorBox is not differentiable, so calling gradient will raise a ValueError

    -
    -
    -property num_threads#
    +
    +
    +property num_threads#

    Get the optional number of threads parameter to use for the accelerated version.

    Defaults to the value set in the CIL multiprocessing module.

    -
    -set_num_threads(value)[source]#
    +
    +set_num_threads(value)[source]#

    Set the optional number of threads parameter to use for the accelerated version.

    This is discarded if accelerated=False.

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -convex_conjugate(x)#
    +
    +convex_conjugate(x)#

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    \[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    Parameters
    -

    x (DataContainer) –

    -
    -
    Returns
    -

    +

    x (DataContainer) –

    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -4602,28 +4503,25 @@

    Indicator box
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    -
    -
    + +

    KullbackLeibler#

    -
    -class cil.optimisation.functions.KullbackLeibler(b, eta=None, mask=None, backend='numba')[source]#
    +
    +class cil.optimisation.functions.KullbackLeibler(b, eta=None, mask=None, backend='numba')[source]#

    Kullback Leibler

    \[\begin{split}F(u, v) @@ -4636,9 +4534,9 @@

    KullbackLeibler
    Parameters
      -
    • b (DataContainer, non-negative) – Translates the function at point b.

    • -
    • eta (DataContainer, default = 0) – Background noise

    • -
    • mask (DataContainer, default = None) – Mask for the data b

    • +
    • b (DataContainer, non-negative) – Translates the function at point b.

    • +
    • eta (DataContainer, default = 0) – Background noise

    • +
    • mask (DataContainer, default = None) – Mask for the data b

    • backend ({'numba','numpy'}, optional) – Backend for the KullbackLeibler methods. Numba is the default backend.

    @@ -4660,7 +4558,7 @@

    KullbackLeibler

    Note

    The default implementation uses the build-in function kl_div from scipy. -The methods of the KullbackLeibler are accelerated provided that numba library is installed.

    +The methods of the KullbackLeibler are accelerated provided that numba library is installed.

    Examples

    >>> from cil.optimisation.functions import KullbackLeibler
    @@ -4670,100 +4568,88 @@ 

    KullbackLeibler>>> F = KullbackLeibler(b = data)

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -convex_conjugate(x)#
    +
    +convex_conjugate(x)#

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    \[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    Parameters
    -

    x (DataContainer) –

    -
    -
    Returns
    -

    +

    x (DataContainer) –

    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    -
    -gradient(x, out=None)#
    +
    +gradient(x, out=None)#

    Returns the value of the gradient of function \(F\) evaluated at \(x\), if it is differentiable

    \[F'(x)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the gradient of the function at x or None if out

    +
    Return type
    +

    DataContainer, the value of the gradient of the function at x or None if out

    -
    -proximal(x, tau, out=None)#
    +
    +proximal(x, tau, out=None)#

    Returns the proximal operator of function \(\tau F\) evaluated at x

    \[\text{prox}_{\tau F}(x) = \underset{z}{\text{argmin}} \frac{1}{2}\|z - x\|^{2} + \tau F(z)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -4773,28 +4659,25 @@

    KullbackLeibler
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    -
    -
    + +

    L1 Norm#

    -
    -class cil.optimisation.functions.L1Norm(b=None, weight=None)[source]#
    +
    +class cil.optimisation.functions.L1Norm(b=None, weight=None)[source]#

    L1Norm function

    Consider the following cases:

      @@ -4818,14 +4701,14 @@

      L1 Norm
      Parameters
        -
      • weight (DataContainer, numpy ndarray, default None) – Array of positive weights. If None returns the L1 Norm.

      • -
      • b (DataContainer, default None) – Translation of the function.

      • +
      • weight (DataContainer, numpy ndarray, default None) – Array of positive weights. If None returns the L1 Norm.

      • +
      • b (DataContainer, default None) – Translation of the function.

    -
    -convex_conjugate(x)[source]#
    +
    +convex_conjugate(x)[source]#

    Returns the value of the convex conjugate of the L1 Norm function at x.

    This is the indicator of the unit \(L^{\infty}\) norm:

      @@ -4857,7 +4740,7 @@

      L1 Norm\(\|x\|_{L^\infty(w^{-1})} = \max_{i} \frac{|x_i|}{w_i}\).

      Parameters
      -

      x (DataContainer) – where to evaluate the convex conjugate of the L1 Norm function.

      +

      x (DataContainer) – where to evaluate the convex conjugate of the L1 Norm function.

      Returns

      the value of the convex conjugate of the WeightedL1Norm function at x

      @@ -4869,8 +4752,8 @@

      L1 Norm -
      -proximal(x, tau, out=None)[source]#
      +
      +proximal(x, tau, out=None)[source]#

      Returns the value of the proximal operator of the L1 Norm function at x with scaling parameter tau.

      Consider the following cases:

        @@ -4897,9 +4780,9 @@

        L1 Norm
        Parameters
        Returns
        @@ -4911,58 +4794,52 @@

        L1 Norm -
        -property L#
        +
        +
        +property L#

        Lipschitz of the gradient of function f.

        L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

        -
        -centered_at(center)#
        +
        +centered_at(center)#
        Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

        TranslateFunction is \(F(x - b)\) and the center is at point b.

        Parameters
        -

        center (DataContainer) – The point to center the function at.

        -
        -
        Returns
        -

        +

        center (DataContainer) – The point to center the function at.

        -
        Return type
        -

        The translated function.

        +
        Return type
        +

        The translated function.

        -
        -gradient(x, out=None)#
        +
        +gradient(x, out=None)#

        Returns the value of the gradient of function \(F\) evaluated at \(x\), if it is differentiable

        \[F'(x)\]
        Parameters
          -
        • x (DataContainer) –

        • +
        • x (DataContainer) –

        • out (return DataContainer, if None a new DataContainer is returned, default None.) –

        -
        Returns
        -

        -
        -
        Return type
        -

        DataContainer, the value of the gradient of the function at x or None if out

        +
        Return type
        +

        DataContainer, the value of the gradient of the function at x or None if out

        -
        -proximal_conjugate(x, tau, out=None)#
        +
        +proximal_conjugate(x, tau, out=None)#

        Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

        \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
        @@ -4972,28 +4849,25 @@

        L1 Norm
        Parameters
        -
        Returns
        -

        -
        -
        Return type
        -

        DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

        +
        Return type
        +

        DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    -
    -
    + +

    L2 Norm Squared#

    -
    -class cil.optimisation.functions.L2NormSquared(**kwargs)[source]#
    +
    +class cil.optimisation.functions.L2NormSquared(**kwargs)[source]#

    L2NormSquared function: \(F(x) = \| x\|^{2}_{2} = \underset{i}{\sum}x_{i}^{2}\)

    Following cases are considered:

    @@ -5018,8 +4892,8 @@

    L2 Norm Squared -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Returns the value of the gradient of the L2NormSquared function at x.

    Following cases are considered:

    @@ -5031,8 +4905,8 @@

    L2 Norm Squared -
    -convex_conjugate(x)[source]#
    +
    +convex_conjugate(x)[source]#

    Returns the value of the convex conjugate of the L2NormSquared function at x.

    Consider the following cases:

    @@ -5048,8 +4922,8 @@

    L2 Norm Squared -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Returns the value of the proximal operator of the L2NormSquared function at x.

    Consider the following cases:

    @@ -5064,36 +4938,33 @@

    L2 Norm Squared -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -5103,16 +4974,13 @@

    L2 Norm Squared
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    @@ -5120,8 +4988,8 @@

    L2 Norm Squared -
    -class cil.optimisation.functions.WeightedL2NormSquared(**kwargs)[source]#
    +
    +class cil.optimisation.functions.WeightedL2NormSquared(**kwargs)[source]#

    WeightedL2NormSquared function: \(F(x) = \|x\|_{W,2}^2 = \Sigma_iw_ix_i^2 = \langle x, Wx\rangle = x^TWx\) where \(W=\text{diag}(weight)\) if weight is a DataContainer or \(W=\text{weight} I\) if weight is a scalar.

    @@ -5134,54 +5002,51 @@

    L2 Norm Squared -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Returns the value of \(F'(x) = 2Wx\) or, if b is defined, \(F'(x) = 2W(x-b)\) where \(W=\text{diag}(weight)\) if weight is a DataContainer or \(\text{weight}I\) if weight is a scalar.

    -
    -convex_conjugate(x)[source]#
    +
    +convex_conjugate(x)[source]#

    Returns the value of the convex conjugate of the WeightedL2NormSquared function at x.

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    +

    center (DataContainer) – The point to center the function at.

    -
    Returns
    -

    -
    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Returns the value of the proximal operator of the WeightedL2NormSquared function at x.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -5191,28 +5056,25 @@

    L2 Norm Squared
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    -

    -
    + +

    Least Squares#

    -
    -class cil.optimisation.functions.LeastSquares(A, b, c=1.0, weight=None)[source]#
    +
    +class cil.optimisation.functions.LeastSquares(A, b, c=1.0, weight=None)[source]#

    (Weighted) Least Squares function

    \[F(x) = c\|Ax-b\|_2^2\]
    @@ -5224,7 +5086,7 @@

    Least SquaresParameters
    • A (LinearOperator) –

    • -
    • b (Data, DataContainer) –

    • +
    • b (Data, DataContainer) –

    • c (Scaling Constant, float, default 1.0) –

    • weight (DataContainer with all positive elements of size of the range of operator A, default None) –

    @@ -5235,8 +5097,8 @@

    Least Squares\(F\) which is \(2 c ||A||_2^2 = 2 c \sigma_1(A)^2\), or \(2 c ||W|| ||A||_2^2 = 2c||W|| \sigma_1(A)^2\), where \(\sigma_1(A)\) is the largest singular value of \(A\) and \(W=\text{diag}(weight)\).

    -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Returns the value of the gradient of \(F(x)\):

    \[F'(x) = 2cA^T(Ax-b)\]
    @@ -5246,78 +5108,69 @@

    Least Squares\(W=\text{diag}(weight)\).

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -convex_conjugate(x)#
    +
    +convex_conjugate(x)#

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    \[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    Parameters
    -

    x (DataContainer) –

    -
    -
    Returns
    -

    +

    x (DataContainer) –

    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    -
    -proximal(x, tau, out=None)#
    +
    +proximal(x, tau, out=None)#

    Returns the proximal operator of function \(\tau F\) evaluated at x

    \[\text{prox}_{\tau F}(x) = \underset{z}{\text{argmin}} \frac{1}{2}\|z - x\|^{2} + \tau F(z)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -5327,33 +5180,30 @@

    Least Squares
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    - -
    + +

    Mixed L21 norm#

    -
    -class cil.optimisation.functions.MixedL21Norm(**kwargs)[source]#
    +
    +class cil.optimisation.functions.MixedL21Norm(**kwargs)[source]#

    MixedL21Norm function: \(F(x) = ||x||_{2,1} = \sum |x|_{2} = \sum \sqrt{ (x^{1})^{2} + (x^{2})^{2} + \dots}\)

    where x is a BlockDataContainer, i.e., \(x=(x^{1}, x^{2}, \dots)\)

    -
    -convex_conjugate(x)[source]#
    +
    +convex_conjugate(x)[source]#

    Returns the value of the convex conjugate of the MixedL21Norm function at x.

    This is the Indicator function of \(\mathbb{I}_{\{\|\cdot\|_{2,\infty}\leq1\}}(x^{*})\),

    i.e.,

    @@ -5369,66 +5219,60 @@

    Mixed L21 norm -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Returns the value of the proximal operator of the MixedL21Norm function at x.

    \[\mathrm{prox}_{\tau F}(x) = \frac{x}{\|x\|_{2}}\max\{ \|x\|_{2} - \tau, 0 \}\]

    where the convention 0 · (0/0) = 0 is used.

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    +

    center (DataContainer) – The point to center the function at.

    -
    Returns
    -

    -
    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -gradient(x, out=None)#
    +
    +gradient(x, out=None)#

    Returns the value of the gradient of function \(F\) evaluated at \(x\), if it is differentiable

    \[F'(x)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the gradient of the function at x or None if out

    +
    Return type
    +

    DataContainer, the value of the gradient of the function at x or None if out

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -5438,110 +5282,98 @@

    Mixed L21 norm
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    -
    -
    + +

    Smooth Mixed L21 norm#

    -
    -class cil.optimisation.functions.SmoothMixedL21Norm(epsilon)[source]#
    +
    +class cil.optimisation.functions.SmoothMixedL21Norm(epsilon)[source]#

    SmoothMixedL21Norm function: \(F(x) = ||x||_{2,1} = \sum |x|_{2} = \sum \sqrt{ (x^{1})^{2} + (x^{2})^{2} + \epsilon^2 + \dots}\)

    where x is a BlockDataContainer, i.e., \(x=(x^{1}, x^{2}, \dots)\)

    Conjugate, proximal and proximal conjugate methods no closed-form solution

    -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Returns the value of the gradient of the SmoothMixedL21Norm function at x.

    frac{x}{|x|}

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -convex_conjugate(x)#
    +
    +convex_conjugate(x)#

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    \[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    Parameters
    -

    x (DataContainer) –

    -
    -
    Returns
    -

    +

    x (DataContainer) –

    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    -
    -proximal(x, tau, out=None)#
    +
    +proximal(x, tau, out=None)#

    Returns the proximal operator of function \(\tau F\) evaluated at x

    \[\text{prox}_{\tau F}(x) = \underset{z}{\text{argmin}} \frac{1}{2}\|z - x\|^{2} + \tau F(z)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • tau (scalar) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the proximal operator of the function at x with scalar \(\tau\) or None if out.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -5551,28 +5383,25 @@

    Smooth Mixed L21 norm
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    -
    -
    + +

    Mixed L11 norm#

    -
    -class cil.optimisation.functions.MixedL11Norm(**kwargs)[source]#
    +
    +class cil.optimisation.functions.MixedL11Norm(**kwargs)[source]#

    MixedL11Norm function

    \[F(x) = ||x||_{1,1} = \sum |x_{1}| + |x_{2}| + \cdots + |x_{n}|\]
    @@ -5584,77 +5413,68 @@

    Mixed L11 normSee also

    L1Norm, MixedL21Norm

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    +

    center (DataContainer) – The point to center the function at.

    -
    Returns
    -

    -
    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -convex_conjugate(x)#
    +
    +convex_conjugate(x)#

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    \[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    Parameters
    -

    x (DataContainer) –

    +

    x (DataContainer) –

    -
    Returns
    -

    -
    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    -
    -gradient(x, out=None)#
    +
    +gradient(x, out=None)#

    Returns the value of the gradient of function \(F\) evaluated at \(x\), if it is differentiable

    \[F'(x)\]
    Parameters
      -
    • x (DataContainer) –

    • +
    • x (DataContainer) –

    • out (return DataContainer, if None a new DataContainer is returned, default None.) –

    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the gradient of the function at x or None if out

    +
    Return type
    +

    DataContainer, the value of the gradient of the function at x or None if out

    -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Returns the value of the proximal operator of the MixedL11Norm function at x.

    \[\mathrm{prox}_{\tau F}(x) = \mathrm{ShinkOperator}(x)\]
    @@ -5664,8 +5484,8 @@

    Mixed L11 norm -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -5675,28 +5495,25 @@

    Mixed L11 norm
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    - -
    + +

    Total variation#

    -
    -class cil.optimisation.functions.TotalVariation(max_iteration=10, tolerance=None, correlation='Space', backend='c', lower=None, upper=None, isotropic=True, split=False, info=False, strong_convexity_constant=0, warm_start=True)[source]#
    +
    +class cil.optimisation.functions.TotalVariation(max_iteration=10, tolerance=None, correlation='Space', backend='c', lower=None, upper=None, isotropic=True, split=False, info=False, strong_convexity_constant=0, warm_start=True)[source]#

    Total variation Function

    \[\mathrm{TV}(u) := \|\nabla u\|_{2,1} = \sum \|\nabla u\|_{2},\, (\mbox{isotropic})\]
    @@ -5791,53 +5608,50 @@

    Total variation -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Returns the proximal operator of the TotalVariation function at x .

    -
    -convex_conjugate(x)[source]#
    +
    +convex_conjugate(x)[source]#

    Returns the value of convex conjugate of the TotalVariation function at x .

    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -calculate_Lipschitz()[source]#
    +
    +calculate_Lipschitz()[source]#

    Default value for the Lipschitz constant.

    -
    -centered_at(center)#
    +
    +centered_at(center)#
    Returns a translated function, namely if we have a function \(F(x)\) the center is at the origin.

    TranslateFunction is \(F(x - b)\) and the center is at point b.

    Parameters
    -

    center (DataContainer) – The point to center the function at.

    -
    -
    Returns
    -

    +

    center (DataContainer) – The point to center the function at.

    -
    Return type
    -

    The translated function.

    +
    Return type
    +

    The translated function.

    -
    -proximal_conjugate(x, tau, out=None)#
    +
    +proximal_conjugate(x, tau, out=None)#

    Returns the proximal operator of the convex conjugate of function \(\tau F\) evaluated at \(x^{*}\)

    \[\text{prox}_{\tau F^{*}}(x^{*}) = \underset{z^{*}}{\text{argmin}} \frac{1}{2}\|z^{*} - x^{*}\|^{2} + \tau F^{*}(z^{*})\]
    @@ -5847,42 +5661,39 @@

    Total variation
    Parameters
    -
    Returns
    -

    -
    -
    Return type
    -

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    +
    Return type
    +

    DataContainer, the value of the proximal operator of the convex conjugate at point \(x\) for scalar \(\tau\) or None if out.

    -
    -
    -property gradient#
    +
    +
    +property gradient#

    GradientOperator is created if it is not instantiated yet. The domain of the _gradient, is created in the __call__ and proximal methods.

    -
    - -
    + + +

    Utilities#

    Contains utilities for the CIL optimisation framework.

    -
    +

    Samplers#

    Here, we define samplers that select from a list of indices {0, 1, …, N-1} either randomly or by some deterministic pattern. The cil.optimisation.utilities.sampler class defines a function next() which gives the next sample. It also has utility to get_samples to access which samples have or will be drawn.

    For ease of use we provide the following static methods in cil.optimisation.utilities.sampler that allow you to configure your sampler object rather than initialising the classes directly:

    -
    -static Sampler.from_function(num_indices, function, prob_weights=None)[source]#
    +
    +static Sampler.from_function(num_indices, function, prob_weights=None)[source]#

    Instantiate a sampler that wraps a function for index selection.

    @@ -5946,8 +5757,8 @@

    Samplers -
    -static Sampler.sequential(num_indices)[source]#
    +
    +static Sampler.sequential(num_indices)[source]#

    Instantiates a sampler that outputs sequential indices.

    Parameters
    @@ -5973,8 +5784,8 @@

    Samplers -
    -static Sampler.staggered(num_indices, stride)[source]#
    +
    +static Sampler.staggered(num_indices, stride)[source]#

    Instantiates a sampler which outputs in a staggered order.

    Parameters
    @@ -6013,8 +5824,8 @@

    Samplers -
    -static Sampler.herman_meyer(num_indices)[source]#
    +
    +static Sampler.herman_meyer(num_indices)[source]#

    Instantiates a sampler which outputs in a Herman Meyer order.

    Parameters
    @@ -6022,13 +5833,13 @@

    SamplersReturns @@ -6047,8 +5858,8 @@

    Samplers -
    -static Sampler.random_with_replacement(num_indices, prob=None, seed=None)[source]#
    +
    +static Sampler.random_with_replacement(num_indices, prob=None, seed=None)[source]#

    Instantiates a sampler which outputs an index between 0 - num_indices with a given probability.

    Parameters
    @@ -6083,8 +5894,8 @@

    Samplers -
    -static Sampler.random_without_replacement(num_indices, seed=None)[source]#
    +
    +static Sampler.random_without_replacement(num_indices, seed=None)[source]#

    Instantiates a sampler which outputs an index between 0 - num_indices. Once sampled the index will not be sampled again until all indices have been returned.

    Parameters
    @@ -6110,8 +5921,8 @@

    Samplers -
    -class cil.optimisation.utilities.Sampler(num_indices, function, sampling_type=None, prob_weights=None)[source]#
    +
    +class cil.optimisation.utilities.Sampler(num_indices, function, sampling_type=None, prob_weights=None)[source]#

    Initialises a sampler that returns and then increments indices from a sequence defined by a function.

    Static methods to easily configure several samplers are provided, such as sequential, staggered, Herman-Mayer, random with and without replacement.

    Custom deterministic samplers can be created by using the from_function static method or by subclassing this sampler class.

    @@ -6184,14 +5995,14 @@

    Samplers -
    -next()[source]#
    +
    +next()[source]#

    Returns a sample from the list of indices `{0, 1, …, N-1}, where N is the number of indices and increments the sampler.

    -
    -get_samples(num_samples)[source]#
    +
    +get_samples(num_samples)[source]#

    Generates a list of the first num_samples output by the sampler. Calling this does not increment the sampler index or affect the behaviour of the sampler .

    Parameters
    @@ -6207,8 +6018,8 @@

    Samplers -
    -static sequential(num_indices)[source]#
    +
    +static sequential(num_indices)[source]#

    Instantiates a sampler that outputs sequential indices.

    Parameters
    @@ -6234,8 +6045,8 @@

    Samplers -
    -static staggered(num_indices, stride)[source]#
    +
    +static staggered(num_indices, stride)[source]#

    Instantiates a sampler which outputs in a staggered order.

    Parameters
    @@ -6274,8 +6085,8 @@

    Samplers -
    -static random_with_replacement(num_indices, prob=None, seed=None)[source]#
    +
    +static random_with_replacement(num_indices, prob=None, seed=None)[source]#

    Instantiates a sampler which outputs an index between 0 - num_indices with a given probability.

    Parameters
    @@ -6310,8 +6121,8 @@

    Samplers -
    -static random_without_replacement(num_indices, seed=None)[source]#
    +
    +static random_without_replacement(num_indices, seed=None)[source]#

    Instantiates a sampler which outputs an index between 0 - num_indices. Once sampled the index will not be sampled again until all indices have been returned.

    Parameters
    @@ -6336,8 +6147,8 @@

    Samplers -
    -static from_function(num_indices, function, prob_weights=None)[source]#
    +
    +static from_function(num_indices, function, prob_weights=None)[source]#

    Instantiate a sampler that wraps a function for index selection.

    @@ -6401,8 +6212,8 @@

    Samplers -
    -static herman_meyer(num_indices)[source]#
    +
    +static herman_meyer(num_indices)[source]#

    Instantiates a sampler which outputs in a Herman Meyer order.

    Parameters
    @@ -6410,13 +6221,13 @@

    SamplersReturns @@ -6438,8 +6249,8 @@

    Samplers -
    -class cil.optimisation.utilities.SamplerRandom(num_indices, seed=None, replace=True, prob=None, sampling_type='random_with_replacement')[source]#
    +
    +class cil.optimisation.utilities.SamplerRandom(num_indices, seed=None, replace=True, prob=None, sampling_type='random_with_replacement')[source]#

    The user is recommended to not instantiate this class directly but instead use one of the static methods in the parent Sampler class that will return instances of different samplers.

    This class produces Samplers that output random samples with and without replacement from the set {0, 1, …, N-1} where N=num_indices.

    Custom random samplers can be created by subclassing this sampler class.

    @@ -6473,8 +6284,8 @@

    Samplers -
    -get_samples(num_samples)[source]#
    +
    +get_samples(num_samples)[source]#

    Generates a list of the first num_samples output by the sampler. Calling this does not increment the sampler index or affect the behaviour of the sampler .

    Parameters
    @@ -6491,10 +6302,10 @@

    Samplers +

    +
    + +

    Block Framework#

    To be able to express more advanced optimisation problems we developed the Block Framework, which provides a generic strategy to treat variational @@ -6536,15 +6347,15 @@

    Block FrameworkBlockGeometry, BlockDataContainer, BlockFunction and BlockOperator.

    -
    +

    BlockDataContainer#

    BlockDataContainer holds `DataContainer`_ as column vector. It is possible to do basic algebra between BlockDataContainer s and with numbers, list or numpy arrays.

    \[ \begin{align}\begin{aligned}x = [x_{1}, x_{2} ]\in (X_{1}\times X_{2})\\y = [y_{1}, y_{2}, y_{3} ]\in(Y_{1}\times Y_{2} \times Y_{3})\end{aligned}\end{align} \]
    -
    -class cil.framework.BlockDataContainer(*args, **kwargs)[source]#
    +
    +class cil.framework.BlockDataContainer(*args, **kwargs)[source]#

    Class to hold DataContainers as column vector

    Provides basic algebra between BlockDataContainer’s, DataContainer’s and subclasses and Numbers

    @@ -6564,26 +6375,26 @@

    BlockDataContainer -
    -__iter__()[source]#
    +
    +__iter__()[source]#

    BlockDataContainer is Iterable

    -
    -next()[source]#
    +
    +next()[source]#

    python2 backwards compatibility

    -
    -is_compatible(other)[source]#
    +
    +is_compatible(other)[source]#

    basic check if the size of the 2 objects fit

    -
    -add(other, *args, **kwargs)[source]#
    +
    +add(other, *args, **kwargs)[source]#

    Algebra: add method of BlockDataContainer with number/DataContainer or BlockDataContainer

    Param
    @@ -6596,8 +6407,8 @@

    BlockDataContainer -
    -subtract(other, *args, **kwargs)[source]#
    +
    +subtract(other, *args, **kwargs)[source]#

    Algebra: subtract method of BlockDataContainer with number/DataContainer or BlockDataContainer

    Param
    @@ -6610,8 +6421,8 @@

    BlockDataContainer -
    -multiply(other, *args, **kwargs)[source]#
    +
    +multiply(other, *args, **kwargs)[source]#

    Algebra: multiply method of BlockDataContainer with number/DataContainer or BlockDataContainer

    Param
    @@ -6624,8 +6435,8 @@

    BlockDataContainer -
    -divide(other, *args, **kwargs)[source]#
    +
    +divide(other, *args, **kwargs)[source]#

    Algebra: divide method of BlockDataContainer with number/DataContainer or BlockDataContainer

    Param
    @@ -6638,8 +6449,8 @@

    BlockDataContainer -
    -power(other, *args, **kwargs)[source]#
    +
    +power(other, *args, **kwargs)[source]#

    Algebra: power method of BlockDataContainer with number/DataContainer or BlockDataContainer

    Param
    @@ -6652,8 +6463,8 @@

    BlockDataContainer -
    -maximum(other, *args, **kwargs)[source]#
    +
    +maximum(other, *args, **kwargs)[source]#

    Algebra: power method of BlockDataContainer with number/DataContainer or BlockDataContainer

    Param
    @@ -6666,8 +6477,8 @@

    BlockDataContainer -
    -minimum(other, *args, **kwargs)[source]#
    +
    +minimum(other, *args, **kwargs)[source]#

    Algebra: power method of BlockDataContainer with number/DataContainer or BlockDataContainer

    Param
    @@ -6680,8 +6491,8 @@

    BlockDataContainer -
    -sapyb(a, y, b, out, num_threads=2)[source]#
    +
    +sapyb(a, y, b, out, num_threads=2)[source]#

    performs axpby element-wise on the BlockDataContainer containers

    Does the operation .. math:: a*x+b*y and stores the result in out, where x is self

    @@ -6707,14 +6518,14 @@

    BlockDataContainer -
    -axpby(a, b, y, out, dtype=<class 'numpy.float32'>, num_threads=2)[source]#
    +
    +axpby(a, b, y, out, dtype=<class 'numpy.float32'>, num_threads=2)[source]#

    Deprecated method. Alias of sapyb

    -
    -binary_operations(operation, other, *args, **kwargs)[source]#
    +
    +binary_operations(operation, other, *args, **kwargs)[source]#

    Algebra: generic method of algebric operation with BlockDataContainer with number/DataContainer or BlockDataContainer

    Provides commutativity with DataContainer and subclasses, i.e. this class’s reverse algebraic methods take precedence w.r.t. direct algebraic @@ -6723,22 +6534,22 @@

    BlockDataContainer -
    -unary_operations(operation, *args, **kwargs)[source]#
    +
    +unary_operations(operation, *args, **kwargs)[source]#

    Unary operation on BlockDataContainer:

    generic method of unary operation with BlockDataContainer: abs, sign, sqrt and conjugate

    This method is not to be used directly

    -
    -copy()[source]#
    +
    +copy()[source]#

    alias of clone

    -
    -__radd__(other)[source]#
    +
    +__radd__(other)[source]#

    Reverse addition

    to make sure that this method is called rather than the __mul__ of a numpy array the class constant __array_priority__ must be set > 0 @@ -6746,8 +6557,8 @@

    BlockDataContainer -
    -__rsub__(other)[source]#
    +
    +__rsub__(other)[source]#

    Reverse subtraction

    to make sure that this method is called rather than the __mul__ of a numpy array the class constant __array_priority__ must be set > 0 @@ -6755,8 +6566,8 @@

    BlockDataContainer -
    -__rmul__(other)[source]#
    +
    +__rmul__(other)[source]#

    Reverse multiplication

    to make sure that this method is called rather than the __mul__ of a numpy array the class constant __array_priority__ must be set > 0 @@ -6764,8 +6575,8 @@

    BlockDataContainer -
    -__rdiv__(other)[source]#
    +
    +__rdiv__(other)[source]#

    Reverse division

    to make sure that this method is called rather than the __mul__ of a numpy array the class constant __array_priority__ must be set > 0 @@ -6773,8 +6584,8 @@

    BlockDataContainer -
    -__rtruediv__(other)[source]#
    +
    +__rtruediv__(other)[source]#

    Reverse truedivision

    to make sure that this method is called rather than the __mul__ of a numpy array the class constant __array_priority__ must be set > 0 @@ -6782,8 +6593,8 @@

    BlockDataContainer -
    -__rpow__(other)[source]#
    +
    +__rpow__(other)[source]#

    Reverse power

    to make sure that this method is called rather than the __mul__ of a numpy array the class constant __array_priority__ must be set > 0 @@ -6791,51 +6602,51 @@

    BlockDataContainer -
    -__iadd__(other)[source]#
    +
    +__iadd__(other)[source]#

    Inline addition

    -
    -__isub__(other)[source]#
    +
    +__isub__(other)[source]#

    Inline subtraction

    -
    -__imul__(other)[source]#
    +
    +__imul__(other)[source]#

    Inline multiplication

    -
    -__idiv__(other)[source]#
    +
    +__idiv__(other)[source]#

    Inline division

    -
    -__itruediv__(other)[source]#
    +
    +__itruediv__(other)[source]#

    Inline truedivision

    -
    -__neg__()[source]#
    +
    +__neg__()[source]#

    Return - self

    -
    -__weakref__#
    +
    +__weakref__#

    list of weak references to the object (if defined)

    -

    -
    +

    +

    Block Function#

    BlockFunction acts on BlockDataContainer as a separable sum function:

    @@ -6849,8 +6660,8 @@

    Block Function -
    -class cil.optimisation.functions.BlockFunction(*functions)[source]#
    +
    +class cil.optimisation.functions.BlockFunction(*functions)[source]#

    BlockFunction represents a separable sum function \(F\) defined as

    \[F:X_{1}\times X_{2}\cdots\times X_{m} \rightarrow (-\infty, \infty]\]
    @@ -6865,21 +6676,20 @@

    Block Function \[\mathrm{prox}_{\tau F}(x) = ( \mathrm{prox}_{\tau_{i} f_{i}}(x_{i}) )_{i=1}^{m}\]

    -
    -__init__(*functions)[source]#
    -

    Initialize self. See help(type(self)) for accurate signature.

    -
    +
    +__init__(*functions)[source]#
    +
    -
    -
    -property L#
    +
    +
    +property L#

    Lipschitz of the gradient of function f.

    L is positive real number, such that \(\|f'(x) - f'(y)\| \leq L\|x-y\|\), assuming \(f: IG \rightarrow \mathbb{R}\)

    -
    -__call__(x)[source]#
    +
    +__call__(x)[source]#

    Returns the value of the BlockFunction \(F\)

    \[F(x) = \overset{m}{\underset{i=1}{\sum}}f_{i}(x_{i}), \mbox{ where } x = (x_{1}, x_{2}, \cdots, x_{m}), \quad i = 1,2,\dots,m\]
    @@ -6891,8 +6701,8 @@

    Block Function -
    -convex_conjugate(x)[source]#
    +
    +convex_conjugate(x)[source]#

    Returns the value of the convex conjugate of the BlockFunction at \(x^{*}\).

    \[F^{*}(x^{*}) = \overset{m}{\underset{i=1}{\sum}}f_{i}^{*}(x^{*}_{i})\]
    @@ -6903,8 +6713,8 @@

    Block Function -
    -proximal(x, tau, out=None)[source]#
    +
    +proximal(x, tau, out=None)[source]#

    Proximal operator of the BlockFunction at x:

    \[\mathrm{prox}_{\tau F}(x) = (\mathrm{prox}_{\tau f_{i}}(x_{i}))_{i=1}^{m}\]
    @@ -6915,8 +6725,8 @@

    Block Function -
    -gradient(x, out=None)[source]#
    +
    +gradient(x, out=None)[source]#

    Returns the value of the gradient of the BlockFunction function at x.

    \[F'(x) = [f_{1}'(x_{1}), ... , f_{m}'(x_{m})]\]
    @@ -6927,8 +6737,8 @@

    Block Function -
    -proximal_conjugate(x, tau, out=None)[source]#
    +
    +proximal_conjugate(x, tau, out=None)[source]#

    Proximal operator of the convex conjugate of BlockFunction at x:

    \[\mathrm{prox}_{\tau F^{*}}(x) = (\mathrm{prox}_{\tau f^{*}_{i}}(x^{*}_{i}))_{i=1}^{m}\]
    @@ -6939,8 +6749,8 @@

    Block Function -
    -__rmul__(other)[source]#
    +
    +__rmul__(other)[source]#

    Define multiplication with a scalar

    Parameters
    @@ -6952,8 +6762,8 @@

    Block Function + +

    Block Operator#

    BlockOperator represent a block matrix with operators

    @@ -7014,8 +6824,8 @@

    Block Operator -
    -class cil.optimisation.operators.BlockOperator(*args, **kwargs)[source]#
    +
    +class cil.optimisation.operators.BlockOperator(*args, **kwargs)[source]#

    A Block matrix containing Operators

    Parameters
    @@ -7046,26 +6856,25 @@

    Block Operator -
    -__init__(*args, **kwargs)[source]#
    -

    Initialize self. See help(type(self)) for accurate signature.

    -

    +
    +__init__(*args, **kwargs)[source]#
    +

    -
    -column_wise_compatible()[source]#
    +
    +column_wise_compatible()[source]#

    Operators in a Block should have the same domain per column

    -
    -row_wise_compatible()[source]#
    +
    +row_wise_compatible()[source]#

    Operators in a Block should have the same range per row

    -
    -get_item(row, col)[source]#
    +
    +get_item(row, col)[source]#

    Returns the Operator at specified row and col :param row: The row index required. :type row: int @@ -7074,20 +6883,20 @@

    Block Operator -
    -norm()[source]#
    +
    +norm()[source]#

    Returns the Euclidean norm of the norms of the individual operators in the BlockOperators

    -
    -get_norms_as_list()[source]#
    +
    +get_norms_as_list()[source]#

    Returns a list of the individual norms of the Operators in the BlockOperator

    -
    -set_norms(norms)[source]#
    +
    +set_norms(norms)[source]#

    Uses the set_norm() function in Operator to set the norms of the operators in the BlockOperator from a list of custom values.

    Parameters
    @@ -7097,8 +6906,8 @@

    Block Operator -
    -direct(x, out=None)[source]#
    +
    +direct(x, out=None)[source]#

    Direct operation for the BlockOperator

    Note

    @@ -7108,8 +6917,8 @@

    Block Operator -
    -adjoint(x, out=None)[source]#
    +
    +adjoint(x, out=None)[source]#

    Adjoint operation for the BlockOperator

    Note

    @@ -7123,14 +6932,14 @@

    Block Operator -
    -is_linear()[source]#
    +
    +is_linear()[source]#

    Returns whether all the elements of the BlockOperator are linear

    -
    -get_output_shape(xshape, adjoint=False)[source]#
    +
    +get_output_shape(xshape, adjoint=False)[source]#

    Returns the shape of the output BlockDataContainer :param xshape: :type xshape: BlockDataContainer @@ -7142,8 +6951,8 @@

    Block Operator -
    -__rmul__(scalar)[source]#
    +
    +__rmul__(scalar)[source]#

    Defines the left multiplication with a scalar. Returns a block operator with Scaled Operators inside.

    Parameters
    @@ -7152,43 +6961,43 @@

    Block Operator -
    -property T#
    +
    +
    +property T#

    Returns the transposed of self.

    Recall the input list is shaped in a row-by-row fashion

    -
    -domain_geometry()[source]#
    +
    +domain_geometry()[source]#

    Returns the domain of the BlockOperator

    If the shape of the BlockOperator is (N,1) the domain is a ImageGeometry or AcquisitionGeometry. Otherwise it is a BlockGeometry.

    -
    -range_geometry()[source]#
    +
    +range_geometry()[source]#

    Returns the range of the BlockOperator

    -
    -__getitem__(index)[source]#
    +
    +__getitem__(index)[source]#

    Returns the index-th operator in the block irrespectively of it’s shape

    -
    -get_as_list()[source]#
    +
    +get_as_list()[source]#

    Returns the list of operators

    -

    Return Home

    - + + + + + +
    + +
    + + + - -
    -
    + + + +
    +
    + + +
    + +
    \ No newline at end of file diff --git a/nightly/plugins.html b/nightly/plugins.html deleted file mode 100644 index ab5ac149bb..0000000000 --- a/nightly/plugins.html +++ /dev/null @@ -1,817 +0,0 @@ - - - - - - - - CIL Plugins — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - - - - - - - - - - - - - - - -
    - -
    - -
    -

    CIL Plugins#

    -
    -

    CCPi Regularisation#

    -

    This plugin allows the use of regularisation functions from the CCPi Regularisation toolkit -(10.1016/j.softx.2019.04.003, -a set of CPU/GPU optimised regularisation modules for iterative image reconstruction and -other image processing tasks.

    -
    -

    Total variation#

    -
    -
    -class cil.plugins.ccpi_regularisation.functions.FGP_TV(alpha=1, max_iteration=100, tolerance=0, isotropic=True, nonnegativity=True, device='cpu', strong_convexity_constant=0)[source]#
    -

    Fast Gradient Projection Total Variation (FGP_TV)

    -

    The FGP_TV computes the proximal operator of the Total variation regulariser

    -
    -\[\mathrm{prox}_{\tau (\alpha TV)}(x) = \underset{z}{\mathrm{argmin}} \,\alpha\,\mathrm{TV}(z) + \frac{1}{2}\|z - x\|^{2} .\]
    -

    The algorithm used for the proximal operator of TV is the Fast Gradient Projection algorithm -applied to the _dual problem_ of the above problem, see [1], [2].

    -
    -
    Parameters
    -
      -
    • alpha (Number (positive), default = 1.0 .) – Total variation regularisation parameter.

    • -
    • max_iteration (int. Default = 100 .) – Maximum number of iterations for the Fast Gradient Projection algorithm.

    • -
    • isotropic (boolean. Default = True .) –

      Isotropic or Anisotropic definition of the Total variation regulariser.

      -
      -\[|x|_{2} = \sqrt{x_{1}^{2} + x_{2}^{2}},\, (\mbox{isotropic})\]
      -
      -\[|x|_{1} = |x_{1}| + |x_{2}|\, (\mbox{anisotropic})\]
      -

    • -
    • nonnegativity (boolean. Default = True .) – Non-negativity constraint for the solution of the FGP algorithm.

    • -
    • tolerance (float, Default = 0 .) –

      Stopping criterion for the FGP algorithm.

      -
      -\[\|x^{k+1} - x^{k}\|_{2} < \mathrm{tolerance}\]
      -

    • -
    • device (str, Default = ‘cpu’ .) – FGP_TV algorithm runs on cpu or gpu.

    • -
    • strong_convexity_constant (float, default = 0) –

      A strongly convex term weighted by the strong_convexity_constant (\(\gamma\)) parameter is added to the Total variation. -Now the TotalVariation function is \(\gamma\) - strongly convex and the proximal operator is

      -
      -\[\underset{u}{\mathrm{argmin}} \frac{1}{2\tau}\|u - b\|^{2} + \mathrm{TV}(u) + \frac{\gamma}{2}\|u\|^{2} \Leftrightarrow\]
      -
      -\[\underset{u}{\mathrm{argmin}} \frac{1}{2\frac{\tau}{1+\gamma\tau}}\|u - \frac{b}{1+\gamma\tau}\|^{2} + \mathrm{TV}(u)\]
      -

    • -
    -
    -
    -

    Examples

    -
    -\[\underset{u\qeq0}{\mathrm{argmin}} \frac{1}{2}\|u - b\|^{2} + \alpha TV(u)\]
    -
    >>> G = alpha * FGP_TV(max_iteration=100, device='gpu')
    ->>> sol = G.proximal(b)
    -
    -
    -
    -

    Note

    -

    The FGP_TV regularisation does not incorparate information on the ImageGeometry, i.e., pixel/voxel size. -Therefore a rescaled parameter should be used to match the same solution computed using TotalVariation.

    -
    >>> G1 = (alpha/ig.voxel_size_x) * FGP_TV(max_iteration=100, device='gpu')
    ->>> G2 = alpha * TotalVariation(max_iteration=100, lower=0.)
    -
    -
    -
    -
    -

    See also

    -

    TotalVariation

    -
    -
    - -
    -
    -

    Other regularisation functions#

    -
    -
    -class cil.plugins.ccpi_regularisation.functions.TGV(alpha=1, gamma=1, max_iteration=100, tolerance=0, device='cpu', **kwargs)[source]#
    -
    -
    -__init__(alpha=1, gamma=1, max_iteration=100, tolerance=0, device='cpu', **kwargs)[source]#
    -

    Creator of Total Generalised Variation Function

    -
    -
    Parameters
    -
      -
    • alpha (number, default 1) – regularisation parameter

    • -
    • gamma (number, default 1, can range between 1 and 2) – ratio of TGV terms

    • -
    • max_iteration (integer, default 100) – max number of sub iterations. The algorithm will iterate up to this number of iteration or up to when the tolerance has been reached

    • -
    • tolerance (float, default 0) – minimum difference between previous iteration of the algorithm that determines the stop of the iteration earlier than max_iteration. If set to 0 only the max_iteration will be used as stop criterion.

    • -
    • device (string, default 'cpu', can be 'gpu' if GPU is installed) – determines if the code runs on CPU or GPU

    • -
    -
    -
    -
    - -
    -
    -__call__(x)[source]#
    -

    Call self as a function.

    -
    - -
    -
    -convex_conjugate(x)[source]#
    -

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    -
    -\[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    -
    -
    Parameters
    -

    x (DataContainer) –

    -
    -
    Returns
    -

    -
    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    -
    -
    -
    - -
    -
    -__rmul__(scalar)[source]#
    -

    Define the multiplication with a scalar

    -

    this changes the regularisation parameter in the plugin

    -
    - -
    - -
    -
    -class cil.plugins.ccpi_regularisation.functions.FGP_dTV(reference, alpha=1, max_iteration=100, tolerance=0, eta=0.01, isotropic=True, nonnegativity=True, device='cpu')[source]#
    -

    Creator of FGP_dTV Function

    -
    -
    Parameters
    -
      -
    • reference (ImageData) – reference image

    • -
    • alpha (number, default 1) – regularisation parameter

    • -
    • max_iteration (integer, default 100) – max number of sub iterations. The algorithm will iterate up to this number of iteration or up to when the tolerance has been reached

    • -
    • tolerance (float, default 0) – minimum difference between previous iteration of the algorithm that determines the stop of the iteration earlier than max_iteration. If set to 0 only the max_iteration will be used as stop criterion.

    • -
    • eta (number, default 0.01) – smoothing constant to calculate gradient of the reference

    • -
    • isotropic (boolean, default True, can range between 1 and 2) – Whether it uses L2 (isotropic) or L1 (anisotropic) norm

    • -
    • nonnegativity (boolean, default True) – Whether to add the non-negativity constraint

    • -
    • device (string, default 'cpu', can be 'gpu' if GPU is installed) – determines if the code runs on CPU or GPU

    • -
    -
    -
    -
    -
    -__init__(reference, alpha=1, max_iteration=100, tolerance=0, eta=0.01, isotropic=True, nonnegativity=True, device='cpu')[source]#
    -

    Initialize self. See help(type(self)) for accurate signature.

    -
    - -
    -
    -__call__(x)[source]#
    -

    Call self as a function.

    -
    - -
    -
    -convex_conjugate(x)[source]#
    -

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    -
    -\[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    -
    -
    Parameters
    -

    x (DataContainer) –

    -
    -
    Returns
    -

    -
    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    -
    -
    -
    - -
    -
    -__rmul__(scalar)[source]#
    -

    Define the multiplication with a scalar

    -

    this changes the regularisation parameter in the plugin

    -
    - -
    - -
    -
    -class cil.plugins.ccpi_regularisation.functions.TNV(alpha=1, max_iteration=100, tolerance=0)[source]#
    -
    -
    -__init__(alpha=1, max_iteration=100, tolerance=0)[source]#
    -

    Creator of TNV Function

    -
    -
    Parameters
    -
      -
    • alpha (number, default 1) – regularisation parameter

    • -
    • max_iteration (integer, default 100) – max number of sub iterations. The algorithm will iterate up to this number of iteration or up to when the tolerance has been reached

    • -
    • tolerance (float, default 0) – minimum difference between previous iteration of the algorithm that determines the stop of the iteration earlier than max_iteration. If set to 0 only the max_iteration will be used as stop criterion.

    • -
    -
    -
    -
    - -
    -
    -__call__(x)[source]#
    -

    Call self as a function.

    -
    - -
    -
    -convex_conjugate(x)[source]#
    -

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    -
    -\[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    -
    -
    Parameters
    -

    x (DataContainer) –

    -
    -
    Returns
    -

    -
    -
    Return type
    -

    The value of the convex conjugate of the function at x.

    -
    -
    -
    - -
    -
    -__rmul__(scalar)[source]#
    -

    Define the multiplication with a scalar

    -

    this changes the regularisation parameter in the plugin

    -
    - -
    -
    -check_input(input)[source]#
    -

    TNV requires 2D+channel data with the first dimension as the channel dimension

    -
    - -
    - -
    -
    -
    -

    TomoPhantom#

    -

    This plugin allows the use of part of TomoPhantom -(10.1016/j.softx.2018.05.003, -a toolbox written in C language to generate customisable 2D-4D phantoms (with a -temporal capability).

    -
    -
    -cil.plugins.TomoPhantom.get_ImageData(num_model, geometry)[source]#
    -

    Returns an ImageData relative to geometry with the model num_model from tomophantom

    -
    -
    Parameters
    -
      -
    • num_model (int) – model number

    • -
    • geometry (ImageGeometry) – geometrical info that describes the phantom

    • -
    -
    -
    -

    Example usage:

    -
    ndim = 2
    -N=128
    -angles = np.linspace(0, 360, 50, True, dtype=np.float32)
    -offset = 0.4
    -channels = 3
    -
    -if ndim == 2:
    -    ag = AcquisitionGeometry.create_Cone2D((offset,-100), (offset,100))
    -    ag.set_panel(N)
    -
    -else:
    -    ag = AcquisitionGeometry.create_Cone3D((offset,-100, 0), (offset,100,0))
    -    ag.set_panel((N,N-2))
    -
    -ag.set_channels(channels)
    -ag.set_angles(angles, angle_unit=AcquisitionGeometry.DEGREE)
    -
    -
    -ig = ag.get_ImageGeometry()
    -num_model = 1
    -phantom = TomoPhantom.get_ImageData(num_model=num_model, geometry=ig)
    -
    -
    -
    - -
    -
    -

    TIGRE#

    -

    This plugin allows the use of TIGRE -(10.1088/2057-1976/2/5/055010 -for forward and back projections and filter back projection reconstruction.

    -
    -

    FBP#

    -

    This reconstructs with FBP for parallel-beam data, and with FDK weights for cone-beam data

    -
    -
    -class cil.plugins.tigre.FBP(image_geometry=None, acquisition_geometry=None, **kwargs)[source]#
    -

    FBP Filtered Back Projection is a reconstructor for 2D and 3D parallel and cone-beam geometries. -It is able to back-project circular trajectories with 2 PI angular range and equally spaced angular steps.

    -

    This uses the ram-lak filter -This is provided for simple and offset parallel-beam geometries only

    -
    -
    acquisition_geometryAcquisitionGeometry

    A description of the acquisition data

    -
    -
    image_geometryImageGeometry, default used if None

    A description of the area/volume to reconstruct

    -
    -
    -

    Example

    -
    >>> from cil.plugins.tigre import FBP
    ->>> fbp = FBP(image_geometry, data.geometry)
    ->>> fbp.set_input(data)
    ->>> reconstruction = fbp.get_ouput()
    -
    -
    -
    -
    -get_output(out=None)#
    -

    Runs the configured processor and returns the processed data

    -
    -
    Parameters
    -

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    -
    -
    Returns
    -

    The processed data. Suppressed if out is passed

    -
    -
    Return type
    -

    DataContainer

    -
    -
    -
    - -
    -
    -set_input(dataset)#
    -

    Set the input data to the processor

    -
    -
    Parameters
    -

    input (DataContainer) – The input DataContainer

    -
    -
    -
    - -
    - -
    -
    -

    Projection Operator#

    -
    -
    -class cil.plugins.tigre.ProjectionOperator(image_geometry=None, acquisition_geometry=None, direct_method='interpolated', adjoint_weights='matched', **kwargs)[source]#
    -

    ProjectionOperator configures and calls TIGRE Projectors for your dataset.

    -

    Please refer to the TIGRE documentation for futher descriptions -https://github.com/CERN/TIGRE -https://iopscience.iop.org/article/10.1088/2057-1976/2/5/055010

    -
    -
    Parameters
    -
      -
    • image_geometry (ImageGeometry, default used if None) – A description of the area/volume to reconstruct

    • -
    • acquisition_geometry (AcquisitionGeometry, BlockGeometry) – A description of the acquisition data. If passed a BlockGeometry it will return a BlockOperator.

    • -
    • direct_method (str, default 'interpolated') – The method used by the forward projector, ‘Siddon’ for ray-voxel intersection, ‘interpolated’ for interpolated projection

    • -
    • adjoint_weights (str, default 'matched') – The weighting method used by the cone-beam backward projector, ‘matched’ for weights to approximately match the ‘interpolated’ forward projector, ‘FDK’ for FDK weights

    • -
    -
    -
    -

    Example

    -
    >>> from cil.plugins.tigre import ProjectionOperator
    ->>> PO = ProjectionOperator(image.geometry, data.geometry)
    ->>> forward_projection = PO.direct(image)
    ->>> backward_projection = PO.adjoint(data)
    -
    -
    -
    - -
    -
    -
    -

    ASTRA#

    -

    This plugin allows the use of ASTRA-toolbox -(10.1364/OE.24.025129) -for forward and back projections and filter back projection reconstruction.

    -
    -

    FBP#

    -

    This reconstructs with FBP for parallel-beam data, and with FDK weights for cone-beam data

    -
    -
    -class cil.plugins.astra.FBP(image_geometry=None, acquisition_geometry=None, device='gpu', **kwargs)[source]#
    -

    FBP configures and calls an appropriate ASTRA FBP or FDK algorithm for your dataset.

    -

    The best results will be on data with circular trajectories of a 2PI angular range and equally spaced small angular steps.

    -
    -
    Parameters
    -
      -
    • image_geometry (ImageGeometry, default used if None) – A description of the area/volume to reconstruct

    • -
    • acquisition_geometry (AcquisitionGeometry) – A description of the acquisition data

    • -
    • device (string, default='gpu') – ‘gpu’ will run on a compatible CUDA capable device using the ASTRA FDK_CUDA algorithm -‘cpu’ will run on CPU using the ASTRA FBP algorithm - see Notes for limitations

    • -
    -
    -
    -

    Example

    -
    >>> from cil.plugins.astra import FBP
    ->>> fbp = FBP(image_geometry, data.geometry)
    ->>> fbp.set_input(data)
    ->>> reconstruction = fbp.get_ouput()
    -
    -
    -

    Notes

    -

    A CPU version is provided for simple 2D parallel-beam geometries only, any offsets and rotations in the acquisition geometry will be ignored.

    -

    This uses the ram-lak filter only.

    -
    -
    -set_input(dataset)[source]#
    -

    Set the input data to the processor

    -
    -
    Parameters
    -

    input (DataContainer) – The input DataContainer

    -
    -
    -
    - -
    -
    -get_output(out=None)[source]#
    -

    Runs the configured processor and returns the processed data

    -
    -
    Parameters
    -

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    -
    -
    Returns
    -

    The processed data. Suppressed if out is passed

    -
    -
    Return type
    -

    DataContainer

    -
    -
    -
    - -
    - -
    -
    -

    Projection Operator#

    -
    -
    -class cil.plugins.astra.ProjectionOperator(image_geometry=None, acquisition_geometry=None, device='gpu', **kwargs)[source]#
    -

    ProjectionOperator configures and calls appropriate ASTRA Projectors for your dataset.

    -
    -
    Parameters
    -
      -
    • image_geometry (ImageGeometry, default used if None) – A description of the area/volume to reconstruct

    • -
    • acquisition_geometry (AcquisitionGeometry, BlockGeometry) – A description of the acquisition data. If passed a BlockGeometry it will return a BlockOperator.

    • -
    • device (string, default='gpu') – ‘gpu’ will run on a compatible CUDA capable device using the ASTRA 3D CUDA Projectors, ‘cpu’ will run on CPU using the ASTRA 2D CPU Projectors

    • -
    -
    -
    -

    Example

    -
    >>> from cil.plugins.astra import ProjectionOperator
    ->>> PO = ProjectionOperator(image.geometry, data.geometry)
    ->>> forward_projection = PO.direct(image)
    ->>> backward_projection = PO.adjoint(data)
    -
    -
    -

    Notes

    -

    For multichannel data the ProjectionOperator will broadcast across all channels.

    -
    - -

    Return Home

    -
    -
    -
    - - -
    - - - - - -
    - - -
    -
    - - - -
    -
    - - - - - -
    -
    - - \ No newline at end of file diff --git a/nightly/plugins/index.html b/nightly/plugins/index.html new file mode 100644 index 0000000000..00bf799cd0 --- /dev/null +++ b/nightly/plugins/index.html @@ -0,0 +1,852 @@ + + + + + + + + + + + + CIL Plugins — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    + + + +
    +
    + +
    + + + + + + + + + + + + + +
    + +
    + + +
    +
    + +
    +
    + +
    + +
    + + + + +
    + +
    + + +
    +
    + + + + + +
    + +
    +

    CIL Plugins#

    +
    +

    CCPi Regularisation#

    +

    This plugin allows the use of regularisation functions from the CCPi Regularisation toolkit +(10.1016/j.softx.2019.04.003, +a set of CPU/GPU optimised regularisation modules for iterative image reconstruction and +other image processing tasks.

    +
    +

    Total variation#

    +
    +
    +class cil.plugins.ccpi_regularisation.functions.FGP_TV(alpha=1, max_iteration=100, tolerance=0, isotropic=True, nonnegativity=True, device='cpu', strong_convexity_constant=0)[source]#
    +

    Fast Gradient Projection Total Variation (FGP_TV)

    +

    The FGP_TV computes the proximal operator of the Total variation regulariser

    +
    +\[\mathrm{prox}_{\tau (\alpha TV)}(x) = \underset{z}{\mathrm{argmin}} \,\alpha\,\mathrm{TV}(z) + \frac{1}{2}\|z - x\|^{2} .\]
    +

    The algorithm used for the proximal operator of TV is the Fast Gradient Projection algorithm +applied to the _dual problem_ of the above problem, see [1], [2].

    +
    +
    Parameters
    +
      +
    • alpha (Number (positive), default = 1.0 .) – Total variation regularisation parameter.

    • +
    • max_iteration (int. Default = 100 .) – Maximum number of iterations for the Fast Gradient Projection algorithm.

    • +
    • isotropic (boolean. Default = True .) –

      Isotropic or Anisotropic definition of the Total variation regulariser.

      +
      +\[|x|_{2} = \sqrt{x_{1}^{2} + x_{2}^{2}},\, (\mbox{isotropic})\]
      +
      +\[|x|_{1} = |x_{1}| + |x_{2}|\, (\mbox{anisotropic})\]
      +

    • +
    • nonnegativity (boolean. Default = True .) – Non-negativity constraint for the solution of the FGP algorithm.

    • +
    • tolerance (float, Default = 0 .) –

      Stopping criterion for the FGP algorithm.

      +
      +\[\|x^{k+1} - x^{k}\|_{2} < \mathrm{tolerance}\]
      +

    • +
    • device (str, Default = ‘cpu’ .) – FGP_TV algorithm runs on cpu or gpu.

    • +
    • strong_convexity_constant (float, default = 0) –

      A strongly convex term weighted by the strong_convexity_constant (\(\gamma\)) parameter is added to the Total variation. +Now the TotalVariation function is \(\gamma\) - strongly convex and the proximal operator is

      +
      +\[\underset{u}{\mathrm{argmin}} \frac{1}{2\tau}\|u - b\|^{2} + \mathrm{TV}(u) + \frac{\gamma}{2}\|u\|^{2} \Leftrightarrow\]
      +
      +\[\underset{u}{\mathrm{argmin}} \frac{1}{2\frac{\tau}{1+\gamma\tau}}\|u - \frac{b}{1+\gamma\tau}\|^{2} + \mathrm{TV}(u)\]
      +

    • +
    +
    +
    +

    Examples

    +
    +\[\underset{u\qeq0}{\mathrm{argmin}} \frac{1}{2}\|u - b\|^{2} + \alpha TV(u)\]
    +
    >>> G = alpha * FGP_TV(max_iteration=100, device='gpu')
    +>>> sol = G.proximal(b)
    +
    +
    +
    +

    Note

    +

    The FGP_TV regularisation does not incorparate information on the ImageGeometry, i.e., pixel/voxel size. +Therefore a rescaled parameter should be used to match the same solution computed using TotalVariation.

    +
    >>> G1 = (alpha/ig.voxel_size_x) * FGP_TV(max_iteration=100, device='gpu')
    +>>> G2 = alpha * TotalVariation(max_iteration=100, lower=0.)
    +
    +
    +
    +
    +

    See also

    +

    TotalVariation

    +
    +
    + +
    +
    +

    Other regularisation functions#

    +
    +
    +class cil.plugins.ccpi_regularisation.functions.TGV(alpha=1, gamma=1, max_iteration=100, tolerance=0, device='cpu', **kwargs)[source]#
    +
    +
    +__init__(alpha=1, gamma=1, max_iteration=100, tolerance=0, device='cpu', **kwargs)[source]#
    +

    Creator of Total Generalised Variation Function

    +
    +
    Parameters
    +
      +
    • alpha (number, default 1) – regularisation parameter

    • +
    • gamma (number, default 1, can range between 1 and 2) – ratio of TGV terms

    • +
    • max_iteration (integer, default 100) – max number of sub iterations. The algorithm will iterate up to this number of iteration or up to when the tolerance has been reached

    • +
    • tolerance (float, default 0) – minimum difference between previous iteration of the algorithm that determines the stop of the iteration earlier than max_iteration. If set to 0 only the max_iteration will be used as stop criterion.

    • +
    • device (string, default 'cpu', can be 'gpu' if GPU is installed) – determines if the code runs on CPU or GPU

    • +
    +
    +
    +
    + +
    +
    +__call__(x)[source]#
    +

    Call self as a function.

    +
    + +
    +
    +convex_conjugate(x)[source]#
    +

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    +
    +\[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    +
    +
    Parameters
    +

    x (DataContainer) –

    +
    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    +
    +
    +
    + +
    +
    +__rmul__(scalar)[source]#
    +

    Define the multiplication with a scalar

    +

    this changes the regularisation parameter in the plugin

    +
    + +
    + +
    +
    +class cil.plugins.ccpi_regularisation.functions.FGP_dTV(reference, alpha=1, max_iteration=100, tolerance=0, eta=0.01, isotropic=True, nonnegativity=True, device='cpu')[source]#
    +

    Creator of FGP_dTV Function

    +
    +
    Parameters
    +
      +
    • reference (ImageData) – reference image

    • +
    • alpha (number, default 1) – regularisation parameter

    • +
    • max_iteration (integer, default 100) – max number of sub iterations. The algorithm will iterate up to this number of iteration or up to when the tolerance has been reached

    • +
    • tolerance (float, default 0) – minimum difference between previous iteration of the algorithm that determines the stop of the iteration earlier than max_iteration. If set to 0 only the max_iteration will be used as stop criterion.

    • +
    • eta (number, default 0.01) – smoothing constant to calculate gradient of the reference

    • +
    • isotropic (boolean, default True, can range between 1 and 2) – Whether it uses L2 (isotropic) or L1 (anisotropic) norm

    • +
    • nonnegativity (boolean, default True) – Whether to add the non-negativity constraint

    • +
    • device (string, default 'cpu', can be 'gpu' if GPU is installed) – determines if the code runs on CPU or GPU

    • +
    +
    +
    +
    +
    +__init__(reference, alpha=1, max_iteration=100, tolerance=0, eta=0.01, isotropic=True, nonnegativity=True, device='cpu')[source]#
    +
    + +
    +
    +__call__(x)[source]#
    +

    Call self as a function.

    +
    + +
    +
    +convex_conjugate(x)[source]#
    +

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    +
    +\[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    +
    +
    Parameters
    +

    x (DataContainer) –

    +
    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    +
    +
    +
    + +
    +
    +__rmul__(scalar)[source]#
    +

    Define the multiplication with a scalar

    +

    this changes the regularisation parameter in the plugin

    +
    + +
    + +
    +
    +class cil.plugins.ccpi_regularisation.functions.TNV(alpha=1, max_iteration=100, tolerance=0)[source]#
    +
    +
    +__init__(alpha=1, max_iteration=100, tolerance=0)[source]#
    +

    Creator of TNV Function

    +
    +
    Parameters
    +
      +
    • alpha (number, default 1) – regularisation parameter

    • +
    • max_iteration (integer, default 100) – max number of sub iterations. The algorithm will iterate up to this number of iteration or up to when the tolerance has been reached

    • +
    • tolerance (float, default 0) – minimum difference between previous iteration of the algorithm that determines the stop of the iteration earlier than max_iteration. If set to 0 only the max_iteration will be used as stop criterion.

    • +
    +
    +
    +
    + +
    +
    +__call__(x)[source]#
    +

    Call self as a function.

    +
    + +
    +
    +convex_conjugate(x)[source]#
    +

    Evaluation of the function F* at x, where F* is the convex conjugate of function F,

    +
    +\[F^{*}(x^{*}) = \underset{x}{\sup} \langle x^{*}, x \rangle - F(x)\]
    +
    +
    Parameters
    +

    x (DataContainer) –

    +
    +
    Return type
    +

    The value of the convex conjugate of the function at x.

    +
    +
    +
    + +
    +
    +__rmul__(scalar)[source]#
    +

    Define the multiplication with a scalar

    +

    this changes the regularisation parameter in the plugin

    +
    + +
    +
    +check_input(input)[source]#
    +

    TNV requires 2D+channel data with the first dimension as the channel dimension

    +
    + +
    + +
    +
    +
    +

    TomoPhantom#

    +

    This plugin allows the use of part of TomoPhantom +(10.1016/j.softx.2018.05.003, +a toolbox written in C language to generate customisable 2D-4D phantoms (with a +temporal capability).

    +
    +
    +cil.plugins.TomoPhantom.get_ImageData(num_model, geometry)[source]#
    +

    Returns an ImageData relative to geometry with the model num_model from tomophantom

    +
    +
    Parameters
    +
      +
    • num_model (int) – model number

    • +
    • geometry (ImageGeometry) – geometrical info that describes the phantom

    • +
    +
    +
    +

    Example usage:

    +
    ndim = 2
    +N=128
    +angles = np.linspace(0, 360, 50, True, dtype=np.float32)
    +offset = 0.4
    +channels = 3
    +
    +if ndim == 2:
    +    ag = AcquisitionGeometry.create_Cone2D((offset,-100), (offset,100))
    +    ag.set_panel(N)
    +
    +else:
    +    ag = AcquisitionGeometry.create_Cone3D((offset,-100, 0), (offset,100,0))
    +    ag.set_panel((N,N-2))
    +
    +ag.set_channels(channels)
    +ag.set_angles(angles, angle_unit=AcquisitionGeometry.DEGREE)
    +
    +
    +ig = ag.get_ImageGeometry()
    +num_model = 1
    +phantom = TomoPhantom.get_ImageData(num_model=num_model, geometry=ig)
    +
    +
    +
    + +
    +
    +

    TIGRE#

    +

    This plugin allows the use of TIGRE +(10.1088/2057-1976/2/5/055010 +for forward and back projections and filter back projection reconstruction.

    +
    +

    FBP#

    +

    This reconstructs with FBP for parallel-beam data, and with FDK weights for cone-beam data

    +
    +
    +

    Projection Operator#

    +
    +
    +
    +

    ASTRA#

    +

    This plugin allows the use of ASTRA-toolbox +(10.1364/OE.24.025129) +for forward and back projections and filter back projection reconstruction.

    +
    +

    FBP#

    +

    This reconstructs with FBP for parallel-beam data, and with FDK weights for cone-beam data

    +
    +
    +

    Projection Operator#

    +

    Return Home

    +
    +
    +
    + + +
    + + + + + +
    + + + + +
    +
    + +
    + +
    +
    +
    + + + + + +
    + + +
    + + \ No newline at end of file diff --git a/nightly/processors.html b/nightly/processors/index.html similarity index 55% rename from nightly/processors.html rename to nightly/processors/index.html index 1e4a4bd8d4..033e075b1f 100644 --- a/nightly/processors.html +++ b/nightly/processors/index.html @@ -1,160 +1,382 @@ + - + + + - + + Processors — CIL 23.1.0 documentation - + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + +
    +
    +
    +
    +
    + + + +
    +
    + +
    + + + + + + - - + +
    + + + + + - -
    - + +
    + +
    + + +
    +
    - -
    - -
    - -
    - - - - - - -
    -
    -
    + +
    + +

    Processors#

    This module allows the user to manipulate or pre-process their data.

    -
    +

    Data Manipulation#

    These processors can be used on ImageData or AcquisitionData objects.

    -
    +

    Data Slicer#

    -
    -class cil.processors.Slicer(roi=None)[source]#
    +
    +class cil.processors.Slicer(roi=None)[source]#

    This creates a Slicer processor.

    The processor will crop the data, and then return every n input pixels along a dimension from the starting index.

    The output will be a data container with the data, and geometry updated to reflect the operation.

    @@ -353,59 +519,59 @@

    Data Slicer -
    -set_input(dataset)[source]#
    +
    +set_input(dataset)[source]#

    Set the input data or geometry to the processor

    Parameters
    -

    dataset (DataContainer, Geometry) – The input DataContainer or Geometry

    +

    dataset (DataContainer, Geometry) – The input DataContainer or Geometry

    -
    -process(out=None)[source]#
    +
    +process(out=None)[source]#

    Processes the input data

    Parameters
    -

    out (ImageData, AcquisitionData, DataContainer, optional) – Fills the referenced DataContainer with the processed output and suppresses the return

    +

    out (ImageData, AcquisitionData, DataContainer, optional) – Fills the referenced DataContainer with the processed output and suppresses the return

    Returns

    The downsampled output is returned. Depending on the input type this may be: ImageData, AcquisitionData, DataContainer, ImageGeometry, AcquisitionGeometry

    Return type
    -

    DataContainer

    +

    DataContainer

    -
    -get_output(out=None)#
    +
    +get_output(out=None)#

    Runs the configured processor and returns the processed data

    Parameters
    -

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    +

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    Returns

    The processed data. Suppressed if out is passed

    Return type
    -

    DataContainer

    +

    DataContainer

    - -
    + +

    Data Binner#

    -
    -class cil.processors.Binner(roi=None, accelerated=True)[source]#
    +
    +class cil.processors.Binner(roi=None, accelerated=True)[source]#

    This creates a Binner processor.

    The processor will crop the data, and then average together n input pixels along a dimension from the starting index.

    The output will be a data container with the data, and geometry updated to reflect the operation.

    @@ -450,59 +616,59 @@

    Data Binner -
    -get_output(out=None)#
    +
    +get_output(out=None)#

    Runs the configured processor and returns the processed data

    Parameters
    -

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    +

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    Returns

    The processed data. Suppressed if out is passed

    Return type
    -

    DataContainer

    +

    DataContainer

    -
    -process(out=None)#
    +
    +process(out=None)#

    Processes the input data

    Parameters
    -

    out (ImageData, AcquisitionData, DataContainer, optional) – Fills the referenced DataContainer with the processed output and suppresses the return

    +

    out (ImageData, AcquisitionData, DataContainer, optional) – Fills the referenced DataContainer with the processed output and suppresses the return

    Returns

    The downsampled output is returned. Depending on the input type this may be: ImageData, AcquisitionData, DataContainer, ImageGeometry, AcquisitionGeometry

    Return type
    -

    DataContainer

    +

    DataContainer

    -
    -set_input(dataset)#
    +
    +set_input(dataset)#

    Set the input data or geometry to the processor

    Parameters
    -

    dataset (DataContainer, Geometry) – The input DataContainer or Geometry

    +

    dataset (DataContainer, Geometry) – The input DataContainer or Geometry

    - -
    + +

    Data Padder#

    -
    -class cil.processors.Padder(mode='constant', pad_width=None, pad_values=0)[source]#
    +
    +class cil.processors.Padder(mode='constant', pad_width=None, pad_values=0)[source]#

    Processor to pad an array with a border, wrapping numpy.pad. See https://numpy.org/doc/stable/reference/generated/numpy.pad.html

    It is recommended to use the static methods to configure your Padder object rather than initialising this class directly. See examples for details.

    @@ -564,8 +730,8 @@

    Data Padder -
    -static constant(pad_width=None, constant_values=0.0)[source]#
    +
    +static constant(pad_width=None, constant_values=0.0)[source]#

    Padder processor wrapping numpy.pad with mode constant.

    Pads the data with a constant value border. Pads in all spatial dimensions unless a dictionary is passed to either pad_width or constant_values

    @@ -613,8 +779,8 @@

    Data Padder -
    -static edge(pad_width=None)[source]#
    +
    +static edge(pad_width=None)[source]#

    Padder processor wrapping numpy.pad with mode edge.

    Pads the data by extending the edge values in to the border. Pads in all spatial dimensions unless a dictionary is passed to pad_width.

    @@ -652,8 +818,8 @@

    Data Padder -
    -static linear_ramp(pad_width=None, end_values=0.0)[source]#
    +
    +static linear_ramp(pad_width=None, end_values=0.0)[source]#

    Padder processor wrapping numpy.pad with mode linear_ramp

    Pads the data with values calculated from a linear ramp between the array edge value and the set end_value. Pads in all spatial dimensions unless a dictionary @@ -702,8 +868,8 @@

    Data Padder -
    -static reflect(pad_width=None)[source]#
    +
    +static reflect(pad_width=None)[source]#

    Padder processor wrapping numpy.pad with mode reflect.

    Pads with the reflection of the data mirrored along first and last values each axis. Pads in all spatial dimensions unless a dictionary is passed to pad_width.

    @@ -741,8 +907,8 @@

    Data Padder -
    -static symmetric(pad_width=None)[source]#
    +
    +static symmetric(pad_width=None)[source]#

    Padder processor wrapping numpy.pad with mode symmetric.

    Pads with the reflection of the data mirrored along the edge of the array. Pads in all spatial dimensions unless a dictionary is passed to pad_width.

    @@ -781,8 +947,8 @@

    Data Padder -
    -static wrap(pad_width=None)[source]#
    +
    +static wrap(pad_width=None)[source]#

    Padder processor wrapping numpy.pad with mode wrap.

    Pads with the wrap of the vector along the axis. The first values are used to pad the end and the end values are used to pad the beginning. Pads in all spatial dimensions @@ -822,45 +988,45 @@

    Data Padder -
    -set_input(dataset)[source]#
    +
    +set_input(dataset)[source]#

    Set the input data to the processor

    Parameters
    -

    dataset (DataContainer, Geometry) – The input DataContainer

    +

    dataset (DataContainer, Geometry) – The input DataContainer

    -
    -get_output(out=None)#
    +
    +get_output(out=None)#

    Runs the configured processor and returns the processed data

    Parameters
    -

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    +

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    Returns

    The processed data. Suppressed if out is passed

    Return type
    -

    DataContainer

    +

    DataContainer

    -
    -
    + +

    Mask Generator from Data#

    -
    -class cil.processors.MaskGenerator(mode='special_values', threshold_value=(None, None), quantiles=(None, None), threshold_factor=3, window=5, axis=None)[source]#
    +
    +class cil.processors.MaskGenerator(mode='special_values', threshold_value=(None, None), quantiles=(None, None), threshold_factor=3, window=5, axis=None)[source]#

    Processor to detect outliers and return a mask with 0 where outliers were detected, and 1 for other pixels. Please use the desiried method to configure a processor for your needs.

    -
    -static special_values(nan=True, inf=True)[source]#
    +
    +static special_values(nan=True, inf=True)[source]#

    This creates a MaskGenerator processor which generates a mask for inf and/or nan values.

    Parameters
    @@ -873,8 +1039,8 @@

    Mask Generator from Data -
    -static threshold(min_val=None, max_val=None)[source]#
    +
    +static threshold(min_val=None, max_val=None)[source]#

    This creates a MaskGenerator processor which generates a mask for values outside boundaries

    Parameters
    @@ -887,8 +1053,8 @@

    Mask Generator from Data -
    -static quantile(min_quantile=None, max_quantile=None)[source]#
    +
    +static quantile(min_quantile=None, max_quantile=None)[source]#

    This creates a MaskGenerator processor which generates a mask for values outside boundaries

    Parameters
    @@ -901,8 +1067,8 @@

    Mask Generator from Data -
    -static mean(axis=None, threshold_factor=3, window=None)[source]#
    +
    +static mean(axis=None, threshold_factor=3, window=None)[source]#

    This creates a MaskGenerator processor which generates a mask for values outside a multiple of standard-devaiations from the mean.

    abs(A - mean(A)) < threshold_factor * std(A).

    @@ -917,8 +1083,8 @@

    Mask Generator from Data -
    -static median(axis=None, threshold_factor=3, window=None)[source]#
    +
    +static median(axis=None, threshold_factor=3, window=None)[source]#

    This creates a MaskGenerator processor which generates a mask for values outside a multiple of median absolute deviation (MAD) from the mean.

    abs(A - median(A)) < threshold_factor * MAD(A), MAD = c*median(abs(A-median(A))) where c=-1/(sqrt(2)*erfcinv(3/2))

    @@ -934,50 +1100,50 @@

    Mask Generator from Data -
    -get_output(out=None)#
    +
    +get_output(out=None)#

    Runs the configured processor and returns the processed data

    Parameters
    -

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    +

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    Returns

    The processed data. Suppressed if out is passed

    Return type
    -

    DataContainer

    +

    DataContainer

    -
    -set_input(dataset)#
    +
    +set_input(dataset)#

    Set the input data to the processor

    Parameters
    -

    input (DataContainer) – The input DataContainer

    +

    input (DataContainer) – The input DataContainer

    -

    -
    + +

    Data Masking#

    -
    -class cil.processors.Masker(mask=None, mode='value', value=0, axis=None, method='linear')[source]#
    +
    +class cil.processors.Masker(mask=None, mode='value', value=0, axis=None, method='linear')[source]#

    Processor to fill missing values provided by mask. Please use the desiried method to configure a processor for your needs.

    -
    -static value(mask=None, value=0)[source]#
    +
    +static value(mask=None, value=0)[source]#

    This sets the masked values of the input data to the requested value.

    Parameters
      -
    • mask (DataContainer, ImageData, AcquisitionData, numpy.ndarray) – A boolean array with the same dimensions as input, where ‘False’ represents masked values. Mask can be generated using ‘MaskGenerator’ processor to identify outliers.

    • +
    • mask (DataContainer, ImageData, AcquisitionData, numpy.ndarray) – A boolean array with the same dimensions as input, where ‘False’ represents masked values. Mask can be generated using ‘MaskGenerator’ processor to identify outliers.

    • value (float, default=0) – values to be assigned to missing elements

    @@ -985,13 +1151,13 @@

    Data Masking -
    -static mean(mask=None, axis=None)[source]#
    +
    +static mean(mask=None, axis=None)[source]#

    This sets the masked values of the input data to the mean of the unmasked values across the array or axis.

    Parameters
      -
    • mask (DataContainer, ImageData, AcquisitionData, numpy.ndarray) – A boolean array with the same dimensions as input, where ‘False’ represents masked values. Mask can be generated using ‘MaskGenerator’ processor to identify outliers.

    • +
    • mask (DataContainer, ImageData, AcquisitionData, numpy.ndarray) – A boolean array with the same dimensions as input, where ‘False’ represents masked values. Mask can be generated using ‘MaskGenerator’ processor to identify outliers.

    • axis (str, int) – specify axis as int or from ‘dimension_labels’ to calculate mean.

    @@ -999,13 +1165,13 @@

    Data Masking -
    -static median(mask=None, axis=None)[source]#
    +
    +static median(mask=None, axis=None)[source]#

    This sets the masked values of the input data to the median of the unmasked values across the array or axis.

    Parameters
      -
    • mask (DataContainer, ImageData, AcquisitionData, numpy.ndarray) – A boolean array with the same dimensions as input, where ‘False’ represents masked values. Mask can be generated using ‘MaskGenerator’ processor to identify outliers.

    • +
    • mask (DataContainer, ImageData, AcquisitionData, numpy.ndarray) – A boolean array with the same dimensions as input, where ‘False’ represents masked values. Mask can be generated using ‘MaskGenerator’ processor to identify outliers.

    • axis (str, int) – specify axis as int or from ‘dimension_labels’ to calculate median.

    @@ -1013,13 +1179,13 @@

    Data Masking -
    -static interpolate(mask=None, axis=None, method='linear')[source]#
    +
    +static interpolate(mask=None, axis=None, method='linear')[source]#

    This operates over the specified axis and uses 1D interpolation over remaining flattened array to fill in missing vaues.

    Parameters
      -
    • mask (DataContainer, ImageData, AcquisitionData, numpy.ndarray) – A boolean array with the same dimensions as input, where ‘False’ represents masked values. Mask can be generated using ‘MaskGenerator’ processor to identify outliers.

    • +
    • mask (DataContainer, ImageData, AcquisitionData, numpy.ndarray) – A boolean array with the same dimensions as input, where ‘False’ represents masked values. Mask can be generated using ‘MaskGenerator’ processor to identify outliers.

    • axis (str, int) – specify axis as int or from ‘dimension_labels’ to loop over and perform 1D interpolation.

    • method – One of the following interpoaltion methods: linear, nearest, zeros, linear, quadratic, cubic, previous, next

    • method – str, default=’linear’

    • @@ -1029,41 +1195,41 @@

      Data Masking -
      -get_output(out=None)#
      +
      +get_output(out=None)#

      Runs the configured processor and returns the processed data

      Parameters
      -

      out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

      +

      out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

      Returns

      The processed data. Suppressed if out is passed

      Return type
      -

      DataContainer

      +

      DataContainer

    -
    -set_input(dataset)#
    +
    +set_input(dataset)#

    Set the input data to the processor

    Parameters
    -

    input (DataContainer) – The input DataContainer

    +

    input (DataContainer) – The input DataContainer

    -

    - -
    + + +

    Pre-processors#

    These processors can be used with AcquisitionData objects

    -
    +

    Centre Of Rotation Corrector#

    In the ideal alignment of a CT instrument, the projection of the axis of rotation onto the detector coincides with the vertical midline of the detector. In practice this is hard to achieve @@ -1079,12 +1245,12 @@

    Centre Of Rotation Corrector -
    -class cil.processors.CentreOfRotationCorrector(**attributes)[source]#
    +
    +class cil.processors.CentreOfRotationCorrector(**attributes)[source]#

    This class contains methods to create a CentreOfRotationCorrector processor using the desired algorithm.

    -
    -static xcorrelation(slice_index='centre', projection_index=0, ang_tol=0.1)[source]#
    +
    +static xcorrelation(slice_index='centre', projection_index=0, ang_tol=0.1)[source]#

    This creates a CentreOfRotationCorrector processor using the cross-correlation algorithm.

    For use on parallel-beam geometry it requires two projections 180 degree apart.

    @@ -1130,8 +1296,8 @@

    Centre Of Rotation Corrector -
    -static image_sharpness(slice_index='centre', backend='tigre', tolerance=0.005, search_range=None, initial_binning=None, **kwargs)[source]#
    +
    +static image_sharpness(slice_index='centre', backend='tigre', tolerance=0.005, search_range=None, initial_binning=None, **kwargs)[source]#

    This creates a CentreOfRotationCorrector processor.

    The processor will find the centre offset by maximising the sharpness of a reconstructed slice.

    Can be used on single slice parallel-beam, and centre slice cone beam geometry. For use only with datasets that can be reconstructed with FBP/FDK.

    @@ -1143,11 +1309,9 @@

    Centre Of Rotation CorrectorOther Parameters -

    **kwargs (dict) – FBP : The FBP class to use as the backend imported from cil.plugins.[backend].FBP - This has been deprecated please use ‘backend’ instead

    -

    Example

    from cil.processors import CentreOfRotationCorrector

    @@ -1167,41 +1331,41 @@

    Centre Of Rotation Corrector -
    -get_output(out=None)#
    +
    +get_output(out=None)#

    Runs the configured processor and returns the processed data

    Parameters
    -

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    +

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    Returns

    The processed data. Suppressed if out is passed

    Return type
    -

    DataContainer

    +

    DataContainer

    -
    -set_input(dataset)#
    +
    +set_input(dataset)#

    Set the input data to the processor

    Parameters
    -

    input (DataContainer) – The input DataContainer

    +

    input (DataContainer) – The input DataContainer

    - -
    + +

    Data Normaliser#

    -
    -class cil.processors.Normaliser(flat_field=None, dark_field=None, tolerance=1e-05)[source]#
    +
    +class cil.processors.Normaliser(flat_field=None, dark_field=None, tolerance=1e-05)[source]#

    Normalisation based on flat and dark

    This processor read in a AcquisitionData and normalises it based on the instrument reading with and without incident photons or neutrons.

    @@ -1212,49 +1376,49 @@

    Data Normaliser -
    -static estimate_normalised_error(projection, flat, dark, delta_flat, delta_dark)[source]#
    +
    +static estimate_normalised_error(projection, flat, dark, delta_flat, delta_dark)[source]#

    returns the estimated relative error of the normalised projection

    n = (projection - dark) / (flat - dark) Dn/n = (flat-dark + projection-dark)/((flat-dark)*(projection-dark))*(Df/f + Dd/d)

    -
    -get_output(out=None)#
    +
    +get_output(out=None)#

    Runs the configured processor and returns the processed data

    Parameters
    -

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    +

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    Returns

    The processed data. Suppressed if out is passed

    Return type
    -

    DataContainer

    +

    DataContainer

    -
    -set_input(dataset)#
    +
    +set_input(dataset)#

    Set the input data to the processor

    Parameters
    -

    input (DataContainer) – The input DataContainer

    +

    input (DataContainer) – The input DataContainer

    -
    -
    + +

    Transmission to Absorption Converter#

    -
    -class cil.processors.TransmissionAbsorptionConverter(min_intensity=0.0, white_level=1.0)[source]#
    +
    +class cil.processors.TransmissionAbsorptionConverter(min_intensity=0.0, white_level=1.0)[source]#

    Processor to convert from transmission measurements to absorption based on the Beer-Lambert law

    @@ -1268,47 +1432,47 @@

    Transmission to Absorption Converter

    returns AcquisitionData, ImageData or DataContainer depending on input data type, return is suppressed if ‘out’ is passed

    Return type
    -

    AcquisitionData, ImageData or DataContainer

    +

    AcquisitionData, ImageData or DataContainer

    Processor first divides by white_level (default=1) and then take negative logarithm. Elements below threshold (after division by white_level) are set to threshold.

    -
    -get_output(out=None)#
    +
    +get_output(out=None)#

    Runs the configured processor and returns the processed data

    Parameters
    -

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    +

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    Returns

    The processed data. Suppressed if out is passed

    Return type
    -

    DataContainer

    +

    DataContainer

    -
    -set_input(dataset)#
    +
    +set_input(dataset)#

    Set the input data to the processor

    Parameters
    -

    input (DataContainer) – The input DataContainer

    +

    input (DataContainer) – The input DataContainer

    -
    -
    + +

    Absorption to Transmission Converter#

    -
    -class cil.processors.AbsorptionTransmissionConverter(white_level=1)[source]#
    +
    +class cil.processors.AbsorptionTransmissionConverter(white_level=1)[source]#

    Processor to convert from absorption measurements to transmission

    Parameters
    @@ -1318,47 +1482,47 @@

    Absorption to Transmission Converter

    returns AcquisitionData, ImageData or DataContainer depending on input data type

    Return type
    -

    AcquisitionData, ImageData or DataContainer

    +

    AcquisitionData, ImageData or DataContainer

    Processor first multiplies data by -1, then calculates exponent and scales result by white_level (default=1)

    -
    -get_output(out=None)#
    +
    +get_output(out=None)#

    Runs the configured processor and returns the processed data

    Parameters
    -

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    +

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    Returns

    The processed data. Suppressed if out is passed

    Return type
    -

    DataContainer

    +

    DataContainer

    -
    -set_input(dataset)#
    +
    +set_input(dataset)#

    Set the input data to the processor

    Parameters
    -

    input (DataContainer) – The input DataContainer

    +

    input (DataContainer) – The input DataContainer

    -
    -
    + +

    Ring Remover#

    -
    -class cil.processors.RingRemover(decNum=4, wname='db10', sigma=1.5, info=True)[source]#
    +
    +class cil.processors.RingRemover(decNum=4, wname='db10', sigma=1.5, info=True)[source]#

    RingRemover Processor: Removes vertical stripes from a DataContainer(ImageData/AcquisitionData) using the algorithm in https://doi.org/10.1364/OE.17.008567

    @@ -1376,90 +1540,116 @@

    Ring Remover

    Corrected ImageData/AcquisitionData 2D, 3D, multi-spectral 2D, multi-spectral 3D

    Return type
    -

    DataContainer

    +

    DataContainer

    -
    -get_output(out=None)#
    +
    +get_output(out=None)#

    Runs the configured processor and returns the processed data

    Parameters
    -

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    +

    out (DataContainer, optional) – Fills the referenced DataContainer with the processed data and suppresses the return

    Returns

    The processed data. Suppressed if out is passed

    Return type
    -

    DataContainer

    +

    DataContainer

    -
    -set_input(dataset)#
    +
    +set_input(dataset)#

    Set the input data to the processor

    Parameters
    -

    input (DataContainer) – The input DataContainer

    +

    input (DataContainer) – The input DataContainer

    -

    Return Home

    -
    - - +

    Return Home

    + + + - + + - - + + + + + + + + +
    + +
    + + + - -
    -
    + + + +
    +
    + + +
    + +
    \ No newline at end of file diff --git a/nightly/py-modindex.html b/nightly/py-modindex.html deleted file mode 100644 index 5c3e012fdf..0000000000 --- a/nightly/py-modindex.html +++ /dev/null @@ -1,255 +0,0 @@ - - - - - - - - Python Module Index — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - - - - - - - - -
    - -
    - - - - - - -
    - -
    - - -

    Python Module Index

    - -
    - c -
    - - - - - - - - - - -
     
    - c
    - cil -
        - cil.utilities.quality_measures -
    - - -
    - - - -
    -
    - -
    - - -
    -
    - - - -
    -
    - - - - - -
    -
    - - \ No newline at end of file diff --git a/nightly/py-modindex/index.html b/nightly/py-modindex/index.html new file mode 100644 index 0000000000..c37dcb6943 --- /dev/null +++ b/nightly/py-modindex/index.html @@ -0,0 +1,492 @@ + + + + + + + + + + + Python Module Index — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    + + + +
    +
    + +
    + + + + + + + + + + + + + +
    + +
    + + +
    +
    + +
    + + + + + + + + + +
    + +
    + +
    +
    +
    + +
    + +
    + +
    + + + + +
    +
    + +
    + +
    +
    +
    + + + + + +
    + + +
    + + \ No newline at end of file diff --git a/nightly/recon.html b/nightly/recon.html deleted file mode 100644 index 8ea7c1ad34..0000000000 --- a/nightly/recon.html +++ /dev/null @@ -1,635 +0,0 @@ - - - - - - - - Recon — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - - - - - - - - - - - - - - - -
    - -
    - -
    -

    Recon#

    -

    This module allows the user to run pre-configured reconstruction algorithms on their data.

    -
    -

    Analytical Reconstruction#

    -

    The CIL analytical reconstructions use CIL to filter and prepare the data using highly optimised routines. The filtered data is then -backprojected using projectors from TIGRE or ASTRA-TOOLBOX.

    -

    Standard FBP (filtered-backprojection) should be used for parallel-beam data. FDK (Feldkamp, Davis, and Kress) is a filtered-backprojection -algorithm for reconstruction of cone-beam data measured with a standard circular orbit.

    -

    The filter can be set to a predefined function, or a custom filter can be set. The predefined filters take the following forms:

    -
    -FBP Filters -
    -
    -

    FBP - Reconstructor for parallel-beam geometry#

    -
    -
    -class cil.recon.FBP(input, image_geometry=None, filter='ram-lak', backend='tigre')[source]#
    -

    Creates an FBP reconstructor based on your parallel-beam acquisition data.

    -
    -
    Parameters
    -
      -
    • input (AcquisitionData) – The input data to reconstruct. The reconstructor is set-up based on the geometry of the data.

    • -
    • image_geometry (ImageGeometry, default used if None) – A description of the area/volume to reconstruct

    • -
    • filter (string, numpy.ndarray, default='ram-lak') – The filter to be applied. Can be a string from: {‘ram-lak’, ‘shepp-logan’, ‘cosine’, ‘hamming’, ‘hann’}, or a numpy array.

    • -
    • backend (string) – The backend to use, can be ‘astra’ or ‘tigre’. Data must be in the correct order for requested backend.

    • -
    -
    -
    -

    Example

    -
    >>> from cil.utilities.dataexample import SIMULATED_PARALLEL_BEAM_DATA
    ->>> from cil.recon import FBP
    ->>> data = SIMULATED_PARALLEL_BEAM_DATA.get()
    ->>> fbp = FBP(data)
    ->>> out = fbp.run()
    -
    -
    -

    Notes

    -

    The reconstructor can be further customised using additional ‘set’ methods provided.

    -
    -
    -set_split_processing(slices_per_chunk=0)[source]#
    -

    Splits the processing in to chunks. Default, 0 will process the data in a single call.

    -
    -
    Parameters
    -

    out (slices_per_chunk, optional) – Process the data in chunks of n slices. It is recommended to use value of power-of-two.

    -
    -
    -

    Notes

    -

    This will reduce memory use but may increase computation time. -It is recommended to tune it too your hardware requirements using 8, 16 or 32 slices.

    -

    This can only be used on simple and offset data-geometries.

    -
    - -
    -
    -run(out=None, verbose=1)[source]#
    -

    Runs the configured FBP recon and returns the reconstruction

    -
    -
    Parameters
    -
      -
    • out (ImageData, optional) – Fills the referenced ImageData with the reconstructed volume and suppresses the return

    • -
    • verbose (int, default=1) – Controls the verbosity of the reconstructor. 0: No output is logged, 1: Full configuration is logged

    • -
    -
    -
    Returns
    -

    The reconstructed volume. Suppressed if out is passed

    -
    -
    Return type
    -

    ImageData

    -
    -
    -
    - -
    -
    -reset()[source]#
    -

    Resets all optional configuration parameters to their default values

    -
    - -
    -
    -get_filter_array()#
    -

    Returns the filter array in the frequency domain.

    -
    -
    Returns
    -

    An array containing the filter values

    -
    -
    Return type
    -

    numpy.ndarray

    -
    -
    -

    Notes

    -

    The filter length N is 2^self.fft_order.

    -

    The indices of the array are interpreted as:

    -
      -
    • [0] The DC frequency component

    • -
    • [1:N/2] positive frequencies

    • -
    • [N/2:N-1] negative frequencies

    • -
    -

    The array can be modified and passed back using set_filter()

    -

    Notes

    -

    Filter reference in frequency domain: -Eq. 1.12 - 1.15 T. M. Buzug. Computed Tomography: From Photon Statistics to Modern Cone-Beam CT. Berlin: Springer, 2008.

    -

    Plantagie, L. Algebraic filters for filtered backprojection, 2017 -https://hdl.handle.net/1887/48289

    -
    - -
    -
    -set_fft_order(order=None)#
    -

    The width of the fourier transform N=2^order.

    -
    -
    Parameters
    -

    order (int, optional) – The width of the fft N=2^order

    -
    -
    -

    Notes

    -

    If None the default used is the power-of-2 greater than 2 * detector width, or 8, whichever is greater -Higher orders will yield more accurate results but increase computation time.

    -
    - -
    -
    -set_filter(filter='ram-lak', cutoff=1.0)#
    -

    Set the filter used by the reconstruction.

    -

    Pre-set filters are constructed in the frequency domain. -Pre-set filters are: ‘ram-lak’, ‘shepp-logan’, ‘cosine’, ‘hamming’, ‘hann’

    -
    -
    Parameters
    -
      -
    • filter (string, numpy.ndarray, default='ram-lak') – Pass a string selecting from the list of pre-set filters, or pass a numpy.ndarray with a custom filter.

    • -
    • cutoff (float, default = 1) – The cut-off frequency of the filter between 0 - 1 pi rads/pixel. The filter will be 0 outside the range rect(-frequency_cutoff, frequency_cutoff)

    • -
    -
    -
    -

    Notes

    -

    If passed a numpy array the filter must have length N = 2^self.fft_order

    -

    The indices of the array are interpreted as:

    -
      -
    • [0] The DC frequency component

    • -
    • [1:N/2] positive frequencies

    • -
    • [N/2:N-1] negative frequencies

    • -
    -
    - -
    -
    -set_filter_inplace(inplace=False)#
    -

    False (default) will allocate temporary memory for filtered projections. -True will filter projections in-place.

    -
    -
    Parameters
    -

    inplace (boolean) – Sets the inplace filtering of projections

    -
    -
    -
    - -
    -
    -set_image_geometry(image_geometry=None)#
    -

    Sets a custom image geometry to be used by the reconstructor

    -
    -
    Parameters
    -

    image_geometry (ImageGeometry, default used if None) – A description of the area/volume to reconstruct

    -
    -
    -
    - -
    -
    -set_input(input)#
    -

    Update the input data to run the reconstructor on. The geometry of the dataset must be compatible with the reconstructor.

    -
    -
    Parameters
    -

    input (AcquisitionData) – A dataset with a compatible geometry

    -
    -
    -
    - -
    - -
    -
    -

    FDK - Reconstructor for cone-beam geometry#

    -
    -
    -class cil.recon.FDK(input, image_geometry=None, filter='ram-lak')[source]#
    -

    Creates an FDK reconstructor based on your cone-beam acquisition data using TIGRE as a backend.

    -
    -
    Parameters
    -
      -
    • input (AcquisitionData) – The input data to reconstruct. The reconstructor is set-up based on the geometry of the data.

    • -
    • image_geometry (ImageGeometry, default used if None) – A description of the area/volume to reconstruct

    • -
    • filter (string, numpy.ndarray, default='ram-lak') – The filter to be applied. Can be a string from: {‘ram-lak’, ‘shepp-logan’, ‘cosine’, ‘hamming’, ‘hann’}, or a numpy array.

    • -
    -
    -
    -

    Example

    -
    >>> from cil.utilities.dataexample import SIMULATED_CONE_BEAM_DATA
    ->>> from cil.recon import FDK
    ->>> data = SIMULATED_CONE_BEAM_DATA.get()
    ->>> fdk = FDK(data)
    ->>> out = fdk.run()
    -
    -
    -

    Notes

    -

    The reconstructor can be futher customised using additional ‘set’ methods provided.

    -
    -
    -run(out=None, verbose=1)[source]#
    -

    Runs the configured FDK recon and returns the reconstruction.

    -
    -
    Parameters
    -
      -
    • out (ImageData, optional) – Fills the referenced ImageData with the reconstructed volume and suppresses the return

    • -
    • verbose (int, default=1) – Controls the verbosity of the reconstructor. 0: No output is logged, 1: Full configuration is logged

    • -
    -
    -
    Returns
    -

    The reconstructed volume. Suppressed if out is passed

    -
    -
    Return type
    -

    ImageData

    -
    -
    -
    - -
    -
    -get_filter_array()#
    -

    Returns the filter array in the frequency domain.

    -
    -
    Returns
    -

    An array containing the filter values

    -
    -
    Return type
    -

    numpy.ndarray

    -
    -
    -

    Notes

    -

    The filter length N is 2^self.fft_order.

    -

    The indices of the array are interpreted as:

    -
      -
    • [0] The DC frequency component

    • -
    • [1:N/2] positive frequencies

    • -
    • [N/2:N-1] negative frequencies

    • -
    -

    The array can be modified and passed back using set_filter()

    -

    Notes

    -

    Filter reference in frequency domain: -Eq. 1.12 - 1.15 T. M. Buzug. Computed Tomography: From Photon Statistics to Modern Cone-Beam CT. Berlin: Springer, 2008.

    -

    Plantagie, L. Algebraic filters for filtered backprojection, 2017 -https://hdl.handle.net/1887/48289

    -
    - -
    -
    -reset()#
    -

    Resets all optional configuration parameters to their default values

    -
    - -
    -
    -set_fft_order(order=None)#
    -

    The width of the fourier transform N=2^order.

    -
    -
    Parameters
    -

    order (int, optional) – The width of the fft N=2^order

    -
    -
    -

    Notes

    -

    If None the default used is the power-of-2 greater than 2 * detector width, or 8, whichever is greater -Higher orders will yield more accurate results but increase computation time.

    -
    - -
    -
    -set_filter(filter='ram-lak', cutoff=1.0)#
    -

    Set the filter used by the reconstruction.

    -

    Pre-set filters are constructed in the frequency domain. -Pre-set filters are: ‘ram-lak’, ‘shepp-logan’, ‘cosine’, ‘hamming’, ‘hann’

    -
    -
    Parameters
    -
      -
    • filter (string, numpy.ndarray, default='ram-lak') – Pass a string selecting from the list of pre-set filters, or pass a numpy.ndarray with a custom filter.

    • -
    • cutoff (float, default = 1) – The cut-off frequency of the filter between 0 - 1 pi rads/pixel. The filter will be 0 outside the range rect(-frequency_cutoff, frequency_cutoff)

    • -
    -
    -
    -

    Notes

    -

    If passed a numpy array the filter must have length N = 2^self.fft_order

    -

    The indices of the array are interpreted as:

    -
      -
    • [0] The DC frequency component

    • -
    • [1:N/2] positive frequencies

    • -
    • [N/2:N-1] negative frequencies

    • -
    -
    - -
    -
    -set_filter_inplace(inplace=False)#
    -

    False (default) will allocate temporary memory for filtered projections. -True will filter projections in-place.

    -
    -
    Parameters
    -

    inplace (boolean) – Sets the inplace filtering of projections

    -
    -
    -
    - -
    -
    -set_image_geometry(image_geometry=None)#
    -

    Sets a custom image geometry to be used by the reconstructor

    -
    -
    Parameters
    -

    image_geometry (ImageGeometry, default used if None) – A description of the area/volume to reconstruct

    -
    -
    -
    - -
    -
    -set_input(input)#
    -

    Update the input data to run the reconstructor on. The geometry of the dataset must be compatible with the reconstructor.

    -
    -
    Parameters
    -

    input (AcquisitionData) – A dataset with a compatible geometry

    -
    -
    -
    - -
    - -

    Return Home

    -
    -
    -
    - - -
    - - - - - -
    - - -
    -
    - - - -
    -
    - - - - - -
    -
    - - \ No newline at end of file diff --git a/nightly/recon/index.html b/nightly/recon/index.html new file mode 100644 index 0000000000..4bb7467729 --- /dev/null +++ b/nightly/recon/index.html @@ -0,0 +1,874 @@ + + + + + + + + + + + + Recon — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    + + + +
    +
    + +
    + + + + + + + + + + + + + +
    + +
    + + +
    +
    + +
    +
    + +
    + +
    + + + + +
    + +
    + + +
    +
    + + + + + +
    + +
    +

    Recon#

    +

    This module allows the user to run pre-configured reconstruction algorithms on their data.

    +
    +

    Analytical Reconstruction#

    +

    The CIL analytical reconstructions use CIL to filter and prepare the data using highly optimised routines. The filtered data is then +backprojected using projectors from TIGRE or ASTRA-TOOLBOX.

    +

    Standard FBP (filtered-backprojection) should be used for parallel-beam data. FDK (Feldkamp, Davis, and Kress) is a filtered-backprojection +algorithm for reconstruction of cone-beam data measured with a standard circular orbit.

    +

    The filter can be set to a predefined function, or a custom filter can be set. The predefined filters take the following forms:

    +
    +FBP Filters +
    +
    +

    FBP - Reconstructor for parallel-beam geometry#

    +
    +
    +class cil.recon.FBP(input, image_geometry=None, filter='ram-lak', backend='tigre')[source]#
    +

    Creates an FBP reconstructor based on your parallel-beam acquisition data.

    +
    +
    Parameters
    +
      +
    • input (AcquisitionData) – The input data to reconstruct. The reconstructor is set-up based on the geometry of the data.

    • +
    • image_geometry (ImageGeometry, default used if None) – A description of the area/volume to reconstruct

    • +
    • filter (string, numpy.ndarray, default='ram-lak') – The filter to be applied. Can be a string from: {’ram-lak’, ‘shepp-logan’, ‘cosine’, ‘hamming’, ‘hann’}, or a numpy array.

    • +
    • backend (string) – The backend to use, can be ‘astra’ or ‘tigre’. Data must be in the correct order for requested backend.

    • +
    +
    +
    +

    Example

    +
    >>> from cil.utilities.dataexample import SIMULATED_PARALLEL_BEAM_DATA
    +>>> from cil.recon import FBP
    +>>> data = SIMULATED_PARALLEL_BEAM_DATA.get()
    +>>> fbp = FBP(data)
    +>>> out = fbp.run()
    +
    +
    +

    Notes

    +

    The reconstructor can be further customised using additional ‘set’ methods provided.

    +
    +
    +set_split_processing(slices_per_chunk=0)[source]#
    +

    Splits the processing in to chunks. Default, 0 will process the data in a single call.

    +
    +
    Parameters
    +

    out (slices_per_chunk, optional) – Process the data in chunks of n slices. It is recommended to use value of power-of-two.

    +
    +
    +

    Notes

    +

    This will reduce memory use but may increase computation time. +It is recommended to tune it too your hardware requirements using 8, 16 or 32 slices.

    +

    This can only be used on simple and offset data-geometries.

    +
    + +
    +
    +run(out=None, verbose=1)[source]#
    +

    Runs the configured FBP recon and returns the reconstruction

    +
    +
    Parameters
    +
      +
    • out (ImageData, optional) – Fills the referenced ImageData with the reconstructed volume and suppresses the return

    • +
    • verbose (int, default=1) – Controls the verbosity of the reconstructor. 0: No output is logged, 1: Full configuration is logged

    • +
    +
    +
    Returns
    +

    The reconstructed volume. Suppressed if out is passed

    +
    +
    Return type
    +

    ImageData

    +
    +
    +
    + +
    +
    +reset()[source]#
    +

    Resets all optional configuration parameters to their default values

    +
    + +
    +
    +get_filter_array()#
    +

    Returns the filter array in the frequency domain.

    +
    +
    Returns
    +

    An array containing the filter values

    +
    +
    Return type
    +

    numpy.ndarray

    +
    +
    +

    Notes

    +

    The filter length N is 2^self.fft_order.

    +

    The indices of the array are interpreted as:

    +
      +
    • [0] The DC frequency component

    • +
    • [1:N/2] positive frequencies

    • +
    • [N/2:N-1] negative frequencies

    • +
    +

    The array can be modified and passed back using set_filter()

    +

    Notes

    +

    Filter reference in frequency domain: +Eq. 1.12 - 1.15 T. M. Buzug. Computed Tomography: From Photon Statistics to Modern Cone-Beam CT. Berlin: Springer, 2008.

    +

    Plantagie, L. Algebraic filters for filtered backprojection, 2017 +https://hdl.handle.net/1887/48289

    +
    + +
    +
    +set_fft_order(order=None)#
    +

    The width of the fourier transform N=2^order.

    +
    +
    Parameters
    +

    order (int, optional) – The width of the fft N=2^order

    +
    +
    +

    Notes

    +

    If None the default used is the power-of-2 greater than 2 * detector width, or 8, whichever is greater +Higher orders will yield more accurate results but increase computation time.

    +
    + +
    +
    +set_filter(filter='ram-lak', cutoff=1.0)#
    +

    Set the filter used by the reconstruction.

    +

    Pre-set filters are constructed in the frequency domain. +Pre-set filters are: ‘ram-lak’, ‘shepp-logan’, ‘cosine’, ‘hamming’, ‘hann’

    +
    +
    Parameters
    +
      +
    • filter (string, numpy.ndarray, default='ram-lak') – Pass a string selecting from the list of pre-set filters, or pass a numpy.ndarray with a custom filter.

    • +
    • cutoff (float, default = 1) – The cut-off frequency of the filter between 0 - 1 pi rads/pixel. The filter will be 0 outside the range rect(-frequency_cutoff, frequency_cutoff)

    • +
    +
    +
    +

    Notes

    +

    If passed a numpy array the filter must have length N = 2^self.fft_order

    +

    The indices of the array are interpreted as:

    +
      +
    • [0] The DC frequency component

    • +
    • [1:N/2] positive frequencies

    • +
    • [N/2:N-1] negative frequencies

    • +
    +
    + +
    +
    +set_filter_inplace(inplace=False)#
    +

    False (default) will allocate temporary memory for filtered projections. +True will filter projections in-place.

    +
    +
    Parameters
    +

    inplace (boolean) – Sets the inplace filtering of projections

    +
    +
    +
    + +
    +
    +set_image_geometry(image_geometry=None)#
    +

    Sets a custom image geometry to be used by the reconstructor

    +
    +
    Parameters
    +

    image_geometry (ImageGeometry, default used if None) – A description of the area/volume to reconstruct

    +
    +
    +
    + +
    +
    +set_input(input)#
    +

    Update the input data to run the reconstructor on. The geometry of the dataset must be compatible with the reconstructor.

    +
    +
    Parameters
    +

    input (AcquisitionData) – A dataset with a compatible geometry

    +
    +
    +
    + +
    + +
    +
    +

    FDK - Reconstructor for cone-beam geometry#

    +
    +
    +class cil.recon.FDK(input, image_geometry=None, filter='ram-lak')[source]#
    +

    Creates an FDK reconstructor based on your cone-beam acquisition data using TIGRE as a backend.

    +
    +
    Parameters
    +
      +
    • input (AcquisitionData) – The input data to reconstruct. The reconstructor is set-up based on the geometry of the data.

    • +
    • image_geometry (ImageGeometry, default used if None) – A description of the area/volume to reconstruct

    • +
    • filter (string, numpy.ndarray, default='ram-lak') – The filter to be applied. Can be a string from: {’ram-lak’, ‘shepp-logan’, ‘cosine’, ‘hamming’, ‘hann’}, or a numpy array.

    • +
    +
    +
    +

    Example

    +
    >>> from cil.utilities.dataexample import SIMULATED_CONE_BEAM_DATA
    +>>> from cil.recon import FDK
    +>>> data = SIMULATED_CONE_BEAM_DATA.get()
    +>>> fdk = FDK(data)
    +>>> out = fdk.run()
    +
    +
    +

    Notes

    +

    The reconstructor can be futher customised using additional ‘set’ methods provided.

    +
    +
    +run(out=None, verbose=1)[source]#
    +

    Runs the configured FDK recon and returns the reconstruction.

    +
    +
    Parameters
    +
      +
    • out (ImageData, optional) – Fills the referenced ImageData with the reconstructed volume and suppresses the return

    • +
    • verbose (int, default=1) – Controls the verbosity of the reconstructor. 0: No output is logged, 1: Full configuration is logged

    • +
    +
    +
    Returns
    +

    The reconstructed volume. Suppressed if out is passed

    +
    +
    Return type
    +

    ImageData

    +
    +
    +
    + +
    +
    +get_filter_array()#
    +

    Returns the filter array in the frequency domain.

    +
    +
    Returns
    +

    An array containing the filter values

    +
    +
    Return type
    +

    numpy.ndarray

    +
    +
    +

    Notes

    +

    The filter length N is 2^self.fft_order.

    +

    The indices of the array are interpreted as:

    +
      +
    • [0] The DC frequency component

    • +
    • [1:N/2] positive frequencies

    • +
    • [N/2:N-1] negative frequencies

    • +
    +

    The array can be modified and passed back using set_filter()

    +

    Notes

    +

    Filter reference in frequency domain: +Eq. 1.12 - 1.15 T. M. Buzug. Computed Tomography: From Photon Statistics to Modern Cone-Beam CT. Berlin: Springer, 2008.

    +

    Plantagie, L. Algebraic filters for filtered backprojection, 2017 +https://hdl.handle.net/1887/48289

    +
    + +
    +
    +reset()#
    +

    Resets all optional configuration parameters to their default values

    +
    + +
    +
    +set_fft_order(order=None)#
    +

    The width of the fourier transform N=2^order.

    +
    +
    Parameters
    +

    order (int, optional) – The width of the fft N=2^order

    +
    +
    +

    Notes

    +

    If None the default used is the power-of-2 greater than 2 * detector width, or 8, whichever is greater +Higher orders will yield more accurate results but increase computation time.

    +
    + +
    +
    +set_filter(filter='ram-lak', cutoff=1.0)#
    +

    Set the filter used by the reconstruction.

    +

    Pre-set filters are constructed in the frequency domain. +Pre-set filters are: ‘ram-lak’, ‘shepp-logan’, ‘cosine’, ‘hamming’, ‘hann’

    +
    +
    Parameters
    +
      +
    • filter (string, numpy.ndarray, default='ram-lak') – Pass a string selecting from the list of pre-set filters, or pass a numpy.ndarray with a custom filter.

    • +
    • cutoff (float, default = 1) – The cut-off frequency of the filter between 0 - 1 pi rads/pixel. The filter will be 0 outside the range rect(-frequency_cutoff, frequency_cutoff)

    • +
    +
    +
    +

    Notes

    +

    If passed a numpy array the filter must have length N = 2^self.fft_order

    +

    The indices of the array are interpreted as:

    +
      +
    • [0] The DC frequency component

    • +
    • [1:N/2] positive frequencies

    • +
    • [N/2:N-1] negative frequencies

    • +
    +
    + +
    +
    +set_filter_inplace(inplace=False)#
    +

    False (default) will allocate temporary memory for filtered projections. +True will filter projections in-place.

    +
    +
    Parameters
    +

    inplace (boolean) – Sets the inplace filtering of projections

    +
    +
    +
    + +
    +
    +set_image_geometry(image_geometry=None)#
    +

    Sets a custom image geometry to be used by the reconstructor

    +
    +
    Parameters
    +

    image_geometry (ImageGeometry, default used if None) – A description of the area/volume to reconstruct

    +
    +
    +
    + +
    +
    +set_input(input)#
    +

    Update the input data to run the reconstructor on. The geometry of the dataset must be compatible with the reconstructor.

    +
    +
    Parameters
    +

    input (AcquisitionData) – A dataset with a compatible geometry

    +
    +
    +
    + +
    + +

    Return Home

    +
    +
    +
    + + +
    + + + + + +
    + + + + +
    +
    + +
    + +
    +
    +
    + + + + + +
    + + +
    + + \ No newline at end of file diff --git a/nightly/search.html b/nightly/search.html deleted file mode 100644 index 2089325751..0000000000 --- a/nightly/search.html +++ /dev/null @@ -1,245 +0,0 @@ - - - - - - - - Search — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - - - - - - - - -
    - -
    - - - - - - -
    - -
    - -

    Search

    -
    - -

    - Please activate JavaScript to enable the search - functionality. -

    -
    -

    - Searching for multiple words only shows matches that contain - all words. -

    -
    - - - -
    - -
    - -
    - -
    - - - -
    -
    - -
    - - -
    -
    - - - -
    -
    - - - - - -
    -
    - - \ No newline at end of file diff --git a/nightly/search/index.html b/nightly/search/index.html new file mode 100644 index 0000000000..d9d5e8b182 --- /dev/null +++ b/nightly/search/index.html @@ -0,0 +1,496 @@ + + + + + + + + + + Search - CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    + + + +
    +
    + +
    + + + + + + + + + + + + + +
    + +
    + + +
    +
    + +
    + + +
    +

    Search

    + + + +
    +
    + + + + +
    + +
    + +
    +
    +
    + +
    + +
    + +
    + + + + +
    +
    + +
    + +
    +
    +
    + + + + + +
    + + +
    + + \ No newline at end of file diff --git a/nightly/searchindex.js b/nightly/searchindex.js index 80e740eedb..6329a52b27 100644 --- a/nightly/searchindex.js +++ b/nightly/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["developer_guide","framework","index","introduction","io","optimisation","plugins","processors","recon","utilities"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,"sphinxcontrib.bibtex":9,sphinx:56},filenames:["developer_guide.rst","framework.rst","index.rst","introduction.rst","io.rst","optimisation.rst","plugins.rst","processors.rst","recon.rst","utilities.rst"],objects:{"cil.framework":{AcquisitionData:[1,0,1,""],AcquisitionGeometry:[1,0,1,""],BlockDataContainer:[5,0,1,""],BlockGeometry:[1,0,1,""],DataContainer:[1,0,1,""],DataOrder:[1,0,1,""],DataProcessor:[1,0,1,""],ImageData:[1,0,1,""],ImageGeometry:[1,0,1,""],Processor:[1,0,1,""],VectorData:[1,0,1,""]},"cil.framework.AcquisitionData":{as_array:[1,1,1,""],clone:[1,1,1,""],copy:[1,1,1,""],dot:[1,1,1,""],dtype:[1,1,1,""],exp:[1,1,1,""],fill:[1,1,1,""],get_data_axes_order:[1,1,1,""],get_dimension_axis:[1,1,1,""],get_slice:[1,1,1,""],log:[1,1,1,""],max:[1,1,1,""],mean:[1,1,1,""],min:[1,1,1,""],ndim:[1,1,1,""],norm:[1,1,1,""],number_of_dimensions:[1,1,1,""],partition:[1,1,1,""],reorder:[1,1,1,""],sapyb:[1,1,1,""],shape:[1,1,1,""],size:[1,1,1,""],squared_norm:[1,1,1,""],sum:[1,1,1,""]},"cil.framework.AcquisitionGeometry":{allocate:[1,1,1,""],create_Cone2D:[1,1,1,""],create_Cone3D:[1,1,1,""],create_Parallel2D:[1,1,1,""],create_Parallel3D:[1,1,1,""],get_ImageGeometry:[1,1,1,""],get_slice:[1,1,1,""],set_angles:[1,1,1,""],set_channels:[1,1,1,""],set_labels:[1,1,1,""],set_panel:[1,1,1,""]},"cil.framework.BlockDataContainer":{__iadd__:[5,1,1,""],__idiv__:[5,1,1,""],__imul__:[5,1,1,""],__isub__:[5,1,1,""],__iter__:[5,1,1,""],__itruediv__:[5,1,1,""],__neg__:[5,1,1,""],__radd__:[5,1,1,""],__rdiv__:[5,1,1,""],__rmul__:[5,1,1,""],__rpow__:[5,1,1,""],__rsub__:[5,1,1,""],__rtruediv__:[5,1,1,""],__weakref__:[5,2,1,""],add:[5,1,1,""],axpby:[5,1,1,""],binary_operations:[5,1,1,""],copy:[5,1,1,""],divide:[5,1,1,""],is_compatible:[5,1,1,""],maximum:[5,1,1,""],minimum:[5,1,1,""],multiply:[5,1,1,""],next:[5,1,1,""],power:[5,1,1,""],sapyb:[5,1,1,""],subtract:[5,1,1,""],unary_operations:[5,1,1,""]},"cil.framework.BlockGeometry":{allocate:[1,1,1,""],get_item:[1,1,1,""]},"cil.framework.DataContainer":{as_array:[1,1,1,""],clone:[1,1,1,""],copy:[1,1,1,""],dot:[1,1,1,""],dtype:[1,1,1,""],exp:[1,1,1,""],fill:[1,1,1,""],get_data_axes_order:[1,1,1,""],get_dimension_axis:[1,1,1,""],get_slice:[1,1,1,""],log:[1,1,1,""],max:[1,1,1,""],mean:[1,1,1,""],min:[1,1,1,""],ndim:[1,1,1,""],norm:[1,1,1,""],number_of_dimensions:[1,1,1,""],reorder:[1,1,1,""],sapyb:[1,1,1,""],shape:[1,1,1,""],size:[1,1,1,""],squared_norm:[1,1,1,""],sum:[1,1,1,""]},"cil.framework.DataProcessor":{check_input:[1,1,1,""],get_input:[1,1,1,""],get_output:[1,1,1,""],set_input:[1,1,1,""]},"cil.framework.ImageData":{apply_circular_mask:[1,1,1,""],as_array:[1,1,1,""],clone:[1,1,1,""],copy:[1,1,1,""],dot:[1,1,1,""],dtype:[1,1,1,""],exp:[1,1,1,""],fill:[1,1,1,""],get_data_axes_order:[1,1,1,""],get_dimension_axis:[1,1,1,""],get_slice:[1,1,1,""],log:[1,1,1,""],max:[1,1,1,""],mean:[1,1,1,""],min:[1,1,1,""],ndim:[1,1,1,""],norm:[1,1,1,""],number_of_dimensions:[1,1,1,""],reorder:[1,1,1,""],sapyb:[1,1,1,""],shape:[1,1,1,""],size:[1,1,1,""],squared_norm:[1,1,1,""],sum:[1,1,1,""]},"cil.framework.ImageGeometry":{allocate:[1,1,1,""],clone:[1,1,1,""],copy:[1,1,1,""],get_slice:[1,1,1,""]},"cil.framework.Processor":{check_input:[1,1,1,""],get_input:[1,1,1,""],get_output:[1,1,1,""],set_input:[1,1,1,""]},"cil.framework.VectorData":{as_array:[1,1,1,""],clone:[1,1,1,""],copy:[1,1,1,""],dot:[1,1,1,""],dtype:[1,1,1,""],exp:[1,1,1,""],fill:[1,1,1,""],get_data_axes_order:[1,1,1,""],get_dimension_axis:[1,1,1,""],get_slice:[1,1,1,""],log:[1,1,1,""],max:[1,1,1,""],mean:[1,1,1,""],min:[1,1,1,""],ndim:[1,1,1,""],norm:[1,1,1,""],number_of_dimensions:[1,1,1,""],reorder:[1,1,1,""],sapyb:[1,1,1,""],shape:[1,1,1,""],size:[1,1,1,""],squared_norm:[1,1,1,""],sum:[1,1,1,""]},"cil.io":{NEXUSDataReader:[4,0,1,""],NEXUSDataWriter:[4,0,1,""],NikonDataReader:[4,0,1,""],RAWFileWriter:[4,0,1,""],TIFFStackReader:[4,0,1,""],TIFFWriter:[4,0,1,""],ZEISSDataReader:[4,0,1,""]},"cil.io.NEXUSDataReader":{get_data_offset:[4,1,1,""],get_data_scale:[4,1,1,""],get_geometry:[4,1,1,""],load_data:[4,1,1,""],read:[4,1,1,""],read_as_original:[4,1,1,""],set_up:[4,1,1,""]},"cil.io.NEXUSDataWriter":{set_up:[4,1,1,""],write:[4,1,1,""]},"cil.io.NikonDataReader":{get_geometry:[4,1,1,""],get_roi:[4,1,1,""],load_projections:[4,1,1,""],read:[4,1,1,""]},"cil.io.RAWFileWriter":{write:[4,1,1,""]},"cil.io.TIFFStackReader":{read:[4,1,1,""],read_as_AcquisitionData:[4,1,1,""],read_as_ImageData:[4,1,1,""],read_rescaled:[4,1,1,""],read_scale_offset:[4,1,1,""]},"cil.io.TIFFWriter":{write:[4,1,1,""]},"cil.io.ZEISSDataReader":{get_geometry:[4,1,1,""],get_metadata:[4,1,1,""],read:[4,1,1,""],set_up:[4,1,1,""],slice_metadata:[4,1,1,""]},"cil.io.utilities":{HDF5_utilities:[4,0,1,""]},"cil.io.utilities.HDF5_utilities":{get_dataset_metadata:[4,1,1,""],print_metadata:[4,1,1,""],read:[4,1,1,""],read_to:[4,1,1,""]},"cil.optimisation.algorithms":{Algorithm:[5,0,1,""],CGLS:[5,0,1,""],FISTA:[5,0,1,""],GD:[5,0,1,""],ISTA:[5,0,1,""],LADMM:[5,0,1,""],PDHG:[5,0,1,""],SIRT:[5,0,1,""],SPDHG:[5,0,1,""]},"cil.optimisation.algorithms.Algorithm":{get_last_loss:[5,1,1,""],get_last_objective:[5,1,1,""],get_output:[5,1,1,""],is_provably_convergent:[5,1,1,""],iterations:[5,1,1,""],loss:[5,1,1,""],max_iteration:[5,1,1,""],max_iteration_stop_criterion:[5,1,1,""],next:[5,1,1,""],objective:[5,1,1,""],run:[5,1,1,""],set_up:[5,1,1,""],should_stop:[5,1,1,""],update:[5,1,1,""],update_objective:[5,1,1,""],verbose_output:[5,1,1,""]},"cil.optimisation.algorithms.CGLS":{flag:[5,1,1,""],get_last_loss:[5,1,1,""],get_last_objective:[5,1,1,""],get_output:[5,1,1,""],is_provably_convergent:[5,1,1,""],iterations:[5,1,1,""],loss:[5,1,1,""],max_iteration:[5,1,1,""],max_iteration_stop_criterion:[5,1,1,""],next:[5,1,1,""],objective:[5,1,1,""],run:[5,1,1,""],set_up:[5,1,1,""],should_stop:[5,1,1,""],update:[5,1,1,""],update_objective:[5,1,1,""],verbose_output:[5,1,1,""]},"cil.optimisation.algorithms.FISTA":{__delattr__:[5,1,1,""],__dir__:[5,1,1,""],__eq__:[5,1,1,""],__format__:[5,1,1,""],__ge__:[5,1,1,""],__getattribute__:[5,1,1,""],__gt__:[5,1,1,""],__hash__:[5,1,1,""],__init__:[5,1,1,""],__init_subclass__:[5,1,1,""],__iter__:[5,1,1,""],__le__:[5,1,1,""],__lt__:[5,1,1,""],__ne__:[5,1,1,""],__new__:[5,1,1,""],__next__:[5,1,1,""],__reduce__:[5,1,1,""],__reduce_ex__:[5,1,1,""],__repr__:[5,1,1,""],__setattr__:[5,1,1,""],__sizeof__:[5,1,1,""],__str__:[5,1,1,""],__subclasshook__:[5,1,1,""],__weakref__:[5,2,1,""],get_last_loss:[5,1,1,""],get_last_objective:[5,1,1,""],get_output:[5,1,1,""],is_provably_convergent:[5,1,1,""],iterations:[5,1,1,""],loss:[5,1,1,""],max_iteration:[5,1,1,""],max_iteration_stop_criterion:[5,1,1,""],next:[5,1,1,""],objective:[5,1,1,""],run:[5,1,1,""],set_step_size:[5,1,1,""],set_up:[5,1,1,""],should_stop:[5,1,1,""],update:[5,1,1,""],update_objective:[5,1,1,""],verbose_output:[5,1,1,""]},"cil.optimisation.algorithms.GD":{armijo_rule:[5,1,1,""],get_last_loss:[5,1,1,""],get_last_objective:[5,1,1,""],get_output:[5,1,1,""],is_provably_convergent:[5,1,1,""],iterations:[5,1,1,""],loss:[5,1,1,""],max_iteration:[5,1,1,""],max_iteration_stop_criterion:[5,1,1,""],next:[5,1,1,""],objective:[5,1,1,""],run:[5,1,1,""],set_up:[5,1,1,""],should_stop:[5,1,1,""],update:[5,1,1,""],update_objective:[5,1,1,""],verbose_output:[5,1,1,""]},"cil.optimisation.algorithms.ISTA":{__delattr__:[5,1,1,""],__dir__:[5,1,1,""],__eq__:[5,1,1,""],__format__:[5,1,1,""],__ge__:[5,1,1,""],__getattribute__:[5,1,1,""],__gt__:[5,1,1,""],__hash__:[5,1,1,""],__init__:[5,1,1,""],__init_subclass__:[5,1,1,""],__iter__:[5,1,1,""],__le__:[5,1,1,""],__lt__:[5,1,1,""],__ne__:[5,1,1,""],__new__:[5,1,1,""],__next__:[5,1,1,""],__reduce__:[5,1,1,""],__reduce_ex__:[5,1,1,""],__repr__:[5,1,1,""],__setattr__:[5,1,1,""],__sizeof__:[5,1,1,""],__str__:[5,1,1,""],__subclasshook__:[5,1,1,""],__weakref__:[5,2,1,""],get_last_loss:[5,1,1,""],get_last_objective:[5,1,1,""],get_output:[5,1,1,""],is_provably_convergent:[5,1,1,""],iterations:[5,1,1,""],loss:[5,1,1,""],max_iteration:[5,1,1,""],max_iteration_stop_criterion:[5,1,1,""],next:[5,1,1,""],objective:[5,1,1,""],run:[5,1,1,""],set_step_size:[5,1,1,""],set_up:[5,1,1,""],should_stop:[5,1,1,""],update:[5,1,1,""],update_objective:[5,1,1,""],verbose_output:[5,1,1,""]},"cil.optimisation.algorithms.LADMM":{get_last_loss:[5,1,1,""],get_last_objective:[5,1,1,""],get_output:[5,1,1,""],is_provably_convergent:[5,1,1,""],iterations:[5,1,1,""],loss:[5,1,1,""],max_iteration:[5,1,1,""],max_iteration_stop_criterion:[5,1,1,""],next:[5,1,1,""],objective:[5,1,1,""],run:[5,1,1,""],set_up:[5,1,1,""],should_stop:[5,1,1,""],update:[5,1,1,""],update_objective:[5,1,1,""],verbose_output:[5,1,1,""]},"cil.optimisation.algorithms.PDHG":{check_convergence:[5,1,1,""],get_last_loss:[5,1,1,""],get_last_objective:[5,1,1,""],get_output:[5,1,1,""],is_provably_convergent:[5,1,1,""],iterations:[5,1,1,""],loss:[5,1,1,""],max_iteration:[5,1,1,""],max_iteration_stop_criterion:[5,1,1,""],next:[5,1,1,""],objective:[5,1,1,""],run:[5,1,1,""],set_gamma_fconj:[5,1,1,""],set_gamma_g:[5,1,1,""],set_step_sizes:[5,1,1,""],set_up:[5,1,1,""],should_stop:[5,1,1,""],update:[5,1,1,""],update_objective:[5,1,1,""],update_step_sizes:[5,1,1,""],verbose_output:[5,1,1,""]},"cil.optimisation.algorithms.SIRT":{get_last_loss:[5,1,1,""],get_last_objective:[5,1,1,""],get_output:[5,1,1,""],is_provably_convergent:[5,1,1,""],iterations:[5,1,1,""],loss:[5,1,1,""],max_iteration:[5,1,1,""],max_iteration_stop_criterion:[5,1,1,""],next:[5,1,1,""],objective:[5,1,1,""],run:[5,1,1,""],set_relaxation_parameter:[5,1,1,""],set_up:[5,1,1,""],should_stop:[5,1,1,""],update:[5,1,1,""],update_objective:[5,1,1,""],verbose_output:[5,1,1,""]},"cil.optimisation.algorithms.SPDHG":{get_last_loss:[5,1,1,""],get_last_objective:[5,1,1,""],get_output:[5,1,1,""],is_provably_convergent:[5,1,1,""],iterations:[5,1,1,""],loss:[5,1,1,""],max_iteration:[5,1,1,""],max_iteration_stop_criterion:[5,1,1,""],next:[5,1,1,""],objective:[5,1,1,""],run:[5,1,1,""],set_up:[5,1,1,""],should_stop:[5,1,1,""],update:[5,1,1,""],update_objective:[5,1,1,""],verbose_output:[5,1,1,""]},"cil.optimisation.functions":{BlockFunction:[5,0,1,""],ConstantFunction:[5,0,1,""],Function:[5,0,1,""],IndicatorBox:[5,0,1,""],KullbackLeibler:[5,0,1,""],L1Norm:[5,0,1,""],L2NormSquared:[5,0,1,""],LeastSquares:[5,0,1,""],MixedL11Norm:[5,0,1,""],MixedL21Norm:[5,0,1,""],OperatorCompositionFunction:[5,0,1,""],Rosenbrock:[5,0,1,""],ScaledFunction:[5,0,1,""],SmoothMixedL21Norm:[5,0,1,""],SumFunction:[5,0,1,""],SumScalarFunction:[5,0,1,""],TotalVariation:[5,0,1,""],TranslateFunction:[5,0,1,""],WeightedL2NormSquared:[5,0,1,""],ZeroFunction:[5,0,1,""]},"cil.optimisation.functions.BlockFunction":{L:[5,1,1,""],__call__:[5,1,1,""],__init__:[5,1,1,""],__rmul__:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.ConstantFunction":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.Function":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.IndicatorBox":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],num_threads:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""],set_num_threads:[5,1,1,""],set_suppress_evaluation:[5,1,1,""]},"cil.optimisation.functions.KullbackLeibler":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.L1Norm":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.L2NormSquared":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.LeastSquares":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.MixedL11Norm":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.MixedL21Norm":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.OperatorCompositionFunction":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.Rosenbrock":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.ScaledFunction":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.SmoothMixedL21Norm":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.SumFunction":{L:[5,1,1,""],Lmax:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.SumScalarFunction":{L:[5,1,1,""],Lmax:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.TotalVariation":{L:[5,1,1,""],calculate_Lipschitz:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.TranslateFunction":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.WeightedL2NormSquared":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.functions.ZeroFunction":{L:[5,1,1,""],centered_at:[5,1,1,""],convex_conjugate:[5,1,1,""],gradient:[5,1,1,""],proximal:[5,1,1,""],proximal_conjugate:[5,1,1,""]},"cil.optimisation.operators":{BlockOperator:[5,0,1,""],ChannelwiseOperator:[5,0,1,""],CompositionOperator:[5,0,1,""],DiagonalOperator:[5,0,1,""],FiniteDifferenceOperator:[5,0,1,""],GradientOperator:[5,0,1,""],IdentityOperator:[5,0,1,""],LinearOperator:[5,0,1,""],MaskOperator:[5,0,1,""],MatrixOperator:[5,0,1,""],Operator:[5,0,1,""],ScaledOperator:[5,0,1,""],SparseFiniteDifferenceOperator:[5,0,1,""],SumOperator:[5,0,1,""],SymmetrisedGradientOperator:[5,0,1,""],ZeroOperator:[5,0,1,""]},"cil.optimisation.operators.BlockOperator":{T:[5,1,1,""],__getitem__:[5,1,1,""],__init__:[5,1,1,""],__rmul__:[5,1,1,""],adjoint:[5,1,1,""],column_wise_compatible:[5,1,1,""],direct:[5,1,1,""],domain_geometry:[5,1,1,""],get_as_list:[5,1,1,""],get_item:[5,1,1,""],get_norms_as_list:[5,1,1,""],get_output_shape:[5,1,1,""],is_linear:[5,1,1,""],norm:[5,1,1,""],range_geometry:[5,1,1,""],row_wise_compatible:[5,1,1,""],set_norms:[5,1,1,""]},"cil.optimisation.operators.ChannelwiseOperator":{adjoint:[5,1,1,""],calculate_norm:[5,1,1,""],direct:[5,1,1,""]},"cil.optimisation.operators.CompositionOperator":{adjoint:[5,1,1,""],direct:[5,1,1,""],is_linear:[5,1,1,""]},"cil.optimisation.operators.DiagonalOperator":{adjoint:[5,1,1,""],calculate_norm:[5,1,1,""],direct:[5,1,1,""]},"cil.optimisation.operators.FiniteDifferenceOperator":{adjoint:[5,1,1,""],direct:[5,1,1,""]},"cil.optimisation.operators.GradientOperator":{adjoint:[5,1,1,""],calculate_norm:[5,1,1,""],direct:[5,1,1,""]},"cil.optimisation.operators.IdentityOperator":{adjoint:[5,1,1,""],calculate_norm:[5,1,1,""],direct:[5,1,1,""]},"cil.optimisation.operators.LinearOperator":{PowerMethod:[5,1,1,""],adjoint:[5,1,1,""],calculate_norm:[5,1,1,""],dot_test:[5,1,1,""],is_linear:[5,1,1,""]},"cil.optimisation.operators.MatrixOperator":{adjoint:[5,1,1,""],direct:[5,1,1,""]},"cil.optimisation.operators.Operator":{calculate_norm:[5,1,1,""],direct:[5,1,1,""],domain_geometry:[5,1,1,""],is_linear:[5,1,1,""],norm:[5,1,1,""],range_geometry:[5,1,1,""],set_norm:[5,1,1,""]},"cil.optimisation.operators.ScaledOperator":{adjoint:[5,1,1,""],direct:[5,1,1,""],is_linear:[5,1,1,""],norm:[5,1,1,""]},"cil.optimisation.operators.SparseFiniteDifferenceOperator":{direct:[5,1,1,""]},"cil.optimisation.operators.SumOperator":{adjoint:[5,1,1,""],direct:[5,1,1,""],is_linear:[5,1,1,""]},"cil.optimisation.operators.SymmetrisedGradientOperator":{adjoint:[5,1,1,""],direct:[5,1,1,""]},"cil.optimisation.operators.ZeroOperator":{adjoint:[5,1,1,""],calculate_norm:[5,1,1,""],direct:[5,1,1,""]},"cil.optimisation.utilities":{Sampler:[5,0,1,""],SamplerRandom:[5,0,1,""]},"cil.optimisation.utilities.Sampler":{from_function:[5,1,1,"id28"],get_samples:[5,1,1,""],herman_meyer:[5,1,1,"id29"],next:[5,1,1,""],random_with_replacement:[5,1,1,"id26"],random_without_replacement:[5,1,1,"id27"],sequential:[5,1,1,"id0"],staggered:[5,1,1,"id25"]},"cil.optimisation.utilities.SamplerRandom":{get_samples:[5,1,1,""]},"cil.plugins.TomoPhantom":{get_ImageData:[6,3,1,""]},"cil.plugins.astra":{FBP:[6,0,1,""],ProjectionOperator:[6,0,1,""]},"cil.plugins.astra.FBP":{get_output:[6,1,1,""],set_input:[6,1,1,""]},"cil.plugins.ccpi_regularisation.functions":{FGP_TV:[6,0,1,""],FGP_dTV:[6,0,1,""],TGV:[6,0,1,""],TNV:[6,0,1,""]},"cil.plugins.ccpi_regularisation.functions.FGP_dTV":{__call__:[6,1,1,""],__init__:[6,1,1,""],__rmul__:[6,1,1,""],convex_conjugate:[6,1,1,""]},"cil.plugins.ccpi_regularisation.functions.TGV":{__call__:[6,1,1,""],__init__:[6,1,1,""],__rmul__:[6,1,1,""],convex_conjugate:[6,1,1,""]},"cil.plugins.ccpi_regularisation.functions.TNV":{__call__:[6,1,1,""],__init__:[6,1,1,""],__rmul__:[6,1,1,""],check_input:[6,1,1,""],convex_conjugate:[6,1,1,""]},"cil.plugins.tigre":{FBP:[6,0,1,""],ProjectionOperator:[6,0,1,""]},"cil.plugins.tigre.FBP":{get_output:[6,1,1,""],set_input:[6,1,1,""]},"cil.processors":{AbsorptionTransmissionConverter:[7,0,1,""],Binner:[7,0,1,""],CentreOfRotationCorrector:[7,0,1,""],MaskGenerator:[7,0,1,""],Masker:[7,0,1,""],Normaliser:[7,0,1,""],Padder:[7,0,1,""],RingRemover:[7,0,1,""],Slicer:[7,0,1,""],TransmissionAbsorptionConverter:[7,0,1,""]},"cil.processors.AbsorptionTransmissionConverter":{get_output:[7,1,1,""],set_input:[7,1,1,""]},"cil.processors.Binner":{get_output:[7,1,1,""],process:[7,1,1,""],set_input:[7,1,1,""]},"cil.processors.CentreOfRotationCorrector":{get_output:[7,1,1,""],image_sharpness:[7,1,1,""],set_input:[7,1,1,""],xcorrelation:[7,1,1,""]},"cil.processors.MaskGenerator":{get_output:[7,1,1,""],mean:[7,1,1,""],median:[7,1,1,""],quantile:[7,1,1,""],set_input:[7,1,1,""],special_values:[7,1,1,""],threshold:[7,1,1,""]},"cil.processors.Masker":{get_output:[7,1,1,""],interpolate:[7,1,1,""],mean:[7,1,1,""],median:[7,1,1,""],set_input:[7,1,1,""],value:[7,1,1,""]},"cil.processors.Normaliser":{estimate_normalised_error:[7,1,1,""],get_output:[7,1,1,""],set_input:[7,1,1,""]},"cil.processors.Padder":{constant:[7,1,1,""],edge:[7,1,1,""],get_output:[7,1,1,""],linear_ramp:[7,1,1,""],reflect:[7,1,1,""],set_input:[7,1,1,""],symmetric:[7,1,1,""],wrap:[7,1,1,""]},"cil.processors.RingRemover":{get_output:[7,1,1,""],set_input:[7,1,1,""]},"cil.processors.Slicer":{get_output:[7,1,1,""],process:[7,1,1,""],set_input:[7,1,1,""]},"cil.processors.TransmissionAbsorptionConverter":{get_output:[7,1,1,""],set_input:[7,1,1,""]},"cil.recon":{FBP:[8,0,1,""],FDK:[8,0,1,""]},"cil.recon.FBP":{get_filter_array:[8,1,1,""],reset:[8,1,1,""],run:[8,1,1,""],set_fft_order:[8,1,1,""],set_filter:[8,1,1,""],set_filter_inplace:[8,1,1,""],set_image_geometry:[8,1,1,""],set_input:[8,1,1,""],set_split_processing:[8,1,1,""]},"cil.recon.FBP.FBP":{run:[0,1,1,""]},"cil.recon.FDK":{get_filter_array:[8,1,1,""],reset:[8,1,1,""],run:[8,1,1,""],set_fft_order:[8,1,1,""],set_filter:[8,1,1,""],set_filter_inplace:[8,1,1,""],set_image_geometry:[8,1,1,""],set_input:[8,1,1,""]},"cil.utilities":{quality_measures:[9,4,0,"-"]},"cil.utilities.dataexample":{SIMULATED_CONE_BEAM_DATA:[9,0,1,"id0"],SIMULATED_PARALLEL_BEAM_DATA:[9,0,1,""],SYNCHROTRON_PARALLEL_BEAM_DATA:[9,0,1,""],TestData:[9,0,1,""]},"cil.utilities.dataexample.SIMULATED_CONE_BEAM_DATA":{get:[9,1,1,"id1"]},"cil.utilities.dataexample.SIMULATED_PARALLEL_BEAM_DATA":{get:[9,1,1,""]},"cil.utilities.dataexample.SYNCHROTRON_PARALLEL_BEAM_DATA":{get:[9,1,1,""]},"cil.utilities.dataexample.TestData":{load:[9,1,1,""],random_noise:[9,1,1,""],scikit_random_noise:[9,1,1,""]},"cil.utilities.display":{show1D:[9,0,1,""],show2D:[9,0,1,""],show_geometry:[9,0,1,""]},"cil.utilities.display.show1D":{figure:[9,2,1,""],save:[9,1,1,""]},"cil.utilities.display.show2D":{save:[9,1,1,""]},"cil.utilities.display.show_geometry":{save:[9,1,1,""]},"cil.utilities.jupyter":{islicer:[9,0,1,""],link_islicer:[9,0,1,""]},"cil.utilities.quality_measures":{mae:[9,3,1,""],mse:[9,3,1,""],psnr:[9,3,1,""]}},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"],"3":["py","function","Python function"],"4":["py","module","Python module"]},objtypes:{"0":"py:class","1":"py:method","2":"py:attribute","3":"py:function","4":"py:module"},terms:{"0000654846240296":5,"0005647295658866":5,"00186":5,"003":6,"005":7,"008":5,"008567":7,"010":5,"018":5,"0192":[2,5],"0193":[2,5],"020":5,"0251":5,"025129":6,"055010":6,"080716542":5,"09076934x":5,"100":[4,5,6],"1007":5,"1015":5,"1016":6,"1046":5,"1088":6,"1098":[2,5],"1102995080":5,"1109":5,"1137":5,"120":[5,7],"128":[6,7],"1321":5,"1364":[6,7],"145":5,"1533217":5,"180":7,"183":5,"1887":8,"1976":6,"1992":5,"200":[4,7],"2001":5,"2003":5,"2008":8,"2009":5,"2010":5,"2011":5,"2016":5,"2017":[5,8],"2018":[5,6],"2019":[5,6,9],"202":5,"2020":[2,5],"20200192":[2,5],"20200193":[2,5],"2021":[2,5],"2022":[0,5],"2028250":5,"2057":6,"20channel":5,"2204":5,"2419":5,"2434":5,"256":9,"2783":5,"2808":5,"2_2":[3,5],"2beta":5,"2ca":5,"2pi":6,"2wx":5,"300":4,"360":6,"360deg":7,"377":5,"379":5,"381":5,"400":5,"430":5,"48289":8,"4t_":5,"500":9,"550":4,"649":5,"664":5,"7142857142857":4,"9225":5,"9780898719277":5,"9ntwu9megq":2,"abstract":5,"boolean":[1,5,6,7,8,9],"byte":5,"case":[1,4,5,7,9],"class":[0,1,2,4,6,7,8,9],"default":[0,1,4,5,6,7,8,9],"final":5,"float":[1,4,5,6,7,8,9],"function":[1,2,3,4,8,9],"import":[4,5,6,7,8,9],"int":[0,1,4,5,6,7,8,9],"j\u00f8rgensen":2,"long":[1,5],"new":[1,2,5],"return":[0,1,4,5,6,7,8,9],"richt\u00e1rik":5,"sch\u00f6nlieb":5,"static":[1,4,5,7,9],"true":[1,4,5,6,7,8,9],"try":1,"var":9,"while":[2,5],AND:9,ARE:9,BUT:9,DLS:9,FOR:9,For:[0,1,2,4,5,6,7,9],IDEs:0,NOT:9,One:[7,9],SUCH:9,THE:9,The:[0,1,2,3,4,5,6,7,8,9],Their:5,Then:5,There:1,These:[4,7],USE:9,Use:[0,2,5,9],Used:[5,9],Uses:[5,7],Will:[1,9],With:[3,5],__array_priority__:5,__call__:[5,6],__delattr__:5,__dir__:5,__eq__:5,__format__:5,__ge__:5,__getattribute__:5,__getitem__:5,__gt__:5,__hash__:5,__iadd__:5,__idiv__:5,__imul__:5,__init__:[5,6],__init_subclass__:5,__isub__:5,__iter__:5,__itruediv__:5,__le__:5,__lt__:5,__mul__:5,__ne__:5,__neg__:5,__new__:5,__next__:5,__radd__:5,__rdiv__:5,__reduce__:5,__reduce_ex__:5,__repr__:5,__rmul__:[5,6],__rpow__:5,__rsub__:5,__rtruediv__:5,__setattr__:[1,5],__sizeof__:5,__str__:5,__subclasscheck__:5,__subclasshook__:5,__weakref__:5,_as_gen:9,_dual:[5,6],_gradient:5,_po_class:0,_pre_filt:0,_process_chunk:0,_setup_po_for_chunk:0,_slices_per_chunk:0,abc:5,abcmeta:5,abl:[3,5,6],about:[4,7],about_original_data:4,abov:[2,3,5,6,9],abs:[1,5,7],absolut:[5,7,9],absorpt:2,absorptiontransmissionconvert:7,abspath:4,acceler:[3,5,7],accept:[0,1,4,5,7],access:5,accord:1,accordingli:5,accumul:1,accur:[5,6,8],accuraci:7,achiev:[3,5,7],acquir:[3,5],acquisit:[1,2,3,4,5,6,8,9],acquisition_geometri:[0,4,6,9],acquisitiondata:[2,3,5,7,8,9],acquisitiondatasetn:7,acquisitiongeomerti:1,acquisitiongeometri:[2,3,4,5,6,7,9],across:[6,7],act:5,activ:0,actor:[3,5],actual:[0,5],ad1:4,adapt:9,add:[0,1,5,6,9],added:[5,6],addit:[0,1,5,7,8,9],adher:0,adjoint:[0,5,6],adjoint_weight:6,adjust:4,admm:5,advanc:[0,3,5],advis:9,affect:5,after:[5,7,9],ag1:4,again:5,against:9,agre:0,aim:2,algebr:[1,5],algebra:[1,5,8],algorithm:[2,3,6,7,8],alia:[1,4,5,9],align:[1,5,7],all:[0,1,4,5,6,7,8,9],alloc:[0,1,5,8],allow:[1,3,4,5,6,7,8,9],alon:9,along:[1,4,5,7,9],alpha:[3,5,6],alphabet:4,also:[0,2,3,4,5,7],alter:7,altern:[4,5],although:5,alwai:[4,5],ametova:5,amir:5,amount:[3,5,9],analyt:[2,5],ang_tol:7,angl:[1,4,6,7],angle_unit:[1,6],angular:[1,6,7],ani:[0,1,3,5,6,9],anisotrop:[5,6],anoth:5,antonin:5,aop:5,apach:0,apart:7,api:9,appear:7,append:5,appli:[1,3,4,5,6,7,8,9],applic:[0,5],apply_circular_mask:1,appropri:[0,1,5,6],approx:5,approxim:[4,6],arbitrari:5,archiv:5,area:[6,8],arg:[0,1,5,9],argmin:[3,5,6],argument:[0,1,5,9],aris:9,armijo:5,armijo_rul:5,around:5,arrai:[0,1,3,4,5,7,8,9],arrang:[3,4],artefact:[1,7],articl:[2,6],artifact:7,arxiv:5,as_arrai:1,ascent:5,aspect:9,assembl:3,assign:7,assum:[5,9],astra:[1,2,3,7,8],asymmetr:7,asymptot:5,attribut:[1,3,4,7],augment:5,author:[0,9],auto:5,automat:7,avail:5,averag:[4,7],avinash:5,avoid:[5,7],axes:[1,4,7],axi:[1,4,7,9],axis_0:4,axis_1:4,axis_2:4,axis_label:[4,9],axis_labels_1:4,axis_labels_2:4,axis_nam:7,axis_name1:7,axis_name2:7,axpbi:[1,5],azimuth:9,b_i:5,back:[3,4,6,8,9],backend:[5,7,8],background:5,backproject:[5,8],backward:[1,4,5,6],backward_project:6,bar:5,base:[0,1,2,3,7,8,9],basi:0,basic:[1,2,4,5],basicconfig:7,batch:1,bdc1:[1,5],bdc2:[1,5],bdc:1,beam:[1,2,6,7,9],becaus:[5,9],beck:5,becom:5,been:[4,5,6,7],beer:7,befor:[4,5,7,9],begin:[0,3,5,7],behav:[1,5],behaviour:[4,5,7,9],being:[2,7,9],below:[3,5,7,9],berlin:8,best:[6,7],beta:5,betck:5,better:[3,5],between:[1,3,5,6,7,8,9],beyond:[3,9],bibian:5,big:5,bin:[4,7],binari:[1,4,9],binary_oper:[1,5],binner:2,binom:[3,5],biologi:5,bit:4,blob:[4,5,9],block:[1,2],blockdatacontain:[2,3,9],blockfunct:[3,5],blockgeometri:[2,3,5,6],blockoper:[3,5,6],blur:7,bmatrix:5,bnd_cond:5,boat:9,book:5,bool:[4,5,7,9],boolian:1,border:7,both:[1,2,3,5,7],bottom:[0,1],bound:5,boundari:[5,7],box:[2,9],broadcast:6,brows:4,build:[2,3,5],burca:5,busi:[5,9],buzug:8,bypass:1,cach:5,calcul:[1,4,5,6,7,9],calculate_lipschitz:5,calculate_norm:5,call:[3,4,5,6,8],callabl:5,callback:5,camera:9,can:[0,1,2,3,4,5,6,7,8,9],cannot:9,cap:0,capabl:6,care:9,carola:5,cast:1,caus:[7,9],ccpi:[2,4],ccpi_regularis:6,cdot:5,ceil:[0,5],center:[3,5,7,9],center_i:1,center_x:1,center_z:1,centered_at:5,centr:[1,2,9],centreofrotationcorrector:7,cern:6,certain:5,cgl:[2,3],chambol:5,chan:5,chang:[0,4,5,6,9],channel:[1,2,5,6,7,9],channel_label:1,channelwiseoper:5,chapter:5,characterist:3,check:[1,4,5],check_converg:5,check_input:[1,6],child:5,choic:5,choos:5,chosen:5,chunk:[0,4,8],cil:[1,3,4,5,7,8,9],cil_log_level:7,circ:5,circular:[1,3,6,8],clair:5,classmethod:9,clear:5,clearli:0,clip:9,clone:[0,1,5],close:[0,5],cmake:0,cmap:9,code:[0,1,2,4,5,6,9],coincid:7,col:5,collect:[2,5],collim:3,color:9,colorbar:9,colormap:9,colour:9,column:[1,4,5,9],column_wise_compat:5,com:[0,2,5,6,9],comment:0,common:3,commonli:1,commut:[1,5],compar:9,comparison:[5,9],compat:[1,4,5,6,8],complex128:1,complex:[1,5],compli:0,complianc:0,compon:[5,7,8],compos:5,composed_with_adjoint:5,composit:2,compositionoper:5,compress:4,compressed_data:4,compris:[3,5],comput:[5,6,7,8],computation:5,computer:5,concret:5,conda:0,conda_prefix:0,condit:[0,5,9],cone2d:2,cone3d:2,cone:[1,2,6,7,9],config:[0,4],configpars:4,configur:[0,2,4,5,6,7,8],conjug:[1,5,6],consecut:5,consequenti:9,consid:[2,3,5,9],consist:[1,5],constant:[5,6,7],constant_valu:7,constantfunct:5,constrain:5,constraint:[5,6],construct:[2,4,5,8],constructor:5,contain:[0,2,3,4,5,7,8,9],content:[4,5],continu:5,contract:9,contribut:[2,5,7],contributor:9,control:[0,5,8],convent:[2,3,5],converg:5,convert:[2,9],convex:[5,6],convex_conjug:[5,6],coordin:9,copi:[0,1,5],copyright:[0,9],core:[0,2,3,5],correct:[1,5,7,8],corrector:2,correl:[5,7],correlation_spac:5,correspond:[4,5,7,9],corrupt:9,cosin:8,costli:5,could:[1,5],counter_offset:4,cours:5,courtesi:[4,5],cpu:[5,6],creat:[0,1,3,4,5,7,8,9],create_cone2d:[1,6],create_cone3d:[1,6],create_local_env_for_cil_development_test:0,create_parallel2d:1,create_parallel3d:1,creation:5,creator:[2,6],criteria:7,criterion:[5,6],crop:[4,7],cross:7,cubic:7,cuda:6,current:[0,1,5],custom:[5,8],custom_list:5,customis:[6,8],cut:8,cutoff:8,damag:9,damp:7,dark:7,dark_field:7,data:[2,4,5,6,8],data_bin:7,data_centr:7,data_channel0:9,data_channel1:9,data_dir:9,data_pad:7,data_rang:9,data_sl:7,data_typ:4,datacontain:[2,4,5,6,7,9],datacontainer0:1,datacontainer1:1,dataexampl:[8,9],dataord:2,dataprocessor:2,dataset:[0,1,2,3,4,6,7,8],date:2,davi:8,db10:7,db1:7,db35:7,dc1:9,dc2:9,dcmake_install_prefix:0,dealloc:5,deblur:5,debug:7,decnum:7,decompos:5,decomposit:7,deep:5,deep_copi:1,def:[0,5],defin:[1,2,3,4,5,6,7,9],definit:[0,3,5,6],degre:[1,6,7,9],delattr:5,delplanck:5,delta:5,delta_dark:7,delta_flat:7,demo:[3,5],denois:5,denot:5,dens:5,depend:[0,3,4,5,7],deprec:[1,5,7],depth:4,deriv:[5,9],descent:5,describ:[1,3,4,5,6],descript:[3,6,7,8],design:[3,5],desir:[5,7],desiri:7,dest_sel:4,destin:4,detail:[1,2,7],detect:7,detector:[1,3,4,7,8],detector_direction_i:1,detector_direction_x:1,detector_i:1,detector_posit:1,detector_x:1,determin:[1,6],determinist:5,devaiat:7,devel:2,develop:[2,3,5],deviat:[7,9],devic:6,diag:5,diagon:5,diagonaloper:5,diamond:2,dict:[4,5,7],dictionari:[1,4,7],differ:[2,3,5,6,7,9],differenti:5,digaonaloper:5,dimens:[0,1,4,5,6,7,9],dimension:[5,9],dimension_label:[1,5,7],dir:5,direct:[1,4,5,6,9],direct_method:6,direct_onli:5,direction0:9,direction1:9,directli:[1,4,5,7],directori:[0,4,9],discard:5,disclaim:9,discord:2,disk:4,displai:[2,3],distanc:[1,3,5,9],distribut:[0,5,9],divid:[0,1,5,7],divis:[1,5,7],doc:[0,4,5,7],docs_environ:0,docstr:2,document:[6,9],doe:[0,1,5,6,7,9],doi:[2,5,7],domain:[5,8,9],domain_geometri:5,domain_init:5,domin:5,done:[1,5],dot:[1,5],dot_test:5,doubl:7,down:9,download:5,downsampl:7,draw:5,drawn:5,dset_path:4,dtype:[1,4,5,6,9],dual:5,dualiti:5,due:[5,7],dure:[0,1,5],dynam:[2,5,9],each:[0,1,4,5,7,9],earli:5,earlier:6,eas:5,easiest:0,easili:5,edg:[1,7],edoardo:5,edu:5,effect:5,effici:5,effort:7,ehrhardt:5,eigenvalu:5,eigenvector:5,either:[0,3,5,7,9],element:[1,4,5,7],elev:9,elif:0,els:[0,6],email:0,embed:0,emiss:5,emit:3,emploi:2,empti:1,enabl:[2,7],enclos:0,end:[0,3,4,5,7],end_valu:7,endors:9,enforc:[2,5],engin:[1,5],enough:2,ensur:7,entri:[4,5],env:0,environ:0,environment_nam:0,epsilon:5,eqnarrai:5,equal:[1,5,6,9],equival:[3,4,5],erfcinv:7,erni:5,error:[1,7,9],essenti:0,esser:5,estim:7,estimate_normalised_error:7,eta:[5,6],euclid:5,euclidean:[1,5],eval:4,evalu:[5,6,9],evangelo:5,evelina:5,even:[1,5,9],event:[5,9],everi:[5,7,9],everyth:4,evolv:0,exact:[4,5],exactli:5,exampl:[1,4,5,6,7,8,9],except:0,excess:0,exclus:[7,9],execut:5,exemplari:9,exist:5,exp:1,expect:[1,5,7],expens:5,explicit:5,explicitli:9,expon:7,expos:9,express:[0,1,3,5,9],ext:5,extend:[5,7,9],extens:4,extract:[4,9],extrapol:7,f_1:5,f_i:5,f_n:5,fact:[1,4,5],factor:[3,4,7,9],fail:[1,5],fals:[0,1,4,5,7,8,9],fan:2,fanbeam:2,fardel:5,fashion:5,fast:[5,6],faster:5,favour:0,fbp:[0,1,2,3,7],fdk:[2,3,6,7],fdk_cuda:6,feldkamp:8,fft:8,fft_order:8,fgp:[5,6],fgp_dtv:6,fgp_tv:6,fidel:[3,5],field:[0,3,7],figsiz:9,figur:9,file:[0,2,3,5],file_nam:4,filenam:[4,9],fill:[0,1,4,5,6,7,8],filter:[3,6,7,8],filter_inplac:0,find:[0,5,7],fine:7,finit:5,finitedifferenceoper:5,first:[3,4,5,6,7,9],firstli:[2,5],fista:2,fit:[1,5,7,9],fix:5,fix_rang:9,flag:[5,7],flat:7,flat_field:7,flatten:[5,7],flip:4,fliplr:4,float32:[1,4,5,6],float64:1,fname:4,folder:[0,4],follow:[0,1,4,5,7,8,9],fontsiz:9,forc:1,fork:7,form:[3,5,8,9],format:[0,3],format_spec:5,formatt:5,formul:[2,5],formula:5,forth:5,forward:[5,6],forward_project:6,found:[2,5,9],fourier:[7,8],frac:[3,5,6],frame:1,framework:[2,4],frequenc:8,frequency_cutoff:8,from:[1,2,3,4,5,6,8],from_funct:5,fromfil:4,full:[0,3,4,8],fulli:[0,4],fundament:5,further:[0,2,5,8],futher:[6,8],futur:5,gamma:[5,6],gamma_fconj:5,gamma_g:5,gantri:3,gap:[5,7],gaussian:9,gemma:5,gener:[0,1,2,4,5,6,9],generalis:[5,6],genericlli:5,geometr:6,geometri:[0,2,4,5,6,7],geometry_bin:7,geometry_sl:7,geq1:5,geq2:5,get:[4,5,8,9],get_as_list:5,get_data_axes_ord:1,get_data_offset:4,get_data_scal:4,get_dataset_metadata:4,get_dimension_axi:1,get_filter_arrai:8,get_geometri:4,get_imagedata:6,get_imagegeometri:[0,1,6],get_input:1,get_item:[1,5],get_last_loss:5,get_last_object:5,get_metadata:4,get_norms_as_list:5,get_ouput:[6,7],get_output:[1,5,6,7],get_output_shap:5,get_roi:4,get_sampl:5,get_slic:[1,9],getattr:5,getlogg:7,git:[0,2],github:[0,2,5,6,9],give:[1,3,5,7],given:5,global:[5,9],gm_domain:5,gm_rang:5,goal:3,good:9,govern:0,gpu:6,gradient:[5,6],gradientoper:2,grai:9,greater:[1,5,8],greatli:3,grid:9,ground:9,ground_truth:9,group:[4,5],guarante:5,guess:5,guid:[2,5],guidelin:2,guler:5,haar:7,hadamard:5,half:[5,7],ham:8,handl:[1,2,3,8],hann:8,happen:1,hard:7,hardwar:8,has:[0,1,3,4,5,6,7],hash:5,have:[0,1,3,4,5,7,8],hdf5:2,hdf5_util:4,hdl:8,height:9,held:1,help:[0,5,6],helper:5,henc:5,here:[0,5],hereof:5,herman:5,herman_mey:5,high:[2,5],higher:[8,9],highli:[5,8],hold:[1,5,7],home:[1,4,5,6,7,8,9],horizont:[1,4,7],horizontal_i:[1,5,7,9],horizontal_x:[1,5,7,9],hotdog:9,how:5,howev:[4,5,9],html:[0,4,5,7,9],http:[0,2,4,5,6,7,8,9],hybrid:5,i_0:4,ideal:7,ident:5,identifi:[0,7],identityoper:5,ieee:5,ignor:[5,6,7],illustr:3,imag:[0,2,3,4,5,6,7,8],image_geometri:[0,4,6,8,9],image_sharp:7,imagedata:[0,2,3,5,6,7,8,9],imagegeometri:[2,3,4,5,6,7,8,9],implement:[2,5],impli:[0,9],impos:[3,5],imraj:5,in_plac:1,inch:9,incid:[3,7],incident:9,includ:[1,5,7,9],inclus:7,incorpar:6,incorrect:7,increas:[5,7,8],increment:5,independ:[1,4,5],index:[1,4,5,7],indic:[1,2,4,7,8],indicatorbox:5,indirect:9,individu:5,industri:5,inequ:5,inexact:5,inf:[5,7],infin:5,infinit:5,influenc:3,info:[4,5,6,7],inform:[0,1,2,4,5,6,7,9],infrastructur:5,infti:5,ingredi:5,inherit:[1,5],ini:4,inifnam:4,initi:[4,5,6,7,9],initial_angl:1,initial_bin:7,initialis:[1,4,5,7],inlin:5,inner:[1,5],innov:0,inpaintingand:5,inplac:8,input:[0,1,2,5,6,7,8,9],insid:[1,5],instal:[0,5,6],instanc:[0,1,4,5],instanti:[1,5],instead:[0,5,7,9],instruct:0,instrument:[3,7],integ:[5,6,7,9],intend:5,intens:7,interact:[2,5],interest:[1,7],intermedi:9,intern:[1,4],interpoalt:7,interpol:[6,7],interpret:[5,7,8],interrupt:9,intersect:6,interv:[5,9],introduc:5,introduct:2,introductori:5,intuit:9,invers:5,invok:5,iop:6,iopscienc:6,ipywidget:9,irrespect:5,is_compat:[1,5],is_fortran:4,is_linear:5,is_provably_converg:5,is_virtu:4,islic:2,isotrop:[5,6],issubclass:5,ista:2,iter:[3,5,6,9],iteration_numb:5,its:[0,5,9],itself:[0,5],jakob:5,januari:5,join:2,journal:5,json:4,julian:5,jun:5,jupyt:9,just:1,k_i:5,kak:5,keep:[5,9],kei:[0,1,4,7],kereta:5,keyward:5,keyword:[1,5],kind:0,kinemat:7,kingdom:0,kl_div:5,kmax:5,knowledg:[3,5],known:5,kress:8,kullback:5,kullbackleibl:2,kwarg:[0,1,5,6,7,9],l11:2,l1norm:5,l21:2,l2norm_:5,l2normsquar:5,lab:3,label:[1,4,5,9],ladmm:2,lagrangian:5,lak:[6,8],lambert:7,langl:[5,6],languag:[0,6],larg:[1,5],larger:5,largest:5,last:[5,7],law:[0,7],layout:4,lead:[4,7],least:[1,2,3],leastsquar:5,lectur:5,left:[1,4,5,9],leftrightarrow:[5,6],legend:9,leibler:5,len:5,length:[1,5,8,9],leq1:5,leq:5,ler:5,less:5,let:5,level:[2,4,5,7,9],liabil:9,liabl:9,librari:[0,1,2,3,5],licens:0,light:2,like:[3,4,5],limit:[0,5,6,9],line:[4,9],line_colour:9,line_styl:9,linear:[5,7],linear_ramp:7,linearoper:5,linestyl:9,link:[0,2,5],link_islic:2,linspac:6,lionheart:5,lipschitz:5,lipshitz:5,list:[1,2,4,5,8,9],lmax:5,load:[4,9],load_data:4,load_project:4,loader:3,local:[2,9],local_var:9,localvar:9,locat:[1,7],log0:5,log10:5,log:[0,1,5,7,8],log_fil:5,logan:8,logarithm:7,look:4,loop:[4,5,7],loss:[5,7,9],lossi:4,low:5,low_val:9,lower:[5,6,7,9],lvert:5,machin:3,mad:7,made:5,mae:9,magnif:3,magnitud:5,mai:[0,1,2,5,7,8,9],mail:2,main:[2,3,5],mainli:3,maintain:9,make:[0,3,5],malcolm:5,manchest:0,mani:5,manipul:[2,3],manual:[4,9],map:[5,9],marc:5,markiewicz:5,martin:5,mask:[1,2,5,9],masker:7,maskgener:7,maskoper:5,master:[5,9],match:[1,5,6],materi:9,math:[1,5],mathbb:5,mathcal:5,mathemat:[2,5],mathrm:[3,5,6],matplotlib:9,matric:5,matrix:[3,5,9],matrixoper:5,matthia:5,max:[1,5,6,9],max_:5,max_iter:[5,6],max_iteration_stop_criterion:5,max_quantil:7,max_val:7,maximis:7,maximum:[1,5,6,9],mayer:5,mbox:[5,6],mean:[1,5,7,9],meant:0,measur:[3,5,7,8],med:5,media:5,median:7,medicin:5,medium:5,member:0,memori:[1,5,8],merchant:9,messag:7,met:[5,9],meta:1,metadata:[2,4],method:[1,2,3,4,5,6,7,8],metric:2,meyer:5,mic:5,midlin:7,might:5,min:[1,5,9],min_:5,min_intens:7,min_quantil:7,min_val:7,min_x:5,mingqiang:5,minim:[4,5],minimis:5,minimum:[1,5,6,9],minmax:9,mirror:7,misalign:7,miss:7,mix:2,mixedl11norm:5,mixedl21norm:5,mkdir:0,mo25:5,mo25_ch6:5,mode:[1,4,5,7,9],model:6,modern:8,modif:9,modifi:[1,8],modul:[3,5,6,7,8],modulu:5,moment:5,monitor:5,mop:5,mop_norm:5,more:[1,3,4,5,7,8,9],moreau:5,most:[1,5],mri:5,mse:9,multi:[2,4,5,7,9],multichannel:[2,5,6],multicontrast:5,multipl:[0,1,4,5,6,7,9],multiplc:5,multipli:[1,5,7],multiprocess:5,must:[0,1,4,5,7,8,9],mx1:5,my_data:4,my_sampling_funct:5,nabla:5,name:[0,1,4,5,7,9],nan:[5,7],nbyte:4,ndarrai:[1,4,5,7,8,9],ndim:[1,4,6],nearest:7,necessari:[0,1,4],need:[0,4,5,7,9],neg:[4,5,6,7,8,9],neglig:9,neither:9,nest:[1,5,9],nesterov:5,net:8,neumann:5,neutron:7,never:5,new_ord:1,newlin:5,next:[1,5,7,9],nexu:[2,3],nexusdataread:4,nexusdatawrit:4,nice:5,nikon:[2,3],nikondataread:4,nois:[5,9],noisy_data:5,non:[0,2,5,6],none:[0,1,4,5,6,7,8,9],nonneg:6,nonzero:9,nor:9,norm2sq:5,norm:[1,2,6],normal:[1,5],normalis:[2,4,5],notat:5,note:[4,5,6,7,8,9],notebook:3,noth:5,notic:[4,5,9],notimpl:5,notimplementederror:5,nov:5,now:[3,5,6],nss:5,num_batch:1,num_channel:1,num_chunk:0,num_col:9,num_indic:5,num_model:6,num_pixel:1,num_pixels_h:1,num_pixels_v:1,num_sampl:5,num_thread:[1,5],numba:5,number:[1,2,3,4,5,6,7,9],number_of_dimens:1,numer:1,numpi:[1,4,5,7,8,9],numpy_vers:0,numpydoc:0,nx1:5,nxs:4,object:[1,2,3,4,5,7],objective_funct:5,obtain:[0,4],occur:9,off:[5,8],offset:[0,1,4,6,7,8],often:0,omega:5,onc:5,one:[1,2,3,5,7,9],ones:[4,5],onli:[0,1,4,5,6,7,8,9],onto:[3,5,7],op0:5,op1:5,op2:5,oper:[0,1,2,3,7,9],operator1:5,operator2:5,operatorcompositionfunct:5,optim:[2,5],optimis:[2,3,6,8],option:[0,1,4,5,6,7,8,9],orbit:8,order:[1,4,5,8,9],ordin:4,org:[0,2,4,5,6,7,9],orient:[0,2,5],origin:[0,1,4,5,9],original_data:4,osman:5,other:[1,2,5,7,9],otherwis:[1,5,9],otim:5,our:[1,2,3,5],out:[0,1,4,5,6,7,8,9],outcom:5,outer:9,outlier:7,output:[0,1,2,4,5,7,8,9],outsid:[1,7,8,9],over:[1,5,7],overrid:5,overridden:5,overset:5,own:0,owner:0,p_i:5,pack:4,packag:[0,2,5],pad:7,pad_valu:7,pad_width:7,padder:2,page:[2,4],pair:[5,9],panel:[0,1,7],paper:2,papoutselli:[2,5],parallel2d:2,parallel3d:2,parallel:[1,2,6,7,9],param:[1,5,9],paramet:[0,1,3,4,5,6,7,8,9],parent:[1,5],pars:4,part:[2,5,6],partial_:5,partial_i:5,partial_x:5,particular:[5,9],partit:1,pasca:5,pass:[0,1,5,6,7,8,9],path:[4,9],pattern:5,pawel:5,pbar:0,pdf:5,pdf_1:5,pdhg:2,pdhg_vs_spdhg:5,peak:9,penalis:5,pepper:9,per:[5,9],percent:9,percentag:1,perform:[1,5,7],period:5,permiss:[0,9],permit:9,permut:1,pet:5,peter:5,phantom:6,phil:2,philip:5,philosoph:5,photon:[7,8],physic:5,pickl:5,pixel:[1,3,4,6,7,8,9],pixel_num_v:0,pixel_s:1,pixel_size_h:1,pixel_size_v:1,pixelwis:9,pjm:5,place:[1,3,8],placehold:[1,5],plantagi:8,play_interv:9,pleas:[0,1,2,3,6,7],plot:9,plugin:[2,3,7],png:9,pock:5,point:[1,3,5,9],pointer:1,poisson:[5,9],poissonloglikelihoodwithlinearmodelformean:5,poorli:9,popul:7,posit:[0,1,5,6,7,8,9],positron:5,possibl:[1,5,9],power:[1,2,5,8,9],powermethod:5,practic:[5,7],pre:[2,3,5,8],precalcul:5,preced:[1,5],precondit:5,predefin:8,prefix:4,prepar:8,prepend:5,present:[1,5,9],preserv:9,preval:9,previou:[5,6,7],primal:5,prime:5,principl:5,print:[0,4,5,7],print_interv:5,print_metadata:4,prior:[3,5,9],prob:5,prob_weight:5,probabl:5,problem:[2,3,5,6,9],problem_:[5,6],process:[0,1,3,5,6,7,8],processor:[1,2,3,6],procur:9,produc:[5,9],product:[1,5,9],profil:7,profit:9,progress:7,proj:5,proj_filt:0,project:[2,3,4,5,7,8],projecteuclid:5,projection_index:7,projectionoper:6,projector:[3,6,8],promot:9,prompt:5,proper:9,properti:[1,2,5],proport:9,protect:0,protocol:5,prototyp:[2,5],provabl:5,provid:[0,1,2,3,4,5,6,7,8,9],prox:[5,6],prox_:5,proxim:[5,6],proximal_conjug:5,pseudo:9,psnr:9,purpos:[5,9],pydata:0,pyplot:9,python2:[1,5],python3:0,python:[2,5],python_vers:0,pywt:7,qeq0:6,quad:5,quadrat:[5,7],qualiti:[2,3],quality_measur:9,quantil:7,quarter:7,question:5,r_1:3,r_2:3,rad:8,radia:2,radian:1,radiat:3,radiu:1,rai:[1,3,6],rainbow:9,rais:[0,1,5],ral:5,ram:[6,8],ramp:7,random:[1,5,9],random_int:1,random_nois:9,random_permut:1,random_with_replac:5,random_without_replac:5,randomli:5,randomsampl:5,randomwithoutreplac:5,rang:[0,5,6,7,8,9],range_geometri:5,range_init:5,rangl:[5,6],rapid:[2,5],rare:9,rasch:5,rate:5,rather:[5,7],ratio:[6,9],ration:9,raw:2,rawfilewrit:4,ray_direct:1,reach:[3,5,6],read:[2,7],read_arrai:4,read_as_acquisitiondata:4,read_as_imagedata:4,read_as_origin:4,read_data:4,read_dtyp:4,read_resc:4,read_scale_offset:4,read_shap:4,read_to:4,reader:[2,3],real:[1,2,3,5],recal:5,receiv:5,recognis:[3,5],recommend:[5,7,8],recon:[0,2,3],reconstruct:[0,1,2,3,4,5,6,7],reconstructor:[0,2,3,6],record:5,recov:5,rect:8,recurs:[0,4],redistribut:9,reduc:[1,3,5,8,9],reduct:1,refer:[0,1,2,3,4,6,7,8,9],referenc:[0,1,6,7,8],reflect:[5,7],region:7,regular:5,regularis:[2,3,5],rel:[5,6,7],relat:[1,5],relax:5,relev:4,remain:7,remaind:0,remov:2,reorder:1,repeat:5,replac:[0,5,9],repo:0,repositori:[2,3],repositoryy:5,repr:5,repres:[1,4,5,7,9],reproduc:[2,9],request:[0,1,4,7,8,9],requir:[0,1,5,6,7,8],rescal:[4,6],rescaled_data:4,research:0,reserv:9,reset:8,reshap:[4,5],resid:4,resolut:[1,7],resolution_chart:9,resort:1,respect:[1,3,4,5,7,9],rest:5,restart:5,restor:5,resul:[1,5],result:[1,2,3,4,5,6,7,8,9],ret:0,retain:9,return_al:5,revers:[1,5],rewritten:5,rgensen:5,right:[1,4,5,9],rightarrow:5,ring:2,ringremov:7,rof:5,roi:[4,7],roll:7,root:[4,5],rosenbrock:5,rotat:[1,2,3,6],rotation_axis_direct:1,rotation_axis_posit:1,round:9,routin:[5,8],row:[0,1,3,4,5],row_wise_compat:5,royal:5,royalsocietypublish:5,rsta:[2,5],rtsd:5,rule:5,run:[0,1,5,6,7,8],rvert_:5,ryan:5,s10107:5,s10589:5,s10851:5,saddl:5,sai:5,salt:9,salt_vs_pepp:9,same:[0,1,4,5,6,7,9],sampl:[3,5],sampler:2,samplerrandom:5,sampling_typ:5,sapyb:[1,5],satisfi:5,save:[3,4,5,9],savefig:9,scalar:[1,5,6,9],scale:[2,4,5,7,9],scaledfunct:5,scaledoper:5,scaleoffset:4,scan:[3,7],scatter:[3,5],schemat:9,schonlieb:5,scienc:5,scikit:9,scikit_random_nois:9,scipi:5,screen:5,script:0,search:[7,9],search_rang:7,sec:5,second:[3,5,7,9],secondli:2,section:[4,5],see:[0,1,5,6,7,9],seed:[1,5,9],select:[3,4,5,8,9],selector:9,self:[0,1,5,6,8],sensibl:4,separ:[0,5,9],sequenc:5,sequenti:[1,5,9],serial:5,serv:0,server:0,servic:9,set:[0,1,2,4,5,6,7,8],set_:0,set_angl:[1,6],set_channel:[1,6],set_fft_ord:8,set_filt:8,set_filter_inplac:8,set_gamma_fconj:5,set_gamma_g:5,set_image_geometri:8,set_input:[1,6,7,8],set_label:1,set_norm:5,set_num_thread:5,set_panel:[1,6],set_relaxation_paramet:5,set_split_process:[0,8],set_step_s:5,set_suppress_evalu:5,set_up:[4,5],setattr:5,setlevel:7,setter:2,sever:[5,7],sgn:5,shall:9,shape:[0,1,4,5,9],share:5,sharp:7,shepp:8,shift:5,shinkoper:5,shortcut:4,shorter:5,should:[0,1,4,5,6,7,8,9],should_stop:5,show1d:2,show2d:2,show:9,show_geometri:2,shown:9,shrinkag:5,siam:5,siddon:6,side:7,sigma:[5,7],sigma_1:5,sigma_:5,sigma_iw_i:5,sigma_iw_ix_i:5,sign:[1,5,9],signal:9,signatur:[5,6],signific:3,simpl:[0,2,6,8],simple_phantom_2d:9,simpli:3,simplifi:5,simul:[2,3,5],simulated_cone_beam_data:[8,9],simulated_parallel_beam_data:[8,9],simulated_sphere_volum:9,simultan:5,singh:5,singl:[1,3,4,5,7,8,9],singular:5,sinogram:1,sirf:5,sirt:2,size:[0,1,4,5,6,7,9],skimag:9,skip:4,slanei:5,slice:[1,2,3,4,7,8],slice_index:7,slice_list:9,slice_metadata:4,slice_numb:9,slicer:2,slices_per_chunk:[0,8],slider:9,slight:7,small:[0,5,6,9],smooth:[2,6],smoothmixedl21norm:5,soc:2,societi:5,softwar:[0,5,9],softx:6,sol:[5,6],solut:[3,5,6],solv:[2,3,5,9],some:[5,7],some_data:1,someth:4,soon:5,sop:5,sort:1,sourc:[1,2,3,4,5,6,7,8],source_posit:1,source_sel:4,space:[5,6,7],spacechannel:5,spars:5,sparsefinitedifferenceoper:5,spatial:[1,5,7],spdhg:2,special:[5,7,9],special_valu:7,specif:[0,4,5,9],specifi:[1,4,5,7,9],speckl:9,spectral:[2,3,5,7],sphere:9,sphinx:0,split:[5,8],springer:[5,8],sqrt:[1,5,6,7],squar:[1,2,3,9],squared_norm:1,stabl:[4,7,9],stack:[4,7],stackexchang:5,stage:3,stagger:[1,5],standard:[1,3,4,7,8,9],stanford:5,start:[0,4,5,7,9],statement:7,stationari:3,statist:8,statu:5,std:7,step:[0,3,4,5,6,7],step_siz:5,stephen:5,sting:1,stochast:5,stop:[5,6,7],store:[0,1,5],store_output:1,str:[1,4,5,6,7,9],strategi:5,strength:7,strict:9,strictli:5,stride:[1,5],string:[1,4,5,6,7,8,9],stripe:7,strong_convexity_const:[5,6],strongli:[5,6],structur:5,style:[0,7],sub:6,subclass:[1,4,5],subject:5,submodul:0,subplot:9,subproblem:5,subsequ:5,subset:5,substitut:9,subtract:[1,5],suffici:3,suit:3,suitabl:[0,1,7],sum:[1,5],sum_:5,sumfunct:5,sumoper:5,sumscalarfunct:5,sup:[5,6],support:[5,7],suppress:[0,1,5,6,7,8,9],suppress_evalu:5,sure:[0,5],swap:5,symmetr:7,symmetris:5,symmetrisedgradientoper:5,sync:5,synchrotron:3,synchrotron_parallel_beam_data:9,syntax:0,system:[1,2,3,5],system_descript:0,tabul:5,take:[1,4,5,7,8,9],target:[0,7],task:6,tau:[5,6],tau_:5,team:9,teboul:5,techniqu:[3,5],tempor:[5,6],temporari:8,temporarili:9,term:[3,5,6],test:[0,2,3,5],testdata:9,text:[0,4,5],textbf:5,tgv:6,than:[4,5,6,7,8],thank:5,thei:[0,1,5,7,9],them:[4,5,9],theme:0,theoret:7,theori:9,therefor:[1,5,6],theta:5,theta_:5,thi:[0,1,3,4,5,6,7,8,9],thieleman:5,thoma:5,those:1,thread:[1,5],three:[3,5],threshold:[5,7],threshold_factor:7,threshold_valu:7,through:[4,9],thu:5,tiff:[2,9],tiffstackread:4,tiffwrit:4,tigr:[1,2,3,7,8],tikhonov:[3,5],tild:[3,5],time:[0,3,5,8,9],tip:5,titl:9,tmp_nexu:4,tnv:6,tofil:4,togeth:[4,7],toggl:5,toler:[5,6,7],tomograph:[1,2,5],tomographi:[2,5,8],tomographicimag:[0,2],tomophantom:[2,3],toni:5,too:8,tool:3,toolbox:[6,8],toolkit:[3,6],top:[1,9],tort:9,tot_slic:0,total:[0,2],totalvari:[5,6],tqdm:0,trade:5,trajectori:[3,6],tran:[2,5],transact:5,transform:8,translat:5,translatefunct:5,transmiss:[2,3],transmissionabsorptionconvert:7,transpos:[4,5],treat:5,trigger:5,trivial:2,truedivis:5,truth:9,tune:[7,8],tupl:[1,4,5,7,9],turner:5,two:[1,5,7,8,9],twx:5,txm:4,txrm:4,type:[0,1,3,4,5,6,7,8,9],typic:[3,5],uint16:4,uint8:4,unari:[1,5],unary_oper:[1,5],unbin:7,unchang:5,uncompress:4,under:[0,5],underbrac:5,underscor:0,underset:[3,5,6],understand:0,unexpect:9,uniform:[1,5,9],uniformli:5,uniqu:[1,9],unit16:4,unit:[0,1,5],univers:0,unknown:[3,5],unless:[0,7],unmask:7,unpack:4,unreli:7,unsign:[4,9],until:5,updat:[0,5,7,8],update_object:5,update_objective_interv:5,update_step_s:5,upper:[5,7,9],url:5,usag:[5,6,7],use:[0,1,2,3,5,6,7,8,9],used:[0,1,2,3,4,5,6,7,8,9],useful:[1,2,5],user:[0,1,3,5,7,8],uses:[5,6,7,9],using:[0,1,3,4,5,6,7,8,9],util:[2,3,8],v_1:5,v_2:5,vai:5,valid:9,valu:[1,4,5,6,7,8,9],valueerror:[0,5],vararg:5,variabl:5,varianc:9,variat:2,variou:9,vaue:7,vector:[1,5,7],vectordata:2,verbos:[0,5,8],verbose_output:5,veri:5,versatil:[2,5],version:[0,5,6],vertic:[1,4,7],via:5,view:[0,1,3,9],view_dist:9,vision:5,visualis:2,vmatrix:[3,5],volum:[0,1,2,4,5,6,7,8],voxel:[5,6],voxel_num_i:1,voxel_num_x:1,voxel_num_z:1,voxel_size_i:1,voxel_size_x:[1,6],voxel_size_z:1,w_i:5,wai:[0,1,5,9],want:[1,5],warm:5,warm_start:5,warn:7,warr:5,warranti:[0,4,9],wavelet:7,weak:5,web:5,websit:2,weight:[5,6],weightedl1norm:5,weightedl2normsquar:5,well:[2,3,5],were:7,wether:5,what:[0,4,5],when:[0,3,4,5,6,9],where:[1,3,5,6,7,9],wherea:5,whether:[1,4,5,6,9],which:[1,3,4,5,7,9],whichev:[1,8],white:4,white_level:7,whole:1,widget:9,width:[7,8,9],william:5,window:7,wise:[1,5],wish:5,wither:5,within:0,without:[0,4,5,7,9],wname:7,won:5,word:0,work:[0,1,3,4,5],would:[4,5],wrap:[5,7],wright:5,write:[0,2,3,5],writer:[2,3],written:[3,4,5,6,9],wrt:5,www:0,x_0:5,x_1:5,x_axis_label:9,x_i:5,x_k:5,x_n:5,xcorrel:7,xiaoqun:5,xin:5,xshape:5,xtekct:4,y_axis_label:9,year:0,yet:5,yield:[5,8],yml:0,you:[0,2,4,5,7],your:[0,5,6,7,8],yurii:5,yyyi:0,zeiss:2,zeissdataread:4,zeljko:5,zero:[1,5,7],zerofunct:5,zerooper:5,zhang:5,zhu:5},titles:["Developers\u2019 Guide","Framework","Welcome to CIL\u2019s documentation!","Introduction","Read/ write AcquisitionData and ImageData","Optimisation framework","CIL Plugins","Processors","Recon","Utilities"],titleterms:{"class":5,"function":[5,6],"new":0,Use:1,absorpt:7,acquisitiondata:[1,4],acquisitiongeometri:1,algorithm:5,analyt:8,astra:6,base:5,beam:[3,8],binner:7,block:[3,5],blockdatacontain:[1,5],blockgeometri:1,box:5,build:0,ccpi:6,centr:7,cgl:5,channel:3,cil:[0,2,6],cite:2,composit:5,cone2d:1,cone3d:1,cone:[3,8],configur:1,contact:2,contain:1,content:2,contribut:0,convent:0,convert:7,corrector:7,creator:0,data:[1,3,7,9],datacontain:1,dataord:1,dataprocessor:1,dataset:9,demo:2,develop:0,diamond:9,displai:9,docstr:0,document:[0,2],exampl:[0,2],fan:3,fanbeam:1,fbp:[6,8],fdk:8,file:4,fista:5,framework:[1,3,5],from:[0,7,9],gener:7,geometri:[1,3,8,9],gradientoper:5,guid:0,guidelin:0,hdf5:4,imag:9,imagedata:[1,4],imagegeometri:1,index:[2,9],indic:5,interact:9,introduct:3,islic:9,ista:5,kullbackleibl:5,l11:5,l21:5,ladmm:5,least:5,light:9,link:9,link_islic:9,local:0,manipul:7,mask:7,method:0,metric:9,mix:5,multi:3,nexu:4,nikon:4,norm:5,normalis:7,object:[0,9],oper:[5,6],optimis:5,other:[0,6],padder:7,parallel2d:1,parallel3d:1,parallel:[3,8],pdhg:5,plugin:6,pre:7,processor:7,project:6,properti:0,qualiti:9,raw:4,read:4,reader:4,recon:8,reconstruct:8,reconstructor:8,refer:5,regularis:6,remov:7,render:0,ring:7,rotat:7,sampler:5,set:9,setter:0,show1d:9,show2d:9,show_geometri:9,simpl:5,simul:9,sirt:5,slice:9,slicer:7,smooth:5,softwar:2,sourc:[0,9],spdhg:5,squar:5,system:9,test:9,thi:2,tiff:4,tigr:6,todo:5,tomophantom:6,total:[5,6],transmiss:7,trivial:5,util:[4,5,9],variat:[5,6],vectordata:1,visualis:9,volum:9,welcom:2,work:2,write:4,writer:4,zeiss:4}}) \ No newline at end of file +Search.setIndex({docnames:["developer_guide","framework","index","introduction","io","optimisation","plugins","processors","recon","utilities"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":5,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,"sphinxcontrib.bibtex":9,sphinx:56},filenames:["developer_guide.rst","framework.rst","index.rst","introduction.rst","io.rst","optimisation.rst","plugins.rst","processors.rst","recon.rst","utilities.rst"],objects:{"cil.framework":[[1,0,1,"","AcquisitionData"],[1,0,1,"","AcquisitionGeometry"],[5,0,1,"","BlockDataContainer"],[1,0,1,"","BlockGeometry"],[1,0,1,"","DataContainer"],[1,0,1,"","DataOrder"],[1,0,1,"","DataProcessor"],[1,0,1,"","ImageData"],[1,0,1,"","ImageGeometry"],[1,0,1,"","Processor"],[1,0,1,"","VectorData"]],"cil.framework.AcquisitionData":[[1,1,1,"","as_array"],[1,1,1,"","clone"],[1,1,1,"","copy"],[1,1,1,"","dot"],[1,2,1,"","dtype"],[1,1,1,"","exp"],[1,1,1,"","fill"],[1,1,1,"","get_data_axes_order"],[1,1,1,"","get_dimension_axis"],[1,1,1,"","get_slice"],[1,1,1,"","log"],[1,1,1,"","max"],[1,1,1,"","mean"],[1,1,1,"","min"],[1,2,1,"","ndim"],[1,1,1,"","norm"],[1,2,1,"","number_of_dimensions"],[1,1,1,"","partition"],[1,1,1,"","reorder"],[1,1,1,"","sapyb"],[1,2,1,"","shape"],[1,2,1,"","size"],[1,1,1,"","squared_norm"],[1,1,1,"","sum"]],"cil.framework.AcquisitionGeometry":[[1,1,1,"","allocate"],[1,1,1,"","create_Cone2D"],[1,1,1,"","create_Cone3D"],[1,1,1,"","create_Parallel2D"],[1,1,1,"","create_Parallel3D"],[1,1,1,"","get_ImageGeometry"],[1,1,1,"","get_slice"],[1,1,1,"","set_angles"],[1,1,1,"","set_channels"],[1,1,1,"","set_labels"],[1,1,1,"","set_panel"]],"cil.framework.BlockDataContainer":[[5,1,1,"","__iadd__"],[5,1,1,"","__idiv__"],[5,1,1,"","__imul__"],[5,1,1,"","__isub__"],[5,1,1,"","__iter__"],[5,1,1,"","__itruediv__"],[5,1,1,"","__neg__"],[5,1,1,"","__radd__"],[5,1,1,"","__rdiv__"],[5,1,1,"","__rmul__"],[5,1,1,"","__rpow__"],[5,1,1,"","__rsub__"],[5,1,1,"","__rtruediv__"],[5,3,1,"","__weakref__"],[5,1,1,"","add"],[5,1,1,"","axpby"],[5,1,1,"","binary_operations"],[5,1,1,"","copy"],[5,1,1,"","divide"],[5,1,1,"","is_compatible"],[5,1,1,"","maximum"],[5,1,1,"","minimum"],[5,1,1,"","multiply"],[5,1,1,"","next"],[5,1,1,"","power"],[5,1,1,"","sapyb"],[5,1,1,"","subtract"],[5,1,1,"","unary_operations"]],"cil.framework.BlockGeometry":[[1,1,1,"","allocate"],[1,1,1,"","get_item"]],"cil.framework.DataContainer":[[1,1,1,"","as_array"],[1,1,1,"","clone"],[1,1,1,"","copy"],[1,1,1,"","dot"],[1,2,1,"","dtype"],[1,1,1,"","exp"],[1,1,1,"","fill"],[1,1,1,"","get_data_axes_order"],[1,1,1,"","get_dimension_axis"],[1,1,1,"","get_slice"],[1,1,1,"","log"],[1,1,1,"","max"],[1,1,1,"","mean"],[1,1,1,"","min"],[1,2,1,"","ndim"],[1,1,1,"","norm"],[1,2,1,"","number_of_dimensions"],[1,1,1,"","reorder"],[1,1,1,"","sapyb"],[1,2,1,"","shape"],[1,2,1,"","size"],[1,1,1,"","squared_norm"],[1,1,1,"","sum"]],"cil.framework.DataProcessor":[[1,1,1,"","check_input"],[1,1,1,"","get_input"],[1,1,1,"","get_output"],[1,1,1,"","set_input"]],"cil.framework.ImageData":[[1,1,1,"","apply_circular_mask"],[1,1,1,"","as_array"],[1,1,1,"","clone"],[1,1,1,"","copy"],[1,1,1,"","dot"],[1,2,1,"","dtype"],[1,1,1,"","exp"],[1,1,1,"","fill"],[1,1,1,"","get_data_axes_order"],[1,1,1,"","get_dimension_axis"],[1,1,1,"","get_slice"],[1,1,1,"","log"],[1,1,1,"","max"],[1,1,1,"","mean"],[1,1,1,"","min"],[1,2,1,"","ndim"],[1,1,1,"","norm"],[1,2,1,"","number_of_dimensions"],[1,1,1,"","reorder"],[1,1,1,"","sapyb"],[1,2,1,"","shape"],[1,2,1,"","size"],[1,1,1,"","squared_norm"],[1,1,1,"","sum"]],"cil.framework.ImageGeometry":[[1,1,1,"","allocate"],[1,1,1,"","clone"],[1,1,1,"","copy"],[1,1,1,"","get_slice"]],"cil.framework.Processor":[[1,1,1,"","check_input"],[1,1,1,"","get_input"],[1,1,1,"","get_output"],[1,1,1,"","set_input"]],"cil.framework.VectorData":[[1,1,1,"","as_array"],[1,1,1,"","clone"],[1,1,1,"","copy"],[1,1,1,"","dot"],[1,2,1,"","dtype"],[1,1,1,"","exp"],[1,1,1,"","fill"],[1,1,1,"","get_data_axes_order"],[1,1,1,"","get_dimension_axis"],[1,1,1,"","get_slice"],[1,1,1,"","log"],[1,1,1,"","max"],[1,1,1,"","mean"],[1,1,1,"","min"],[1,2,1,"","ndim"],[1,1,1,"","norm"],[1,2,1,"","number_of_dimensions"],[1,1,1,"","reorder"],[1,1,1,"","sapyb"],[1,2,1,"","shape"],[1,2,1,"","size"],[1,1,1,"","squared_norm"],[1,1,1,"","sum"]],"cil.io":[[4,0,1,"","NEXUSDataReader"],[4,0,1,"","NEXUSDataWriter"],[4,0,1,"","NikonDataReader"],[4,0,1,"","RAWFileWriter"],[4,0,1,"","TIFFStackReader"],[4,0,1,"","TIFFWriter"],[4,0,1,"","ZEISSDataReader"]],"cil.io.NEXUSDataReader":[[4,1,1,"","get_data_offset"],[4,1,1,"","get_data_scale"],[4,1,1,"","get_geometry"],[4,1,1,"","load_data"],[4,1,1,"","read"],[4,1,1,"","read_as_original"],[4,1,1,"","set_up"]],"cil.io.NEXUSDataWriter":[[4,1,1,"","set_up"],[4,1,1,"","write"]],"cil.io.NikonDataReader":[[4,1,1,"","get_geometry"],[4,1,1,"","get_roi"],[4,1,1,"","load_projections"],[4,1,1,"","read"]],"cil.io.RAWFileWriter":[[4,1,1,"","write"]],"cil.io.TIFFStackReader":[[4,1,1,"","read"],[4,1,1,"","read_as_AcquisitionData"],[4,1,1,"","read_as_ImageData"],[4,1,1,"","read_rescaled"],[4,1,1,"","read_scale_offset"]],"cil.io.TIFFWriter":[[4,1,1,"","write"]],"cil.io.ZEISSDataReader":[[4,1,1,"","get_geometry"],[4,1,1,"","get_metadata"],[4,1,1,"","read"],[4,1,1,"","set_up"],[4,1,1,"","slice_metadata"]],"cil.io.utilities":[[4,0,1,"","HDF5_utilities"]],"cil.io.utilities.HDF5_utilities":[[4,1,1,"","get_dataset_metadata"],[4,1,1,"","print_metadata"],[4,1,1,"","read"],[4,1,1,"","read_to"]],"cil.optimisation.algorithms":[[5,0,1,"","Algorithm"],[5,0,1,"","CGLS"],[5,0,1,"","FISTA"],[5,0,1,"","GD"],[5,0,1,"","ISTA"],[5,0,1,"","LADMM"],[5,0,1,"","PDHG"],[5,0,1,"","SIRT"],[5,0,1,"","SPDHG"]],"cil.optimisation.algorithms.Algorithm":[[5,1,1,"","get_last_loss"],[5,1,1,"","get_last_objective"],[5,1,1,"","get_output"],[5,1,1,"","is_provably_convergent"],[5,2,1,"","iterations"],[5,2,1,"","loss"],[5,2,1,"","max_iteration"],[5,1,1,"","max_iteration_stop_criterion"],[5,1,1,"","next"],[5,2,1,"","objective"],[5,1,1,"","run"],[5,1,1,"","set_up"],[5,1,1,"","should_stop"],[5,1,1,"","update"],[5,1,1,"","update_objective"],[5,1,1,"","verbose_output"]],"cil.optimisation.algorithms.CGLS":[[5,1,1,"","flag"],[5,1,1,"","get_last_loss"],[5,1,1,"","get_last_objective"],[5,1,1,"","get_output"],[5,1,1,"","is_provably_convergent"],[5,2,1,"","iterations"],[5,2,1,"","loss"],[5,2,1,"","max_iteration"],[5,1,1,"","max_iteration_stop_criterion"],[5,1,1,"","next"],[5,2,1,"","objective"],[5,1,1,"","run"],[5,1,1,"","set_up"],[5,1,1,"","should_stop"],[5,1,1,"","update"],[5,1,1,"","update_objective"],[5,1,1,"","verbose_output"]],"cil.optimisation.algorithms.FISTA":[[5,1,1,"","__delattr__"],[5,1,1,"","__dir__"],[5,1,1,"","__eq__"],[5,1,1,"","__format__"],[5,1,1,"","__ge__"],[5,1,1,"","__getattribute__"],[5,1,1,"","__gt__"],[5,1,1,"","__hash__"],[5,1,1,"","__init__"],[5,1,1,"","__init_subclass__"],[5,1,1,"","__iter__"],[5,1,1,"","__le__"],[5,1,1,"","__lt__"],[5,1,1,"","__ne__"],[5,1,1,"","__new__"],[5,1,1,"","__next__"],[5,1,1,"","__reduce__"],[5,1,1,"","__reduce_ex__"],[5,1,1,"","__repr__"],[5,1,1,"","__setattr__"],[5,1,1,"","__sizeof__"],[5,1,1,"","__str__"],[5,1,1,"","__subclasshook__"],[5,3,1,"","__weakref__"],[5,1,1,"","get_last_loss"],[5,1,1,"","get_last_objective"],[5,1,1,"","get_output"],[5,1,1,"","is_provably_convergent"],[5,2,1,"","iterations"],[5,2,1,"","loss"],[5,2,1,"","max_iteration"],[5,1,1,"","max_iteration_stop_criterion"],[5,1,1,"","next"],[5,2,1,"","objective"],[5,1,1,"","run"],[5,1,1,"","set_step_size"],[5,1,1,"","set_up"],[5,1,1,"","should_stop"],[5,1,1,"","update"],[5,1,1,"","update_objective"],[5,1,1,"","verbose_output"]],"cil.optimisation.algorithms.GD":[[5,1,1,"","armijo_rule"],[5,1,1,"","get_last_loss"],[5,1,1,"","get_last_objective"],[5,1,1,"","get_output"],[5,1,1,"","is_provably_convergent"],[5,2,1,"","iterations"],[5,2,1,"","loss"],[5,2,1,"","max_iteration"],[5,1,1,"","max_iteration_stop_criterion"],[5,1,1,"","next"],[5,2,1,"","objective"],[5,1,1,"","run"],[5,1,1,"","set_up"],[5,1,1,"","should_stop"],[5,1,1,"","update"],[5,1,1,"","update_objective"],[5,1,1,"","verbose_output"]],"cil.optimisation.algorithms.ISTA":[[5,1,1,"","__delattr__"],[5,1,1,"","__dir__"],[5,1,1,"","__eq__"],[5,1,1,"","__format__"],[5,1,1,"","__ge__"],[5,1,1,"","__getattribute__"],[5,1,1,"","__gt__"],[5,1,1,"","__hash__"],[5,1,1,"","__init__"],[5,1,1,"","__init_subclass__"],[5,1,1,"","__iter__"],[5,1,1,"","__le__"],[5,1,1,"","__lt__"],[5,1,1,"","__ne__"],[5,1,1,"","__new__"],[5,1,1,"","__next__"],[5,1,1,"","__reduce__"],[5,1,1,"","__reduce_ex__"],[5,1,1,"","__repr__"],[5,1,1,"","__setattr__"],[5,1,1,"","__sizeof__"],[5,1,1,"","__str__"],[5,1,1,"","__subclasshook__"],[5,3,1,"","__weakref__"],[5,1,1,"","get_last_loss"],[5,1,1,"","get_last_objective"],[5,1,1,"","get_output"],[5,1,1,"","is_provably_convergent"],[5,2,1,"","iterations"],[5,2,1,"","loss"],[5,2,1,"","max_iteration"],[5,1,1,"","max_iteration_stop_criterion"],[5,1,1,"","next"],[5,2,1,"","objective"],[5,1,1,"","run"],[5,1,1,"","set_step_size"],[5,1,1,"","set_up"],[5,1,1,"","should_stop"],[5,1,1,"","update"],[5,1,1,"","update_objective"],[5,1,1,"","verbose_output"]],"cil.optimisation.algorithms.LADMM":[[5,1,1,"","get_last_loss"],[5,1,1,"","get_last_objective"],[5,1,1,"","get_output"],[5,1,1,"","is_provably_convergent"],[5,2,1,"","iterations"],[5,2,1,"","loss"],[5,2,1,"","max_iteration"],[5,1,1,"","max_iteration_stop_criterion"],[5,1,1,"","next"],[5,2,1,"","objective"],[5,1,1,"","run"],[5,1,1,"","set_up"],[5,1,1,"","should_stop"],[5,1,1,"","update"],[5,1,1,"","update_objective"],[5,1,1,"","verbose_output"]],"cil.optimisation.algorithms.PDHG":[[5,1,1,"","check_convergence"],[5,1,1,"","get_last_loss"],[5,1,1,"","get_last_objective"],[5,1,1,"","get_output"],[5,1,1,"","is_provably_convergent"],[5,2,1,"","iterations"],[5,2,1,"","loss"],[5,2,1,"","max_iteration"],[5,1,1,"","max_iteration_stop_criterion"],[5,1,1,"","next"],[5,2,1,"","objective"],[5,1,1,"","run"],[5,1,1,"","set_gamma_fconj"],[5,1,1,"","set_gamma_g"],[5,1,1,"","set_step_sizes"],[5,1,1,"","set_up"],[5,1,1,"","should_stop"],[5,1,1,"","update"],[5,1,1,"","update_objective"],[5,1,1,"","update_step_sizes"],[5,1,1,"","verbose_output"]],"cil.optimisation.algorithms.SIRT":[[5,1,1,"","get_last_loss"],[5,1,1,"","get_last_objective"],[5,1,1,"","get_output"],[5,1,1,"","is_provably_convergent"],[5,2,1,"","iterations"],[5,2,1,"","loss"],[5,2,1,"","max_iteration"],[5,1,1,"","max_iteration_stop_criterion"],[5,1,1,"","next"],[5,2,1,"","objective"],[5,1,1,"","run"],[5,1,1,"","set_relaxation_parameter"],[5,1,1,"","set_up"],[5,1,1,"","should_stop"],[5,1,1,"","update"],[5,1,1,"","update_objective"],[5,1,1,"","verbose_output"]],"cil.optimisation.algorithms.SPDHG":[[5,1,1,"","get_last_loss"],[5,1,1,"","get_last_objective"],[5,1,1,"","get_output"],[5,1,1,"","is_provably_convergent"],[5,2,1,"","iterations"],[5,2,1,"","loss"],[5,2,1,"","max_iteration"],[5,1,1,"","max_iteration_stop_criterion"],[5,1,1,"","next"],[5,2,1,"","objective"],[5,1,1,"","run"],[5,1,1,"","set_up"],[5,1,1,"","should_stop"],[5,1,1,"","update"],[5,1,1,"","update_objective"],[5,1,1,"","verbose_output"]],"cil.optimisation.functions":[[5,0,1,"","BlockFunction"],[5,0,1,"","ConstantFunction"],[5,0,1,"","Function"],[5,0,1,"","IndicatorBox"],[5,0,1,"","KullbackLeibler"],[5,0,1,"","L1Norm"],[5,0,1,"","L2NormSquared"],[5,0,1,"","LeastSquares"],[5,0,1,"","MixedL11Norm"],[5,0,1,"","MixedL21Norm"],[5,0,1,"","OperatorCompositionFunction"],[5,0,1,"","Rosenbrock"],[5,0,1,"","ScaledFunction"],[5,0,1,"","SmoothMixedL21Norm"],[5,0,1,"","SumFunction"],[5,0,1,"","SumScalarFunction"],[5,0,1,"","TotalVariation"],[5,0,1,"","TranslateFunction"],[5,0,1,"","WeightedL2NormSquared"],[5,0,1,"","ZeroFunction"]],"cil.optimisation.functions.BlockFunction":[[5,2,1,"","L"],[5,1,1,"","__call__"],[5,1,1,"","__init__"],[5,1,1,"","__rmul__"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.ConstantFunction":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.Function":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.IndicatorBox":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,2,1,"","num_threads"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"],[5,1,1,"","set_num_threads"],[5,1,1,"","set_suppress_evaluation"]],"cil.optimisation.functions.KullbackLeibler":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.L1Norm":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.L2NormSquared":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.LeastSquares":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.MixedL11Norm":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.MixedL21Norm":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.OperatorCompositionFunction":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.Rosenbrock":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.ScaledFunction":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.SmoothMixedL21Norm":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.SumFunction":[[5,2,1,"","L"],[5,2,1,"","Lmax"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.SumScalarFunction":[[5,2,1,"","L"],[5,2,1,"","Lmax"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.TotalVariation":[[5,2,1,"","L"],[5,1,1,"","calculate_Lipschitz"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,2,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.TranslateFunction":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.WeightedL2NormSquared":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.functions.ZeroFunction":[[5,2,1,"","L"],[5,1,1,"","centered_at"],[5,1,1,"","convex_conjugate"],[5,1,1,"","gradient"],[5,1,1,"","proximal"],[5,1,1,"","proximal_conjugate"]],"cil.optimisation.operators":[[5,0,1,"","BlockOperator"],[5,0,1,"","ChannelwiseOperator"],[5,0,1,"","CompositionOperator"],[5,0,1,"","DiagonalOperator"],[5,0,1,"","FiniteDifferenceOperator"],[5,0,1,"","GradientOperator"],[5,0,1,"","IdentityOperator"],[5,0,1,"","LinearOperator"],[5,0,1,"","MaskOperator"],[5,0,1,"","MatrixOperator"],[5,0,1,"","Operator"],[5,0,1,"","ScaledOperator"],[5,0,1,"","SparseFiniteDifferenceOperator"],[5,0,1,"","SumOperator"],[5,0,1,"","SymmetrisedGradientOperator"],[5,0,1,"","ZeroOperator"]],"cil.optimisation.operators.BlockOperator":[[5,2,1,"","T"],[5,1,1,"","__getitem__"],[5,1,1,"","__init__"],[5,1,1,"","__rmul__"],[5,1,1,"","adjoint"],[5,1,1,"","column_wise_compatible"],[5,1,1,"","direct"],[5,1,1,"","domain_geometry"],[5,1,1,"","get_as_list"],[5,1,1,"","get_item"],[5,1,1,"","get_norms_as_list"],[5,1,1,"","get_output_shape"],[5,1,1,"","is_linear"],[5,1,1,"","norm"],[5,1,1,"","range_geometry"],[5,1,1,"","row_wise_compatible"],[5,1,1,"","set_norms"]],"cil.optimisation.operators.ChannelwiseOperator":[[5,1,1,"","adjoint"],[5,1,1,"","calculate_norm"],[5,1,1,"","direct"]],"cil.optimisation.operators.CompositionOperator":[[5,1,1,"","adjoint"],[5,1,1,"","direct"],[5,1,1,"","is_linear"]],"cil.optimisation.operators.DiagonalOperator":[[5,1,1,"","adjoint"],[5,1,1,"","calculate_norm"],[5,1,1,"","direct"]],"cil.optimisation.operators.FiniteDifferenceOperator":[[5,1,1,"","adjoint"],[5,1,1,"","direct"]],"cil.optimisation.operators.GradientOperator":[[5,1,1,"","adjoint"],[5,1,1,"","calculate_norm"],[5,1,1,"","direct"]],"cil.optimisation.operators.IdentityOperator":[[5,1,1,"","adjoint"],[5,1,1,"","calculate_norm"],[5,1,1,"","direct"]],"cil.optimisation.operators.LinearOperator":[[5,1,1,"","PowerMethod"],[5,1,1,"","adjoint"],[5,1,1,"","calculate_norm"],[5,1,1,"","dot_test"],[5,1,1,"","is_linear"]],"cil.optimisation.operators.MatrixOperator":[[5,1,1,"","adjoint"],[5,1,1,"","direct"]],"cil.optimisation.operators.Operator":[[5,1,1,"","calculate_norm"],[5,1,1,"","direct"],[5,1,1,"","domain_geometry"],[5,1,1,"","is_linear"],[5,1,1,"","norm"],[5,1,1,"","range_geometry"],[5,1,1,"","set_norm"]],"cil.optimisation.operators.ScaledOperator":[[5,1,1,"","adjoint"],[5,1,1,"","direct"],[5,1,1,"","is_linear"],[5,1,1,"","norm"]],"cil.optimisation.operators.SparseFiniteDifferenceOperator":[[5,1,1,"","direct"]],"cil.optimisation.operators.SumOperator":[[5,1,1,"","adjoint"],[5,1,1,"","direct"],[5,1,1,"","is_linear"]],"cil.optimisation.operators.SymmetrisedGradientOperator":[[5,1,1,"","adjoint"],[5,1,1,"","direct"]],"cil.optimisation.operators.ZeroOperator":[[5,1,1,"","adjoint"],[5,1,1,"","calculate_norm"],[5,1,1,"","direct"]],"cil.optimisation.utilities":[[5,0,1,"","Sampler"],[5,0,1,"","SamplerRandom"]],"cil.optimisation.utilities.Sampler":[[5,1,1,"id28","from_function"],[5,1,1,"","get_samples"],[5,1,1,"id29","herman_meyer"],[5,1,1,"","next"],[5,1,1,"id26","random_with_replacement"],[5,1,1,"id27","random_without_replacement"],[5,1,1,"id0","sequential"],[5,1,1,"id25","staggered"]],"cil.optimisation.utilities.SamplerRandom":[[5,1,1,"","get_samples"]],"cil.plugins.TomoPhantom":[[6,4,1,"","get_ImageData"]],"cil.plugins.ccpi_regularisation.functions":[[6,0,1,"","FGP_TV"],[6,0,1,"","FGP_dTV"],[6,0,1,"","TGV"],[6,0,1,"","TNV"]],"cil.plugins.ccpi_regularisation.functions.FGP_dTV":[[6,1,1,"","__call__"],[6,1,1,"","__init__"],[6,1,1,"","__rmul__"],[6,1,1,"","convex_conjugate"]],"cil.plugins.ccpi_regularisation.functions.TGV":[[6,1,1,"","__call__"],[6,1,1,"","__init__"],[6,1,1,"","__rmul__"],[6,1,1,"","convex_conjugate"]],"cil.plugins.ccpi_regularisation.functions.TNV":[[6,1,1,"","__call__"],[6,1,1,"","__init__"],[6,1,1,"","__rmul__"],[6,1,1,"","check_input"],[6,1,1,"","convex_conjugate"]],"cil.processors":[[7,0,1,"","AbsorptionTransmissionConverter"],[7,0,1,"","Binner"],[7,0,1,"","CentreOfRotationCorrector"],[7,0,1,"","MaskGenerator"],[7,0,1,"","Masker"],[7,0,1,"","Normaliser"],[7,0,1,"","Padder"],[7,0,1,"","RingRemover"],[7,0,1,"","Slicer"],[7,0,1,"","TransmissionAbsorptionConverter"]],"cil.processors.AbsorptionTransmissionConverter":[[7,1,1,"","get_output"],[7,1,1,"","set_input"]],"cil.processors.Binner":[[7,1,1,"","get_output"],[7,1,1,"","process"],[7,1,1,"","set_input"]],"cil.processors.CentreOfRotationCorrector":[[7,1,1,"","get_output"],[7,1,1,"","image_sharpness"],[7,1,1,"","set_input"],[7,1,1,"","xcorrelation"]],"cil.processors.MaskGenerator":[[7,1,1,"","get_output"],[7,1,1,"","mean"],[7,1,1,"","median"],[7,1,1,"","quantile"],[7,1,1,"","set_input"],[7,1,1,"","special_values"],[7,1,1,"","threshold"]],"cil.processors.Masker":[[7,1,1,"","get_output"],[7,1,1,"","interpolate"],[7,1,1,"","mean"],[7,1,1,"","median"],[7,1,1,"","set_input"],[7,1,1,"","value"]],"cil.processors.Normaliser":[[7,1,1,"","estimate_normalised_error"],[7,1,1,"","get_output"],[7,1,1,"","set_input"]],"cil.processors.Padder":[[7,1,1,"","constant"],[7,1,1,"","edge"],[7,1,1,"","get_output"],[7,1,1,"","linear_ramp"],[7,1,1,"","reflect"],[7,1,1,"","set_input"],[7,1,1,"","symmetric"],[7,1,1,"","wrap"]],"cil.processors.RingRemover":[[7,1,1,"","get_output"],[7,1,1,"","set_input"]],"cil.processors.Slicer":[[7,1,1,"","get_output"],[7,1,1,"","process"],[7,1,1,"","set_input"]],"cil.processors.TransmissionAbsorptionConverter":[[7,1,1,"","get_output"],[7,1,1,"","set_input"]],"cil.recon":[[8,0,1,"","FBP"],[8,0,1,"","FDK"]],"cil.recon.FBP":[[8,1,1,"","get_filter_array"],[8,1,1,"","reset"],[8,1,1,"","run"],[8,1,1,"","set_fft_order"],[8,1,1,"","set_filter"],[8,1,1,"","set_filter_inplace"],[8,1,1,"","set_image_geometry"],[8,1,1,"","set_input"],[8,1,1,"","set_split_processing"]],"cil.recon.FBP.FBP":[[0,1,1,"","run"]],"cil.recon.FDK":[[8,1,1,"","get_filter_array"],[8,1,1,"","reset"],[8,1,1,"","run"],[8,1,1,"","set_fft_order"],[8,1,1,"","set_filter"],[8,1,1,"","set_filter_inplace"],[8,1,1,"","set_image_geometry"],[8,1,1,"","set_input"]],"cil.utilities":[[9,5,0,"-","quality_measures"]],"cil.utilities.dataexample":[[9,0,1,"id0","SIMULATED_CONE_BEAM_DATA"],[9,0,1,"","SIMULATED_PARALLEL_BEAM_DATA"],[9,0,1,"","SYNCHROTRON_PARALLEL_BEAM_DATA"],[9,0,1,"","TestData"]],"cil.utilities.dataexample.SIMULATED_CONE_BEAM_DATA":[[9,1,1,"id1","get"]],"cil.utilities.dataexample.SIMULATED_PARALLEL_BEAM_DATA":[[9,1,1,"","get"]],"cil.utilities.dataexample.SYNCHROTRON_PARALLEL_BEAM_DATA":[[9,1,1,"","get"]],"cil.utilities.dataexample.TestData":[[9,1,1,"","load"],[9,1,1,"","random_noise"],[9,1,1,"","scikit_random_noise"]],"cil.utilities.display":[[9,0,1,"","show1D"],[9,0,1,"","show2D"],[9,0,1,"","show_geometry"]],"cil.utilities.display.show1D":[[9,3,1,"","figure"],[9,1,1,"","save"]],"cil.utilities.display.show2D":[[9,1,1,"","save"]],"cil.utilities.display.show_geometry":[[9,1,1,"","save"]],"cil.utilities.quality_measures":[[9,4,1,"","mae"],[9,4,1,"","mse"],[9,4,1,"","psnr"]]},objnames:{"0":["py","class","Python class"],"1":["py","method","Python method"],"2":["py","property","Python property"],"3":["py","attribute","Python attribute"],"4":["py","function","Python function"],"5":["py","module","Python module"]},objtypes:{"0":"py:class","1":"py:method","2":"py:property","3":"py:attribute","4":"py:function","5":"py:module"},terms:{"0":[0,1,3,4,5,6,7,8,9],"0000654846240296":5,"0005647295658866":5,"00186":5,"003":6,"005":7,"008":5,"008567":7,"01":[6,9],"010":5,"018":5,"0192":[2,5],"0193":[2,5],"020":5,"0251":5,"025129":6,"04":6,"05":[5,6,7,9],"055010":6,"06":5,"080716542":5,"09076934x":5,"1":[0,1,2,4,5,6,7,8,9],"10":[1,2,4,5,6,7,9],"100":[4,5,6],"1007":5,"1015":5,"1016":6,"1046":5,"1088":6,"1098":[2,5],"11":[1,5],"1102995080":5,"1109":5,"1137":5,"12":[5,8],"120":[5,7],"128":[6,7],"1321":5,"1364":[6,7],"145":5,"15":[5,8,9],"1533217":5,"16":[4,5,8],"17":[5,7],"18":5,"180":7,"183":5,"1887":8,"1976":6,"1992":5,"1d":[1,2,3,7],"1e":[5,7],"2":[0,1,2,3,4,5,6,7,8,9],"20":[5,9],"200":[4,7],"2001":5,"2003":5,"2008":8,"2009":5,"2010":5,"2011":5,"2016":5,"2017":[5,8],"2018":[5,6],"2019":[5,6,9],"202":5,"2020":[2,5],"20200192":[2,5],"20200193":[2,5],"2021":[2,5],"2022":[0,5],"2028250":5,"2057":6,"21":5,"22":5,"2204":5,"23":[5,7],"24":6,"2419":5,"2434":5,"25":5,"256":9,"2783":5,"28":5,"2808":5,"2_2":[3,5],"2beta":5,"2c":5,"2ca":5,"2d":[0,1,2,3,5,6,7],"2w":5,"2wx":5,"2x":5,"3":[1,4,5,6,7,9],"300":4,"32":[1,8],"35":9,"360":6,"360deg":7,"377":5,"379":5,"381":5,"3d":[0,1,3,4,5,7,9],"4":[1,3,4,5,6,7],"40":5,"400":5,"430":5,"47":5,"48289":8,"4d":[3,4,5,6,9],"4t_":5,"5":[1,4,5,6,7,9],"50":[5,6,9],"550":4,"6":[1,4,5,7,9],"64":5,"649":5,"664":5,"7":[1,5,7],"7142857142857":4,"76":5,"8":[1,4,5,7,8,9],"87":5,"9":[4,5],"9225":5,"9780898719277":5,"99":1,"9ntwu9megq":2,"\u00f6":5,"\u00fc":5,"abstract":5,"boolean":[1,5,6,7,8,9],"byte":5,"case":[1,4,5,7,9],"class":[0,1,2,4,6,7,8,9],"default":[0,1,4,5,6,7,8,9],"do":[0,4,5],"final":5,"float":[1,4,5,6,7,8,9],"function":[1,2,3,4,8,9],"import":[4,5,7,8,9],"int":[0,1,4,5,6,7,8,9],"j\u00f8rgensen":2,"long":[1,5],"new":[1,2,5],"return":[0,1,4,5,6,7,8,9],"richt\u00e1rik":5,"sch\u00f6nlieb":5,"static":[1,4,5,7,9],"true":[1,4,5,6,7,8,9],"try":1,"var":9,"while":[2,5],A:[1,2,3,4,5,6,7,8],AND:9,AS:[0,9],As:5,BE:9,BUT:9,BY:9,By:[4,5],FOR:9,For:[0,1,2,4,5,7,9],IF:9,IN:9,IS:[0,9],If:[1,2,4,5,6,7,8,9],In:[1,3,4,5,7,9],It:[0,1,3,5,7,8],NO:9,NOT:9,No:[0,8],OF:[0,9],ON:9,OR:[0,9],Of:2,On:5,One:[7,9],SUCH:9,THE:9,TO:9,The:[0,1,2,3,4,5,6,7,8,9],Then:5,There:1,These:[4,7],To:[0,3,4,5,9],Will:[1,9],With:[3,5],_1:5,_2:5,_:[0,3,5,6],__array_priority__:5,__call__:[5,6],__delattr__:5,__dir__:5,__eq__:5,__format__:5,__ge__:5,__getattribute__:5,__getitem__:5,__gt__:5,__hash__:5,__iadd__:5,__idiv__:5,__imul__:5,__init__:[5,6],__init_subclass__:5,__isub__:5,__iter__:5,__itruediv__:5,__le__:5,__lt__:5,__mul__:5,__ne__:5,__neg__:5,__new__:5,__next__:5,__radd__:5,__rdiv__:5,__reduce__:5,__reduce_ex__:5,__repr__:5,__rmul__:[5,6],__rpow__:5,__rsub__:5,__rtruediv__:5,__setattr__:[1,5],__sizeof__:5,__str__:5,__subclasscheck__:5,__subclasshook__:5,__weakref__:5,_as_gen:9,_dual:[5,6],_gradient:5,_po_class:0,_pre_filt:0,_process_chunk:0,_setup_po_for_chunk:0,_slices_per_chunk:0,a_:5,ab:[1,5,7],abc:5,abcmeta:5,abl:[3,5],about:[4,7],about_original_data:4,abov:[2,3,5,6,9],absolut:[5,7,9],absorpt:2,absorptiontransmissionconvert:7,abspath:4,acceler:[3,5,7],accept:[0,1,4,5,7],access:5,accord:1,accordingli:5,accumul:1,accur:8,accuraci:7,achiev:[3,5,7],acquir:[3,5],acquisit:[1,2,3,4,5,8,9],acquisition_geometri:[0,4,9],acquisitiondata:[2,3,5,7,8,9],acquisitiondatasetn:7,acquisitiongeomerti:1,acquisitiongeometri:[2,3,4,5,6,7,9],across:7,act:5,activ:0,actor:[3,5],actual:[0,5],ad1:4,ad:[5,6],adapt:9,add:[0,1,5,6,9],addit:[0,1,5,7,8,9],adher:0,adjoint:[0,5],adjust:4,admm:5,advanc:[0,3,5],advis:9,affect:5,after:[5,7,9],ag1:4,ag:[5,6],again:5,against:9,agre:0,aim:2,al:[2,5],algebr:[1,5],algebra:[1,5,8],algorithm:[2,3,6,7,8],alia:[1,4,5,9],align:[1,5,7],all:[0,1,4,5,7,8,9],alloc:[0,1,5,8],allow:[1,3,4,5,6,7,8,9],alon:9,along:[1,4,5,7],alpha:[3,5,6],alphabet:4,also:[0,2,3,4,5,7],alter:7,altern:[4,5],although:5,alwai:[4,5],ametova:5,amir:5,amount:[3,5,9],an:[0,1,2,3,4,5,6,7,8,9],analyt:[2,5],ang_tol:7,angl:[1,4,6,7],angle_unit:[1,6],angular:[1,7],ani:[0,1,3,5,9],anisotrop:[5,6],anoth:5,antonin:5,aop:5,apach:0,apart:7,api:9,appear:7,append:5,appli:[1,3,4,5,6,7,8,9],applic:[0,5],apply_circular_mask:1,appropri:[0,1,5],approx:5,approxim:4,ar:[0,1,3,4,5,7,8,9],arbitrari:5,archiv:5,area:8,arg:[0,1,5],argmin:[3,5,6],argument:[0,1,5,9],aris:9,armijo:5,armijo_rul:5,around:5,arrai:[0,1,3,4,5,7,8,9],arrang:[3,4],artefact:[1,7],articl:2,artifact:7,arxiv:5,as_arrai:1,ascent:5,assembl:3,assign:7,assum:[5,9],astra:[1,2,3,7,8],asymmetr:7,asymptot:5,attribut:[1,3,4,7],au:5,augment:5,author:[0,9],auto:5,automat:7,avail:5,averag:[4,7],avinash:5,avoid:[5,7],ax:[1,4,5,7],axi:[1,4,7,9],axis_0:4,axis_1:4,axis_2:4,axis_label:[4,9],axis_labels_1:4,axis_labels_2:4,axis_nam:7,axis_name1:7,axis_name2:7,axpbi:[1,5],azimuth:9,b:[1,3,5,6],b_:5,b_i:5,back:[3,4,6,8,9],backend:[5,7,8],background:5,backproject:[5,8],backward:[1,4,5],bar:5,base:[0,1,2,3,7,8,9],basi:0,basic:[1,2,4,5],basicconfig:7,batch:1,bdc1:[1,5],bdc2:[1,5],bdc:1,beam:[1,2,6,7,9],becaus:[5,9],beck:5,becom:5,been:[4,5,6,7],beer:7,befor:[4,5,7,9],begin:[0,3,5,7],behav:[1,5],behaviour:[4,5,7,9],being:[2,7],below:[3,5,7,9],berlin:8,best:7,beta:5,betck:5,better:[3,5],between:[1,3,5,6,7,8,9],beyond:[3,9],bibian:5,big:5,bin:[4,7],binari:[1,4,9],binary_oper:[1,5],binner:2,binom:[3,5],biologi:5,bit:4,blob:4,block:[1,2],blockdatacontain:[2,3,9],blockfunct:[3,5],blockgeometri:[2,3,5],blockoper:[3,5],blur:7,bmatrix:5,bnd_cond:5,boat:9,book:5,bool:[4,5,7,9],boolian:1,border:7,both:[1,2,3,5,7],bottom:[0,1],bound:5,boundari:[5,7],box:2,brows:4,build:[2,3,5],burca:5,busi:[5,9],buzug:8,bypass:1,c:[0,1,4,5,6,7,9],cach:5,calcul:[1,4,5,6,7,9],calculate_lipschitz:5,calculate_norm:5,call:[3,4,5,6,8],callabl:5,callback:5,camera:9,can:[0,1,2,3,4,5,6,7,8,9],cannot:9,cap:0,capabl:6,care:9,carola:5,cast:1,caus:[7,9],ccpi:[2,4],ccpi_regularis:6,cd:0,cdot:5,ceil:[0,5],center:[3,5,7],center_i:1,center_x:1,center_z:1,centered_at:5,centr:[1,2,9],centreofrotationcorrector:7,certain:5,cgl:[2,3],chambol:5,chan:5,chang:[0,4,5,6,9],channel:[1,2,5,6,7,9],channel_label:1,channelwiseoper:5,chapter:5,characterist:3,check:[1,4,5],check_converg:5,check_input:[1,6],child:5,choic:5,choos:5,chosen:5,chunk:[0,4,8],cil:[1,3,4,5,7,8,9],cil_log_level:7,circ:5,circular:[1,3,8],clair:5,classmethod:9,clear:5,clearli:0,clip:9,clone:[0,1,5],close:[0,5],cmake:0,cmap:9,code:[0,1,2,4,5,6,9],coincid:7,col:5,collect:[2,5],collim:3,color:9,colour:9,column:[1,4,5,9],column_wise_compat:5,com:[0,5],comment:0,common:3,commonli:1,commut:[1,5],compar:9,comparison:[5,9],compat:[1,4,5,8],complex128:1,complex:[1,5],compli:0,complianc:0,compon:[5,7,8],compos:5,composed_with_adjoint:5,composit:2,compositionoper:5,compress:4,compressed_data:4,compris:[3,5],comput:[5,6,7,8],computation:5,computer:5,concret:5,conda:0,conda_prefix:0,condit:[0,5,9],cone2d:2,cone3d:2,cone:[1,2,6,7,9],config:[0,4],configpars:4,configur:[0,2,4,5,7,8],conjug:[1,5,6],consecut:5,consequenti:9,consid:[2,3,5,9],consist:[1,5],constant:[5,6,7],constant_valu:7,constantfunct:5,constrain:5,constraint:[5,6],construct:[2,4,5,8],constructor:5,contain:[0,2,3,4,5,7,8,9],content:[4,5],continu:5,contract:9,contribut:[2,5,7],contributor:9,control:[0,5,8],convent:[2,3,5],converg:5,convert:[2,9],convex:[5,6],convex_conjug:[5,6],coordin:9,copi:[0,1,5],copyright:[0,9],core:[0,2,3,5],correct:[1,5,7,8],corrector:2,correl:[5,7],correlation_spac:5,correspond:[4,5,7,9],corrupt:9,cosin:8,costli:5,could:[1,5],counter_offset:4,cours:5,courtesi:[4,5],cpu:[5,6],creat:[0,1,3,4,5,7,8,9],create_cone2d:[1,6],create_cone3d:[1,6],create_local_env_for_cil_development_test:0,create_parallel2d:1,create_parallel3d:1,creation:5,creator:[2,6],criteria:7,criterion:[5,6],crop:[4,7],cross:7,ct:[1,2,7,8],cubic:7,current:[0,1,5],custom:[5,8],custom_list:5,customis:[6,8],cut:8,cutoff:8,d:[1,5,7],d_:5,damag:9,damp:7,dark:7,dark_field:7,data:[2,4,5,6,8],data_bin:7,data_centr:7,data_channel0:9,data_channel1:9,data_dir:9,data_pad:7,data_rang:9,data_sl:7,data_typ:4,datacontain:[2,4,5,6,7,9],datacontainer0:1,datacontainer1:1,dataexampl:[8,9],dataord:2,dataprocessor:2,dataset:[0,1,2,3,4,7,8],date:2,davi:8,db10:7,db1:7,db35:7,dc1:9,dc2:9,dc:[1,8],dcmake_install_prefix:0,dd:7,dealloc:5,deblur:5,debug:7,decnum:7,decompos:5,decomposit:7,deep:5,deep_copi:1,def:[0,5],defin:[1,2,3,4,5,6,7,9],definit:[0,3,5,6],degre:[1,6,7,9],delattr:5,delplanck:5,delta:5,delta_dark:7,delta_flat:7,demo:[3,5],denois:5,denot:5,dens:5,depend:[0,3,4,5,7],deprec:[1,5,7],depth:4,deriv:[5,9],descent:5,describ:[1,3,4,5,6],descript:[3,7,8],design:[3,5],desir:[5,7],desiri:7,dest_sel:4,destin:4,detail:[1,2,7],detect:7,detector:[1,3,4,7,8],detector_direction_i:1,detector_direction_x:1,detector_i:1,detector_posit:1,detector_x:1,determin:[1,6],determinist:5,devaiat:7,devel:2,develop:[2,3,5],deviat:[7,9],devic:6,df:7,diag:5,diagon:5,diagonaloper:5,diamond:2,dict:[4,5,7],dictionari:[1,4,7],differ:[2,3,5,6,7,9],differenti:5,digaonaloper:5,dimens:[0,1,4,5,6,7,9],dimension:[5,9],dimension_label:[1,5,7],dir:5,direct:[1,4,5,9],direct_onli:5,direction0:9,direction1:9,directli:[1,4,5,7],directori:[0,4,9],discard:5,disclaim:9,discord:2,disk:4,displai:[2,3],distanc:[1,3,5,9],distribut:[0,5,9],divid:[0,1,5,7],divis:[1,5,7],dl:9,dn:7,doc:[0,4,5,7],docs_environ:0,docstr:2,document:9,doe:[0,1,5,6,7,9],doi:[2,5,7],domain:[5,8,9],domain_geometri:5,domain_init:5,domin:5,done:[1,5],dot:[1,5],dot_test:5,doubl:7,down:9,download:5,downsampl:7,draw:5,drawn:5,dset_path:4,dtype:[1,4,5,6,9],dual:5,dualiti:5,due:[5,7],dure:[0,1,5],dynam:[2,5,9],e:[0,1,2,3,4,5,6,7,9],each:[0,1,4,5,7,9],earli:5,earlier:6,eas:5,easiest:0,easili:5,edg:[1,7],edoardo:5,edu:5,effect:5,effici:5,effort:7,ehrhardt:5,eigenvalu:5,eigenvector:5,either:[0,3,5,7,9],element:[1,4,5,7],elev:9,elif:0,els:[0,6],email:0,embed:0,emiss:5,emit:3,emploi:2,empti:1,enabl:[2,7],enclos:0,end:[0,3,4,5,7],end_valu:7,endors:9,enforc:[2,5],engin:[1,5],enough:2,ensur:7,entri:[4,5],env:0,environ:0,environment_nam:0,epsilon:5,eq:[5,8],eqnarrai:5,equal:[1,5,9],equival:[3,4,5],erfcinv:7,erni:5,error:[1,7,9],essenti:0,esser:5,estim:7,estimate_normalised_error:7,et:[2,5],eta:[5,6],euclid:5,euclidean:[1,5],eval:4,evalu:[5,6,9],evangelo:5,evelina:5,even:[1,5,9],event:[5,9],everi:[5,7,9],everyth:4,evolv:0,exact:[4,5],exactli:5,exampl:[1,4,5,6,7,8,9],except:0,excess:0,exclus:[7,9],execut:5,exemplari:9,exist:5,exp:1,expect:[1,5,7],expens:5,explicit:5,explicitli:9,expon:7,expos:9,express:[0,1,3,5,9],ext:5,extend:[5,7,9],extens:4,extract:4,extrapol:7,f1:5,f2:5,f:[0,3,5,6,7],f_1:5,f_:5,f_i:5,f_n:5,fact:[1,4,5],factor:[3,4,7,9],fail:[1,5],fals:[0,1,4,5,7,8,9],fan:2,fanbeam:2,fardel:5,fashion:5,fast:[5,6],faster:5,favour:0,fbp:[0,1,2,3,7],fdk:[2,3,6,7],feldkamp:8,fft:8,fft_order:8,fgp:[5,6],fgp_dtv:6,fgp_tv:6,fidel:[3,5],field:[0,3,7],figsiz:9,figur:9,file:[0,2,3,5],file_nam:4,filenam:[4,9],fill:[0,1,4,5,7,8],filter:[3,6,7,8],filter_inplac:0,find:[0,5,7],fine:7,finit:5,finitedifferenceoper:5,first:[3,4,5,6,7,9],firstli:[2,5],fista:2,fit:[1,5,7,9],fix:5,fix_rang:9,flag:[5,7],flat:7,flat_field:7,flatten:[5,7],flip:4,fliplr:4,float32:[1,4,5,6],float64:1,fname:4,folder:[0,4],follow:[0,1,4,5,7,8,9],fontsiz:9,forc:1,fork:7,form:[3,5,8,9],format:[0,3],format_spec:5,formatt:5,formul:[2,5],formula:5,forth:5,forward:[5,6],found:[2,5,9],fourier:[7,8],frac:[3,5,6],frame:1,framework:[2,4],frequenc:8,frequency_cutoff:8,from:[1,2,3,4,5,6,8],from_funct:5,fromfil:4,full:[0,3,4,8],fulli:[0,4],fundament:5,further:[0,2,5,8],futher:8,futur:5,g1:6,g2:6,g:[0,1,2,3,4,5,6,7,9],gamma:[5,6],gamma_fconj:5,gamma_g:5,gantri:3,gap:[5,7],gaussian:9,gd:2,ge:5,gemma:5,gener:[0,1,2,4,5,6,9],generalis:[5,6],genericlli:5,geometr:6,geometri:[0,2,4,5,6,7],geometry_bin:7,geometry_sl:7,geq1:5,geq2:5,get:[4,5,8,9],get_as_list:5,get_data_axes_ord:1,get_data_offset:4,get_data_scal:4,get_dataset_metadata:4,get_dimension_axi:1,get_filter_arrai:8,get_geometri:4,get_imagedata:6,get_imagegeometri:[0,1,6],get_input:1,get_item:[1,5],get_last_loss:5,get_last_object:5,get_metadata:4,get_norms_as_list:5,get_ouput:7,get_output:[1,5,7],get_output_shap:5,get_roi:4,get_sampl:5,get_slic:[1,9],getattr:5,getlogg:7,gg:2,git:[0,2],github:[0,2],give:[1,3,5,7],given:5,global:[5,9],gm_domain:5,gm_rang:5,go:[0,3,4],goal:3,good:9,govern:0,gpu:6,gradient:[5,6],gradientoper:2,grai:9,greater:[1,5,8],greatli:3,grid:9,ground:9,ground_truth:9,group:[4,5],gt:5,guarante:5,guess:5,guid:[2,5],guidelin:2,guler:5,h_:5,ha:[0,1,3,4,5,6,7],haar:7,hadamard:5,half:[5,7],ham:8,handl:[1,2,3,8],hann:8,happen:1,hard:7,hardwar:8,hash:5,have:[0,1,3,4,5,7,8],hdf5:2,hdf5_util:4,hdl:8,held:1,help:0,helper:5,henc:5,here:[0,5],hereof:5,herman:5,herman_mey:5,high:[2,5],higher:[8,9],highli:[5,8],hold:[1,5,7],home:[1,4,5,6,7,8,9],horizont:[1,4,7],horizontal_i:[1,5,7,9],horizontal_x:[1,5,7,9],hotdog:9,how:5,howev:[4,5,9],html:[0,4,5,7,9],http:[0,2,4,5,7,8,9],hybrid:5,i:[0,1,2,4,5,6,7,9],i_0:4,ib:5,id:[0,5],ideal:7,ident:5,identifi:[0,7],identityoper:5,ieee:5,ig:[1,5,6],ignor:[5,7],ii:[2,5],illustr:3,imag:[0,2,3,4,5,6,7,8],image_geometri:[0,4,8,9],image_sharp:7,imagedata:[0,2,3,5,6,7,8,9],imagegeometri:[2,3,4,5,6,7,8,9],implement:[2,5],impli:[0,9],impos:[3,5],in_plac:1,inch:9,incid:[3,7],incident:9,includ:[1,5,7,9],inclus:7,incorpar:6,incorrect:7,increas:[5,7,8],increment:5,independ:[1,4,5],index:[1,4,5,7],indic:[1,2,4,7,8],indicatorbox:5,indirect:9,individu:5,industri:5,inequ:5,inexact:5,inf:[5,7],infin:5,infinit:5,influenc:3,info:[4,5,6,7],inform:[0,1,2,4,5,6,7,9],infrastructur:5,infti:5,ingredi:5,inherit:[1,5],ini:4,inifnam:4,initi:[4,5,7],initial_angl:1,initial_bin:7,initialis:[1,4,5,7],inlin:5,inner:[1,5],innov:0,inpaintingand:5,inplac:8,input:[0,1,2,5,6,7,8,9],insid:[1,5],instal:[0,5,6],instanc:[0,1,4,5],instanti:[1,5],instead:[0,5,7,9],instruct:0,instrument:[3,7],integ:[5,6,7,9],intend:5,intens:7,interact:[2,5],interest:[1,7],intermedi:9,intern:[1,4],interpoalt:7,interpol:7,interpret:[5,7,8],interrupt:9,interv:5,introduc:5,introduct:2,introductori:5,intuit:9,invers:5,invok:5,io:[0,3,4],irrespect:5,is_compat:[1,5],is_fortran:4,is_linear:5,is_provably_converg:5,is_virtu:4,islic:2,isotrop:[5,6],issubclass:5,ista:2,iter:[3,5,6],iteration_numb:5,its:[0,5,9],itself:[0,5],j:[5,6],jakob:5,januari:5,join:2,journal:5,js:2,json:4,julian:5,jun:5,just:1,k:[5,6],k_i:5,kak:5,keep:5,kei:[0,1,4,7],keyward:5,keyword:[1,5],kind:0,kinemat:7,kingdom:0,kl_div:5,kmax:5,knowledg:[3,5],known:5,kress:8,kullback:5,kullbackleibl:2,kw:[1,5],kwarg:[0,1,5,6,7,9],kx:5,l11:2,l1:[2,6],l1norm:5,l21:2,l2:[2,6],l2norm_:5,l2normsquar:5,l:[3,5,8],l_:5,lab:3,label:[1,4,5,9],ladmm:2,lagrangian:5,lak:8,lambert:7,langl:[5,6],languag:[0,6],larg:[1,5],larger:5,largest:5,last:[5,7],law:[0,7],layout:4,lb:5,lead:[4,7],least:[1,2,3],leastsquar:5,lectur:5,left:[1,4,5,9],leftrightarrow:[5,6],legend:9,leibler:5,len:5,length:[1,5,8,9],leq1:5,leq:5,ler:5,less:5,let:5,level:[2,4,5,7],liabil:9,liabl:9,librari:[0,1,2,3,5],licens:0,light:2,like:[3,4,5],limit:[0,5,9],line:[4,9],line_colour:9,line_styl:9,linear:[5,7],linear_ramp:7,linearoper:5,linestyl:9,link:[0,2,5],link_islic:2,linspac:6,lionheart:5,lipschitz:5,lipshitz:5,list:[1,2,4,5,8,9],lmax:5,load:[4,9],load_data:4,load_project:4,loader:3,local:[2,9],local_var:9,localvar:9,locat:[1,7],log0:5,log10:5,log:[0,1,5,7,8],log_fil:5,logan:8,logarithm:7,look:4,loop:[4,5,7],loss:[5,7,9],lossi:4,low:5,low_val:9,lower:[5,6,7,9],lu:[3,5],lvert:5,m:[0,5,8],machin:3,mad:7,made:5,mae:9,magnif:3,magnitud:5,mai:[0,1,2,5,7,8,9],mail:2,main:[2,3,5],mainli:3,maintain:9,make:[0,3,5],malcolm:5,manchest:0,mani:5,manipul:[2,3],manual:[4,9],map:[5,9],marc:5,markiewicz:5,martin:5,mask:[1,2,5,9],masker:7,maskgener:7,maskoper:5,match:[1,5,6],materi:9,math:[1,5],mathbb:5,mathcal:5,mathemat:[2,5],mathrm:[3,5,6],matplotlib:9,matric:5,matrix:[3,5,9],matrixoper:5,matthia:5,max:[1,5,6,9],max_:5,max_iter:[5,6],max_iteration_stop_criterion:5,max_quantil:7,max_val:7,maximis:7,maximum:[1,5,6,9],mayer:5,mbox:[5,6],mean:[1,5,7,9],meant:0,measur:[3,5,7,8],med:5,media:5,median:7,medicin:5,medium:5,member:0,memori:[1,5,8],merchant:9,messag:7,met:[5,9],meta:1,metadata:[2,4],method:[1,2,3,4,5,7,8],metric:2,meyer:5,mic:5,midlin:7,might:5,min:[1,5,9],min_:5,min_intens:7,min_quantil:7,min_val:7,min_x:5,mingqiang:5,minim:[4,5],minimis:5,minimum:[1,5,6,9],mirror:7,misalign:7,miss:7,mix:2,mixedl11norm:5,mixedl21norm:5,mkdir:0,mo25:5,mo25_ch6:5,mode:[1,4,5,7,9],model:6,modern:8,modif:9,modifi:[1,8],modul:[3,5,6,7,8],modulu:5,moment:5,monitor:5,mop:5,mop_norm:5,more:[1,3,4,5,7,8,9],moreau:5,most:[1,5],mri:5,mse:9,multi:[2,4,5,7,9],multichannel:[2,5],multicontrast:5,multipl:[0,1,4,5,6,7,9],multiplc:5,multipli:[1,5,7],multiprocess:5,must:[0,1,4,5,7,8,9],mx1:5,my_data:4,my_sampling_funct:5,n:[0,5,6,7,8,9],nabla:5,name:[0,1,4,5,7,9],nan:[5,7],nbyte:4,ndarrai:[1,4,5,7,8,9],ndim:[1,4,6],nearest:7,necessari:[0,1,4],need:[0,4,5,7,9],neg:[4,5,6,7,8,9],neglig:9,neither:9,nest:[1,5,9],nesterov:5,net:8,neumann:5,neutron:7,never:5,new_ord:1,newlin:5,next:[1,5,7,9],nexu:[2,3],nexusdataread:4,nexusdatawrit:4,nice:5,nikon:[2,3],nikondataread:4,nois:[5,9],noisy_data:5,non:[0,2,5,6],none:[0,1,4,5,7,8,9],nonneg:6,nonzero:9,nor:9,norm2sq:5,norm:[1,2,6],normal:[1,5],normalis:[2,4,5],notat:5,note:[4,5,7,8,9],notebook:3,noth:5,notic:[4,5,9],notimpl:5,notimplementederror:5,nov:5,now:[3,5,6],np:[0,4,5,6],nss:5,num_batch:1,num_channel:1,num_chunk:0,num_col:9,num_indic:5,num_model:6,num_pixel:1,num_pixels_h:1,num_pixels_v:1,num_sampl:5,num_thread:[1,5],numba:5,number:[1,2,3,4,5,6,7,9],number_of_dimens:1,numer:1,numpi:[1,4,5,7,8,9],numpy_vers:0,numpydoc:0,nx1:5,nx:4,o:5,o_:5,object:[1,2,3,4,5,7],objective_funct:5,obtain:[0,4],occur:9,oe:[6,7],off:[5,8],offset:[0,1,4,6,7,8],often:0,omega:5,onc:5,one:[1,2,3,5,7,9],ones:[4,5],onli:[0,1,4,5,6,7,8,9],onto:[3,5,7],op0:5,op1:5,op2:5,op:5,oper:[0,1,2,3,7,9],operator1:5,operator2:5,operatorcompositionfunct:5,optim:[2,5],optimis:[2,3,6,8],option:[0,1,4,5,7,8,9],orbit:8,order:[1,4,5,8],ordin:4,org:[0,2,4,5,7,9],orient:[0,2,5],origin:[0,1,4,5,9],original_data:4,os:4,osman:5,other:[1,2,5,7,9],otherwis:[1,5,9],otim:5,our:[1,2,3,5],out:[0,1,4,5,7,8,9],outcom:5,outer:9,outlier:7,output:[0,1,2,4,5,7,8,9],outsid:[1,7,8,9],over:[1,5,7],overrid:5,overridden:5,overset:5,own:0,owner:0,p:[0,5,9],p_i:5,pack:4,packag:[0,2,5],pad:7,pad_valu:7,pad_width:7,padder:2,page:[2,4],pair:[5,9],panel:[0,1,7],paper:2,papoutselli:[2,5],parallel2d:2,parallel3d:2,parallel:[1,2,6,7,9],param:[1,5,9],paramet:[0,1,3,4,5,6,7,8,9],parent:[1,5],pars:4,part:[2,5,6],partial_:5,partial_i:5,partial_x:5,particular:[5,9],partit:1,pasca:5,pass:[0,1,5,7,8,9],path:[4,9],pattern:5,pawel:5,pbar:0,pdf:5,pdf_1:5,pdhg:2,peak:9,penalis:5,pepper:9,per:[5,9],percent:9,percentag:1,perform:[1,5,7],period:5,permiss:[0,9],permit:9,permut:1,pet:5,peter:5,phantom:6,phil:2,philip:5,philosoph:5,photon:[7,8],physic:5,pi:8,pickl:5,pixel:[1,3,4,6,7,8,9],pixel_num_v:0,pixel_s:1,pixel_size_h:1,pixel_size_v:1,pixelwis:9,pjm:5,place:[1,3,8],placehold:[1,5],plantagi:8,pleas:[0,1,2,3,7],plot:9,plugin:[2,3,7],png:9,pock:5,point:[1,3,5,9],pointer:1,poisson:[5,9],poissonloglikelihoodwithlinearmodelformean:5,poorli:9,popul:7,posit:[0,1,5,6,7,8,9],positron:5,possibl:[1,5,9],power:[1,2,5,8,9],powermethod:5,practic:[5,7],pre:[2,3,5,8],precalcul:5,preced:[1,5],precondit:5,predefin:8,prefix:4,prepar:8,prepend:5,present:[1,5],preserv:9,preval:9,previou:[5,6,7],primal:5,prime:5,principl:5,print:[0,4,5,7],print_interv:5,print_metadata:4,prior:[3,5,9],prob:5,prob_weight:5,probabl:5,problem:[2,3,5,6,9],problem_:[5,6],process:[0,1,3,5,6,7,8],processor:[1,2,3],procur:9,produc:[5,9],product:[1,5,9],profil:7,profit:9,progress:7,proj:5,proj_filt:0,project:[2,3,4,5,7,8],projecteuclid:5,projection_index:7,projector:[3,8],promot:9,prompt:5,proper:9,properti:[1,2,5],proport:9,protect:0,protocol:5,prototyp:[2,5],provabl:5,provid:[0,1,2,3,4,5,7,8,9],prox:[5,6],prox_:5,proxim:[5,6],proximal_conjug:5,pseudo:9,psnr:9,purpos:[5,9],py:5,pydata:0,pyplot:9,python2:[1,5],python3:0,python:[2,5],python_vers:0,pywt:7,qeq0:6,quad:5,quadrat:[5,7],qualiti:[2,3],quality_measur:9,quantil:7,quarter:7,question:5,r:[1,2,5],r_1:3,r_2:3,rad:8,radia:2,radian:1,radiat:3,radiu:1,rai:[1,3],rainbow:9,rais:[0,1,5],ral:5,ram:8,ramp:7,random:[1,5,9],random_int:1,random_nois:9,random_permut:1,random_with_replac:5,random_without_replac:5,randomli:5,randomsampl:5,randomwithoutreplac:5,rang:[0,5,6,7,8,9],range_geometri:5,range_init:5,rangl:[5,6],rapid:[2,5],rare:9,rasch:5,rate:5,rather:[5,7],ratio:[6,9],ration:9,raw:2,rawfilewrit:4,ray_direct:1,re:[3,5],reach:[3,5,6],read:[2,7],read_arrai:4,read_as_acquisitiondata:4,read_as_imagedata:4,read_as_origin:4,read_data:4,read_dtyp:4,read_resc:4,read_scale_offset:4,read_shap:4,read_to:4,reader:[2,3],real:[1,2,3,5],recal:5,receiv:5,recognis:[3,5],recommend:[5,7,8],recon:[0,2,3],reconstruct:[0,1,2,3,4,5,6,7],reconstructor:[0,2,3],record:5,recov:5,rect:8,recurs:[0,4],redistribut:9,reduc:[1,3,5,8,9],reduct:1,refer:[0,1,2,3,4,6,7,8,9],referenc:[0,1,7,8],reflect:[5,7],region:7,regular:5,regularis:[2,3,5],rel:[5,6,7],relat:[1,5],relax:5,relev:4,remain:7,remaind:0,remov:2,reorder:1,repeat:5,replac:[0,5,9],repo:0,repositori:[2,3],repositoryy:5,repr:5,repres:[1,4,5,7,9],reproduc:[2,9],request:[0,1,4,7,8,9],requir:[0,1,5,6,7,8],rescal:[4,6],rescaled_data:4,research:0,reserv:9,reset:8,reshap:[4,5],resid:4,resolut:[1,7],resolution_chart:9,resort:1,respect:[1,3,4,5,7,9],rest:5,restart:5,restor:5,resul:[1,5],result:[1,2,3,4,5,7,8,9],ret:0,retain:9,return_al:5,revers:[1,5],rewritten:5,rgensen:5,right:[1,4,5,9],rightarrow:5,ring:2,ringremov:7,rof:5,roi:[4,7],roll:7,root:[4,5],rosenbrock:5,rotat:[1,2,3],rotation_axis_direct:1,rotation_axis_posit:1,round:9,routin:[5,8],row:[0,1,3,4,5],row_wise_compat:5,royal:5,royalsocietypublish:5,rsta:[2,5],rtsd:5,rule:5,run:[0,1,5,6,7,8],rvert_:5,ryan:5,s10107:5,s10589:5,s10851:5,s:[0,1,4,5,9],s_:4,saddl:5,sai:5,salt:9,salt_vs_pepp:9,same:[0,1,4,5,6,7,9],sampl:[3,5],sampler:2,samplerrandom:5,sampling_typ:5,sapyb:[1,5],satisfi:5,save:[3,4,5,9],savefig:9,scalar:[1,5,6,9],scale:[2,4,5,7,9],scaledfunct:5,scaledoper:5,scaleoffset:4,scan:[3,7],scatter:[3,5],schemat:9,schonlieb:5,scienc:5,scikit:9,scikit_random_nois:9,scipi:5,screen:5,script:0,search:[7,9],search_rang:7,sec:5,second:[3,5,7,9],secondli:2,section:[4,5],see:[0,1,5,6,7,9],seed:[1,5,9],select:[3,4,5,8,9],selector:9,self:[0,1,5,6,8],sensibl:4,separ:[0,5,9],sequenc:5,sequenti:[1,5,9],serial:5,serv:0,server:0,servic:9,set:[0,1,2,4,5,6,7,8],set_:0,set_angl:[1,6],set_channel:[1,6],set_fft_ord:8,set_filt:8,set_filter_inplac:8,set_gamma_fconj:5,set_gamma_g:5,set_image_geometri:8,set_input:[1,7,8],set_label:1,set_norm:5,set_num_thread:5,set_panel:[1,6],set_relaxation_paramet:5,set_split_process:[0,8],set_step_s:5,set_suppress_evalu:5,set_up:[4,5],setattr:5,setlevel:7,setter:2,sever:[5,7],sgn:5,sh:0,shall:9,shape:[0,1,4,5,9],share:5,sharp:7,shepp:8,shift:5,shinkoper:5,shortcut:4,shorter:5,should:[0,1,4,5,6,7,8,9],should_stop:5,show1d:2,show2d:2,show:9,show_geometri:2,shrinkag:5,siam:5,side:7,sigma:[5,7],sigma_1:5,sigma_:5,sigma_iw_i:5,sigma_iw_ix_i:5,sign:[1,5,9],signal:9,signatur:5,signific:3,simpl:[0,2,8],simple_phantom_2d:9,simpli:3,simplifi:5,simul:[2,3],simulated_cone_beam_data:[8,9],simulated_parallel_beam_data:[8,9],simulated_sphere_volum:9,simultan:5,singh:5,singl:[1,3,4,5,7,8,9],singular:5,sinogram:1,sirf:5,sirt:2,size:[0,1,4,5,6,7,9],skimag:9,skip:4,slanei:5,slice:[1,2,3,4,7,8],slice_index:7,slice_list:9,slice_metadata:4,slicer:2,slices_per_chunk:[0,8],slight:7,small:[0,5,9],smooth:[2,6],smoothmixedl21norm:5,so:[0,3,5],soc:2,societi:5,softwar:[0,5,9],softx:6,sol:[5,6],solut:[3,5,6],solv:[2,3,5,9],some:[5,7],some_data:1,someth:4,soon:5,sop:5,sort:1,sourc:[1,2,3,4,5,6,7,8],source_posit:1,source_sel:4,space:[5,7],spacechannel:5,spars:5,sparsefinitedifferenceoper:5,spatial:[1,5,7],spdhg:2,special:[5,7,9],special_valu:7,specif:[0,4,5,9],specifi:[1,4,5,7,9],speckl:9,spectral:[2,3,5,7],sphere:9,sphinx:0,split:[5,8],springer:[5,8],sqrt:[1,5,6,7],squar:[1,2,3,9],squared_norm:1,stabl:[4,7,9],stack:[4,7],stackexchang:5,stage:3,stagger:[1,5],standard:[1,3,4,7,8,9],stanford:5,start:[0,4,5,7],statement:7,stationari:3,statist:8,statu:5,std:7,step:[0,3,4,5,7],step_siz:5,stephen:5,sting:1,stochast:5,stop:[5,6,7],store:[0,1,5],store_output:1,str:[1,4,5,6,7,9],strategi:5,strength:7,strict:9,strictli:5,stride:[1,5],string:[1,4,5,6,7,8,9],stripe:7,strong_convexity_const:[5,6],strongli:[5,6],structur:5,style:[0,7],sub:6,subclass:[1,4,5],subject:5,submodul:0,subplot:9,subproblem:5,subsequ:5,subset:5,substitut:9,subtract:[1,5],suffici:3,suit:3,suitabl:[0,1,7],sum:[1,5],sum_:5,sumfunct:5,sumoper:5,sumscalarfunct:5,sup:[5,6],support:[5,7],suppress:[0,1,5,7,8,9],suppress_evalu:5,sure:[0,5],swap:5,symmetr:7,symmetris:5,symmetrisedgradientoper:5,sync:5,synchrotron:3,synchrotron_parallel_beam_data:9,syntax:0,system:[1,2,3,5],system_descript:0,t:[1,4,5,8],t_:5,ta:5,tabul:5,take:[1,4,5,7,8,9],target:[0,7],task:6,tau:[5,6],tau_:5,team:9,teboul:5,techniqu:[3,5],tempor:[5,6],temporari:8,temporarili:9,term:[3,5,6],test:[0,2,3,5],testdata:9,text:[0,4,5],textbf:5,tgv:6,th:[5,9],than:[4,5,6,7,8],thei:[0,1,5,7,9],them:[4,5],theme:0,theoret:7,theori:9,therefor:[1,5,6],theta:5,theta_:5,thi:[0,1,3,4,5,6,7,8,9],thieleman:5,thoma:5,those:1,thread:[1,5],three:[3,5],threshold:[5,7],threshold_factor:7,threshold_valu:7,through:4,thu:5,tiff:[2,9],tiffstackread:4,tiffwrit:4,tigr:[1,2,3,7,8],tikhonov:[3,5],tild:[3,5],time:[0,3,5,8],tip:5,titl:9,tmp_nexu:4,tnv:6,tofil:4,togeth:[4,7],toggl:5,toler:[5,6,7],tomograph:[1,2,5],tomographi:[2,5,8],tomographicimag:[0,2],tomophantom:[2,3],toni:5,too:8,tool:3,toolbox:[6,8],toolkit:[3,6],top:1,tort:9,tot_slic:0,total:[0,2],totalvari:[5,6],tqdm:0,trade:5,trajectori:3,tran:[2,5],transact:5,transform:8,translat:5,translatefunct:5,transmiss:[2,3],transmissionabsorptionconvert:7,transpos:[4,5],treat:5,trigger:5,trivial:2,truedivis:5,truth:9,tune:[7,8],tupl:[1,4,5,7,9],turner:5,tv:[5,6],tw:5,two:[1,5,7,8,9],twx:5,tx:5,txm:4,txrm:4,type:[0,1,3,4,5,6,7,8,9],typic:[3,5],u2:4,u:[3,5,6],uint16:4,uint8:4,unari:[1,5],unary_oper:[1,5],unbin:7,unchang:5,uncompress:4,under:[0,5],underbrac:5,underscor:0,underset:[3,5,6],understand:0,unexpect:9,uniform:[1,5,9],uniformli:5,uniqu:[1,9],unit16:4,unit:[0,1,5],univers:0,unknown:[3,5],unless:[0,7],unmask:7,unpack:4,unreli:7,unsign:[4,9],until:5,up:[2,4,5,6,8,9],updat:[0,5,7,8],update_object:5,update_objective_interv:5,update_step_s:5,upper:[5,7,9],url:5,us:[0,2,3,4,5,6,7,8,9],usag:[5,6,7],user:[0,1,3,5,7,8],util:[2,3,8],v1:5,v2:5,v:5,v_1:5,v_2:5,vai:5,valid:9,valu:[1,4,5,6,7,8,9],valueerror:[0,5],vararg:5,variabl:5,varianc:9,variat:2,variou:9,vaue:7,vector:[1,5,7],vectordata:2,verbos:[0,5,8],verbose_output:5,veri:5,versatil:[2,5],version:[0,5],vertic:[1,4,7],via:5,view:[0,1,3,9],view_dist:9,vision:5,visualis:2,vmatrix:[3,5],volum:[0,1,2,4,5,7,8],voxel:[5,6],voxel_num_i:1,voxel_num_x:1,voxel_num_z:1,voxel_size_i:1,voxel_size_x:[1,6],voxel_size_z:1,vs:9,w:[1,5],w_i:5,wa:[5,9],wai:[0,1,5,9],want:[1,5],warm:5,warm_start:5,warn:7,warr:5,warranti:[0,4,9],wavelet:7,we:[1,3,4,5,9],weak:5,web:5,websit:2,weight:[5,6],weightedl1norm:5,weightedl2normsquar:5,well:[2,3,5],were:7,wether:5,what:[0,4,5],when:[0,3,4,5,6,9],where:[1,3,5,6,7,9],wherea:5,whether:[1,4,5,6,9],which:[1,3,4,5,7,9],whichev:[1,8],white:4,white_level:7,whole:1,width:[7,8],william:5,window:7,wise:[1,5],wish:5,wither:5,within:0,without:[0,4,5,7,9],wname:7,won:5,word:0,work:[0,1,3,4,5],would:[4,5],wrap:[5,7],wright:5,write:[0,2,3,5],writer:[2,3],written:[3,4,5,6,9],wrt:5,www:0,wx:5,x:[1,2,3,5,6,9],x_0:5,x_1:5,x_:[5,6],x_axis_label:9,x_i:5,x_k:5,x_n:5,xcorrel:7,xiaoqun:5,xin:5,xshape:5,xtekct:4,y:[1,5,9],y_:5,y_axis_label:9,year:0,yet:5,yield:[5,8],yml:0,you:[0,2,4,5,7],your:[0,5,7,8],yurii:5,yyyi:0,z:[1,5,6],zeiss:2,zeissdataread:4,zero:[1,5,7],zerofunct:5,zerooper:5,zhang:5,zhu:5},titles:["Developers\u2019 Guide","Framework","Welcome to CIL\u2019s documentation!","Introduction","Read/ write AcquisitionData and ImageData","Optimisation framework","CIL Plugins","Processors","Recon","Utilities"],titleterms:{"1d":9,"2d":9,"class":5,"function":[5,6],"new":0,A:9,Of:7,absorpt:7,acquisitiondata:[1,4],acquisitiongeometri:1,algorithm:5,analyt:8,astra:6,base:5,beam:[3,8],binner:7,block:[3,5],blockdatacontain:[1,5],blockgeometri:1,box:5,build:0,ccpi:6,centr:7,cgl:5,channel:3,cil:[0,2,6],cite:2,composit:5,cone2d:1,cone3d:1,cone:[3,8],configur:1,contact:2,contain:1,content:2,contribut:0,convent:0,convert:7,corrector:7,creator:0,ct:[3,9],data:[1,3,7,9],datacontain:1,dataord:1,dataprocessor:1,dataset:9,demo:2,develop:0,diamond:9,displai:9,docstr:0,document:[0,2],exampl:[0,2],fan:3,fanbeam:1,fbp:[6,8],fdk:8,file:4,fista:5,framework:[1,3,5],from:[0,7,9],gd:5,gener:7,geometri:[1,3,8,9],gradientoper:5,guid:0,guidelin:0,hdf5:4,imag:9,imagedata:[1,4],imagegeometri:1,index:[2,9],indic:5,interact:9,introduct:3,islic:9,ista:5,kullbackleibl:5,l11:5,l1:5,l21:5,l2:5,ladmm:5,least:5,light:9,link:9,link_islic:9,local:0,manipul:7,mask:7,method:0,metric:9,mix:5,multi:3,nexu:4,nikon:4,norm:5,normalis:7,object:[0,9],oper:[5,6],optimis:5,other:[0,6],padder:7,parallel2d:1,parallel3d:1,parallel:[3,8],pdhg:5,plugin:6,pre:7,processor:7,project:6,properti:0,qualiti:9,raw:4,read:4,reader:4,recon:8,reconstruct:8,reconstructor:8,refer:5,regularis:6,remov:7,render:0,ring:7,rotat:7,s:2,sampler:5,set:9,setter:0,show1d:9,show2d:9,show_geometri:9,simpl:5,simul:9,sirt:5,slice:9,slicer:7,smooth:5,softwar:2,sourc:[0,9],spdhg:5,squar:5,system:9,test:9,thi:2,tiff:4,tigr:6,todo:5,tomophantom:6,total:[5,6],transmiss:7,trivial:5,us:1,util:[4,5,9],variat:[5,6],vectordata:1,visualis:9,volum:9,welcom:2,work:2,write:4,writer:4,zeiss:4}}) \ No newline at end of file diff --git a/nightly/utilities.html b/nightly/utilities.html deleted file mode 100644 index 7c67913a6f..0000000000 --- a/nightly/utilities.html +++ /dev/null @@ -1,910 +0,0 @@ - - - - - - - - Utilities — CIL 23.1.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - - - - - - - - - - - - - - - -
    - -
    - -
    -

    Utilities#

    -
    -

    Test datasets#

    -

    A range of small test datasets to generate and use

    -
    -

    A set of simulated volumes and CT data#

    -
    -
    -class cil.utilities.dataexample.SIMULATED_CONE_BEAM_DATA[source]#
    -
    -
    -classmethod get(**kwargs)[source]#
    -

    A cone-beam dataset generated from SIMULATED_SPHERE_VOLUME

    -
    -
    Parameters
    -

    data_dir (str, optional) – The path to the data directory

    -
    -
    Returns
    -

    The simulated spheres dataset

    -
    -
    Return type
    -

    AcquisitionData

    -
    -
    -
    - -
    - -
    -
    -class cil.utilities.dataexample.SIMULATED_PARALLEL_BEAM_DATA[source]#
    -
    -
    -classmethod get(**kwargs)[source]#
    -

    A simulated parallel-beam dataset generated from SIMULATED_SPHERE_VOLUME

    -
    -
    Parameters
    -

    data_dir (str, optional) – The path to the data directory

    -
    -
    Returns
    -

    The simulated spheres dataset

    -
    -
    Return type
    -

    AcquisitionData

    -
    -
    -
    - -
    - -
    -
    -class cil.utilities.dataexample.SIMULATED_CONE_BEAM_DATA[source]#
    -
    -
    -classmethod get(**kwargs)[source]#
    -

    A cone-beam dataset generated from SIMULATED_SPHERE_VOLUME

    -
    -
    Parameters
    -

    data_dir (str, optional) – The path to the data directory

    -
    -
    Returns
    -

    The simulated spheres dataset

    -
    -
    Return type
    -

    AcquisitionData

    -
    -
    -
    - -
    - -
    -
    -

    A CT dataset from the Diamond Light Source#

    -
    -
    -class cil.utilities.dataexample.SYNCHROTRON_PARALLEL_BEAM_DATA[source]#
    -
    -
    -classmethod get(**kwargs)[source]#
    -

    A DLS dataset

    -
    -
    Parameters
    -

    data_dir (str, optional) – The path to the data directory

    -
    -
    Returns
    -

    The DLS dataset

    -
    -
    Return type
    -

    AcquisitionData

    -
    -
    -
    - -
    - -
    -
    -

    Simulated image data#

    -
    -
    -class cil.utilities.dataexample.TestData(**kwargs)[source]#
    -

    Class to return test data

    -

    provides 6 dataset: -BOAT = ‘boat.tiff’ -CAMERA = ‘camera.png’ -PEPPERS = ‘peppers.tiff’ -RESOLUTION_CHART = ‘resolution_chart.tiff’ -SIMPLE_PHANTOM_2D = ‘hotdog’ -SHAPES = ‘shapes.png’ -RAINBOW = ‘rainbow.png’

    -
    -
    -load(which, size=None, scale=(0, 1), **kwargs)[source]#
    -

    Return a test data of the requested image

    -
    -
    Parameters
    -
      -
    • which (str) – Image selector: BOAT, CAMERA, PEPPERS, RESOLUTION_CHART, SIMPLE_PHANTOM_2D, SHAPES, RAINBOW

    • -
    • size (tuple, optional) – The size of the returned ImageData. If None default will be used for each image type

    • -
    • scale (tuple, optional) – The scale of the data values

    • -
    -
    -
    Returns
    -

    The simulated spheres volume

    -
    -
    Return type
    -

    ImageData

    -
    -
    -
    - -
    -
    -static random_noise(image, mode='gaussian', seed=None, clip=True, **kwargs)[source]#
    -

    Function to add noise to input image

    -
    -
    Parameters
    -
      -
    • image – input dataset, DataContainer of numpy.ndarray

    • -
    • mode – type of noise

    • -
    • seed – seed for random number generator

    • -
    • clip – should clip the data.

    • -
    -
    -
    -

    See https://github.com/scikit-image/scikit-image/blob/master/skimage/util/noise.py

    -
    - -
    -
    -static scikit_random_noise(image, mode='gaussian', seed=None, clip=True, **kwargs)[source]#
    -

    Function to add random noise of various types to a floating-point image. -:param image: Input image data. Will be converted to float. -:type image: ndarray -:param mode: One of the following strings, selecting the type of noise to add:

    -
    -
      -
    • ‘gaussian’ Gaussian-distributed additive noise.

    • -
    • -
      ‘localvar’ Gaussian-distributed additive noise, with specified

      local variance at each point of image.

      -
      -
      -
    • -
    • ‘poisson’ Poisson-distributed noise generated from the data.

    • -
    • ‘salt’ Replaces random pixels with 1.

    • -
    • -
      ‘pepper’ Replaces random pixels with 0 (for unsigned images) or

      -1 (for signed images).

      -
      -
      -
    • -
    • -
      ‘s&p’ Replaces random pixels with either 1 or low_val, where

      low_val is 0 for unsigned images or -1 for signed -images.

      -
      -
      -
    • -
    • -
      ‘speckle’ Multiplicative noise using out = image + n*image, where

      n is uniform noise with specified mean & variance.

      -
      -
      -
    • -
    -
    -
    -
    Parameters
    -
      -
    • seed (int, optional) – If provided, this will set the random seed before generating noise, -for valid pseudo-random comparisons.

    • -
    • clip (bool, optional) – If True (default), the output will be clipped after noise applied -for modes ‘speckle’, ‘poisson’, and ‘gaussian’. This is -needed to maintain the proper image data range. If False, clipping -is not applied, and the output may extend beyond the range [-1, 1].

    • -
    • mean (float, optional) – Mean of random distribution. Used in ‘gaussian’ and ‘speckle’. -Default : 0.

    • -
    • var (float, optional) – Variance of random distribution. Used in ‘gaussian’ and ‘speckle’. -Note: variance = (standard deviation) ** 2. Default : 0.01

    • -
    • local_vars (ndarray, optional) – Array of positive floats, same shape as image, defining the local -variance at every image point. Used in ‘localvar’.

    • -
    • amount (float, optional) – Proportion of image pixels to replace with noise on range [0, 1]. -Used in ‘salt’, ‘pepper’, and ‘salt & pepper’. Default : 0.05

    • -
    • salt_vs_pepper (float, optional) – Proportion of salt vs. pepper noise for ‘s&p’ on range [0, 1]. -Higher values represent more salt. Default : 0.5 (equal amounts)

    • -
    -
    -
    Returns
    -

    out – Output floating-point image data on range [0, 1] or [-1, 1] if the -input image was unsigned or signed, respectively.

    -
    -
    Return type
    -

    ndarray

    -
    -
    -

    Notes

    -

    Speckle, Poisson, Localvar, and Gaussian noise may generate noise outside -the valid image range. The default is to clip (not alias) these values, -but they may be preserved by setting clip=False. Note that in this case -the output may contain values outside the ranges [0, 1] or [-1, 1]. -Use this option with care. -Because of the prevalence of exclusively positive floating-point images in -intermediate calculations, it is not possible to intuit if an input is -signed based on dtype alone. Instead, negative values are explicitly -searched for. Only if found does this function assume signed input. -Unexpected results only occur in rare, poorly exposes cases (e.g. if all -values are above 50 percent gray in a signed image). In this event, -manually scaling the input to the positive domain will solve the problem. -The Poisson distribution is only defined for positive integers. To apply -this noise type, the number of unique values in the image is found and -the next round power of two is used to scale up the floating-point result, -after which it is scaled back down to the floating-point image range. -To generate Poisson noise against a signed image, the signed image is -temporarily converted to an unsigned image in the floating point domain, -Poisson noise is generated, then it is returned to the original range.

    -

    This function is adapted from scikit-image. -https://github.com/scikit-image/scikit-image/blob/master/skimage/util/noise.py

    -

    Copyright (C) 2019, the scikit-image team -All rights reserved.

    -

    Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met:

    -
      -
    1. -
      Redistributions of source code must retain the above copyright

      notice, this list of conditions and the following disclaimer.

      -
      -
      -
    2. -
    3. -
      Redistributions in binary form must reproduce the above copyright

      notice, this list of conditions and the following disclaimer in -the documentation and/or other materials provided with the -distribution.

      -
      -
      -
    4. -
    5. -
      Neither the name of skimage nor the names of its contributors may be

      used to endorse or promote products derived from this software without -specific prior written permission.

      -
      -
      -
    6. -
    -

    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS’’ AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE.

    -
    - -
    - -
    -
    -
    -

    Image Quality metrics#

    -
    -
    -cil.utilities.quality_measures.mse(dc1, dc2, mask=None)[source]#
    -

    Calculates the mean squared error of two images

    -
    -
    Parameters
    -
      -
    • dc1 (DataContainer) – One image to be compared

    • -
    • dc2 (DataContainer) – Second image to be compared

    • -
    • mask (array or DataContainer with the same dimensions as the dc1 and dc2) – The pixelwise operation only considers values where the mask is True or NonZero.

    • -
    -
    -
    Returns
    -

    -
    -
    Return type
    -

    A number, the mean squared error of the two images

    -
    -
    -
    - -
    -
    -cil.utilities.quality_measures.mae(dc1, dc2, mask=None)[source]#
    -

    Calculates the Mean Absolute error of two images.

    -
    -
    Parameters
    -
      -
    • dc1 (DataContainer) – One image to be compared

    • -
    • dc2 (DataContainer) – Second image to be compared

    • -
    • mask (array or DataContainer with the same dimensions as the dc1 and dc2) – The pixelwise operation only considers values where the mask is True or NonZero.

    • -
    -
    -
    Returns
    -

    -
    -
    Return type
    -

    A number with the mean absolute error between the two images.

    -
    -
    -
    - -
    -
    -cil.utilities.quality_measures.psnr(ground_truth, corrupted, data_range=None, mask=None)[source]#
    -

    Calculates the Peak signal to noise ratio (PSNR) between the two images.

    -
    -
    Parameters
    -
      -
    • ground_truth (DataContainer) – The reference image

    • -
    • corrupted (DataContainer) – The image to be evaluated

    • -
    • data_range (scalar value, default=None) – PSNR scaling factor, the dynamic range of the images (i.e., the difference between the maximum the and minimum allowed values). We take the maximum value in the ground truth array.

    • -
    • mask (array or DataContainer with the same dimensions as the dc1 and dc2) – The pixelwise operation only considers values where the mask is True or NonZero..

    • -
    -
    -
    Returns
    -

    -
    -
    Return type
    -

    A number, the peak signal to noise ration between the two images.

    -
    -
    -
    - -
    -
    -

    Visualisation#

    -
    -

    show2D - Display 2D slices#

    -
    -
    -class cil.utilities.display.show2D(datacontainers, title=None, slice_list=None, fix_range=False, axis_labels=None, origin='lower-left', cmap='gray', num_cols=2, size=(15, 15))[source]#
    -

    This plots 2D slices from cil DataContainer types.

    -

    Plots 1 or more 2D plots in an (n x num_cols) matrix. -Can plot multiple slices from one 3D dataset, or compare multiple datasets -Inputs can be single arguments or list of arguments that will be sequentially applied to subplots -If no slice_list is passed a 3D dataset will display the centre slice of the outer dimension, a 4D dataset will show the centre slices of the two outer dimension.

    -
    -
    Parameters
    -
      -
    • datacontainers (ImageData, AcquisitionData, list of ImageData / AcquisitionData, BlockDataContainer) – The DataContainers to be displayed

    • -
    • title (string, list of strings, optional) – The title for each figure

    • -
    • slice_list (tuple, int, list of tuples, list of ints, optional) – The slices to show. A list of integers will show slices for the outer dimension. For 3D datacontainers single slice: (direction, index). For 4D datacontainers two slices: [(direction0, index),(direction1, index)].

    • -
    • fix_range (boolean, tuple, list of tuples) – Sets the display range of the data. True sets all plots to the global (min, max).

    • -
    • axis_labels (tuple, list of tuples, optional) – The axis labels for each figure e.g. (‘x’,’y’)

    • -
    • origin (string, list of strings) – Sets the display origin. ‘lower/upper-left/right’

    • -
    • cmap (str, list or tuple of strings) – Sets the colour map of the plot (see matplotlib.pyplot). If passed a list or tuple of the -length of datacontainers, allows to set a different color map for each datacontainer.

    • -
    • num_cols (int) – Sets the number of columns of subplots to display

    • -
    • size (tuple) – Figure size in inches

    • -
    -
    -
    Returns
    -

    returns a matplotlib.pyplot figure object

    -
    -
    Return type
    -

    matplotlib.figure.Figure

    -
    -
    -
    -
    -save(filename, **kwargs)#
    -

    Saves the image as a .png using matplotlib.figure.savefig()

    -

    matplotlib kwargs can be passed, refer to documentation -https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.savefig.html

    -
    - -
    - -
    -
    -

    show1D - Display 1D slices#

    -
    -
    -class cil.utilities.display.show1D(data, slice_list=None, label='default', title=None, line_colours=None, line_styles=None, axis_labels=('Index', 'Value'), size=(8, 6))[source]#
    -

    This creates and displays 1D plots of pixel values by slicing -multi-dimensional data.

    -

    The behaviour is as follows: if provided multiple datasets and a single -slice set (see first example below), one line plot will be generated -per dataset; if provided a single dataset and multiple sets of slices -(see second example below), one line plot will be generated per slice -set; if provided multiple datasets and multiple slice sets, the -\(i\)-th set of slices will apply to the \(i\)-th dataset, with -a line plot generated in each case.

    -
    -
    Parameters
    -
      -
    • data (DataContainer, list of DataContainer, tuple of DataContainer) – Multi-dimensional data to be reduced to 1D.

    • -
    • slice_list (tuple, list of tuple or list of list of tuple, default=None) – A tuple of (dimension, coordinate) pair, or a list, or nested list, of -such pairs for slicing data (default is None, which is only valid when 1D -data is passed)

    • -
    • label ('default', str, list of str, None, default='default') – Label(s) to use in the plot’s legend. Use None to suppress legend.

    • -
    • title (str, default None) – A title for the plot

    • -
    • line_colours (str, list of str, default=None) – Colour(s) for each line plot

    • -
    • line_styles ({"-","--","-.",":"}, list of {"-","--","-.",":"}, default=None) – Linestyle(s) for each line plot

    • -
    • axis_labels (tuple of str, list of str, default=('Index','Value')) – Axis labels in the form (x_axis_label,y_axis_label)

    • -
    • num_cols (int, default=3) – The number of columns in the grid of subplots produced in the case -of multiple plots

    • -
    • size (tuple, default=(8,6)) – The size of the figure

    • -
    -
    -
    -
    -
    -figure#
    -
    -
    Type
    -

    matplotlib.figure.Figure

    -
    -
    -
    - -

    Examples

    -

    This example creates two 2D datasets (images), and uses the provided -slicing information to generate two plots on the same axis, -corresponding to the two datasets.

    -
    >>> from cil.utilities.display import show1D
    ->>> from cil.utilities.dataexample import PEPPERS
    ->>> data = PEPPERS.get()
    ->>> data_channel0 = data.get_slice(channel=0)
    ->>> data_channel1 = data.get_slice(channel=1)
    ->>> show1D([data_channel0, data_channel1], slice_list=[('horizontal_x', 256)],
    -...        label=['Channel 0', 'Channel 1'], line_styles=["--", "-"])
    -
    -
    -

    The following example uses two sets of slicing information applied to a -single dataset, resulting in two separate plots.

    -
    >>> from cil.utilities.display import show1D
    ->>> from cil.utilities.dataexample import PEPPERS
    ->>> data = PEPPERS.get()
    ->>> slices = [[('channel', 0), ('horizontal_x', 256)], [('channel', 1), ('horizontal_y', 256)]]
    ->>> show1D(data, slice_list=slices, title=['Channel 0', 'Channel 1'])
    -
    -
    -
    -
    -save(filename, **kwargs)#
    -

    Saves the image as a .png using matplotlib.figure.savefig()

    -

    matplotlib kwargs can be passed, refer to documentation -https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.savefig.html

    -
    - -
    - -
    -
    -

    show_geometry - Display system geometry#

    -
    -
    -class cil.utilities.display.show_geometry(acquisition_geometry, image_geometry=None, elevation=20, azimuthal=- 35, view_distance=10, grid=False, figsize=(10, 10), fontsize=10)[source]#
    -

    Displays a schematic of the acquisition geometry -for 2D geometries elevation and azimuthal cannot be changed

    -
    -
    Parameters
    -
      -
    • acquisition_geometry (AcquisitionGeometry) – CIL acquisition geometry

    • -
    • image_geometry (ImageGeometry, optional) – CIL image geometry

    • -
    • elevation (float) – Camera elevation in degrees, 3D geometries only, default=20

    • -
    • azimuthal (float) – Camera azimuthal in degrees, 3D geometries only, default=-35

    • -
    • view_distance (float) – Camera view distance, default=10

    • -
    • grid (boolean) – Show figure axis, default=False

    • -
    • figsize (tuple (x, y)) – Set figure size (inches), default (10,10)

    • -
    • fontsize (int) – Set fontsize, default 10

    • -
    -
    -
    Returns
    -

    returns a matplotlib.pyplot figure object

    -
    -
    Return type
    -

    matplotlib.figure.Figure

    -
    -
    -
    -
    -save(filename, **kwargs)#
    -

    Saves the image as a .png using matplotlib.figure.savefig()

    -

    matplotlib kwargs can be passed, refer to documentation -https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.savefig.html

    -
    - -
    - -
    -
    -

    islicer - interactive display of 2D slices#

    -
    -
    -class cil.utilities.jupyter.islicer(data, direction=0, title=None, slice_number=None, cmap='gray', minmax=None, size=None, axis_labels=None, origin='lower-left', play_interval=500)[source]#
    -

    Creates an interactive slider that slices a 3D volume along an axis.

    -
    -
    Parameters
    -
      -
    • data (DataContainer or numpy.ndarray) – A 3-dimensional dataset from which 2-dimensional slices will be -shown

    • -
    • direction (int) – Axis to slice on. Can be 0,1,2 or the axis label, default 0

    • -
    • title (str, list of str or tuple of str, default='') – Title for the display

    • -
    • slice_number (int, optional) – Start slice number (default is None, which results in the center -slice being shown initially)

    • -
    • cmap (str or matplotlib.colors.Colormap, default='gray') – Set the colour map

    • -
    • minmax (tuple) – Colorbar (min, max) values, default None (uses the min, max of -values in data)

    • -
    • size (int or tuple, optional) – Specify the figure size in inches. If int this specifies the -width, and scales the height in order to keep the standard -matplotlib aspect ratio, default None (use the default matplotlib -figure size)

    • -
    • axis_labels (list of str, optional) – The axis labels to use for each of the 3 dimensions in the data -(default is None, resulting in labels extracted from the data, or -[‘X’,’Y’,’Z’] if no labels are present)

    • -
    • origin ({'lower-left', 'upper-left', 'lower-right', 'upper-right'}) – Sets the display origin

    • -
    • play_interval (int, default=500) – The interval of time (in ms) a slice is selected for when iterating -through a set of them

    • -
    -
    -
    Returns
    -

    box – The top-level widget container.

    -
    -
    Return type
    -

    ipywidgets.Box

    -
    -
    -
    - -
    - -
    -
    - - -
    - - - - - -
    - - -
    -
    - - - -
    -
    - - - - - -
    -
    - - \ No newline at end of file diff --git a/nightly/utilities/index.html b/nightly/utilities/index.html new file mode 100644 index 0000000000..11cf76c746 --- /dev/null +++ b/nightly/utilities/index.html @@ -0,0 +1,1049 @@ + + + + + + + + + + + + Utilities — CIL 23.1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    +
    +
    + + + +
    +
    + +
    + + + + + + + + + + + + + +
    + +
    + + +
    +
    + +
    +
    + +
    + +
    + + + + +
    + +
    + + +
    +
    + + + + + +
    + +
    +

    Utilities#

    +
    +

    Test datasets#

    +

    A range of small test datasets to generate and use

    +
    +

    A set of simulated volumes and CT data#

    +
    +
    +class cil.utilities.dataexample.SIMULATED_CONE_BEAM_DATA[source]#
    +
    +
    +classmethod get(**kwargs)[source]#
    +

    A cone-beam dataset generated from SIMULATED_SPHERE_VOLUME

    +
    +
    Parameters
    +

    data_dir (str, optional) – The path to the data directory

    +
    +
    Returns
    +

    The simulated spheres dataset

    +
    +
    Return type
    +

    AcquisitionData

    +
    +
    +
    + +
    + +
    +
    +class cil.utilities.dataexample.SIMULATED_PARALLEL_BEAM_DATA[source]#
    +
    +
    +classmethod get(**kwargs)[source]#
    +

    A simulated parallel-beam dataset generated from SIMULATED_SPHERE_VOLUME

    +
    +
    Parameters
    +

    data_dir (str, optional) – The path to the data directory

    +
    +
    Returns
    +

    The simulated spheres dataset

    +
    +
    Return type
    +

    AcquisitionData

    +
    +
    +
    + +
    + +
    +
    +class cil.utilities.dataexample.SIMULATED_CONE_BEAM_DATA[source]#
    +
    +
    +classmethod get(**kwargs)[source]#
    +

    A cone-beam dataset generated from SIMULATED_SPHERE_VOLUME

    +
    +
    Parameters
    +

    data_dir (str, optional) – The path to the data directory

    +
    +
    Returns
    +

    The simulated spheres dataset

    +
    +
    Return type
    +

    AcquisitionData

    +
    +
    +
    + +
    + +
    +
    +

    A CT dataset from the Diamond Light Source#

    +
    +
    +class cil.utilities.dataexample.SYNCHROTRON_PARALLEL_BEAM_DATA[source]#
    +
    +
    +classmethod get(**kwargs)[source]#
    +

    A DLS dataset

    +
    +
    Parameters
    +

    data_dir (str, optional) – The path to the data directory

    +
    +
    Returns
    +

    The DLS dataset

    +
    +
    Return type
    +

    AcquisitionData

    +
    +
    +
    + +
    + +
    +
    +

    Simulated image data#

    +
    +
    +class cil.utilities.dataexample.TestData(**kwargs)[source]#
    +

    Class to return test data

    +

    provides 6 dataset: +BOAT = ‘boat.tiff’ +CAMERA = ‘camera.png’ +PEPPERS = ‘peppers.tiff’ +RESOLUTION_CHART = ‘resolution_chart.tiff’ +SIMPLE_PHANTOM_2D = ‘hotdog’ +SHAPES = ‘shapes.png’ +RAINBOW = ‘rainbow.png’

    +
    +
    +load(which, size=None, scale=(0, 1), **kwargs)[source]#
    +

    Return a test data of the requested image

    +
    +
    Parameters
    +
      +
    • which (str) – Image selector: BOAT, CAMERA, PEPPERS, RESOLUTION_CHART, SIMPLE_PHANTOM_2D, SHAPES, RAINBOW

    • +
    • size (tuple, optional) – The size of the returned ImageData. If None default will be used for each image type

    • +
    • scale (tuple, optional) – The scale of the data values

    • +
    +
    +
    Returns
    +

    The simulated spheres volume

    +
    +
    Return type
    +

    ImageData

    +
    +
    +
    + +
    +
    +static random_noise(image, mode='gaussian', seed=None, clip=True, **kwargs)[source]#
    +

    Function to add noise to input image

    +
    +
    Parameters
    +
      +
    • image – input dataset, DataContainer of numpy.ndarray

    • +
    • mode – type of noise

    • +
    • seed – seed for random number generator

    • +
    • clip – should clip the data.

    • +
    +
    +
    +

    See scikit-image/scikit-image

    +
    + +
    +
    +static scikit_random_noise(image, mode='gaussian', seed=None, clip=True, **kwargs)[source]#
    +

    Function to add random noise of various types to a floating-point image. +:param image: Input image data. Will be converted to float. +:type image: ndarray +:param mode: One of the following strings, selecting the type of noise to add:

    +
    +
      +
    • ‘gaussian’ Gaussian-distributed additive noise.

    • +
    • +
      ‘localvar’ Gaussian-distributed additive noise, with specified

      local variance at each point of image.

      +
      +
      +
    • +
    • ‘poisson’ Poisson-distributed noise generated from the data.

    • +
    • ‘salt’ Replaces random pixels with 1.

    • +
    • +
      ‘pepper’ Replaces random pixels with 0 (for unsigned images) or

      -1 (for signed images).

      +
      +
      +
    • +
    • +
      ‘s&p’ Replaces random pixels with either 1 or low_val, where

      low_val is 0 for unsigned images or -1 for signed +images.

      +
      +
      +
    • +
    • +
      ‘speckle’ Multiplicative noise using out = image + n*image, where

      n is uniform noise with specified mean & variance.

      +
      +
      +
    • +
    +
    +
    +
    Parameters
    +
      +
    • seed (int, optional) – If provided, this will set the random seed before generating noise, +for valid pseudo-random comparisons.

    • +
    • clip (bool, optional) – If True (default), the output will be clipped after noise applied +for modes ‘speckle’, ‘poisson’, and ‘gaussian’. This is +needed to maintain the proper image data range. If False, clipping +is not applied, and the output may extend beyond the range [-1, 1].

    • +
    • mean (float, optional) – Mean of random distribution. Used in ‘gaussian’ and ‘speckle’. +Default : 0.

    • +
    • var (float, optional) – Variance of random distribution. Used in ‘gaussian’ and ‘speckle’. +Note: variance = (standard deviation) ** 2. Default : 0.01

    • +
    • local_vars (ndarray, optional) – Array of positive floats, same shape as image, defining the local +variance at every image point. Used in ‘localvar’.

    • +
    • amount (float, optional) – Proportion of image pixels to replace with noise on range [0, 1]. +Used in ‘salt’, ‘pepper’, and ‘salt & pepper’. Default : 0.05

    • +
    • salt_vs_pepper (float, optional) – Proportion of salt vs. pepper noise for ‘s&p’ on range [0, 1]. +Higher values represent more salt. Default : 0.5 (equal amounts)

    • +
    +
    +
    Returns
    +

    out – Output floating-point image data on range [0, 1] or [-1, 1] if the +input image was unsigned or signed, respectively.

    +
    +
    Return type
    +

    ndarray

    +
    +
    +

    Notes

    +

    Speckle, Poisson, Localvar, and Gaussian noise may generate noise outside +the valid image range. The default is to clip (not alias) these values, +but they may be preserved by setting clip=False. Note that in this case +the output may contain values outside the ranges [0, 1] or [-1, 1]. +Use this option with care. +Because of the prevalence of exclusively positive floating-point images in +intermediate calculations, it is not possible to intuit if an input is +signed based on dtype alone. Instead, negative values are explicitly +searched for. Only if found does this function assume signed input. +Unexpected results only occur in rare, poorly exposes cases (e.g. if all +values are above 50 percent gray in a signed image). In this event, +manually scaling the input to the positive domain will solve the problem. +The Poisson distribution is only defined for positive integers. To apply +this noise type, the number of unique values in the image is found and +the next round power of two is used to scale up the floating-point result, +after which it is scaled back down to the floating-point image range. +To generate Poisson noise against a signed image, the signed image is +temporarily converted to an unsigned image in the floating point domain, +Poisson noise is generated, then it is returned to the original range.

    +

    This function is adapted from scikit-image. +scikit-image/scikit-image

    +

    Copyright (C) 2019, the scikit-image team +All rights reserved.

    +

    Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met:

    +
      +
    1. +
      Redistributions of source code must retain the above copyright

      notice, this list of conditions and the following disclaimer.

      +
      +
      +
    2. +
    3. +
      Redistributions in binary form must reproduce the above copyright

      notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution.

      +
      +
      +
    4. +
    5. +
      Neither the name of skimage nor the names of its contributors may be

      used to endorse or promote products derived from this software without +specific prior written permission.

      +
      +
      +
    6. +
    +

    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS’’ AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE.

    +
    + +
    + +
    +
    +
    +

    Image Quality metrics#

    +
    +
    +cil.utilities.quality_measures.mse(dc1, dc2, mask=None)[source]#
    +

    Calculates the mean squared error of two images

    +
    +
    Parameters
    +
      +
    • dc1 (DataContainer) – One image to be compared

    • +
    • dc2 (DataContainer) – Second image to be compared

    • +
    • mask (array or DataContainer with the same dimensions as the dc1 and dc2) – The pixelwise operation only considers values where the mask is True or NonZero.

    • +
    +
    +
    Return type
    +

    A number, the mean squared error of the two images

    +
    +
    +
    + +
    +
    +cil.utilities.quality_measures.mae(dc1, dc2, mask=None)[source]#
    +

    Calculates the Mean Absolute error of two images.

    +
    +
    Parameters
    +
      +
    • dc1 (DataContainer) – One image to be compared

    • +
    • dc2 (DataContainer) – Second image to be compared

    • +
    • mask (array or DataContainer with the same dimensions as the dc1 and dc2) – The pixelwise operation only considers values where the mask is True or NonZero.

    • +
    +
    +
    Return type
    +

    A number with the mean absolute error between the two images.

    +
    +
    +
    + +
    +
    +cil.utilities.quality_measures.psnr(ground_truth, corrupted, data_range=None, mask=None)[source]#
    +

    Calculates the Peak signal to noise ratio (PSNR) between the two images.

    +
    +
    Parameters
    +
      +
    • ground_truth (DataContainer) – The reference image

    • +
    • corrupted (DataContainer) – The image to be evaluated

    • +
    • data_range (scalar value, default=None) – PSNR scaling factor, the dynamic range of the images (i.e., the difference between the maximum the and minimum allowed values). We take the maximum value in the ground truth array.

    • +
    • mask (array or DataContainer with the same dimensions as the dc1 and dc2) – The pixelwise operation only considers values where the mask is True or NonZero..

    • +
    +
    +
    Return type
    +

    A number, the peak signal to noise ration between the two images.

    +
    +
    +
    + +
    +
    +

    Visualisation#

    +
    +

    show2D - Display 2D slices#

    +
    +
    +class cil.utilities.display.show2D(datacontainers, title=None, slice_list=None, fix_range=False, axis_labels=None, origin='lower-left', cmap='gray', num_cols=2, size=(15, 15))[source]#
    +

    This plots 2D slices from cil DataContainer types.

    +

    Plots 1 or more 2D plots in an (n x num_cols) matrix. +Can plot multiple slices from one 3D dataset, or compare multiple datasets +Inputs can be single arguments or list of arguments that will be sequentially applied to subplots +If no slice_list is passed a 3D dataset will display the centre slice of the outer dimension, a 4D dataset will show the centre slices of the two outer dimension.

    +
    +
    Parameters
    +
      +
    • datacontainers (ImageData, AcquisitionData, list of ImageData / AcquisitionData, BlockDataContainer) – The DataContainers to be displayed

    • +
    • title (string, list of strings, optional) – The title for each figure

    • +
    • slice_list (tuple, int, list of tuples, list of ints, optional) – The slices to show. A list of integers will show slices for the outer dimension. For 3D datacontainers single slice: (direction, index). For 4D datacontainers two slices: [(direction0, index),(direction1, index)].

    • +
    • fix_range (boolean, tuple, list of tuples) – Sets the display range of the data. True sets all plots to the global (min, max).

    • +
    • axis_labels (tuple, list of tuples, optional) – The axis labels for each figure e.g. (‘x’,’y’)

    • +
    • origin (string, list of strings) – Sets the display origin. ‘lower/upper-left/right’

    • +
    • cmap (str, list or tuple of strings) – Sets the colour map of the plot (see matplotlib.pyplot). If passed a list or tuple of the +length of datacontainers, allows to set a different color map for each datacontainer.

    • +
    • num_cols (int) – Sets the number of columns of subplots to display

    • +
    • size (tuple) – Figure size in inches

    • +
    +
    +
    Returns
    +

    returns a matplotlib.pyplot figure object

    +
    +
    Return type
    +

    matplotlib.figure.Figure

    +
    +
    +
    +
    +save(filename, **kwargs)#
    +

    Saves the image as a .png using matplotlib.figure.savefig()

    +

    matplotlib kwargs can be passed, refer to documentation +https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.savefig.html

    +
    + +
    + +
    +
    +

    show1D - Display 1D slices#

    +
    +
    +class cil.utilities.display.show1D(data, slice_list=None, label='default', title=None, line_colours=None, line_styles=None, axis_labels=('Index', 'Value'), size=(8, 6))[source]#
    +

    This creates and displays 1D plots of pixel values by slicing +multi-dimensional data.

    +

    The behaviour is as follows: if provided multiple datasets and a single +slice set (see first example below), one line plot will be generated +per dataset; if provided a single dataset and multiple sets of slices +(see second example below), one line plot will be generated per slice +set; if provided multiple datasets and multiple slice sets, the +\(i\)-th set of slices will apply to the \(i\)-th dataset, with +a line plot generated in each case.

    +
    +
    Parameters
    +
      +
    • data (DataContainer, list of DataContainer, tuple of DataContainer) – Multi-dimensional data to be reduced to 1D.

    • +
    • slice_list (tuple, list of tuple or list of list of tuple, default=None) – A tuple of (dimension, coordinate) pair, or a list, or nested list, of +such pairs for slicing data (default is None, which is only valid when 1D +data is passed)

    • +
    • label ('default', str, list of str, None, default='default') – Label(s) to use in the plot’s legend. Use None to suppress legend.

    • +
    • title (str, default None) – A title for the plot

    • +
    • line_colours (str, list of str, default=None) – Colour(s) for each line plot

    • +
    • line_styles ({"-","--","-.",":"}, list of {"-","--","-.",":"}, default=None) – Linestyle(s) for each line plot

    • +
    • axis_labels (tuple of str, list of str, default=('Index','Value')) – Axis labels in the form (x_axis_label,y_axis_label)

    • +
    • num_cols (int, default=3) – The number of columns in the grid of subplots produced in the case +of multiple plots

    • +
    • size (tuple, default=(8,6)) – The size of the figure

    • +
    +
    +
    +
    +
    +figure#
    +
    +
    Type
    +

    matplotlib.figure.Figure

    +
    +
    +
    + +

    Examples

    +

    This example creates two 2D datasets (images), and uses the provided +slicing information to generate two plots on the same axis, +corresponding to the two datasets.

    +
    >>> from cil.utilities.display import show1D
    +>>> from cil.utilities.dataexample import PEPPERS
    +>>> data = PEPPERS.get()
    +>>> data_channel0 = data.get_slice(channel=0)
    +>>> data_channel1 = data.get_slice(channel=1)
    +>>> show1D([data_channel0, data_channel1], slice_list=[('horizontal_x', 256)],
    +...        label=['Channel 0', 'Channel 1'], line_styles=["--", "-"])
    +
    +
    +

    The following example uses two sets of slicing information applied to a +single dataset, resulting in two separate plots.

    +
    >>> from cil.utilities.display import show1D
    +>>> from cil.utilities.dataexample import PEPPERS
    +>>> data = PEPPERS.get()
    +>>> slices = [[('channel', 0), ('horizontal_x', 256)], [('channel', 1), ('horizontal_y', 256)]]
    +>>> show1D(data, slice_list=slices, title=['Channel 0', 'Channel 1'])
    +
    +
    +
    +
    +save(filename, **kwargs)#
    +

    Saves the image as a .png using matplotlib.figure.savefig()

    +

    matplotlib kwargs can be passed, refer to documentation +https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.savefig.html

    +
    + +
    + +
    +
    +

    show_geometry - Display system geometry#

    +
    +
    +class cil.utilities.display.show_geometry(acquisition_geometry, image_geometry=None, elevation=20, azimuthal=- 35, view_distance=10, grid=False, figsize=(10, 10), fontsize=10)[source]#
    +

    Displays a schematic of the acquisition geometry +for 2D geometries elevation and azimuthal cannot be changed

    +
    +
    Parameters
    +
      +
    • acquisition_geometry (AcquisitionGeometry) – CIL acquisition geometry

    • +
    • image_geometry (ImageGeometry, optional) – CIL image geometry

    • +
    • elevation (float) – Camera elevation in degrees, 3D geometries only, default=20

    • +
    • azimuthal (float) – Camera azimuthal in degrees, 3D geometries only, default=-35

    • +
    • view_distance (float) – Camera view distance, default=10

    • +
    • grid (boolean) – Show figure axis, default=False

    • +
    • figsize (tuple (x, y)) – Set figure size (inches), default (10,10)

    • +
    • fontsize (int) – Set fontsize, default 10

    • +
    +
    +
    Returns
    +

    returns a matplotlib.pyplot figure object

    +
    +
    Return type
    +

    matplotlib.figure.Figure

    +
    +
    +
    +
    +save(filename, **kwargs)#
    +

    Saves the image as a .png using matplotlib.figure.savefig()

    +

    matplotlib kwargs can be passed, refer to documentation +https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.savefig.html

    +
    + +
    + +
    +
    +

    islicer - interactive display of 2D slices#

    +
    + +
    +
    + + +
    + + + + + +
    + + + + +
    +
    + +
    + +
    +
    +
    + + + + + + + + \ No newline at end of file diff --git a/versions.json b/versions.json new file mode 100644 index 0000000000..6a33c46657 --- /dev/null +++ b/versions.json @@ -0,0 +1 @@ +[{"name": "nightly", "version": "23.1.0", "url": "/CIL/nightly/"}] \ No newline at end of file