Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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)
Esempio n. 4
0
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
Esempio n. 5
0
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
Esempio n. 6
0
# 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))