Fri 29 Nov 2024 04:30:50 PM CET
This commit is contained in:
parent
b3131500ca
commit
ea135a04cb
303
src/SimNDT/core/inspectionMethods.py
Normal file
303
src/SimNDT/core/inspectionMethods.py
Normal file
|
@ -0,0 +1,303 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# encoding: utf-8
|
||||||
|
"""
|
||||||
|
inspectionMethods.py
|
||||||
|
|
||||||
|
Created by Miguel Molero on 2013-09-26.
|
||||||
|
Copyright (c) 2013 MMolero. All rights reserved.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from math import sin, cos, sqrt, pi
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
import SimNDT.core.inspectionSetup as Inspection
|
||||||
|
import copy
|
||||||
|
|
||||||
|
class Source:
|
||||||
|
def __init__(self):
|
||||||
|
self.Longitudinal = True
|
||||||
|
self.Shear = False
|
||||||
|
self.Pressure = True
|
||||||
|
self.Displacement = False
|
||||||
|
self.hideReceiver = False
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return ("Source: Longitudinal={}, Shear={}, Pressure={}, "
|
||||||
|
"Displacement={}, HideReceiver={}").format(
|
||||||
|
self.Longitudinal, self.Shear, self.Pressure,
|
||||||
|
self.Displacement, self.hideReceiver)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return ("Source(Longitudinal={}, Shear={}, Pressure={}, "
|
||||||
|
"Displacement={}, HideReceiver={})").format(
|
||||||
|
self.Longitudinal, self.Shear, self.Pressure,
|
||||||
|
self.Displacement, self.hideReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class SingleLaunch:
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def view(cls, M, N, Pixel_mm, Theta, transducer):
|
||||||
|
x2 = np.zeros((2,),dtype=np.float32)
|
||||||
|
y2 = np.zeros((2,),dtype=np.float32)
|
||||||
|
|
||||||
|
Ntheta = np.size(Theta,0)
|
||||||
|
D_T = np.around(M/2.)
|
||||||
|
|
||||||
|
if transducer.PointSource:
|
||||||
|
SizePixel = 0.5
|
||||||
|
else:
|
||||||
|
SizePixel = np.around( 0.5 * Pixel_mm * transducer.Size )
|
||||||
|
|
||||||
|
Location = transducer.Location
|
||||||
|
|
||||||
|
if Location == "Top":
|
||||||
|
|
||||||
|
x2 = M/2. + (D_T)*np.sin(Theta)
|
||||||
|
y2 = N/2. + (D_T)*np.cos(Theta)
|
||||||
|
|
||||||
|
X0 = np.around(M/2.)
|
||||||
|
Y0 = np.around(N/2.)
|
||||||
|
|
||||||
|
XL, YL = Inspection.setEmisor(Theta, SizePixel, x2, y2, X0, Y0)
|
||||||
|
YL += (np.around(transducer.CenterOffset * Pixel_mm ))
|
||||||
|
XL[:,0] += (np.around(transducer.BorderOffset * Pixel_mm ))
|
||||||
|
XL[:,1] -= (np.around(transducer.BorderOffset * Pixel_mm ))
|
||||||
|
XL = np.fliplr(XL)
|
||||||
|
|
||||||
|
|
||||||
|
elif Location == "Left":
|
||||||
|
|
||||||
|
x2 = M/2. + (D_T)*np.sin(Theta)
|
||||||
|
y2 = N/2. + (D_T)*np.cos(Theta)
|
||||||
|
|
||||||
|
X0 = np.around(M/2.)
|
||||||
|
Y0 = np.around(N/2.)
|
||||||
|
|
||||||
|
XL, YL = Inspection.setEmisor(Theta, SizePixel, x2, y2, X0, Y0)
|
||||||
|
XL += (np.around(transducer.CenterOffset * Pixel_mm ))
|
||||||
|
|
||||||
|
YL[:,0] += (np.around(transducer.BorderOffset * Pixel_mm ))
|
||||||
|
YL[:,1] -= (np.around(transducer.BorderOffset * Pixel_mm ))
|
||||||
|
YL = np.fliplr(YL)
|
||||||
|
|
||||||
|
|
||||||
|
return XL, YL
|
||||||
|
|
||||||
|
|
||||||
|
def setInspection(self, Scenario, Transducer, Simulation):
|
||||||
|
"""
|
||||||
|
set Inspection on numerical model
|
||||||
|
"""
|
||||||
|
MRI, NRI = Simulation.MRI, Simulation.NRI
|
||||||
|
TapGrid = Simulation.TapGrid
|
||||||
|
Rgrid = Simulation.Rgrid
|
||||||
|
M = np.shape(Scenario.Iabs)[0] *Rgrid
|
||||||
|
N = np.shape(Scenario.Iabs)[1] *Rgrid
|
||||||
|
M2 = M/ 2.0
|
||||||
|
N2 = N/ 2.0
|
||||||
|
|
||||||
|
x2 = np.zeros((2,),dtype=np.float32)
|
||||||
|
y2 = np.zeros((2,),dtype=np.float32)
|
||||||
|
Ntheta = np.size(self.Theta,0)
|
||||||
|
|
||||||
|
X0 = np.around((MRI)/2.0)
|
||||||
|
Y0 = np.around((NRI)/2.0)
|
||||||
|
x2[0] = X0 + (M2-TapGrid[0])*np.sin(self.Theta[0])+1
|
||||||
|
|
||||||
|
|
||||||
|
if Transducer.Location == "Top":
|
||||||
|
|
||||||
|
if self.Method == "PulseEcho" or self.hideReceiver == True:
|
||||||
|
x2[1] = x2[0]
|
||||||
|
else:
|
||||||
|
x2[1] = X0 + (M2-TapGrid[1])*np.sin(self.Theta[1])-1
|
||||||
|
y2[:] = (NRI-TapGrid[2]-TapGrid[3])/2.0 + TapGrid[2]
|
||||||
|
|
||||||
|
|
||||||
|
elif Transducer.Location == "Left":
|
||||||
|
|
||||||
|
if self.Method == "PulseEcho":
|
||||||
|
y2[1] = y2[0]
|
||||||
|
else:
|
||||||
|
y2[1] = Y0 + (M2-TapGrid[1])*np.sin(self.Theta[1])-1
|
||||||
|
|
||||||
|
x2[:] = (NRI-TapGrid[2]-TapGrid[3])/2.0 + TapGrid[2]
|
||||||
|
|
||||||
|
|
||||||
|
if Transducer.PointSource:
|
||||||
|
Transducer.SizePixel = 0.5
|
||||||
|
else:
|
||||||
|
Transducer.SizePixel = np.around( 0.5 * Scenario.Pixel_mm * Transducer.Size * Rgrid )
|
||||||
|
|
||||||
|
XL, YL = Inspection.setEmisor(self.Theta, Transducer.SizePixel, x2, y2, X0, Y0)
|
||||||
|
XL, YL, IR = Inspection.centerOffset(XL, YL, self.Theta, Scenario, Transducer, Rgrid)
|
||||||
|
XL, YL = Inspection.borderOffset(XL, YL, Scenario, Transducer, Rgrid)
|
||||||
|
|
||||||
|
self.XL = XL.copy()
|
||||||
|
self.YL = YL.copy()
|
||||||
|
self.IR = IR.copy()
|
||||||
|
|
||||||
|
|
||||||
|
def getReceivers(self, T):
|
||||||
|
return Inspection.getReceivers(self.XL, self.YL, self.IR, T, False)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Transmission(SingleLaunch):
|
||||||
|
|
||||||
|
def __init__(self,Location="Top"):
|
||||||
|
self.Name = "Transmission"
|
||||||
|
self.Method = "Transmission"
|
||||||
|
self.Location = Location
|
||||||
|
self.hideReceiver = False
|
||||||
|
|
||||||
|
|
||||||
|
if Location=="Top":
|
||||||
|
self.Theta = [270.0*pi/180.0, 90.0*pi/180.0]
|
||||||
|
elif Location == "Left":
|
||||||
|
self.Theta = [180.0*pi/180.0, 0.0*pi/180.0]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return ("Transmission: Method={}, Location={}, Theta={}, HideReceiver={}, "
|
||||||
|
"XL={}, YL={}, IR={}").format(
|
||||||
|
self.Method, self.Location, self.Theta, self.hideReceiver,
|
||||||
|
getattr(self, 'XL', 'Not set'), getattr(self, 'YL', 'Not set'), getattr(self, 'IR', 'Not set'))
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "Transmission(Location='{}')".format(self.Location)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class PulseEcho(SingleLaunch):
|
||||||
|
|
||||||
|
def __init__(self,Location="Top"):
|
||||||
|
self.Name = "PulseEcho"
|
||||||
|
self.Method = "PulseEcho"
|
||||||
|
self.Location = Location
|
||||||
|
self.hideReceiver = False
|
||||||
|
if Location=="Top":
|
||||||
|
self.Theta = [270.0*pi/180.0, 270*pi/180.0]
|
||||||
|
elif Location=="Left":
|
||||||
|
self.Theta = [180.0*pi/180.0, 0.0*pi/180.0]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return ("PulseEcho: Method={}, Location={}, "
|
||||||
|
"Theta={}, HideReceiver={}").format(
|
||||||
|
self.Method, self.Location, self.Theta, self.hideReceiver)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "PulseEcho(Location='{}')".format(self.Location)
|
||||||
|
|
||||||
|
|
||||||
|
class LinearScan(SingleLaunch):
|
||||||
|
|
||||||
|
def __init__(self, ini=-10, end=10, step=1,
|
||||||
|
Location="Top", Method = "Transmission",Theta = [270.0*pi/180.0, 90.0*pi/180.0]):
|
||||||
|
|
||||||
|
self.Name = "LinearScan"
|
||||||
|
self.Location = Location
|
||||||
|
Num = np.size( np.arange(ini,end,step))
|
||||||
|
self.ScanVector = np.linspace(ini, end, Num+1, endpoint=True)
|
||||||
|
self.ScanVectorString = "(%g,%g,%g)"%(ini,end,step)
|
||||||
|
self.Method = Method
|
||||||
|
self.Theta = Theta
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return ("LinearScan: Method={}, Location={}, "
|
||||||
|
"ScanVector={}, Theta={}").format(
|
||||||
|
self.Method, self.Location, self.ScanVectorString, self.Theta)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return ("LinearScan(ini={}, end={}, "
|
||||||
|
"step={}, Location='{}', Method='{}')").format(
|
||||||
|
self.ScanVector[0],
|
||||||
|
self.ScanVector[-1],
|
||||||
|
(self.ScanVector[1] - self.ScanVector[0] if len(self.ScanVector) > 1 else 'N/A'),
|
||||||
|
self.Location,
|
||||||
|
self.Method)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Tomography:
|
||||||
|
|
||||||
|
def __init__(self,ProjectionStep=45,DiameterRing=50,OneProjection=False):
|
||||||
|
|
||||||
|
self.Name = "Tomography"
|
||||||
|
self.Method = "Transmission"
|
||||||
|
self.DiameterRing = DiameterRing
|
||||||
|
self.ProjectionStep = ProjectionStep
|
||||||
|
self.OneProjection = OneProjection
|
||||||
|
self.Theta = np.arange(270,-90.0, -self.ProjectionStep)*(pi/180.0)
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def view(M, N, DiameterRing, Pixel_mm, Theta, transducer):
|
||||||
|
|
||||||
|
x2 = np.zeros((2,),dtype=np.float32)
|
||||||
|
y2 = np.zeros((2,),dtype=np.float32)
|
||||||
|
|
||||||
|
Ntheta = np.size(Theta,0)
|
||||||
|
D_T = np.around(DiameterRing*Pixel_mm/2.)
|
||||||
|
|
||||||
|
x2 = M/2. + (D_T)*np.sin(Theta)
|
||||||
|
y2 = N/2. + (D_T)*np.cos(Theta)
|
||||||
|
|
||||||
|
X0 = np.around(M/2.)
|
||||||
|
Y0 = np.around(N/2.)
|
||||||
|
|
||||||
|
if transducer.PointSource:
|
||||||
|
SizePixel = 0.5
|
||||||
|
else:
|
||||||
|
SizePixel = np.around( 0.5 * Pixel_mm * transducer.Size )
|
||||||
|
|
||||||
|
XL, YL = Inspection.setEmisor(Theta, SizePixel, x2, y2, X0, Y0)
|
||||||
|
|
||||||
|
return XL, YL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def setInspection(self, Scenario, Transducer, Simulation):
|
||||||
|
"""
|
||||||
|
set Inspection on numerical model
|
||||||
|
"""
|
||||||
|
MRI, NRI = Simulation.MRI, Simulation.NRI
|
||||||
|
TapGrid = Simulation.TapGrid
|
||||||
|
Rgrid = Simulation.Rgrid
|
||||||
|
M = np.shape(Scenario.Iabs)[0] *Rgrid
|
||||||
|
N = np.shape(Scenario.Iabs)[1] *Rgrid
|
||||||
|
M2 = M/ 2.0
|
||||||
|
N2 = N/ 2.0
|
||||||
|
Pixel_mm = Scenario.Pixel_mm
|
||||||
|
|
||||||
|
Ntheta = np.size(self.Theta,0)
|
||||||
|
DR = np.around(self.DiameterRing*Pixel_mm*Rgrid/2.)
|
||||||
|
|
||||||
|
X0 = TapGrid[0] + (Scenario.M/2.0)*Rgrid
|
||||||
|
Y0 = TapGrid[2] + (Scenario.N/2.0)*Rgrid
|
||||||
|
x2 = X0 + (DR)*np.sin(self.Theta)
|
||||||
|
y2 = Y0 + (DR)*np.cos(self.Theta)
|
||||||
|
|
||||||
|
if Transducer.PointSource:
|
||||||
|
Transducer.SizePixel = 0.5
|
||||||
|
else:
|
||||||
|
Transducer.SizePixel = np.floor( 0.5 * Scenario.Pixel_mm * Transducer.Size * Rgrid )
|
||||||
|
|
||||||
|
XL, YL = Inspection.setEmisor(self.Theta, Transducer.SizePixel, x2, y2, X0, Y0)
|
||||||
|
XL, YL, IR = Inspection.centerOffset(XL, YL, self.Theta, Scenario, Transducer, Rgrid)
|
||||||
|
|
||||||
|
|
||||||
|
self.XL = XL.copy()
|
||||||
|
self.YL = YL.copy()
|
||||||
|
self.IR = IR.copy()
|
||||||
|
|
||||||
|
|
||||||
|
def getReceivers(self, T):
|
||||||
|
return Inspection.getReceivers(self.XL, self.YL, self.IR, T, False)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user