コード例 #1
0
ファイル: runners.py プロジェクト: brenthuisman/postdoc_tools
def calcdvh(dose1, dose2, mask=None):
    plandose = image(dose1)
    otherdose = image(dose2)
    if mask == None or not mask.is_file():
        print(
            'No mask or maskregion specified; using isodose 50 volume of plandose for DVH analysis.'
        )
        maskim = plandose.copy()
        maskim.tomask_atthreshold((50 / 100.) * maskim.max())
    else:
        maskim = image(mask)

    plandose.applymask(maskim)
    otherdose.applymask(maskim)

    # note: array is sorted in reverse for DVHs, i.e. compute 100-n%
    planD2, planD50, planD98 = plandose.percentiles([98, 50, 2])
    otherD2, otherD50, otherD98 = otherdose.percentiles([98, 50, 2])

    labels = ["Dmax", "D2", "D50", "D98", "Dmean"]
    planres = plandose.max(), planD2, planD50, planD98, plandose.mean()
    otherres = otherdose.max(), otherD2, otherD50, otherD98, otherdose.mean()
    diffres = [
        label + "=" + str(i - j)
        for label, i, j in zip(labels, planres, otherres)
    ]

    print(diffres)

    result = "files=" + str(dose1) + ";" + str(dose2) + " " + ' '.join(diffres)

    return result
コード例 #2
0
ファイル: runners.py プロジェクト: brenthuisman/postdoc_tools
def dvhcompare(casedir, *args, **kwargs):
    dose1 = ''
    dose2 = ''
    if len(args) == 0:
        #assume casedir is a dosia dumpdir
        assert os.path.isdir(casedir)
        dose1 = os.path.join(casedir, 'sum_dose.xdr')
        dose2 = os.path.join(casedir, 'sum_gpumcd_dose.xdr')
    else:
        #assume casedir is a file and secondfile also
        assert os.path.isfile(casedir)
        dose1 = casedir
        dose2 = args[0]  #secondfile

    assert os.path.isfile(dose1)
    assert os.path.isfile(dose2)

    plandose = image(dose1)
    otherdose = image(dose2)

    maskim = None
    #is there a mask?
    if os.path.isfile(os.path.join(casedir, 'ptv.xdr')):
        maskim = image(os.path.absos.path(os.path.join(casedir, 'ptv.xdr')))
    else:
        print(
            'No mask or maskregion specified; using isodose 50 volume of plandose for DVH analysis.'
        )
        maskim = plandose.copy()
        maskim.tomask_atthreshold((50 / 100.) * maskim.max())

    plandose.applymask(maskim)
    otherdose.applymask(maskim)

    # note: array is sorted in reverse for DVHs, i.e. compute 100-n%
    planD2, planD50, planD98 = plandose.percentiles([98, 50, 2])
    otherD2, otherD50, otherD98 = otherdose.percentiles([98, 50, 2])

    labels = ["Dmax", "D2", "D50", "D98", "Dmean"]
    planres = plandose.max(), planD2, planD50, planD98, plandose.mean()
    otherres = otherdose.max(), otherD2, otherD50, otherD98, otherdose.mean()
    diffres = [
        label + "=" + str(i - j)
        for label, i, j in zip(labels, planres, otherres)
    ]

    print(diffres)

    result = "files=" + dose1 + ";" + dose2 + " " + ' '.join(diffres)

    return result
