Пример #1
0
    def step(self, model, step_num):
        alpha = self.get_alpha(model, step_num)
        # multiplication
        det_num = model.detector_signal.shape[0]
        for i in range(self.n_slices):
            # get slice
            # ############## may be speeded up if all slices are calc. once out of for cycle
            i1 = int(i * np.ceil(det_num / self.n_slices))
            i2 = int(min((i + 1) * np.ceil(det_num / self.n_slices), det_num))
            w_slice = model.detector_geometry[i1:i2]
            wi_slice = self.wi[i1:i2]
            y_slice = model.detector_signal[i1:i2]
            # calculating  correction
            p = signal.get_signal(model.solution, w_slice)
            dp = y_slice - p
            a = np.divide(dp,
                          wi_slice,
                          out=np.zeros_like(dp),
                          where=wi_slice != 0)

            if self.iter_type == 1:  # SMART
                a = np.divide(a,
                              np.abs(y_slice),
                              out=np.zeros_like(a),
                              where=y_slice > 1E-20)
            correction = alpha / (i2 - i1) * np.sum(
                np.multiply(np.moveaxis(w_slice, 0, -1), a), axis=-1)
            model.solution = model.solution + correction
Пример #2
0
 def step(self, model, step_num):
     # expected signal
     y_expected = signal.get_signal(model.solution, model.detector_geometry)
     # multiplication
     mult = np.sum(np.divide(self.w_det,
                             y_expected,
                             out=np.zeros_like(self.w_det),
                             where=y_expected != 0),
                   axis=-1)
     mult = mult / self.wi
     # find delta
     model.solution = model.solution * mult
Пример #3
0
    def step(self, model, solution, real_solution, *args, **kwargs):
        """Residual norm at current step.

        Args:
            model(tomomak.Model): used model.
            real_solution(ndarray): known solution.
            *args, **kwargs: not used, but needed to be here in order to work with Solver properly.

        Returns:
            float: residual norm

        """
        norm = model.detector_signal - signal.get_signal(
            model.solution, model.detector_geometry)
        norm = np.square(norm)
        res = np.sqrt(np.sum(norm))
        self.data.append(res)
        return res
mod.solution = None

# Next step is to provide information about the detectors.
# Let's create 15 fans with 22 detectors around the investigated object.
# Each line will have 1 cm width and 0.2 Rad divergence.
# Note that number of detectors = 330 < solution cells = 600, so it's impossible to get perfect solution.
det = detectors2d.fan_detector_array(mesh=mesh,
                                     focus_point=(5, 5),
                                     radius=11,
                                     fan_num=15,
                                     line_num=22,
                                     width=1,
                                     divergence=0.2)
# Now we can calculate signal of each detector.
# Of course in the real experiment you measure detector signals so you don't need this function.
det_signal = signal.get_signal(real_solution, det)
mod.detector_signal = det_signal
mod.detector_geometry = det
# Let's take a look at the detectors geometry:
mod.plot2d(data_type='detector_geometry')
# It's also possible to get short model summary by converting the model object to string.
print(mod)

# The next step is optional. You can perform transformation with existing geometry,
# e.g. switch to another coordinate system or to basic function space.
# Convenient way to do this is to use pipeline. Once pipeline is created,
# you can do transformations using forward() method.
# And if you wish to perform backward transformation later, you can use backward() method.
# let's rescale our model to 20x20 cells. Rescale class performs transformation to the
# keeps axes types but changes number of segments. If the axis is irregular, rescaling take it into account.
pipe = pipeline.Pipeline(mod)
# You should see a discrete circle. Now let's pretend that solution is unknown.
mod.solution = None

# We will start with the ideal case: no signal noise and number of detectors > number of cells.
# Let's create 30 fan detectors around the target. 40 detectors in each fan.
det = detectors2d.fan_detector_array(mesh=mesh,
                                     focus_point=(5, 5),
                                     radius=11,
                                     fan_num=30,
                                     line_num=40,
                                     width=0.5,
                                     divergence=0.05)
mod.detector_geometry = det

# Next step is to simulate each detector signal.
det_signal = signal.get_signal(real_solution, det)
mod.detector_signal = det_signal

