6161
6262class TaskQC (base .QC ):
6363 """A class for computing task QC metrics"""
64- criteria = {"PASS" : 0.99 , "WARNING" : 0.95 , "FAIL" : 0 }
65- fcns_value2status = {'default' : lambda x : TaskQC ._thresholding (x ),
66- '_task_stimFreeze_delays' : lambda x : - 1 ,
67- '_task_response_stimFreeze_delays' : lambda x : - 1 ,
68- '_task_passed_trial_checks' : lambda x : - 1 ,
69- '_task_iti_delays' : lambda x : - 1 }
64+
65+ criteria = dict ()
66+ criteria ['default' ] = {"PASS" : 0.99 , "WARNING" : 0.90 , "FAIL" : 0 } # Note: WARNING was 0.95 prior to Aug 2022
67+ criteria ['_task_stimOff_itiIn_delays' ] = {"PASS" : 0.99 , "WARNING" : 0 }
68+ criteria ['_task_positive_feedback_stimOff_delays' ] = {"PASS" : 0.99 , "WARNING" : 0 }
69+ criteria ['_task_negative_feedback_stimOff_delays' ] = {"PASS" : 0.99 , "WARNING" : 0 }
70+ criteria ['_task_wheel_move_during_closed_loop' ] = {"PASS" : 0.99 , "WARNING" : 0 }
71+ criteria ['_task_response_stimFreeze_delays' ] = {"PASS" : 0.99 , "WARNING" : 0 }
72+ criteria ['_task_detected_wheel_moves' ] = {"PASS" : 0.99 , "WARNING" : 0 }
73+ criteria ['_task_trial_length' ] = {"PASS" : 0.99 , "WARNING" : 0 }
74+ criteria ['_task_goCue_delays' ] = {"PASS" : 0.99 , "WARNING" : 0 }
75+ criteria ['_task_errorCue_delays' ] = {"PASS" : 0.99 , "WARNING" : 0 }
76+ criteria ['_task_stimOn_delays' ] = {"PASS" : 0.99 , "WARNING" : 0 }
77+ criteria ['_task_stimOff_delays' ] = {"PASS" : 0.99 , "WARNING" : 0 }
78+ criteria ['_task_stimFreeze_delays' ] = {"PASS" : 0.99 , "WARNING" : 0 }
79+ criteria ['_task_iti_delays' ] = {"NOT_SET" : 0 }
80+ criteria ['_task_passed_trial_checks' ] = {"NOT_SET" : 0 }
7081
7182 @staticmethod
7283 def _thresholding (qc_value , thresholds = None ):
@@ -75,18 +86,25 @@ def _thresholding(qc_value, thresholds=None):
7586 :param qc_value: proportion of passing qcs, between 0 and 1
7687 :param thresholds: dictionary with keys 'PASS', 'WARNING', 'FAIL'
7788 (cf. TaskQC.criteria attribute)
78- :return: int where -1: NOT_SET, 0: FAIL , 1: WARNING, 2: PASS
89+ :return: int where -1: NOT_SET, 0: PASS , 1: WARNING, 2: FAIL
7990 """
8091 MAX_BOUND , MIN_BOUND = (1 , 0 )
8192 if not thresholds :
82- thresholds = TaskQC .criteria .copy ()
93+ thresholds = TaskQC .criteria [ 'default' ] .copy ()
8394 if qc_value is None or np .isnan (qc_value ):
8495 return int (- 1 )
8596 elif (qc_value > MAX_BOUND ) or (qc_value < MIN_BOUND ):
8697 raise ValueError ("Values out of bound" )
87- else :
88- passed = qc_value >= np .fromiter (thresholds .values (), dtype = float )
89- return int (np .argmax (passed ))
98+ if 'PASS' in thresholds .keys () and qc_value >= thresholds ['PASS' ]:
99+ return 0
100+ if 'WARNING' in thresholds .keys () and qc_value >= thresholds ['WARNING' ]:
101+ return 1
102+ if 'FAIL' in thresholds and qc_value >= thresholds ['FAIL' ]:
103+ return 2
104+ if 'NOT_SET' in thresholds and qc_value >= thresholds ['NOT_SET' ]:
105+ return - 1
106+ # if None of this applies, return 'NOT_SET'
107+ return - 1
90108
91109 def __init__ (self , session_path_or_eid , ** kwargs ):
92110 """
@@ -163,16 +181,15 @@ def compute_session_status_from_dict(results):
163181 :return: Overall session QC outcome as a string
164182 :return: A dict of QC tests and their outcomes
165183 """
166- v2status_fcns = TaskQC .fcns_value2status # the need to have this as a parameter may arise
167184 indices = np .zeros (len (results ), dtype = int )
168185 for i , k in enumerate (results ):
169- if k in v2status_fcns :
170- indices [i ] = v2status_fcns [k ]( results [k ])
186+ if k in TaskQC . criteria . keys () :
187+ indices [i ] = TaskQC . _thresholding ( results [k ], thresholds = TaskQC . criteria [k ])
171188 else :
172- indices [i ] = v2status_fcns [ 'default' ] (results [k ])
189+ indices [i ] = TaskQC . _thresholding (results [k ], thresholds = TaskQC . criteria [ 'default' ])
173190
174191 def key_map (x ):
175- return 'NOT_SET' if x < 0 else list (TaskQC .criteria .keys ())[x ]
192+ return 'NOT_SET' if x < 0 else list (TaskQC .criteria [ 'default' ] .keys ())[x ]
176193 # Criteria map is in order of severity so the max index is our overall QC outcome
177194 session_outcome = key_map (max (indices ))
178195 outcomes = dict (zip (results .keys (), map (key_map , indices )))
0 commit comments