コード例 #3
0
def build_casedir(dname, loadimages=True):
    ct_dirs = glob.glob(path.join(dname, "*PLAN*"))
    upi_dirs = glob.glob(path.join(dname, "*UPI*"))

    studies = collections.defaultdict(dict)

    for ct_dir in ct_dirs:
        a = pydicom_object(ct_dir)
        if a.modality == 'CT':
            studies[a.studyid]['ct'] = a
            if loadimages:
                if a.PatientPosition != 'HFS':
                    raise NotImplementedError(
                        "Patient (Dose) is not in HFS position.")
                studies[a.studyid]['ct_im'] = image.image(ct_dir)
                # studies[a.studyid]['ct_im'].ct_to_hu(a.RescaleIntercept,a.RescaleSlope)
        else:
            IOError("Expected CT image, but", a.modality, "was found.")

    for upi_dir in upi_dirs:
        files_in_upi = glob.glob(path.join(upi_dir, '*'))
        for f in files_in_upi:
            a = pydicom_object(f)
            try:
                studies[a.studyid][a.sopid]
            except:
                studies[a.studyid][a.sopid] = {}
            if a.modality == "RTDOSE":
                studies[a.studyid][a.sopid]['dose'] = a
                if loadimages:
                    # if str(a.data.DoseUnits) != "GY":
                    # 	raise NotImplementedError("The provided dicom dose image has relative units.")
                    # if str(a.data.DoseType) != "PHYSICAL":
                    # 	raise NotImplementedError("The provided dicom dose image is not in physical units.")
                    # if str(a.data.DoseSummationType) not in ["PLAN","FRACTION"]:
                    # 	raise NotImplementedError("Dose was not computed for 'PLAN' or 'FRACTION'.")
                    studies[a.studyid][a.sopid]['dose_im'] = image.image(f)
                    studies[a.studyid][a.sopid]['dose_im'].mul(
                        a.data.DoseGridScaling)
            elif a.modality == "RTPLAN":
                studies[a.studyid][a.sopid]['plan'] = a
                # if loadimages and a.PatientPosition != 'HFS':
                # 	raise NotImplementedError("Patient (Plan) is not in HFS position.")
            else:
                IOError("Expected RTDOSE or RTPLAN, but", a.modality,
                        "was found.")

    return studies
コード例 #4
0
ファイル: runners.py プロジェクト: brenthuisman/postdoc_tools
def makedose_old(casedir, recalcdose=True, sumdoses=True):
    import glob, os
    from shutil import copyfile
    beamdirs = [
        os.path.split(i)[0]
        for i in glob.glob(os.path.join(casedir, "**", "dbtype.dump"),
                           recursive=True)
    ]

    print("recalcdose", "=", recalcdose)
    print("beamdirs", "=", beamdirs)

    if recalcdose or not os.path.isfile(
            os.path.join(beamdirs[0], "gpumcd_dose.xdr")):
        for beamdir in beamdirs:
            arrgs = "-i " + beamdir
            execute(dosiaengine, arrgs)

    #copy mask if exists.
    if os.path.isfile(os.path.join(beamdirs[0], 'ptvmask.xdr')):
        copyfile(os.path.join(beamdirs[0], 'ptvmask.xdr'),
                 os.path.join(casedir, 'ptvmask.xdr'))

    tpsdosesum_fn = os.path.join(casedir, 'sum_dose.xdr')
    gpumcddosesum_fn = os.path.join(casedir, 'sum_gpumcd_dose.xdr')

    tpsdosesum = image(os.path.join(beamdirs[0], 'dose.xdr'))
    gpumcddosesum = image(os.path.join(beamdirs[0], 'gpumcd_dose.xdr'))

    if len(beamdirs) > 1:
        for beamdir in beamdirs[1:]:
            print(os.path.join(beamdir, 'dose.xdr'))
            imaget = image(os.path.join(beamdir, 'dose.xdr'))
            imageg = image(os.path.join(beamdir, 'gpumcd_dose.xdr'))
            tpsdosesum.add(imaget)
            gpumcddosesum.add(imageg)

    tpsdosesum.saveas(tpsdosesum_fn)
    gpumcddosesum.saveas(gpumcddosesum_fn)

    return [tpsdosesum_fn, gpumcddosesum_fn, beamdirs]
コード例 #5
0
ファイル: runners.py プロジェクト: brenthuisman/postdoc_tools
def calcgamma(dose1, dose2, outf, mask=None, overwrite=True):
    if overwrite:
        arrgs = "/dose1 " + str(dose1) + " /dose2 " + str(
            dose2) + " /outf " + str(outf) + " 2>&1"
        print(arrgs)
        execute(xdr_gamma, arrgs)
    gammamap = image(outf)
    if mask == None or not mask.is_file():
        print(
            'No mask or maskregion specified; using isodose 50 volume of gammamap for gamma statistical analysis.'
        )
        maskim = image(dose1)
        maskim.tomask_atthreshold((50 / 100.) * maskim.max())
    else:
        maskim = image(mask)
    gammamap.applymask(maskim)
    result = 'mean=' + str(gammamap.mean()) + ' passrate=' + str(
        gammamap.passrate())
    result = "files=" + str(dose1) + ";" + str(dose2) + " " + result

    gammamap.saveas(str(outf) + '.masked.xdr')
    return result
