Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 53 additions & 28 deletions bin/Xnat_tools/XnatSwitchProcessStatus
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Change assessor job/quality control status
Created on Jan 24, 2013
Edited on February 19, 2015
Edited on February 22, 2017
Edited on March 13, 2026 - Added Subject Level Assessor

@author: Benjamin Yvernault, Electrical Engineering, Vanderbilt University
'''
Expand Down Expand Up @@ -94,7 +95,7 @@ def edit_list_procs(proctypes, has_fs_datatypes=False):
return proctypes


def get_assessor_dict(xnat, assessor_label, has_fs_datatypes):
def get_assessor_dict(xnat, assessor_label, sub_level, has_fs_datatypes):
"""
Function to convert assessor label into a dictionary

Expand All @@ -104,11 +105,22 @@ def get_assessor_dict(xnat, assessor_label, has_fs_datatypes):
"""
assessor = dict()
labels = assessor_label.split('-x-')
if len(labels) < 4 or len(labels) > 5:
if sub_level and (len(labels) == 4):
assessor['project_id'] = labels[0]
assessor['subject_label'] = labels[1]
assessor['proctype'] = labels[2]
assessor['label'] = assessor_label
assessor['xsiType'] = 'proc:subjGenProcData'

assr_obj = xnat.select_sgp_assessor(
labels[0], labels[1], assessor_label
)

if (len(labels) < 4 or len(labels) > 5) and not sub_level:
err = 'Wrong assessor label: "%s".\n The label should look \
like: project-x-subject-x-session(-x-scan)-x-proctype.'
return None, err % assessor_label
else:
elif not sub_level:
assessor['project_id'] = labels[0]
assessor['subject_label'] = labels[1]
assessor['session_label'] = labels[2]
Expand All @@ -123,14 +135,15 @@ like: project-x-subject-x-session(-x-scan)-x-proctype.'
# get procstatus and qcstatus:
assr_obj = xnat.select_assessor(
labels[0], labels[1], labels[2], assessor['label'])
if not assr_obj.exists():
err = 'Assessor "%s" does not exist on XNAT.'
return None, err % assessor_label
status = assr_obj.attrs.get('%s/procstatus' % assessor['xsiType'])
qcstatus = assr_obj.attrs.get('%s/validation/status'
% assessor['xsiType'])
assessor['procstatus'] = status
assessor['qcstatus'] = qcstatus

if not assr_obj.exists():
err = 'Assessor "%s" does not exist on XNAT.'
return None, err % assessor_label
status = assr_obj.attrs.get('%s/procstatus' % assessor['xsiType'])
qcstatus = assr_obj.attrs.get('%s/validation/status'
% assessor['xsiType'])
assessor['procstatus'] = status
assessor['qcstatus'] = qcstatus

return assessor, None

Expand All @@ -149,7 +162,7 @@ def get_assessors(xnat, args, has_fs_datatypes=False):
projects = list()

if args.select:
assessor, err = get_assessor_dict(xnat, args.select, has_fs_datatypes)
assessor, err = get_assessor_dict(xnat, args.select, args.sublev, has_fs_datatypes)
if err:
err = 'Argument --select not set properly.\nTraceback: %s' % err
raise XnatToolsUserError(__exe__, err)
Expand All @@ -163,7 +176,7 @@ def get_assessors(xnat, args, has_fs_datatypes=False):
for line in f_read:
assr_label = line.strip().split('\n')[0]
assessor, err = get_assessor_dict(
xnat, assr_label, has_fs_datatypes)
xnat, assr_label, args.sublev, has_fs_datatypes)
if err:
err = 'Argument --txtfile some assessors label are not \
set properly.\nTraceback: %s' % err
Expand Down Expand Up @@ -399,7 +412,7 @@ def set_qc_status(assessor_obj, status, username='NULL',
% (assessor_obj.label(), status))


def set_proc_status(assessor_obj, status, username='NULL',
def set_proc_status(assessor_obj, args, status, username='NULL',
xsitype=XnatUtils.DEFAULT_DATATYPE):
"""
Function to set the proc status and remove other information for an
Expand All @@ -412,7 +425,11 @@ def set_proc_status(assessor_obj, status, username='NULL',
:param xsitype: datatype to change status
:return: None
"""
if args.sublev:
xsitype = 'proc:subjGenProcData'

assessor_obj.attrs.set(xsitype + '/procstatus', status)

if status == task.NEED_INPUTS or status == task.NEED_TO_RUN:
assessor_obj.attrs.mset({xsitype + '/validation/status': 'Job Pending',
xsitype + '/jobid': 'NULL',
Expand All @@ -425,12 +442,12 @@ def set_proc_status(assessor_obj, status, username='NULL',
xsitype + '/validation/notes': 'NULL',
xsitype + '/validation/method': 'NULL'})
sys.stdout.write(' - Job Status on Assessor %s changed to %s\n'
% (assessor_obj.label(), status))
% (assessor_obj.label(), status))
if status == task.COMPLETE:
set_qc_status(assessor_obj, task.NEEDS_QA, username, xsitype=xsitype)



def set_need_inputs_proctype(xnat, assessor, need_inputs, full_regex=False):
def set_need_inputs_proctype(xnat, args, assessor, need_inputs, full_regex=False):
"""
Function to set to NEED_INPUTS the linked assessors.

Expand All @@ -453,10 +470,10 @@ def set_need_inputs_proctype(xnat, assessor, need_inputs, full_regex=False):
assessor_obj = xnat.select_assessor(a_linked_dict['label'])
if assessor_obj.exists():
if a_linked_dict['xsiType'] == XnatUtils.DEFAULT_FS_DATATYPE:
set_proc_status(assessor_obj, task.NEED_INPUTS,
set_proc_status(assessor_obj, args, task.NEED_INPUTS,
xsitype=XnatUtils.DEFAULT_FS_DATATYPE)
else:
set_proc_status(assessor_obj, task.NEED_INPUTS)
set_proc_status(assessor_obj, args, task.NEED_INPUTS)

li_assessors = xnat.get_assessor_out_resources(
a_linked_dict['project_id'],
Expand Down Expand Up @@ -527,22 +544,23 @@ assessors.')
raise XnatToolsUserError(__exe__, err)
print('INFO: Switching assessors status:')
nb = str(len(assessors))

sorted_list = sorted(assessors, key=lambda k: k['label'])
for ind, assessor in enumerate(sorted_list):
sys.stdout.write(_format % (str(ind + 1), nb, assessor['label']))
sys.stdout.flush()

set_status_assessor(xnat, assessor, status, delete_resources,
set_status_assessor(xnat, args, assessor, status, delete_resources,
args.qcstatus)

if ni_proctypes:
msg = ' +Setting assessors status to %s that are linked to %s\n'
sys.stdout.write(msg % (task.NEED_INPUTS, assessor['label']))
set_need_inputs_proctype(xnat, assessor, ni_proctypes,
args.full_regex)
set_need_inputs_proctype(xnat, args, assessor, ni_proctypes,
args.full_regex)


def set_status_assessor(xnat, assessor, status,
def set_status_assessor(xnat, args, assessor, status,
delete_resources=False, qcstatus=False):
"""
Function to set the status for an assessor pyxnat obj
Expand All @@ -555,8 +573,14 @@ def set_status_assessor(xnat, assessor, status,
:return: None
"""
labels = assessor['label'].split('-x-')
assessor_obj = xnat.select_assessor(
labels[0], labels[1], labels[2], assessor['label'])
# Session level
if not args.sublev:
assessor_obj = xnat.select_assessor(
labels[0], labels[1], labels[2], assessor['label'])
# Subject level
else:
assessor_obj = xnat.select_sgp_assessor(
labels[0], labels[1], assessor['label'])

if qcstatus:
if assessor['xsiType'] == XnatUtils.DEFAULT_FS_DATATYPE:
Expand All @@ -566,10 +590,10 @@ def set_status_assessor(xnat, assessor, status,
set_qc_status(assessor_obj, status, username=xnat.user)
else:
if assessor['xsiType'] == XnatUtils.DEFAULT_FS_DATATYPE:
set_proc_status(assessor_obj, status, username=xnat.user,
set_proc_status(assessor_obj, args, status, username=xnat.user,
xsitype=XnatUtils.DEFAULT_FS_DATATYPE)
else:
set_proc_status(assessor_obj, status, username=xnat.user)
set_proc_status(assessor_obj, args, status, username=xnat.user)

if delete_resources:
if 'resources' in list(assessor.keys()):
Expand Down Expand Up @@ -688,10 +712,11 @@ assessors that have been set to NO_DATA."
status to NEED_INPUTS from JOB_FAILED and delete previous resources.'
parser.add_argument("--rerundiskq", dest="rerundiskq", action='store_true',
help=_h)
_h = 'Flag marking changed assessor as subject level'
parser.add_argument("--sublev", dest="sublev", action='store_true', help=_h)
return parser


if __name__ == '__main__':
utils.run_tool(__exe__, __description__, add_to_parser, __purpose__,
run_xnat_switch_process_status)

Loading