Package: edc-identifier
edc-identifierAdd research subject identifiers and other useful identifiers to your projectInstallationAdd to settings:INSTALLED_APPS=[...'edc_identifier.apps.AppConfig',...]Identifiers for research subjectsCreate subject identifiers.fromedc_identifier.subject_identifierimportSubjectIdentifiersubject_identifier=SubjectIdentifier(subject_type_name='subject',model='edc_example.enrollment',protocol='000',device_id='99',study_site='40')>>>subject_identifier.identifier'000-40990001-6'Maternal and Infant IdentifiersSee also,edc_pregnancymodel mixinsDeliveryMixin,BirthMixin.For example:fromedc_identifier.maternal_identifierimportMaternalIdentifiermaternal_identifier=MaternalIdentifier(subject_type_name='maternal',model='edc_example.enrollment',study_site='40',last_name='Carter')>>>maternal_identifier.identifier'000-40990001-6'Add infants>>>maternal_identifier.deliver(2,model='edc_example.maternallabdel')>>>[infant.identifierforinfantinmaternal_identifier.infants]['000-40990001-6-25','000-40990001-6-26']maternal_identifier.infantsis a list ofInfantIdentifierinstancesReload class:>>>maternal_identifier=MaternalIdentifier(identifier='000-40990001-6')>>>maternal_identifier.identifier'000-40990001-6'>>>[infant.identifierforinfantinmaternal_identifier.infants]['000-40990001-6-25','000-40990001-6-26']Only allocate an identifier to one infant of twins:>>>maternal_identifier.deliver(2,model='edc_example.maternallabdel',birth_orders='2')>>>[infant.identifierforinfantinmaternal_identifier.infants][None,'000-40990001-6-26']Of triplets, allocate identifiers to the 2nd and 3rd infants only:>>>maternal_identifier.deliver(3,model='edc_example.maternallabdel',birth_orders='2,3')>>>[infant.identifierforinfantinmaternal_identifier.infants][None,'000-40990001-6-37','000-40990001-6-38']Research subject identifier classes can create a Registered Subject instanceSee alsoedc_registrationSubjectIdentifierby default does not create aRegisteredSubjectinstance unlesscreate_registration=True.By default,MaternalIdentifierandInfantIdentifiercreateRegisteredSubjectinstances that can be updated with full details later with the Delivery and Birth models. Continuing from above:maternal_identifier=MaternalIdentifier(identifier='000-40990001-6')maternal_identifier.deliver(1,model='edc_example.maternallabdel',create_registration=True)# mother>>>RegisteredSubject.objects.get(subject_identifier='000-40990001-6')<RegisteredSubject'000-40990001-6'># infant is linked to the mother>>>RegisteredSubject.objects.get(linked_identifier='000-40990001-6')<RegisteredSubject'000-40990001-6-10'># infant>>>obj=RegisteredSubject.objects.get(subject_identifier='000-40990001-6-10')>>>obj.first_name'Baby1Carter'## generates a temp name until Birth form is added with complete information.>>>obj.relative_identifier'000-40990001-6'Subject type “Caps” are enforced by the research subject identifier classesSee alsoedc_protocolLimits on the number of identifiers that can be allocated per subject type are enforced when identifiers are created.edc_identifierreads the “caps” fromedc_protocol.apps.AppConfiglinking the subject type, e.g.subject, ormaternalorinfant, to the relevant cap and not allowing the number of allocated identifiers to exceed the cap.(Subject type “Caps” still working? needs to be verified)Numeric IdentifiersThe numeric identifier uses a check-digit and may have a separator if specified.fromedc_identifierimportNumericIdentifierclassMyIdentifier(NumericIdentifier):pass>>>id=MyIdentifier(None)>>>idMyIdentifier('00000000018')>>>next(id)'00000000026'>>>next(id)'00000000034'# add a separatorclassMyIdentifier(NumericIdentifier):identifier_pattern=r'^[0-9]{4}\-[0-9]{4}\-[0-9]{4}$'checkdigit_pattern=r'^\-[0-9]{1}$'separator='-'seed=['3200-0000-0000']>>>id=MyIdentifier(None)>>>idMyIdentifier('3200-0000-0001-1')>>>next(id)'3200-0000-0002-9'>>>next(id)'3200-0000-0003-7'# start from the last identifier, increment is immediate and automatic>>>id=MyIdentifier('3200-0000-3222-0')>>>idMyIdentifier('3200-0000-3223-8')Alphanumeric Identifiersfromedc_identifierimportAlphanumericIdentifierclassMyIdentifier(AlphanumericIdentifier):alpha_pattern=r'^[A-Z]{3}$'numeric_pattern=r'^[0-9]{4}$'seed=['AAA','0000']>>>id=MyIdentifier(None)>>>idMyIdentifier('AAA00015')Your identifier will starts with ‘AAA0001’ plus the checkdigit “5”. Subsequent calls to next increment like this:>>>print(next(id))AAA00023>>>print(next(id))AAA00031>>>print(next(id))AAA00049The identifier increments on the numeric sequence then the alpha:>>>id=MyIdentifier('AAA99991)>>>idMyIdentifier('AAB00013')>>>next(id)'AAB00021'>>>next(id)'AAB00039'>>>next(id)'AAB00047'>>>id=MyIdentifier('AAB99999')>>>idMyIdentifier('AAC00010')...Seegetresults-receivefor sample usage withsettingsand aHistorymodel.Short IdentifiersCreates a small identifier that is almost unique, for example, across 25 Edc devices in a community. We use these as sample requisition identifiers that are transcribed manually onto a tube from the Edc screen in a household. Once the sample is received at the local lab it is allocated a laboratory-wide unique specimen identifier.fromedc_identifierimportShortIdentifier>>>ShortIdentifier()ShortIdentifier('46ZZ2')Add a static prefix –prefix(2) + identifier(5):fromedc_identifierimportShortIdentifierclassMyIdentifier(ShortIdentifier):prefix_pattern=r'^[0-9]{2}$'>>>options={'prefix':22}>>>id=MyIdentifier(options=options)>>>idMyIdentifier('22UYMBT')>>>next(id)'22KM84G'Add a checkdigit –prefix(2) + identifier(5) + checkdigit(1):fromedc_identifierimportShortIdentifierclassMyIdentifier(ShortIdentifier):prefix_pattern=r'^[0-9]{2}$'checkdigit_pattern=r'^[0-9]{1}$'>>>options={'prefix':22}>>>id=MyIdentifier(options=options)>>>idMyIdentifier('223GF8A3')>>>next(id)'22DXVW23'We use this in edc-quota to get a confirmation code:fromedc_identifierimportShortIdentifierclassConfirmationCode(ShortIdentifier):identifier_type='confirmation'prefix_pattern=''>>>code=ConfirmationCode()>>>print(code)CAT33>>>next(code)3FU7DAdd more to the prefix, such as device code and community code.fromedc_identifier.short_identifierimportShortIdentifierclassRequisitionIdentifier(ShortIdentifier):identifier_type='requisition'prefix_pattern=r'^[0-9]{4}$'template='{device_id}{community_id}{random_string}'@propertydefoptions(self):if'prefix'notinself._options:self._options.update({'prefix':str(self._options.get('device_id'))+str(self._options.get('community_id'))})returnself._options>>>options={'device_id':22,'community_id':'12'}>>>id=RequisitionIdentifier(options=options)>>>idRequisitionIdentifier('22126MZXD')>>>next(id)'2212Y899C'… if you prefer not to use theIdentifierHistorymodel, for example, if you are filling in a model field onsave():frommy_app.modelsimportRequisitionclassRequisitionIdentifier(ShortIdentifier):identifier_type='requisition'requisition_model=Requisitiondefis_duplicate(self,identifier):try:self.requisition_model.get(requisition_identifier=identifier)returnTrueexceptself.requisition_model.DoesNotExist:passreturnFalsedefupdate_history(self):passBatch IdentifierTo have an identifier prefixed by the current date stamp:fromedc_identifier.batch_identifierimportBatchIdentifier>>>datetime.today().strftime('%Y%m%d)20150817>>>id=BatchIdentifier()>>>idBatchIdentifier('201508170001')>>>next(id)'201508170002'