コード例 #6
0
ファイル: ct.py プロジェクト: brenthuisman/dosia
    def __init__(self, settings, ct_image):  #,intercept=0,slope=1):
        '''
		The supplied image is assumed to have its voxels set to HU.
		'''
        assert (isinstance(ct_image, image))
        assert (isinstance(settings, Settings))

        hu2dens_table = [[], []]
        with open(
                path.join(settings.directories['hounsfield_conversion'],
                          'hu2dens.ini'), 'r') as f:
            for line in f.readlines():
                if line.startswith('#'):
                    continue
                hu2dens_table[0].append(float(line.split()[0]))
                hu2dens_table[1].append(float(line.split()[1]))
        dens2mat_table = [[], []]
        with open(
                path.join(settings.directories['hounsfield_conversion'],
                          'dens2mat.ini'), 'r') as f:
            for line in f.readlines():
                if line.startswith('#'):
                    continue
                dens2mat_table[0].append(float(line.split()[0]))
                dens2mat_table[1].append(line.split()[1])

        dens = ct_image.copy()
        # dens.ct_to_hu(intercept,slope)

        if path.isdir(settings.debug['output']):
            dens.saveas(path.join(settings.debug['output'], 'ct_as_hu.xdr'))

        dens.hu_to_density(hu2dens_table)
        med = dens.copy()

        self.materials = med.density_to_materialindex(dens2mat_table)
        #self.materials.append("Tungsten") # collimator material

        self.phantom = Phantom(massDensityArray_image=dens,
                               mediumIndexArray_image=med)
        self.dosemap = image(DimSize=med.header['DimSize'],
                             ElementSpacing=med.header['ElementSpacing'],
                             Offset=med.header['Offset'],
                             dt='<f4')

        if path.isdir(settings.debug['output']):
            dens.saveas(path.join(settings.debug['output'], 'dens.xdr'))
            med.saveas(path.join(settings.debug['output'], 'med.xdr'))
コード例 #7
0
ファイル: engine.py プロジェクト: brenthuisman/postdoc_tools
    def get_dose(self, dosemap):
        '''
		Add dose to provided dosemap voxel by voxel.
		'''
        #cant write to self.ct.dosemap directly, because self will be destroyed after this function exits!
        assert (isinstance(dosemap, image.image))
        assert (self.ct.phantom.nvox() == dosemap.nvox())
        newdose = image.image(DimSize=dosemap.header['DimSize'],
                              ElementSpacing=dosemap.header['ElementSpacing'],
                              Offset=dosemap.header['Offset'],
                              dt='<f4')
        self.__gpumcd_object__.get_dose(newdose.get_ctypes_pointer_to_data())
        newdose.imdata = np.asarray(newdose.imdata, order='F').reshape(
            tuple(reversed(newdose.imdata.shape))).swapaxes(
                0,
                len(newdose.imdata.shape) - 1)
        dosemap.add(newdose)
コード例 #8
0
    def __init__(self, fname, *args, **kwargs):
        super().__init__(*args, **kwargs)

        if isinstance(fname, image.image):
            self.image = fname.copy()
        else:
            self.image = image.image(fname)

        x, y, z = self.image.get_slices_at_index()
        # import scipy.misc
        # scipy.misc.imsave("d:/slicex.png",x)
        # scipy.misc.imsave("d:/slicey.png",y)
        # scipy.misc.imsave("d:/slicez.png",z)
        s = np.uint8(np.interp(x, (x.min(), x.max()), (0, 255)).T)
        im = np.copy(np.rot90(np.rot90(s)), order='C')
        self.qimage = QImage(im.data, im.shape[1], im.shape[0],
                             im.shape[1] * 1, QImage.Format_Grayscale8)

        self.ready = True
