diff --git a/CHANGELOG b/CHANGELOG index c45d1d0..d7491eb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,26 @@ Changelog ========= +## [1.6.0] - 2020-12-15 +### Summary +This change was implemented after getting feedback from OHSU. Some ADRCs do +not have the optional forms like A2 or A3 in their REDCap project at all, since +they will not be used for that center. NACCulator used to run with the +requirement that all forms be present in a REDCap project, whether they were +optional or not. This change is very similar to the one made previously that +made the CLS, Z1, and C1 forms optional for the REDCap csv input. +I also fixed a bug in the FTLD FVP builder that would cause it to look for the +IVP Z1X form. + +### added + * Make optional forms for FTLD optional in REDCap project + * Make all optional UDS3 forms optional in REDCap project + + +### changed +* Fix cruft in FVP builder (Samantha Emerson) +* Update README to account for cappy install complication +* Fix ftld fvp builder to take followup Z1X instead of initial + ## [1.5.0] - 2020-12-08 ### Summary diff --git a/README.md b/README.md index f863219..295ca7b 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ HOW TO Convert from REDCap to NACC To install NACCulator, run: + $ python3 -m pip install git+https://github.com/ctsit/cappy.git@2.0.0#egg=cappy-2.0.0 $ pip3 install git+https://github.com/ctsit/nacculator.git Once the project data is exported from REDCap to the CSV file `data.csv`, run: diff --git a/nacc/ftld/fvp/builder.py b/nacc/ftld/fvp/builder.py index 4a69ca1..2e0166c 100644 --- a/nacc/ftld/fvp/builder.py +++ b/nacc/ftld/fvp/builder.py @@ -27,20 +27,32 @@ def build_ftld_fvp_form(record: dict, err=sys.stderr): # Forms B3F, B9F, C1F, C2F, C3F, E2F, and E3F are REQUIRED. # Forms A3A, C4F, C5F, and C6F are OPTIONAL and must be specifically # marked as present for nacculator to process them - if record['ivp_z1x_complete'] in ['1', '2']: - if record['ftda3afs'] == '1': - add_a3a(record, packet) + if record['fvp_z1x_complete'] in ['1', '2']: + try: + if record['fu_ftda3afs'] == '1': + add_a3a(record, packet) + except KeyError: + pass add_b3f(record, packet) add_b9f(record, packet) add_c1f(record, packet) add_c2f(record, packet) add_c3f(record, packet) - if record['ftdc4fs'] == '1': - add_c4f(record, packet) - if record['ftdc5fs'] == '1': - add_c5f(record, packet) - if record['ftdc6fs'] == '1': - add_c6f(record, packet) + try: + if record['fu_ftdc4fs'] == '1': + add_c4f(record, packet) + except KeyError: + pass + try: + if record['fu_ftdc5fs'] == '1': + add_c5f(record, packet) + except KeyError: + pass + try: + if record['fu_ftdc6fs'] == '1': + add_c6f(record, packet) + except KeyError: + pass else: print("ptid " + str(record['ptid']) + ": No Z1X form found.", file=err) diff --git a/nacc/ftld/ivp/builder.py b/nacc/ftld/ivp/builder.py index b04ec96..6424265 100644 --- a/nacc/ftld/ivp/builder.py +++ b/nacc/ftld/ivp/builder.py @@ -28,19 +28,31 @@ def build_ftld_ivp_form(record: dict, err=sys.stderr): # Forms A3A, C4F, C5F, and C6F are OPTIONAL and must be specifically # marked as present for nacculator to process them if record['ivp_z1x_complete'] in ['1', '2']: - if record['ftda3afs'] == '1': - add_a3a(record, packet) + try: + if record['ftda3afs'] == '1': + add_a3a(record, packet) + except KeyError: + pass add_b3f(record, packet) add_b9f(record, packet) add_c1f(record, packet) add_c2f(record, packet) add_c3f(record, packet) - if record['ftdc4fs'] == '1': - add_c4f(record, packet) - if record['ftdc5fs'] == '1': - add_c5f(record, packet) - if record['ftdc6fs'] == '1': - add_c6f(record, packet) + try: + if record['ftdc4fs'] == '1': + add_c4f(record, packet) + except KeyError: + pass + try: + if record['ftdc5fs'] == '1': + add_c5f(record, packet) + except KeyError: + pass + try: + if record['ftdc6fs'] == '1': + add_c6f(record, packet) + except KeyError: + pass else: print("ptid " + str(record['ptid']) + ": No Z1X form found.", file=err) diff --git a/nacc/redcap2nacc.py b/nacc/redcap2nacc.py index 68c47cc..066acaa 100755 --- a/nacc/redcap2nacc.py +++ b/nacc/redcap2nacc.py @@ -198,6 +198,7 @@ def check_redcap_event(options, record) -> bool: form_match_z1 = record['ivp_z1_complete'] except KeyError: form_match_z1 = '' + record['ivp_z1_complete'] = '' form_match_z1x = record['ivp_z1x_complete'] if form_match_z1 in ['0', ''] and form_match_z1x in ['0', '']: return False @@ -207,6 +208,7 @@ def check_redcap_event(options, record) -> bool: form_match_z1 = record['fvp_z1_complete'] except KeyError: form_match_z1 = '' + record['ivp_z1_complete'] = '' form_match_z1x = record['fvp_z1x_complete'] if form_match_z1 in ['0', ''] and form_match_z1x in ['0', '']: return False diff --git a/nacc/uds3/fvp/builder.py b/nacc/uds3/fvp/builder.py index 1e95f79..52a8224 100644 --- a/nacc/uds3/fvp/builder.py +++ b/nacc/uds3/fvp/builder.py @@ -19,37 +19,79 @@ def build_uds3_fvp_form(record, err=sys.stderr): add_z1_or_z1x(record, packet) add_a1(record, packet) if record['fvp_z1x_complete'] in ['1', '2']: - if record['fu_a2sub'] == '1': - add_a2(record, packet) - if record['fu_a3sub'] == '1': - add_a3(record, packet) - if record['fu_a4sub'] == '1': - add_a4(record, packet) - if record['fu_b1sub'] == '1': - add_b1(record, packet) + try: + if record['fu_a2sub'] == '1': + add_a2(record, packet) + except KeyError: + pass + try: + if record['fu_a3sub'] == '1': + add_a3(record, packet) + except KeyError: + pass + try: + if record['fu_a4sub'] == '1': + add_a4(record, packet) + except KeyError: + pass + try: + if record['fu_b1sub'] == '1': + add_b1(record, packet) + except KeyError: + pass add_b4(record, packet) - if record['fu_b5sub'] == '1': - add_b5(record, packet) - if record['fu_b6sub'] == '1': - add_b6(record, packet) - if record['fu_b7sub'] == '1': - add_b7(record, packet) + try: + if record['fu_b5sub'] == '1': + add_b5(record, packet) + except KeyError: + pass + try: + if record['fu_b6sub'] == '1': + add_b6(record, packet) + except KeyError: + pass + try: + if record['fu_b7sub'] == '1': + add_b7(record, packet) + except KeyError: + pass elif record['fvp_z1_complete'] in ['1', '2']: - if record['fu_a2_sub'] == '1': - add_a2(record, packet) - if record['fu_a3_sub'] == '1': - add_a3(record, packet) - if record['fu_a4_sub'] == '1': - add_a4(record, packet) - if record['fu_b1_sub'] == '1': - add_b1(record, packet) + try: + if record['fu_a2_sub'] == '1': + add_a2(record, packet) + except KeyError: + pass + try: + if record['fu_a3_sub'] == '1': + add_a3(record, packet) + except KeyError: + pass + try: + if record['fu_a4_sub'] == '1': + add_a4(record, packet) + except KeyError: + pass + try: + if record['fu_b1_sub'] == '1': + add_b1(record, packet) + except KeyError: + pass add_b4(record, packet) - if record['fu_b5_sub'] == '1': - add_b5(record, packet) - if record['fu_b6_sub'] == '1': - add_b6(record, packet) - if record['fu_b7_sub'] == '1': - add_b7(record, packet) + try: + if record['fu_b5_sub'] == '1': + add_b5(record, packet) + except KeyError: + pass + try: + if record['fu_b6_sub'] == '1': + add_b6(record, packet) + except KeyError: + pass + try: + if record['fu_b7_sub'] == '1': + add_b7(record, packet) + except KeyError: + pass else: print("ptid " + str(record['ptid']) + ": No Z1X or Z1 form found.", file=err) diff --git a/nacc/uds3/ivp/builder.py b/nacc/uds3/ivp/builder.py index 3dc977a..f433595 100644 --- a/nacc/uds3/ivp/builder.py +++ b/nacc/uds3/ivp/builder.py @@ -19,39 +19,81 @@ def build_uds3_ivp_form(record, err=sys.stderr): add_z1_or_z1x(record, packet) add_a1(record, packet) if record['ivp_z1x_complete'] in ['1', '2']: - if record['a2sub'] == '1': - add_a2(record, packet) - if record['a3sub'] == '1': - add_a3(record, packet) - if record['a4sub'] == '1': - add_a4(record, packet) + try: + if record['a2sub'] == '1': + add_a2(record, packet) + except KeyError: + pass + try: + if record['a3sub'] == '1': + add_a3(record, packet) + except KeyError: + pass + try: + if record['a4sub'] == '1': + add_a4(record, packet) + except KeyError: + pass add_a5(record, packet) - if record['b1sub'] == '1': - add_b1(record, packet) + try: + if record['b1sub'] == '1': + add_b1(record, packet) + except KeyError: + pass add_b4(record, packet) - if record['b5sub'] == '1': - add_b5(record, packet) - if record['b6sub'] == '1': - add_b6(record, packet) - if record['b7sub'] == '1': - add_b7(record, packet) + try: + if record['b5sub'] == '1': + add_b5(record, packet) + except KeyError: + pass + try: + if record['b6sub'] == '1': + add_b6(record, packet) + except KeyError: + pass + try: + if record['b7sub'] == '1': + add_b7(record, packet) + except KeyError: + pass elif record['ivp_z1_complete'] in ['1', '2']: - if record['a2_sub'] == '1': - add_a2(record, packet) - if record['a3_sub'] == '1': - add_a3(record, packet) - if record['a4_sub'] == '1': - add_a4(record, packet) + try: + if record['a2_sub'] == '1': + add_a2(record, packet) + except KeyError: + pass + try: + if record['a3_sub'] == '1': + add_a3(record, packet) + except KeyError: + pass + try: + if record['a4_sub'] == '1': + add_a4(record, packet) + except KeyError: + pass add_a5(record, packet) - if record['b1_sub'] == '1': - add_b1(record, packet) + try: + if record['b1_sub'] == '1': + add_b1(record, packet) + except KeyError: + pass add_b4(record, packet) - if record['b5_sub'] == '1': - add_b5(record, packet) - if record['b6_sub'] == '1': - add_b6(record, packet) - if record['b7_sub'] == '1': - add_b7(record, packet) + try: + if record['b5_sub'] == '1': + add_b5(record, packet) + except KeyError: + pass + try: + if record['b6_sub'] == '1': + add_b6(record, packet) + except KeyError: + pass + try: + if record['b7_sub'] == '1': + add_b7(record, packet) + except KeyError: + pass else: print("ptid " + str(record['ptid']) + ": No Z1X or Z1 form found.", file=err) diff --git a/setup.py b/setup.py index 8dc73df..11ce025 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ from setuptools import setup, find_packages -VERSION = "1.5.0" +VERSION = "1.6.0" setup( name="nacculator",