def bowtie_filter(cfg): ''' Apply the transmittance of bowtie filter, dim: [Ebin, totalNumCells] ''' if not cfg.protocol.bowtie: return cfg # find bowtie file bowtieFile = cfg.protocol.bowtie if not os.path.isfile(bowtieFile): bowtiePath = get_path().bowtie + "/" if os.path.isfile(bowtieFile + ".dat"): bowtieFile += ".dat" elif os.path.isfile(bowtiePath + bowtieFile): bowtieFile = bowtiePath + bowtieFile elif os.path.isfile(bowtiePath + bowtieFile + ".dat"): bowtieFile = bowtiePath + bowtieFile + ".dat" else: raise Exception("Cannot find bowtie file: %s or %s.dat" % (bowtieFile, bowtieFile)) # read bowtie file data = np.loadtxt(bowtieFile, dtype=np.single, comments=['#', '%']) gammas0 = data[:, 0] t0 = data[:, 1:] # thickness in cm bowtieMaterials = ['al', 'graphite', 'cu', 'ti'] Evec = cfg.spec.Evec gammas1 = cfg.det.gammas muT = 0 for i in range(len(bowtieMaterials)): mu = GetMu(bowtieMaterials[i], Evec) f = interpolate.interp1d(gammas0, t0[:, i], kind='linear', fill_value='extrapolate') t1 = f(gammas1) / cfg.det.cosAlphas muT += t1 @ mu.reshape(1, len(mu)) trans = np.exp(-muT) cfg.src.filterTrans *= trans return cfg
def flat_filter(cfg): ''' Apply the transmittance of flat filter at source side, dim: [Ebin, totalNumCells] ''' cosineFactors = 1/cfg.det.cosGammas/cfg.det.cosAlphas Evec = cfg.sim.Evec trans = np.ones([cfg.det.totalNumCells, cfg.spec.nEbin], dtype = np.single) if hasattr(cfg.protocol, "flatFilter"): for ii in range(0, round(len(cfg.protocol.flatFilter)/2)): material = cfg.protocol.flatFilter[2*ii] depth = cfg.protocol.flatFilter[2*ii+1] mu = GetMu(material, Evec) trans *= np.exp(-depth*0.1*cosineFactors @ mu.reshape(1, mu.size)) cfg.src.filterTrans *= trans return cfg
def set_material(cfg, materialList): Evec = cfg.spec.Evec nMat = len(materialList) Mus = np.zeros([Evec.size, nMat], dtype=np.single) for i in range(nMat): Mus[:, i] = GetMu(materialList[i], Evec) / 10 # cm^-1 --> mm^-1 # the C func wants data order: materialIndex -> Ebin, so the dim is [Ebin, materialIndex] fun = cfg.clib.set_material_info_vox fun.argtypes = [c_int, c_int, ndpointer(c_float)] fun.restype = None fun(nMat, Evec.size, Mus)
def Detection_EI(cfg, viewId, subViewId): Evec = cfg.sim.Evec # detection efficiency if viewId == cfg.sim.startViewId and subViewId == 0: # detector prefilter Wvec = feval(cfg.physics.prefilterCallback, cfg) # detector absorption detectorMu = GetMu(cfg.scanner.detectorMaterial, Evec) detEff = 1-np.exp(-0.1*cfg.scanner.detectorDepth/cfg.det.cosBetas*detectorMu) cfg.sim.Wvec = Wvec*detEff # Apply energy-dependent detection efficiency thisSubView = cfg.thisSubView*cfg.sim.Wvec # scatter cross-talk if cfg.physics.crosstalkCallback: thisSubView = feval(cfg.physics.crosstalkCallback, thisSubView, cfg) # quantum noise if cfg.sim.enableQuantumNoise: thisSubView = randpf(thisSubView) # merge energies thisSubView = thisSubView.dot(Evec) # lag if cfg.physics.lagCallback: thisSubView = feval(cfg.physics.lagCallback, thisSubView, cfg) # accumulate subviews if subViewId == 0: cfg.thisView = thisSubView else: cfg.thisView += thisSubView # for final subview if subViewId == cfg.sim.subViewCount-1: # optical cross-talk if cfg.physics.opticalCrosstalkCallback: cfg.thisView = feval(cfg.physics.opticalCrosstalkCallback, cfg.thisView, cfg) # DAS cfg.thisView = feval(cfg.physics.DASCallback, cfg.thisView, cfg) return cfg
def Detection_prefilter(cfg): # Wvec dim: [pixel, Ebin] ([col, row, Ebin]) Evec = cfg.sim.Evec Wvec = np.ones(Evec.shape, dtype=np.single) if hasattr(cfg.scanner, "detectorPrefilter"): for ii in range(round(len(cfg.scanner.detectorPrefilter) / 2)): material = cfg.scanner.detectorPrefilter[2 * ii] depth = cfg.scanner.detectorPrefilter[2 * ii + 1] mu = GetMu(material, Evec) Wvec = Wvec * np.exp(-mu * depth * 0.1) Wvec = nm.repmat(Wvec, cfg.det.totalNumCells, 1) return Wvec
# Copyright 2020, General Electric Company. All rights reserved. See https://github.com/xcist/code/blob/master/LICENSE import numpy as np from catsim.GetMu import GetMu Mu = [] Mu.append(GetMu('water', 70)) Mu.append(GetMu('water', 70.0)) Mu.append(GetMu('bone', (30, 50, 70))) Mu.append(GetMu('bone', [30, 50, 70])) Mu.append(GetMu('al', range(10, 60, 10))) types = ['int', 'float', 'tuple', 'list', 'range'] for mu in Mu: print() for ii in range(len(mu)): print(mu[ii], end="\n") print() Evec = np.array([(20, 30, 40), (50, 60, 70)], dtype=np.single) mu = GetMu('water', Evec) print(mu, type(mu))