コード例 #9
0
ファイル: ops_math.py プロジェクト: brenthuisman/medimage
	def resample(self, new_ElementSpacing=[2,2,2], allowcrop=True, order=1):
		'''
		Resample image. Provide the desired ElementSpacing to which will be interpolated. Note that the spacing will be adjusted to obtain an integer image grid. Set allowcrop to True if you want to fix your new spacing and prefer to crop (subpixel distances) around the edges if necesary.
		'''

		old_ElementSpacing = np.array(self.header['ElementSpacing'])
		new_ElementSpacing = np.array(new_ElementSpacing)
		new_req_shape = self.imdata.shape * old_ElementSpacing / new_ElementSpacing
		new_shape = np.round(new_req_shape)

		if not allowcrop:
			#We keep the extent of the image fixed, so we'll adjust the new_ElementSpacing such that it fits into the new shape.
			real_resize_factor = new_shape / self.imdata.shape
			new_ElementSpacing = old_ElementSpacing / real_resize_factor

		new_shape = tuple(int(i) for i in new_shape) #new image expects tuples
		self.crop_as(image.image(ElementSpacing=new_ElementSpacing,Offset=self.header['Offset'],DimSize=new_shape))

		for s in self.imdata.shape:
			if s < 1:
				raise Exception('invalid image shape {}'.format(self.imdata.shape))
コード例 #10
0
import ctypes,numpy as np,os,math,time
from os import path
import gpumcd
import medimage as image

print('Start of program.')

sett = gpumcd.Settings("d:\\postdoc\\gpumcd_data")
print(sett.planSettings.goalSfom)

casedir = "d:\\postdoc\\analyses\\gpumcd_python"

ct_image=image.image(path.join(casedir,'ct.xdr'))
ct_image.ct_to_hu(1000,1)
ct_image.resample([3,3,3])

ct = gpumcd.CT(sett,ct_image) #for dicoms, dont set intercept,slope.

machfile = "d:/postdoc/gpumcd_data/machines/machine_van_sami/brentAgility.beamlets.gpumdt"

engine = gpumcd.Engine(sett,ct,machfile)

print('gpumcd init done.')

print (engine.lasterror())

start_time = time.time()