# Now let's create solver which will use ART with step = 0.1 in order to find the solution.
solver = solver.Solver()
solver.iterator = algebraic.ART()
solver.iterator.alpha = 0.1
# When you are using ART, often a good idea is to suggest that all values are positive.
c1 = tomomak.constraints.basic.Positive()
solver.constraints = [c1]

# Finally we want some quantitative parameters in order to evaluate reconstruction results.
# Let's count residual mean square and residual norm.
solver.statistics = [statistics.RMS(), statistics.RN()]
# In order to get RMS real solution should be defined.
solver.real_solution = real_solution
Пример #6
0
    end = time.time()
    print("Parallel calculation took {} s ".format(end - start))
    # This calculation went faster. Note, that parallelization is effective only for the long calculation.
    # We can visualize new geometry and see that it is the same.
    mod.detector_geometry = det
    mod.plot2d(data_type='detector_geometry')

    # The next step is inverse problem solution. Here you can use GPU acceleration. It requires CuPy to be installed.
    # To turn it on run script with environmental variable TM_GPU set to any nonzero value.
    # Or just write in your script:
    #        import os
    #        os.environ["TM_GPU"] = "1"

    # Let's create synthetic object and find the solution using CPU.
    real_solution = objects2d.ellipse(mesh, (5, 5), (3, 3))
    mod.detector_signal = signal.get_signal(real_solution, det)
    solver = Solver()
    solver.iterator = ml.ML()
    steps = 3000
    solver.solve(mod, steps=steps)

    # Now we let's switch to GPU.
    os.environ["TM_GPU"] = "1"
    mod.solution = None
    # Since you enabled GPU in the middle of the execution, you need to recreate solver.
    # The syntax doesn't change.
    solver.iterator = ml.ML()
    solver.solve(mod, steps=steps)
    # Let's see the result.
    mod.plot2d()
Пример #7
0
                                                           radius=45, theta_num=20, phi_num=20)

mod.plot3d(axes=True, style=3, data_type='detector_geometry', cartesian_coordinates=True)
# You can add other detectors - just uncomment the line and append the result  using mod.add_detector(det)
# det = [detectors3d.aperture_detector(mesh, [(4, -5, 4), (6, -5, 4), (4, -5, 6), (6, -5, 6)],
#                                      [(4, 0, 4), (6, 0, 4), (4, 0, 6), (6, 0, 6)])]
# det = [detectors3d.aperture_detector(mesh, [(4, -5, 4), (6, -5, 4), (4, -5, 6), (6, -5, 6)],
#                                                        [(4, 0, 4), (6, 0, 4), (4, 0, 6), (6, 0, 6)])]
# ver = np.array([[0, 0, 0], [0, 0, 10], [0, 10, 0], [10, 0, 0]])
# det = [detectors3d.custom_detector(mesh, ver, radius_dependence=False)]
# det = [detectors3d.line_detector(mesh, (5, 5, 12), (10, 2, 0), 1, calc_volume=True)]
# det = [detectors3d.cone_detector(mesh, (5, 5, 20), (5, 5, 0), 0.3)]
# det = [detectors3d.line_detector(mesh, (5, 5, 12), (10, 2, 0), None, calc_volume=False)]
# det = detectors3d.fan_detector(mesh, (-5, 5, 5), [[5, 2, 6], [5, 7, 6], [5, 2, 4], [5, 7, 4]],
#                                number=[4, 4], divergence=0.3)
det_signal = signal.get_signal(real_solution, mod.detector_geometry)
mod.detector_signal = det_signal
# Now let's find the solution
solver = Solver()
solver.statistics = [statistics.RN(), statistics.RMS()]
solver.real_solution = real_solution
solver.iterator = ml.ML()
steps = 1500
solver.solve(mod, steps=steps)
mod.save("tor.tmm")
# Now we can see the solution.
mod.plot3d(axes=True, style=3, cartesian_coordinates=True)
mod.plot2d(index=(1,2), cartesian_coordinates=True)

solver.plot_statistics()
# Of course, the result we got is not ideal due to limitations of our synthetic experiment.