def save(self, viewInteractor): path = self.paths[viewInteractor] parentDirectory, name = os.path.split(path) interactors = viewInteractor.interactionWidget.interactors header = str(dicom.read_file(os.path.join(path, sorted(os.listdir( path))[viewInteractor.volumeView.currentSlice]))) # get data from inputs contrast = interactors[0].itemText(interactors[0].currentIndex()) orientation = interactors[1].itemText(interactors[1].currentIndex()) enhanced = interactors[2].isChecked() poorQuality = interactors[3].isChecked() review = interactors[4].isChecked() derived = interactors[5].isChecked() if derived: derivedType = interactors[6].itemText( interactors[6].currentIndex()) else: derivedType = "" comment = interactors[7].text() # get data from header seriesNumber = dcm.findSeriesNumber(header) sequence = ' '.join(dcm.findSequence(header)) vendor = dcm.findVendor(header) fieldStrength = dcm.findFieldStrength(header) echoTime, inversionTime, repetitionTime = dcm.findTimeParameters( header) # get data from folder structure directoryStem, date = os.path.split(self.workingDirectory) _, identifier = os.path.split(directoryStem) centerID, patientID = map(int, identifier.split('_')) # save and rename info = [str(seriesNumber), contrast, orientation] uniqueIdentifier = '_'.join(map(str, [centerID, patientID, date, seriesNumber])) if enhanced: info.insert(2, "CE") if derived: info.append(derivedType) newName = '_'.join(info) if newName == name: if self.database is not None: self.databaseCursor.execute( 'INSERT OR REPLACE INTO Series VALUES\ (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', (centerID, patientID, date, seriesNumber, contrast, enhanced, orientation, sequence, derived, derivedType, vendor, fieldStrength, echoTime, inversionTime, repetitionTime, poorQuality, review, comment, uniqueIdentifier)) self.database.commit() return newPath = os.path.join(parentDirectory, newName) if os.path.exists(newPath): review = True if self.database is not None: self.databaseCursor.execute( 'INSERT OR REPLACE INTO Series VALUES\ (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', (centerID, patientID, date, seriesNumber, contrast, enhanced, orientation, sequence, derived, derivedType, vendor, fieldStrength, echoTime, inversionTime, repetitionTime, poorQuality, review, comment, uniqueIdentifier)) self.database.commit() return else: os.rename(path, newPath) self.paths[viewInteractor] = newPath if self.database is not None: self.databaseCursor.execute( 'INSERT INTO Series VALUES\ (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', (centerID, patientID, date, seriesNumber, contrast, enhanced, orientation, sequence, derived, derivedType, vendor, fieldStrength, echoTime, inversionTime, repetitionTime, poorQuality, review, comment, uniqueIdentifier)) self.database.commit()
def setWorkingDirectory(self, workingDirectory): self.workingDirectory = os.path.abspath(workingDirectory) self.setWindowTitle(self.workingDirectory) self.multiView.removeAllViews() # working directory needs to contain DICOM folders for dataset in os.listdir(self.workingDirectory): datasetPath = os.path.join(self.workingDirectory, dataset) if len(os.listdir(datasetPath)) < 200: viewInteractor = view.VolumeViewInteraction( data=dcm.volumeFromDCMDirectory(datasetPath), interactionRows=2) else: viewInteractor = view.VolumeViewInteraction( data=dcm.LazyDCMVolume(datasetPath), interactionRows=2) # get header sliceNumber = viewInteractor.volumeView.currentSlice path = os.path.join(datasetPath, sorted(os.listdir(datasetPath))[sliceNumber]) header = str(dicom.read_file(path)) # set label searches = ["Series Description", "Sequence Name", "Protocol Name"] leftLabel = dcm.valueFromSearch(searches, header, True) for search in searches: if search in leftLabel.keys(): if leftLabel[search] != '': leftLabel = leftLabel[search] break else: leftLabel = '' viewInteractor.interactionWidget.setLeftLabel(leftLabel) # contrast combo box contrast = dcm.findContrast(header) sequence = dcm.findSequence(header) if contrast == "T2" and "FLAIR" in sequence: contrast = "FLAIR" viewInteractor.interactionWidget.addComboBox( sorted(dcm.allContrasts.keys() + ["UNKNOWN"]), contrast) # orientation combo box orientation = dcm.findOrientation(header) if orientation == "UNKNOWN": orientation = "ax" viewInteractor.interactionWidget.addComboBox( sorted(dcm.allOrientations)) # contrast agent checkbox enhanced = dcm.isContrastEnhanced(header) viewInteractor.interactionWidget.addCheckBox("CE", "left", enhanced, 1) # quality checkbox viewInteractor.interactionWidget.addCheckBox("LQ", "left") # review checkbox viewInteractor.interactionWidget.addCheckBox("RVW", "left") # derived checkbox isDerived = dcm.isDerived(header) viewInteractor.interactionWidget.addCheckBox("DRV", "left", isDerived[0], 1) viewInteractor.interactionWidget.interactors[-1].stateChanged.\ connect(self.onDerivedCheckBoxChanged) # view header button viewInteractor.interactionWidget.addButton("Header") viewInteractor.interactionWidget.buttons[-1].clicked.connect( self.onHeaderButtonClicked) # save button viewInteractor.interactionWidget.addButton("Save", 1) viewInteractor.interactionWidget.buttons[-1].clicked.connect( self.onSaveButtonClicked) # derivatives combobox derivativeOptions = [] for key in dcm.allDerivatives.keys(): derivativeOptions += dcm.allDerivatives[key] default = 0 if contrast in isDerived[1].keys(): if len(isDerived[1][contrast]) == 1: default = isDerived[1][contrast][0] elif "other" in isDerived[1].keys(): if len(isDerived[1]["other"]) == 1: default = isDerived[1]["other"][0] viewInteractor.interactionWidget.addComboBox(derivativeOptions, default, 1) if isDerived[0]: viewInteractor.interactionWidget.interactors[-1].show() else: viewInteractor.interactionWidget.interactors[-1].hide() # comment line edit viewInteractor.interactionWidget.addLineEdit(row=1) # add view self.paths[viewInteractor] = datasetPath self.multiView.addView(viewInteractor)