frame1size = 5
コード例 #11
0
    def __init__(self, input_, sett, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.sett = sett
        self.image = []
        if isinstance(input_, image.image):
            self.image.append(input_.copy())
            self.fname = "GPUMCD"
        elif isinstance(input_, list):
            self.fname = "GPUMCD"
            for im in input_:
                assert (isinstance(im, image.image))
                self.image.append(im.copy())
        else:
            self.image.append(image.image(input_))
            self.fname = str(input_)

        self.imi = 0
        self.axi = 0
        self.slicei = int(self.image[self.imi].imdata.shape[self.axi] /
                          2)  #FIXME isoc

        imnav = QHBoxLayout()
        imnav.setContentsMargins(0, 0, 0, 0)

        self.imselect = QComboBox()
        for i, im in enumerate(self.image):
            self.imselect.addItem(str(i))
        self.imselect.currentIndexChanged.connect(self.setim)

        self.axselect = QComboBox()
        self.axselect.addItems(["x", "y", "z"])
        self.axselect.currentIndexChanged.connect(self.setax)

        # self.sliceselect = QSpinBox()

        self.sliceselect = QSlider(Qt.Horizontal, self)
        self.sliceselect.setTickPosition(QSlider.TicksBelow)
        self.sliceselect.setMinimum(0)
        self.sliceselect.setMaximum(
            self.image[self.imi].imdata.shape[self.axi])
        self.sliceselect.setValue(self.slicei)
        self.sliceselect.valueChanged.connect(self.setslice)

        self.savebutton = QPushButton('Save (.xdr)', self)
        self.savebutton.setToolTip('Save this image or images as XDR')
        self.savebutton.clicked.connect(self.save)

        imnav.addWidget(self.imselect, 0)
        imnav.addWidget(self.axselect, 0)
        imnav.addWidget(self.sliceselect, 0)
        imnav.addWidget(self.savebutton, 0)

        l = QVBoxLayout()
        self.fname_label = QLabel(self.fname)
        self.canvas = ImageCanvas()  #blank for now
        self.setimagecanvas()
        l.addWidget(self.fname_label, 0)
        l.addLayout(imnav, 0)
        l.addWidget(self.canvas, 1)

        self.setLayout(l)

        self.ready = True
コード例 #12
0
import medimage as image

tps = image.image(
    "D:/postdoc/analyses/gpumcd_python/dicom/20181101 CTRT KNO-hals/1. UPI263538/2.25.117736802457958133832899838499337503296"
)
xdr = image.image("D:/postdoc/analyses/gpumcd_python/ct.xdr")

tps.saveas("D:/postdoc/analyses/gpumcd_python/TEST2.dcm")
xdr.saveas("D:/postdoc/analyses/gpumcd_python/TEST.dcm")
コード例 #13
0
BeamFrames[1] = gpumcd.BeamFrame(1)
BeamFrames[1].beamInfo[0].relativeWeight = 100
BeamFrames[1].beamInfo[0].isoCenter.x = 0
BeamFrames[1].beamInfo[0].isoCenter.y = 0
BeamFrames[1].beamInfo[0].isoCenter.z = 0
BeamFrames[1].beamInfo[0].collimatorAngle.first = 0
BeamFrames[1].beamInfo[0].collimatorAngle.second = 0
BeamFrames[1].beamInfo[0].couchAngle.first = 0
BeamFrames[1].beamInfo[0].couchAngle.second = 0
BeamFrames[1].beamInfo[0].gantryAngle.first = 90
BeamFrames[1].beamInfo[0].gantryAngle.second = 90
BeamFrames[1].beamInfo[0].fieldMax.first = 1
BeamFrames[1].beamInfo[0].fieldMax.second = 1
BeamFrames[1].beamInfo[0].fieldMin.first = -1
BeamFrames[1].beamInfo[0].fieldMin.second = -1

print('executing simulation...')

retval = Engine.execute_beamlets(*gpumcd.c_array_to_pointer(BeamFrames, True),
                                 planSettings)

print(retval)

dose = image.image(DimSize=[50, 50, 50],
                   ElementSpacing=[0.2, 0.2, 0.2],
                   dt='<f4')

Engine.get_dose(dose.get_ctypes_pointer_to_data())

dose.saveas(path.join(outputdir, 'dose.xdr'))
dose.saveas(path.join(outputdir, 'dose.mhd'))
コード例 #14
0
for dirpath, dirnames, filenames in os.walk(dumpdir):
    if len(filenames) > 0:
        firstfname = os.path.join(dirpath, filenames[0])
        try:  #catch any problematic dcm
            # test if in CT dir
            dicomobj = dicom.pydicom_object(firstfname)
            if dicomobj.valid and dicomobj.sopid is None:
                #we've got a CT on our hands boys, yeehaw
                dcms.append(firstfname)
                studies[dicomobj.studyid]['ct'] = dirpath
                if loadimages:
                    if dicomobj.PatientPosition != 'HFS':
                        NotImplementedError(
                            "Patient (Dose) is not in HFS position.")
                    studies[dicomobj.studyid]['ct_im'] = image.image(dirpath)
            elif dicomobj.valid and dicomobj.sopid is not None:
                #this aint no CT-dir, therefore, iterate over all files to see whats what.
                for filename in filenames:
                    fname = os.path.join(dirpath, filename)
                    dicomobj = dicom.pydicom_object(fname)

                    if dicomobj.valid:
                        dcms.append(fname)
                    else:
                        notdcms.append(fname)

                    #did we make a dict for this sopid already?
                    try:
                        studies[dicomobj.studyid][dicomobj.sopid]
                    except:
コード例 #15
0
ファイル: gpumcd.noise.py プロジェクト: brenthuisman/dosia
# parser.add_argument('--perc', action='store_true')
# opt = parser.parse_args()

dose_threshold = 50  #in percentage volume

rungpu = False

noiselevels = [0.2, 0.5, 1.0, 2.0, 5.0]
# noiselevels = [5.0]
realisations = 10
# realisations =1

if rungpu:
    for nlevel in noiselevels:
        for real in range(realisations):
            im_art = image.image(DimSize=[50, 50, 50],
                                 ElementSpacing=[2, 2, 2])
            im_art.fill_gaussian_noise(1000, nlevel)
            im_art.saveas(r'D:\postdoc\analyses\unc_study\artnoise' +
                          str(nlevel) + '_' + str(real) + '.xdr')

            outname = r'D:\postdoc\analyses\unc_study\gpunoise' + str(
                nlevel) + '_' + str(real) + '.xdr'
            runners.execute(
                r"D:\postdoc\analyses\unc_study\BeamletLibraryConsumer\x64\Release\BeamletLibraryConsumer.exe",
                "-o \"" + outname + "\" -p " + str(nlevel))

mask = image.image(r"D:\postdoc\analyses\unc_study\gpunoise0.2_0.xdr")
mask.tomask_atvolume(dose_threshold)

for nlevel in noiselevels:
    print(nlevel)