def get_risk_factor_codes(self): ''' Get breast and ovarian cancer risk factor code and PRS from header lines. ''' bc_rfs = BCRiskFactors() oc_rfs = OCRiskFactors() bc_prs = oc_prs = None hgt = -1 for line in self.lines: try: parts = line.split('=', 1) rfnam = parts[0][2:].lower().strip() # risk factor name rfval = parts[1].strip() # risk factor value if rfnam == 'prs_oc': # get ovarian cancer prs oc_prs = self.get_prs(rfval) elif rfnam == 'prs_bc': # get breast cancer prs bc_prs = self.get_prs(rfval) else: # lookup breast/ovarian cancer risk factors if rfnam == 'height': hgt = float(rfval) bc_rfs.add_category(rfnam, rfval) oc_rfs.add_category(rfnam, rfval) except Exception: logger.error("CanRisk header format contains an error.") raise PedigreeFileError( "CanRisk header format contains an error in: " + line) return (BCRiskFactors.encode(bc_rfs.cats), OCRiskFactors.encode(oc_rfs.cats), hgt, bc_prs, oc_prs)
def test_BC_risk_factor_code(self): ''' Test the breast cancer risk factor code generated RFC = menarch category + parity category * 8 + first birth category * 40 + OC category * 200 + MHT category * 800 + BMI category * 3200 + alcohol category * 16000 + menopause category * 128000 + density category * 768000 + height category * 3840000 ''' bc_risk_categories = [0 for _k in BCRiskFactors.categories.keys()] bc_risk_categories[0] = bc.MenarcheAge.get_category('12') rfc = 3 self.assertEqual(BCRiskFactors.encode(bc_risk_categories), rfc) bc_risk_categories[1] = bc.Parity.get_category('1') rfc += 2 * 8 self.assertEqual(BCRiskFactors.encode(bc_risk_categories), rfc) bc_risk_categories[2] = bc.AgeOfFirstLiveBirth.get_category('31') rfc += 4 * 40 self.assertEqual(BCRiskFactors.encode(bc_risk_categories), rfc) bc_risk_categories[3] = bc.OralContraception.get_category('F:3') rfc += 2 * 200 self.assertEqual(BCRiskFactors.encode(bc_risk_categories), rfc) bc_risk_categories[4] = bc.MHT.get_category('C') rfc += 3 * 800 self.assertEqual(BCRiskFactors.encode(bc_risk_categories), rfc) bc_risk_categories[5] = bc.BMI.get_category(22.3) rfc += 2 * 3200 self.assertEqual(BCRiskFactors.encode(bc_risk_categories), rfc) bc_risk_categories[6] = bc.AlcoholIntake.get_category(0) rfc += 1 * 16000 self.assertEqual(BCRiskFactors.encode(bc_risk_categories), rfc) bc_risk_categories[7] = bc.AgeOfMenopause.get_category(52) rfc += 4 * 128000 self.assertEqual(BCRiskFactors.encode(bc_risk_categories), rfc) bc_risk_categories[8] = bc.MammographicDensity.get_category('1') rfc += 1 * 768000 self.assertEqual(BCRiskFactors.encode(bc_risk_categories), rfc) bc_risk_categories[9] = bc.Height.get_category('174.21') rfc += 5 * 3840000 self.assertEqual(BCRiskFactors.encode(bc_risk_categories), rfc)
def test_risk_factors_inconsistent(self): ''' Test inconsistent risk factors, e.g. age of first birth specified with parity unobserved. ''' data = { 'mut_freq': 'UK', 'cancer_rates': 'UK', 'pedigree_data': self.pedigree_data, 'user_id': 'test_XXX', 'risk_factor_code': BCRiskFactors.encode([0, 0, 1, 0, 0, 0, 0, 0, 0, 0]) } self.client.credentials(HTTP_AUTHORIZATION='Token ' + BwsRiskFactors.token.key) BwsRiskFactors.user.user_permissions.add( Permission.objects.get(name='Can risk')) response = self.client.post(BwsRiskFactors.url, data, format='multipart', HTTP_ACCEPT="application/json") self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) content = json.loads(force_text(response.content)) self.assertTrue('Model Error' in content)
def handle(self, *args, **options): risk_factor_code = options['factor'] categories = BCRiskFactors.decode(risk_factor_code) for idx, cat in enumerate(categories): name = BCRiskFactors.risk_factors[idx].__name__ print(name + " idx: " + str(cat) + " category: " + BCRiskFactors.risk_factors[idx].cats[cat])
class OwsExtendedInputSerializer(OwsInputSerializer): """ Other input parameters. """ risk_factor_code = serializers.IntegerField( max_value=BCRiskFactors.get_max_factor(), min_value=0, default=0) prs = serializers.JSONField(required=False)
def test_bounds_exceeded_u_decoding(self): ''' Test that an error is raised when a risk is above bounds - decoding ''' max_plus_1 = BCRiskFactors.encode( list(BCRiskFactors.categories.values())) + 1 self.assertRaises(RiskFactorError, BCRiskFactors.decode, max_plus_1)
def test_round_trip(self): ''' Test encoding of risk categories and decoding returns same risk categories. ''' category1 = list(BCRiskFactors.categories.values()) category2 = BCRiskFactors.decode(BCRiskFactors.encode(category1)) self.assertListEqual(category1, category2, "round trip encode/decode")