Skip to content

Commit 6fc159f

Browse files
authored
Dom fix controls (#160)
* fixed #158 and #159
1 parent 8449012 commit 6fc159f

File tree

2 files changed

+87
-1
lines changed

2 files changed

+87
-1
lines changed

ptmd/lib/validator/core.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class VerticalValidator:
170170

171171
def __init__(self, definitions: dict, validator: ExcelValidator) -> None:
172172
""" The validator constructor. """
173-
self.controls_keys: list[str] = ['CONTROL (DMSO)', 'CONTROL (WATER)']
173+
self.controls_keys: list[str] = ['CONTROL (DMSO)', 'CONTROL (Water)']
174174
self.validator: ExcelValidator = validator
175175
self.timepoints: list = definitions['timepoints']
176176
self.replicates: int = definitions['replicates']
@@ -263,6 +263,10 @@ def validate(self) -> None:
263263
if compound_name == 'EXTRACTION BLANK':
264264
break
265265

266+
if compound_name in self.controls_keys:
267+
self.validate_controls(compound_val)
268+
break
269+
266270
for timepoint in compound_val['replicates']:
267271
if timepoint in self.timepoints:
268272
replicate: int = compound_val['replicates'][timepoint]
@@ -283,3 +287,27 @@ def validate(self) -> None:
283287
elif timepoint < len(self.timepoints):
284288
message = f"Timepoint {replicate} is missing {len(self.timepoints) - timepoint} replicate(s)."
285289
self.validator.add_error(compound_name, message, 'replicates')
290+
291+
def validate_controls(self, compound_values: dict) -> None:
292+
""" Validates the controls points against the general information. Verify the number of replicates and
293+
timepoints.
294+
295+
:param compound_values: The compound values to validate.
296+
"""
297+
message: str
298+
for timepoint, replicate in compound_values['replicates'].items():
299+
if replicate < self.controls:
300+
message = f"Control at timepoint {timepoint} is missing {self.controls - replicate} replicate(s)."
301+
self.validator.add_error('Control', message, 'replicates')
302+
elif replicate > self.controls:
303+
message = f"Control at timepoint {timepoint} has too many replicates ({replicate})."
304+
self.validator.add_error('Control', message, 'replicates')
305+
306+
for replicate, timepoint in compound_values['timepoints'].items():
307+
if timepoint > len(self.timepoints):
308+
message = f"Timepoint {replicate} has greater number of controls {timepoint} " \
309+
f"than expected ({self.controls})."
310+
self.validator.add_error('Control', message, 'timepoints')
311+
elif timepoint < len(self.timepoints):
312+
message = f"Timepoint {replicate} is missing {len(self.timepoints) - timepoint} control(s)."
313+
self.validator.add_error('Control', message, 'timepoints')

tests/test_lib/test_validator/test_core.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,61 @@ def test_validate_failed_box_id(self):
287287
}
288288
self.assertFalse(validator.report['valid'])
289289
self.assertEqual(validator.report['errors'], expected_error)
290+
291+
def test_validate_failed_too_many_controls(self):
292+
validator = MockValidator()
293+
self.general_information['controls'] = 1
294+
self.general_information['timepoints'] = [4]
295+
vertical_validator = VerticalValidator(self.general_information, validator)
296+
vertical_validator.add_node({
297+
'data': {
298+
'compound_name': 'CONTROL (Water)',
299+
'replicate': 1,
300+
'timepoint_(hours)': 4,
301+
'dose_code': 0,
302+
'box_id': 'Box1',
303+
'box_column': 1,
304+
'box_row': 'A',
305+
'collection_order': 1
306+
},
307+
'label': 'CP1'
308+
})
309+
vertical_validator.add_node({
310+
'data': {
311+
'compound_name': 'CONTROL (Water)',
312+
'replicate': 2,
313+
'timepoint_(hours)': 4,
314+
'dose_code': 0,
315+
'box_id': 'Box1',
316+
'box_column': 1,
317+
'box_row': 'B',
318+
'collection_order': 2
319+
},
320+
'label': 'CP2'
321+
})
322+
vertical_validator.validate()
323+
errors = validator.report['errors']
324+
self.assertEqual(errors['CP2'][0]['message'], 'Control 2 is greater than the number of controls 1.')
325+
self.assertEqual(errors['Control'][0]['message'], 'Control at timepoint 4 has too many replicates (2).')
326+
327+
def test_validate_failed_not_enough_controls(self):
328+
validator = MockValidator()
329+
self.general_information['controls'] = 1
330+
self.general_information['timepoints'] = [4, 12]
331+
vertical_validator = VerticalValidator(self.general_information, validator)
332+
vertical_validator.add_node({
333+
'data': {
334+
'compound_name': 'CONTROL (Water)',
335+
'replicate': 1,
336+
'timepoint_(hours)': 4,
337+
'dose_code': 0,
338+
'box_id': 'Box1',
339+
'box_column': 1,
340+
'box_row': 'A',
341+
'collection_order': 1
342+
},
343+
'label': 'CP1'
344+
})
345+
vertical_validator.validate()
346+
errors = validator.report['errors']
347+
self.assertEqual(errors['Control'][0]['message'], 'Timepoint 1 is missing 1 control(s).')

0 commit comments

Comments
 (0)