Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 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
Esempio n. 4
0
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]
Esempio n. 5
0
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
Esempio n. 6
0
    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'))
Esempio n. 7
0
    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)
Esempio n. 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
Esempio n. 9
0
	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))
Esempio n. 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
Esempio n. 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
Esempio n. 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")
Esempio n. 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'))
Esempio n. 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:
Esempio n. 15
0
# 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)