Commit 59353812 authored by Mark Hymers's avatar Mark Hymers Committed by Joe Lyons
Browse files

Allow editing of files from GUI


Signed-off-by: Mark Hymers's avatarMark Hymers <mark.hymers@hankel.co.uk>
parent 97458f9c
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EditDialog</class>
<widget class="QDialog" name="EditDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>490</width>
<height>142</height>
</rect>
</property>
<property name="windowTitle">
<string>Edit Scan Details</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="filenameLabel">
<property name="text">
<string>Filename</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="partLabel">
<property name="text">
<string>Participant ID:</string>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="partOrig">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="scanLabel">
<property name="text">
<string>Scan ID:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="scanOrig">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="scanEdit"/>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="partEdit"/>
</item>
<item row="3" column="0" colspan="3">
<widget class="QLabel" name="label">
<property name="text">
<string>Note that Edit does not not rename the files on disk, it just edits the metadata</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>EditDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>EditDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
......@@ -19,14 +19,16 @@ import yias
from PyQt5 import uic
from PyQt5.QtWidgets import (QMainWindow, QApplication, QWidget, QAction,
QTableWidget, QTableWidgetItem, QVBoxLayout,
QAbstractItemView, QHeaderView, QMessageBox)
QAbstractItemView, QHeaderView, QMessageBox,
QDialog, QDialogButtonBox)
from PyQt5.QtGui import QIcon, QColor
from PyQt5.QtCore import pyqtSlot, QAbstractTableModel, Qt, QVariant
YIAS_PATH = dirname(yias.__file__)
Ui_MainWindow, QtBaseClass = uic.loadUiType(join(YIAS_PATH, 'gui', 'megtransfergui.ui'))
Ui_MainWindow, BaseClass_MainWindow = uic.loadUiType(join(YIAS_PATH, 'gui', 'megtransfergui.ui'))
Ui_EditDialog, BaseClass_EditDialog = uic.loadUiType(join(YIAS_PATH, 'gui', 'megeditdialog.ui'))
def find_scans(base_path):
raw_scans = set([basename(x) for x in glob(join(base_path, 'raw', '*.hdf5'))])
......@@ -174,6 +176,125 @@ class ScanModel(QAbstractTableModel):
return len(self.headers)
class EditDialog(QDialog, Ui_EditDialog):
def __init__(self, filenames):
QDialog.__init__(self)
Ui_EditDialog.__init__(self)
self.setupUi(self)
if not isinstance(filenames, list) or len(filenames) < 1:
raise Exception("No files passed")
self.filenames = filenames
self.load_data()
self.buttonBox.accepted.connect(self.apply)
#self.buttonBox.rejected.connect(self.cancel)
def load_data(self):
short_filenames = set()
partid = None
scanid = None
diff_partid = False
diff_scanid = False
for filename in self.filenames:
short_filenames.add(basename(filename))
with h5py.File(filename, 'r') as f:
try:
this_partid = f['subject'].attrs['id']
if partid is None:
partid = this_partid
else:
# Check for different IDs in different files
if partid != this_partid:
diff_partid = True
except KeyError:
pass
try:
this_scanid = f['config']['protocol'].attrs['protocol_name']
if scanid is None:
scanid = this_scanid
else:
# Check for different IDs in different files
if scanid != this_scanid:
diff_scanid = True
except KeyError:
pass
# Show any loading errors
errors = []
if partid is None:
partid = ''
errors.append('Participant ID not found in files')
if scanid is None:
scanid = ''
errors.append('Scan/Protocol ID not found in files')
if diff_partid:
errors.append('Multiple participant IDs found: only first one shown; all will be changed')
if diff_scanid:
errors.append('Multiple scan/protocol IDs found: only first one shown; all will be changed')
if len(errors) > 0:
QMessageBox.warning(self, "Warning", '\n'.join(errors))
self.partOrig.setText(partid)
self.partEdit.setText(partid)
self.scanOrig.setText(scanid)
self.scanEdit.setText(scanid)
self.filenameLabel.setText('\n'.join(sorted(list(short_filenames))))
def apply(self):
orig_partid = self.partOrig.text()
new_partid = self.partEdit.text()
partid_changed = orig_partid != new_partid
orig_scanid = self.scanOrig.text()
new_scanid = self.scanEdit.text()
scanid_changed = orig_scanid != new_scanid
if partid_changed or scanid_changed:
# Make changes
errors = []
for filename in self.filenames:
try:
with h5py.File(filename, 'r+') as f:
# Only change files where data is present otherwise
# we'd have to copy the whole structure; leave that to the
# transfer code which will do it if necessary
if partid_changed:
if 'subject' in f:
f['subject'].attrs['id'] = new_partid
if scanid_changed:
if 'config' in f and 'protocol' in f['config']:
f['config']['protocol'].attrs['protocol_name'] = new_scanid
except Exception as e:
errors.append('{}: {}'.format(filename, str(e)))
if len(errors) > 0:
QMessageBox.warning(self, "Warning - could not make all changes", '\n'.join(errors))
else:
QMessageBox.information(self, "Info", 'No changes made; not saving')
self.close()
class TransferApp(QMainWindow, Ui_MainWindow):
def __init__(self, base_path, upload_path):
QMainWindow.__init__(self)
......@@ -270,9 +391,22 @@ class TransferApp(QMainWindow, Ui_MainWindow):
QMessageBox.warning(self, "Edit", "To edit select only one row")
return
# TODO: Allow editing of patient ID and study ID
QMessageBox.warning(self, "Edit", "Editing not yet implemented")
filename = list(filenames)[0]
edit_files = []
raw_name = abspath(join(base_path, 'raw', filename))
if exists(raw_name):
edit_files.append(raw_name)
proc_name = abspath(join(base_path, 'processed', filename))
if exists(proc_name):
edit_files.append(proc_name)
dlg = EditDialog(edit_files)
dlg.exec_()
self.OnRefresh(None)
def OnUpload(self, evt):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment