oship-dev team mailing list archive
-
oship-dev team
-
Mailing list archive
-
Message #01287
[Merge] lp:~oship-dev/oship/repkg into lp:oship
Tim Cook has proposed merging lp:~oship-dev/oship/repkg into lp:oship.
Requested reviews:
OSHIP Development Team (oship-dev)
Moved oship/rm to oship/rm/openehr
The attached diff has been truncated due to its size.
--
https://code.launchpad.net/~oship-dev/oship/repkg/+merge/31921
Your team OSHIP Development Team is requested to review the proposed merge of lp:~oship-dev/oship/repkg into lp:oship.
=== removed file 'src/oship/km/mlhim/clinical/cluster/device_v1.py'
--- src/oship/km/mlhim/clinical/cluster/device_v1.py 2010-08-02 02:06:04 +0000
+++ src/oship/km/mlhim/clinical/cluster/device_v1.py 1970-01-01 00:00:00 +0000
@@ -1,219 +0,0 @@
-#This file was created with atbldr module from the OSHIP project.
-#Its quality is not guaranteed and will need hand editing, especially the definition section before use.
-
-import grok
-import datetime
-from zope.i18nmessageid import MessageFactory
-from oship.openehr.archetype import *
-from oship.openehr.demographic import *
-from oship.openehr.extract import *
-from oship.openehr.integration import *
-from oship.openehr.openehrprofile import *
-from oship.openehr.sm import *
-
-_ = MessageFactory('oship')
-
-class DeviceV1(Archetype):
-
- grok.implements(IArchetype)
-
- def __init__(self):
- self.adlVersion =u'1.4'
- self.archetypeId = ArchetypeId(ObjectId(u'openEHR-EHR-CLUSTER.device.v1'))
- self.concept = u'at0000'
- self.parentArchetypeId=ArchetypeId(ObjectId(u''))
-
- # Create the description components.
- self.originalLanguage=CodePhrase(u'ISO_639-1',u'en')
- self.translationDetails=None # needs to be completed in atbldr
- self.description=[u'original_author', u'name', u'Sam Heard', u'organisation', u'Ocean Informatics', u'email', u'sam.heard@xxxxxxxxxxxxxxxxxxxx', u'date', u'19/03/2008', u'details', u'en', u'language', u'_ISO_639-1::en_', u'purpose', u'Record details of devices use in clinical care', u'use', u'Use to record the details pertaining to the device that is used to record clinical details. This is likely to be as a nested archetype as part of a Protocol.', u'keywords', u'Device', u'Machine', u'Tool', u'misuse', u'', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'lifecycle_state', u'AuthorDraft', u'other_contributors', u'other_details', u'references', u''] # needs to be completed in atbldr
- self.revisionHistory=None # needs to be completed in atbldr
- self.isControlled=False # needs to be completed in atbldr
-
- # Create the ontology.
-
- # Terminologies Available Section
- termAvail=[]
- # Term Code Section (note that there is a bug in atbldr that always cutsoff the last description of termCodes)
- termCodes={u'en':{u'at0000':[_(u'text'),_(u'Device details'),_(u'description'),_(u'The details of the device used')],\
- u'at0001':[_(u'text'),_(u'Name'),_(u'description'),_(u'The name of the device')],\
- u'at0002':[_(u'text'),_(u'Description'),_(u'description'),_(u'Description of the device')],\
- u'at0003':[_(u'text'),_(u'Manufacturer'),_(u'description'),_(u'The name of the manufacturer')],\
- u'at0004':[_(u'text'),_(u'Manufacturer details'),_(u'description'),_(u'Information about the manufacture of the device')],\
- u'at0005':[_(u'text'),_(u'Model'),_(u'description'),_(u'The model of the device')],\
- u'at0006':[_(u'text'),_(u'Serial number'),_(u'description'),_(u'The serial number of the device')],\
- u'at0007':[_(u'text'),_(u'Components'),_(u'description'),_(u'Information about the device components')],\
- u'at0008':[_(u'text'),_(u'Servicing'),_(u'description'),_(u'Details of servicing')],\
- u'at0009':[_(u'text'),_(u'Date last serviced'),_(u'description'),_(u'The date the device was last serviced')],\
- u'at0010':[_(u'text'),_(u'Date last calibration'),_(u'description'),_(u'Date the device was last calibrated')],\
- u'at0011':[_(u'text'),_(u'Serviced by'),_(u'description'),_(u'Agent performed the servicing')],\
- u'at0012':[_(u'text'),_(u'Components'),_(u'description'),_()]}}
-
- # Constraint Code Section
- constCodes={}
- # Term Binding Section
- term_binding={}
- # Constraint Binding Section
- constraint_binding={}
- self.ontology=ArchetypeOntology(termAvail,specDepth,termCodes,constraintCodes,termAN,self.parentArchetypeId)
-
- # Definition Section Begins Here. We build it from the leaf nodes up.
-
- #Length of DefinList= 144
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0011'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'yyyy-??-??T??:??:??'
- #u'value'
- #1
- #u'..'
- #1
- DvDateTime(value)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0010'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'yyyy-??-??T??:??:??'
- #u'value'
- #1
- #u'..'
- #1
- DvDateTime(value)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0009'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0008'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'exclude'
- #u'/openEHR-EHR-CLUSTER\\.device\\.v1/'
- #u'archetype_id/value'
- #u'include'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0012'
- #u''
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'allow_archetype'
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0007'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0006'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0005'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0003'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0004'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0002'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0001'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #1
- nodeid=u'at0000'
- self.definition=Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
=== removed file 'src/oship/km/mlhim/clinical/cluster/level_of_exertion_v1.py'
--- src/oship/km/mlhim/clinical/cluster/level_of_exertion_v1.py 2010-08-02 02:06:04 +0000
+++ src/oship/km/mlhim/clinical/cluster/level_of_exertion_v1.py 1970-01-01 00:00:00 +0000
@@ -1,150 +0,0 @@
-#This file was created with atbldr module from the OSHIP project.
-#Its quality is not guaranteed and will need hand editing, especially the definition section before use.
-
-import grok
-import datetime
-from zope.i18nmessageid import MessageFactory
-from oship.openehr.archetype import *
-from oship.openehr.demographic import *
-from oship.openehr.extract import *
-from oship.openehr.integration import *
-from oship.openehr.openehrprofile import *
-from oship.openehr.sm import *
-
-_ = MessageFactory('oship')
-
-class LevelOfExertionV1(Archetype):
-
- grok.implements(IArchetype)
-
- def __init__(self):
- self.adlVersion =u'1.4'
- self.archetypeId = ArchetypeId(ObjectId(u'openEHR-EHR-CLUSTER.level_of_exertion.v1'))
- self.concept = u'at0000'
- self.parentArchetypeId=ArchetypeId(ObjectId(u''))
-
- # Create the description components.
- self.originalLanguage=CodePhrase(u'ISO_639-1',u'en')
- self.translationDetails=None # needs to be completed in atbldr
- self.description=[u'original_author', u'name', u'Heather Leslie', u'organisation', u'Ocean Informatics', u'email', u'heather.leslie@xxxxxxxxxxxxxxxxxxxx', u'date', u'27/10/2008', u'details', u'en', u'language', u'_ISO_639-1::en_', u'purpose', u'Record information about the amount of energy expenditure that has been, or is being, experienced by the patient', u'use', u'Record information about phase and levels of exertion - to provide state/context information within OBSERVATIONS such as Blood Pressure.', u'keywords', u'exercise', u'work', u'exertion', u'activity', u'energy', u'misuse', u'Not to be used to record actual exercise activities and measurements which should be recorded as OBSERVATIONS in their own right.', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'lifecycle_state', u'AuthorDraft', u'other_contributors', u'other_details', u'references', u''] # needs to be completed in atbldr
- self.revisionHistory=None # needs to be completed in atbldr
- self.isControlled=False # needs to be completed in atbldr
-
- # Create the ontology.
-
- # Terminologies Available Section
- termAvail=[]
- # Term Code Section (note that there is a bug in atbldr that always cutsoff the last description of termCodes)
- termCodes={u'en':{ u'at0000':[_(u'text'),_(u'Level of Exertion'),_(u'description'),_(u'Record information about level of exertion')],\
- u'at0005':[_(u'text'),_(u'Measured'),_(u'description'),_(u'The measured level of exertion')],\
- u'at0006':[_(u'text'),_(u'At rest'),_(u'description'),_(u'The person is at rest, prior to undertaking exercise')],\
- u'at0007':[_(u'text'),_(u'During exertion'),_(u'description'),_(u'The person is exerting themselves at the time')],\
- u'at0008':[_(u'text'),_(u'Post-exertion'),_(u'description'),_(u'Measurement is taken after exertion has ceased')],\
- u'at0009':[_(u'text'),_(u'Phase'),_(u'description'),_(u'The phase or context of exercise')],\
- u'at0010':[_(u'text'),_(u'Exercise intensity'),_(u'description'),_(u'Amount of work being done during exercise')],\
- u'at0011':[_(u'text'),_(u'Intensity'),_(u'description'),_(u'Semiquantitative description of the intensity of exercise undertaken')],\
- u'at0012':[_(u'text'),_(u'Low Intensity'),_(u'description'),_(u'Up to 80% Maximal Heart Rate')],\
- u'at0013':[_(u'text'),_(u'Medium Intensity '),_(u'description'),_(u'80-85% of Maximal Heart Rate')],\
- u'at0014':[_(u'text'),_(u'High Intensity '),_(u'description'),_(u'85-90% Maximal Heart Rate')],\
- u'at0015':[_(u'text'),_(u'Flat Out '),_(u'description'),_(u'90-100% Maximal Heart Rate')],\
- u'at0016':[_(u'text'),_(u'Description'),_(u'description'),_()]}}
-
- # Constraint Code Section
- constCodes={}
- # Term Binding Section
- term_binding={}
- # Constraint Binding Section
- constraint_binding={}
- self.ontology=ArchetypeOntology(termAvail,specDepth,termCodes,constraintCodes,termAN,self.parentArchetypeId)
-
- # Definition Section Begins Here. We build it from the leaf nodes up.
-
- #Length of DefinList= 82
- #u'at0008'
- #u'at0007'
- #u'at0006'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0009'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'|'
- #1000.0
- #u'..'
- #0.0
- #u'|'
- #u'magnitude'
- #u'J/min'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::130_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0005'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'at0015'
- #u'at0014'
- #u'at0013'
- #u'at0012'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0011'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0016'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0010'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #1
- nodeid=u'at0000'
- self.definition=Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
=== removed file 'src/oship/km/mlhim/clinical/composition/encounter_v1.py'
--- src/oship/km/mlhim/clinical/composition/encounter_v1.py 2010-08-02 02:06:04 +0000
+++ src/oship/km/mlhim/clinical/composition/encounter_v1.py 1970-01-01 00:00:00 +0000
@@ -1,65 +0,0 @@
-#This file was created with atbldr module from the OSHIP project.
-#Its quality is not guaranteed and will need hand editing, especially the definition section before use.
-
-import grok
-import datetime
-from zope.i18nmessageid import MessageFactory
-from oship.openehr.archetype import *
-from oship.openehr.demographic import *
-from oship.openehr.extract import *
-from oship.openehr.integration import *
-from oship.openehr.openehrprofile import *
-from oship.openehr.sm import *
-
-
-_ = MessageFactory('oship')
-
-class EncounterV1(Archetype):
-
- grok.implements(IArchetype)
-
- def __init__(self):
- self.adlVersion =u'1.4'
- self.archetypeId = ArchetypeId(ObjectId(u'openEHR-EHR-COMPOSITION.encounter.v1'))
- self.concept = u'at0000'
- self.parentArchetypeId=ArchetypeId(ObjectId(u''))
-
- # Create the description components.
- self.originalLanguage=CodePhrase(u'ISO_639-1',u'en')
- self.translationDetails=None # needs to be completed in atbldr
- self.description=[u'original_author', u'name', u'Thomas Beale', u'organisation', u'Ocean Informatics', u'date', u'2005-10-10', u'details', u'en', u'language', u'_ISO_639-1::en_', u'purpose', u'Record of encounter as a progress note.', u'use', u'', u'keywords', u'progress', u'note', u'encounter', u'misuse', u'', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'lifecycle_state', u'AuthorDraft', u'other_contributors'] # needs to be completed in atbldr
- self.revisionHistory=None # needs to be completed in atbldr
- self.isControlled=False # needs to be completed in atbldr
-
- # Create the ontology.
-
- # Terminologies Available Section
- termAvail=[]
- # Term Code Section (note that there is a bug in atbldr that always cutsoff the last description of termCodes)
- termCodes={u'en':{ u'at0000':[_(u'text'),_(u'Encounter'),_(u'description'),_(u'Generic encounter or progress note composition')]}}
-
- # Constraint Code Section
- constCodes={}
- # Term Binding Section
- term_binding={}
- # Constraint Binding Section
- constraint_binding={}
- self.ontology=ArchetypeOntology(termAvail,specDepth,termCodes,constraintCodes,termAN,self.parentArchetypeId)
-
- # Definition Section Begins Here. We build it from the leaf nodes up.
-
- #Length of DefinList= 12
- #u'433'
- #u'openehr::'
- #u'defining_code'
- #1
- #u'..'
- #1
- defining_code = CodePhrase(TerminologyId('openehr'),'433')
- DvCodedText(definingCode,value='',mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'category'
- #1
- #u'..'
- #1
- nodeid=u'at0000'
- self.definition=Composition(content,context,composer,category,lang,terr,uid,nodeid,name,atdetails,fdraudit,links)
=== removed file 'src/oship/km/mlhim/clinical/entry/observation/blood_pressure_v1.py'
--- src/oship/km/mlhim/clinical/entry/observation/blood_pressure_v1.py 2010-08-02 02:06:04 +0000
+++ src/oship/km/mlhim/clinical/entry/observation/blood_pressure_v1.py 1970-01-01 00:00:00 +0000
@@ -1,532 +0,0 @@
-#This file was created with atbldr module from the OSHIP project.
-#Its quality is not guaranteed and will need hand editing, especially the definition section before use.
-
-import grok
-import datetime
-from zope.i18nmessageid import MessageFactory
-from oship.openehr.archetype import *
-from oship.openehr.demographic import *
-from oship.openehr.extract import *
-from oship.openehr.integration import *
-from oship.openehr.openehrprofile import *
-from oship.openehr.sm import *
-
-_ = MessageFactory('oship')
-
-class BloodPressureV1(Archetype):
-
- grok.implements(IArchetype)
-
- def __init__(self):
- self.adlVersion =u'1.4'
- self.archetypeId = ArchetypeId(ObjectId(u'openEHR-EHR-OBSERVATION.blood_pressure.v1'))
- self.concept = u'at0000'
- self.parentArchetypeId=ArchetypeId(ObjectId(u''))
-
- # Create the description components.
- self.originalLanguage=CodePhrase(u'ISO_639-1',u'en')
- self.translationDetails=None # needs to be completed in atbldr
- self.description=[u'original_author', u'name', u'Sam Heard', u'organisation', u'Ocean Informatics', u'email', u'sam.heard@xxxxxxxxxxxxxxxxxxxx', u'date', u'22/03/2006', u'details', u'en', u'language', u'_ISO_639-1::en_', u'purpose', u'To record the systemic arterial blood pressure of a person. ', u'use', u'All systemic arterial blood pressure measurements are recorded using this archetype. There is a rich state model, which can be used to support exercise/stress testing and research using tilt tables.', u'keywords', u'observations', u'measurement', u'bp', u'vital signs', u'mean arterial pressure', u'pulse pressure', u'systolic', u'diastolic', u'RR', u'NIBP', u'misuse', u'Not to be used for intravenous pressure.\r\nNot to be used for the recording of the measurement of arterial pressure specific locations such as the radial artery or brachial artery.\r\nUse OBSERVATION.intravascular_pressure and related specialisations in these situations.', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'ja', u'language', u'_ISO_639-1::ja_', u'purpose', u'*To record the systemic blood pressure of a person. The measurement records the systolic and the diastolic pressure by some means suitable for the result to be seen as a surrogate for the general and systemic blood pressure.(en)', u'use', u'*All blood pressure measurements are recorded using this archetype. There is a rich state model for use with exercise ECGs and Tilt Table measurements.(en)', u'keywords', u'*observations(en)', u'*blood pressure(en)', u'*measurement(en)', u'misuse', u'*Not to be used for intravascular pressure.(en)', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'de', u'language', u'_ISO_639-1::de_', u'purpose', u'Dient der Dokumentation des systemischen Blutdrucks einer Person. Die Messung zeichnet den systolischen und diastolischen Blutdruck auf geeignete Art und Weise auf, sodass das Resultat der Messung als charakteristisch f\xfcr den tats\xe4chlichen systemischen Blutdruck angesehen werden kann.', u'use', u'Alle Blutdruckmessungen werden unter Zuhilfenahme dieses Archetypen dokumentiert. Der Archetyp beinhaltet ein umfassendes Status-Modell z.B. bei Durchf\xfchrung von Belastungs-EKGs und Kipptischuntersuchungen.', u'misuse', u'Nicht zu Benutzen zur Dokumentation des intravaskul\xe4ren Drucks.', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'zh-cn', u'language', u'_ISO_639-1::zh-cn_', u'purpose', u'*To record the systemic blood pressure of a person. The measurement records the systolic and the diastolic pressure by some means suitable for the result to be seen as a surrogate for the general and systemic blood pressure.(en)', u'use', u'*All blood pressure measurements are recorded using this archetype. There is a rich state model for use with exercise ECGs and Tilt Table measurements.(en)', u'keywords', u'*observations(en)', u'*blood pressure(en)', u'*measurement(en)', u'misuse', u'*Not to be used for intravascular pressure.(en)', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'lifecycle_state', u'AuthorDraft', u'other_contributors', u'Heather Leslie, Ocean Informatics', u'Sundaresan Jagannathan, NHS Scotland', u'Sebastian Garde, Ocean Informatics', u'Jeroen Meintjens, Medisch Centrum Alkmaar, Netherlands', u'Pieter Hummel, Medisch Centrum Alkmaar, Netherlands', u'Melvin Reynolds, UK', u'Evelyn Hovenga, Australia', u'Ian McNicoll, Ocean Informatics, Scotland', u'Derek Hoy, Scotland', u'Anneke Goossen, Netherlands', u'Tony Shannon, NHS, UK', u'Rong Chen, Sweden', u'Beatriz De Faria Leao, Brazil', u'Knut Bernstein, Denmark', u'Eugene Igras, IRIS Systems, Canada', u'other_details', u'references', u'Cuff sizes: Circulation (1993;88:2460-2467), by Dorothee Perloff,MD; Carlene Grim, MSN, SpDN; John Flack, MD; Edward D. Frohlich, MD; Martha Hill, PhD, RN; Mary McDonald, MSPH, RN; and Bruce Z. Morgenstern, MD, Writing Group'] # needs to be completed in atbldr
- self.revisionHistory=None # needs to be completed in atbldr
- self.isControlled=False # needs to be completed in atbldr
-
- # Create the ontology.
-
- # Terminologies Available Section
- termAvail=[u'SNOMED-CT',u'...',]
-
- # Term Code Section (note that there is a bug in atbldr that always cutsoff the last description of termCodes)
- termCodes={u'en':{ u'at0000':[_(u'text'),_(u'Blood pressure'),_(u'description'),_(u'The measurement of arterial blood pressure which is a surrogate for arterial pressure in the systemic circulation.')],\
- u'at0001':[_(u'text'),_(u'history'),_(u'description'),_(u'history Structural node')],\
- u'at0003':[_(u'text'),_(u'blood pressure'),_(u'description'),_(u'@ internal @')],\
- u'at0004':[_(u'text'),_(u'Systolic'),_(u'description'),_(u'Peak systemic arterial blood pressure over one cycle - measured in systolic or contraction phase of the heart cycle')],\
- u'at0005':[_(u'text'),_(u'Diastolic'),_(u'description'),_(u'Minimum systemic arterial blood pressure over one cycle - measured in the diastolic or relaxation phase')],\
- u'at0006':[_(u'text'),_(u'any event'),_(u'description'),_(u'Other event in event history')],\
- u'at0007':[_(u'text'),_(u'state structure'),_(u'description'),_(u'@ internal @')],\
- u'at0008':[_(u'text'),_(u'Position'),_(u'description'),_(u'The position of the person at the time of measurement')],\
- u'at0011':[_(u'text'),_(u'list structure'),_(u'description'),_(u'list structure')],\
- u'at0013':[_(u'text'),_(u'Cuff size'),_(u'description'),_(u'The size of the cuff used for blood pressure measurement')],\
- u'at0014':[_(u'text'),_(u'Location of measurement'),_(u'description'),_(u'The site of the measurement of the blood pressure')],\
- u'at0015':[_(u'text'),_(u'Adult'),_(u'description'),_(u'A cuff that is standard for an adult - bladder approx 13cm x 30cm')],\
- u'at0016':[_(u'text'),_(u'Large Adult'),_(u'description'),_(u'A cuff for adults with larger arms - bladder approx 16cm x 38cm')],\
- u'at0017':[_(u'text'),_(u'Paediatric/Child'),_(u'description'),_(u'A cuff that is appropriate for a child or thin arm - bladder approx 8cm x 21cm')],\
- u'at0025':[_(u'text'),_(u'Right arm'),_(u'description'),_(u'The right arm of the person')],\
- u'at0026':[_(u'text'),_(u'Left arm'),_(u'description'),_(u'The left arm of the person')],\
- u'at0027':[_(u'text'),_(u'Right thigh'),_(u'description'),_(u'The right thigh of the person')],\
- u'at0028':[_(u'text'),_(u'Left thigh'),_(u'description'),_(u'The left thigh of the person')],\
- u'at0031':[_(u'text'),_(u'Postural change'),_(u'description'),_(u'The difference between standing and sitting/lying blood pressure')],\
- u'at0033':[_(u'text'),_(u'Comment'),_(u'description'),_(u'Comment on blood pressure measurement')],\
- u'at1000':[_(u'text'),_(u'Standing'),_(u'description'),_(u'Standing at the time of blood pressure measurement')],\
- u'at1001':[_(u'text'),_(u'Sitting'),_(u'description'),_(u'Sitting (for example on bed or chair) at the time of blood pressure measurement')],\
- u'at1002':[_(u'text'),_(u'Reclining'),_(u'description'),_(u'Reclining at the time of blood pressure measurement')],\
- u'at1003':[_(u'text'),_(u'Lying'),_(u'description'),_(u'Lying flat at the time of blood pressure measurement')],\
- u'at1004':[_(u'text'),_(u'Paradox'),_(u'description'),_(u'Variation in blood pressure with respiration')],\
- u'at1005':[_(u'text'),_(u'Tilt'),_(u'description'),_(u'The craniocaudal tilt of the surface on which the person is lying at the time of measurement')],\
- u'at1006':[_(u'text'),_(u'Mean Arterial Pressure'),_(u'description'),_(u'The average arterial pressure that occurs over the entire course of the heart contraction and relaxation cycle. ')],\
- u'at1007':[_(u'text'),_(u'Pulse Pressure'),_(u'description'),_(u'The difference between the systolic and diastolic pressure over one contraction cycle.')],\
- u'at1008':[_(u'text'),_(u'Adult Thigh'),_(u'description'),_(u'A cuff used for an adult thigh - bladder approx 20cm x 42cm')],\
- u'at1009':[_(u'text'),_(u'Neonatal'),_(u'description'),_(u'A cuff used for a new born - bladder approx 3cm x 6cm')],\
- u'at1010':[_(u'text'),_(u'Korotkoff sounds'),_(u'description'),_(u'Record which Korotkoff sound is used for determining diastolic pressure')],\
- u'at1011':[_(u'text'),_(u'Fourth sound'),_(u'description'),_(u'The fourth Korotkoff sound is identified as an abrupt muffling of sounds')],\
- u'at1012':[_(u'text'),_(u'Fifth sound'),_(u'description'),_(u'The fifth Korotkoff sound is identified by absence of sounds as the cuff pressure drops below the diastolic blood pressure')],\
- u'at1013':[_(u'text'),_(u'Trendelenburg'),_(u'description'),_(u'Lying flat on the back (supine position) with the feet higher than the head at the time of blood pressure measurement')],\
- u'at1014':[_(u'text'),_(u'Left Lateral'),_(u'description'),_(u'Lying on the left side at the time of blood pressure measurement')],\
- u'at1018':[_(u'text'),_(u'Infant'),_(u'description'),_(u'A cuff used for infants - bladder approx 5cm x 15cm')],\
- u'at1019':[_(u'text'),_(u'Small Adult'),_(u'description'),_(u'A cuff used for a small adult - bladder approx 10cm x 24cm')],\
- u'at1020':[_(u'text'),_(u'Right wrist'),_(u'description'),_(u'The right wrist of the person')],\
- u'at1021':[_(u'text'),_(u'Left wrist'),_(u'description'),_(u'The left wrist of the person')],\
- u'at1025':[_(u'text'),_(u'Device'),_(u'description'),_(u'Details about sphygmomanometer or other device used to measure the blood pressure')],\
- u'at1026':[_(u'text'),_(u'Finger'),_(u'description'),_(u'A finger of the person')],\
- u'at1030':[_(u'text'),_(u'Exertion '),_(u'description'),_(u'Details about physical activity undertaken at the time of blood pressure measurement')],\
- u'at1031':[_(u'text'),_(u'Right ankle'),_(u'description'),_(u'The right ankle of the person')],\
- u'at1032':[_(u'text'),_(u'Left ankle'),_(u'description'),_(u'The left ankle of the person')],\
- u'at1033':[_(u'text'),_(u'Location'),_(u'description'),_(u'Body site of blood pressure location')],\
- u'at1034':[_(u'text'),_(u'Description of location'),_(u'description'),_(u'Detailed description about the site of the measurement of the blood pressure')],\
- u'at1035':[_(u'text'),_(u'Method'),_(u'description'),_(u'Method of measurement of blood pressure')],\
- u'at1036':[_(u'text'),_(u'Auscultation'),_(u'description'),_(u'Method of measuring blood pressure externally, using a stethoscope and Korotkoff sounds')],\
- u'at1037':[_(u'text'),_(u'Palpation'),_(u'description'),_(u'Method of measuring blood pressure externally, using palpation (usually of the radial artery at the wrist)')],\
- u'at1038':[_(u'text'),_(u'Mean Arterial Pressure Formula'),_(u'description'),_(u'Formula used to calculate the MAP (if recorded in data)')],\
- u'at1039':[_(u'text'),_(u'Machine'),_(u'description'),_(u'Method of measuring blood pressure externally, using a blood pressure machine')],\
- u'at1040':[_(u'text'),_(u'Invasive'),_(u'description'),_(u'Method of measuring blood pressure internally ie involving penetration of the skin and measuring inside blood vessels')],\
- u'at1041':[_(u'text'),_(u'Anxiety '),_(u'description'),_(u"Details about the subject's level of anxiety at the time of blood pressure measurement")]}}
-
- # Constraint Code Section
- constCodes={}
- # Term Binding Section
- term_binding={u'SNOMED-CT':[{u'at0000':u'_SNOMED-CT(2003)::163020007_'},{u'at0004':u'_SNOMED-CT(2003)::163030003_'},{u'at0005':u'_SNOMED-CT(2003)::163031004_'},{u'at0013':u'_SNOMED-CT(2003)::246153002_'},]}
-
- # Constraint Binding Section
- constraint_binding={}
- self.ontology=ArchetypeOntology(termAvail,specDepth,termCodes,constraintCodes,termAN,self.parentArchetypeId)
-
- # Definition Section Begins Here. We build it from the leaf nodes up.
-
- #Length of DefinList= 399
- #u'at1012'
- #u'at1011'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1010'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1038'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'exclude'
- #u'/openEHR-EHR-CLUSTER\\.device\\.v1/'
- #u'archetype_id/value'
- #u'include'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1025'
- #u''
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'allow_archetype'
- #u'at1040'
- #u'at1039'
- #u'at1037'
- #u'at1036'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1035'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1034'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'at1032'
- #u'at1031'
- #u'at1026'
- #u'at1021'
- #u'at1020'
- #u'at0028'
- #u'at0027'
- #u'at0026'
- #u'at0025'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0014'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1033'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'at1019'
- #u'at1018'
- #u'at1009'
- #u'at1008'
- #u'at0017'
- #u'at0016'
- #u'at0015'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0013'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #1
- nodeid=u'at0011'
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'protocol'
- nodeid=u'at0001_/events_at0006_/state_at0007'
- #u'/data'
- #1
- #u'..'
- #1
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'use_node'
- #u'state'
- nodeid=u'at0001_/events_at0006_/data_at0003'
- #u'/data'
- #1
- #u'..'
- #1
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'use_node'
- #u'data'
- #u'149'
- #u'openehr::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'math_function'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1004'
- IntervalEvent(width,mfunc,scount)
- nodeid=u'at0001_/events_at0006_/state_at0007'
- #u'/data'
- #1
- #u'..'
- #1
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'use_node'
- #u'state'
- nodeid=u'at0001_/events_at0006_/data_at0003'
- #u'/data'
- #1
- #u'..'
- #1
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'use_node'
- #u'data'
- #u'147'
- #u'openehr::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'math_function'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0031'
- IntervalEvent(width,mfunc,scount)
- #0
- #u'precision'
- #u'\xb0'
- #u'units'
- #0.0
- #u'magnitude'
- #u'assumed_value'
- #u'|'
- #0
- #u'|'
- #u'precision'
- #u'|'
- #90.0
- #u'..'
- #-90.0
- #u'|'
- #u'magnitude'
- #u'\xb0'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::497_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1005'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'exclude'
- #u'/.*/'
- #u'archetype_id/value'
- #u'include'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1041'
- #u''
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'allow_archetype'
- #u'exclude'
- #u'/openEHR-EHR-CLUSTER\\.level_of_exertion\\.v1/'
- #u'archetype_id/value'
- #u'include'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1030'
- #u''
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'allow_archetype'
- #u'at1001'
- #u'at1014'
- #u'at1013'
- #u'at1003'
- #u'at1002'
- #u'at1001'
- #u'at1000'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0008'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #1
- nodeid=u'at0007'
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'state'
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0033'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'|'
- #0
- #u'|'
- #u'precision'
- #u'|'
- #1000.0
- #u'<'
- #u'..'
- #0.0
- #u'|'
- #u'magnitude'
- #u'mm_Hg_'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::125_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1007'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'|'
- #0
- #u'|'
- #u'precision'
- #u'|'
- #1000.0
- #u'<'
- #u'..'
- #0.0
- #u'|'
- #u'magnitude'
- #u'mm_Hg_'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::125_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1006'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'|'
- #0
- #u'|'
- #u'precision'
- #u'|'
- #1000.0
- #u'<'
- #u'..'
- #0.0
- #u'|'
- #u'magnitude'
- #u'mm_Hg_'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::125_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0005'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'|'
- #0
- #u'|'
- #u'precision'
- #u'|'
- #1000.0
- #u'<'
- #u'..'
- #0.0
- #u'|'
- #u'magnitude'
- #u'mm_Hg_'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::125_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0004'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #1
- nodeid=u'at0003'
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'data'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0006'
- Event(time,data,state,parent,offset)
- #u'unordered'
- #u'*'
- #u'..'
- #1
- #u'cardinality'
- #u'events'
- #1
- #u'..'
- #1
- nodeid=u'at0001'
- History(origin,events,period,duration,summary,uid,nodeid,name,atdetails,fdraudit,links)
- #u'data'
- #1
- #u'..'
- #1
- nodeid=u'at0000'
- self.definition=Observation(data,state,nodeid,protocol,gid,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links)
=== removed file 'src/oship/km/mlhim/demographics/person_name_iso_v1.py'
--- src/oship/km/mlhim/demographics/person_name_iso_v1.py 2010-08-02 02:06:04 +0000
+++ src/oship/km/mlhim/demographics/person_name_iso_v1.py 1970-01-01 00:00:00 +0000
@@ -1,413 +0,0 @@
-#This file was created with atbldr module from the OSHIP project.
-#Its quality is not guaranteed and will need hand editing, especially the definition section before use.
-
-import grok
-import datetime
-from zope.i18nmessageid import MessageFactory
-from oship.openehr.archetype import *
-from oship.openehr.demographic import *
-from oship.openehr.extract import *
-from oship.openehr.integration import *
-from oship.openehr.openehrprofile import *
-from oship.openehr.sm import *
-
-_ = MessageFactory('oship')
-
-class PersonNameIsoV1(Archetype):
-
- grok.implements(IArchetype)
-
- def __init__(self):
- self.adlVersion =u'1.4'
- self.archetypeId = ArchetypeId(ObjectId(u'openEHR-DEMOGRAPHIC-PARTY_IDENTITY.person_name_iso.v1'))
- self.concept = u'at0000'
- self.parentArchetypeId=ArchetypeId(ObjectId(u''))
-
- # Create the description components.
- self.originalLanguage=CodePhrase(u'ISO_639-1',u'en')
- self.translationDetails=None # needs to be completed in atbldr
- self.description=[u'original_author', u'name', u'Rigoleta Dutra & Sergio Miranda Freire', u'organisation', u'Universidade do Estado do Rio de Janeiro - UERJ', u'email', u'sergio@xxxxxxxxxxxxxxx', u'date', u'20/05/2009', u'details', u'en', u'language', u'_ISO_639-1::en_', u'purpose', u'Representation of a personal name, based on ISO standards.', u'use', u'Used in demographic services to represent the names by which a person is known.', u'keywords', u'demographic service', u'person name', u'misuse', u'', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'pt-br', u'language', u'_ISO_639-1::pt-br_', u'purpose', u'Representa\xe7\xe3o do nome de uma pessoa', u'use', u'Utilizado em servi\xe7os de demografia para representar os nomes que uma pessoa pode ter', u'keywords', u'servi\xe7o demogr\xe1fico', u'nome de uma pessoa', u'misuse', u'', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'lifecycle_state', u'AuthorDraft', u'other_contributors', u'other_details', u'references', u'ISO/TS 22220:2008(E) - Identification of Subject of Care - Technical Specification- International Organization for Standardization.'] # needs to be completed in atbldr
- self.revisionHistory=None # needs to be completed in atbldr
- self.isControlled=False # needs to be completed in atbldr
-
- # Create the ontology.
-
- # Terminologies Available Section
- termAvail=[]
- # Term Code Section
- termCodes={u'pt-br':{u'at0000':[_(u'text'),_(u'Nome da pessoa'),_(u'description'),_(u'Estrutura do nome de uma pessoa')],\
- u'at0001':[_(u'text'),_(u'Componentes do nome'),_(u'description'),_(u'Componentes do nome da pessoa')],\
- u'at0002':[_(u'text'),_(u'Grupo do nome atribu\xeddo'),_(u'description'),_(u'Grupo que consiste de um nome atribu\xeddo e a ordem dele no nome')],\
- u'at0003':[_(u'text'),_(u'Grupo do sobrenome'),_(u'description'),_(u'Grupo que consiste de um sobrenome e a ordem dele no nome')],\
- u'at0004':[_(u'text'),_(u'Grupo de t\xedtulo do nome'),_(u'description'),_(u'Grupo que consiste de um t\xedtulo do nome de uma pessoa e a ordem dele no nome')],\
- u'at0005':[_(u'text'),_(u'Grupo de sufixo do nome'),_(u'description'),_(u'Grupo que consiste de um sufixo do nome de uma pessoa e a ordem dele no nome')],\
- u'at0006':[_(u'text'),_(u'Grupo de utiliza\xe7\xe3o do nome'),_(u'description'),_(u'Grupo que descreve como este nome deve ser usado')],\
- u'at0007':[_(u'text'),_(u'Representa\xe7\xe3o alternativa do nome'),_(u'description'),_(u'Grupo que descreve uma forma alternativa de representar o nome de uma pessoa')],\
- u'at0008':[_(u'text'),_(u'Nome preferencial'),_(u'description'),_(u'Indica o nome pelo qual a pessoa prefere ser identificada')],\
- u'at0009':[_(u'text'),_(u'Indicador de uso condicional'),_(u'description'),_(u'Um indicador das condi\xe7\xf5es espec\xedficas ou regras que devem ser aplicadas ao nome de uma pessoa')],\
- u'at0010':[_(u'text'),_(u'Nome atribu\xeddo'),_(u'description'),_(u'O nome que identifica a pessoa no grupo familiar ou pelo qual ela \xe9 univocamente identificada socialmente')],\
- u'at0011':[_(u'text'),_(u'N\xfamero de seq\xfc\xeancia do nome atribu\xeddo'),_(u'description'),_(u'Um indicator da ordem de uso para os nomes atribu\xeddos')],\
- u'at0012':[_(u'text'),_(u'Nome de fam\xedlia'),_(u'description'),_(u'A parte do nome que uma pessoa possui em comum com outros membros de sua fam\xedlia, distinta do(s) seu(s) nome(s) atribu\xeddo(s)')],\
- u'at0013':[_(u'text'),_(u'N\xfamero de seq\xfc\xeancia do sobrenome'),_(u'description'),_(u'Um indicator da ordem de uso para os sobrenomes')],\
- u'at0014':[_(u'text'),_(u'T\xedtulo do nome'),_(u'description'),_(u'Uma forma honor\xedfica que inicia o nome, usada ao se referir a uma pessoa pelo nome, seja por correspond\xeancia ou por telefone, ou, dependendo da situa\xe7\xe3o cultural, pessoalmente')],\
- u'at0015':[_(u'text'),_(u'N\xfamero de seq\xfc\xeancia do t\xedtulo do nome'),_(u'description'),_(u'Um indicator da ordem de uso para os t\xedtulos do nome')],\
- u'at0016':[_(u'text'),_(u'Sufixo do nome'),_(u'description'),_(u'Termo adicional usado ap\xf3s o nome da pessoa')],\
- u'at0017':[_(u'text'),_(u'N\xfamero de seq\xfc\xeancia do sufixo do nome'),_(u'description'),_(u'Um indicator da ordem de uso para os sufixos do nome')],\
- u'at0018':[_(u'text'),_(u'Uso do nome'),_(u'description'),_(u'Uma classifica\xe7\xe3o que permite a diferencia\xe7\xe3o entre os usos do nome de uma pessoa. Um nome de um indiv\xedduo pode ter muitos usos')],\
- u'at0019':[_(u'text'),_(u'Intervalo de utiliza\xe7\xe3o'),_(u'description'),_(u'O per\xedodo de tempo para o qual este uso do nome se aplica para o nome ao qual ele est\xe1 associado')],\
- u'at0020':[_(u'text'),_(u'Identificador usado'),_(u'description'),_(u'A combina\xe7\xe3o do tipo de identificador, emissor do identificador e nome do identificador que especifica o v\xednculo entre este nome e o uso do identificador para relat\xf3rio, ou outros usos')],\
- u'at0021':[_(u'text'),_(u'Uso da representa\xe7\xe3o'),_(u'description'),_(u'Nome da forma de representa\xe7\xe3o usada')],\
- u'at0022':[_(u'text'),_(u'Representa\xe7\xe3o alternativa do nome'),_(u'description'),_(u'Representa\xe7\xe3o alternativa do nome desta pessoa usando estilos alternativos de representa\xe7\xe3o, tais como caracteres ou varia\xe7\xf5es do conjunto de caracteres do idioma para exibi\xe7\xe3o local')],\
- u'at0023':[_(u'text'),_(u'Nome para relat\xf3rio'),_(u'description'),_(u'o nome do sujeito usado para relat\xf3rio, quando acompanhado por um identificador espec\xedfico')],\
- u'at0024':[_(u'text'),_(u'Nome de rec\xe9m-nascido'),_(u'description'),_(u'tipo reservado para identifica\xe7\xe3o de rec\xe9m-nascidos sem nome')],\
- u'at0025':[_(u'text'),_(u'Nome profissional ou comercial'),_(u'description'),_(u'o nome usado pela pessoa para prop\xf3sitos profissionais ou de neg\xf3cios')],\
- u'at0026':[_(u'text'),_(u'Nome de solteiro(a)'),_(u'description'),_(u'o nome usado pela pessoa antes de se casar')],\
- u'at0027':[_(u'text'),_(u'Nome legal'),_(u'description'),_(u'Nome registrado (legal) para a pessoa')],\
- u'at0028':[_(u'text'),_(u'Outro nome'),_(u'description'),_(u'qualquer outro nome pelo qual o sujeito \xe9 conhecido, ou foi conhecido no passado')],\
- u'at0031':[_(u'text'),_(u'Nome n\xe3o confi\xe1vel'),_(u'description'),_(u'indica que o nome registrado \xe9 um nome fict\xedcio ou parcial')],\
- u'at0032':[_(u'text'),_(u'Escrito de forma errada'),_(u'description'),_(u'Este indicador permite ao usu\xe1rio indicar que h\xe1 um erro de digita\xe7\xe3o, mas que deve ser retido para um uso potencial na vincula\xe7\xe3o de registros')],\
- u'at0033':[_(u'text'),_(u'Nome para n\xe3o ser usado'),_(u'description'),_(u'Indica que este nome n\xe3o deve ser usado ao se referir \xe0 pessoa')],\
- u'at0034':[_(u'text'),_(u'V\xednculo do nome proibido por lei'),_(u'description'),_(u'indica que este nome e todos os nomes antes dele na seq\xfc\xeancia de nomes n\xe3o devem ser exibidos ou indicados de nenhum modo ao procurar por ou lidar com informa\xe7\xf5es e eventos associados com um nome que segue a este na seq\xfc\xeancia de nomes')],\
- u'at0035':[_(u'text'),_(u'Requisito especial seguranca/privacidade'),_(u'description'),_(u'indica um nome para o qual epis\xf3dios s\xe3o vinculados e devem somente ser acessados por pessoas autorizadas')],\
- u'at0036':[_(u'text'),_(u'Nome tempor\xe1rio'),_(u'description'),_(u'Indica que o nome da pessoa n\xe3o foi determinado')]}}
-
- {u'en':{u'at0000':[_(u'text'),_(u'Person name'),_(u'description'),_(u'Person name details.')],\
- u'at0001':[_(u'text'),_(u'Name'),_(u'description'),_(u'Components of a person name.')],\
- u'at0002':[_(u'text'),_(u'Given names'),_(u'description'),_(u'Details of given names.')],\
- u'at0003':[_(u'text'),_(u'Family names'),_(u'description'),_(u'Details of family names.')],\
- u'at0004':[_(u'text'),_(u'Titles'),_(u'description'),_(u'Details of person titles.')],\
- u'at0005':[_(u'text'),_(u'Suffixes'),_(u'description'),_(u'Details of person suffixes.')],\
- u'at0006':[_(u'text'),_(u'Name usages'),_(u'description'),_(u'Details of person name usages.')],\
- u'at0007':[_(u'text'),_(u'Alternative name repesentations'),_(u'description'),_(u'Details of alternative representations such as local codesets or language variations.')],\
- u'at0008':[_(u'text'),_(u'Preferred name'),_(u'description'),_(u'Indicates that this is the name by which a person chooses to be identified.')],\
- u'at0009':[_(u'text'),_(u'Specific issues'),_(u'description'),_(u'Specific issues that apply to use of the person name.')],\
- u'at0010':[_(u'text'),_(u'Given name'),_(u'description'),_(u"The person's identifying name(s) within the family group or by which he/she is uniquely socially identified.")],\
- u'at0011':[_(u'text'),_(u'Given name sequence number'),_(u'description'),_(u'The order of use for a Given name')],\
- u'at0012':[_(u'text'),_(u'Family name'),_(u'description'),_(u'The part of a name a person usually has in common with some other members of his/her family, as distinguished from his/her given names.')],\
- u'at0013':[_(u'text'),_(u'Family name sequence number'),_(u'description'),_(u'An indicator of the order of use for a Family name.')],\
- u'at0014':[_(u'text'),_(u'Title'),_(u'description'),_(u'An honorific form of address commencing a name, used when addressing a person by name, whether by mail, by phone, or depending upon cultural situation in person.')],\
- u'at0015':[_(u'text'),_(u'Title sequence number'),_(u'description'),_(u'An indicator of the order of use for the name Title.')],\
- u'at0016':[_(u'text'),_(u'Suffix'),_(u'description'),_(u'Additional term used following a person name.')],\
- u'at0017':[_(u'text'),_(u'Suffix sequence number'),_(u'description'),_(u'An indicator of the order of use for the name Suffix')],\
- u'at0018':[_(u'text'),_(u'Name usage'),_(u'description'),_(u'A classification that enables differentiation between the usage of names for a person. An individual name may have many name uses')],\
- u'at0019':[_(u'text'),_(u'Usage interval'),_(u'description'),_(u'The period of time for which this name usage applies.')],\
- u'at0020':[_(u'text'),_(u'Usage identifier'),_(u'description'),_(u'The combination of identifier type, identifier issuer and identifier name that specify the link between this name and reporting or other unique identifier usage.')],\
- u'at0021':[_(u'text'),_(u'Representation usage'),_(u'description'),_(u'Name of the representational form used.')],\
- u'at0022':[_(u'text'),_(u'Alternative representation'),_(u'description'),_(u'Alternative Representation of this subject of care name using alternative styles of representation such as characters or language character set variations for local display.')],\
- u'at0023':[_(u'text'),_(u'Reporting name'),_(u'description'),_(u'The subject\u2019s name as it is to be used for reporting, when used with a specific identifier.')],\
- u'at0024':[_(u'text'),_(u'Newborn name'),_(u'description'),_(u'A type reserved for the identification of unnamed newborn babies.')],\
- u'at0025':[_(u'text'),_(u'Professional or business name'),_(u'description'),_(u'The name used by the subject for business or professional purposes.')],\
- u'at0026':[_(u'text'),_(u'Maiden name'),_(u'description'),_(u'The name used by the subject of care prior to marriage.')],\
- u'at0027':[_(u'text'),_(u'Legal name'),_(u'description'),_(u'Registered name (Legal name).')],\
- u'at0028':[_(u'text'),_(u'Other name'),_(u'description'),_(u'Any other name by which the subject is known, or has been known by in the past.')],\
- u'at0031':[_(u'text'),_(u'Unreliable information'),_(u'description'),_(u'The name recorded is a fictitious or partial name.')],\
- u'at0032':[_(u'text'),_(u'Known misspelling'),_(u'description'),_(u'This is a misspelling, but should be retained for potential future matching.')],\
- u'at0033':[_(u'text'),_(u'Name not to be used'),_(u'description'),_(u'This name should not be used when referring to this subject.')],\
- u'at0034':[_(u'text'),_(u'Name linkage forbidden by law'),_(u'description'),_(u'By Law, this name and all names prior to it in the name sequence are not to be displayed or indicated in any way when searching for or dealing with information and events associated with a name that is subsequent to this one in the name sequence.')],\
- u'at0035':[_(u'text'),_(u'Special privacy/security requirements'),_(u'description'),_(u'A name for which episodes are attached that should only be accessible to specified authorised persons.')],\
- u'at0036':[_(u'text'),_(u'Temporary name'),_(u'description'),_()]}}
-
- # Constraint Code Section
- constCodes={u'pt-br':{u'ac0000':[u'text',u'T\xedtulos',u'description',u'Termos como Doutor, Mestre, ....'],\
- u'ac0001':[u'text',u'Sufixos',u'description',u'Sufixos do nome \u2013 neto, neta, junior, ...'],\
- u'ac0002':[u'text',u'C\xf3digos para o idioma de representa\xe7\xe3o',u'description',u'idiomas para a representa\xe7\xe3o alternativa do nome']}},\
- {u'en':{u'ac0000':[u'text',u'Titles',u'description',u'Terms like Dr, Prof, Rev etc used as an honorific form of addressing a person.'],\
- u'ac0001':[u'text',u'Suffixes',u'description',u'Terms like Jr, PhD used after the name.'],\
- u'ac0002':[u'text',u'Language code',u'description',]}}
-
- # Term Binding Section
- term_binding={}
- # Constraint Binding Section
- constraint_binding={}
- self.ontology=ArchetypeOntology(termAvail,specDepth,termCodes,constraintCodes,termAN,self.parentArchetypeId)
-
- # Definition Section Begins Here. We build it from the leaf nodes up.
-
- #Length of DefinList= 264
- #u'at0036'
- #u'at0035'
- #u'at0034'
- #u'at0033'
- #u'at0032'
- #u'at0031'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0009'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvBoolean(value)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0008'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0022'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'_ac0002_'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0021'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #u'*'
- #u'..'
- #1
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0007'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0020'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- #u'DV_INTERVAL<DV_DATE>'
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0019'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'at0028'
- #u'at0027'
- #u'at0026'
- #u'at0025'
- #u'at0024'
- #u'at0023'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0018'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #3
- #u'..'
- #2
- #u'cardinality'
- #u'items'
- #u'*'
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0006'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvCount(magnitude,accuracy,accuracyIsPercent,magnitudeStatus,normalStatus,normalRange,otherReferenceRanges)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0017'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'_ac0001_'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0016'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #2
- #u'..'
- #2
- #u'cardinality'
- #u'items'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0005'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvCount(magnitude,accuracy,accuracyIsPercent,magnitudeStatus,normalStatus,normalRange,otherReferenceRanges)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0015'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'_ac0000_'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0014'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #2
- #u'..'
- #2
- #u'cardinality'
- #u'items'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0004'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvCount(magnitude,accuracy,accuracyIsPercent,magnitudeStatus,normalStatus,normalRange,otherReferenceRanges)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0013'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0012'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #2
- #u'..'
- #2
- #u'cardinality'
- #u'items'
- #u'*'
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0003'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvCount(magnitude,accuracy,accuracyIsPercent,magnitudeStatus,normalStatus,normalRange,otherReferenceRanges)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0011'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0010'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #2
- #u'..'
- #2
- #u'cardinality'
- #u'items'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0002'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'ordered'
- #u'*'
- #u'..'
- #1
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0001'
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'details'
- #1
- #u'..'
- #1
- nodeid=u'at0000'
- #u'PARTY_IDENTITY'
=== removed file 'src/oship/km/openehr/demographics/person_name_iso_v1.py'
--- src/oship/km/openehr/demographics/person_name_iso_v1.py 2010-08-02 02:06:04 +0000
+++ src/oship/km/openehr/demographics/person_name_iso_v1.py 1970-01-01 00:00:00 +0000
@@ -1,413 +0,0 @@
-#This file was created with atbldr module from the OSHIP project.
-#Its quality is not guaranteed and will need hand editing, especially the definition section before use.
-
-import grok
-import datetime
-from zope.i18nmessageid import MessageFactory
-from oship.openehr.archetype import *
-from oship.openehr.demographic import *
-from oship.openehr.extract import *
-from oship.openehr.integration import *
-from oship.openehr.openehrprofile import *
-from oship.openehr.sm import *
-
-_ = MessageFactory('oship')
-
-class PersonNameIsoV1(Archetype):
-
- grok.implements(IArchetype)
-
- def __init__(self):
- self.adlVersion =u'1.4'
- self.archetypeId = ArchetypeId(ObjectId(u'openEHR-DEMOGRAPHIC-PARTY_IDENTITY.person_name_iso.v1'))
- self.concept = u'at0000'
- self.parentArchetypeId=ArchetypeId(ObjectId(u''))
-
- # Create the description components.
- self.originalLanguage=CodePhrase(u'ISO_639-1',u'en')
- self.translationDetails=None # needs to be completed in atbldr
- self.description=[u'original_author', u'name', u'Rigoleta Dutra & Sergio Miranda Freire', u'organisation', u'Universidade do Estado do Rio de Janeiro - UERJ', u'email', u'sergio@xxxxxxxxxxxxxxx', u'date', u'20/05/2009', u'details', u'en', u'language', u'_ISO_639-1::en_', u'purpose', u'Representation of a personal name, based on ISO standards.', u'use', u'Used in demographic services to represent the names by which a person is known.', u'keywords', u'demographic service', u'person name', u'misuse', u'', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'pt-br', u'language', u'_ISO_639-1::pt-br_', u'purpose', u'Representa\xe7\xe3o do nome de uma pessoa', u'use', u'Utilizado em servi\xe7os de demografia para representar os nomes que uma pessoa pode ter', u'keywords', u'servi\xe7o demogr\xe1fico', u'nome de uma pessoa', u'misuse', u'', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'lifecycle_state', u'AuthorDraft', u'other_contributors', u'other_details', u'references', u'ISO/TS 22220:2008(E) - Identification of Subject of Care - Technical Specification- International Organization for Standardization.'] # needs to be completed in atbldr
- self.revisionHistory=None # needs to be completed in atbldr
- self.isControlled=False # needs to be completed in atbldr
-
- # Create the ontology.
-
- # Terminologies Available Section
- termAvail=[]
- # Term Code Section
- termCodes={u'pt-br':{u'at0000':[_(u'text'),_(u'Nome da pessoa'),_(u'description'),_(u'Estrutura do nome de uma pessoa')],\
- u'at0001':[_(u'text'),_(u'Componentes do nome'),_(u'description'),_(u'Componentes do nome da pessoa')],\
- u'at0002':[_(u'text'),_(u'Grupo do nome atribu\xeddo'),_(u'description'),_(u'Grupo que consiste de um nome atribu\xeddo e a ordem dele no nome')],\
- u'at0003':[_(u'text'),_(u'Grupo do sobrenome'),_(u'description'),_(u'Grupo que consiste de um sobrenome e a ordem dele no nome')],\
- u'at0004':[_(u'text'),_(u'Grupo de t\xedtulo do nome'),_(u'description'),_(u'Grupo que consiste de um t\xedtulo do nome de uma pessoa e a ordem dele no nome')],\
- u'at0005':[_(u'text'),_(u'Grupo de sufixo do nome'),_(u'description'),_(u'Grupo que consiste de um sufixo do nome de uma pessoa e a ordem dele no nome')],\
- u'at0006':[_(u'text'),_(u'Grupo de utiliza\xe7\xe3o do nome'),_(u'description'),_(u'Grupo que descreve como este nome deve ser usado')],\
- u'at0007':[_(u'text'),_(u'Representa\xe7\xe3o alternativa do nome'),_(u'description'),_(u'Grupo que descreve uma forma alternativa de representar o nome de uma pessoa')],\
- u'at0008':[_(u'text'),_(u'Nome preferencial'),_(u'description'),_(u'Indica o nome pelo qual a pessoa prefere ser identificada')],\
- u'at0009':[_(u'text'),_(u'Indicador de uso condicional'),_(u'description'),_(u'Um indicador das condi\xe7\xf5es espec\xedficas ou regras que devem ser aplicadas ao nome de uma pessoa')],\
- u'at0010':[_(u'text'),_(u'Nome atribu\xeddo'),_(u'description'),_(u'O nome que identifica a pessoa no grupo familiar ou pelo qual ela \xe9 univocamente identificada socialmente')],\
- u'at0011':[_(u'text'),_(u'N\xfamero de seq\xfc\xeancia do nome atribu\xeddo'),_(u'description'),_(u'Um indicator da ordem de uso para os nomes atribu\xeddos')],\
- u'at0012':[_(u'text'),_(u'Nome de fam\xedlia'),_(u'description'),_(u'A parte do nome que uma pessoa possui em comum com outros membros de sua fam\xedlia, distinta do(s) seu(s) nome(s) atribu\xeddo(s)')],\
- u'at0013':[_(u'text'),_(u'N\xfamero de seq\xfc\xeancia do sobrenome'),_(u'description'),_(u'Um indicator da ordem de uso para os sobrenomes')],\
- u'at0014':[_(u'text'),_(u'T\xedtulo do nome'),_(u'description'),_(u'Uma forma honor\xedfica que inicia o nome, usada ao se referir a uma pessoa pelo nome, seja por correspond\xeancia ou por telefone, ou, dependendo da situa\xe7\xe3o cultural, pessoalmente')],\
- u'at0015':[_(u'text'),_(u'N\xfamero de seq\xfc\xeancia do t\xedtulo do nome'),_(u'description'),_(u'Um indicator da ordem de uso para os t\xedtulos do nome')],\
- u'at0016':[_(u'text'),_(u'Sufixo do nome'),_(u'description'),_(u'Termo adicional usado ap\xf3s o nome da pessoa')],\
- u'at0017':[_(u'text'),_(u'N\xfamero de seq\xfc\xeancia do sufixo do nome'),_(u'description'),_(u'Um indicator da ordem de uso para os sufixos do nome')],\
- u'at0018':[_(u'text'),_(u'Uso do nome'),_(u'description'),_(u'Uma classifica\xe7\xe3o que permite a diferencia\xe7\xe3o entre os usos do nome de uma pessoa. Um nome de um indiv\xedduo pode ter muitos usos')],\
- u'at0019':[_(u'text'),_(u'Intervalo de utiliza\xe7\xe3o'),_(u'description'),_(u'O per\xedodo de tempo para o qual este uso do nome se aplica para o nome ao qual ele est\xe1 associado')],\
- u'at0020':[_(u'text'),_(u'Identificador usado'),_(u'description'),_(u'A combina\xe7\xe3o do tipo de identificador, emissor do identificador e nome do identificador que especifica o v\xednculo entre este nome e o uso do identificador para relat\xf3rio, ou outros usos')],\
- u'at0021':[_(u'text'),_(u'Uso da representa\xe7\xe3o'),_(u'description'),_(u'Nome da forma de representa\xe7\xe3o usada')],\
- u'at0022':[_(u'text'),_(u'Representa\xe7\xe3o alternativa do nome'),_(u'description'),_(u'Representa\xe7\xe3o alternativa do nome desta pessoa usando estilos alternativos de representa\xe7\xe3o, tais como caracteres ou varia\xe7\xf5es do conjunto de caracteres do idioma para exibi\xe7\xe3o local')],\
- u'at0023':[_(u'text'),_(u'Nome para relat\xf3rio'),_(u'description'),_(u'o nome do sujeito usado para relat\xf3rio, quando acompanhado por um identificador espec\xedfico')],\
- u'at0024':[_(u'text'),_(u'Nome de rec\xe9m-nascido'),_(u'description'),_(u'tipo reservado para identifica\xe7\xe3o de rec\xe9m-nascidos sem nome')],\
- u'at0025':[_(u'text'),_(u'Nome profissional ou comercial'),_(u'description'),_(u'o nome usado pela pessoa para prop\xf3sitos profissionais ou de neg\xf3cios')],\
- u'at0026':[_(u'text'),_(u'Nome de solteiro(a)'),_(u'description'),_(u'o nome usado pela pessoa antes de se casar')],\
- u'at0027':[_(u'text'),_(u'Nome legal'),_(u'description'),_(u'Nome registrado (legal) para a pessoa')],\
- u'at0028':[_(u'text'),_(u'Outro nome'),_(u'description'),_(u'qualquer outro nome pelo qual o sujeito \xe9 conhecido, ou foi conhecido no passado')],\
- u'at0031':[_(u'text'),_(u'Nome n\xe3o confi\xe1vel'),_(u'description'),_(u'indica que o nome registrado \xe9 um nome fict\xedcio ou parcial')],\
- u'at0032':[_(u'text'),_(u'Escrito de forma errada'),_(u'description'),_(u'Este indicador permite ao usu\xe1rio indicar que h\xe1 um erro de digita\xe7\xe3o, mas que deve ser retido para um uso potencial na vincula\xe7\xe3o de registros')],\
- u'at0033':[_(u'text'),_(u'Nome para n\xe3o ser usado'),_(u'description'),_(u'Indica que este nome n\xe3o deve ser usado ao se referir \xe0 pessoa')],\
- u'at0034':[_(u'text'),_(u'V\xednculo do nome proibido por lei'),_(u'description'),_(u'indica que este nome e todos os nomes antes dele na seq\xfc\xeancia de nomes n\xe3o devem ser exibidos ou indicados de nenhum modo ao procurar por ou lidar com informa\xe7\xf5es e eventos associados com um nome que segue a este na seq\xfc\xeancia de nomes')],\
- u'at0035':[_(u'text'),_(u'Requisito especial seguranca/privacidade'),_(u'description'),_(u'indica um nome para o qual epis\xf3dios s\xe3o vinculados e devem somente ser acessados por pessoas autorizadas')],\
- u'at0036':[_(u'text'),_(u'Nome tempor\xe1rio'),_(u'description'),_(u'Indica que o nome da pessoa n\xe3o foi determinado')]}}
-
- {u'en':{u'at0000':[_(u'text'),_(u'Person name'),_(u'description'),_(u'Person name details.')],\
- u'at0001':[_(u'text'),_(u'Name'),_(u'description'),_(u'Components of a person name.')],\
- u'at0002':[_(u'text'),_(u'Given names'),_(u'description'),_(u'Details of given names.')],\
- u'at0003':[_(u'text'),_(u'Family names'),_(u'description'),_(u'Details of family names.')],\
- u'at0004':[_(u'text'),_(u'Titles'),_(u'description'),_(u'Details of person titles.')],\
- u'at0005':[_(u'text'),_(u'Suffixes'),_(u'description'),_(u'Details of person suffixes.')],\
- u'at0006':[_(u'text'),_(u'Name usages'),_(u'description'),_(u'Details of person name usages.')],\
- u'at0007':[_(u'text'),_(u'Alternative name repesentations'),_(u'description'),_(u'Details of alternative representations such as local codesets or language variations.')],\
- u'at0008':[_(u'text'),_(u'Preferred name'),_(u'description'),_(u'Indicates that this is the name by which a person chooses to be identified.')],\
- u'at0009':[_(u'text'),_(u'Specific issues'),_(u'description'),_(u'Specific issues that apply to use of the person name.')],\
- u'at0010':[_(u'text'),_(u'Given name'),_(u'description'),_(u"The person's identifying name(s) within the family group or by which he/she is uniquely socially identified.")],\
- u'at0011':[_(u'text'),_(u'Given name sequence number'),_(u'description'),_(u'The order of use for a Given name')],\
- u'at0012':[_(u'text'),_(u'Family name'),_(u'description'),_(u'The part of a name a person usually has in common with some other members of his/her family, as distinguished from his/her given names.')],\
- u'at0013':[_(u'text'),_(u'Family name sequence number'),_(u'description'),_(u'An indicator of the order of use for a Family name.')],\
- u'at0014':[_(u'text'),_(u'Title'),_(u'description'),_(u'An honorific form of address commencing a name, used when addressing a person by name, whether by mail, by phone, or depending upon cultural situation in person.')],\
- u'at0015':[_(u'text'),_(u'Title sequence number'),_(u'description'),_(u'An indicator of the order of use for the name Title.')],\
- u'at0016':[_(u'text'),_(u'Suffix'),_(u'description'),_(u'Additional term used following a person name.')],\
- u'at0017':[_(u'text'),_(u'Suffix sequence number'),_(u'description'),_(u'An indicator of the order of use for the name Suffix')],\
- u'at0018':[_(u'text'),_(u'Name usage'),_(u'description'),_(u'A classification that enables differentiation between the usage of names for a person. An individual name may have many name uses')],\
- u'at0019':[_(u'text'),_(u'Usage interval'),_(u'description'),_(u'The period of time for which this name usage applies.')],\
- u'at0020':[_(u'text'),_(u'Usage identifier'),_(u'description'),_(u'The combination of identifier type, identifier issuer and identifier name that specify the link between this name and reporting or other unique identifier usage.')],\
- u'at0021':[_(u'text'),_(u'Representation usage'),_(u'description'),_(u'Name of the representational form used.')],\
- u'at0022':[_(u'text'),_(u'Alternative representation'),_(u'description'),_(u'Alternative Representation of this subject of care name using alternative styles of representation such as characters or language character set variations for local display.')],\
- u'at0023':[_(u'text'),_(u'Reporting name'),_(u'description'),_(u'The subject\u2019s name as it is to be used for reporting, when used with a specific identifier.')],\
- u'at0024':[_(u'text'),_(u'Newborn name'),_(u'description'),_(u'A type reserved for the identification of unnamed newborn babies.')],\
- u'at0025':[_(u'text'),_(u'Professional or business name'),_(u'description'),_(u'The name used by the subject for business or professional purposes.')],\
- u'at0026':[_(u'text'),_(u'Maiden name'),_(u'description'),_(u'The name used by the subject of care prior to marriage.')],\
- u'at0027':[_(u'text'),_(u'Legal name'),_(u'description'),_(u'Registered name (Legal name).')],\
- u'at0028':[_(u'text'),_(u'Other name'),_(u'description'),_(u'Any other name by which the subject is known, or has been known by in the past.')],\
- u'at0031':[_(u'text'),_(u'Unreliable information'),_(u'description'),_(u'The name recorded is a fictitious or partial name.')],\
- u'at0032':[_(u'text'),_(u'Known misspelling'),_(u'description'),_(u'This is a misspelling, but should be retained for potential future matching.')],\
- u'at0033':[_(u'text'),_(u'Name not to be used'),_(u'description'),_(u'This name should not be used when referring to this subject.')],\
- u'at0034':[_(u'text'),_(u'Name linkage forbidden by law'),_(u'description'),_(u'By Law, this name and all names prior to it in the name sequence are not to be displayed or indicated in any way when searching for or dealing with information and events associated with a name that is subsequent to this one in the name sequence.')],\
- u'at0035':[_(u'text'),_(u'Special privacy/security requirements'),_(u'description'),_(u'A name for which episodes are attached that should only be accessible to specified authorised persons.')],\
- u'at0036':[_(u'text'),_(u'Temporary name'),_(u'description'),_()]}}
-
- # Constraint Code Section
- constCodes={u'pt-br':{u'ac0000':[u'text',u'T\xedtulos',u'description',u'Termos como Doutor, Mestre, ....'],\
- u'ac0001':[u'text',u'Sufixos',u'description',u'Sufixos do nome \u2013 neto, neta, junior, ...'],\
- u'ac0002':[u'text',u'C\xf3digos para o idioma de representa\xe7\xe3o',u'description',u'idiomas para a representa\xe7\xe3o alternativa do nome']}},\
- {u'en':{u'ac0000':[u'text',u'Titles',u'description',u'Terms like Dr, Prof, Rev etc used as an honorific form of addressing a person.'],\
- u'ac0001':[u'text',u'Suffixes',u'description',u'Terms like Jr, PhD used after the name.'],\
- u'ac0002':[u'text',u'Language code',u'description',]}}
-
- # Term Binding Section
- term_binding={}
- # Constraint Binding Section
- constraint_binding={}
- self.ontology=ArchetypeOntology(termAvail,specDepth,termCodes,constraintCodes,termAN,self.parentArchetypeId)
-
- # Definition Section Begins Here. We build it from the leaf nodes up.
-
- #Length of DefinList= 264
- #u'at0036'
- #u'at0035'
- #u'at0034'
- #u'at0033'
- #u'at0032'
- #u'at0031'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0009'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvBoolean(value)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0008'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0022'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'_ac0002_'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0021'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #u'*'
- #u'..'
- #1
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0007'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0020'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- #u'DV_INTERVAL<DV_DATE>'
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0019'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'at0028'
- #u'at0027'
- #u'at0026'
- #u'at0025'
- #u'at0024'
- #u'at0023'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0018'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #3
- #u'..'
- #2
- #u'cardinality'
- #u'items'
- #u'*'
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0006'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvCount(magnitude,accuracy,accuracyIsPercent,magnitudeStatus,normalStatus,normalRange,otherReferenceRanges)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0017'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'_ac0001_'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0016'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #2
- #u'..'
- #2
- #u'cardinality'
- #u'items'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0005'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvCount(magnitude,accuracy,accuracyIsPercent,magnitudeStatus,normalStatus,normalRange,otherReferenceRanges)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0015'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'_ac0000_'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0014'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #2
- #u'..'
- #2
- #u'cardinality'
- #u'items'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0004'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvCount(magnitude,accuracy,accuracyIsPercent,magnitudeStatus,normalStatus,normalRange,otherReferenceRanges)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0013'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0012'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #2
- #u'..'
- #2
- #u'cardinality'
- #u'items'
- #u'*'
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0003'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvCount(magnitude,accuracy,accuracyIsPercent,magnitudeStatus,normalStatus,normalRange,otherReferenceRanges)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0011'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #1
- #u'occurrences'
- nodeid=u'at0010'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'ordered'
- #2
- #u'..'
- #2
- #u'cardinality'
- #u'items'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0002'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'ordered'
- #u'*'
- #u'..'
- #1
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0001'
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'details'
- #1
- #u'..'
- #1
- nodeid=u'at0000'
- #u'PARTY_IDENTITY'
=== removed file 'src/oship/km/openehr/ehr/cluster/device_v1.py'
--- src/oship/km/openehr/ehr/cluster/device_v1.py 2010-08-02 02:06:04 +0000
+++ src/oship/km/openehr/ehr/cluster/device_v1.py 1970-01-01 00:00:00 +0000
@@ -1,219 +0,0 @@
-#This file was created with atbldr module from the OSHIP project.
-#Its quality is not guaranteed and will need hand editing, especially the definition section before use.
-
-import grok
-import datetime
-from zope.i18nmessageid import MessageFactory
-from oship.openehr.archetype import *
-from oship.openehr.demographic import *
-from oship.openehr.extract import *
-from oship.openehr.integration import *
-from oship.openehr.openehrprofile import *
-from oship.openehr.sm import *
-
-_ = MessageFactory('oship')
-
-class DeviceV1(Archetype):
-
- grok.implements(IArchetype)
-
- def __init__(self):
- self.adlVersion =u'1.4'
- self.archetypeId = ArchetypeId(ObjectId(u'openEHR-EHR-CLUSTER.device.v1'))
- self.concept = u'at0000'
- self.parentArchetypeId=ArchetypeId(ObjectId(u''))
-
- # Create the description components.
- self.originalLanguage=CodePhrase(u'ISO_639-1',u'en')
- self.translationDetails=None # needs to be completed in atbldr
- self.description=[u'original_author', u'name', u'Sam Heard', u'organisation', u'Ocean Informatics', u'email', u'sam.heard@xxxxxxxxxxxxxxxxxxxx', u'date', u'19/03/2008', u'details', u'en', u'language', u'_ISO_639-1::en_', u'purpose', u'Record details of devices use in clinical care', u'use', u'Use to record the details pertaining to the device that is used to record clinical details. This is likely to be as a nested archetype as part of a Protocol.', u'keywords', u'Device', u'Machine', u'Tool', u'misuse', u'', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'lifecycle_state', u'AuthorDraft', u'other_contributors', u'other_details', u'references', u''] # needs to be completed in atbldr
- self.revisionHistory=None # needs to be completed in atbldr
- self.isControlled=False # needs to be completed in atbldr
-
- # Create the ontology.
-
- # Terminologies Available Section
- termAvail=[]
- # Term Code Section (note that there is a bug in atbldr that always cutsoff the last description of termCodes)
- termCodes={u'en':{u'at0000':[_(u'text'),_(u'Device details'),_(u'description'),_(u'The details of the device used')],\
- u'at0001':[_(u'text'),_(u'Name'),_(u'description'),_(u'The name of the device')],\
- u'at0002':[_(u'text'),_(u'Description'),_(u'description'),_(u'Description of the device')],\
- u'at0003':[_(u'text'),_(u'Manufacturer'),_(u'description'),_(u'The name of the manufacturer')],\
- u'at0004':[_(u'text'),_(u'Manufacturer details'),_(u'description'),_(u'Information about the manufacture of the device')],\
- u'at0005':[_(u'text'),_(u'Model'),_(u'description'),_(u'The model of the device')],\
- u'at0006':[_(u'text'),_(u'Serial number'),_(u'description'),_(u'The serial number of the device')],\
- u'at0007':[_(u'text'),_(u'Components'),_(u'description'),_(u'Information about the device components')],\
- u'at0008':[_(u'text'),_(u'Servicing'),_(u'description'),_(u'Details of servicing')],\
- u'at0009':[_(u'text'),_(u'Date last serviced'),_(u'description'),_(u'The date the device was last serviced')],\
- u'at0010':[_(u'text'),_(u'Date last calibration'),_(u'description'),_(u'Date the device was last calibrated')],\
- u'at0011':[_(u'text'),_(u'Serviced by'),_(u'description'),_(u'Agent performed the servicing')],\
- u'at0012':[_(u'text'),_(u'Components'),_(u'description'),_()]}}
-
- # Constraint Code Section
- constCodes={}
- # Term Binding Section
- term_binding={}
- # Constraint Binding Section
- constraint_binding={}
- self.ontology=ArchetypeOntology(termAvail,specDepth,termCodes,constraintCodes,termAN,self.parentArchetypeId)
-
- # Definition Section Begins Here. We build it from the leaf nodes up.
-
- #Length of DefinList= 144
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0011'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'yyyy-??-??T??:??:??'
- #u'value'
- #1
- #u'..'
- #1
- DvDateTime(value)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0010'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'yyyy-??-??T??:??:??'
- #u'value'
- #1
- #u'..'
- #1
- DvDateTime(value)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0009'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0008'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'exclude'
- #u'/openEHR-EHR-CLUSTER\\.device\\.v1/'
- #u'archetype_id/value'
- #u'include'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0012'
- #u''
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'allow_archetype'
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0007'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0006'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0005'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0003'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0004'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0002'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0001'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #1
- nodeid=u'at0000'
- self.definition=Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
=== removed file 'src/oship/km/openehr/ehr/cluster/level_of_exertion_v1.py'
--- src/oship/km/openehr/ehr/cluster/level_of_exertion_v1.py 2010-08-02 02:06:04 +0000
+++ src/oship/km/openehr/ehr/cluster/level_of_exertion_v1.py 1970-01-01 00:00:00 +0000
@@ -1,150 +0,0 @@
-#This file was created with atbldr module from the OSHIP project.
-#Its quality is not guaranteed and will need hand editing, especially the definition section before use.
-
-import grok
-import datetime
-from zope.i18nmessageid import MessageFactory
-from oship.openehr.archetype import *
-from oship.openehr.demographic import *
-from oship.openehr.extract import *
-from oship.openehr.integration import *
-from oship.openehr.openehrprofile import *
-from oship.openehr.sm import *
-
-_ = MessageFactory('oship')
-
-class LevelOfExertionV1(Archetype):
-
- grok.implements(IArchetype)
-
- def __init__(self):
- self.adlVersion =u'1.4'
- self.archetypeId = ArchetypeId(ObjectId(u'openEHR-EHR-CLUSTER.level_of_exertion.v1'))
- self.concept = u'at0000'
- self.parentArchetypeId=ArchetypeId(ObjectId(u''))
-
- # Create the description components.
- self.originalLanguage=CodePhrase(u'ISO_639-1',u'en')
- self.translationDetails=None # needs to be completed in atbldr
- self.description=[u'original_author', u'name', u'Heather Leslie', u'organisation', u'Ocean Informatics', u'email', u'heather.leslie@xxxxxxxxxxxxxxxxxxxx', u'date', u'27/10/2008', u'details', u'en', u'language', u'_ISO_639-1::en_', u'purpose', u'Record information about the amount of energy expenditure that has been, or is being, experienced by the patient', u'use', u'Record information about phase and levels of exertion - to provide state/context information within OBSERVATIONS such as Blood Pressure.', u'keywords', u'exercise', u'work', u'exertion', u'activity', u'energy', u'misuse', u'Not to be used to record actual exercise activities and measurements which should be recorded as OBSERVATIONS in their own right.', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'lifecycle_state', u'AuthorDraft', u'other_contributors', u'other_details', u'references', u''] # needs to be completed in atbldr
- self.revisionHistory=None # needs to be completed in atbldr
- self.isControlled=False # needs to be completed in atbldr
-
- # Create the ontology.
-
- # Terminologies Available Section
- termAvail=[]
- # Term Code Section (note that there is a bug in atbldr that always cutsoff the last description of termCodes)
- termCodes={u'en':{ u'at0000':[_(u'text'),_(u'Level of Exertion'),_(u'description'),_(u'Record information about level of exertion')],\
- u'at0005':[_(u'text'),_(u'Measured'),_(u'description'),_(u'The measured level of exertion')],\
- u'at0006':[_(u'text'),_(u'At rest'),_(u'description'),_(u'The person is at rest, prior to undertaking exercise')],\
- u'at0007':[_(u'text'),_(u'During exertion'),_(u'description'),_(u'The person is exerting themselves at the time')],\
- u'at0008':[_(u'text'),_(u'Post-exertion'),_(u'description'),_(u'Measurement is taken after exertion has ceased')],\
- u'at0009':[_(u'text'),_(u'Phase'),_(u'description'),_(u'The phase or context of exercise')],\
- u'at0010':[_(u'text'),_(u'Exercise intensity'),_(u'description'),_(u'Amount of work being done during exercise')],\
- u'at0011':[_(u'text'),_(u'Intensity'),_(u'description'),_(u'Semiquantitative description of the intensity of exercise undertaken')],\
- u'at0012':[_(u'text'),_(u'Low Intensity'),_(u'description'),_(u'Up to 80% Maximal Heart Rate')],\
- u'at0013':[_(u'text'),_(u'Medium Intensity '),_(u'description'),_(u'80-85% of Maximal Heart Rate')],\
- u'at0014':[_(u'text'),_(u'High Intensity '),_(u'description'),_(u'85-90% Maximal Heart Rate')],\
- u'at0015':[_(u'text'),_(u'Flat Out '),_(u'description'),_(u'90-100% Maximal Heart Rate')],\
- u'at0016':[_(u'text'),_(u'Description'),_(u'description'),_()]}}
-
- # Constraint Code Section
- constCodes={}
- # Term Binding Section
- term_binding={}
- # Constraint Binding Section
- constraint_binding={}
- self.ontology=ArchetypeOntology(termAvail,specDepth,termCodes,constraintCodes,termAN,self.parentArchetypeId)
-
- # Definition Section Begins Here. We build it from the leaf nodes up.
-
- #Length of DefinList= 82
- #u'at0008'
- #u'at0007'
- #u'at0006'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0009'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'|'
- #1000.0
- #u'..'
- #0.0
- #u'|'
- #u'magnitude'
- #u'J/min'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::130_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0005'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'at0015'
- #u'at0014'
- #u'at0013'
- #u'at0012'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0011'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0016'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0010'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #1
- nodeid=u'at0000'
- self.definition=Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
=== removed file 'src/oship/km/openehr/ehr/composition/encounter_v1.py'
--- src/oship/km/openehr/ehr/composition/encounter_v1.py 2010-08-02 02:06:04 +0000
+++ src/oship/km/openehr/ehr/composition/encounter_v1.py 1970-01-01 00:00:00 +0000
@@ -1,65 +0,0 @@
-#This file was created with atbldr module from the OSHIP project.
-#Its quality is not guaranteed and will need hand editing, especially the definition section before use.
-
-import grok
-import datetime
-from zope.i18nmessageid import MessageFactory
-from oship.openehr.archetype import *
-from oship.openehr.demographic import *
-from oship.openehr.extract import *
-from oship.openehr.integration import *
-from oship.openehr.openehrprofile import *
-from oship.openehr.sm import *
-
-
-_ = MessageFactory('oship')
-
-class EncounterV1(Archetype):
-
- grok.implements(IArchetype)
-
- def __init__(self):
- self.adlVersion =u'1.4'
- self.archetypeId = ArchetypeId(ObjectId(u'openEHR-EHR-COMPOSITION.encounter.v1'))
- self.concept = u'at0000'
- self.parentArchetypeId=ArchetypeId(ObjectId(u''))
-
- # Create the description components.
- self.originalLanguage=CodePhrase(u'ISO_639-1',u'en')
- self.translationDetails=None # needs to be completed in atbldr
- self.description=[u'original_author', u'name', u'Thomas Beale', u'organisation', u'Ocean Informatics', u'date', u'2005-10-10', u'details', u'en', u'language', u'_ISO_639-1::en_', u'purpose', u'Record of encounter as a progress note.', u'use', u'', u'keywords', u'progress', u'note', u'encounter', u'misuse', u'', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'lifecycle_state', u'AuthorDraft', u'other_contributors'] # needs to be completed in atbldr
- self.revisionHistory=None # needs to be completed in atbldr
- self.isControlled=False # needs to be completed in atbldr
-
- # Create the ontology.
-
- # Terminologies Available Section
- termAvail=[]
- # Term Code Section (note that there is a bug in atbldr that always cutsoff the last description of termCodes)
- termCodes={u'en':{ u'at0000':[_(u'text'),_(u'Encounter'),_(u'description'),_(u'Generic encounter or progress note composition')]}}
-
- # Constraint Code Section
- constCodes={}
- # Term Binding Section
- term_binding={}
- # Constraint Binding Section
- constraint_binding={}
- self.ontology=ArchetypeOntology(termAvail,specDepth,termCodes,constraintCodes,termAN,self.parentArchetypeId)
-
- # Definition Section Begins Here. We build it from the leaf nodes up.
-
- #Length of DefinList= 12
- #u'433'
- #u'openehr::'
- #u'defining_code'
- #1
- #u'..'
- #1
- defining_code = CodePhrase(TerminologyId('openehr'),'433')
- DvCodedText(definingCode,value='',mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'category'
- #1
- #u'..'
- #1
- nodeid=u'at0000'
- self.definition=Composition(content,context,composer,category,lang,terr,uid,nodeid,name,atdetails,fdraudit,links)
=== removed file 'src/oship/km/openehr/ehr/entry/observation/blood_pressure_v1.py'
--- src/oship/km/openehr/ehr/entry/observation/blood_pressure_v1.py 2010-08-02 02:06:04 +0000
+++ src/oship/km/openehr/ehr/entry/observation/blood_pressure_v1.py 1970-01-01 00:00:00 +0000
@@ -1,532 +0,0 @@
-#This file was created with atbldr module from the OSHIP project.
-#Its quality is not guaranteed and will need hand editing, especially the definition section before use.
-
-import grok
-import datetime
-from zope.i18nmessageid import MessageFactory
-from oship.openehr.archetype import *
-from oship.openehr.demographic import *
-from oship.openehr.extract import *
-from oship.openehr.integration import *
-from oship.openehr.openehrprofile import *
-from oship.openehr.sm import *
-
-_ = MessageFactory('oship')
-
-class BloodPressureV1(Archetype):
-
- grok.implements(IArchetype)
-
- def __init__(self):
- self.adlVersion =u'1.4'
- self.archetypeId = ArchetypeId(ObjectId(u'openEHR-EHR-OBSERVATION.blood_pressure.v1'))
- self.concept = u'at0000'
- self.parentArchetypeId=ArchetypeId(ObjectId(u''))
-
- # Create the description components.
- self.originalLanguage=CodePhrase(u'ISO_639-1',u'en')
- self.translationDetails=None # needs to be completed in atbldr
- self.description=[u'original_author', u'name', u'Sam Heard', u'organisation', u'Ocean Informatics', u'email', u'sam.heard@xxxxxxxxxxxxxxxxxxxx', u'date', u'22/03/2006', u'details', u'en', u'language', u'_ISO_639-1::en_', u'purpose', u'To record the systemic arterial blood pressure of a person. ', u'use', u'All systemic arterial blood pressure measurements are recorded using this archetype. There is a rich state model, which can be used to support exercise/stress testing and research using tilt tables.', u'keywords', u'observations', u'measurement', u'bp', u'vital signs', u'mean arterial pressure', u'pulse pressure', u'systolic', u'diastolic', u'RR', u'NIBP', u'misuse', u'Not to be used for intravenous pressure.\r\nNot to be used for the recording of the measurement of arterial pressure specific locations such as the radial artery or brachial artery.\r\nUse OBSERVATION.intravascular_pressure and related specialisations in these situations.', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'ja', u'language', u'_ISO_639-1::ja_', u'purpose', u'*To record the systemic blood pressure of a person. The measurement records the systolic and the diastolic pressure by some means suitable for the result to be seen as a surrogate for the general and systemic blood pressure.(en)', u'use', u'*All blood pressure measurements are recorded using this archetype. There is a rich state model for use with exercise ECGs and Tilt Table measurements.(en)', u'keywords', u'*observations(en)', u'*blood pressure(en)', u'*measurement(en)', u'misuse', u'*Not to be used for intravascular pressure.(en)', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'de', u'language', u'_ISO_639-1::de_', u'purpose', u'Dient der Dokumentation des systemischen Blutdrucks einer Person. Die Messung zeichnet den systolischen und diastolischen Blutdruck auf geeignete Art und Weise auf, sodass das Resultat der Messung als charakteristisch f\xfcr den tats\xe4chlichen systemischen Blutdruck angesehen werden kann.', u'use', u'Alle Blutdruckmessungen werden unter Zuhilfenahme dieses Archetypen dokumentiert. Der Archetyp beinhaltet ein umfassendes Status-Modell z.B. bei Durchf\xfchrung von Belastungs-EKGs und Kipptischuntersuchungen.', u'misuse', u'Nicht zu Benutzen zur Dokumentation des intravaskul\xe4ren Drucks.', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'zh-cn', u'language', u'_ISO_639-1::zh-cn_', u'purpose', u'*To record the systemic blood pressure of a person. The measurement records the systolic and the diastolic pressure by some means suitable for the result to be seen as a surrogate for the general and systemic blood pressure.(en)', u'use', u'*All blood pressure measurements are recorded using this archetype. There is a rich state model for use with exercise ECGs and Tilt Table measurements.(en)', u'keywords', u'*observations(en)', u'*blood pressure(en)', u'*measurement(en)', u'misuse', u'*Not to be used for intravascular pressure.(en)', u'copyright', u'copyright (c) 2009 openEHR Foundation', u'lifecycle_state', u'AuthorDraft', u'other_contributors', u'Heather Leslie, Ocean Informatics', u'Sundaresan Jagannathan, NHS Scotland', u'Sebastian Garde, Ocean Informatics', u'Jeroen Meintjens, Medisch Centrum Alkmaar, Netherlands', u'Pieter Hummel, Medisch Centrum Alkmaar, Netherlands', u'Melvin Reynolds, UK', u'Evelyn Hovenga, Australia', u'Ian McNicoll, Ocean Informatics, Scotland', u'Derek Hoy, Scotland', u'Anneke Goossen, Netherlands', u'Tony Shannon, NHS, UK', u'Rong Chen, Sweden', u'Beatriz De Faria Leao, Brazil', u'Knut Bernstein, Denmark', u'Eugene Igras, IRIS Systems, Canada', u'other_details', u'references', u'Cuff sizes: Circulation (1993;88:2460-2467), by Dorothee Perloff,MD; Carlene Grim, MSN, SpDN; John Flack, MD; Edward D. Frohlich, MD; Martha Hill, PhD, RN; Mary McDonald, MSPH, RN; and Bruce Z. Morgenstern, MD, Writing Group'] # needs to be completed in atbldr
- self.revisionHistory=None # needs to be completed in atbldr
- self.isControlled=False # needs to be completed in atbldr
-
- # Create the ontology.
-
- # Terminologies Available Section
- termAvail=[u'SNOMED-CT',u'...',]
-
- # Term Code Section (note that there is a bug in atbldr that always cutsoff the last description of termCodes)
- termCodes={u'en':{ u'at0000':[_(u'text'),_(u'Blood pressure'),_(u'description'),_(u'The measurement of arterial blood pressure which is a surrogate for arterial pressure in the systemic circulation.')],\
- u'at0001':[_(u'text'),_(u'history'),_(u'description'),_(u'history Structural node')],\
- u'at0003':[_(u'text'),_(u'blood pressure'),_(u'description'),_(u'@ internal @')],\
- u'at0004':[_(u'text'),_(u'Systolic'),_(u'description'),_(u'Peak systemic arterial blood pressure over one cycle - measured in systolic or contraction phase of the heart cycle')],\
- u'at0005':[_(u'text'),_(u'Diastolic'),_(u'description'),_(u'Minimum systemic arterial blood pressure over one cycle - measured in the diastolic or relaxation phase')],\
- u'at0006':[_(u'text'),_(u'any event'),_(u'description'),_(u'Other event in event history')],\
- u'at0007':[_(u'text'),_(u'state structure'),_(u'description'),_(u'@ internal @')],\
- u'at0008':[_(u'text'),_(u'Position'),_(u'description'),_(u'The position of the person at the time of measurement')],\
- u'at0011':[_(u'text'),_(u'list structure'),_(u'description'),_(u'list structure')],\
- u'at0013':[_(u'text'),_(u'Cuff size'),_(u'description'),_(u'The size of the cuff used for blood pressure measurement')],\
- u'at0014':[_(u'text'),_(u'Location of measurement'),_(u'description'),_(u'The site of the measurement of the blood pressure')],\
- u'at0015':[_(u'text'),_(u'Adult'),_(u'description'),_(u'A cuff that is standard for an adult - bladder approx 13cm x 30cm')],\
- u'at0016':[_(u'text'),_(u'Large Adult'),_(u'description'),_(u'A cuff for adults with larger arms - bladder approx 16cm x 38cm')],\
- u'at0017':[_(u'text'),_(u'Paediatric/Child'),_(u'description'),_(u'A cuff that is appropriate for a child or thin arm - bladder approx 8cm x 21cm')],\
- u'at0025':[_(u'text'),_(u'Right arm'),_(u'description'),_(u'The right arm of the person')],\
- u'at0026':[_(u'text'),_(u'Left arm'),_(u'description'),_(u'The left arm of the person')],\
- u'at0027':[_(u'text'),_(u'Right thigh'),_(u'description'),_(u'The right thigh of the person')],\
- u'at0028':[_(u'text'),_(u'Left thigh'),_(u'description'),_(u'The left thigh of the person')],\
- u'at0031':[_(u'text'),_(u'Postural change'),_(u'description'),_(u'The difference between standing and sitting/lying blood pressure')],\
- u'at0033':[_(u'text'),_(u'Comment'),_(u'description'),_(u'Comment on blood pressure measurement')],\
- u'at1000':[_(u'text'),_(u'Standing'),_(u'description'),_(u'Standing at the time of blood pressure measurement')],\
- u'at1001':[_(u'text'),_(u'Sitting'),_(u'description'),_(u'Sitting (for example on bed or chair) at the time of blood pressure measurement')],\
- u'at1002':[_(u'text'),_(u'Reclining'),_(u'description'),_(u'Reclining at the time of blood pressure measurement')],\
- u'at1003':[_(u'text'),_(u'Lying'),_(u'description'),_(u'Lying flat at the time of blood pressure measurement')],\
- u'at1004':[_(u'text'),_(u'Paradox'),_(u'description'),_(u'Variation in blood pressure with respiration')],\
- u'at1005':[_(u'text'),_(u'Tilt'),_(u'description'),_(u'The craniocaudal tilt of the surface on which the person is lying at the time of measurement')],\
- u'at1006':[_(u'text'),_(u'Mean Arterial Pressure'),_(u'description'),_(u'The average arterial pressure that occurs over the entire course of the heart contraction and relaxation cycle. ')],\
- u'at1007':[_(u'text'),_(u'Pulse Pressure'),_(u'description'),_(u'The difference between the systolic and diastolic pressure over one contraction cycle.')],\
- u'at1008':[_(u'text'),_(u'Adult Thigh'),_(u'description'),_(u'A cuff used for an adult thigh - bladder approx 20cm x 42cm')],\
- u'at1009':[_(u'text'),_(u'Neonatal'),_(u'description'),_(u'A cuff used for a new born - bladder approx 3cm x 6cm')],\
- u'at1010':[_(u'text'),_(u'Korotkoff sounds'),_(u'description'),_(u'Record which Korotkoff sound is used for determining diastolic pressure')],\
- u'at1011':[_(u'text'),_(u'Fourth sound'),_(u'description'),_(u'The fourth Korotkoff sound is identified as an abrupt muffling of sounds')],\
- u'at1012':[_(u'text'),_(u'Fifth sound'),_(u'description'),_(u'The fifth Korotkoff sound is identified by absence of sounds as the cuff pressure drops below the diastolic blood pressure')],\
- u'at1013':[_(u'text'),_(u'Trendelenburg'),_(u'description'),_(u'Lying flat on the back (supine position) with the feet higher than the head at the time of blood pressure measurement')],\
- u'at1014':[_(u'text'),_(u'Left Lateral'),_(u'description'),_(u'Lying on the left side at the time of blood pressure measurement')],\
- u'at1018':[_(u'text'),_(u'Infant'),_(u'description'),_(u'A cuff used for infants - bladder approx 5cm x 15cm')],\
- u'at1019':[_(u'text'),_(u'Small Adult'),_(u'description'),_(u'A cuff used for a small adult - bladder approx 10cm x 24cm')],\
- u'at1020':[_(u'text'),_(u'Right wrist'),_(u'description'),_(u'The right wrist of the person')],\
- u'at1021':[_(u'text'),_(u'Left wrist'),_(u'description'),_(u'The left wrist of the person')],\
- u'at1025':[_(u'text'),_(u'Device'),_(u'description'),_(u'Details about sphygmomanometer or other device used to measure the blood pressure')],\
- u'at1026':[_(u'text'),_(u'Finger'),_(u'description'),_(u'A finger of the person')],\
- u'at1030':[_(u'text'),_(u'Exertion '),_(u'description'),_(u'Details about physical activity undertaken at the time of blood pressure measurement')],\
- u'at1031':[_(u'text'),_(u'Right ankle'),_(u'description'),_(u'The right ankle of the person')],\
- u'at1032':[_(u'text'),_(u'Left ankle'),_(u'description'),_(u'The left ankle of the person')],\
- u'at1033':[_(u'text'),_(u'Location'),_(u'description'),_(u'Body site of blood pressure location')],\
- u'at1034':[_(u'text'),_(u'Description of location'),_(u'description'),_(u'Detailed description about the site of the measurement of the blood pressure')],\
- u'at1035':[_(u'text'),_(u'Method'),_(u'description'),_(u'Method of measurement of blood pressure')],\
- u'at1036':[_(u'text'),_(u'Auscultation'),_(u'description'),_(u'Method of measuring blood pressure externally, using a stethoscope and Korotkoff sounds')],\
- u'at1037':[_(u'text'),_(u'Palpation'),_(u'description'),_(u'Method of measuring blood pressure externally, using palpation (usually of the radial artery at the wrist)')],\
- u'at1038':[_(u'text'),_(u'Mean Arterial Pressure Formula'),_(u'description'),_(u'Formula used to calculate the MAP (if recorded in data)')],\
- u'at1039':[_(u'text'),_(u'Machine'),_(u'description'),_(u'Method of measuring blood pressure externally, using a blood pressure machine')],\
- u'at1040':[_(u'text'),_(u'Invasive'),_(u'description'),_(u'Method of measuring blood pressure internally ie involving penetration of the skin and measuring inside blood vessels')],\
- u'at1041':[_(u'text'),_(u'Anxiety '),_(u'description'),_(u"Details about the subject's level of anxiety at the time of blood pressure measurement")]}}
-
- # Constraint Code Section
- constCodes={}
- # Term Binding Section
- term_binding={u'SNOMED-CT':[{u'at0000':u'_SNOMED-CT(2003)::163020007_'},{u'at0004':u'_SNOMED-CT(2003)::163030003_'},{u'at0005':u'_SNOMED-CT(2003)::163031004_'},{u'at0013':u'_SNOMED-CT(2003)::246153002_'},]}
-
- # Constraint Binding Section
- constraint_binding={}
- self.ontology=ArchetypeOntology(termAvail,specDepth,termCodes,constraintCodes,termAN,self.parentArchetypeId)
-
- # Definition Section Begins Here. We build it from the leaf nodes up.
-
- #Length of DefinList= 399
- #u'at1012'
- #u'at1011'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1010'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1038'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'exclude'
- #u'/openEHR-EHR-CLUSTER\\.device\\.v1/'
- #u'archetype_id/value'
- #u'include'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1025'
- #u''
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'allow_archetype'
- #u'at1040'
- #u'at1039'
- #u'at1037'
- #u'at1036'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1035'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1034'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'at1032'
- #u'at1031'
- #u'at1026'
- #u'at1021'
- #u'at1020'
- #u'at0028'
- #u'at0027'
- #u'at0026'
- #u'at0025'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0014'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1033'
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'at1019'
- #u'at1018'
- #u'at1009'
- #u'at1008'
- #u'at0017'
- #u'at0016'
- #u'at0015'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0013'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #1
- nodeid=u'at0011'
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'protocol'
- nodeid=u'at0001_/events_at0006_/state_at0007'
- #u'/data'
- #1
- #u'..'
- #1
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'use_node'
- #u'state'
- nodeid=u'at0001_/events_at0006_/data_at0003'
- #u'/data'
- #1
- #u'..'
- #1
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'use_node'
- #u'data'
- #u'149'
- #u'openehr::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'math_function'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1004'
- IntervalEvent(width,mfunc,scount)
- nodeid=u'at0001_/events_at0006_/state_at0007'
- #u'/data'
- #1
- #u'..'
- #1
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'use_node'
- #u'state'
- nodeid=u'at0001_/events_at0006_/data_at0003'
- #u'/data'
- #1
- #u'..'
- #1
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'use_node'
- #u'data'
- #u'147'
- #u'openehr::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'math_function'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0031'
- IntervalEvent(width,mfunc,scount)
- #0
- #u'precision'
- #u'\xb0'
- #u'units'
- #0.0
- #u'magnitude'
- #u'assumed_value'
- #u'|'
- #0
- #u'|'
- #u'precision'
- #u'|'
- #90.0
- #u'..'
- #-90.0
- #u'|'
- #u'magnitude'
- #u'\xb0'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::497_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1005'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'exclude'
- #u'/.*/'
- #u'archetype_id/value'
- #u'include'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1041'
- #u''
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'allow_archetype'
- #u'exclude'
- #u'/openEHR-EHR-CLUSTER\\.level_of_exertion\\.v1/'
- #u'archetype_id/value'
- #u'include'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1030'
- #u''
- Cluster(uid,nodeid,name,archetypeDetails,feederAudit,links,items)
- #u'allow_archetype'
- #u'at1001'
- #u'at1014'
- #u'at1013'
- #u'at1003'
- #u'at1002'
- #u'at1001'
- #u'at1000'
- #u'local::'
- #u'defining_code'
- #1
- #u'..'
- #1
- DvCodedText(definingCode,value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0008'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #1
- nodeid=u'at0007'
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'state'
- #u'*'
- #1
- #u'..'
- #1
- DvText(value,mappings=None,formatting=None,hyperlink=None,language=None,encoding=None)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0033'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'|'
- #0
- #u'|'
- #u'precision'
- #u'|'
- #1000.0
- #u'<'
- #u'..'
- #0.0
- #u'|'
- #u'magnitude'
- #u'mm_Hg_'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::125_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1007'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'|'
- #0
- #u'|'
- #u'precision'
- #u'|'
- #1000.0
- #u'<'
- #u'..'
- #0.0
- #u'|'
- #u'magnitude'
- #u'mm_Hg_'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::125_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at1006'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'|'
- #0
- #u'|'
- #u'precision'
- #u'|'
- #1000.0
- #u'<'
- #u'..'
- #0.0
- #u'|'
- #u'magnitude'
- #u'mm_Hg_'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::125_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0005'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'|'
- #0
- #u'|'
- #u'precision'
- #u'|'
- #1000.0
- #u'<'
- #u'..'
- #0.0
- #u'|'
- #u'magnitude'
- #u'mm_Hg_'
- #u'units'
- #u'"1"'
- #u'list'
- #u'_openehr::125_'
- #u'property'
- CDvQuantity(list,property)
- #u'value'
- #1
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0004'
- Element(value,nullFlavor,nodeid,uid,name,atdetails,fdraudit,links)
- #u'unordered'
- #u'*'
- #u'..'
- #0
- #u'cardinality'
- #u'items'
- #1
- #u'..'
- #1
- nodeid=u'at0003'
- ItemTree(uid,nodeid,name, atdetails, fdraudit, links, items)
- #u'data'
- #u'*'
- #u'..'
- #0
- #u'occurrences'
- nodeid=u'at0006'
- Event(time,data,state,parent,offset)
- #u'unordered'
- #u'*'
- #u'..'
- #1
- #u'cardinality'
- #u'events'
- #1
- #u'..'
- #1
- nodeid=u'at0001'
- History(origin,events,period,duration,summary,uid,nodeid,name,atdetails,fdraudit,links)
- #u'data'
- #1
- #u'..'
- #1
- nodeid=u'at0000'
- self.definition=Observation(data,state,nodeid,protocol,gid,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links)
=== modified file 'src/oship/openehr/__init__.py'
--- src/oship/openehr/__init__.py 2009-04-26 09:48:59 +0000
+++ src/oship/openehr/__init__.py 2010-08-06 02:32:43 +0000
@@ -1,1 +1,1 @@
-# this directory is a package
+# This is a package
\ No newline at end of file
=== modified file 'src/oship/openehr/adl2xsd.py'
--- src/oship/openehr/adl2xsd.py 2010-07-25 15:56:04 +0000
+++ src/oship/openehr/adl2xsd.py 2010-08-06 02:32:43 +0000
@@ -40,8 +40,8 @@
from classmap import getClassName
from archetype import ArchetypeOntology
-from oship.rm.support import *
-from oship.rm.datatypes import *
+from oship.openehr.rm.support import *
+from oship.openehr.rm.datatypes import *
from demographic import *
import adl_1_4
from utils import Languages
=== modified file 'src/oship/openehr/archetype.py'
--- src/oship/openehr/archetype.py 2010-08-01 16:37:49 +0000
+++ src/oship/openehr/archetype.py 2010-08-06 02:32:43 +0000
@@ -24,9 +24,9 @@
from zope.schema.interfaces import IField
from zope.i18nmessageid import MessageFactory
-from oship.rm.support.interfaces import IArchetypeId,IUidBasedId,IObjectRef
-from oship.rm.common.resource import AuthoredResource
-from oship.rm.datatypes.quantity.interfaces import IDvInterval
+from oship.openehr.rm.support.interfaces import IArchetypeId,IUidBasedId,IObjectRef
+from oship.openehr.rm.common.resource import AuthoredResource
+from oship.openehr.rm.datatypes.quantity.interfaces import IDvInterval
_ = MessageFactory('oship')
=== modified file 'src/oship/openehr/demographic.py'
--- src/oship/openehr/demographic.py 2010-08-01 16:37:49 +0000
+++ src/oship/openehr/demographic.py 2010-08-06 02:32:43 +0000
@@ -26,11 +26,11 @@
from zope.i18nmessageid import MessageFactory
import grok
from grok import index
-from oship.rm.common.archetyped import Locatable, ILocatable
-from oship.rm.support.interfaces import IUidBasedId, IPartyRef, ILocatableRef
-from oship.rm.datatypes.text.interfaces import IDvText, IDvCodedText, ICodePhrase
-from oship.rm.datatypes.quantity.interfaces import IDvInterval
-from oship.rm.data_structures.item_structure.interfaces import IItemStructure
+from oship.openehr.rm.common.archetyped import Locatable, ILocatable
+from oship.openehr.rm.support.interfaces import IUidBasedId, IPartyRef, ILocatableRef
+from oship.openehr.rm.datatypes.text.interfaces import IDvText, IDvCodedText, ICodePhrase
+from oship.openehr.rm.datatypes.quantity.interfaces import IDvInterval
+from oship.openehr.rm.data_structures.item_structure.interfaces import IItemStructure
from oship.app import OSHIP
=== modified file 'src/oship/openehr/extract.py'
--- src/oship/openehr/extract.py 2010-08-02 01:10:26 +0000
+++ src/oship/openehr/extract.py 2010-08-06 02:32:43 +0000
@@ -21,18 +21,18 @@
from zope.schema import TextLine, Field, List, Int, Object, Bool, Set, Dict, \
Container
-from oship.rm.common.archetyped import Locatable
-from oship.rm.common.archetyped.interfaces import IPartyIdentified, ILocatable
-from oship.rm.common.generic.interfaces import IRevisionHistory, IAuditDetails
-from oship.rm.common.directory.interfaces import IFolder
-from oship.rm.common.change_control.interfaces import IOriginalVersion, IVersion
-from oship.rm.support.interfaces import (IArchetypeId, IUidBasedId,
+from oship.openehr.rm.common.archetyped import Locatable
+from oship.openehr.rm.common.archetyped.interfaces import IPartyIdentified, ILocatable
+from oship.openehr.rm.common.generic.interfaces import IRevisionHistory, IAuditDetails
+from oship.openehr.rm.common.directory.interfaces import IFolder
+from oship.openehr.rm.common.change_control.interfaces import IOriginalVersion, IVersion
+from oship.openehr.rm.support.interfaces import (IArchetypeId, IUidBasedId,
IObjectRef, ILocatableRef)
-from oship.rm.data_structures.item_structure.interfaces import IItemStructure
-from oship.rm.datatypes.quantity.datetime.interfaces import (IDvDuration,
+from oship.openehr.rm.data_structures.item_structure.interfaces import IItemStructure
+from oship.openehr.rm.datatypes.quantity.datetime.interfaces import (IDvDuration,
IDvDateTime,)
-from oship.rm.datatypes.uri.interfaces import IDvUri
-from oship.rm.composition.interfaces import IComposition, IPartyProxy
+from oship.openehr.rm.datatypes.uri.interfaces import IDvUri
+from oship.openehr.rm.composition.interfaces import IComposition, IPartyProxy
_ = MessageFactory('oship')
=== modified file 'src/oship/openehr/integration.py'
--- src/oship/openehr/integration.py 2010-08-02 01:10:26 +0000
+++ src/oship/openehr/integration.py 2010-08-06 02:32:43 +0000
@@ -24,8 +24,8 @@
from zope.schema import Field, Object
from zope.i18nmessageid import MessageFactory
-from oship.rm.data_structures.item_structure.interfaces import IItemTree
-from oship.rm.composition.content import ContentItem
+from oship.openehr.rm.data_structures.item_structure.interfaces import IItemTree
+from oship.openehr.rm.composition.content import ContentItem
_ = MessageFactory('oship')
=== modified file 'src/oship/openehr/openehrprofile.py'
--- src/oship/openehr/openehrprofile.py 2010-07-12 21:32:11 +0000
+++ src/oship/openehr/openehrprofile.py 2010-08-06 02:32:43 +0000
@@ -23,11 +23,11 @@
import grok
from oship.openehr.archetype import CDomainType
-from oship.rm.datatypes.text.interfaces import ICodePhrase
-from oship.rm.datatypes.quantity.interfaces import IDvOrdinal,IDvInterval
+from oship.openehr.rm.datatypes.text.interfaces import ICodePhrase
+from oship.openehr.rm.datatypes.quantity.interfaces import IDvOrdinal,IDvInterval
-from oship.rm.support import Interval
-from oship.rm.support.interfaces import ITerminologyId
+from oship.openehr.rm.support import Interval
+from oship.openehr.rm.support.interfaces import ITerminologyId
_ = MessageFactory('oship')
=== added directory 'src/oship/openehr/rm'
=== added file 'src/oship/openehr/rm/__init__.py'
--- src/oship/openehr/rm/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,1 @@
+# This is a package
\ No newline at end of file
=== added file 'src/oship/openehr/rm/__init__.pyc'
Binary files src/oship/openehr/rm/__init__.pyc 1970-01-01 00:00:00 +0000 and src/oship/openehr/rm/__init__.pyc 2010-08-06 02:32:43 +0000 differ
=== added directory 'src/oship/openehr/rm/common'
=== added file 'src/oship/openehr/rm/common/__init__.py'
--- src/oship/openehr/rm/common/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,1 @@
+# This file just exists to make it's directory as a module.
=== added directory 'src/oship/openehr/rm/common/archetyped'
=== added file 'src/oship/openehr/rm/common/archetyped/__init__.py'
--- src/oship/openehr/rm/common/archetyped/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/archetyped/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,245 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import grok
+from interfaces import *
+
+
+class Pathable(grok.Model):
+ """
+ Abstract parent of all classes whose instances are reachable by paths, and
+ which know how to locate child object by paths. The parent feature may be
+ implemented as a function or attribute.
+
+ The two attributes required for locatable in Grok is __parent__ and
+ __name__. We inherit those from grok.Model.
+
+ The functionality to get paths and find children is contained in the
+ traversal mechanism. """
+
+ grok.implements(IPathable)
+
+
+
+ def pathOfItem(an_item):
+ """
+ The path to an item relative to the root of this archetyped structure.
+
+ getPath is from the Traversal API.
+ """
+
+ def itemAtPath(a_path):
+ """
+ The item at a path (relative to this item);only valid for unique paths,
+ i.e. paths that resolve to a single item. a_path is a string. Return
+ a_path is not None and pathUnique(a_path)
+
+ If the path is not unique or not found then a TraversalError is raised.
+ """
+
+ def itemsAtPath(a_path):
+ """
+ List of items corresponding to a non-unique path.
+ a_path is a List
+ Return a_path is not None and pathUnique(a_path)
+ """
+
+ def pathExists(a_path):
+ """
+ True if the path exists in the data with respect to the current item.
+ Return a_path is not None and a_path != ''
+ """
+
+ def pathUnique(a_path):
+ """
+ True if the path corresponds to a single item in the data.
+ Return a_path is not None and pathExists(a_path)
+ """
+
+
+class Locatable(Pathable):
+ """
+ Root class of all information model classes that can be archetyped.
+ """
+
+ grok.implements(ILocatable)
+
+ def __init__(self, uid, atnodeid, name, atdetails, fdraudit, links):
+ self.uid=uid
+ self.archetypeNodeId=atnodeid
+ self.name=name
+ self.archetypeDetails=atdetails
+ self.feederAudit=fdraudit
+ self.links=links
+
+ def isArchetypeRoot(self):
+ """True if this node is the root of an archetyped structure. At
+ specification there's a requiment for archetypeDetails in all root
+ points in data """
+ return self.archetypeDetails is not None
+
+ def concept():
+ """
+ Clinical concept of the archetype as a whole (= derived from the
+ 'archetype_node_id' of the root node) isArchetypeRoot must be True.
+ """
+ if (self.isArchetypeRoot()):
+ return DvText(self.archetypeDetails.archetypeId.conceptName())
+ raise TypeError('Not root node')
+
+ def nameValid():
+ """ name is not None"""
+ return self.name is not None
+
+ def linksValid():
+ """ links is not None and links != []"""
+ if self.links is not None:
+ return self.links != []
+ return self.links is None
+
+ def archetypedValid():
+ """ isArchetypeRoot xor archetypeDetails = None """
+ return xor(self.isArchetypeRoot(), self.archetypeDetails is None)
+
+ def archetypeNodeIdValid():
+ """ archetypeNodeId is not None and archetypeNodeId != '' """
+ if(self.archetypeNodeId is not None):
+ return self.archetypeNodeId != ''
+ return self.archetypeNodeId is None
+
+ def __eq__(self, obj):
+ if self is obj:
+ return True
+ if isinstance(obj, Locatable):
+ return obj.uid == self.uid and obj.archetypeNodeId == self.archetypeNodeId and obj.name == self.name and obj.archetypeDetails == self.archetypeDetails and obj.feederAudit == self.feederAudit and obj.links == self.links
+ return False
+
+ def __hash__(self):
+ result = 17
+ result += 31 * result + hash(self.uid)
+ result += 31 * result + hash(self.archetypeNodeId)
+ result += 31 * result + hash(self.name)
+ result += 31 * result + hash(self.archetypeDetails)
+ result += 31 * result + hash(self.feederAudit)
+ result += 31 * result + hash(self.links)
+ return result
+
+
+class Archetyped(grok.Model):
+ """
+ Archetypes act as the configuration basis for the particular structures of
+ instances defined by the reference model. To enable archetypes to be used
+ to create valid data, key classes in the reference model act as "root"
+ points for archetyping; accordingly, these classes have the
+ archetype_details attribute set. An instance of the class ARCHETYPED
+ contains the relevant archetype identification information, allowing
+ generating archetypes to be matched up with data instances """
+
+ grok.implements(IArchetyped)
+
+ def __init__(self, atid, tmplid, rmver):
+ self.archetypeId=atid
+ self.templateId=tmplid
+ self.rmVersion=rmver
+
+ def archetypeIdValid():
+ """ archetypeId is not None """
+
+ def rmVersionValid():
+ """ rmVersion is not None and rmVersion != '' """
+
+ def __eq__(self, obj):
+ if obj is self:
+ return True
+ if isinstance(obj, Archetyped):
+ return obj.archetypeId == self.archetypeId and obj.templateId == self.templateId and obj.rmVersion == self.rmVersion
+ return False
+
+ def __hash__(self):
+ result = 17
+ result = 31 * result + hash(self.archetypeId)
+ result = 31 * result + hash(self.templateId)
+ result = 31 * result + hash(self.rmVersion)
+ return result
+
+
+class FeederAuditDetails(grok.Model):
+ u"""
+ Audit details for any system in a feeder system chain. Audit details here
+ means the general notion of who/where/when the information item to which
+ the audit is attached was created. None of the attributes is defined as
+ mandatory, however, in different scenarios, various combinations of
+ attributes will usually be mandatory. This can be controlled by specifying
+ feeder audit details in legacy archetypes. """
+
+ grok.implements(IFeederAuditDetails)
+
+ def __init__(self, sysid, provider, location, time, subject, verid):
+
+
+ self.systemId=sysid
+ self.provider=provider
+ self.location=location
+ self.time=time
+ self.subject=subject
+ self.versionId=verid
+
+ def systemIdValid():
+ u"""systemId is not None and systemId != '' """
+
+
+class FeederAudit(Locatable):
+ """
+ Audit and other meta-data for systems in the feeder chain.
+ """
+
+ grok.implements(IFeederAudit)
+
+ def __init__(self, orgsysaudit, orgsysids, fsaudit, fsauditids,
+ orgcontent):
+
+
+ self.originatingSystemAudit=orgsysaudit
+ self.originatingSystemItemIds=orgsysids
+ self.feederSystemAudit=fsaudit
+ self.feederSystemItemIds=fsauditids
+ self.originalContent=orgcontent
+
+ def originatingSystemAuditValid():
+ """ originatingSystemAudit is not None """
+
+
+class Link(Locatable):
+ """
+ The LINK type defines a logical relationship between two items, such as two
+ ENTRYs or an ENTRY and a COMPOSITION. Links can be used across composi-
+ tions, and across EHRs. Links can potentially be used between interior
+ (i.e. non archetype root) nodes, although this probably should be prevented
+ in archetypes. Multiple LINKs can be attached to the root object of any
+ archetyped structure to give the effect of a 1->N link 1:1 and 1:N
+ relationships between archetyped content elements (e.g. ENTRYs) can be
+ expressed by using one, or more than one, respectively, DV_LINKs. Chains of
+ links can be used to see "problem threads" or other logical groupings of
+ items. Links should be between archetyped structures only, i.e. between
+ objects representing complete domain concepts because relationships between
+ sub-elements of whole concepts are not necessarily meaningful, and may be
+ downright confusing. Sensible links only exist between whole ENTRYs,
+ SECTIONs, COMPOSITIONs and so on. """
+
+ grok.implements(ILink)
+
+ def __init__(self, meaning, type_, target):
+
+ self.meaning=meaning
+ self.type_=type_
+ self.target=target
+
+ def meaningValid():
+ """Return meaning is not None """
+
+ def typeValid():
+ """Return type is not None """
+
+ def targetValid():
+ """Return target is not None """
+
=== added file 'src/oship/openehr/rm/common/archetyped/interfaces.py'
--- src/oship/openehr/rm/common/archetyped/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/archetyped/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,436 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface
+from zope.schema import TextLine, Object, List, Set
+from zope.i18nmessageid import MessageFactory
+import grok
+
+from oship.openehr.rm.support.interfaces import IArchetypeId, ITemplateId, IUidBasedId
+from oship.openehr.rm.datatypes.basic import IDvIdentifier
+from oship.openehr.rm.datatypes.text.interfaces import IDvText
+from oship.openehr.rm.datatypes.quantity.datetime.interfaces import IDvDateTime
+from oship.openehr.rm.datatypes.encapsulated.interfaces import IDvEncapsulated
+from oship.openehr.rm.datatypes.uri.interfaces import IDvEhrUri
+from oship.openehr.rm.common.generic.interfaces import IPartyIdentified
+from oship.openehr.rm.common.generic.interfaces import IPartyProxy
+
+_ = MessageFactory('oship')
+
+
+class ILink(Interface):
+ """
+ The LINK type defines a logical relationship between two items, such as two
+ ENTRYs or an ENTRY and a COMPOSITION. Links can be used across composi-
+ tions, and across EHRs. Links can potentially be used between interior
+ (i.e. non archetype root) nodes, although this probably should be prevented
+ in archetypes. Multiple LINKs can be attached to the root object of any
+ archetyped structure to give the effect of a 1->N link 1:1 and 1:N
+ relationships between archetyped content elements (e.g. ENTRYs) can be
+ expressed by using one, or more than one, respectively, DV_LINKs. Chains of
+ links can be used to see "problem threads" or other logical groupings of
+ items. Links should be between archetyped structures only, i.e. between
+ objects representing complete domain concepts because relationships between
+ sub-elements of whole concepts are not necessarily meaningful, and may be
+ downright confusing. Sensible links only exist between whole ENTRYs,
+ SECTIONs, COMPOSITIONs and so on. """
+
+ meaning = Object(
+ schema=IDvText,
+ title=_(u"Meaning"),
+ description=_(u"""Used to describe the relationship, usually in
+ clinical terms, such as "in response to"
+ (the relationship between test results and an order),
+ "follow-up to" and so on. Such relationships can represent
+ any clinically meaningful connection between pieces of
+ information. Values for meaning include those described in
+ Annex C, ENV 13606 pt 2 [11] under the categories of
+ "generic", "documenting and
+ reporting","organisational","clinical",
+ "circumstancial", and "view management". """),
+
+ )
+
+ type_ = Object(
+ schema=IDvText,
+ title=_(u"Type"),
+ description=_(u"""The type attribute is used to indicate a clinical or
+ domain-level meaning for the kind of link, for example "problem" or
+ "issue". If type values are designed appropriately, they can be used by
+ the requestor of EHR extracts to categorise links which must be
+ followed and which can be broken when the extract is created. """),
+
+ )
+
+ target = Object(
+ schema=IDvEhrUri,
+ title=_(u"Target"),
+ description=_(u"""The logical "to" object in the link relation,
+ as target: per the linguistic sense of the meaning
+ attribute."""),
+
+ )
+
+ def meaningValid():
+ """Return meaning is not None """
+
+ def typeValid():
+ """Return type is not None """
+
+ def targetValid():
+ """Return target is not None """
+
+
+
+class IFeederAuditDetails(Interface):
+ u"""
+ Audit details for any system in a feeder system chain. Audit details
+ here means the general notion of who/where/when the information item to
+ which the audit is attached was created. None of the attributes is defined
+ as mandatory, however, in different scenarios, various combinations of
+ attributes will usually be mandatory. This can be controlled by specifying
+ feeder audit details in legacy archetypes. """
+
+ systemId = TextLine(
+ title=_(u'System Id'),
+ description=_(u"""Identifier of the system which handled the
+ information item."""),
+ )
+
+ provider = Object(
+ schema=IPartyIdentified,
+ title=_(u'Provider'),
+ description=_(u"""Optional provider(s) who created, committed,
+ forwarded or otherwise handled the item. Type ==
+ PARTY_IDENTIFIED"""),
+ required=False,
+ )
+
+ location = Object(
+ schema=IPartyIdentified,
+ title=_(u'Location'),
+ description=_(u"""Identifier of the particular site/facility within an
+ organisation which handled the item. For computability, this identifier
+ needs to be e.g. a PKI identifier which can be included in the
+ identifier list of the PARTY_IDENTIFIED object."""),
+ required=False,
+ )
+
+ time = Object(
+ schema=IDvDateTime,
+ title=_(u'Time'),
+ description=_(u"""Time of handling the item. For an originating time:
+ DV_DATE_TIME system, this will be time of creation, for an intermediate
+ feeder system, this will be a time of accession or other time of
+ handling, where available."""),
+ required=False,
+ )
+
+ subject = Object(
+ schema=IPartyProxy,
+ title=_(u'Subject'),
+ description=_(u"""Identifiers for subject of the received information
+ item."""),
+ required=False,
+ )
+
+ versionId = TextLine(
+ title=_(u'Version Id'),
+ description=_(u"""Any identifier used in the system such as "interim",
+ "final",
+ or numeric versions if available."""),
+ required=False,
+ )
+
+ def systemIdValid():
+ u"""systemId is not None and systemId != '' """
+
+
+class IFeederAudit(Interface):
+ """
+ Audit and other meta-data for systems in the feeder chain.
+ """
+
+ originatingSystemAudit = Object(
+ schema=IFeederAuditDetails,
+ title=_(u"Originating System Audit"),
+ description=_(u"""Any audit information for the information item from
+ the originating system."""),
+
+ )
+
+ originatingSystemItemIds = List(
+ value_type=Object(schema=IDvIdentifier),
+ title=_(u"Originating System Item IDs"),
+ description=_(u"""Identifiers used for the item in the originating
+ system, e.g. filler and placer ids."""),
+ required=False,
+ )
+
+
+ feederSystemAudit = Object(
+ schema=IFeederAuditDetails,
+ title=_(u"Feeder System Audit"),
+ description=_(u"""Any audit information for the information item from
+ the feeder system, if different from the originating system."""),
+ required=False,
+ )
+
+ feederSystemItemIds = List(
+ value_type=Object(schema=IDvIdentifier),
+ title=_(u"Feeder System Item IDs"),
+ description=_(u"""Identifiers used for the item in the feeder system,
+ where the feeder system is distinct from the originating system. The
+ List contents are restricted to type == DvIdentifiers"""),
+ required=False,
+ )
+
+ originalContent=Object(
+ schema=IDvEncapsulated,
+ title=_(u"Original Content"),
+ description=_(u""" """),
+ required=False,
+ )
+
+ def originatingSystemAuditValid():
+ """ originatingSystemAudit is not None """
+
+
+class IArchetyped(Interface):
+ """
+ Archetypes act as the configuration basis for the particular structures of
+ instances defined by the reference model. To enable archetypes to be used
+ to create valid data, key classes in the reference model act as "root"
+ points for archetyping; accordingly, these classes have the
+ archetype_details attribute set. An instance of the class ARCHETYPED
+ contains the relevant archetype identification information, allowing
+ generating archetypes to be matched up with data instances """
+
+ archetypeId = Object(
+ schema=IArchetypeId,
+ title=_(u"Archetype ID"),
+ description=_(u"Globally unique archetype identifier."),
+ )
+
+ templateId = Object(
+ schema=ITemplateId,
+ title=_(u"Template ID"),
+ description=_(u"""Globally unique template identifier, if a template
+ was active at this point in the structure. Normally, a template would
+ only be used at the top of a top-level structure, but the possibility
+ exists for templates at lower levels."""),
+ required=False,
+ )
+
+ rmVersion = TextLine(
+ title=_(u"RM Version"),
+ description=_(u"""Version of the openEHR reference model used to create
+ this object. Expressed in terms of the release version string, e.g.
+ "1.0", "1.2.4". """),
+ )
+
+ def archetypeIdValid():
+ """ archetypeId is not None """
+
+ def rmVersionValid():
+ """ rmVersion is not None and rmVersion != '' """
+
+
+class IPathable(Interface):
+ """
+ Abstract parent of all classes whose instances are reachable by paths, and
+ which know how to locate child object by paths. The parent feature may be
+ implemented as a function or attribute.
+
+ The two attributes required for locatable in Grok is __parent__ and
+ __name__. We inherit those from grok.Model.
+
+ The functionality to get paths and find children is contained in the
+ traversal mechanism. """
+
+ def pathOfItem(an_item):
+ """
+ The path to an item relative to the root of this archetyped structure.
+
+ getPath is from the Traversal API.
+ """
+
+ def itemAtPath(a_path):
+ """
+ The item at a path (relative to this item);only valid for unique paths,
+ i.e. paths that resolve to a single item. a_path is a string. Return
+ a_path is not None and pathUnique(a_path)
+
+ If the path is not unique or not found then a TraversalError is raised.
+ """
+
+ def itemsAtPath(a_path):
+ """
+ List of items corresponding to a non-unique path.
+ a_path is a List
+ Return a_path is not None and pathUnique(a_path)
+ """
+
+ def pathExists(a_path):
+ """
+ True if the path exists in the data with respect to the current item.
+ Return a_path is not None and a_path != ''
+ """
+
+ def pathUnique(a_path):
+ """
+ True if the path corresponds to a single item in the data.
+ Return a_path is not None and pathExists(a_path)
+ """
+
+
+class ILocatable(Interface):
+ u"""
+ Root class of all information model classes that can be archetyped.
+ """
+
+
+ uid = Object(
+ schema=IUidBasedId,
+ title=_(u"UID"),
+ description=_(u"Optional globally unique object identifier for root"
+ " points of archetyped structures. A UidBasedId "),
+ required=False,
+ )
+
+
+ archetypeNodeId = TextLine(
+ title=_(u"Node ID"),
+ description=_(u"""Design-time archetype id of this node taken from its
+ generating archetype; used to build archetype paths. Always in the form
+ of an "at" code, e.g. "at0005". This value enables a "standardised"
+ name for this node to be generated, by referring to the generating
+ archetype local ontology. At an archetype root point, the value of this
+ attribute is always the stringified form of the archetype_id found in
+ the archetype_details object."""),
+ required=True)
+
+ name = Object(
+ schema=IDvText,
+ title=_(u"Name"),
+ description=_(u"""DvText type - Runtime name of this fragment, used to
+ build runtime paths. This is the term provided via a clinical
+ application or batch process to name this EHR construct: its retention
+ in the EHR faithfully preserves the original label by which this entry
+ was known to end. """),
+
+ )
+
+
+ archetypeDetails = Object(
+ schema=IArchetyped,
+ title=_(u"Archetype Details"),
+ description=_(u"Details of archetyping used on this node."),
+ required=False,
+ )
+
+ feederAudit = Object(
+ schema=IFeederAudit,
+ title=_(u"Feeder Audit"),
+ description=_(u"""Audit trail from non-openEHR system of original
+ commit of information forming the content of this node, or
+ from a conversion gateway which has synthesised this node."""),
+ required=False,
+ )
+
+
+ links = Set(
+ value_type=Object(schema=ILink),
+ title=_(u"Links"),
+ description=_(u"""Audit trail from non-openEHR system of original
+ commit of information forming the content of this node,
+ or from a conversion gateway which has synthesised this
+ node."""),
+ required=False,
+ )
+
+ def isArchetypeRoot():
+ u"""True if this node is the root of an archetyped structure."""
+
+ def concept():
+ u"""
+ Clinical concept of the archetype as a whole (= derived from the
+ 'archetype_node_id' of the root node) isArchetypeRoot must be True.
+ """
+
+ def nameValid():
+ u""" name is not None"""
+
+ def linksValid():
+ u""" links is not None and links != []"""
+
+ def archetypedValid():
+ u""" isArchetypeRoot xor archetypeDetails = None """
+
+ def archetypeNodeIdValid():
+ u""" archetypeNodeId is not None and archetypeNodeId != '' """
+
+
+class IFeederAuditDetails(Interface):
+ u"""
+ Audit details for any system in a feeder system chain. Audit details here
+ means the general notion of who/where/when the information item to which
+ the audit is attached was created. None of the attributes is defined as
+ mandatory, however, in different scenarios, various combinations of
+ attributes will usually be mandatory. This can be controlled by specifying
+ feeder audit details in legacy archetypes. """
+
+ systemId = TextLine(
+ title=_(u'System Id'),
+ description=_(u"""Identifier of the system which handled the
+ information item."""),
+ )
+
+ provider = Object(
+ schema=IPartyIdentified,
+ title=_(u'Provider'),
+ description=_(u"""Optional provider(s) who created, committed,
+ forwarded or otherwise handled the item. Type ==
+ PARTY_IDENTIFIED"""),
+ required=False,
+ )
+
+ location = Object(
+ schema=IPartyIdentified,
+ title=_(u'Location'),
+ description=_(u"""Identifier of the particular site/facility within an
+ organisation which handled the item. For computability, this identifier
+ needs to be e.g. a PKI identifier which can be included in the
+ identifier list of the PARTY_IDENTIFIED object."""),
+ required=False,
+ )
+
+ time = Object(
+ schema=IDvDateTime,
+ title=_(u'Time'),
+ description=_(u"""Time of handling the item. For an originating time:
+ DV_DATE_TIME system, this will be time of creation, for an intermediate
+ feeder system, this will be a time of accession or other time of
+ handling, where available."""),
+ required=False,
+ )
+
+ subject = Object(
+ schema=IPartyProxy,
+ title=_(u'Subject'),
+ description=_(u"""Identifiers for subject of the received information
+ item."""),
+ required=False,
+ )
+
+ versionId = TextLine(
+ title=_(u'Version Id'),
+ description=_(u"""Any identifier used in the system such as "interim",
+ "final",
+ or numeric versions if available."""),
+ required=False,
+ )
+
+ def systemIdValid():
+ u"""systemId is not None and systemId != '' """
+
=== added directory 'src/oship/openehr/rm/common/archetyped/tests'
=== added file 'src/oship/openehr/rm/common/archetyped/tests/__init__.py'
=== added directory 'src/oship/openehr/rm/common/change_control'
=== added file 'src/oship/openehr/rm/common/change_control/__init__.py'
--- src/oship/openehr/rm/common/change_control/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/change_control/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,214 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import grok
+
+from oship.openehr.rm.support.identification import HierObjectId
+from interfaces import *
+
+class Contribution(grok.Container):
+ u"""
+ Documents a contribution of one or more versions added to a
+ change-controlled repository. """
+
+ grok.implements(IContribution)
+
+ def __init__(self, uid, versions, audit):
+ self.uid=uid
+ self.versions=versions
+ self.audit=audit
+
+
+
+class Version(grok.Model):
+ u"""
+ Abstract model of one Version within a Version container, containing
+ data, commit audit trail, and the identifier of its Contribution.
+ """
+
+ grok.implements(IVersion)
+
+ def __init__(self, uid, preVid, data, lcstate, caudit, contr, sig):
+ self.uid=uid
+ self.precedingVersionId=preVid
+ self.data=data
+ self.lifecycleState=lcstate
+ self.commitAudit=caudit
+ self.signature=sig
+
+ def ownerId(self):
+ return HierObjectId(self.uid.objectId().value)
+
+ def isBranch(self):
+ return self.uid.versionTreeId().isBranch()
+
+ def canonicalForm(self):
+ raise NotImplementedError
+
+
+
+class OriginalVersion(Version):
+ u"""
+ A Version containing locally created content and optional attestations.
+ """
+
+ grok.implements(IOriginalVersion)
+
+ def __init__(self, uid, previd,otherInputVersionUids,data,attestations,lifecycleState,caudit,contribution,sig):
+ Version.__init__(self,uid,previd,data,lifecycleState,caudit,contribution,sig)
+ self.otherInputVersionUids=otherInputVersionUids
+ self.attestations=attestations
+
+ def isMerged(self):
+ """
+ True if this Version was created from more than
+ just the preceding (checked out) version.
+ """
+
+
+
+class ImportedVersion(Version):
+ u"""
+ A Version containing locally created content and optional attestations.
+ """
+ grok.implements(IImportedVersion)
+
+ def __init__(self, item):
+ self.item = item
+
+
+
+class VersionedObject(grok.Container):
+ u"""
+ Version control abstraction, defining semantics for versioning one
+ complex object.
+ """
+
+ grok.implements(IVersionedObject)
+
+ def __init__(self, uid, ownerId, timeCreated):
+ super(VersionedObject, self).__init__()
+ self.uid=uid
+ self.ownerId=ownerId
+ self.timeCreated=timeCreated
+
+ def allVersions():
+ u"""Return a list of all versionsin this object. List <VERSION<T>>"""
+
+ def allVersionIds():
+ u"""Return a list of ids of all versions in this object.
+ List <OBJECT_VERSION_ID>"""
+
+ def versionCount(self):
+ return len(self)
+
+ def hasVersionId(an_id):
+ u"""Return True if an_id exists. Require an_id is not None
+ and an_id != '' """
+
+ def isOriginalVersion(an_id):
+ u"""True if version with an_id is an ORIGINAL_VERSION.
+ Require an_id is not None and hasVersionId(an_id)"""
+
+ def hasVersionAtTime(a_time):
+ u"""Return True if a version for time; 'a_time' exists.
+ Require isinstance(a_time, datetime)."""
+
+ def versionWithId(an_id):
+ u"""Return the version with id of 'an_id'.
+ Require hasVersionId(an_id)"""
+
+ def versionAtTime(a_time):
+ u"""Return the version for time 'a_time'.
+ Require hasVersionAtTime(a_time)."""
+
+ def latestVersion():
+ u"""Return the most recently added version (i.e. on trunk
+ or any branch)."""
+
+ def latestTrunkVersion():
+ u"""Return the most recently added trunk version."""
+
+ def trunkLifecycleState():
+ u"""Return the lifecycle state from the latest trunk version.
+ Useful for determining if the version container is logically deleted.
+ """
+
+ def revisionHistory():
+ u"""History of all audits and attestations in this versioned
+ repository."""
+
+ def commitOriginalVersion(self,newVersionUid,precedingVersionUid,data,lifecycleState,commitAudit,contribution,signingKey):
+ v = OriginalVersion(newVersionUid,precedingVersionUid,None,data,None,lifecycleState,commitAudit,contribution,signingKey)
+ self[newVersionUid.value] = v
+
+ def commitOriginalMergedVersion():
+ u"""Add a new original merged version. This commit function adds a
+ parameter containing the ids of other versions merged into the
+ current one.
+
+ (a_contribution: OBJECT_REF;a_new_version_uid, a_preceding_version_uid:
+ OBJECT_VERSION_ID; an_audit: AUDIT_DETAILS; a_lifecycle_state:
+ DV_CODED_TEXT; a_data: T; an_other_input_uids:Set<OBJECT_VERSION_ID>;
+ signing_key: String)
+
+ Require
+ Contribution_valid: a_contribution /= Void
+ New_version_valid: a_new_version_uid /= Void
+ Preceding_version_id_valid:
+ all_version_ids.has(a_preceding_version_uid)
+ or else version_count = 0
+ audit_valid: an_audit /= Void
+ data_valid: a_version_data /= Void
+ lifecycle_state_valid: a_lifecycle_state /= Void
+ Merge_input_ids_valid: an_other_input_uids /= Void
+ """
+
+ def commitImportedVersion(a_contribution, an_audit, a_version):
+ u"""Add a new imported version. Details of version id etc come from the
+ ORIGINAL_VERSION being committed.
+
+ (a_contribution: OBJECT_REF; an_audit: AUDIT_DETAILS;
+ a_version: ORIGINAL_VERSION<T>)
+
+ Require
+ Contribution_valid: a_contribution /= Void
+ audit_valid: an_audit /= Void
+ Version_valid: a_version /= Void
+ """
+
+ def commitAttestation(an_attestation, a_ver_id, signing_key):
+ u"""Add a new attestation to a specified original version. Attestations
+ can only be added to Original versions.
+
+ an_attestation: ATTESTATION; a_ver_id: OBJECT_VERSION_ID; signing_key:
+ String)
+
+ Require
+ Attestation_valid: an_attestation /= Void
+ Version_id_valid: has_version_id(a_ver_id) and
+ is_original_version(a_ver_id) """
+
+ def uidValid():
+ u"""uid is not None"""
+
+ def ownerIdValid():
+ u"""owner_id is not None"""
+
+ def timeCreatedValid():
+ u"""timeCreated is not None"""
+
+ def versionCountValid():
+ u"""versionCount >= 0"""
+
+ def allVersionIdsValid():
+ u"""allVersionIds is not None and allVersionIds.count = versionCount"""
+
+ def allVersionsValid():
+ u"""allVersions is not None and allVersions.count = versionCount"""
+
+ def latestVersionValid():
+ u"""versionCount > 0 implies latestVersion is not None"""
+
+ def revisionHistoryValid():
+ u"""revisionHistory is not None"""
=== added file 'src/oship/openehr/rm/common/change_control/interfaces.py'
--- src/oship/openehr/rm/common/change_control/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/change_control/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,341 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface
+from zope.schema import TextLine, Object, Field, List, Set
+from zope.i18nmessageid import MessageFactory
+import grok
+
+from oship.openehr.rm.support.interfaces import (IUidBasedId,
+ IObjectRef, IObjectVersionId)
+from oship.openehr.rm.datatypes.text.interfaces import IDvCodedText
+from oship.openehr.rm.datatypes.quantity.datetime.interfaces import IDvDateTime
+from oship.openehr.rm.common.generic.interfaces import IAuditDetails, IAttestation
+
+
+_ = MessageFactory('oship')
+
+class IContribution(Interface):
+ u"""
+ Documents a contribution of one or more versions added to a
+ change-controlled repository. """
+
+ uid=Object(
+ schema=IUidBasedId,
+ title=_(u'UID'),
+ description=_(u"""Unique identifier for this contribution."""),
+ required=True)
+
+ versions=Set(
+ value_type=Object(schema=IObjectRef),
+ title=_(u'Versions'),
+ description=_(u"""Set of references to versions causing changes to
+ this EHR. Each contribution contains a list of versions
+ which may include paths pointing to any number of
+ VERSIONABLE items, i.e. items of type COMPOSITION and
+ FOLDER."""),
+ required=True)
+
+ audit=Object(
+ schema=IAuditDetails,
+ title=_(u'Audit'),
+ description=_(u"""Audit trail corresponding to the committal of this
+ Contribution."""),
+ required=True)
+
+
+
+
+class IVersion(Interface):
+ u"""
+ Abstract model of one Version within a Version container, containing
+ data, commit audit trail, and the identifier of its Contribution.
+ """
+
+ uid = Object(
+ schema=IObjectVersionId,
+ title=_(u'UID'),
+ description=_(u"""Unique identifier of this version, containing
+ owner_id, version_tree_id and creating_system_id.
+ Type == OBJECT_VERSION_ID"""),
+ )
+
+ precedingVersionUid = Object(
+ schema=IObjectVersionId,
+ title=_(u'Preceding Version Uid'),
+ description=_(u"""Unique identifier of the version of which this
+ version is a modification; Void if this is the first version.
+ Type == OBJECT_VERSION_ID"""),
+ required=False,
+ )
+
+ data = Field(
+ title=_(u'Data'),
+ description=_(u"""Original content of this Version. Any Type."""),
+ required=False,
+ )
+
+ lifecycleState = Object(
+ schema=IDvCodedText,
+ title=_(u'Lifecycle State'),
+ description=_(u"""Lifecycle state of this version; coded by openEHR
+ vocabulary "version lifecycle state".
+ Type == DV_CODED_TEXT"""),
+
+ )
+
+
+ commitAudit = Object(
+ schema=IAuditDetails,
+ title=_(u'Commit Audit'),
+ description=_(u"""Audit trail corresponding to the committal of this
+ version to the VERSIONED_OBJECT. Type == AUDIT_DETAILS"""),
+
+ )
+
+ contribution = Object(
+ schema=IObjectRef,
+ title=_(u'Contribution'),
+ description=_(u"""Contribution in which this version was added."""),
+
+ )
+
+ signature = TextLine(
+ title=_(u'Signature'),
+ description=_(u"""OpenPGP digital signature or digest of content
+ committed in this Version."""),
+ required=False,
+ )
+
+ def ownerId():
+ u"""Unique identifier of the owning VERSIONED_OBJECT.
+ Type == HIER_OBJECT_ID"""
+
+ def isBranch():
+ u"""True if this Version represents a branch.
+ Derived from uid attribute."""
+
+ def canonicalForm():
+ u"""Canonical form of Version object, created by serialising all
+ attributes except signature."""
+
+
+
+class IOriginalVersion(Interface):
+ u"""
+ A Version containing locally created content and optional attestations.
+ """
+
+ uid=Object(
+ schema=IObjectVersionId,
+ title=_(u"UID"),
+ description=_(u"""Stored version of inheritence precursor."""),
+ required=True)
+
+ precedingVersionUid=Object(
+ schema=IObjectVersionId,
+ title=_(u"Preceding Version UID"),
+ description=_(u"""Stored version of inheritence precursor."""),
+ required=True)
+
+ otherInputVersionUids=Set(
+ value_type=Object(schema=IObjectVersionId),
+ title=_(u"Other Input Version Uids"),
+ description=_(u"""Identifiers of other versions whose content was merged into this version, if any."""),
+ required=False,
+ )
+
+ attestations=List(
+ value_type=Object(schema=IAttestation),
+ title=_(u"Attestations"),
+ description=_(u"""Set of attestations relating to this version."""),
+ required=False,
+ )
+
+ def isMerged():
+ """
+ True if this Version was created from more than
+ just the preceding (checked out) version.
+ """
+
+
+
+class IImportedVersion(Interface):
+ u"""
+ A Version containing locally created content and optional attestations.
+ """
+
+ item=Object(
+ schema=IOriginalVersion,
+ title=_(u"Item"),
+ description=_(u"""Original Version object that was imported."""),
+ required=True)
+
+
+
+class IVersionedObject(Interface):
+ u"""
+ Version control abstraction, defining semantics for versioning one
+ complex object.
+ """
+
+ uid = Object(
+ schema=IUidBasedId,
+ title=_(u'UID'),
+ description=_(u"""Unique identifier of this version container. This id
+ will be the same in all instances of the same container
+ in a distributed environment, meaning that it can be
+ understood as the uid of the "virtual version tree"."""),
+
+ )
+
+ ownerId = Object(
+ schema=IObjectRef,
+ title=_(u'Owner Id'),
+ description=_(u"""Reference to object to which this version container
+ belongs, e.g. the id of the containing EHR or other
+ relevant owning entity."""),
+
+ )
+
+ timeCreated = Object(
+ schema=IDvDateTime,
+ title=_(u'Time Created'),
+ description=_(u"""Time of initial creation of this versioned
+ object."""),
+ )
+
+ def allVersions():
+ u"""Return a list of all versionsin this object. List <VERSION<T>>"""
+
+ def allVersionIds():
+ u"""Return a list of ids of all versions in this object.
+ List <OBJECT_VERSION_ID>"""
+
+ def versionCount():
+ u"Return the total number of versions in this object as an Integer."
+
+ def hasVersionId(an_id):
+ u"""Return True if an_id exists. Require an_id is not None
+ and an_id != '' """
+
+ def isOriginalVersion(an_id):
+ u"""True if version with an_id is an ORIGINAL_VERSION.
+ Require an_id is not None and hasVersionId(an_id)"""
+
+ def hasVersionAtTime(a_time):
+ u"""Return True if a version for time; 'a_time' exists.
+ Require isinstance(a_time, datetime)."""
+
+ def versionWithId(an_id):
+ u"""Return the version with id of 'an_id'.
+ Require hasVersionId(an_id)"""
+
+ def versionAtTime(a_time):
+ u"""Return the version for time 'a_time'.
+ Require hasVersionAtTime(a_time)."""
+
+ def latestVersion():
+ u"""Return the most recently added version (i.e. on trunk
+ or any branch)."""
+
+ def latestTrunkVersion():
+ u"""Return the most recently added trunk version."""
+
+ def trunkLifecycleState():
+ u"""Return the lifecycle state from the latest trunk version.
+ Useful for determining if the version container is logically deleted.
+ """
+
+ def revisionHistory():
+ u"""History of all audits and attestations in this versioned
+ repository."""
+
+ def commitOriginalVersion():
+ u"""
+ Add a new original version.
+ (a_contribution: OBJECT_REF; a_new_version_uid,
+ a_preceding_version_uid: OBJECT_VERSION_ID; an_audit: AUDIT_DETAILS;
+ a_lifecycle_state: DV_CODED_TEXT; a_data: T; signing_key: String)
+
+ Require
+ contributionValid: a_contribution /= Void
+ newVersionValid: a_new_version_uid /= Void
+ precedingVersionUidValid:all_version_ids.has(a_preceding_version_uid)
+ or else version_count = 0
+ audit_valid: an_audit /= Void
+ data_valid: a_version_data /= Void
+ lifecycle_state_valid: a_lifecycle_state /= Void
+ """
+
+ def commitOriginalMergedVersion():
+ u"""Add a new original merged version. This commit function adds a
+ parameter containing the ids of other versions merged into the
+ current one.
+
+ (a_contribution: OBJECT_REF;a_new_version_uid, a_preceding_version_uid:
+ OBJECT_VERSION_ID; an_audit: AUDIT_DETAILS; a_lifecycle_state:
+ DV_CODED_TEXT; a_data: T; an_other_input_uids:Set<OBJECT_VERSION_ID>;
+ signing_key: String)
+
+ Require
+ Contribution_valid: a_contribution /= Void
+ New_version_valid: a_new_version_uid /= Void
+ Preceding_version_id_valid:
+ all_version_ids.has(a_preceding_version_uid)
+ or else version_count = 0
+ audit_valid: an_audit /= Void
+ data_valid: a_version_data /= Void
+ lifecycle_state_valid: a_lifecycle_state /= Void
+ Merge_input_ids_valid: an_other_input_uids /= Void
+ """
+
+ def commitImportedVersion(a_contribution, an_audit, a_version):
+ u"""Add a new imported version. Details of version id etc come from the
+ ORIGINAL_VERSION being committed.
+
+ (a_contribution: OBJECT_REF; an_audit: AUDIT_DETAILS;
+ a_version: ORIGINAL_VERSION<T>)
+
+ Require
+ Contribution_valid: a_contribution /= Void
+ audit_valid: an_audit /= Void
+ Version_valid: a_version /= Void
+ """
+
+ def commitAttestation(an_attestation, a_ver_id, signing_key):
+ u"""Add a new attestation to a specified original version. Attestations
+ can only be added to Original versions.
+
+ an_attestation: ATTESTATION; a_ver_id: OBJECT_VERSION_ID; signing_key:
+ String)
+
+ Require
+ Attestation_valid: an_attestation /= Void
+ Version_id_valid: has_version_id(a_ver_id) and
+ is_original_version(a_ver_id) """
+
+ def uidValid():
+ u"""uid is not None"""
+
+ def ownerIdValid():
+ u"""owner_id is not None"""
+
+ def timeCreatedValid():
+ u"""timeCreated is not None"""
+
+ def versionCountValid():
+ u"""versionCount >= 0"""
+
+ def allVersionIdsValid():
+ u"""allVersionIds is not None and allVersionIds.count = versionCount"""
+
+ def allVersionsValid():
+ u"""allVersions is not None and allVersions.count = versionCount"""
+
+ def latestVersionValid():
+ u"""versionCount > 0 implies latestVersion is not None"""
+
+ def revisionHistoryValid():
+ u"""revisionHistory is not None"""
+
=== added directory 'src/oship/openehr/rm/common/change_control/tests'
=== added file 'src/oship/openehr/rm/common/change_control/tests/__init__.py'
=== added file 'src/oship/openehr/rm/common/change_control/tests/version.txt'
--- src/oship/openehr/rm/common/change_control/tests/version.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/change_control/tests/version.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,19 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.common.change_control import Version,OriginalVersion
+>>> from oship.openehr.rm.common.change_control.interfaces import IVersion,IOriginalVersion
+>>> from oship.openehr.rm.support.identification import ObjectVersionId,TerminologyId
+>>> from oship.openehr.rm.datatypes.text import DvCodedText,CodePhrase
+>>> uid = ObjectVersionId("87284370-2D4B-4e3d-A3F3-F303D2F4F34B::2::1")
+>>> data = u"Some data"
+>>> openEhrTerminologyId = TerminologyId(u"openehr")
+>>> versionCodePhrase = CodePhrase(openEhrTerminologyId,u"version lifecycle state")
+>>> lifecycleState = DvCodedText(versionCodePhrase,u"complete",None,None,None,None,None)
+>>> caudit=None
+>>> contribution=None
+>>> version = OriginalVersion(uid,None,None,data,None,lifecycleState,caudit,contribution,None)
+>>> version.ownerId().value
+u'87284370-2D4B-4e3d-A3F3-F303D2F4F34B'
+>>> version.isBranch()
+False
+>>>
=== added file 'src/oship/openehr/rm/common/change_control/tests/versionedobject.txt'
--- src/oship/openehr/rm/common/change_control/tests/versionedobject.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/change_control/tests/versionedobject.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,20 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.common.change_control import Version,OriginalVersion, VersionedObject
+>>> from oship.openehr.rm.common.change_control.interfaces import IVersion,IOriginalVersion
+>>> from oship.openehr.rm.support.identification import ObjectVersionId,TerminologyId
+>>> from oship.openehr.rm.datatypes.text import DvCodedText,CodePhrase
+>>> uid = ObjectVersionId("87284370-2D4B-4e3d-A3F3-F303D2F4F34B::2::1")
+>>> data = u"Some data"
+>>> openEhrTerminologyId = TerminologyId(u"openehr")
+>>> versionCodePhrase = CodePhrase(openEhrTerminologyId,u"version lifecycle state")
+>>> lifecycleState = DvCodedText(versionCodePhrase,u"complete",None,None,None,None,None)
+>>> caudit=None
+>>> contribution=None
+>>> versionedObject = VersionedObject(None,None,None)
+>>> versionedObject.versionCount()
+0
+>>> versionedObject.commitOriginalVersion(uid,None,data,lifecycleState,caudit,contribution,None)
+>>> versionedObject.versionCount()
+1
+>>>
=== added directory 'src/oship/openehr/rm/common/directory'
=== added file 'src/oship/openehr/rm/common/directory/__init__.py'
--- src/oship/openehr/rm/common/directory/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/directory/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import grok
+from oship.openehr.rm.common.archetyped import Locatable
+from oship.openehr.rm.common.change_control import VersionedObject
+from interfaces import *
+
+
+class Folder(Locatable):
+ u"""
+ The concept of a named folder.
+ """
+
+ grok.implements(IFolder)
+
+ def __init__(self, folders, items):
+
+ self.folders=folders
+ self.items=items
+
+ def foldersValid():
+ u"""folders is not None and folders != '' """
+
+
+class VersionedFolder(VersionedObject):
+ u"""
+ A version-controlled hierarchy of FOLDERs giving the effect of a directory.
+ """
+
+ grok.implements(IVersionedFolder)
+
+ def __init__(self, ownerId, timeCreated, uid):
+ VersionedObject.__init__(ownerId, timeCreated, uid)
=== added file 'src/oship/openehr/rm/common/directory/interfaces.py'
--- src/oship/openehr/rm/common/directory/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/directory/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface
+from zope.schema import Object, List
+from zope.i18nmessageid import MessageFactory
+from oship.openehr.rm.support.interfaces import IObjectRef
+
+
+_ = MessageFactory('oship')
+
+
+
+class IVersionedFolder(Interface):
+ u"""
+ A version-controlled hierarchy of FOLDERs giving the effect of a directory.
+ """
+ pass
+
+
+class IFolder(Interface):
+ u"""
+ The concept of a named folder.
+ """
+
+ folders = List(
+ value_type=Object(schema=IObjectRef), # documented as a list of folders
+ title=_(u"Folders"),
+ description=_(u"""Subfolders of this folder."""),
+ required=False,
+ )
+
+ items = List(
+ value_type=Object(schema=IObjectRef),
+ title=_(u"Items"),
+ description=_(u"""The list of references to other (usually) versioned
+ objects logically in this folder."""),
+ required=False,
+ )
+
+ def foldersValid():
+ u"""folders is not None and folders != '' """
=== added directory 'src/oship/openehr/rm/common/directory/tests'
=== added file 'src/oship/openehr/rm/common/directory/tests/__init__.py'
=== added directory 'src/oship/openehr/rm/common/generic'
=== added file 'src/oship/openehr/rm/common/generic/__init__.py'
--- src/oship/openehr/rm/common/generic/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/generic/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,162 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface
+import grok
+from interfaces import *
+
+class Participation(grok.Model):
+
+ grok.implements(IParticipation)
+
+ def __init__(self, performer, function, mode, time):
+ self.performer=performer
+ self.function=function
+ self.mode=mode
+ self.time=time
+
+
+class AuditDetails(grok.Model):
+ u"""
+ The set of attributes required to document the committal of an information
+ item to a repository.
+ """
+
+ grok.implements(IAuditDetails)
+
+ def __init___(self, systemId, committer, timeCommited, changeType,
+ description):
+
+ self.systemId=systemId
+ self.committer=committer
+ self.timeCommitted=timeCommited
+ self.changeType=changeType
+ self.description=description
+
+
+class Attestation(AuditDetails):
+ u"""
+ Record an attestation of a party (the committer) to item(s) of record
+ content. The type of attestation is """
+
+ grok.implements(IAttestation)
+
+ def __init__(self, aview, proof, items, reason, ispend):
+
+ self.attestedView=aview
+ self.proof=proof
+ self.items=items
+ self.reason=reason
+ self.isPending=ispend
+
+ def itemsValid():
+ u"""items is not None items != '' """
+
+ def reasonValid():
+ u"""reason is not None and
+ then(reason.generating_type.is_equal("DV_CODED_TEXT") implies
+ terminology(Terminology_id_openehr).has_code_for_group_id
+ (Group_id_attestation_reason, reason.defining_code))"""
+
+
+class PartyProxy(grok.Model):
+ u"""
+ Abstract concept of a proxy description of a party, including an optional
+ link to data for this party in a demographic or other identity management
+ system. Subtyped into PARTY_IDENTIFIED and PARTY_SELF.
+ """
+
+ grok.implements(IPartyProxy)
+
+ def __init__(self, extref):
+ self.externalRef=extref
+
+
+class PartyIdentified(PartyProxy):
+ """
+ An identity owned by a party.
+ """
+
+ grok.implements(IPartyIdentified)
+
+ def __init__(self, name, identifiers, extref):
+ PartyProxy.__init__(self,extref)
+ self.name=name
+ self.identifiers=identifiers
+
+ def asString():
+ """
+ Indentity in the form of a string.
+ """
+
+
+class PartyRelated(PartyIdentified):
+ u"""
+ Proxy type for identifying a party and its relationship to the subject of
+ the record.
+
+ Use where the relationship between the party and the subject of the record
+ must be known.
+ """
+
+ grok.implements(IPartyRelated)
+
+ def __init__(self, relationship, name, identifiers, extref):
+ PartyIdentified.__init__(self, name, identifiers, extref)
+ self.relationship=relationship
+
+ def relationshipValid():
+ u"""relationship is not None and relationship in the relationship
+ vocabulary."""
+
+
+class PartySelf(PartyProxy):
+
+ grok.implements(IPartySelf)
+
+ def __init__(self,extref):
+ PartyProxy.__init__(self,extref)
+
+
+class RevisionHistoryItem(grok.Model):
+ u"""
+ An entry in a revision history, corresponding to a version from a versioned
+ container. Consists of AUDIT_DETAILS instances with revision identifier of
+ the revision to which the AUDIT_DETAILS intance belongs.
+ """
+
+ grok.implements(IRevisionHistoryItem)
+
+ def __init__(self, audits, verid):
+ self.audits=audits
+ self.versionId=verid
+
+ def auditValid():
+ u"""audits is not None and audits != ' """
+
+ def versionIdValid():
+ u"""versionId is not None"""
+
+
+class RevisionHistory(grok.Model):
+ u"""
+ Defines the notion of a revision history of audit items, each associated
+ with the version for which that audit was committed. The list is in
+ most-recent-first order.
+ """
+
+ grok.implements(IRevisionHistory)
+
+ def __init__(self, items):
+ self.items=items
+
+ def mostRecentVersion():
+ u"""The version id of the most recent item, as a String.
+ Ensure Result.is_equal(items.last.version_id.value)"""
+
+ def mostRecentVersionTimeCommitted():
+ u"""The commit date/time of the most recent item, as a string.
+ Ensure Result.is_equal(items.last.audits.first.time_committed.value)"""
+
+ def itemsValid():
+ u"""items is not None """
=== added file 'src/oship/openehr/rm/common/generic/interfaces.py'
--- src/oship/openehr/rm/common/generic/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/generic/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,341 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+
+from zope.interface import Interface
+from zope.schema import TextLine, Object, List, Set, Bool
+from zope.i18nmessageid import MessageFactory
+import grok
+from oship.openehr.rm.support.interfaces import IPartyRef, IObjectVersionId
+from oship.openehr.rm.datatypes.basic import IDvIdentifier
+from oship.openehr.rm.datatypes.text.interfaces import IDvText, IDvCodedText
+from oship.openehr.rm.datatypes.quantity.interfaces import IDvInterval
+from oship.openehr.rm.datatypes.quantity.datetime.interfaces import IDvDateTime
+from oship.openehr.rm.datatypes.encapsulated.interfaces import IDvMultimedia
+from oship.openehr.rm.datatypes.uri.interfaces import IDvEhrUri
+
+
+_ = MessageFactory('oship')
+
+class IPartyProxy(Interface):
+ u"""
+ Abstract concept of a proxy description of a party, including an optional
+ link to data for this party in a demographic or other identity management
+ system. Subtyped into PARTY_IDENTIFIED and PARTY_SELF.
+ """
+
+ externalRef = Object(
+ schema=IPartyRef,
+ title=_(u"External Reference"),
+ description=_(u"""Optional reference to more detailed demographic or
+ identification information for this party, in an external
+ system. Type == PartyRef."""),
+ required=False,
+ )
+
+
+class IParticipation(Interface):
+ u"""
+ Model of a participation of a Party (any Actor or Role) in an activity.
+
+ Used to represent any participation of a Party in some activity, which is
+ not explicitly in the model, e.g. assisting nurse. Can be used to record
+ past or future participations.
+
+ Should not be used in place of more permanent relationships between
+ demographic entities. """
+
+ performer = Object(
+ schema=IPartyProxy,
+ title=_(u'Performer'),
+ description=_(u"""The id and possibly demographic system link of
+ performer: (PartyProxy) the party participating in the
+ activity."""),
+
+ )
+
+ function = Object(
+ schema=IDvText,
+ title=_(u'Function'),
+ description=_(u"""The function of the Party in this participation (note
+ in a particular activity). This attribute should be coded,
+ but cannot be limited to the HL7v3:ParticipationFunction
+ vocabulary, since it is too limited and
+ hospital-oriented."""),
+
+ )
+
+ mode = Object(
+ schema=IDvCodedText,
+ title=_(u'Mode'),
+ description=_(u"""The mode of the performer / activity interaction,
+ e.g. present, by telephone, by email etc. Type ==
+ DvCodedText"""),
+ )
+
+ time = Object(
+ schema=IDvInterval,
+ title=_(u'Time Interval'),
+ description=_(u"""The time interval during which the participation took
+ place, if it is used in an observational context (i.e.
+ recording facts about the past); or the intended time
+ interval of the participation when used in future contexts,
+ such as EHR Instructions."""),
+ required=False,
+ )
+
+ def performerValid():
+ u"""performer is not None"""
+
+ def functionValid():
+ u"""function is not None and then
+ function.generating_type.is_equal("DV_CODED_TEXT") implies
+ terminology(Terminology_id_openehr)\
+ .has_code_for_group_id(Group_id_participation_function,
+ function.defining_code)"""
+
+ def modeValid():
+ u"""mode is not None and
+ terminology(Terminology_id_openehr).has_code_for_group_id
+ (Group_id_participation_mode, mode.defining_code)"""
+
+
+class IPartyRelated(Interface):
+ u"""
+ Proxy type for identifying a party and its relationship to the subject of
+ the record.
+
+ Use where the relationship between the party and the subject of the record
+ must be known.
+ """
+
+ relationship = Object(
+ schema=IDvCodedText,
+ title=_(u'Relationship'),
+ description=_(u"""Relationship of subject of this ENTRY to the subject
+ of the record. May be coded. If it is the patient, coded
+ as "self"."""),
+
+ )
+
+ def relationshipValid():
+ u"""relationship is not None and relationship in the relationship
+ vocabulary."""
+
+class IAuditDetails(Interface):
+ u"""
+ The set of attributes required to document the committal of an information
+ item to a repository.
+ """
+
+ systemId = TextLine(
+ title=_(u"""System Id"""),
+ description=_(u"""Identity of the system where the change was
+ committed. Ideally this is a machine- and
+ human-processable identifier, but it may not be."""),
+ )
+
+ committer = Object(
+ schema=IPartyProxy,
+ title=_(u"""Committer"""),
+ description=_(u"""Identity and optional reference into identity
+ management service, of user who committed the item."""),
+ )
+
+ timeCommitted = Object(
+ schema=IDvDateTime,
+ title=_(u"""Time Committed"""),
+ description=_(u"""Time of committal of the item."""),
+
+ )
+
+ changeType = Object(
+ schema=IDvCodedText,
+ title=_(u"""Change Type"""),
+ description=_(u"""Type of change. Coded using the openEHR Terminology
+ "audit change type" group. Type==DvCodedText"""),
+
+ )
+
+ description = Object(
+ schema=IDvText,
+ title=_(u"""Description"""),
+ description=_(u"""Reason for committal. Type==DvText"""),
+ required=False,
+ )
+
+ def systemIdValid():
+ u"""systemId is not None and systemId != '' """
+
+ def committerValid():
+ u"""committer!= None"""
+
+ def timeCommittedValid():
+ u"""timeCommitted is not None"""
+
+ def changeTypeValid():
+ u"""changeType is not None and then terminology(Terminology_id_openehr).
+ has_code_for_group_id(Group_id_audit_change_type,
+ change_type.defining_code)"""
+
+
+class IPartyIdentified(Interface):
+ u"""
+ Proxy data for an identified party other than the subject of the record,
+ minimally consisting of human-readable identifier(s), such as name, formal
+ (and possibly computable) identifiers such as NHS number, and an optional
+ link to external data. There must be at least one of name, identifier or
+ external_ref present.
+
+ Used to describe parties where only identifiers may be known, and there is
+ no entry at all in the demographic system (or even no demographic system).
+ Typically for health care providers, e.g. name and provider number of an
+ institution.
+
+ Should not be used to include patient identifying information.
+ """
+
+ name = TextLine(
+ title=_(u'Name'),
+ description=_(u"""Optional human-readable name (in String form)."""),
+ required=False,
+ )
+
+ identifiers = List(
+ value_type=Object(schema=IDvIdentifier),
+ title=_(u'Identifiers'),
+ description=_(u"""One or more formal identifiers (possibly computable).
+ List<DvIdentifier>"""),
+ required=False,
+ )
+
+ def basicValid(obj):
+ u"""name None or identifiers is not None or external_ref is not None"""
+
+ def nameValid():
+ u"""name is not None and name != '' """
+
+ def identifiersValid():
+ u"""identifiers != none and identifiers != '' """
+
+
+class IAttestation(Interface):
+ u"""
+ Record an attestation of a party (the committer) to item(s) of record
+ content. The type of attestation is """
+
+ attestedView = Object(
+ schema=IDvMultimedia,
+ title=_(u'Attested View'),
+ description=_(u"""Optional visual representation of content attested
+ e.g. screen image. Type==DvMultimedia"""),
+ required=False,
+ )
+
+ proof = TextLine(
+ title=_(u'Proof'),
+ description=_(u"""Proof of attestation."""),
+ required=False,
+ )
+
+ items = Set(
+ value_type=Object(IDvEhrUri),
+ title=_(u'Items'),
+ description=_(u"""Items attested, expressed as fully qualified runtime
+ paths to the items in question. Although not recommended,
+ these may include fine-grained items which have been
+ attested in some other system. Otherwise it is assumed to
+ be for the entire VERSION with which it is associated.
+ Set <DV_EHR_URI>"""),
+ required=False,
+ )
+
+
+ reason = Object(
+ schema=IDvText,
+ title=_(u'Reason'),
+ description=_(u"""Reason of this attestation. Optionally coded by the
+ openEHR Terminology group "attestation reason"; includes
+ values like "authorisation", "witness" etc."""),
+
+ )
+
+ isPending = Bool(
+ title=_(u'Pending?'),
+ description=_(u"""True if this attestation is outstanding;
+ False means it has been completed."""),
+
+ )
+
+ def itemsValid():
+ u"""items is not None items != '' """
+
+ def reasonValid():
+ u"""Reason is not None and
+ then(reason.generating_type.is_equal("DV_CODED_TEXT") implies
+ terminology(Terminology_id_openehr).has_code_for_group_id
+ (Group_id_attestation_reason, reason.defining_code))"""
+
+
+class IPartySelf(Interface):
+ u"""
+ Party proxy representing the subject of the record.
+ Used to indicate that the party is the owner of the record. May or may
+ not have external_ref set.
+ """
+ pass
+
+
+class IRevisionHistoryItem(Interface):
+ u"""
+ An entry in a revision history, corresponding to a version from a versioned
+ container. Consists of AUDIT_DETAILS instances with revision identifier of
+ the revision to which the AUDIT_DETAILS intance belongs.
+ """
+
+ audits = List(
+ value_type=Object(IAuditDetails),
+ title=_(u'Audits'),
+ description=_(u"""The audits for this revision; there will always be at
+ least one commit audit (which may itself be an
+ ATTESTATION), there may also be further attestations."""),
+ )
+
+ versionId = Object(
+ schema=IObjectVersionId,
+ title=_(u'Version Id'),
+ description=_(u"""Version identifier for this revision."""),
+
+ )
+
+ def auditValid():
+ u"""audits is not None and audits != ' """
+
+ def versionIdValid():
+ u"""versionId is not None"""
+
+
+class IRevisionHistory(Interface):
+ u"""
+ Defines the notion of a revision history of audit items, each associated
+ with the version for which that audit was committed. The list is in
+ most-recent-first order.
+ """
+
+ items = List(
+ value_type=TextLine(),
+ title=_(u'Items'),
+ description=_(u"The items in this history in most-recent-last order."),
+
+ )
+
+ def mostRecentVersion():
+ u"""The version id of the most recent item, as a String.
+ Ensure Result.is_equal(items.last.version_id.value)"""
+
+ def mostRecentVersionTimeCommitted():
+ u"""The commit date/time of the most recent item, as a string.
+ Ensure Result.is_equal(items.last.audits.first.time_committed.value)"""
+
+ def itemsValid():
+ u"""items is not None """
=== added directory 'src/oship/openehr/rm/common/generic/tests'
=== added file 'src/oship/openehr/rm/common/generic/tests/__init__.py'
=== added directory 'src/oship/openehr/rm/common/resource'
=== added file 'src/oship/openehr/rm/common/resource/__init__.py'
--- src/oship/openehr/rm/common/resource/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/resource/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import grok
+
+from oship.openehr.rm.datatypes.text import CodePhrase
+from interfaces import *
+
+
+
+class AuthoredResource(grok.Model):
+ u"""
+ Abstract idea of an online resource created by a human author.
+ """
+
+ grok.implements(IAuthoredResource)
+
+ def __init__(self,originalLanguage,translations,description,revisionHistory,isControlled):
+ if isinstance(originalLanguage, CodePhrase):
+ self.originalLanguage=originalLanguage
+ else:
+ raise AttributeError("Incorrect AuthoredResource.originalLanguage")
+
+ self.translations=translations
+ self.description=description
+ self.revisionHistory=revisionHistory
+ if isControlled is None:
+ self.isControlled = False
+ else:
+ self.isControlled=isControlled
+
+ def currentRevision(self):
+ u"""
+ Extracted from revisionHistory.
+ """
+ revlist = self.revisionHistory.items
+
+ return revlist[(lenrevlist)] # the last one
+
+ def languagesAvailable(self):
+ u"""
+ Derived from originalLanguage and translations.
+ """
+ return [self.originalLanguage,self.translations]
+
+
+class TranslationDetails(grok.Model):
+ u""" """
+
+ grok.implements(ITranslationDetails)
+
+ def __init__(self, lang, author, accred, other):
+ self.language=lang
+ self.author=author
+ self.accreditation=accred
+ self.otherDetails=other
+
+
+class ResourceDescriptionItem(grok.Model):
+ u"""Language-specific detail of resource description. When a resource is
+ translated for use in another language environment, each
+ RESOURCE_DESCRIPTION_ITEM needs to be copied and translated into the new
+ language. """
+
+ pass
+
+
+class ResourceDescription(grok.Model):
+ u"""Defines the descriptive meta-data of a resource."""
+
+ pass
=== added file 'src/oship/openehr/rm/common/resource/interfaces.py'
--- src/oship/openehr/rm/common/resource/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/common/resource/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,175 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface, Attribute
+from zope.schema import TextLine, List, Object, Set, Bool, Dict
+from zope.i18nmessageid import MessageFactory
+import grok
+
+from oship.openehr.rm.support.interfaces import IPartyRef
+from oship.openehr.rm.datatypes.text.interfaces import ICodePhrase
+from oship.openehr.rm.common.generic.interfaces import IRevisionHistory
+
+_ = MessageFactory('oship')
+
+
+
+
+class ITranslationDetails(Interface):
+ u""""""
+
+ language=Object(
+ schema=ICodePhrase,
+ title=_(u'Language'),
+ description=_(u""" """),
+ required=True)
+
+ author=Dict(
+ title=_(u'Author'),
+ description=_(u""" """),
+ required=True)
+
+ accreditation=TextLine(
+ title=_(u'Accreditation'),
+ description=_(u""""""),
+ required=False)
+
+ otherDetails=Dict(
+ title=_(u'Other Details'),
+ description=_(u""""""),
+ required=False)
+
+
+class IResourceDescriptionItem(Interface):
+ u"""Language-specific detail of resource description. When a resource is
+ translated for use in another language environment, each
+ RESOURCE_DESCRIPTION_ITEM needs to be copied and translated into the new
+ language. """
+
+ language=Object(
+ schema=ICodePhrase,
+ title=_(u'Language'),
+ description=_(u""""""),
+ required=True)
+
+ purpose=TextLine(
+ title=_(u'Purpose'),
+ description=_(u""""""),
+ required=True)
+
+ keywords=List(
+ value_type=TextLine(),
+ title=_(u'Keywords'),
+ description=_(u""""""),
+ required=False)
+
+ use=TextLine(
+ title=_(u'Use'),
+ description=_(u""""""),
+ required=False)
+
+ misuse=TextLine(
+ title=_(u'Misuse'),
+ description=_(u""""""),
+ required=False)
+
+ copyright=TextLine(
+ title=_(u'Copyright'),
+ description=_(u""""""),
+ required=False)
+
+ originalResourceUri=Dict(
+ title=_(u'Original Resource URI'),
+ description=_(u""""""),
+ required=False)
+
+ otherDetails=Dict(
+ title=_(u'Other Details'),
+ description=_(u""""""),
+ required=False)
+
+
+class IResourceDescription(Interface):
+ u"""Defines the descriptive meta-data of a resource."""
+
+ originalAuthor=Dict(
+ title=_(u'Original Author'),
+ description=_(u""""""),
+ required=True
+ )
+
+ otherContributors=List(
+ title=_(u'Other Contributors'),
+ description=_(u""""""),
+ required=False
+ )
+
+ lifecycleState=TextLine(
+ title=_(u'Lifecycle State'),
+ description=_(u""""""),
+ required=True
+ )
+
+ details=Dict(
+ title=_(u'Details'),
+ description=_(u""""""),
+ required=True
+ )
+
+ resourcePackageUri=TextLine(
+ title=_(u'Resource Package URI'),
+ description=_(u""""""),
+ required=False
+ )
+
+ otherDetails=Dict(
+ title=_(u'Other Details'),
+ description=_(u""""""),
+ required=False
+ )
+
+ parentResource=Attribute(u'Parent Resource')
+
+
+class IAuthoredResource(Interface):
+ u"""Abstract idea of an online resource created by a human author. """
+
+ originalLanguage=Object(
+ schema=ICodePhrase,
+ title=_(u"Original Language"),
+ description=_(u"""Original Language"""),
+ required=False)
+
+ translations=Dict(
+ key_type = TextLine(),
+ value_type = Object(schema=ITranslationDetails),
+ title=_(u"Translations"),
+ description=_(u"Translations"),
+ required=False)
+
+ description=Object(
+ schema=IResourceDescription,
+ title=_(u"Description"),
+ description=_(u""""""),
+ required=False)
+
+ revisionHistory=Object(
+ schema=IRevisionHistory,
+ title=_(u"Revision History"),
+ description=_(u""""""),
+ required=False)
+
+ isControlled=Bool(
+ title=_(u"Is Controlled"),
+ description=_(u""""""),
+ required=False)
+
+ def currentRevision():
+ u"""
+ Extracted from revisionHistory.
+ """
+
+ def languagesAvailable():
+ u"""
+ Derived from originalLanguage and translations.
+ """
=== added directory 'src/oship/openehr/rm/common/resource/tests'
=== added file 'src/oship/openehr/rm/common/resource/tests/__init__.py'
=== added directory 'src/oship/openehr/rm/composition'
=== added file 'src/oship/openehr/rm/composition/__init__.py'
--- src/oship/openehr/rm/composition/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+
+import grok
+from oship.openehr.rm.common.archetyped import Locatable, Pathable
+from interfaces import *
+
+
+
+class Composition(Locatable,grok.Container):
+ """
+ One version in a VersionedComposition. A composition is considered the unit of modification in an EHR.
+ """
+
+ grok.implements(IComposition)
+
+ def __init__(self,content,context,composer,cat,lang,terr,uid,atnodeid,name,atdetails,fdraudit,links):
+ Locatable.__init__(self,uid,atnodeid,name,atdetails,fdraudit,links)
+ self.content=content
+ self.context=context
+ self.composer=composer
+ self.category=cat
+ self.language=lang
+ self.territory=terr
+
+ def isPersistent(self):
+ return True # all Compositions in OSHIP are persistent.
+
+
+
+
+class EventContext(Pathable):
+ """
+ The context information of a healthcare event.
+ These include patient contacts or other investigations.
+ """
+
+ grok.implements(IEventContext)
+
+ def __init__(self,hcf,start,end,part,loc,sett,other):
+ self.healthCareFacility=hcf
+ self.startTime=start
+ self.endTime=end
+ self.participations=part
+ self.location=loc
+ self.setting=sett
+ self.otherContext=other
=== added directory 'src/oship/openehr/rm/composition/content'
=== added file 'src/oship/openehr/rm/composition/content/__init__.py'
--- src/oship/openehr/rm/composition/content/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/content/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import grok
+
+from oship.openehr.rm.common.archetyped import Locatable
+from interfaces import IContentItem
+
+
+class ContentItem(Locatable):
+ """
+ Abstract ancestor of all concrete content types.
+ """
+
+ grok.implements(IContentItem)
=== added directory 'src/oship/openehr/rm/composition/content/entry'
=== added file 'src/oship/openehr/rm/composition/content/entry/__init__.py'
--- src/oship/openehr/rm/composition/content/entry/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/content/entry/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,187 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from oship.openehr.rm.common.archetyped import Locatable, Pathable
+from oship.openehr.rm.common.generic import PartySelf
+from oship.openehr.rm.common.change_control import VersionedObject
+from oship.openehr.rm.composition.content import ContentItem
+from interfaces import *
+
+
+
+class Entry(ContentItem):
+ """
+ The abstract parent of all ENTRY subtypes. An ENTRY is the root of a logical item
+ of "hard" clinical information created in the "clinical statement" context, within a
+ clinical session. There can be numerous such contexts in a clinical session. Obser-
+ vations and other Entry types only ever document information captured/created in
+ the event documented by the enclosing Composition.
+ An ENTRY is also the minimal unit of information any query should return, since a
+ whole ENTRY (including subparts) records spatial structure, timing information,
+ and contextual information, as well as the subject and generator of the informa-
+ tion.
+ """
+
+ grok.implements(IEntry)
+
+ def __init__(self,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links):
+ ContentItem.__init__(self,uid,atnodeid,name,atdetails,fdraudit,links)
+
+ self.language=lang
+ self.encoding=encod
+ self.subject=subject
+ self.provider=provider
+ self.otherParticipations=opart
+ self.workflowId=wfid
+
+ def subjectIsSelf(self):
+ u"""Returns True if this Entry is about the subject of the EHR, in which case the
+ subject attribute is of type PARTY_SELF. """
+ return (isinstance(self.subject, PartySelf))
+
+
+
+class CareEntry(Entry):
+ """
+ The abstract parent of all clinical ENTRY subtypes. A CARE_ENTRY defines
+ protocol and guideline attributes for all clinical Entry subtypes.
+ """
+
+ grok.implements(ICareEntry)
+
+
+ def __init__(self,protocol,gid,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links):
+ Entry.__init__(self,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links)
+ self.protocol=protocol
+ self.guidelineId=gid
+
+
+
+class AdminEntry(Entry):
+ """
+ Entry subtype for administrative information, i.e. information about setting up the
+ clinical process, but not itself clinically relevant. Archetypes will define con-
+ tained information.
+ Used for admistrative details of admission, episode, ward location, discharge,
+ appointment (if not stored in a practice management or appointments system).
+
+ Not used for any clinically significant information.
+ """
+
+ grok.implements(IAdminEntry)
+
+
+ def __init__(self,data,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links):
+ Entry.__init__(self,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links)
+ self.data=data
+
+
+
+class Evaluation(CareEntry):
+ """
+ Entry type for evaluation statements.
+ """
+
+ grok.implements(IEvaluation)
+
+ def __init__(self,data,protocol,gid,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links):
+ CareEntry.__init__(self,protocol,gid,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links)
+ self.data=data
+
+
+
+class Action(CareEntry):
+ """
+ Used to record a clinical action that has been performed.
+ """
+
+ grok.implements(IAction)
+
+
+ def __init__(self,time,desc,ism,inst,protocol,gid,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links):
+ CareEntry.__init__(self,protocol,gid,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links)
+ self.time=time
+ self.description=desc
+ self.ismTransition=ism
+ self.instructionDetails=inst
+
+
+
+class Activity(Locatable):
+ """
+ A single activity within an instruction.
+ """
+
+ grok.implements(IActivity)
+
+
+ def __init__(self,description,timing,atid,uid,atnodeid,name,atdetails,fdraudit,links):
+ Locatable.__init__(self,uid,atnodeid,name,atdetails,fdraudit,links)
+ self.description=description
+ self.timing=timing
+ self.actionArchetypeId=atid
+
+
+
+class InstructionDetails(Pathable):
+ """
+ Used to record the details of an Instruction causing an Action.
+ """
+
+ grok.implements(IInstructionDetails)
+
+ def __init__(self,inst,actid,wfd):
+ Pathable.__init__(self)
+ self.instructionId=inst
+ self.activityId=actid
+ self.wfDetails=wfd
+
+
+
+class Instruction(CareEntry):
+ """
+ Used to specify future actions and includes a workflow form.
+ """
+
+ grok.implements(IInstruction)
+
+ def __init__(self,narr,act,exp,wfd,protocol,gid,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links):
+ CareEntry.__init__(self,protocol,gid,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links)
+ self.narrative=narr
+ self.activities=act
+ self.expiryTime=exp
+ self.wfDefinition=wfd
+
+
+
+class IsmTransition(Pathable):
+ """
+ Model of a transition in the Instruction state machine.
+ """
+
+ grok.implements(IIsmTransition)
+
+ def __init__(self,cstate,trans,cfs):
+ Pathable.__init__(self)
+ self.currentState=cstate
+ self.transition=trans
+ self.careflowStep=cfs
+
+
+class Observation(CareEntry):
+ """
+ Entry subtype for all clinical data in the past or present, i.e. which (by the time it
+ is recorded) has already occurred. OBSERVATION data is expressed using the class
+ HISTORY<T>, which guarantees that it is situated in time.
+ OBSERVATION is used for all notionally objective (i.e. measured in some way)
+ observations of phenomena, and patient-reported phenomena, e.g. pain.
+ Not used for recording opinion or future statements of any kind, including instructions,
+ intentions, plans etc.
+ """
+
+ grok.implements(IObservation)
+
+ def __init__(self,data,state,protocol,gid,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links):
+ CareEntry.__init__(self,protocol,gid,lang,encod,subject,provider,opart,wfid,uid,atnodeid,name,atdetails,fdraudit,links)
+ self.data=data
+ self.state=state
=== added file 'src/oship/openehr/rm/composition/content/entry/interfaces.py'
--- src/oship/openehr/rm/composition/content/entry/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/content/entry/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,335 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import grok
+
+from zope.interface import Interface
+from zope.schema import List, TextLine, Object, Bool
+from zope.i18nmessageid import MessageFactory
+
+from oship.openehr.rm.common.generic.interfaces import IParticipation, IPartyProxy
+from oship.openehr.rm.support.interfaces import IUidBasedId, IObjectRef, ILocatableRef
+from oship.openehr.rm.datatypes.text.interfaces import IDvCodedText, ICodePhrase, IDvText
+from oship.openehr.rm.datatypes.encapsulated.interfaces import IDvParsable
+from oship.openehr.rm.datatypes.quantity.datetime.interfaces import IDvDateTime
+from oship.openehr.rm.data_structures.item_structure.interfaces import IItemStructure
+from oship.openehr.rm.data_structures.history.interfaces import IHistory
+
+
+_ = MessageFactory('oship')
+
+
+class ICareEntry(Interface):
+ u"""
+ The abstract parent of all clinical ENTRY subtypes. A CARE_ENTRY defines
+ protocol and guideline attributes for all clinical Entry subtypes.
+
+ """
+
+ protocol = Object(
+ schema=IItemStructure,
+ title=_(u"Protocol"),
+ description=_(u"""Description of the method (i.e. how) the information in this
+ entry was arrived at. For OBSERVATIONs, this is a description of the
+ method or instrument used. For EVALUATIONs, how the evaluation was
+ arrived at. For INSTRUCTIONs, how to execute the Instruction.
+ This may take the form of references to guidelines, including
+ manually followed and executable; knowledge references such as a
+ paper in Medline; clinical reasons within a largercare process."""),
+ required=False
+ )
+
+ guidelineId = Object(
+ schema=IObjectRef,
+ title=_(u"guidelineId"),
+ description=_(u"""Optional external identifier of guideline creating this
+ action if relevant."""),
+ required=False
+ )
+
+
+
+class IAdminEntry(Interface):
+ u"""
+ Entry subtype for administrative information, i.e. information about setting up the
+ clinical process, but not itself clinically relevant. Archetypes will define con-
+ tained information.
+ Used for admistrative details of admission, episode, ward location, discharge,
+ appointment (if not stored in a practice management or appointments system).
+
+ Not used for any clinically significant information.
+ """
+
+ data = Object(
+ schema=IItemStructure,
+ title=u"""data""",
+ description=u"""The data of the Entry; modelled in archetypes.""",
+ required=True
+ )
+
+
+
+class IEvaluation(Interface):
+ """
+ Entry type for evaluation statements.
+ """
+
+ data=Object(
+ schema=IItemStructure,
+ title=_(u"Data"),
+ description=_(u"The data of this evaluation."),
+
+ )
+
+
+
+class IIsmTransition(Interface):
+ """
+ Model of a transition in the Instruction state machine.
+ """
+
+ currentState=Object(
+ schema=IDvCodedText,
+ title=_(u"Current State"),
+ description=_(u"The ISM current state."),
+
+ )
+
+ transition=Object(
+ schema=IDvCodedText,
+ title=_(u"Transition"),
+ description=_(u"The ISM transition which occured to arrive at the current state."),
+ required=False,
+ )
+
+ careflowStep=Object(
+ schema=IDvCodedText,
+ title=_(u"Careflow Step"),
+ description=_(u"The step in the careflow process which occured as part of this process."),
+ required=False,
+ )
+
+
+
+class IEntry(Interface):
+ u"""
+ The abstract parent of all ENTRY subtypes. An ENTRY is the root of a logical item
+ of "hard" clinical information created in the "clinical statement" context, within a
+ clinical session. There can be numerous such contexts in a clinical session. Obser-
+ vations and other Entry types only ever document information captured/created in
+ the event documented by the enclosing Composition.
+ An ENTRY is also the minimal unit of information any query should return, since a
+ whole ENTRY (including subparts) records spatial structure, timing information,
+ and contextual information, as well as the subject and generator of the informa-
+ tion.
+
+ """
+
+ language = Object(
+ schema=ICodePhrase,
+ title = _(u"language"),
+ description = _(u"""Mandatory indicator of the localised language in which this Entry
+ is written. Coded from openEHR Code Set "languages"."""),
+ required = True
+ )
+
+ encoding = Object(
+ schema=ICodePhrase,
+ title = _(u"encoding"),
+ description = _(u"""Name of character set in which text values in this Entry are encoded.
+ Coded from openEHR Code Set "character sets"."""),
+ required = True
+ )
+
+
+ subject = Object(
+ schema=IPartyProxy,
+ title = _(u"subject"),
+ description = _(u"""Id of human subject of this ENTRY, e.g.
+ organ donor, foetus, a family member
+ another clinically relevant person."""),
+ required = True
+ )
+
+ provider = Object(
+ schema=IPartyProxy,
+ title = _(u"provider"),
+ description = _(u"""Optional identification of provider of the information in this ENTRY, which might be:
+ the patient
+ a patient agent, e.g. parent, guardian
+ the clinician
+ a device or software
+ Generally only used when the recorder needs to make it explicit. Otherwise, Composition
+ composer and other participants are assumed. """),
+ required = False
+ )
+
+ otherParticipations = List(
+ title = _(u"otherParticipations"),
+ description = _(u"""Other participations at ENTRY level."""),
+ value_type=Object(schema=IParticipation),
+ required = False
+ )
+
+ workflowId = Object(
+ schema=IObjectRef,
+ title = _(u"workflowId"),
+ description = _(u"""Identifier of externally held workflow engine data for this
+ workflow execution, for this subject of care."""),
+ required = False
+ )
+
+
+ def subectIsSelf():
+ u"""Returns True if this Entry is about the subject of the EHR, in which case the
+ subject attribute is of type PARTY_SELF. """
+
+
+
+
+class IInstructionDetails(Interface):
+ """
+ Used to record the details of an Instruction causing an Action.
+ """
+
+ instructionId=Object(
+ schema=ILocatableRef,
+ title=_(u"Instruction Id"),
+ description=_(u"Reference to causing Instruction."),
+
+ )
+
+ activityId=TextLine(
+ title=_(u"Activity Id"),
+ description=_(u"Indentifier of Activity within Instruction."),
+ required=False,
+ )
+
+ wfDetails=Object(
+ schema=IItemStructure,
+ title=_(u"WF Details"),
+ description=_(u"Various workflow engine state details."),
+ required=False,
+ )
+
+
+
+
+class IAction(Interface):
+ """
+ Used to record a clinical action that has been performed.
+ """
+
+ time=Object(
+ schema=IDvDateTime,
+ title=_(u"Timing"),
+ description=_(u"Point in time of completion of this action."),
+ )
+
+ description=Object(
+ schema=IItemStructure,
+ title=_(u"Description"),
+ description=_(u"Description of the activity in ItemStructure form."),
+ )
+
+ ismTransition=Object(
+ schema=IIsmTransition,
+ title=_(u"ISM Transition"),
+ description=_(u"Details of the transition of the Instruction state."),
+ )
+
+ instructionDetails=Object(
+ schema=IInstructionDetails,
+ title=_(u"Instruction Details"),
+ description=_(u"Details of the Instruction causing this Action."),
+ required=False,
+ )
+
+
+class IActivity(Interface):
+ """
+ A single activity within an instruction.
+ """
+
+ description=Object(
+ schema=IItemStructure,
+ title=_(u"Description"),
+ description=_(u"Description of the activity."),
+ required=True,
+ )
+
+ timing=Object(
+ schema=IDvParsable,
+ title=_(u"Timing"),
+ description=_(u"Timing of the activity in a format such as ISO8601."),
+ required=True,
+ )
+
+ actionArchetypeId=TextLine(
+ title=_(u"Action ArchetypeId"),
+ description=_(u"re pattern enclosed in '//' delimiters."),
+ required=False,
+ )
+
+
+class IInstruction(Interface):
+ """
+ Used to specify future actions and includes a workflow form.
+ """
+
+ narrative=Object(
+ schema=IDvText,
+ title=_(u"Narrative"),
+ description=_(u"Human readable version of the Instructions."),
+ required=True
+ )
+
+ activities=List(
+ value_type = Object(schema = IActivity),
+ title=_(u"Activities"),
+ description=_(u"List of all activities in the Instruction."),
+ required=False,
+ )
+
+ expiryTime=Object(
+ schema=IDvDateTime,
+ title=_(u"Expiry Time"),
+ description=_(u"Data/time when this Instruction can be assumed to have expired."),
+ required=False,
+ )
+
+ wfDefinition=Object(
+ schema=IDvParsable,
+ title=_(u"Workflow Definition"),
+ description=_(u"Workflow engine executable expression of the Instruction."),
+ required=False,
+ )
+
+
+
+class IObservation(Interface):
+ u"""Entry subtype for all clinical data in the past or present, i.e. which (by the time it
+ is recorded) has already occurred. OBSERVATION data is expressed using the class
+ HISTORY<T>, which guarantees that it is situated in time.
+ OBSERVATION is used for all notionally objective (i.e. measured in some way)
+ observations of phenomena, and patient-reported phenomena, e.g. pain.
+ Not used for recording opinion or future statements of any kind, including instructions,
+ intentions, plans etc."""
+
+ data = Object(
+ schema=IHistory,
+ title=_(u"data"),
+ description=_(u"""The data of this observation, in the form of a history of
+ values which may be of any complexity."""),
+ required=True
+ )
+
+ state = Object(
+ schema=IHistory,
+ title=_(u"state"),
+ description=_(u"""Optional recording of the state of subject of this
+ observation during the observation process, in the form of
+ a separate history of values which may be of any complexity.
+ State may also be recorded within the History of the data attribute."""),
+ required=False
+ )
=== added directory 'src/oship/openehr/rm/composition/content/entry/tests'
=== added file 'src/oship/openehr/rm/composition/content/entry/tests/__init__.py'
=== added file 'src/oship/openehr/rm/composition/content/entry/tests/action.txt'
--- src/oship/openehr/rm/composition/content/entry/tests/action.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/content/entry/tests/action.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,55 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.composition.content.entry import Action,IsmTransition
+>>> from oship.openehr.rm.composition.content.entry.interfaces import IAction,IIsmTransition
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> from oship.openehr.rm.datatypes.text import CodePhrase,DvText,DvCodedText
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvDateTime
+>>> from oship.openehr.rm.data_structures.history import History
+>>> from oship.openehr.rm.data_structures.item_structure import ItemSingle
+>>> from oship.openehr.rm.common.generic import PartySelf
+>>> tid1 = TerminologyId(u'ISO_639-1')
+>>> encod = CodePhrase(tid1,u'en')
+>>> lang = CodePhrase(tid1,u'UTF-8')
+>>> subject = PartySelf(None)
+>>> actionName = DvText(u"An action", None, u"font-family:Arial", None, None, None)
+>>> time = DvDateTime(u'2010-01-13T00:00:00',0,None,None,None,None)
+>>> origin_date = DvDateTime(u'2009-09-09T00:00:00',0,None,None,None,None)
+>>> description = History(origin_date, ItemSingle)
+>>> openEhrTerminologyId = TerminologyId(u"openehr")
+>>> stateCodePhrase = CodePhrase(openEhrTerminologyId,u"Instruction States")
+>>> currentState = DvCodedText(stateCodePhrase,u"planned",None,None,None,None,None)
+>>> transitionCodePhrase = CodePhrase(openEhrTerminologyId,u"Instruction Transition")
+>>> transition = DvCodedText(transitionCodePhrase,u"initiate",None,None,None,None,None)
+>>> ismTransition = IsmTransition(currentState,transition,None)
+>>> action = Action(time,description,ismTransition,None,None,None,lang,encod,subject,None,None,None,None,u'at0004',actionName,None,None,None)
+>>> action.time.value
+u'2010-01-13T00:00:00'
+>>> action.description.origin.value
+u'2009-09-09T00:00:00'
+>>> action.ismTransition.currentState.definingCode.codeString
+u'Instruction States'
+>>> action.ismTransition.currentState.definingCode.terminologyId.value
+u'openehr'
+>>> action.ismTransition.currentState.value
+u'planned'
+>>> action.ismTransition.transition.definingCode.codeString
+u'Instruction Transition'
+>>> action.ismTransition.transition.definingCode.terminologyId.value
+u'openehr'
+>>> action.ismTransition.transition.value
+u'initiate'
+>>> action.name.value
+u'An action'
+>>> action.archetypeNodeId
+u'at0004'
+>>> IAction.providedBy(action)
+True
+>>> isinstance(action,Action)
+True
+>>> IIsmTransition.providedBy(ismTransition)
+True
+>>> isinstance(ismTransition,IsmTransition)
+True
+>>>
+
=== added file 'src/oship/openehr/rm/composition/content/entry/tests/evaluation.txt'
--- src/oship/openehr/rm/composition/content/entry/tests/evaluation.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/content/entry/tests/evaluation.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,47 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.composition.content.entry import Evaluation
+>>> from oship.openehr.rm.composition.content.entry.interfaces import IEvaluation
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> from oship.openehr.rm.datatypes.text import CodePhrase, TermMapping, DvText
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvDateTime
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> from oship.openehr.rm.data_structures.history import History
+>>> from oship.openehr.rm.data_structures.item_structure import ItemSingle
+>>> from oship.openehr.rm.common.generic import PartySelf
+>>> origin_date = DvDateTime(u'2009-09-09T00:00:00',0,None,None,None,None)
+>>> data = History(origin_date, ItemSingle)
+>>> tid1 = TerminologyId(u'ISO_639-1')
+>>> encod = CodePhrase(tid1,u'en')
+>>> lang = CodePhrase(tid1,u'UTF-8')
+>>> partySelf = PartySelf(None)
+>>> tid2 = TerminologyId(u"ISO_639-1")
+>>> tid3 = TerminologyId(u"10646-1:1993")
+>>> cpm = CodePhrase(tid1,u"abc123")
+>>> tm = TermMapping(cpm,u"=",None)
+>>> uri = DvUri(u"http://www.oship.org")
+>>> cplang = CodePhrase(tid2,u"en")
+>>> cpenc = CodePhrase(tid3,u"utf-8")
+>>> entryName = DvText(u"Evaluation", [tm,], u"font-family:Arial", uri, cplang, cpenc)
+>>> evaluation = Evaluation(data,None,None,lang,encod,partySelf,None,None,None,None,u'at0004',entryName,None,None,None)
+>>> evaluation.data.origin.value
+u'2009-09-09T00:00:00'
+>>> evaluation.language.terminologyId.value
+u'ISO_639-1'
+>>> evaluation.language.codeString
+u'UTF-8'
+>>> evaluation.encoding.terminologyId.value
+u'ISO_639-1'
+>>> evaluation.encoding.codeString
+u'en'
+>>> evaluation.subjectIsSelf()
+True
+>>> evaluation.archetypeNodeId
+u'at0004'
+>>> evaluation.name.value
+u'Evaluation'
+>>> IEvaluation.providedBy(evaluation)
+True
+>>> isinstance(evaluation,Evaluation)
+True
+>>>
=== added file 'src/oship/openehr/rm/composition/content/entry/tests/instruction.txt'
--- src/oship/openehr/rm/composition/content/entry/tests/instruction.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/content/entry/tests/instruction.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,73 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.composition.content.entry import Instruction,Activity
+>>> from oship.openehr.rm.composition.content.entry.interfaces import IInstruction
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> from oship.openehr.rm.datatypes.text import CodePhrase,DvText
+>>> from oship.openehr.rm.datatypes.encapsulated import DvParsable
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvDateTime
+>>> from oship.openehr.rm.data_structures.history import History
+>>> from oship.openehr.rm.data_structures.item_structure import ItemSingle
+>>> from oship.openehr.rm.common.generic import PartySelf
+>>> tid1 = TerminologyId(u'ISO_639-1')
+>>> encod = CodePhrase(tid1,u'en')
+>>> lang = CodePhrase(tid1,u'UTF-8')
+>>> partySelf = PartySelf(None)
+>>> # Minimal instruction - without activities and workflow definition
+>>> minimalInstructionNarrative = DvText(u"A minimal instruction. It just has a narrative.", None, u"font-family:Arial", None, None, None)
+>>> minimalInstructionName = DvText(u"Minimal Instruction", None, u"font-family:Arial", None, None, None)
+>>> minimalInstruction = Instruction(minimalInstructionNarrative,None,None,None,None,None,lang,encod,partySelf,None,None,None,None,u'at0004',minimalInstructionName,None,None,None)
+>>> minimalInstruction.narrative.value
+u'A minimal instruction. It just has a narrative.'
+>>> minimalInstruction.name.value
+u'Minimal Instruction'
+>>> IInstruction.providedBy(minimalInstruction)
+True
+>>> isinstance(minimalInstruction,Instruction)
+True
+>>> #Basic instruction - without a workflow definition but with computable activities
+>>> basicInstructionNarrative = DvText(u"A basic instruction. It has a narrative and computable activities.", None, u"font-family:Arial", None, None, None)
+>>> basicInstructionName = DvText(u"Basic Instruction", None, u"font-family:Arial", None, None, None)
+>>> activityTiming = DvParsable(u"Timing",u"ISO8601",None,None,None)
+>>> origin_date = DvDateTime(u'2009-09-09T00:00:00',0,None,None,None,None)
+>>> activityDescription = History(origin_date, ItemSingle)
+>>> activityName = DvText(u"Activity", None, u"font-family:Arial", None, None, None)
+>>> activity = Activity(activityDescription,activityTiming,None,None,u'at0005',activityName,None,None,None)
+>>> basicInstruction = Instruction(basicInstructionNarrative,[activity],None,None,None,None,lang,encod,partySelf,None,None,None,None,u'at0004',basicInstructionName,None,None,None)
+>>> basicInstruction.narrative.value
+u'A basic instruction. It has a narrative and computable activities.'
+>>> basicInstruction.name.value
+u'Basic Instruction'
+>>> basicInstruction.activities[0].name.value
+u'Activity'
+>>> basicInstruction.activities[0].timing.value
+u'Timing'
+>>> basicInstruction.activities[0].description.origin.value
+u'2009-09-09T00:00:00'
+>>> IInstruction.providedBy(basicInstruction)
+True
+>>> isinstance(basicInstruction,Instruction)
+True
+>>> #Full instruction - with activities and a computable workflow
+>>> fullInstructionNarrative = DvText(u"A full instruction", None, u"font-family:Arial", None, None, None)
+>>> fullInstructionName = DvText(u"Full Instruction", None, u"font-family:Arial", None, None, None)
+>>> wfDefinition = DvParsable(u"Workflow engine", u"", None, None, None)
+>>> fullInstruction = Instruction(fullInstructionNarrative,[activity],None,wfDefinition,None,None,lang,encod,partySelf,None,None,None,None,u'at0004',fullInstructionName,None,None,None)
+>>> fullInstruction.narrative.value
+u'A full instruction'
+>>> fullInstruction.name.value
+u'Full Instruction'
+>>> fullInstruction.activities[0].name.value
+u'Activity'
+>>> fullInstruction.activities[0].timing.value
+u'Timing'
+>>> fullInstruction.activities[0].description.origin.value
+u'2009-09-09T00:00:00'
+>>> fullInstruction.wfDefinition.value
+u'Workflow engine'
+>>> IInstruction.providedBy(fullInstruction)
+True
+>>> isinstance(fullInstruction,Instruction)
+True
+>>>
+
=== added file 'src/oship/openehr/rm/composition/content/entry/tests/observation.txt'
--- src/oship/openehr/rm/composition/content/entry/tests/observation.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/content/entry/tests/observation.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,45 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.composition.content.entry import Observation
+>>> from oship.openehr.rm.composition.content.entry.interfaces import IObservation
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> from oship.openehr.rm.datatypes.text import CodePhrase,TermMapping,DvText
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvDateTime
+>>> from oship.openehr.rm.data_structures.history import History
+>>> from oship.openehr.rm.data_structures.item_structure import ItemSingle
+>>> from oship.openehr.rm.common.generic import PartySelf
+>>> data = History(DvDateTime(u'2009-09-09T00:00:00',0,None,None,None,None), ItemSingle, None, None, None, None)
+>>> tid1 = TerminologyId(u'ISO_639-1')
+>>> encod = CodePhrase(tid1,u'en')
+>>> lang = CodePhrase(tid1,u'UTF-8')
+>>> partySelf = PartySelf(None)
+>>> tid2 = TerminologyId(u"ISO_639-1")
+>>> tid3 = TerminologyId(u"10646-1:1993")
+>>> cpm = CodePhrase(tid1,u"abc123")
+>>> tm = TermMapping(cpm,u"=",None)
+>>> uri = DvUri(u"http://www.oship.org")
+>>> cplang = CodePhrase(tid2,u"en")
+>>> cpenc = CodePhrase(tid3,u"utf-8")
+>>> entryName = DvText(u"Observation", [tm,], u"font-family:Arial", uri, cplang, cpenc)
+>>> observation = Observation(data,None,None,None,lang,encod,partySelf,None,None,None,None,u'at0004',entryName,None,None,None)
+>>> observation.data.origin.value
+u'2009-09-09T00:00:00'
+>>> observation.language.terminologyId.value
+u'ISO_639-1'
+>>> observation.language.codeString
+u'UTF-8'
+>>> observation.encoding.terminologyId.value
+u'ISO_639-1'
+>>> observation.encoding.codeString
+u'en'
+>>> observation.subjectIsSelf()
+True
+>>> observation.archetypeNodeId
+u'at0004'
+>>> observation.name.value
+u'Observation'
+>>> IObservation.providedBy(observation)
+True
+>>> isinstance(observation,Observation)
+True
=== added file 'src/oship/openehr/rm/composition/content/interfaces.py'
--- src/oship/openehr/rm/composition/content/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/content/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,8 @@
+
+from zope.interface import Interface
+
+
+class IContentItem(Interface):
+ """
+ Abstract ancestor of all concrete content types.
+ """
=== added directory 'src/oship/openehr/rm/composition/content/navigation'
=== added file 'src/oship/openehr/rm/composition/content/navigation/__init__.py'
--- src/oship/openehr/rm/composition/content/navigation/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/content/navigation/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,18 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from oship.openehr.rm.composition.content import ContentItem
+from interfaces import ISection
+import grok
+
+class Section(ContentItem):
+ """
+ Represents a heading in a heading structure or 'section tree'.
+ """
+
+ grok.implements(ISection)
+
+ def __init__(self,items,uid,atnodeid,name,atdetails,fdraudit,links):
+ ContentItem.__init__(self,uid,atnodeid,name,atdetails,fdraudit,links)
+
+ self.items=items
=== added file 'src/oship/openehr/rm/composition/content/navigation/interfaces.py'
--- src/oship/openehr/rm/composition/content/navigation/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/content/navigation/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface
+from zope.i18nmessageid import MessageFactory
+from zope.schema import List, Object
+from oship.openehr.rm.composition.content.interfaces import IContentItem
+import grok
+
+
+
+_ = MessageFactory('oship')
+
+
+
+class ISection(Interface):
+ """
+ Represents a heading in a heading structure or 'section tree'.
+ """
+
+ items=List(
+ title=_(u"Items"),
+ description=_(u"Ordered list of content items that may include more SECTIONs or ENTRYs."),
+ value_type=Object(schema=IContentItem),
+ required=False,
+ )
=== added directory 'src/oship/openehr/rm/composition/content/navigation/tests'
=== added file 'src/oship/openehr/rm/composition/content/navigation/tests/__init__.py'
=== added file 'src/oship/openehr/rm/composition/content/navigation/tests/section.txt'
--- src/oship/openehr/rm/composition/content/navigation/tests/section.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/content/navigation/tests/section.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,50 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.composition.content.navigation import Section
+>>> from oship.openehr.rm.composition.content.navigation.interfaces import ISection
+>>> from oship.openehr.rm.composition.content.entry import Observation
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> from oship.openehr.rm.datatypes.text import CodePhrase,TermMapping,DvText
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvDateTime
+>>> from oship.openehr.rm.data_structures.item_structure import ItemSingle
+>>> from oship.openehr.rm.data_structures.history import History
+>>> from oship.openehr.rm.common.generic import PartySelf
+>>> origin_date = DvDateTime(u'2009-09-09T00:00:00',0,None,None,None,None)
+>>> data = History(origin_date,ItemSingle)
+>>> tid1 = TerminologyId(u'ISO_639-1')
+>>> encod = CodePhrase(tid1,u'en')
+>>> lang = CodePhrase(tid1,u'UTF-8')
+>>> partySelf = PartySelf(None)
+>>> tid2 = TerminologyId(u"ISO_639-1")
+>>> tid3 = TerminologyId(u"10646-1:1993")
+>>> cpm = CodePhrase(tid1,u"abc123")
+>>> tm = TermMapping(cpm,u"=",None)
+>>> uri = DvUri(u"http://www.oship.org")
+>>> cplang = CodePhrase(tid2,u"en")
+>>> cpenc = CodePhrase(tid3,u"utf-8")
+>>> observationEntryName = DvText(u"Observation", [tm,], u"font-family:Arial", uri, cplang, cpenc)
+>>> observation = Observation(data,None,None,None,lang,encod,partySelf,None,None,None,None,u'at0004',observationEntryName,None,None,None)
+>>> items = [observation,]
+>>> section1EntryName = DvText(u"Section 1", [tm,], u"font-family:Arial", uri, cplang, cpenc)
+>>> section1 = Section(items,None,u"at0003",section1EntryName,None,None,None)
+>>> section1.items[0].data.origin.value
+u'2009-09-09T00:00:00'
+>>> section1.archetypeNodeId
+u'at0003'
+>>> section1.name.value
+u'Section 1'
+>>> ISection.providedBy(section1)
+True
+>>> isinstance(section1,Section)
+True
+>>> section2EntryName = DvText(u"Section 2", [tm,], u"font-family:Arial", uri, cplang, cpenc)
+>>> section2 = Section([section1],None,u"at0003",section2EntryName,None,None,None)
+>>> section2.name.value
+u'Section 2'
+>>> section2.items[0].name.value
+u'Section 1'
+>>> section2.items[0].items[0].name.value
+u'Observation'
+>>>
+
=== added file 'src/oship/openehr/rm/composition/interfaces.py'
--- src/oship/openehr/rm/composition/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+
+
+from zope.interface import Interface
+from zope.i18nmessageid import MessageFactory
+from zope.schema import List, Object, TextLine
+from oship.openehr.rm.common.generic.interfaces import (IPartyIdentified,
+ IParticipation, IPartyProxy)
+from oship.openehr.rm.datatypes.text.interfaces import IDvCodedText,ICodePhrase
+from oship.openehr.rm.datatypes.quantity.datetime.interfaces import IDvDateTime
+from oship.openehr.rm.data_structures.item_structure.interfaces import IItemStructure
+from oship.openehr.rm.composition.content.interfaces import IContentItem
+
+
+_ = MessageFactory('oship')
+
+
+class IEventContext(Interface):
+ """
+ The context information of a healthcare event.
+ These include patient contacts or other investigations.
+ """
+
+ healthCareFacility=Object(
+ schema=IPartyIdentified,
+ title=_(u"Healthcare Facility"),
+ description=_(u"Where this event took place."),
+ required=False,
+ )
+
+ startTime=Object(
+ schema=IDvDateTime,
+ title=_(u"Start Time"),
+ description=_(u"Start Time"),
+
+ )
+
+ endTime=Object(
+ schema=IDvDateTime,
+ title=_(u"End Time"),
+ description=_(u"End Time"),
+ required=False,
+ )
+
+ participations=List(
+ title=_(u"Participations"),
+ description=_(u"List of all parties involved in the event."),
+ value_type=Object(schema=IParticipation),
+ required=False,
+ )
+
+ location=TextLine(
+ title=_(u"Location"),
+ description=_(u"Physical location of this event; ABCLab, home,etc."),
+ required=False,
+ )
+
+ setting=Object(
+ schema=IDvCodedText,
+ title=_(u"Setting"),
+ description=_(u"The setting of the clinical event."),
+
+ )
+
+ otherContext=Object(
+ schema=IItemStructure,
+ title=_(u"Other Context"),
+ description=_(u"Other optional archetyped context."),
+ required=False,
+ )
+
+
+class IComposition(Interface):
+ """
+ One version in a VersionedComposition. A composition is considered the unit of modification in an EHR.
+ """
+
+ content=List(
+ title=_(u"Content"),
+ description=_(u"Content of this composition."),
+ value_type=Object(schema=IContentItem),
+ required=False,
+ )
+
+ context=Object(
+ schema=IEventContext,
+ title=_(u"Context"),
+ description=_(u"The clinical session context."),
+ required=False,
+ )
+
+ composer=Object(
+ schema=IPartyProxy,
+ title=_(u"Composer"),
+ description=_(u"The party responsible for the content. It may not be the actual person entering the data."),
+
+ )
+
+ category=Object(
+ schema=IDvCodedText,
+ title=_(u"Category"),
+ description=_(u"Defines the broad category of this composition."),
+
+ )
+
+ language=Object(
+ schema=ICodePhrase,
+ title=_(u"Language"),
+ description=_(u"Indicator of the localised language where this composition was created."),
+
+ )
+
+ territory=Object(
+ schema=ICodePhrase,
+ title=_(u"Territory"),
+ description=_(u"Territory where this composition was written. ISO 3166."),
+
+ )
+
+ def isPersistent():
+ """Used to locate items that are of interest to most users."""
=== added directory 'src/oship/openehr/rm/composition/tests'
=== added file 'src/oship/openehr/rm/composition/tests/__init__.py'
=== added file 'src/oship/openehr/rm/composition/tests/composition.txt'
--- src/oship/openehr/rm/composition/tests/composition.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/tests/composition.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,66 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.composition.content.entry import Observation
+>>> from oship.openehr.rm.composition.content.navigation import Section
+>>> from oship.openehr.rm.composition import EventContext, Composition
+>>> from oship.openehr.rm.composition.interfaces import IComposition
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> from oship.openehr.rm.datatypes.text import CodePhrase,TermMapping,DvText,DvCodedText
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvDateTime
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> from oship.openehr.rm.data_structures.history import History
+>>> from oship.openehr.rm.data_structures.item_structure import ItemSingle
+>>> from oship.openehr.rm.common.generic import PartySelf,PartyIdentified,Participation
+>>> origin_date = DvDateTime(u'2009-09-09T00:00:00',0,None,None,None,None)
+>>> data = History(origin_date, ItemSingle)
+>>> tid1 = TerminologyId(u'ISO_639-1')
+>>> encod = CodePhrase(tid1,u'en')
+>>> lang = CodePhrase(tid1,u'UTF-8')
+>>> partySelf = PartySelf(None)
+>>> observationEntryName = DvText(u"Observation", None, u"font-family:Arial", None, None, None)
+>>> observation = Observation(data,None,None,None,lang,encod,partySelf,None,None,None,None,u'at0004',observationEntryName,None,None,None)
+>>> sectionEntryName = DvText(u"Section 1", None, u"font-family:Arial", None, None, None)
+>>> section = Section([observation,],None,u"at0003",sectionEntryName,None,None,None)
+>>> healthCareFacility = PartyIdentified(u'The health care facility', None, None)
+>>> start = DvDateTime(u'2009-12-31T00:00:00',0,None,None,None,None)
+>>> tid2 = TerminologyId(u'OpenEHR Terminology - setting group')
+>>> cp = CodePhrase(tid2,u'abc123')
+>>> setting = DvCodedText(cp,u"setting",[],u"",None,None,None)
+>>> performer = PartyIdentified(u'Performer',None,None)
+>>> function = DvText(u"Some really interesting text.",None,u"font-family:Arial",None,None,None)
+>>> mode = DvCodedText(cp,u"mode",[],u"",None,None,None)
+>>> participations = [Participation(performer,function,mode,None),]
+>>> location = u'home'
+>>> eventContext = EventContext(healthCareFacility,start,None,participations,location,setting,None)
+>>> composer = PartyIdentified(u'Composer',None,None)
+>>> cpcategory = CodePhrase(tid1,u'abc123')
+>>> category = DvCodedText(cpcategory,u'category',[],u'',None,None,None)
+>>> lang = CodePhrase(tid1,u'en')
+>>> tid3 = TerminologyId(u'ISO_3166')
+>>> territory = CodePhrase(tid3,u'US')
+>>> compositionEntryName = DvText(u"Composition", None, u"font-family:Arial", None, None, None)
+>>> composition = Composition([section,],eventContext,composer,category,lang,territory,None,u'at0005',compositionEntryName,None,None,None)
+>>> composition.content[0].name.value
+u'Section 1'
+>>> composition.content[0].items[0].name.value
+u'Observation'
+>>> composition.context.location
+u'home'
+>>> composition.composer.name
+u'Composer'
+>>> composition.category.value
+u'category'
+>>> composition.language.codeString
+u'en'
+>>> composition.territory.codeString
+u'US'
+>>> composition.name.value
+u'Composition'
+>>> composition.isPersistent()
+True
+>>> IComposition.providedBy(composition)
+True
+>>> isinstance(composition,Composition)
+True
+>>>
+
=== added file 'src/oship/openehr/rm/composition/tests/eventcontext.txt'
--- src/oship/openehr/rm/composition/tests/eventcontext.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/composition/tests/eventcontext.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,38 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.composition import EventContext
+>>> from oship.openehr.rm.composition.interfaces import IEventContext
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> from oship.openehr.rm.datatypes.text import CodePhrase, DvCodedText, DvText
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvDateTime
+>>> from oship.openehr.rm.common.generic import PartyIdentified,Participation
+>>> healthCareFacility = PartyIdentified(u'The health care facility', None, None)
+>>> start = DvDateTime(u'2009-12-31T00:00:00',0,None,None,None,None)
+>>> tid = TerminologyId(u'OpenEHR Terminology - setting group')
+>>> cp = CodePhrase(tid,u'abc123')
+>>> setting = DvCodedText(cp,u"setting",[],u"",None,None,None)
+>>> performer = PartyIdentified(u'Performer',None,None)
+>>> function = DvText(u"Some really interesting text.",None,u"font-family:Arial",None,None,None)
+>>> mode = DvCodedText(cp,u"mode",[],u"",None,None,None)
+>>> participations = [Participation(performer,function,mode,None),]
+>>> location = u'home'
+>>> eventContext = EventContext(healthCareFacility,start,None,participations,location,setting,None)
+>>> eventContext.healthCareFacility.name
+u'The health care facility'
+>>> eventContext.startTime.value
+u'2009-12-31T00:00:00'
+>>> eventContext.participations[0].performer.name
+u'Performer'
+>>> eventContext.participations[0].function.value
+u'Some really interesting text.'
+>>> eventContext.participations[0].mode.value
+u'mode'
+>>> eventContext.location
+u'home'
+>>> eventContext.setting.value
+u'setting'
+>>> IEventContext.providedBy(eventContext)
+True
+>>> isinstance(eventContext,EventContext)
+True
+>>>
=== added directory 'src/oship/openehr/rm/data_structures'
=== added file 'src/oship/openehr/rm/data_structures/__init__.py'
--- src/oship/openehr/rm/data_structures/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+# Copyright (c) 2007, Timothy W. Cook and Contributors. All rights reserved.
+# Redistribution and use are governed by the MPL license.
+#
+# Use and/or redistribution of this file assumes you have read and accepted the
+# terms of the license.
+##############################################################################
+
+
+u"""
+From the Data Structures Information Model
+Data Structure Package Rev. 2.1.0.
+"""
+
+
+__author__ = u'Timothy Cook <timothywayne.cook@xxxxxxxxx>'
+__docformat__ = u'plaintext'
+__contributors__ = u'<name> <email address>'
+
+import grok
+
+
+from oship.openehr.rm.common.archetyped import Locatable
+from interfaces import *
+
+
+class DataStructure(Locatable):
+ u"""
+ Abstract parent class of all data structure types. Includes the
+ as_hierarchy function which can generate the equivalent CEN EN13606 single
+ hierarchy for each subtype's physical representation. For example, the
+ physical representation of an ITEM_LIST is List<ELEMENT>; its
+ implementation of as_hierarchy will generate a CLUSTER containing the set
+ of ELEMENT nodes from the list.
+ """
+
+ grok.implements(IDataStructure)
+
+ def __init__(self, uid, atnodeid, name, atdetails, fdraudit, links, parent):
+ Locatable.__init__(self, uid, atnodeid, name, atdetails, fdraudit,
+ links)
+
+ def asHierarchy(self):
+ u"""Hierarchical equivalent of the physical representation of each
+ subtype, compatible with CEN EN 13606 structures. Returns a List."""
+ pass
+
+
=== added directory 'src/oship/openehr/rm/data_structures/history'
=== added file 'src/oship/openehr/rm/data_structures/history/__init__.py'
--- src/oship/openehr/rm/data_structures/history/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/history/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,226 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import time
+from zope.container.constraints import checkObject
+from zope.schema.fieldproperty import FieldProperty
+from zope.container.contained import NameChooser
+from zope.container.interfaces import INameChooser
+import grok
+from grok import IObjectRemovedEvent
+from oship.openehr.rm.common.archetyped import Locatable
+from oship.openehr.rm.data_structures import DataStructure
+from interfaces import *
+
+_ = MessageFactory('oship')
+
+
+class DiferentStructureError(Exception):
+ pass
+
+
+class NotAItemStructureError(Exception):
+ pass
+
+
+class EventContainer(grok.Container):
+ grok.implements(IEventContainer)
+
+
+ def __init__(self, history, klass_structure, event_list=None ):
+ if IItemStructure.implementedBy(klass_structure):
+ self.klass_structure = klass_structure
+ else:
+ raise NotAItemStructureError("""The %s class don't implement the
+ IItemStructure Interface.""")
+ self.history = history
+ super(EventContainer,self).__init__()
+ if event_list is not None:
+ name_chooser = INameChooser(self)
+ for event_object in event_list:
+ name = name_chooser.chooseName('',event_object)
+ self[name] = event_object
+
+ def __setitem__(self,name,value):
+ if not isinstance(value.data,self.klass_structure):
+ raise DiferentStructureError("""It was expected a diferent Structure""")
+ checkObject(self,name, value)
+ super(EventContainer,self).__setitem__(name,value)
+ value.__parent__ = self.history
+
+
+class Event(Locatable):
+ u"""
+ Defines the abstract notion of a single event in a series. This class is
+ generic,allowing types to be generated which are locked to particular
+ spatial types, such as EVENT<ITEM_LIST> Subtypes express point or interval
+ data.
+
+ """
+
+
+ grok.implements(IEvent, IEventContained)
+
+ def __init__( self, time, data, state, uid, atnodeid, name, atdetails, fdraudit, links ):
+ """
+ Event class initializer.
+
+ time -- A object that implement IDvDateTime Interface.
+ Usually a object from DvDateTime class.
+ data -- A object that implement IItemStructure Interface.
+ state --
+
+ """
+ Locatable.__init__(self, uid, atnodeid, name, atdetails, fdraudit, links)
+ self.time=time
+ self.data=data
+ self.state=state
+
+ def __eq__(self, obj):
+ if obj is self: return True
+ return isinstance(obj, Event)
+
+ def __ne__(self, obj):
+ return not self == obj
+
+ def __hash__(self):
+ return hash(self.time)
+
+ def parent(self):
+ return self.__parent__
+
+ def offset(self):
+ if self.parent is None:
+ return None
+ return self.time.diff(self.parent.origin)
+
+class EventNameChooser(grok.Adapter, NameChooser):
+
+ grok.context(IEventContainer)
+ grok.implements(INameChooser)
+
+ def chooseName(self, name, obj):
+ if not name:
+ new_name = str(len(self.context)+1)
+ self.checkName(new_name, obj)
+ else:
+ new_name = super(EventNameChooser,self).chooseName(name, obj)
+ return new_name
+
+
+@grok.subscribe(IHistory, IObjectRemovedEvent)
+def notifyEventsToHaveNoParents(history, event):
+ # TODO: improve the history removed event trigger to enable redefine
+ # the contained events even the history is not added to a container.
+ for event_key in history.events.keys():
+ history.events[event_key].__parent__ = None
+
+
+class History(DataStructure):
+ u"""
+ Root object of a linear history, i.e. time series structure. For a periodic
+ series of events, period will be set, and the time of each Event in the
+ History must correspond; i.e. the EVENT.offset must be a multiple of period
+ for each Event. Missing events in a period History are however allowed.
+
+ NOTE: The invariants have NOT been written yet for this interface.
+
+ """
+
+ grok.implements(IEventContainer, IHistory)
+
+ origin = FieldProperty(IHistory['origin'])
+ period = FieldProperty(IHistory['period'])
+ summary = FieldProperty(IHistory['summary'])
+ duration = FieldProperty(IHistory['duration'])
+ events = FieldProperty(IHistory['events'])
+
+
+ def __init__(self, origin, klass_structure, events=None,
+ period=None, duration=None, summary=None):
+
+ self.origin=origin
+ self.events = EventContainer(self,klass_structure,events)
+ self.period=period
+ self.duration=duration
+ self.summary=summary
+
+ def __setitem__(self, key, value):
+ self.events[key] = value
+
+ def __getitem__(self, key):
+ return self.events[key]
+
+ def __delitem__(self, key):
+ del self.events[key]
+
+ def keys(self):
+ """Return the keys of the mapping object.
+ """
+ return self.events.keys()
+
+ def __iter__(self):
+ """Return an iterator for the keys of the mapping object.
+ """
+ return iter(self.events)
+
+ def values(self):
+ """Return the values of the mapping object.
+ """
+ return self.events.values()
+
+ def items(self):
+ """Return the items of the mapping object.
+ """
+ return self.events.items()
+
+ def __len__(self):
+ """Return the number of items.
+ """
+ return len(self.events)
+
+ def __ne__(self, obj):
+ if not isinstance(obj, History): return True
+ return not self == obj
+
+ def __hash__(self):
+ return hash(self.origin) + hash(self.events)
+
+
+ def isPeriodic(self):
+ u"""Indicates whether history is periodic. Returns Boolean"""
+ pass
+
+
+class PointEvent(Event):
+ u"""
+ Defines a single point event in a series.
+ """
+
+ grok.implements(IEvent)
+
+ def __init__( self, time, data, state, uid, atnodeid, name, atdetails, fdraudit, links ):
+ Event.__init__(self, time, data, state, uid, atnodeid, name, atdetails, fdraudit, links)
+
+
+class IntervalEvent(Event):
+ u"""
+ Defines a single interval event in a series.
+
+ """
+
+ grok.implements(IIntervalEvent)
+
+ def __init__(self, width, mfunc, scount):
+ self.width=width
+ self.mathFunction=mfunc
+ self.sampleCount=scount
+
+ self.startTime=None
+ self.timer()
+
+ def timer(self):
+ self.startTime=time.strftime("%Y-%m-%dT%H:%M:%S")
+
+ def intervalStartTime(self):
+ return self.startTime
=== added file 'src/oship/openehr/rm/data_structures/history/interfaces.py'
--- src/oship/openehr/rm/data_structures/history/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/history/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,150 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from zope.i18nmessageid import MessageFactory
+from zope.interface import Interface
+from zope.schema import Object, Int
+
+from zope.container.interfaces import IContainer, IContained, INameChooser
+from zope.container.constraints import contains, containers, checkObject
+from oship.openehr.rm.datatypes.quantity.datetime.interfaces import (IDvDateTime,
+ IDvDuration)
+from oship.openehr.rm.datatypes.text.interfaces import IDvCodedText
+from oship.openehr.rm.data_structures.item_structure.interfaces import IItemStructure
+
+_ = MessageFactory('oship')
+
+
+class IEvent(Interface):
+ u"""
+ Defines the abstract notion of a single event in a series. This class is
+ generic,allowing types to be generated which are locked to particular
+ spatial types, such as EVENT<ITEM_LIST> Subtypes express point or interval
+ data. """
+
+ time=Object(
+ schema=IDvDateTime,
+ title=_(u'time'),
+ description=_(u"""Time of this event. If the width is non-zero, it is
+ the time point of the trailing edge of the event."""),
+ required=True)
+
+
+ data=Object(
+ schema=IItemStructure,
+ title=_(u'data'),
+ description=_(u'The data of this event.'),
+ required=True)
+
+ state=Object(
+ schema=IItemStructure,
+ title=_(u'state'),
+ description=_(u'Optional state information for this event.'),
+ required=False)
+
+ def parent():
+ u"""
+ Parent IHistory where the Event is Contained.
+ It's redefinition of LOCATABLE.parent to be of type History
+ """
+
+ def offset():
+ u"""
+ Offset of this event from origin , computed as
+ time.diff(parent.origin) .
+ """
+
+
+class IEventContainer(IContainer):
+ contains(IEvent)
+
+
+class IHistory(Interface):
+ u"""
+ Root object of a linear history, i.e. time series structure. For a periodic
+ series of events, period will be set, and the time of each Event in the
+ History must correspond; i.e. the EVENT.offset must be a multiple of period
+ for each Event. Missing events in a period History are however allowed.
+
+ NOTE: The invariants have NOT been written yet for this interface.
+
+ """
+
+ origin = Object(
+ schema=IDvDateTime,
+ title=_(u"origin"),
+ description=_(u"Time origin of this event history. The first event is"
+ " not necessarily at the origin point."),
+ required=True)
+
+ events = Object(
+ schema=IEventContainer,
+ title=_(u"events"),
+ description=_(u"The events in the series."),
+ required = False,
+ )
+
+ period=Object(
+ schema=IDvDuration,
+ title=_(u"period"),
+ description=_(u"Period between samples in this segment if periodic."),
+ required=False)
+
+ duration=Object(
+ schema=IDvDuration,
+ title=_(u"duration"),
+ description=_(u"Duration of the entire History; either corresponds to"
+ " the duration of all the events, and/or the duration represented by"
+ " the summary, if it exists."),
+ required=False)
+
+ summary=Object(
+ schema=IItemStructure,
+ title=_(u"summary"),
+ description=_(u"Optional summary data expressing e.g. text or image"
+ " which summarises entire History."),
+ required=False)
+
+ def isPeriodic():
+ u"""Indicates whether history is periodic. Returns Boolean"""
+
+ def asHierarchy():
+ u"""
+ Returns CLUSTER. Generate a CEN EN13606-compatible hierarchy of the
+ physical representation.
+
+ """
+
+
+class IEventContained(IContained):
+ containers(IEventContainer)
+
+
+class IIntervalEvent(Interface):
+ u"""
+ Defines a single interval event in a series.
+ """
+
+ width=Object(
+ schema=IDvDuration,
+ title=_(u"width"),
+ description=_(u"Length of the interval during which the state was"
+ " true."),
+ required=True)
+
+ mathFunction=Object(
+ schema=IDvCodedText,
+ title=_(u"mathFunction"),
+ description=_(u'Mathematical function of the data of this event, e.g.'
+ ' "maximum", "mean" etc. Coded using openEHR Terminology group'
+ ' "event math function".'),
+ required=True)
+
+ sampleCount=Int(
+ title=_(u"sampleCount"),
+ description=_(u"Optional count of original samples to which this event"
+ " corresponds."),
+ required=False)
+
+ def intervalStartTime():
+ u"""Start time of the interval of this event."""
=== added directory 'src/oship/openehr/rm/data_structures/history/tests'
=== added file 'src/oship/openehr/rm/data_structures/history/tests/__init__.py'
--- src/oship/openehr/rm/data_structures/history/tests/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/history/tests/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,1 @@
+# this directory is a package
=== added file 'src/oship/openehr/rm/data_structures/history/tests/event.py'
--- src/oship/openehr/rm/data_structures/history/tests/event.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/history/tests/event.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,56 @@
+"""
+Do a Python test on the app.
+
+:Test-Layer: python
+"""
+import unittest
+import grok
+
+from oship.openehr.rm.data_structures.history import PointEvent, History
+from oship.openehr.rm.datatypes.quantity.datetime import DvDateTime, DvDuration
+from oship.openehr.rm.data_structures.item_structure.interfaces import IItemStructure
+
+class EventTest(unittest.TestCase):
+
+ def setUp(self):
+ self.originOne = DvDateTime(value=u"2010-07-29T11:00 + 0000",magnitude=None,accuracy=None,normalRange=None,otherReferenceRanges=None,normalStatus=None)
+ self.originTwo = DvDateTime(value=u"2010-07-29T12:00 + 0000",magnitude=None,accuracy=None,normalRange=None,otherReferenceRanges=None,normalStatus=None)
+ self.historyOne = History(origin=self.originOne, klass_structure=SomeStructure)
+ self.historyTwo = History(origin=self.originTwo, klass_structure=SomeStructure)
+
+ self.aTime = DvDateTime(value=u"2010-07-29T12:00 +0000",magnitude=None,accuracy=None,normalRange=None,otherReferenceRanges=None,normalStatus=None)
+ self.pointEventOne = PointEvent(self.aTime, None, None, None, None, None, None, None, None)
+ self.pointEventOne.parent = self.historyOne #Verify event initializer
+
+ self.pointEventTwo = PointEvent(self.aTime, None, None, None, None, None, None, None, None)
+ self.pointEventTwo.parent = self.historyTwo #Verify event initializer
+
+ self.pointEventWithoutParent = PointEvent(self.aTime, None, None, None, None, None, None, None, None)
+ self.pointEventWithoutParent.parent = None
+
+ def tearDown(self):
+ self.aTime = None
+ self.originOne = None
+ self.originTwo = None
+ self.historyOne = None
+ self.historyTwo = None
+ self.pointEventOne = None
+ self.pointEventTwo = None
+ self.pointEventWithoutParent = None
+
+ def testOffsetMethodWithTimeGreaterOrigin(self):
+ result = self.pointEventOne.offset()
+ expected = DvDuration(u'PT3600.0S', None, None, None, None, None, None)
+ self.assertEqual(expected.value, result.value) #modify __eq__?
+
+ def testOffsetMethodWithTimeEqualToOrigin(self):
+ result = self.pointEventTwo.offset()
+ expected = DvDuration(u'PT0.0S', None, None, None, None, None, None)
+ self.assertEqual(expected.value, result.value) #modify __eq__?
+
+ def testOffsetMethodWithNoParent(self):
+ result = self.pointEventWithoutParent.offset()
+ self.assertEqual(None, result)
+
+class SomeStructure(object):
+ grok.implements(IItemStructure)
=== added file 'src/oship/openehr/rm/data_structures/history/tests/history.txt'
--- src/oship/openehr/rm/data_structures/history/tests/history.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/history/tests/history.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,244 @@
+:Test-Layer: functional
+
+
+The History Package
+===================
+
+This package defines the concept of past, linear time, which any kind of
+data with structural complexity can be stored. It supports both instantaneuos
+and interval event samples within periodic and aperiodic series.
+
+>>> from oship.openehr.rm.data_structures.history import Event, History
+>>> import grok
+
+Timing the data
+===============
+
+The package has two important classes : History and Event.
+The intention of the History class is to represent time-based data for which
+every sample in the series is a measurement of the same phenomenon
+(e.g. patient heartrate) and is obtained using the same measurement method
+(e.g. pulse oximeter). Samples taken in this way can be reliably treated as
+representing changes in a phenomenon over time, and accordingly can be
+safely used for time-based computation, such as graphing, statistical
+analysis and so on.
+
+An instance of the History class contains the **origin**: DvDateTime attribute,
+indicating what is considered the â0-pointâ of the time series, and a series
+of instances of the Event subtype, each containing a **time**: DvDateTime
+attribute representing the absolute time of the event.
+
+>>> from oship.openehr.rm.datatypes.quantity.datetime.interfaces import IDvDateTime
+>>> class ADateTime(object):
+... grok.implements(IDvDateTime)
+... def __init__(self, value):
+... self.value = value
+>>> origin_date = ADateTime(u"2010-05-20T16:29 +0000")
+>>> a_history = History(origin_date)
+... # doctest: +ELLIPSIS
+Traceback (most recent call last):
+TypeError: ...
+
+A History therefore constrains the type of the data at each Event (EVENT.item)
+to implement IItemList Interface and nothing else. The ``History`` class forces the
+type of the **item** attirbute in each Event to be the same. To make this
+work, a class have to be passed as a argument for the History class
+constructor.
+
+>>> class MyClass(object):
+... pass
+>>> History(origin_date, MyClass)
+... # doctest: +ELLIPSIS
+Traceback (most recent call last):
+NotAItemStructureError: ...
+
+
+One important point is the class have to implement the IItemStructure Interface.
+Firstly, let's define a Dummy class that implement IItemStructure to
+be responsible to store data during this example::
+
+>>> from oship.openehr.rm.data_structures.item_structure.interfaces import IItemStructure
+>>> class AStructure(object):
+... grok.implements(IItemStructure)
+>>> a_history = History(origin_date, AStructure)
+
+The events attribute contains a set of events related to the measurement. Acting as
+object container, it stores objects that implement IEvent Iterface. Is possible
+to see how is the interaction bewteem these concepts in
+`Defining a Event-History Relationship` section.
+
+Capturing samples with Events
+=============================
+
+The Event class is used to capture samples of data based on a kind of measurement
+(such as patient heartrate) over the time. The data was taken by the data Event
+attribute. The Event class represent this concept, but the Event
+class shouldn't have objects: It's a abstract class.
+
+>>> a_time = ADateTime(u"2010-05-26T15:12 +0000")
+>>> a_data = AStructure()
+>>> a_event = Event(a_time,a_data, None, None, None, None, None, None, None)
+
+The expected behavior above wasn't create a Event object : The Python Language
+don't allow create abstract classes, so it shouldn't be used. So, to express
+how a Event works, the class PointEvent will be used. It allows define a
+instananeous measurement on a specific point of time.
+
+>>> from oship.openehr.rm.data_structures.history import PointEvent
+>>> data = AStructure()
+>>> time = ADateTime(u'2010-05-25T14:04:52 +0000')
+>>> event_with_a_item = PointEvent(time, data, None, None, None, None, None, None, None)
+
+
+Defining the Event-History Relationship
+=======================================
+
+An History stores linear samples of data using the Event class.
+For each Event which describes the timing of the measurement, the History class
+forces the type of the data in each Event to be the same. So, History constrains
+the type of the data at each Event (EVENT.item) to be of type defined by the
+History measurement and nothing else.
+
+
+History class act as a Event Container, but stores the real events into the
+events attribute. Let's define a scenario when a weight is measured using
+a dummy structure called WeightStructure that stores the data.
+
+>>> origin_date = ADateTime(u"2010-05-25T18:31:34 +0000")
+>>> WeightStructure = AStructure
+>>> weight_measurement_series = History(origin_date, WeightStructure)
+>>> measurement_time = ADateTime(u"2010-05-25T18:32:34 +0000")
+>>> weight_measurement_data = WeightStructure()
+>>> wmd = weight_measurement_data
+>>> first_weight_measurement = PointEvent(measurement_time, wmd, None, None, None, None, None, None, None)
+
+An interesting fact is a history can store events using the zope container
+interface. To store a event into a history, a key is necessary to associate
+with it. The History container just act as a proxy to the events attribute container.
+
+>>> weight_measurement_series['1'] = first_weight_measurement
+>>> weight_measurement_series.events['1'] is first_weight_measurement
+True
+
+Now, let's verify what happens if a Event object with a diferent structure is included as
+the weight measurement ::
+
+>>> class OtherStructure(object):
+... grok.implements(IItemStructure)
+>>> wrong_weight_data = OtherStructure()
+>>> event_with_wrong_data = PointEvent(time, wrong_weight_data, None, None, None, None, None, None, None)
+>>> weight_measurement_series['2'] = event_with_wrong_data
+... # doctest: +ELLIPSIS
+Traceback (most recent call last):
+DiferentStructureError: ...
+
+The class History deny any Event object which has the item attribute not
+compatible with the structure declared on the History object initializer. If a
+event was set on the events attribute directly, this works well too::
+
+>>> weight_measurement_series.events["2"] = event_with_wrong_data
+... # doctest: +ELLIPSIS
+Traceback (most recent call last):
+DiferentStructureError: ...
+
+Anyway, the events attribute only stores object that implement IEvent
+interface::
+
+
+>>> class MyEvent(object):
+... data = WeightStructure()
+>>> weird_event = MyEvent()
+>>> weight_measurement_series["3"] = weird_event
+... # doctest: +ELLIPSIS
+Traceback (most recent call last):
+InvalidItemType: ...
+
+
+It's also possible provide a list of events to be added at the object
+initialization::
+
+>>> WeightStructure = AStructure
+>>> first_measurement_time = ADateTime(u"2010-05-25T18:32:34 +0000")
+>>> second_measurement_time = ADateTime(u"2010-05-25T18:35:34 +0000")
+>>> third_measurement_time = ADateTime(u"2010-05-25T18:40:34 +0000")
+>>> weight_measurement_data = WeightStructure()
+>>> wmd = weight_measurement_data
+>>> event_list = []
+>>> event_list.append(PointEvent(first_measurement_time, wmd, None, None, None, None, None, None, None))
+>>> event_list.append(PointEvent(second_measurement_time, wmd, None, None, None, None, None, None, None))
+>>> event_list.append(PointEvent(third_measurement_time, wmd, None, None, None, None, None, None, None))
+>>> second_weight_measurement = PointEvent(measurement_time, wmd, None, None, None, None, None, None, None)
+>>> third_weight_measurement = PointEvent(measurement_time, wmd, None, None, None, None, None, None, None)
+>>> myhistory = History(origin_date, WeightStructure, event_list)
+>>> myhistory["1"] # doctest: +ELLIPSIS
+<...PointEvent object at...>
+>>> myhistory["2"] # doctest: +ELLIPSIS
+<...PointEvent object at...>
+
+Let's remove the third event from the weight measurement included::
+
+>>> del myhistory["3"]
+
+Now we have only two items on it::
+
+>>> len(myhistory)
+2
+
+Just to remind: the history object act as a proxy container to the events
+attribute.::
+
+>>> len(myhistory) == len(myhistory.events)
+True
+
+The parent Event method
+=======================
+
+When a Event is added to a History object, it gains access to its parent
+History object. This is provided by the parent method of the Event class.
+When a Event is created, it don't have any parent. So, let's figure out how it
+works::
+
+>>> a_weight = WeightStructure()
+>>> now_time = ADateTime(u"")
+>>> a_alone_event = PointEvent(now_time, a_weight, None, None, None, None, None, None, None)
+>>> a_alone_event.parent() is None
+True
+
+Let's try add this event to a weight measurement history::
+
+>>> weight_measurement_series["4"] = a_alone_event
+
+
+>>> a_alone_event.parent() == weight_measurement_series
+True
+
+Now let's add it to events attribute directly and see what's happen::
+
+>>> other_alone_event = PointEvent(now_time,a_weight, None, None, None, None, None, None, None)
+>>> weight_measurement_series.events["5"] = other_alone_event
+>>> other_alone_event.parent() == weight_measurement_series
+True
+
+
+When a History is deleted and already there's a object reference to a event, the parent
+method points no history. A important fact is the history ONLY trigger the
+events reference removal if the history was added to a container::
+
+>>> getRootFolder()['weight-measurement'] = weight_measurement_series
+>>> del getRootFolder()['weight-measurement']
+>>> other_alone_event.parent() is None
+True
+>>> a_alone_event.parent() is None
+True
+>>> event_measurement_list = [a_alone_event, other_alone_event,]
+>>> eml = event_measurement_list
+>>> a_new_weight_measurement_series = History(origin_date, WeightStructure, eml)
+>>> a_alone_event.parent() == a_new_weight_measurement_series
+True
+>>> del a_new_weight_measurement_series
+>>> a_alone_event.parent() is None
+False
+>>> other_alone_event.parent() is not None
+True
+>>> other_alone_event.parent() # doctest : +ELIPSIS
+<...History object at...>
=== added file 'src/oship/openehr/rm/data_structures/interfaces.py'
--- src/oship/openehr/rm/data_structures/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface
+
+class IDataStructure(Interface):
+ u"""
+ Abstract parent class of all data structure types. Includes the
+ as_hierarchy function which can generate the equivalent CEN EN13606 single
+ hierarchy for each subtype's physical representation. For example, the
+ physical representation of an ITEM_LIST is List<ELEMENT>; its
+ implementation of as_hierarchy will generate a CLUSTER containing the set
+ of ELEMENT nodes from the list. """
+
+ def asHierarchy():
+ u"""Hierarchical equivalent of the physical representation of each
+ subtype, compatible with CEN EN 13606 structures. Returns a List."""
=== added directory 'src/oship/openehr/rm/data_structures/item_structure'
=== added file 'src/oship/openehr/rm/data_structures/item_structure/__init__.py'
--- src/oship/openehr/rm/data_structures/item_structure/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/item_structure/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import grok
+from interfaces import *
+from oship.openehr.rm.data_structures import DataStructure
+
+class ItemStructure(DataStructure):
+ u"""
+ Abstract parent class of all spatial data types.
+ """
+ grok.implements(IItemStructure)
+
+ def __init__(self, uid, atnodeid, name, atdetails, fdraudit, links, parent):
+ DataStructure.__init__(self, uid, atnodeid, name, atdetails,
+ fdraudit, links, parent)
+
+class ItemList(ItemStructure):
+ u"""
+ Logical list data structure, where each item has a value and can be
+ referred to by a name and a positional index in the list. The list may be
+ empty."""
+
+ grok.implements(IItemList)
+
+ def __init__(self, items, uid, atnodeid, name, atdetails, fdraudit, links, parent):
+ ItemStructure.__init__(self, uid, atnodeid, name, atdetails, fdraudit, links, parent)
+ self.item=items
+
+ def itemCount():
+ u"""Count of all items."""
+
+ def names():
+ u"""Return the names of all items."""
+
+ def namedItem(str):
+ u"""Return the named 'str'"""
+
+ def ithItem(n):
+ u"""Return the 'n' ith item."""
+
+ def asHierarchy():
+ u"""Generate a CEN EN13606-compatible hierarchy consisting of a single
+ CLUSTER containing the ELEMENTs of this list."""
+
+
+class ItemSingle(ItemStructure):
+ u"""
+ Logical single value data structure.
+ Used to represent any data which is logically a single value, such as a
+ person's height or weight. """
+
+ grok.implements(IItemSingle)
+
+ def __init__(self, item, uid, atnodeid, name, atdetails, fdraudit, links, parent):
+ ItemStructure.__init__(self, uid, atnodeid, name, atdetails, fdraudit, links, parent)
+ self.item=item
+
+ def asHierarchy():
+ u"""
+ Generate a CEN EN13606-compatible hierarchy consisting of a single
+ ELEMENT. """
+
+
+class ItemTable(ItemStructure):
+ u"""
+ Logical relational database style table data structure, in which
+ columns are named and ordered with respect to each other. Implemented
+ using Cluster-per-row encoding. Each row Cluster must have an identical
+ number of Elements, each of which in turn must have identical names and
+ value types in the corresponding postions in each row. Some columns may
+ be designated 'key' columns, containing key data for each row, in the
+ manner of relational tables. This allows row-naming, where each row
+ represents a body site, a blood antigen etc. All values in a column
+ have the same data type. Used to represent any data which is logically
+ a table of values, such as blood pressure, most protocols, many blood
+ tests etc. Not used for time-based data, which should be represented
+ with the temporal class HISTORY.. The table may be empty.
+ """
+
+ grok.implements(IItemTable)
+
+ def __init__(self, rows, uid, atnodeid, name, atdetails, fdraudit, links, parent):
+ ItemStructure.__init__(self, uid, atnodeid, name, atdetails, fdraudit, links, parent)
+ self.rows=rows
+
+ def rowCount():
+ u"""Return number of rows as an integer."""
+
+ def columnCount():
+ u"""Return the number of columns as an integer."""
+
+ def rowNames():
+ u"""Return the List of row names as DvText items."""
+
+ def columnNames():
+ u"""Return the List of column names as DvText items."""
+
+ def ithRow(n):
+ u"""Return the 'n' ith row as a Cluster."""
+
+ def hasRowWithName(a_key):
+ u"""Return True if a_key exists as a row name."""
+
+ def hasColumnWithName(a_key):
+ u"""Return True if a_key exists as a column name."""
+
+ def namedRow(a_key):
+ u"""Return the row whose first column has the name a_key."""
+
+ def hasRowWithKeys(keys):
+ u"""Return True if a row's first n columns contain the names of set of
+ keys."""
+
+ def rowWithKeys(keys):
+ u"""Return the row whose first n columns contain the names in the set
+ of keys."""
+
+ def elementAtCell(i, j):
+ u"""
+ NOTE: In the specs this is called elementAtCellij. I think it should be
+ changed. Return the element at the intersection of column i and row j.
+ i and j are integers. """
+
+ def elementAtNamedCell(row_key, col_key):
+ u"""Return the element at the intersection or col_key and row_key """
+
+ def asHierarchy():
+ u"""Generate a CEN EN13606-compatible hierarchy consisting of a single
+ CLUSTER containing the ELEMENTs of this list."""
+
+
+class ItemTree(ItemStructure):
+ u"""
+ Logical tree data structure. The tree may be empty. Used to represent data
+ which are logically a tree such as audiology results, microbiology results,
+ biochemistry results. """
+
+ grok.implements(IItemTree)
+
+ def __init__(self, uid, atnodeid, name, atdetails, fdraudit, links, items,
+ parent):
+ ItemStructure.__init__(self, uid, atnodeid, name, atdetails, fdraudit,
+ links, parent)
+ self.items = items
+
+ def hasElementPath(a_path):
+ u"""Return True if a_path is a valid leaf element path."""
+
+ def elementAtPath(a_path):
+ u"""Return the leaf element at the path, a_path."""
+
+ def asHierarchy():
+ u"""Generate a CEN EN13606-compatible hierarchy consisting of a single
+ CLUSTER containing the ELEMENTs of this list."""
+
+
=== added file 'src/oship/openehr/rm/data_structures/item_structure/interfaces.py'
--- src/oship/openehr/rm/data_structures/item_structure/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/item_structure/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,158 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from zope.i18nmessageid import MessageFactory
+from zope.schema import List, Object
+from zope.interface import Interface
+from oship.openehr.rm.datatypes.basic.interfaces import IDataValue
+from oship.openehr.rm.data_structures.item_structure.representation.interfaces import (
+ IElement,ICluster,IItem)
+
+
+_ = MessageFactory('oship')
+
+class IItemStructure(Interface):
+ u"""
+ Abstract parent class of all spatial data types.
+ """
+ pass
+
+
+class IItemList(Interface):
+ u"""
+ Logical list data structure, where each item has a value and can be
+ referred to by a name and a positional index in the list.
+ The list may be empty. """
+
+ items = List(
+ value_type=Object(schema=IElement),
+ title=_(u"items"),
+ description=_(u"""Physical representation of the list."""),
+ required=False)
+
+ def itemCount():
+ u"""Count of all items."""
+
+ def names():
+ u"""Return the names of all items."""
+
+ def namedItem(str):
+ u"""Return the named 'str'"""
+
+ def ithItem(n):
+ u"""Return the 'n' ith item."""
+
+ def asHierarchy():
+ u"Generate a CEN EN13606-compatible hierarchy consisting of a"
+ " single CLUSTER containing the ELEMENTs of this list."
+
+
+
+class IItemSingle(Interface):
+ u"""
+ Logical single value data structure.
+ Used to represent any data which is logically a single value, such as a
+ person's height or weight. """
+
+ item = Object(
+ schema=IElement,
+ title=_(u"item"),
+ description=_(u"""Single item."""),
+ required=True)
+
+ def asHierarchy():
+ u"""
+ Generate a CEN EN13606-compatible hierarchy consisting of a single
+ ELEMENT. """
+
+
+class IItemTable(Interface):
+ u"""
+ Logical relational database style table data structure, in which
+ columns are named and ordered with respect to each other. Implemented
+ using Cluster-per-row encoding. Each row Cluster must have an identical
+ number of Elements, each of which in turn must have identical names and
+ value types in the corresponding postions in each row. Some columns may
+ be designated 'key' columns, containing key data for each row, in the
+ manner of relational tables. This allows row-naming, where each row
+ represents a body site, a blood antigen etc. All values in a column
+ have the same data type. Used to represent any data which is logically
+ a table of values, such as blood pressure, most protocols, many blood
+ tests etc. Not used for time-based data, which should be represented
+ with the temporal class HISTORY.. The table may be empty.
+ """
+
+ rows = List(
+ value_type=Object(schema=ICluster),
+ title=_(u"rows"),
+ description=_(u"""Physical representation of the table as a list of
+ CLUSTERs, each containing the data of one row of the table."""),
+ required=False)
+
+ def rowCount():
+ u"""Return number of rows as an integer."""
+
+ def columnCount():
+ u"""Return the number of columns as an integer."""
+
+ def rowNames():
+ u"""Return the List of row names as DvText items."""
+
+ def columnNames():
+ u"""Return the List of column names as DvText items."""
+
+ def ithRow(n):
+ u"""Return the 'n' ith row as a Cluster."""
+
+ def hasRowWithName(a_key):
+ u"""Return True if a_key exists as a row name."""
+
+ def hasColumnWithName(a_key):
+ u"""Return True if a_key exists as a column name."""
+
+ def namedRow(a_key):
+ u"""Return the row whose first column has the name a_key."""
+
+ def hasRowWithKeys(keys):
+ u"""Return True if a row's first n columns contain the names of set of
+ keys."""
+
+ def rowWithKeys(keys):
+ u"""Return the row whose first n columns contain the names in the set
+ of keys."""
+
+ def elementAtCell(i, j):
+ u"""
+ NOTE: In the specs this is called elementAtCellij. I think it should be
+ changed. Return the element at the intersection of column i and row j.
+ i and j are integers. """
+
+ def elementAtNamedCell(row_key, col_key):
+ u"""Return the element at the intersection or col_key and row_key """
+
+ def asHierarchy():
+ u"""Generate a CEN EN13606-compatible hierarchy consisting of a single
+ CLUSTER containing the ELEMENTs of this list."""
+
+
+class IItemTree(Interface):
+ u"""
+ Logical tree data structure.
+ """
+
+ # the list contents should be restricted to schema = IItem,
+ items = List(
+ value_type=Object(schema=IItem),
+ title=_(u"items"),
+ description=_(u"Physical representation of the tree."),
+ required=False)
+
+ def hasElementPath(a_path):
+ u"""Return True if a_path is a valid leaf element path."""
+
+ def elementAtPath(a_path):
+ u"""Return the leaf element at the path; a_path."""
+
+ def asHierarchy():
+ u"""Generate a CEN EN13606-compatible hierarchy consisting of a single
+ CLUSTER containing the ELEMENTs of this list."""
=== added directory 'src/oship/openehr/rm/data_structures/item_structure/representation'
=== added file 'src/oship/openehr/rm/data_structures/item_structure/representation/__init__.py'
--- src/oship/openehr/rm/data_structures/item_structure/representation/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/item_structure/representation/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+import grok
+from oship.openehr.rm.common.archetyped import Locatable
+from interfaces import *
+
+class Item(Locatable):
+ u"""
+ The abstract parent of CLUSTER and ELEMENT representation classes.
+ """
+
+ grok.implements(IItem)
+
+ def __init__(self, uid, archetypeNodeId, name, archetypeDetails,
+ feederAudit, links, parent):
+ Locatable.__init__(self, uid, archetypeNodeId, name, archetypeDetails,
+ feederAudit, links)
+ self.uid = uid
+ self.archetypeNodeId = archetypeNodeId
+ self.name = name
+ self.archetypeDetails = archetypeDetails
+ self.feederAudit = feederAudit
+ self.links = links
+ self.parent = parent
+
+
+class Cluster(Item):
+ u"""
+ The grouping variant of ITEM, which may contain further instances of ITEM,
+ in an ordered list. """
+
+ grok.implements(ICluster)
+
+ def __init__(self, uid, archetypeNodeId, name, archetypeDetails,
+ feederAudit, links, items, parent):
+ Item.__init__(self,uid, archetypeNodeId, name, archetypeDetails,
+ feederAudit, links, parent)
+ self.items = items
+
+
+class Element(Item):
+ u"The leaf variant of ITEM, to which a DATA_VALUE instance is attached."
+
+ grok.implements(IElement)
+
+ def __init__(self, value, nullFlavour, atnodeid, uid, name, atdetails,
+ fdraudit, links, parent):
+ self.value=value
+ self.nullFlavour=nullFlavour
+ self.archetypeNodeId=atnodeid
+ self.uid=uid
+ self.name=name
+ self.archetypeDetails=atdetails
+ self.feederAudit=fdraudit
+ self.links=links
+ self.parent=parent
+
+
+ def __eq__(self, obj):
+ if self == obj: return True
+ return isinstance(obj, Element)
+
+ def __ne__(self, obj):
+ if not isinstance(obj, Element): return True
+ return not self == obj
+
+ def __hash__(self):
+ result = hash(self.uid) + hash(self.value) + hash(self.uid) +\
+ hash(self.name)
+ return result
+
+
+ def isNull():
+ u"""Return True if value is unknown, etc."""
+ return self.value is None
+
+ def nullFlavourValid(obj):
+ u"""If value is None then nullFlavour must be in the terminology code
+ set for null Flavours."""
=== added file 'src/oship/openehr/rm/data_structures/item_structure/representation/interfaces.py'
--- src/oship/openehr/rm/data_structures/item_structure/representation/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/item_structure/representation/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from zope.i18nmessageid import MessageFactory
+from zope.interface import Interface
+from zope.schema import Object,List
+
+from oship.openehr.rm.datatypes.basic.interfaces import IDataValue
+from oship.openehr.rm.support.interfaces import IObjectRef
+from oship.openehr.rm.datatypes.text.interfaces import IDvCodedText
+
+
+_ = MessageFactory('oship')
+
+class IItem(Interface):
+ u"""
+ The abstract parent of CLUSTER and ELEMENT representation classes.
+ """
+ pass
+
+
+class IElement(Interface):
+ u"The leaf variant of ITEM, to which a DATA_VALUE instance is attached."
+
+ value = Object(
+ schema=IDataValue,
+ title=_(u"value"),
+ description=_(u"""Data value of this leaf."""),
+ required=False)
+
+ nullFlavour = Object(
+ schema=IDvCodedText,
+ title=_(u"""nullFlavour"""),
+ description=_(u"Flavour of null value, e.g. 'indeterminate',"
+ " 'not asked', etc."),
+ required=False)
+
+ def isNull():
+ u"""Return True if value is unknown, etc."""
+
+ def nullFlavourValid(obj):
+ u"If value is None then nullFlavour must be in the terminology"
+ " code set for null Flavours."
+
+
+class ICluster(Interface):
+ u"""
+ The grouping variant of ITEM, which may contain further instances of ITEM,
+ in an ordered list. """
+
+ # the list contents should be restricted to schema = IItem,
+ items = List(
+ value_type=Object(schema=IItem),
+ title=_(u"items"),
+ description=_(u"Ordered list of items - CLUSTER or ELEMENT objects"
+ " - under this CLUSTER."),
+ required=True)
+
=== added directory 'src/oship/openehr/rm/data_structures/item_structure/representation/tests'
=== added file 'src/oship/openehr/rm/data_structures/item_structure/representation/tests/__init__.py'
=== added directory 'src/oship/openehr/rm/data_structures/tests'
=== added file 'src/oship/openehr/rm/data_structures/tests/datastructure.txt'
--- src/oship/openehr/rm/data_structures/tests/datastructure.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/data_structures/tests/datastructure.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,94 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.data_structures.item_structure.representation import Element
+>>> from oship.openehr.rm.data_structures import DataStructure
+>>> from oship.openehr.rm.data_structures.item_structure import *
+>>> from oship.openehr.rm.data_structures.item_structure.interfaces import *
+>>> from oship.openehr.rm.data_structures.history import IntervalEvent, PointEvent
+>>> from oship.openehr.rm.data_structures.item_structure.representation import (Item,
+... Cluster)
+>>> from oship.openehr.rm.data_structures.item_structure.representation.interfaces import IItem
+>>> from oship.openehr.rm.data_structures.history.interfaces import IIntervalEvent
+>>> from oship.openehr.rm.data_structures.interfaces import IDataStructure
+>>> from oship.openehr.rm.support.identification import TerminologyId, Uid
+>>> from oship.openehr.rm.datatypes.text import DvText, CodePhrase, TermMapping
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvDateTime, DvTime
+>>> from oship.openehr.rm.datatypes.quantity import DvAmount
+
+
+>>> tid1 = TerminologyId(u"SNOMED-CT(2003)")
+>>> tid2 = TerminologyId(u"ISO_639-1")
+>>> tid3 = TerminologyId(u"10646-1:1993")
+>>> tid4 = TerminologyId(u"ISO_8601")
+>>> cpm1 = CodePhrase(tid1, u"abc123")
+>>> tm1 = TermMapping(cpm1, u"=",None)
+>>> cplang1 = CodePhrase(tid2, u"en")
+>>> cpenc1 = CodePhrase(tid3, u"utf-8")
+>>> uri1 = DvUri(u"http://www.oship.org")
+>>> elementValue1 = DvText(u"abc123", [tm1,], u"font-family:Arial", uri1, cplang1, cpenc1)
+>>> element1 = Element(elementValue1, None, u"at0001", None, None, None, None, None, None)
+>>> txt1 = DvText(u"Some really interesting ReferenceRange.", [tm1,], u"font-family:Arial", uri1, cplang1, cpenc1)
+>>> archNodeId1 = CodePhrase(tid1, u"at0042")
+>>> uid1 = Uid(u"HL7v3_uid_data")
+>>> time1 = DvTime(u"T19:20:30", None, None, None, None, None)
+>>> time2 = DvDateTime(u"9999/01/01T19:20:30", None, None, None, None, None)
+>>> amount1 = DvAmount(None, None, None, None, None, None)
+>>> data1 = u"some data"
+>>> name1 = u"some name"
+
+>>> ds1 = DataStructure(uid1, archNodeId1, None, None, None, uri1, None)
+>>> ds1.uid.value
+u'HL7v3_uid_data'
+>>> ds1.archetypeNodeId.codeString
+u'at0042'
+>>> ds1.links.value
+u'http://www.oship.org'
+>>> IDataStructure.providedBy(ds1)
+True
+
+>>> item1 = ItemStructure(uid1, archNodeId1, name1, None, None, uri1, None)
+>>> item1.uid.value
+u'HL7v3_uid_data'
+>>> IItemStructure.providedBy(item1)
+True
+
+>>> ie1 = IntervalEvent(amount1, u"y = 3*x", None)
+>>> ie1.mathFunction
+u'y = 3*x'
+>>> IIntervalEvent.providedBy(ie1)
+True
+
+>>> point1 = PointEvent(time1, data1, None, None, None, None, None, None, None)
+>>> point1.data
+u'some data'
+
+>>> item2 = Item(uid1, archNodeId1, name1, None, None, uri1, None)
+>>> item2.name
+u'some name'
+>>> IItem.providedBy(item2)
+True
+
+>>> il1 = ItemList(uid1, archNodeId1, name1, None, None, uri1, None, [element1, element1])
+>>> IItemList.providedBy(il1)
+True
+
+>>> item3 = ItemSingle(uid1, archNodeId1, name1, None, None, uri1, None, element1)
+>>> IItemSingle.providedBy(item3)
+True
+
+>>> itable1 = ItemTable(uid1, archNodeId1, name1, None, None, uri1, None, [element1, element1])
+>>> IItemTable.providedBy(itable1)
+True
+
+>>> itree1 = ItemTree(None, u"at0066", None, None, None, None, [element1], None)
+>>> IItemTree.providedBy(itree1)
+True
+
+>>> cluster1 = Cluster(uid1, archNodeId1, name1, None, None, uri1, [element1, element1], None)
+>>> ICluster.providedBy(cluster1)
+True
+
+>>> element1 = Element(None, None, archNodeId1, uid1, name1, None, None, uri1, None)
+>>> IElement.providedBy(element1)
+True
=== added directory 'src/oship/openehr/rm/datatypes'
=== added file 'src/oship/openehr/rm/datatypes/__init__.py'
--- src/oship/openehr/rm/datatypes/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,1 @@
+#it's just a file to make this directory a module
=== added directory 'src/oship/openehr/rm/datatypes/basic'
=== added file 'src/oship/openehr/rm/datatypes/basic/__init__.py'
--- src/oship/openehr/rm/datatypes/basic/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/basic/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,91 @@
+# -*- coding: UTF-8 -*-
+
+import grok
+
+from interfaces import (IDataValue,IDvBoolean, IDvBoolean,
+ IDvState, IDvIdentifier)
+
+class DataValue(grok.Model):
+ u"""
+ Abstract class.
+ Serves as a common ancestor of all data value types in openEHR models.
+
+ In OSHIP we inherit from grok.Model instead of 'object' so that we
+ can more easily operate in the Grok environment.
+ """
+ grok.implements(IDataValue)
+
+
+class DvBoolean(DataValue):
+ """
+ Items which are truly boolean data, such as true/false answers.
+ For such data, it is important to devise the meanings (usually questions in subjec-
+ tive data) carefully, so that the only allowed results are in fact true or false.
+ The DV_BOOLEAN class should not be used as a replacement for naively modelled
+ enumerated types such as male/female etc. Such values should be coded, and in
+ any case the enumeration often has more than two values.
+ """
+
+ grok.implements(IDvBoolean)
+
+ def __init__(self, value):
+ if value == True or value == False:
+ self.value = value
+ else:
+ raise AttributeError("Invalid DvBoolean Value")
+
+
+class DvIdentifier(DataValue):
+ """
+ Type for representing identifiers of real-world entities. Typical identifiers include
+ drivers licence number, social security number, vertans affairs number, prescrip-
+ tion id, order id, and so on.
+ DV_IDENTIFIER is used to represent any identifier of a real thing, issued by
+ some authority or agency.
+ DV_IDENTIFIER is not used to express identifiers generated by the infrastruc-
+ ture to refer to information items; the types OBJECT_ID and OBJECT_REF and
+ subtypes are defined for this purpose.
+ """
+
+ grok.implements(IDvIdentifier)
+
+ def __init__(self, issuer, assignor, id_, type_):
+ if isinstance(issuer,basestring):
+ self.issuer = issuer
+ else:
+ raise AttributeError
+
+ if isinstance(assignor,basestring):
+ self.assignor = assignor
+ else:
+ raise AttributeError
+
+ if isinstance(id_,basestring):
+ self.id_ = id_
+ else:
+ raise AttributeError
+
+ if isinstance(type_,basestring):
+ self.type_ = type_
+ else:
+ raise AttributeError
+
+
+class DvState(DataValue):
+ """
+ For representing state values which obey a defined state machine, such as a vari-
+ able representing the states of an instruction or care process.
+ """
+
+ grok.implements(IDvState)
+
+ def __init__(self,value,isTerminal):
+ if isinstance(value,DvCodedText):
+ self.value=value
+ else:
+ raise AttributeError("DvState.value")
+
+ if isinstance(isTerminal,Bool):
+ self.isTerminal=isTerminal
+ else:
+ raise AttributeError("DvState.isTerminal")
=== added file 'src/oship/openehr/rm/datatypes/basic/interfaces.py'
--- src/oship/openehr/rm/datatypes/basic/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/basic/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,104 @@
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface, Attribute
+from zope.schema import Bool, Text, Object
+from zope.i18nmessageid.message import MessageFactory
+
+
+_ = MessageFactory('oship')
+
+class IDataValue(Interface):
+ """
+ Serves as a common ancestor of all data value types in openEHR
+ models. It should be noted that this is essentially what provides
+ the basis for programming language independence.
+ """
+ pass
+
+
+class IDvBoolean(Interface):
+ """
+ Items which are truly boolean data, such as true/false or yes/no answers.
+ The invariant defined in the spec for this class is that it is not void.
+ In Python a 'None' is defined as False.
+ """
+
+ value = Bool(
+ title = _(u"value"),
+ description = _(u"The boolean value of this item."),
+ required = True,
+ )
+
+
+class IDvIdentifier(Interface):
+ """
+ Type for representing identifiers of real-world entities. Typical identifiers include
+ drivers licence number, social security number, veterans affairs number, prescrip-
+ tion id, order id, and so on.
+
+ DV_IDENTIFIER is used to represent any identifier of a real thing, issued by
+ some authority or agency.
+
+ DV_IDENTIFIER is not used to express identifiers generated by the infrastruc-
+ ture to refer to information items; the types OBJECT_ID and OBJECT_REF and
+ subtypes are defined for this purpose.
+ """
+
+ issuer = Text(
+ title = _(u"Issuer"),
+ description = _(u"""Authority which issues the kind of id used in the id field
+ of this object."""),
+ required = True
+ )
+
+ assignor = Text(
+ title = _(u"Assignor"),
+ description = _(u"""Organisation that assigned the id to the item being identified."""),
+ required = True
+ )
+
+ id_ = Text(
+ title = _(u"Id"),
+ description = _(u""" The identifier value. Often structured, according to the
+ definition of the issuing authority's rules."""),
+ required = True
+ )
+
+ type_ = Text(
+ title = _(u"Type"),
+ description = _(u"""The identifier type, such as "prescription",or "SSN".
+ One day a controlled vocabulary might be possible for this."""),
+ required = True
+ )
+
+
+class IDvState(Interface):
+ """
+ For representing state values which obey a defined state machine, such as a vari-
+ able representing the states of an instruction or care process.
+
+ DV_STATE is expressed as a String but its values are driven by archetype-
+ defined state machines. This provides a powerful way of capturing stateful com-
+ plex processes in simple data.
+ """
+
+ value = Attribute(u"""The state name. State names are determined by a state/event
+ table defined in archetypes, and coded using openEHR Terminology
+ or local archetype terms, as specified by the archetype.
+
+ A module was added to the rm.support package to parse the State
+ values from the archetype in the current context. This function
+ is DvStateParser() and it may be called anywhere in the application
+ that the developer needs to know the current available states.
+ It returns a DvCodedText type.
+ """)
+
+
+ isTerminal = Bool(
+ title = _(u"isTerminal"),
+ description= _(u"""Indicates whether this state is a terminal
+ state, such as "aborted", "completed" etc
+ from which no further transitions are possible.
+ It is required and the default is False.
+ """)
+ )
=== added directory 'src/oship/openehr/rm/datatypes/basic/tests'
=== added file 'src/oship/openehr/rm/datatypes/basic/tests/__init__.py'
=== added file 'src/oship/openehr/rm/datatypes/basic/tests/dvboolean.txt'
--- src/oship/openehr/rm/datatypes/basic/tests/dvboolean.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/basic/tests/dvboolean.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,18 @@
+:Test-Layer: unit
+
+
+>>> from oship.openehr.rm.datatypes.basic import DvBoolean,IDvBoolean
+>>> from oship.openehr.rm.datatypes.basic.interfaces import IDvBoolean
+>>> b = DvBoolean(0)
+>>> print b.value
+0
+>>> b.value == True
+False
+>>> b.value == False
+True
+>>> IDvBoolean.providedBy(b)
+True
+>>> c = 1
+>>> IDvBoolean.providedBy(c)
+False
+>>>
=== added directory 'src/oship/openehr/rm/datatypes/encapsulated'
=== added file 'src/oship/openehr/rm/datatypes/encapsulated/__init__.py'
--- src/oship/openehr/rm/datatypes/encapsulated/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/encapsulated/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,98 @@
+
+from oship.openehr.rm.datatypes.basic import DataValue
+import grok
+from interfaces import *
+
+class DvEncapsulated(DataValue):
+ """Abstract class defining the common meta-data of all types of encapsulated data."""
+
+ grok.implements(IDvEncapsulated)
+
+ def __init__(self,size,charset,language):
+ self.charset=charset
+ self.language=language
+ if isinstance(size,int) and size >= 0:
+ self.size=size
+ else:
+ raise AttributeError("Invalid size attribute.")
+
+ def asString(self):
+ u"""
+ Result = alternate_text [(uri)]
+ Redefined in subclasses because it makes no sense here.
+ """
+ return u""
+
+
+class DvMultimedia(DvEncapsulated):
+ """
+ A specialisation of DvEncapsulated for audiovisual and biosignal types. Includes further
+ metadata relating to multimedia types which are not applicable to other subtypes of DvEncapsulated.
+ """
+
+ grok.implements(IDvMultimedia)
+
+ def __init__(self,altTxt,mType,compAlg,intChk,intChkAlg,tnail,uri,data,size,charset,language):
+ self.alternateText=altTxt
+ self.mediaType=mType
+ self.compressionAlgorithm = compAlg
+ self.integrityCheck=intChk
+ self.integrityCheckAlgorithm=intChkAlg
+ self.thumbnail=tnail
+ self.uri=uri
+ self.data=data
+ size=len(self.data)
+ self.size=size
+ DvEncapsulated.__init__(self,size,charset,language)
+
+ def isExternal(self):
+ u"""Computed from the value of the uri attribute: True if the data is stored externally
+ to the record, as indicated by 'uri'. A copy may also be stored internally, in which case
+ 'isExpanded' is also true. Ensure uri !=None and uri != '' """
+
+ return isinstance(self.uri,DvUri)
+
+ def isInline(self):
+ u"""
+ Computed from the value of the data attribute:
+ True if the data is stored in expanded
+ form, ie within the EHR itself. Ensure data is not None.
+ """
+ return self.data is not None and len(self.data) > 0
+
+ def isCompressed(self):
+ u"""Computed from the value of the compression_algorithm attribute: True if the data is
+ stored in compressed form. Ensure compressionAlgorithm is not None. """
+
+ return isinstance(self.compressionAlgorithm,CodePhrase)
+
+ def hasIntegrityCheck(self):
+ u"""Computed from the value of the integrityCheckAlgorithm attribute: True if an
+ integrity check has been computed. Ensure integrityCheckAlgorithm is not None."""
+
+ return isinstance(self.integrityCheckAlgorithm,CodePhrase)
+
+
+class DvParsable(DvEncapsulated):
+ u"""
+ Encapsulated data expressed as a parsable String. The internal model of the data item is not
+ described in the openEHR model in common with other encapsulated types, but in this case, the
+ form of the data is assumed to be plaintext, rather than compressed or other types of large binary data.
+ Used for representing values which are formal textual representations, e.g. guidelines.
+ """
+
+ grok.implements(IDvParsable)
+
+ def __init__(self,value,formalism,size,charset,language):
+ self.value=value
+ size=len(value)
+ self.size=size
+ self.formalism=formalism
+ DvEncapsulated.__init__(self,size,charset,language)
+
+ def asString(self):
+ u"""
+ Result = alternate_text [(uri)]
+ Redefined in subclasses
+ """
+ return self.value
=== added file 'src/oship/openehr/rm/datatypes/encapsulated/interfaces.py'
--- src/oship/openehr/rm/datatypes/encapsulated/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/encapsulated/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,145 @@
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface
+from zope.schema import Int, Object, TextLine, BytesLine, Field
+from zope.i18nmessageid.message import MessageFactory
+from oship.openehr.rm.datatypes.text.interfaces import ICodePhrase
+from oship.openehr.rm.datatypes.uri.interfaces import IDvUri
+
+_ = MessageFactory('oship')
+
+class IDvEncapsulated(Interface):
+ """Abstract class defining the common meta-data of all types of encapsulated data."""
+
+ size = Int(
+ title=_(u"Size"),
+ description=_(u"""Original size in bytes of unencoded encapsulated data. I.e. encodings
+ such as base64, hexadecimal etc do not change the value of this attribute."""),
+ required=False,
+ )
+
+ charset = Object(
+ schema=ICodePhrase,
+ title=_(u"charset"),
+ description=_(u"""Name of character encoding scheme in which this value is encoded.
+ Coded from openEHR Code Set "character sets". Unicode is the default assumption
+ in openEHR, with UTF-8 being the assumed encoding. This attribute allows for
+ variations from these assumptions. Type==CodePhrase"""),
+ required=False,
+ )
+
+ language = Object(
+ schema=ICodePhrase,
+ title=_(u"Language"),
+ description=_(u"""Optional indicator of the localised language in which the data
+ is written, if relevant. Coded from openEHR Code Set "languages". Type==CodePhrase"""),
+ required=False,
+ )
+
+ def asString():
+ """Result = alternate_text [(uri)]"""
+
+
+class IDvMultimedia(Interface):
+ """
+ A specialisation of DvEncapsulated for audiovisual and biosignal types. Includes further
+ metadata relating to multimedia types which are not applicable to other subtypes of DvEncapsulated.
+ """
+
+ alternateText = TextLine(
+ title=_(u"Alternate Text"),
+ description=_(u"""Text to display in lieu of multimedia display/replay"""),
+ required=False,
+ )
+
+ mediaType = Object(
+ schema=ICodePhrase,
+ title=_(u"Media Type"),
+ description=_(u"""Data media type coded from openEHR code set "media types"
+ (interface for the IANA MIME types code set)."""),
+
+ )
+
+ compressionAlgorithm = Object(
+ schema=ICodePhrase,
+ title=_(u"Compression Algorithm"),
+ description=_(u"""Compression type, a coded value from the openEHR "Integrity check"
+ code set. Void means no compression."""),
+ required=False,
+ )
+
+ integrityCheck = BytesLine(
+ title=_(u"Integrity Check"),
+ description=_(u"""Binary cryptographic integrity checksum. Type==Array<Octet>"""),
+ required=False,
+ )
+
+ integrityCheckAlgorithm = Object(
+ schema=ICodePhrase,
+ title=_(u"Integrity Check Algorithm"),
+ description=_(u"""Type of integrity check, a coded value from the openEHR "Integrity check" code set."""),
+ required=False,
+ )
+
+ thumbnail = Field(
+ title=_(u"Thumbnail"),
+ required=False
+ )
+
+ uri = Object(
+ schema=IDvUri,
+ title=_(u"URI"),
+ description=_(u"""URI reference to electronic information stored outside the record as a file,
+ database entry etc, if supplied as a reference. Type == DvUri."""),
+ required=False,
+ )
+
+ data = BytesLine(
+ title=_(u"Data"),
+ description=_(u"""The actual data found at uri, if supplied inline. Type==Array<Octet>"""),
+ required=False,
+ )
+
+ def isExternal(self):
+ u"""Computed from the value of the uri attribute: True if the data is stored externally
+ to the record, as indicated by 'uri'. A copy may also be stored internally, in which case
+ 'isExpanded' is also true. Ensure uri !=None and uri != '' """
+
+ def isInline(self):
+ u"""Computed from the value of the data attribute: True if the data is stored in expanded
+ form, ie within the EHR itself. Ensure data is not None. """
+
+ def isCompressed(self):
+ u"""Computed from the value of the compression_algorithm attribute: True if the data is
+ stored in compressed form. Ensure compressionAlgorithm is not None. """
+
+ def hasIntegrityCheck(self):
+ u"""Computed from the value of the integrityCheckAlgorithm attribute: True if an
+ integrity check has been computed. Ensure integrityCheckAlgorithm is not None."""
+
+class IDvParsable(Interface):
+ """
+ Encapsulated data expressed as a parsable String. The internal model of the data item is not
+ described in the openEHR model in common with other encapsulated types, but in this case, the
+ form of the data is assumed to be plaintext, rather than compressed or other types of large binary data.
+ Used for representing values which are formal textual representations, e.g. guidelines.
+ """
+
+ value = TextLine(
+ title=_(u"Value"),
+ description=_(u"""The string, which may validly be empty in some syntaxes"""),
+
+ )
+
+ formalism = TextLine(
+ title=_(u"Formalism"),
+ description=_(u"""The name of the formalism, e.g. "GLIF 1.0", "proforma" etc."""),
+
+ )
+
+ def asString():
+ u"""
+ Result = alternate_text [(uri)]
+ """
+
+
=== added directory 'src/oship/openehr/rm/datatypes/encapsulated/tests'
=== added file 'src/oship/openehr/rm/datatypes/encapsulated/tests/__init__.py'
=== added file 'src/oship/openehr/rm/datatypes/encapsulated/tests/dvmultimedia.txt'
--- src/oship/openehr/rm/datatypes/encapsulated/tests/dvmultimedia.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/encapsulated/tests/dvmultimedia.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,18 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.text import CodePhrase
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> from oship.openehr.rm.datatypes.encapsulated import DvMultimedia
+>>> from oship.openehr.rm.datatypes.encapsulated.interfaces import IDvEncapsulated
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> mt = CodePhrase(TerminologyId(u"media types"),u"text/plain")
+>>> mm = DvMultimedia(u"Alt. Text",mt,None,None,None,None,None,u"This is my data.",None,None,None)
+>>> isinstance(mm,DvMultimedia)
+True
+>>> print mm.data
+This is my data.
+>>> print mm.size
+16
+>>> IDvEncapsulated.providedBy(mm)
+True
+
=== added file 'src/oship/openehr/rm/datatypes/encapsulated/tests/dvparsable.txt'
--- src/oship/openehr/rm/datatypes/encapsulated/tests/dvparsable.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/encapsulated/tests/dvparsable.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,9 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.text import CodePhrase
+>>> from oship.openehr.rm.datatypes.encapsulated import DvParsable
+>>> par = DvParsable(u"Some Action",u"proForma",0,None,None)
+>>> isinstance(par,DvParsable)
+True
+>>> print par.value
+Some Action
=== added directory 'src/oship/openehr/rm/datatypes/quantity'
=== added file 'src/oship/openehr/rm/datatypes/quantity/__init__.py'
--- src/oship/openehr/rm/datatypes/quantity/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,461 @@
+# -*- coding: UTF-8 -*-
+
+from interfaces import *
+
+from oship.openehr.rm.datatypes.basic import DataValue
+from oship.openehr.rm.datatypes.text import DvCodedText, DvText
+from oship.openehr.rm.support import Interval
+import grok
+
+
+class DvOrdered(DataValue,Orderable):
+ """
+ Purpose:
+ Abstract class defining the concept of ordered values, which includes ordinals as
+ well as true quantities. It defines the functions '<' and is_strictly_comparable_to,
+ the latter of which must evaluate to True for instances being compared with the
+ '<' function, or used as limits in the DV_INTERVAL<T> class.
+
+ Use:
+ Data value types which are to be used as limits in the DV_INTERVAL<T> class
+ must inherit from this class, and implement the function
+ is_strictly_comparable_to to ensure that instances compare meaningfully. For
+ example, instances of DV_QUANTITY can only be compared if they measure the
+ same kind of physical quantity.
+ """
+
+ grok.implements(IDvOrdered)
+
+ def __init__(self,normalRange,otherReferenceRanges,normalStatus):
+ self.normalRange=normalRange
+ self.otherReferenceRanges=otherReferenceRanges
+ self.normalStatus=normalStatus
+
+
+ def isNormal(self):
+ """
+ Value is in the normal range, determined by comparison of the value to the normalRange
+ if present, or by the normalStatus marker if present.
+
+ isNormal: Boolean
+ require
+ normalRange /= Void or normalStatus /= Void
+ ensure
+ normalRange /= Void implies Result = normalRange.has(Current)
+ normalStatus /= Void implies normal_status.code_string.is_equal("N")
+ """
+
+ if self.normalStatus.codeString == "N":
+ return True
+ else:
+ return self.value in self.normalRange
+
+
+ def isSimple(self):
+ """
+ is_simple: Boolean
+ True if this quantity has no reference ranges.
+ """
+ if (self.normalRange is None or (self.normalRange is []) and (self.otherReferenceRanges is None or self.otherReferenceRanges is [])):
+ return True
+ else:
+ return False
+
+
+class DvOrdinal(DvOrdered):
+ u"""
+ Models rankings and scores, e.g. pain, Apgar values, etc, where there is a)
+ implied ordering, b) no implication that the distance between each value is con-
+ stant, and c) the total number of values is finite.
+
+ Used for recording any clinical datum which is customarily recorded using sym-
+ bolic values. Example: the results on a urinalysis strip, e.g. {neg, trace, +,
+ ++, +++} are used for leucocytes, protein, nitrites etc; for non-haemolysed
+ blood {neg, trace, moderate}; for haemolysed blood {neg, trace,
+ small, moderate, large}.
+ """
+
+ grok.implements(IDvOrdinal)
+
+ def __init__(self,value,symbol,normalRange,otherReferenceRanges,normalStatus):
+ self.value=value
+ if symbol is None or isinstance(symbol,DvCodedText) == False:
+ raise ValueError(_("Invalid DvOrdinal.symbol"))
+ else:
+ self.symbol=symbol
+ DvOrdered.__init__(self,normalRange,otherReferenceRanges,normalStatus)
+
+
+ def limits(self,refRange):
+ """
+ limits of the ordinal enumeration, to allow
+ comparison of an ordinal value to its limits.
+ Returns DvOrdinal.
+ """
+
+ return (refRange.range_.lower,refRange.range_.upper)
+
+
+
+ def isStrictlyComparableTo(self, other):
+ u"""
+ True if symbols come from same vocabulary,assuming the vocabulary is a
+ subset or value range, e.g. "urine:protein".
+
+ (other: like Current): Boolean
+ ensure symbol.is_comparable (other.symbol)
+ """
+
+ return self.symbol == other.symbol
+
+
+class DvQuantified(DvOrdered):
+ """
+ Abstract class defining the concept of true quantified values, i.e. values which are
+ not only ordered, but which have a precise magnitude.
+ """
+
+ grok.implements(IDvQuantified)
+
+ def __init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus):
+ self.magnitude=magnitude
+ self.accuracy=accuracy
+ self.magnitudeStatus = ['=','>','<','<=','>=','~']
+ DvOrdered.__init__(self,normalRange,otherReferenceRanges,normalStatus)
+
+ def validMagnitudeStatus(self,val):
+ """
+ Test whether a string 'val' is one of the valid values for the magnitude_status attribute.
+ """
+ if val in self.magnitudeStatus:
+ return val
+ else:
+ return '='
+
+ def magnitudeExists(self):
+ """
+ Does the magnitude exist?
+ """
+ return self.magnitude is not None
+
+
+
+class DvAbsoluteQuantity(DvQuantified):
+ """
+ Abstract class defining the concept of quantified entities whose values are abso-
+ lute with respect to an origin. Dates and Times are the main example.
+ """
+
+ grok.implements(IDvAbsoluteQuantity)
+
+
+ def __init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus):
+ self.accuracy = accuracy
+ DvQuantified.__init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus)
+
+
+ def accuracyUnknown(self):
+ """ True if accuracy is None """
+ return self.accuracy is None
+
+
+class DvAmount(DvQuantified):
+ u"""
+ Abstract class defining the concept of relative quantified 'amounts'. For relative
+ quantities, the '+' and '-' operators are defined (unlike descendants of
+ DV_ABSOLUTE_QUANTITY, such as the date/time types).
+ """
+
+ grok.implements(IDvAmount)
+
+ def __init__(self,accuracy,accuracyIsPercent,magnitude,normalRange,otherReferenceRanges,normalStatus):
+ if accuracy is None:
+ self.accuracy = -1
+ else:
+ self.accuracy = accuracy
+ self.accuracyIsPercent = accuracyIsPercent
+ DvQuantified.__init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus)
+
+ # constant
+ self.unknownAccuracyValue = -1.0
+
+ def validPercentage(val):
+ u"""
+ Test whether a number is a valid percentage,i.e. between 0 and 100.
+ ensure
+ Result implies val >= 0.0 and val <= 100.0
+ """
+
+ return val >= 0.0 and val <= 100.0
+
+ def accuracyUnknown(self):
+ """
+ Accuracy wasn't known or wasn't recorded.
+ """
+ if self.accuracy == -1:
+ return True
+ else:
+ return False
+
+
+class DvCount(DvAmount):
+ u"""
+ Purpose: Countable quantities
+
+ Used for countable types such as pregnancies and steps (taken by a physiotherapy
+ Use: patient), number of cigarettes smoked in a day.
+
+ Misuse: Not used for amounts of physical entities (which all have units)
+ """
+
+ grok.implements(IDvCount)
+
+ def __init__(self,accuracy,accuracyIsPercent,magnitude,magnitudeStatus,normalRange,otherReferenceRanges,normalStatus):
+ if isinstance(magnitude,int):
+ self.magnitude=magnitude
+ else:
+ raise TypeError("Incorrect magnitude attribute.")
+ DvAmount.__init__(self,accuracy,accuracyIsPercent,magnitude,normalRange,otherReferenceRanges,normalStatus)
+
+ def __add__(self, val):
+ if not isinstance(val,DvCount):
+ raise TypeError("Argument type must be DvCount")
+ else:
+ return DvCount(self.magnitude + val.magnitude, self.accuracy, self.accuracyIsPercent, self.magnitudeStatus, self.normalStatus, self.normalRange, self.otherReferenceRanges)
+
+
+ def __sub__(self, val):
+ if not isinstance(val,DvCount):
+ raise TypeError("Argument type must be DvCount")
+ else:
+ return DvCount(self.magnitude - val.magnitude, self.accuracy, self.accuracyIsPercent, self.magnitudeStatus, self.normalStatus, self.normalRange, self.otherReferenceRanges)
+
+ def negate(self):
+ return DvCount(-self.magnitude, self.accuracy, self.accuracyIsPercent, self.magnitudeStatus, self.normalStatus, self.normalRange, self.otherReferenceRanges)
+
+
+
+
+
+class DvInterval(DataValue,Interval):
+ """
+ Used to define intervals of dates, times, quantities (whose units match) and so on.
+ The type parameter, T, must be a descendant of the type DV_ORDERED, which is
+ necessary (but not sufficient) for instances to be compared (strictly_comparable
+ is also needed).
+ Without the DV_INTERVAL class, quite a few more DV_ classes would be needed
+ to express logical intervals, namely interval versions of all the date/time classes,
+ and of quantity classes. Further, it allows the semantics of intervals to be stated in
+ one place unequivocally, including the conditions for strict comparison.
+ The basic semantics are derived from the class INTERVAL<T>, described in the
+ support RM.
+
+ """
+
+ grok.implements(IDvInterval)
+
+ def __init__(self, lower, upper, lower_included, upper_included):
+ Interval.__init__(self, lower, upper, lower_included, upper_included)
+
+
+class ProportionKind(grok.Model):
+ """
+ Class of enumeration constants defining types of proportion for the
+ DV_PROPORTION class.
+ """
+ def __init__(self):
+ self.pkRatio = 0
+ self.pkUnitary = 1
+ self.pkPercent = 2
+ self.pkFraction = 3
+ self.pkIntegerFraction = 4
+
+ def validProportionKind(n):
+ """
+ True if n is one of the defined types.
+ """
+ return n in (pkRatio,pkUnitary,pkPercent,pkFraction,pkIntegerFraction)
+
+
+class DvProportion(DvAmount,ProportionKind):
+ """
+ Models a ratio of values, i.e. where the numerator and denominator are both pure
+ Purpose: numbers.
+
+ Used for recording titers (e.g. 1:128), concentration ratios, e.g. Na:K (unitary
+ Use: denominator), albumin:creatinine ratio, and percentages, e.g. red cell distirbution
+ width (RDW).
+
+ Should not be used to represent things like blood pressure which are often written
+ using a '/' character, giving the misleading impression that the item is a ratio,
+ MisUse: when in fact it is a structured value. E.g. visual acuity "6/24" is not a ratio.
+ Should not be used for formulations.
+ """
+
+ grok.implements(IDvProportion)
+
+ def __init__(self,numerator,denominator,type_,precision,accuracy,accuracyIsPercent,magnitude,normalRange,otherReferenceRanges,normalStatus):
+ if isinstance(numerator, float) or isinstance(numerator, int):
+ self.numerator = numerator
+ else:
+ raise AttributeError(_("Invalid numerator type."))
+
+ if isinstance(denominator, float) or isinstance(denominator,int):
+ self.denominator = denominator
+ else:
+ raise AttributeError(_("Invalid denominator type."))
+
+ if isinstance(type_, int):
+ self.type_ = type_
+ else:
+ raise AttributeError(_("Invalid type_ type."))
+
+ if precision is not None:
+ if isinstance(precision,int):
+ self.precision = precision
+ else:
+ raise AttributeError(_("Invalid precision type_."))
+
+ DvAmount.__init__(self,accuracy,accuracyIsPercent,magnitude,normalRange,otherReferenceRanges,normalStatus)
+
+
+ def isIntegral(self):
+ """
+ True if the numerator and denominator values are integers, i.e. if the precision is 0.
+ """
+ return isinstance(self.numerator,int) and isinstance(self.denominator,int)
+
+ def magnitude(self):
+ """
+ Effective magnitude represented by ratio.
+ Result = numerator / denominator
+ """
+ return self.numerator / self.denominator
+
+
+
+class DvProportion(DvAmount,ProportionKind):
+ """
+ Models a ratio of values, i.e. where the numerator and denominator are both pure
+ Purpose: numbers.
+
+ Used for recording titers (e.g. 1:128), concentration ratios, e.g. Na:K (unitary
+ Use: denominator), albumin:creatinine ratio, and percentages, e.g. red cell distirbution
+ width (RDW).
+
+ Should not be used to represent things like blood pressure which are often written
+ using a '/' character, giving the misleading impression that the item is a ratio,
+ MisUse: when in fact it is a structured value. E.g. visual acuity "6/24" is not a ratio.
+ Should not be used for formulations.
+ """
+
+ grok.implements(IDvProportion)
+
+ def __init__(self,numerator,denominator,type_,precision,accuracy,accuracyIsPercent,magnitude,normalRange,otherReferenceRanges,normalStatus):
+ if isinstance(numerator, float) or isinstance(numerator, int):
+ self.numerator = numerator
+ else:
+ raise AttributeError(_("Invalid numerator type."))
+
+ if isinstance(denominator, float) or isinstance(denominator,int):
+ self.denominator = denominator
+ else:
+ raise AttributeError(_("Invalid denominator type."))
+
+ if isinstance(type_, int):
+ self.type_ = type_
+ else:
+ raise AttributeError(_("Invalid type_ type."))
+
+ if precision is not None:
+ if isinstance(precision,int):
+ self.precision = precision
+ else:
+ raise AttributeError(_("Invalid precision type_."))
+
+ DvAmount.__init__(self,accuracy,accuracyIsPercent,magnitude,normalRange,otherReferenceRanges,normalStatus)
+
+
+ def isIntegral(self):
+ """
+ True if the numerator and denominator values are integers, i.e. if the precision is 0.
+ """
+ return isinstance(self.numerator,int) and isinstance(self.denominator,int)
+
+ def magnitude(self):
+ """
+ Effective magnitude represented by ratio.
+ Result = numerator / denominator
+ """
+ return self.numerator / self.denominator
+
+
+
+class DvQuantity(DvAmount):
+ """
+ Quantitified type representing "scientific" quantities, i.e. quantities expressed as a
+ magnitude and units.
+ Units were inspired by the Unified Code for Units of Measure (UCUM), devel-
+ oped by Gunther Schadow and Clement J. McDonald of The Regenstrief Institute.
+
+ Can also be used for time durations, where it is more convenient to treat these as
+ simply a number of seconds rather than days, months, years.
+ """
+
+ grok.implements(IDvQuantity)
+
+ def __init__(self,magnitude,units,precision,accuracy,accuracyIsPercent,normalRange,otherReferenceRanges,normalStatus):
+ self.magnitude=magnitude
+ self.units=units
+ if isinstance(precision,int) and precision >= -1:
+ self.precision=precision
+ else:
+ self.precision = None
+ DvAmount.__init__(self,accuracy,accuracyIsPercent,magnitude,normalRange,otherReferenceRanges,normalStatus)
+
+ def isIntegral(self):
+ """True if precision = 0; quantity represents an integral number."""
+ return self.precision == 0
+
+
+ def isStrictlyComparableTo(self,other):
+ """
+ Test if two instances are strictly comparable by ensuring that the measured
+ property is the same, achieved using the Measurement service function units_equivalent.
+ """
+ if(isinstance(other, self.__class__)):
+ return self.units==other.units and self.magnitude==other.magnitude
+
+
+class ReferenceRange(DvOrdered):
+ """
+ Defines a named range to be associated with any ORDERED datum. Each such
+ range is particular to the patient and context, e.g. sex, age, and any other factor
+ which affects ranges.
+ May be used to represent normal, therapeutic, dangerous, critical etc ranges.
+ ** NOTE ** the specs call for the attribute 'range' OSHIP redefines this as range_ in order to avoid
+ conflict with the Python builtin range.
+ """
+
+ grok.implements(IReferenceRange)
+
+ def __init__(self,meaning,range_,normalRange,otherReferenceRanges,normalStatus):
+
+ if isinstance(meaning,DvText):
+ self.meaning=meaning
+ else:
+ raise TypeError
+
+ if isinstance(range_,DvInterval):
+ self.range_=range_
+ else:
+ raise TypeError
+
+ DvOrdered.__init__(self,normalRange,otherReferenceRanges,normalStatus)
+
+ def isInRange(self,val):
+ """
+ Indicates if the value 'val' is inside the range
+ """
+ return self.range_.has(val)
+
=== added directory 'src/oship/openehr/rm/datatypes/quantity/datetime'
=== added file 'src/oship/openehr/rm/datatypes/quantity/datetime/__init__.py'
--- src/oship/openehr/rm/datatypes/quantity/datetime/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/datetime/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,180 @@
+# -*- coding: UTF-8 -*-
+
+
+import grok
+from mx.DateTime import DateTimeFrom, TimeFrom, DateFrom
+from oship.openehr.rm.datatypes.quantity import DvAbsoluteQuantity, DvAmount
+from interfaces import *
+
+class DvDuration(DvAmount):
+ u"""
+ Represents a period of time with respect to a notional point in time, which is not
+ specified. A sign may be used to indicate the duration is "backwards" in time
+ rather than forwards.
+
+ Note that a deviation from ISO8601 is supported in the openEHR specs, allowing the 'W' designator to
+ be mixed with other designators. See assumed types section in the Support IM. In OSHIP it
+ is believed that implementations should stay with calculating days and presenting them as weeks/days
+ in order to stay with the ISO 8601 specs.
+
+ Used for recording the duration of something in the real world, particularly when
+ there is a need a) to represent the duration in customary format, i.e. days, hours,
+ minutes etc, and b) if it will be used in computational operations with date/time
+ quantities, i.e. additions, subtractions etc.
+ """
+
+ grok.implements(IDvDuration)
+
+ def __init__(self,value,accuracy,accuracyIsPercent,magnitude,normalRange,otherReferenceRanges,normalStatus):
+ if isinstance(value,basestring) and value[0] == 'P':
+ self.value=value
+ else:
+ raise AttributeError("Invalid DvDuration.value")
+ if isinstance(magnitude,int) == False:
+ magnitude = 0.0
+
+ self.magnitude = magnitude
+ DvAmount.__init__(self,accuracy,accuracyIsPercent,magnitude,normalRange,otherReferenceRanges,normalStatus)
+
+ def magnitude(self):
+ """
+ Numeric value of the duration in seconds.
+ Result >= 0.0
+ This is incomplete. Need to parse the string and
+ calculate the magnitude of the duration in seconds.
+ """
+
+ return self.magnitude
+
+ def valueValid(self):
+ u"""
+ validIso8601Duration(value)
+ Just some very basic validation on the string at this
+ point to see if it 'looks' like a valid format.
+ """
+ if isinstance(self.value,basestring) and self.value[0] == 'P':
+ if self.value[2] in ("YyMmDdWwTHh-"):
+ return True
+ else:
+ return False
+
+class DvTemporal(DvAbsoluteQuantity):
+ """
+ Abstract class. Specialised temporal variant of DV_ABSOLUTE_QUANTITY whose diff type is
+ DV_DURATION.
+ """
+
+ grok.implements(IDvTemporal)
+
+ def __init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus):
+ self.magnitude = magnitude
+ DvAbsoluteQuantity.__init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus)
+
+ def diff(self,other):
+ """
+ Redefined to return a DvDuration
+ Incomplete method, but it's an abstract class.
+ """
+ return 0.0 #DvDuration(other,self.magnitude)
+
+
+
+
+class DvDate(DvTemporal):
+ """
+ Represents an absolute point in time, as measured on the Gregorian calendar, and
+ specified only to the day. Semantics defined by ISO 8601.
+ Used for recording dates in real world time. The partial form is used for
+ approximate birth dates, dates of death, etc.
+ """
+
+ grok.implements(IDvDate)
+
+ def __init__(self,value,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus):
+ self.value = value
+ dt1 = DateFrom(value)
+ dt2 = DateFrom(u'0000-01-01')
+ dtDiff = dt1 - dt2
+ magnitude = dtDiff.days
+
+ DvTemporal.__init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus)
+
+
+ def diff(self,other):
+ """
+ Difference of two dates. 'other' must be a DvDate. Returns a DvDuration.
+ """
+
+ diffdays = self.magnitude - other.magnitude
+
+ return DvDuration(u"P"+str(diffdays)+"D",None,None,diffdays,None,None,None)
+
+ def valueValid(self):
+ u"""validIso8601DateTime(value)"""
+
+ return DateTimeFrom(self.value) is not None
+
+
+
+class DvDateTime(DvTemporal):
+ u"""
+ Represents an absolute point in time, specified to the second. Semantics defined by ISO 8601.
+ Used for recording a precise point in real world time, and for approximate time
+ stamps, e.g. the origin of a HISTORY in an OBSERVATION which is only partially known.
+ """
+
+ grok.implements(IDvDateTime)
+
+ def __init__(self,value,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus):
+ self.value = value
+ dt1 = DateTimeFrom(value)
+ dt2 = DateTimeFrom(u'0000-01-01T00:00:00')
+ dtDiff = dt1 - dt2
+ magnitude = dtDiff.seconds
+
+ DvTemporal.__init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus)
+
+ def diff(self,other):
+ u"""Difference of two date/times. Returns a DvDuration"""
+ diffsecs = self.magnitude - other.magnitude
+
+ return DvDuration(u"PT"+str(diffsecs)+"S",None,None,diffsecs,None,None,None)
+
+
+ def valueValid(self):
+ u"""validIso8601DateTime(value)"""
+
+ return DateTimeFrom(self.value) is not None
+
+class DvTime(DvTemporal):
+ u"""
+ Represents an absolute point in time from an origin usually interpreted as meaning the start
+ of the current day, specified to the second. Semantics defined by ISO8601.
+
+ Used for recording real world times, rather than scientifically measured fine
+ amounts of time. The partial form is used for approximate times of events and
+ substance administrations.
+ """
+
+ grok.implements(IDvTime)
+
+ def __init__(self,value,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus):
+ self.value=value
+ dt1 = TimeFrom(value)
+ dt2 = TimeFrom(u'00:00:00')
+ dtDiff = dt1 - dt2
+ magnitude = dtDiff.seconds
+ DvTemporal.__init__(self,magnitude,accuracy,normalRange,otherReferenceRanges,normalStatus)
+
+ def diff(self,other):
+ u"""Difference of two times. Returns a DvDuration"""
+ diffsecs = self.magnitude - other.magnitude
+
+ return DvDuration(u"PT"+str(diffsecs)+"S",None,None,diffsecs,None,None,None)
+
+
+
+ def valueValid(self):
+ u"""validIso8601DateTime(value)"""
+
+ return DateTimeFrom(self.value) is not None
=== added file 'src/oship/openehr/rm/datatypes/quantity/datetime/interfaces.py'
--- src/oship/openehr/rm/datatypes/quantity/datetime/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/datetime/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,119 @@
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface, providedBy
+from zope.schema import (Text, Bool, TextLine, Int, Field,
+ BytesLine, Float, List, URI, Orderable, Choice, Object)
+from zope.i18nmessageid.message import MessageFactory
+
+from oship.openehr.rm.datatypes.text.interfaces import (IDvText, IDvCodedText,
+ ICodePhrase)
+
+from oship.openehr.rm.datatypes.quantity.interfaces import IDvAmount
+
+_ = MessageFactory('oship')
+
+
+class IDvDuration(IDvAmount):
+ """
+ Represents a period of time with respect to a notional point in time, which is not
+ specified. A sign may be used to indicate the duration is "backwards" in time
+ rather than forwards.
+
+ Note that a deviation from ISO8601 is supported, allowing the 'W' designator to
+ be mixed with other designators. See assumed types section in the Support IM.
+
+ Used for recording the duration of something in the real world, particularly when
+ there is a need a) to represent the duration in customary format, i.e. days, hours,
+ minutes etc, and b) if it will be used in computational operations with date/time
+ quantities, i.e. additions, subtractions etc.
+ """
+
+ value = TextLine(
+ title=_(u"Value"),
+ description=_(u"""ISO8601 duration"""),
+ required=True,
+ )
+
+ def magnitude():
+ """
+ Numeric value of the duration in seconds.
+ Result >= 0.0
+ """
+
+
+ def valueValid():
+ """validIso8601Duration(value)"""
+
+
+class IDvTemporal(Interface):
+ """
+ Specialised temporal variant of DV_ABSOLUTE_QUANTITY whose diff type is DvDuration.
+ """
+
+ pass
+
+class IDvDate(Interface):
+ """
+ Represents an absolute point in time, as measured on the Gregorian calendar, and
+ specified only to the day. Semantics defined by ISO 8601.
+ Used for recording dates in real world time. The partial form is used for
+ approximate birth dates, dates of death, etc.
+ """
+
+ value = TextLine(
+ title=_(u"Value"),
+ description=_(u"""ISO8601 date string"""),
+
+ )
+
+ def diff(other):
+ """Difference of two dates. Returns a DvDuration"""
+
+ def valueValid():
+ u"""validIso8601DateTime(value)"""
+
+class IDvDateTime(Interface):
+ """
+ Represents an absolute point in time, specified to the second. Semantics defined by ISO 8601.
+ Used for recording a precise point in real world time, and for approximate time
+ stamps, e.g. the origin of a HISTORY in an OBSERVATION which is only partially known.
+ """
+
+ value = TextLine(
+ title=_(u"Value"),
+ description=_(u"""ISO8601 date/time string"""),
+
+ )
+
+ def diff(other):
+ """Difference of two date/times. Returns a DvDuration"""
+
+
+
+ def valueValid():
+ """validIso8601DateTime(value)"""
+
+
+class IDvTime(Interface):
+ """
+ Represents an absolute point in time from an origin usually interpreted as meaning the start
+ of the current day, specified to the second. Semantics defined by ISO8601.
+
+ Used for recording real world times, rather than scientifically measured fine
+ amounts of time. The partial form is used for approximate times of events and
+ substance administrations.
+ """
+
+ value = TextLine(
+ title=_(u"Value"),
+ description=_(u"""ISO8601 time string"""),
+
+ )
+
+ def diff(other):
+ """Difference of two times. Returns a DvDuration"""
+
+
+ def valueValid():
+ """validIso8601Time(value)"""
+
=== added directory 'src/oship/openehr/rm/datatypes/quantity/datetime/tests'
=== added file 'src/oship/openehr/rm/datatypes/quantity/datetime/tests/__init__.py'
=== added file 'src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvdate.txt'
--- src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvdate.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvdate.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,16 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvDate, DvDuration
+>>> dt1 = DvDate(u"2009-09-09",0,None,None,None,None)
+>>> print dt1.magnitude
+734024.0
+>>> isinstance(dt1,DvDate)
+True
+>>> dt2 = DvDate(u"2009-09-19",0,None,None,None,None)
+>>> print dt2.magnitude
+734034.0
+>>> isinstance(dt2,DvDate)
+True
+>>> dur = dt1.diff(dt2)
+>>> isinstance(dur, DvDuration)
+True
=== added file 'src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvdatetime.txt'
--- src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvdatetime.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvdatetime.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,16 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvDateTime, DvDuration
+>>> dt1 = DvDateTime(u'2009-09-09T00:00:00',0,None,None,None,None)
+>>> print dt1.magnitude
+63419673600.0
+>>> isinstance(dt1,DvDateTime)
+True
+>>> dt2 = DvDateTime(u'2009-09-09 01:00:00',0,None,None,None,None)
+>>> print dt2.magnitude
+63419677200.0
+>>> isinstance(dt2,DvDateTime)
+True
+>>> dur = dt1.diff(dt2)
+>>> isinstance(dur, DvDuration)
+True
=== added file 'src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvduration.txt'
--- src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvduration.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvduration.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,14 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvDuration
+>>> from oship.openehr.rm.datatypes.quantity.datetime.interfaces import IDvDuration
+>>> dur = DvDuration("P1Y",None,None,None,None,None,None)
+>>> isinstance(dur,DvDuration)
+True
+>>> dur.value == "P1Y"
+True
+>>> dur.valueValid()
+True
+
+
+
=== added file 'src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvtime.txt'
--- src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvtime.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/datetime/tests/dvtime.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,16 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvTime, DvDuration
+>>> dt1 = DvTime(u'00:00:00',0,None,None,None,None)
+>>> print dt1.magnitude
+0.0
+>>> isinstance(dt1,DvTime)
+True
+>>> dt2 = DvTime(u'01:00:00',0,None,None,None,None)
+>>> print dt2.magnitude
+3600.0
+>>> isinstance(dt2,DvTime)
+True
+>>> dur = dt1.diff(dt2)
+>>> isinstance(dur, DvDuration)
+True
=== added file 'src/oship/openehr/rm/datatypes/quantity/interfaces.py'
--- src/oship/openehr/rm/datatypes/quantity/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,387 @@
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface
+from zope.schema import (Text, Bool, TextLine, Int, Field,
+ BytesLine, Float, List, URI, Orderable, Choice, Object)
+from zope.i18nmessageid.message import MessageFactory
+
+from oship.openehr.rm.datatypes.text.interfaces import (IDvText, IDvCodedText,
+ ICodePhrase)
+
+
+_ = MessageFactory('oship')
+
+
+class IDvInterval(Interface):
+ """
+ Used to define intervals of dates, times, quantities (whose units match) and so on.
+ The type parameter, T, must be a descendant of the type DV_ORDERED, which is
+ necessary (but not sufficient) for instances to be compared (strictly_comparable
+ is also needed).
+ Without the DV_INTERVAL class, quite a few more DV_ classes would be needed
+ to express logical intervals, namely interval versions of all the date/time classes,
+ and of quantity classes. Further, it allows the semantics of intervals to be stated in
+ one place unequivocally, including the conditions for strict comparison.
+ The basic semantics are derived from the class INTERVAL<T>, described in the
+ support RM.
+ """
+ pass
+
+class IReferenceRange(Interface):
+ """
+ Defines a named range to be associated with any ORDERED datum. Each such
+ range is particular to the patient and context, e.g. sex, age, and any other factor
+ which affects ranges.
+ May be used to represent normal, therapeutic, dangerous, critical etc ranges.
+ """
+
+ meaning=Object(
+ schema=IDvText,
+ title=_(u"meaning"),
+ description=_(u"""Term whose value indicates the meaning of this range, e.g. "normal", "critical", "therapeutic" etc."""),
+ required=True
+ )
+
+ range_=Object(
+ schema=IDvInterval,
+ title=_(u"range"),
+ description=_(u"""The data range for this meaning, e.g."critical" etc."""),
+ required=True
+ )
+
+ def isInRange(val):
+ """
+ Indicates if the value 'val' is inside the range.
+ """
+
+
+class IDvOrdered(Interface):
+ """
+ Purpose:
+ Abstract class defining the concept of ordered values, which includes ordinals as
+ well as true quantities. It defines the functions '<' and is_strictly_comparable_to,
+ the latter of which must evaluate to True for instances being compared with the
+ '<' function, or used as limits in the DV_INTERVAL<T> class.
+
+ Use:
+ Data value types which are to be used as limits in the DV_INTERVAL<T> class
+ must inherit from this class, and implement the function
+ is_strictly_comparable_to to ensure that instances compare meaningfully. For
+ example, instances of DV_QUANTITY can only be compared if they measure the
+ same kind of physical quantity.
+ """
+
+
+ normalRange = Object(
+ schema=IDvInterval,
+ title = _(u"normalRange"),
+ description = _(u"Optional normal range."),
+ required = False
+ )
+
+ otherReferenceRanges = List(
+ value_type=Object(schema=IReferenceRange),
+ title = _(u"otherReferenceRanges"),
+ description = _(u"""Optional tagged other reference ranges for this value in its particular measurement context. A list of ReferenceRange types."""),
+ required = False
+ )
+
+ normalStatus = Object(
+ schema=ICodePhrase,
+ title = _(u"normalStatus"),
+ description = _(u"""Optional normal status indicator of value with respect to normal range for this value. Often included by lab, even if the normal range itself is not included. Coded by ordinals in series HHH, HH, H, (nothing), L, LL, LLL; see openEHR terminology group "normal status"."""),
+ required = False
+ )
+
+
+ def isNormal():
+ """
+ Value is in the normal range, determined by comparison of the value to the normalRange if present, or by the normalStatus marker if present.
+ isNormal: Boolean
+ require
+ normalRange /= Void or normalStatus /= Void
+ ensure
+ normalRange /= Void implies Result = normalRange.has(Current)
+ normalStatus /= Void implies normal_status.code_string.is_equal("N")
+ """
+
+ def isSimple():
+ """
+ is_simple: Boolean
+ True if this quantity has no reference ranges.
+ """
+
+
+class IDvQuantified(Interface):
+ """
+ Abstract class defining the concept of true quantified values, i.e. values which are
+ not only ordered, but which have a precise magnitude.
+ """
+
+ magnitude = Float(
+ title=_(u"magnitude"),
+ description=_(u"""Numeric value of the quantity in canonical (i.e. single value)
+ form. Implemented as constant, function or attribute in subtypes as
+ appropriate. The type OrdereNumeric is mapped to the available
+ appropriate type in each implementation technology."""),
+ required=True
+ )
+
+ accuracy = Field(
+ title = _(u"accuracy"),
+ )
+
+ accuracyUnknown = Bool(
+ title = _(u"accuracyUnknown"),
+ )
+
+ magnitudeStatus = TextLine(
+ title=_(u"magnitudeStatus"),
+ description=_(u"""Optional status of magnitude with values:
+ = : magnitude is a point value
+ < : value is < magnitude
+ > : value is > magnitude
+ <= : value is <= magnitude
+ >= : value is >= magnitude
+ ~ : value is approximately magnitude
+ If not present, meaning is =. """),
+ required=False
+ )
+
+
+ def validMagnitudeStatus(val):
+ """
+ Test whether a string 'val' is one of the valid values for the magnitude_status attribute.
+ """
+
+ def magnitudeExists():
+ """
+ Does the magnitude exist?
+ """
+
+
+class IDvOrdinal(Interface):
+ """
+ Models rankings and scores, e.g. pain, Apgar values, etc, where there is a)
+ implied ordering, b) no implication that the distance between each value is con-
+ stant, and c) the total number of values is finite.
+
+ Used for recording any clinical datum which is customarily recorded using sym-
+ bolic values. Example: the results on a urinalysis strip, e.g. {neg, trace, +,
+ ++, +++} are used for leucocytes, protein, nitrites etc; for non-haemolysed
+ blood {neg, trace, moderate}; for haemolysed blood {neg, trace,
+ small, moderate, large}.
+ """
+
+ value = Int(
+ title=_(u"value"),
+ description=_(u""" Ordinal position in enumeration of values. """),
+ required=True
+ )
+
+ symbol = Object(
+ schema=IDvCodedText,
+ title=_(u"symbol"),
+ description=_(u"""Coded textual representation of this
+ value in the enumeration, which may be strings made from "+" symbols,
+ or other enumerations of terms such as "mild", "moderate", "severe",
+ or even the same number series as the values,
+ e.g. "1", "2", "3". Codes come from archetype."""),
+ required=True
+ )
+
+
+ def limits(ref_range):
+ """
+ limits of the ordinal enumeration, to allow
+ comparison of an ordinal value to its limits.
+ Returns DvOrdinal.
+ """
+
+ def isStrictlyComparableTo(other):
+ """
+ True if symbols come from same vocabulary,assuming the vocabulary is a
+ subset or value range, e.g. urine:protein.
+
+ (other: like Current): Boolean
+ ensure
+ symbol.is_comparable (other.symbol) implies Result
+ """
+
+
+class IDvAmount(Interface):
+ """
+ Abstract class defining the concept of relative quantified amounts. For relative
+ quantities, the + and - operators are defined (unlike descendants of
+ DV_ABSOLUTE_QUANTITY, such as the date/time types).
+ """
+
+ accuracy = Int(
+ title=_(u"accuracy"),
+ description=_(u"""Accuracy of measurement, expressed either as a half-range
+ percent value (accuracyIsPercent = True) or a half-range
+ quantity. A value of 0 means that accuracy was not recorded."""),
+ required=False
+ )
+
+
+ accuracyIsPercent = Bool(
+ title=_(u"accuracyIsPercent"),
+ description=_(u"""If True, indicates that when this object was created, accuracy was recorded
+ as a percent value; if False, as an absolute quantity value."""),
+ required=False
+ )
+
+
+ def validPercentage(val):
+ """
+ Test whether a number is a valid percentage,i.e. between 0 and 100.
+ ensure
+ Result implies val >= 0.0 and val <= 100.0
+ """
+
+
+class IDvAbsoluteQuantity(Interface):
+ """
+ Abstract class defining the concept of quantified entities whose values are absolute with respect to an origin. Dates and Times are the main example.
+ """
+
+ accuracy = Field(
+ title=_(u"Accuracy"),
+ description=_(u"""Accuracy of measurement, expressed as a half-range value of the diff type for this quantity (i.e. an accuracy of x means +/- x)."""),
+ default=None,
+ )
+
+
+ def accuracyUnknown():
+ """ True if accuracy is None """
+
+
+class IDvCount(Interface):
+ """
+ Purpose: Countable quantities
+
+ Used for countable types such as pregnancies and steps (taken by a physiotherapy
+ Use: patient), number of cigarettes smoked in a day.
+
+ Misuse: Not used for amounts of physical entities (which all have units)
+ """
+
+ magnitude = Int(
+ title=_(u"Magnitude"),
+ description=_(u"""numeric magnitude of the quantity"""),
+ required=True
+ )
+
+
+class IProportionKind(Interface):
+ """
+ Class of enumeration constants defining types of proportion for the
+ DV_PROPORTION class.
+ """
+
+
+ def validProportionKind(n):
+ """
+ True if n is one of the defined types.
+ """
+
+class IDvProportion(Interface):
+ """
+ Models a ratio of values, i.e. where the numerator and denominator are both pure
+ Purpose: numbers.
+
+ Used for recording titers (e.g. 1:128), concentration ratios, e.g. Na:K (unitary
+ Use: denominator), albumin:creatinine ratio, and percentages, e.g. red cell distirbution
+ width (RDW).
+
+ Should not be used to represent things like blood pressure which are often written
+ using a / character, giving the misleading impression that the item is a ratio,
+ MisUse: when in fact it is a structured value. E.g. visual acuity 6/24 is not a ratio.
+ Should not be used for formulations.
+ """
+
+
+ numerator = Float(
+ title=_(u"numerator"),
+ description=_(u"""numerator of ratio"""),
+ required=True
+ )
+
+ denominator = Float(
+ title=_(u"denominator"),
+ description=_(u"""denominator of ratio"""),
+ required=True
+ )
+
+ type_ = Int(
+ title=_(u"type"),
+ description=_(u"""Indicates semantic type of proportion, including percent, unitary etc."""),
+ required=True
+ )
+
+ precision = Int(
+ title=_(u"precision"),
+ description=_(u"""Precision to which the numerator and denominator values of the proportion
+ are expressed, in terms of number of decimal places. The value 0 implies an
+ integral quantity. The value -1 implies no limit, i.e.any number of decimal places."""),
+ required=False
+ )
+
+
+ def isIntegral():
+ """
+ True if the numerator and denominator values are integers, i.e. if the precision is 0.
+ """
+
+ def magnitude():
+ """
+ Effective magnitude represented by ratio.
+ Result = numerator / denominator
+ """
+
+
+class IDvQuantity(Interface):
+ """
+ Quantitified type representing scientific quantities, i.e. quantities expressed as a
+ magnitude and units.
+ Units were inspired by the Unified Code for Units of Measure (UCUM), devel-
+ oped by Gunther Schadow and Clement J. McDonald of The Regenstrief Institute.
+
+ Can also be used for time durations, where it is more convenient to treat these as
+ simply a number of seconds rather than days, months, years.
+ """
+
+ magnitude = Float(
+ title=_(u"Magnitude"),
+ description=_(u"""Numeric magnitude of the quantity."""),
+ required=True
+ )
+
+ units = TextLine(
+ title=_(u"Units"),
+ description=_(u"""Stringified units, expressed in UCUM unit syntax,
+ e.g. "kg/m2", "mm[Hg]", "ms-1", "km/h".Implemented accordingly in subtypes."""),
+
+ )
+
+
+ precision = Int(
+ title=_(u"Precision"),
+ description=_(u"""Precision to which the value of the quantity is expressed, in terms of
+ number of decimal places. The value 0 implies an integral quantity.
+ The value -1 implies no limit, i.e. any number of decimal places."""),
+ required=False,
+ )
+
+ def isIntegral():
+ """True if precision = 0; quantity represents an integral number."""
+
+
+ def isStrictlyComparableTo(other):
+ """Test if two instances are strictly comparable by ensuring that the measured
+ property is the same, achieved using the Measurement service function units_equivalent.
+
+ Return selfunits == other.units
+ """
+
=== added directory 'src/oship/openehr/rm/datatypes/quantity/tests'
=== added file 'src/oship/openehr/rm/datatypes/quantity/tests/__init__.py'
=== added file 'src/oship/openehr/rm/datatypes/quantity/tests/dvcount.txt'
--- src/oship/openehr/rm/datatypes/quantity/tests/dvcount.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/tests/dvcount.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,9 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.quantity import DvCount
+>>> from oship.openehr.rm.datatypes.quantity.interfaces import IDvCount
+>>> c = DvCount(None,None,9,None,None,None,None)
+>>> isinstance(c,DvCount)
+True
+>>>
+
=== added file 'src/oship/openehr/rm/datatypes/quantity/tests/dvordinal.txt'
--- src/oship/openehr/rm/datatypes/quantity/tests/dvordinal.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/tests/dvordinal.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,14 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.text import DvCodedText, CodePhrase
+>>> from oship.openehr.rm.datatypes.quantity import DvOrdinal
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> tid = TerminologyId(u"SNOMED-CT(2003)")
+>>> cp = CodePhrase(tid,u"abc123")
+>>> ct = DvCodedText(cp,u"abc123",[],u"",None,None,None)
+>>> isinstance(ct,DvCodedText)
+True
+>>> ord = DvOrdinal(1,ct,None,None,None)
+>>> isinstance(ord,DvOrdinal)
+True
+
=== added file 'src/oship/openehr/rm/datatypes/quantity/tests/dvproportion.txt'
--- src/oship/openehr/rm/datatypes/quantity/tests/dvproportion.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/tests/dvproportion.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,8 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.quantity import DvProportion
+>>> p = DvProportion(2,1,0,-1,None,None,None,None,None,None)
+>>> isinstance(p, DvProportion)
+True
+>>>
+
=== added file 'src/oship/openehr/rm/datatypes/quantity/tests/dvquantity.txt'
--- src/oship/openehr/rm/datatypes/quantity/tests/dvquantity.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/tests/dvquantity.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,8 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.quantity import DvQuantity
+>>> qty = DvQuantity(100.2,"km/h",-1,None,None,None,None,None)
+>>> isinstance(qty,DvQuantity)
+True
+>>>
+
=== added file 'src/oship/openehr/rm/datatypes/quantity/tests/referencerange.txt'
--- src/oship/openehr/rm/datatypes/quantity/tests/referencerange.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/quantity/tests/referencerange.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,23 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.text import DvText, CodePhrase, TermMapping
+>>> from oship.openehr.rm.datatypes.text.interfaces import IDvText
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> from oship.openehr.rm.datatypes.quantity import ReferenceRange, DvInterval
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> tid = TerminologyId(u"SNOMED-CT(2003)")
+>>> tid1 = TerminologyId(u"ISO_639-1")
+>>> tid2 = TerminologyId(u"10646-1:1993")
+>>> cpm = CodePhrase(tid,u"abc123")
+>>> tm = TermMapping(cpm,u"=",None)
+>>> cplang = CodePhrase(tid1,u"en")
+>>> cpenc = CodePhrase(tid2,u"utf-8")
+>>> uri = DvUri(u"http://www.mlhim.org")
+>>> txt = DvText(u"Some really interesting ReferenceRange.",[tm,],u"font-family:Arial",uri,cplang,cpenc)
+>>> isinstance(txt,DvText)
+True
+>>> intvl = DvInterval(0, 10, 1, 1)
+>>> rr = ReferenceRange(txt,intvl,None,None,None)
+>>> isinstance(rr,ReferenceRange)
+True
+
=== added directory 'src/oship/openehr/rm/datatypes/text'
=== added file 'src/oship/openehr/rm/datatypes/text/__init__.py'
--- src/oship/openehr/rm/datatypes/text/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/text/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,152 @@
+# -*- coding: UTF-8 -*-
+
+import grok
+from interfaces import *
+from oship.openehr.rm.datatypes.basic import DataValue
+
+class TermMapping(DataValue):
+ """
+ Represents a coded term mapped to a DV_TEXT, and the relative match of the tar-
+ get term with respect to the mapped item. Plain or coded text items may appear in
+ the EHR for which one or mappings in alternative terminologies are required.
+ Mappings are only used to enable computer processing, so they can only be
+ instances of DV_CODED_TEXT.
+
+ Used for adding classification terms (e.g. adding ICD classifiers to SNOMED
+ descriptive terms), or mapping into equivalents in other terminologies (e.g.
+ across nursing vocabularies).
+
+ """
+
+ grok.implements(ITermMapping)
+
+ def __init__(self,target,match,purpose):
+ self.target = target
+ self.purpose = purpose
+ if match in ['<','>','=','?']:
+ self.match = match
+ else:
+ raise AttributeError(_('Invalid match parameter'))
+
+
+ def narrower():
+ return self.match == '<'
+
+ def equivalent():
+ return self.match == '='
+
+ def broader():
+ return self.match == '>'
+
+ def unknown():
+ return self.match == '?'
+
+ def isValidMatchCode(match):
+ " I see no purpose in this method. twc"
+ return match in ['<','>','=','?']
+
+
+class DvParagraph(DataValue):
+ """
+ A logical composite text value consisting of a series of DV_TEXTs, i.e. plain text
+ (optionally coded) potentially with simple formatting, to form a larger tract of
+ prose, which may be interpreted for display purposes as a paragraph.
+ DV_PARAGRAPH is the standard way for constructing longer text items in summa-
+ ries, reports and so on.
+
+ """
+
+ grok.implements(IDvParagraph)
+
+ def __init__(self,items):
+ self.items=items
+
+
+
+class DvText(DataValue):
+ """
+ A text item, which may contain any amount of legal characters arranged as e.g.
+ words, sentences etc (i.e. one DV_TEXT may be more than one word). Visual for-
+ matting and hyperlinks may be included.
+ A DV_TEXT can be "coded" by adding mappings to it.
+ Fragments of text, whether coded or not are used on their own as values, or to
+ make up larger tracts of text which may be marked up in some way, eventually
+ going to make up paragraphs.
+
+ """
+
+ grok.implements(IDvText)
+
+ def __init__(self,value,mappings,formatting,hyperlink,language,encoding):
+ if value is not None and value != '':
+ self.value = value
+ else:
+ raise AttributeError("DvText.value")
+ self.mappings=mappings
+ self.formatting = formatting
+ self.hyperlink = hyperlink
+ self.language = language
+ self.encoding = encoding
+
+ def __eq__(self, obj):
+ if obj is self:
+ return True
+ if isinstance(obj, DvText):
+ return obj.value == self.value and obj.encoding == self.encoding and obj.language == self.language
+ return False
+
+ def __hash__(self):
+ result = 17
+ result += 31 * result + hash(self.value)
+ result += 31 * result + hash(self.encoding)
+ result += 31 * result + hash(self.language)
+ return result
+
+ def __str__(self):
+ return self.value
+
+
+class CodePhrase(grok.Model):
+ """
+ A fully coordinated (i.e. all "coordination" has been performed) term from a ter-
+ minology service (as distinct from a particular terminology).
+
+ """
+
+ grok.implements(ICodePhrase)
+
+ def __init__(self,terminologyId,codeString):
+ #if isinstance(terminologyId, TerminologyId) and isinstance(codeString,basestring):
+ self.terminologyId=terminologyId
+ self.codeString=codeString
+ #else:
+ # raise AttributeError("CodePhrase attributes")
+
+
+class DvCodedText(DvText):
+ """
+ A text item whose value must be the rubric from a controlled terminology, the
+ key (i.e. the 'code') of which is the defining_code attribute. In other words: a
+ DV_CODED_TEXT is a combination of a CODE_PHRASE (effectively a code) and
+ the rubric of that term, from a terminology service, in the language in which the
+ data was authored.
+
+ Since DV_CODED_TEXT is a subtype of DV_TEXT, it can be used in place of it,
+ effectively allowing the type DV_TEXT to mean "a text item, which may option-
+ ally be coded".
+
+ If the intention is to represent a term code attached in some way to a fragment of
+ plain text, DV_CODED_TEXT should not be used; instead use a DV_TEXT and a
+ TERM_MAPPING to a CODE_PHRASE.
+
+
+ """
+
+ grok.implements(IDvCodedText)
+
+ def __init__(self,definingCode,value,mappings,formatting,hyperlink,language,encoding):
+ if isinstance(definingCode,CodePhrase):
+ self.definingCode=definingCode
+ DvText.__init__(self,value,mappings,formatting,hyperlink,language,encoding)
+ else:
+ raise AttributeError("DvCodedText.definingCode")
=== added file 'src/oship/openehr/rm/datatypes/text/interfaces.py'
--- src/oship/openehr/rm/datatypes/text/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/text/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,178 @@
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface, providedBy, Attribute
+from zope.i18nmessageid.message import MessageFactory
+from zope.schema import Text, Bool, TextLine, Int, Field, \
+ BytesLine, Float, List, URI, Orderable, Choice, Object
+
+import grok
+
+
+_ = MessageFactory('oship')
+
+from oship.openehr.rm.support.identification.interfaces import ITerminologyId
+#from oship.openehr.rm.datatypes.uri.interfaces import IDvUri
+
+class ICodePhrase(Interface):
+ """
+ A fully coordinated (i.e. all "coordination" has been performed) term from a ter-
+ minology service (as distinct from a particular terminology).
+ """
+
+ terminologyId = Object(
+ schema = ITerminologyId,
+ title = _(u"TerminologyId"),
+ description = _(u"""Identifier of the distinct terminology from
+ which the code_string (or its elements) was extracted."""),
+ required = True,
+ )
+
+ codeString = TextLine(
+ title = _(u"CodeString"),
+ description = _(u"""The key used by the terminology service to
+ identify a concept or coordination of concepts.
+ This string is most likely parsable inside the ter-
+ minology service, but nothing can be assumed
+ about its syntax outside that context."""),
+ required = True
+ )
+
+class IDvCodedText(Interface):
+ """
+ A text item whose value must be the rubric from a controlled terminology, the
+ key (i.e. the 'code') of which is the defining_code attribute. In other words: a
+ DV_CODED_TEXT is a combination of a CODE_PHRASE (effectively a code) and
+ the rubric of that term, from a terminology service, in the language in which the
+ data was authored.
+
+ Since DV_CODED_TEXT is a subtype of DV_TEXT, it can be used in place of it,
+ effectively allowing the type DV_TEXT to mean "a text item, which may option-
+ ally be coded".
+
+ If the intention is to represent a term code attached in some way to a fragment of
+ plain text, DV_CODED_TEXT should not be used; instead use a DV_TEXT and a
+ TERM_MAPPING to a CODE_PHRASE.
+ """
+
+ definingCode = Object(
+ schema=ICodePhrase,
+ title = _(u"DefiningCode"),
+ description = _(u"""The term which the 'value' attribute is the defining_code:CODE_PHRASE textual rendition (i.e. rubric) of."""),
+ required = True
+ )
+
+class ITermMapping(Interface):
+ """
+ Represents a coded term mapped to a DV_TEXT, and the relative match of the tar-
+ get term with respect to the mapped item. Plain or coded text items may appear in
+ the EHR for which one or mappings in alternative terminologies are required.
+ Mappings are only used to enable computer processing, so they can only be
+ instances of DV_CODED_TEXT.
+
+ Used for adding classification terms (e.g. adding ICD classifiers to SNOMED
+ descriptive terms), or mapping into equivalents in other terminologies (e.g.
+ across nursing vocabularies).
+ """
+
+ target = Object(
+ schema=ICodePhrase,
+ title = _(u"Target"),
+ description = _(u"""The target term of the mapping as a CodePhrase."""),
+ required = True
+ )
+
+ match = TextLine(
+ title = _(u"Match"),
+ description = _(u"""The relative match of the target term with respect to the mapped text item. Result meanings:'>': the mapping is to a broader term e.g. orginal text = "arbovirus infection", target = "viral infection" '=': the mapping is to a (supposedly) equivalent to the original item '<': the mapping is to a narrower term. e.g. original text = "diabetes", mapping = "diabetes mellitus". '?': the kind of mapping is unknown. The first three values are taken from the ISO standards 2788 ("Guide to Establishment and development of monolingual thesauri") and 5964 ("Guide to Establishment and development of multilingual thesauri")."""),
+ required = True
+ )
+
+ purpose = Object(
+ schema=IDvCodedText,
+ title = _(u"Purpose"),
+ description = _(u"""Purpose of the mapping e.g. "automated data mining", "billing", "interoperability" """),
+ required=False
+ )
+
+ def narrower():
+ u"""The mapping is to a narrower term."""
+
+ def equivalent():
+ u"""The mapping is to an equivalent term."""
+
+ def broader():
+ u"""The mapping is to a broader term."""
+
+ def unknown():
+ u"""The kind of mapping is unknown."""
+
+ def isValidMatchCode():
+ u"""True if match valid."""
+
+
+class IDvText(Interface):
+ """
+ A text item, which may contain any amount of legal characters arranged as e.g.
+ words, sentences etc (i.e. one DV_TEXT may be more than one word). Visual for-
+ matting and hyperlinks may be included.
+ A DV_TEXT can be "coded" by adding mappings to it.
+ Fragments of text, whether coded or not are used on their own as values, or to
+ make up larger tracts of text which may be marked up in some way, eventually
+ going to make up paragraphs.
+ """
+
+ value = TextLine(
+ title = _(u"Value"),
+ description = _(u"""Displayable rendition of the item, regardless of its underlying structure. For DV_CODED_TEXT, this is the rubric of the complete term as provided by the terminology service. No carriage returns, line feeds, or other non-printing characters permitted."""),
+ required=True
+ )
+
+ mappings=List(
+ value_type=Object(schema=ITermMapping),
+ title = _(u"Mappings"),
+ description = _(u"""A list of MappingTerm,terms from other terminologies most closely matching this term, typically used where the originator (e.g. pathology lab) of information uses a local terminology but also supplies one or more equivalents from wellknown terminologies (e.g. LOINC). The list contents should be of the type TermMapping"""),
+ required = False,
+ )
+
+ formatting = Text(
+ title = _(u"Formatting"),
+ description = _(u"""A format string of the form "name:value; name:value...", e.g. "font-weight : bold; font-family : Arial; font-size : 12pt;". Values taken from W3C CSS2 properties lists "background" and "font"."""),
+ required = False
+ )
+
+ hyperlink = Attribute("""Optional link sitting behind a section of plain
+ text or coded term item as type DvUri.""")
+
+ language = Object(
+ schema = ICodePhrase,
+ title = _(u"Language"),
+ description = _(u"""Optional indicator of the localised language in which the value is written. Coded from openEHR Code Set "languages". Only used when either the text object is in a different language from the enclosing ENTRY, or else the text object is being used outside of an ENTRY or other enclosing structure which indicates the language."""),
+ required = False
+ )
+
+ encoding = Object(
+ schema = ICodePhrase,
+ title = _(u"Encoding"),
+ description = _(u"""Name of character encoding scheme in which this value is encoded. Coded from openEHR Code Set "character sets". Unicode is the default assumption in openEHR, with UTF-8 being the assumed encoding. This attribute allows for variations from these assumptions."""),
+ required = False
+ )
+
+class IDvParagraph(Interface):
+ """
+ A logical composite text value consisting of a series of DV_TEXTs, i.e. plain text
+ (optionally coded) potentially with simple formatting, to form a larger tract of
+ prose, which may be interpreted for display purposes as a paragraph.
+ DV_PARAGRAPH is the standard way for constructing longer text items in summa-
+ ries, reports and so on.
+ """
+
+ items = List(
+ value_type=Object(schema=IDvText),
+ title = _(u"Items"),
+ description = _(u"""Items making up the paragraph, each of which is a text item
+ (which may have its own formatting, and/or have hyperlinks).
+ The list contents are DvText"""),
+ required = True
+ )
+
+
=== added directory 'src/oship/openehr/rm/datatypes/text/tests'
=== added file 'src/oship/openehr/rm/datatypes/text/tests/__init__.py'
=== added file 'src/oship/openehr/rm/datatypes/text/tests/codephrase.txt'
--- src/oship/openehr/rm/datatypes/text/tests/codephrase.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/text/tests/codephrase.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,15 @@
+:Test-Layer: unit
+
+>>> import zope.schema
+>>> from oship.openehr.rm.datatypes.text import CodePhrase, ICodePhrase
+>>> from oship.openehr.rm.datatypes.text.interfaces import ICodePhrase
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> tid = TerminologyId(u"SNOMED-CT(2003)")
+>>> isinstance(tid,TerminologyId)
+True
+>>> cp = CodePhrase(tid,u"abc123")
+>>> ICodePhrase.providedBy(cp)
+True
+>>> isinstance(cp,CodePhrase)
+True
+>>>
=== added file 'src/oship/openehr/rm/datatypes/text/tests/dvcodedtext.txt'
--- src/oship/openehr/rm/datatypes/text/tests/dvcodedtext.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/text/tests/dvcodedtext.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,11 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.text import DvCodedText, CodePhrase
+>>> from oship.openehr.rm.datatypes.text.interfaces import IDvCodedText
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> tid = TerminologyId(u"SNOMED-CT(2003)")
+>>> cp = CodePhrase(tid,u"abc123")
+>>> ct = DvCodedText(cp,u"abc123",[],u"",None,None,None)
+>>> isinstance(ct,DvCodedText)
+True
+>>>
=== added file 'src/oship/openehr/rm/datatypes/text/tests/dvparagraph.txt'
--- src/oship/openehr/rm/datatypes/text/tests/dvparagraph.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/text/tests/dvparagraph.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,33 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.text import DvParagraph, DvText, CodePhrase, TermMapping
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> from oship.openehr.rm.datatypes.text.interfaces import IDvText
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> tid = TerminologyId(u"SNOMED-CT(2003)")
+>>> tid1 = TerminologyId(u"ISO_639-1")
+>>> tid2 = TerminologyId(u"10646-1:1993")
+>>> cpm = CodePhrase(tid,u"abc123")
+>>> tm = TermMapping(cpm,u"=",None)
+>>> cplang = CodePhrase(tid1,u"en")
+>>> cpenc = CodePhrase(tid2,u"utf-8")
+>>> uri = DvUri(u"http://www.mlhim.org")
+>>> txt1 = DvText(u"Some really interesting text line 1.",[tm,],u"font-family:Arial",uri,cplang,cpenc)
+>>> txt2 = DvText(u"Some really interesting text line 2.",[tm,],u"font-family:Arial",uri,cplang,cpenc)
+>>> txt3 = DvText(u"Some really interesting text line 3.",[tm,],u"font-family:Arial",uri,cplang,cpenc)
+>>> txt4 = DvText(u"Some really interesting text line 4.",[tm,],u"font-family:Arial",uri,cplang,cpenc)
+>>> par = DvParagraph([txt1,txt2,txt3,txt4])
+>>> isinstance(par,DvParagraph)
+True
+>>> len(par.items)
+4
+>>> for x in par.items:
+... print x.value
+Some really interesting text line 1.
+Some really interesting text line 2.
+Some really interesting text line 3.
+Some really interesting text line 4.
+
+
+
+
=== added file 'src/oship/openehr/rm/datatypes/text/tests/dvtext.txt'
--- src/oship/openehr/rm/datatypes/text/tests/dvtext.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/text/tests/dvtext.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,18 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.datatypes.text import DvText, CodePhrase, TermMapping
+>>> from oship.openehr.rm.datatypes.text.interfaces import IDvText
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> from oship.openehr.rm.support.identification import TerminologyId
+>>> tid = TerminologyId(u"SNOMED-CT(2003)")
+>>> tid1 = TerminologyId(u"ISO_639-1")
+>>> tid2 = TerminologyId(u"10646-1:1993")
+>>> cpm = CodePhrase(tid,u"abc123")
+>>> tm = TermMapping(cpm,u"=",None)
+>>> cplang = CodePhrase(tid1,u"en")
+>>> cpenc = CodePhrase(tid2,u"utf-8")
+>>> uri = DvUri(u"http://www.mlhim.org")
+>>> txt = DvText(u"Some really interesting text.",[tm,],u"font-family:Arial",uri,cplang,cpenc)
+>>> isinstance(txt,DvText)
+True
+>>>
=== added directory 'src/oship/openehr/rm/datatypes/time_specification'
=== added file 'src/oship/openehr/rm/datatypes/time_specification/__init__.py'
--- src/oship/openehr/rm/datatypes/time_specification/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/time_specification/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,96 @@
+# -*- coding: UTF-8 -*-
+
+from oship.openehr.rm.datatypes.basic import DataValue
+from interfaces import *
+
+import grok
+
+class DvTimeSpecification(DataValue):
+ u"""
+ This is an abstract class of which all timing specifications are specialisations.
+ Specifies points in time, possibly linked to the calendar, or a real world repeating
+ event, such as "breakfast".
+ """
+
+ grok.implements(IDvTimeSpecification)
+
+ def __init__(self,value):
+ if isinstance(value,DvParsable):
+ self.value=value
+ else:
+ raise AttributeError("Invalid DvTimeSpecification.value")
+
+ def calendarAlignment(self):
+ u"""Indicates what prototypical point in the calendar the specification is
+ aligned to, e.g. "5th of the month". Empty if not aligned. Extracted from
+ the 'value' attribute.
+ """
+
+ return u""
+
+ def eventAlignment(self):
+ u"""Indicates what real-world event the specification is aligned to if any.
+ Extracted from the 'value' attribute.
+ """
+
+ return u""
+
+ def institutionSpecified(self):
+ u"""Indicates if the specification is aligned with institution schedules,
+ e.g. a hospital nursing changeover or meal serving times. Extracted from
+ the 'value' attribute.
+ """
+ return u""
+
+
+class DvGeneralTimeSpecification(DvTimeSpecification):
+ u"""Specifies points in time in a general syntax. Based on the HL7v3 GTS data type."""
+
+ grok.implements(IDvGeneralTimeSpecification)
+
+ def __init__(self,value):
+ DvTimeSpecification.__init__(self,value)
+
+ def calendarAlignment(self):
+ u"""Calendar alignment extracted from value. """
+ return self.calendarAlignment
+
+ def eventAlignment(self):
+ u"""Event alignment extracted from value."""
+ return self.eventAlignment
+
+ def institutionSpecified(self):
+ u"""Extracted from value."""
+ return self.institutionSpecified
+
+
+class DvPeriodicTimeSpecification(DvTimeSpecification):
+ u"""
+ Specifies periodic points in time, linked to the calendar (phase-linked),
+ or a real world repeating event, such as "breakfast" (event-linked).
+ Based on the HL7v3 data types PIVL<T> and EIVL<T>.
+ Used in therapeutic prescriptions, expressed as INSTRUCTIONs in the openEHR model.
+ """
+
+ grok.implements(IDvPeriodicTimeSpecification)
+
+ def __init__(self,value):
+ DvTimeSpecification.__init__(self,value)
+
+ def period(self):
+ u"""The period of the repetition, computationally derived from the syntax
+ representation. Extracted from the 'value' attribute.
+ """
+ return self.value
+
+ def calendarAlignment(self):
+ u"""Calendar alignment extracted from value."""
+ return self.calendarAlignment
+
+ def eventAlignment(self):
+ u"""Event alignment extracted from value."""
+ return self.eventAlignment
+
+ def institutionSpecified(self):
+ u"""Extracted from value. """
+ return self.institutionSpecified
=== added file 'src/oship/openehr/rm/datatypes/time_specification/interfaces.py'
--- src/oship/openehr/rm/datatypes/time_specification/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/time_specification/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,71 @@
+
+from zope.interface import Interface, Attribute
+from zope.schema import Object
+
+class IDvTimeSpecification(Interface):
+ """
+ This is an abstract class of which all timing specifications are specialisations.
+ Specifies points in time, possibly linked to the calendar, or a real world repeating
+ event, such as "breakfast".
+ """
+
+ value = Attribute("""the specification, in the HL7v3 syntax for PIVL or EIVL types.
+ See section 8.2.2.1 Phase-linked Time Specification Syntax""")
+
+ def calendarAlignment():
+ """Indicates what prototypical point in the calendar the specification is
+ aligned to, e.g. "5th of the month". Empty if not aligned. Extracted from
+ the 'value' attribute.
+ """
+
+ def eventAlignment():
+ """Indicates what real-world event the specification is aligned to if any.
+ Extracted from the 'value' attribute.
+ """
+
+ def institutionSpecified():
+ """Indicates if the specification is aligned with institution schedules,
+ e.g. a hospital nursing changeover or meal serving times. Extracted from
+ the 'value' attribute.
+ """
+
+
+
+class IDvGeneralTimeSpecification(Interface):
+ """Specifies points in time in a general syntax. Based on the HL7v3 GTS data type."""
+
+ def calendarAlignment():
+ """Calendar alignment extracted from value. """
+
+ def eventAlignment():
+ """Event alignment extracted from value."""
+
+ def institutionSpecified():
+ """Extracted from value."""
+
+ def valueValid():
+ """value.formalism.is_equal("HL7:GTS")"""
+
+
+class IDvPeriodicTimeSpecification(Interface):
+ """
+ Specifies periodic points in time, linked to the calendar (phase-linked),
+ or a real world repeating event, such as "breakfast" (event-linked).
+ Based on the HL7v3 data types PIVL<T> and EIVL<T>.
+ Used in therapeutic prescriptions, expressed as INSTRUCTIONs in the openEHR model.
+ """
+
+ def period():
+ """The period of the repetition, computationally derived from the syntax
+ representation. Extracted from the 'value' attribute. Returns a DvDuration.
+ """
+
+ def calendarAlignment():
+ """Calendar alignment extracted from value."""
+
+
+ def eventAlignment():
+ u"""Event alignment extracted from value."""
+
+ def institutionSpecified():
+ """Extracted from value. """
=== added directory 'src/oship/openehr/rm/datatypes/time_specification/tests'
=== added file 'src/oship/openehr/rm/datatypes/time_specification/tests/__init__.py'
=== added directory 'src/oship/openehr/rm/datatypes/uri'
=== added file 'src/oship/openehr/rm/datatypes/uri/__init__.py'
--- src/oship/openehr/rm/datatypes/uri/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/uri/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,94 @@
+# -*- coding: UTF-8 -*-
+
+from oship.openehr.rm.datatypes.basic import DataValue
+from zope.schema import URI
+import grok
+
+from interfaces import IDvUri
+
+class DvUri(DataValue,URI):
+ """A reference to an object which conforms to the Universal Resource Identifier
+ (URI) standard, as defined by W3C RFC 2936. See "Universal Resource Identifiers in WWW"
+ by Tim Berners-Lee at http://www.ietf.org/rfc/rfc2396.txt. This is a World-Wide Web RFC
+ for global identification of resources. See http://www.w3.org/Addressing for a starting
+ point on URIs. See http://www.ietf.org/rfc/rfc2806.txt for new URI types like telephone,
+ fax and modem numbers.
+
+ Enables external resources to be referenced from within the content of the EHR. A number
+ of functions return the logical subparts of the URI string."""
+
+ grok.implements(IDvUri)
+
+ def __init__(self, value):
+ # check that it is a valid URI, else URI.validate will raise an error
+ _uri = URI()
+ _uri.fromUnicode(value)
+ self.value=value
+
+ def scheme(self):
+ """
+ A distributed information "space" in which information objects exist. The scheme
+ simultaneously specifies an information space and a mechanism for accessing objects
+ in that space. For example if scheme = "ftp", it identifies the information space in
+ which all ftpable objects exist, and also the application - ftp - which can be used
+ to access them. Values may include: "ftp", "telnet", "mailto", "gopher" and many others.
+ Refer to WWW URI RFC for a full list. New information spaces can be accommodated within
+ the URI specification.
+ """
+ colon = self.value.find(':')
+ return self.value[:colon]
+
+
+ def path(self):
+ u"""A string whose format is a function of the scheme. Identifies the location in
+ <scheme>-space of an information entity. Typical values include hierarchical directory
+ paths for any machine. For example, with scheme = "ftp", path might be /pub/images/image_01.
+ The strings "." and ".." are reserved for use in the path. Paths may include internet/intranet
+ location identifiers of the form: sub_domain...domain, e.g. "info.cern.ch" """
+
+ colon = self.value.find(':')
+ return self.value[colon+1:]
+
+ def fragmentId(self,fragstr):
+ u"""A part of, a fragment or a sub-function within an object. Allows references to sub-parts
+ of objects, such as a certain line and character position in a text object. The syntax and
+ semantics are defined by the application responsible for the object. """
+ if frastr in self.value:
+ return (self.value.find(fragstr),fragstr)
+ else:
+ return (None,u"Fragment not found in URI." + self.value)
+
+ def query(self, qstr):
+ u"""Query string to send to application implied by scheme and path Enables queries to
+ applications, including databases to be included in the URI Any query meaningful to the
+ server, including SQL."""
+ if qstr in self.value:
+ return (self.value.find(qstr),qstr)
+ else:
+ return (None,u"Query not found in URI." + self.value)
+
+
+class DvEhrUri(DvUri):
+ u"""
+ A DvEhrUri is a DvUri which has the scheme name ehr, and which can only reference
+ elements in EHRs. The syntax is described below.
+
+ Used to reference elements in an EHR, which may be the current one, or another.
+
+ The syntax of a DV_EHR_URI is an openEHR path, inside the ehr URI scheme-space, and is
+ of the form: ehr:// ehr_path
+ The syntax of ehr_path is described in the section on Paths in The openEHR Architecture Overview
+ document. DV_EHR_URIs are used as a mechanism for referencing in the EHR, ensuring readability by
+ humans, as well as validity when extracts are transmitted elsewhere: even if the target of a path
+ is not present, the path can be used to locate the missing item on demand.
+ """
+ def __init__(self, value):
+ # check that it is a valid URI, else URI.validate will raise an error
+ _uri = URI()
+ _uri.fromUnicode(value)
+ self.value=value
+
+ def schemeIsEhr(self):
+ u""" Ensure scheme == 'ehr' """
+ return self.scheme() == 'ehr'
+
=== added file 'src/oship/openehr/rm/datatypes/uri/interfaces.py'
--- src/oship/openehr/rm/datatypes/uri/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/uri/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,70 @@
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface
+from zope.schema import TextLine
+from zope.i18nmessageid.message import MessageFactory
+
+_ = MessageFactory('oship')
+
+class IDvUri(Interface):
+ """A reference to an object which conforms to the Universal Resource Identifier
+ (URI) standard, as defined by W3C RFC 2936. See "Universal Resource Identifiers in WWW"
+ by Tim Berners-Lee at http://www.ietf.org/rfc/rfc2396.txt. This is a World-Wide Web RFC
+ for global identification of resources. See http://www.w3.org/Addressing for a starting
+ point on URIs. See http://www.ietf.org/rfc/rfc2806.txt for new URI types like telephone,
+ fax and modem numbers.
+
+ Enables external resources to be referenced from within the content of the EHR. A number
+ of functions return the logical subparts of the URI string."""
+
+ value = TextLine(
+ title = _(u"Value"),
+ description = _(u"""The URI as a string."""),
+ )
+
+ def scheme():
+ """A distributed information "space" in which information objects exist. The scheme
+ simultaneously specifies an information space and a mechanism for accessing objects
+ in that space. For example if scheme = "ftp", it identifies the information space in
+ which all ftpable objects exist, and also the application - ftp - which can be used
+ to access them. Values may include: "ftp", "telnet", "mailto", "gopher" and many others.
+ Refer to WWW URI RFC for a full list. New information spaces can be accommodated within
+ the URI specification."""
+
+ def path():
+ """A string whose format is a function of the scheme. Identifies the location in
+ <scheme>-space of an information entity. Typical values include hierarchical directory
+ paths for any machine. For example, with scheme = "ftp", path might be /pub/images/image_01.
+ The strings "." and ".." are reserved for use in the path. Paths may include internet/intranet
+ location identifiers of the form: sub_domain...domain, e.g. "info.cern.ch" """
+
+ def fragmentId():
+ """A part of, a fragment or a sub-function within an object. Allows references to sub-parts
+ of objects, such as a certain line and character position in a text object. The syntax and
+ semantics are defined by the application responsible for the object. """
+
+
+ def query():
+ """Query string to send to application implied by scheme and path Enables queries to
+ applications, including databases to be included in the URI Any query meaningful to the
+ server, including SQL."""
+
+
+
+class IDvEhrUri(Interface):
+ """
+ A DvEhrUri is a DvUri which has the scheme name "ehr", and which can only reference
+ elements in EHRs. The syntax is described below.
+
+ Used to reference elements in an EHR, which may be the current one, or another.
+
+ The syntax of a DV_EHR_URI is an openEHR path, inside the "ehr" URI scheme-space, and is
+ of the form: "ehr://" ehr_path
+ The syntax of ehr_path is described in the section on Paths in The openEHR Architecture Overview
+ document. DV_EHR_URIs are used as a mechanism for referencing in the EHR, ensuring readability by
+ humans, as well as validity when extracts are transmitted elsewhere: even if the target of a path
+ is not present, the path can be used to locate the missing item on demand.
+ """
+
+ def schemeIsEhr():
+ """ Ensure scheme == 'ehr' """
=== added directory 'src/oship/openehr/rm/datatypes/uri/tests'
=== added file 'src/oship/openehr/rm/datatypes/uri/tests/__init__.py'
=== added file 'src/oship/openehr/rm/datatypes/uri/tests/dvehruri.txt'
--- src/oship/openehr/rm/datatypes/uri/tests/dvehruri.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/uri/tests/dvehruri.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,11 @@
+:Test-Layer: unit
+
+
+>>> from oship.openehr.rm.datatypes.uri import DvEhrUri
+>>> uri = DvEhrUri(u"ehr://www.oship.org")
+>>> uri.scheme()
+u'ehr'
+>>> uri.path()
+u'//www.oship.org'
+>>> uri.schemeIsEhr()
+True
=== added file 'src/oship/openehr/rm/datatypes/uri/tests/dvuri.txt'
--- src/oship/openehr/rm/datatypes/uri/tests/dvuri.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/datatypes/uri/tests/dvuri.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,10 @@
+:Test-Layer: unit
+
+
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> uri = DvUri(u"http://www.oship.org")
+>>> uri.scheme()
+u'http'
+>>> uri.path()
+u'//www.oship.org'
+
=== added directory 'src/oship/openehr/rm/ehr'
=== added file 'src/oship/openehr/rm/ehr/__init__.py'
--- src/oship/openehr/rm/ehr/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/ehr/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,147 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+# Copyright (c) 2007, Timothy W. Cook and Contributors. All rights reserved.
+# Redistribution and use are governed by the MPL license.
+#
+# Use and/or redistribution of this file assumes you have read and accepted the
+# terms of the license.
+##############################################################################
+
+u"""
+openEHR EHR Information Model package Rev. 5.1.0
+
+"""
+
+
+__author__ = 'Timothy Cook <timothywayne.cook@xxxxxxxxx>'
+__docformat__ = 'plaintext'
+__contributors__ = u'Renato Pesca <rpesca@xxxxxxxxx>', u'Wagner Francisco Mezaroba <wagnerfrancisco@xxxxxxxxx>'
+
+
+import grok
+
+
+from oship.openehr.rm.common.archetyped import Locatable
+from oship.openehr.rm.common.change_control import VersionedObject
+from interfaces import *
+
+
+
+class Ehr(grok.Container):
+ """
+ Root EHR container.
+ """
+
+ grok.implements(IEhr)
+
+ def __init__(self,systemId,ehrId,timeCreated,contributions,ehrAccess,ehrStatus,directory,compositions):
+ self.systemId=systemId
+ self.ehrId=ehrId
+ self.timeCreated=timeCreated
+ self.ehrStatus=ehrStatus
+ self.contributions=contributions
+ self.ehrAccess=ehrAccess
+ self.ehrStatus=ehrStatus
+ self.directory=directory
+ self.compositions=compositions
+
+
+class VersionedEhrAccess(VersionedObject):
+ """
+ Version container for EHR_ACCESS instance.
+ """
+
+ grok.implements(IVersionedEhrAccess)
+
+ def __init__(self,uid,ownerId,timeCreated):
+ VersionedObject.__init__(self,uid,ownerId,timeCreated)
+
+
+class EhrAccess(Locatable):
+
+ grok.implements(IEhrAccess)
+
+ def __init__(self, settings, uid, atnodeid, name, atdetails, fdraudit, links):
+ Locatable.__init__(self, uid, atnodeid, name, atdetails, fdraudit, links)
+ self.settings = settings
+
+ def scheme(self):
+ """The name of the access control scheme in use. Corresponds to the concrete instance of the settings attribute."""
+
+ def __eq__(self, obj):
+ if obj is self:
+ return True
+ if isinstance(obj, EhrAccess):
+ return obj.settings == self.settings
+ return False
+
+ def __ne__(self, obj):
+ return not self == obj
+
+ def __hash__(self):
+ return hash(self.settings)
+
+ def __repr__(self):
+ return 'settings: %s, %s' % (self.settings, super(EhrAccess, self).__repr__())
+
+
+class VersionedEhrStatus(VersionedObject):
+ """
+ Version container for EHR_STATUS instance.
+ """
+
+ grok.implements(IVersionedEhrStatus)
+
+ def __init__(self,uid,ownerId,timeCreated):
+ VersionedObject.__init__(self,uid,ownerId,timeCreated)
+
+
+class EhrStatus(Locatable):
+ """
+ Single object per EHR giving various EHR-wide information.
+ """
+
+ grok.implements(IEhrStatus)
+
+ def __init__(self,subject,isQueryable,isModifiable,otherDetails,uid,atnodeid,name,atdetails,fdraudit,links):
+ Locatable.__init__(self,uid,atnodeid,name,atdetails,fdraudit,links)
+ self.subject=subject
+ self.isQueryable=isQueryable
+ self.isModifiable=isModifiable
+ self.otherDetails=otherDetails
+
+ def __eq__(self, obj):
+ if obj is self:
+ return True
+ if isinstance(obj, EhrStatus):
+ return obj.subject == self.subject and obj.isQueryable == self.isQueryable and obj.isModifiable == self.isModifiable and obj.otherDetails == self.otherDetails
+ return False
+
+ def __ne__(self, obj):
+ return not self == obj
+
+ def __hash__(self):
+ result = 17
+ result = 31 * result + hash(self.isQueryable)
+ result = 31 * result + hash(self.isModifiable)
+ result = 31 * result + hash(self.subject)
+ result = 31 * result + hash(self.otherDetails)
+ return result
+
+ def __repr__(self):
+ return "subject: %s, isQueryable: %s, isModifiable: %s, otherDetails: %s, %s" % (self.subject, self.isQueryable, self.isModifiable, self.otherDetails, super(EhrStatus, self).__repr__())
+
+
+class VersionedComposition(VersionedObject):
+ """
+ Version-controlled composition abstraction.
+ """
+
+ grok.implements(IVersionedComposition)
+
+ def __init__(self,uid,ownerId,timeCreated):
+ VersionedObject.__init__(self,uid,ownerId,timeCreated)
+
+ def isPersistent():
+ """Indicates whether this composition set is persistent; derived from first version."""
+ pass
=== added file 'src/oship/openehr/rm/ehr/interfaces.py'
--- src/oship/openehr/rm/ehr/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/ehr/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,150 @@
+
+import grok
+
+from zope.interface import Interface
+from zope.schema import List, Object, Bool
+from zope.i18nmessageid import MessageFactory
+
+from oship.openehr.rm.support.interfaces import IUidBasedId,IObjectRef
+from oship.openehr.rm.datatypes.quantity.datetime.interfaces import IDvDateTime
+from oship.openehr.rm.data_structures.item_structure.interfaces import IItemStructure
+from oship.openehr.rm.common.generic.interfaces import IPartySelf
+from oship.openehr.security import IAccessControlSetting
+
+
+
+_ = MessageFactory('oship')
+
+
+
+class IEhr(Interface):
+ """
+ Root EHR container
+ """
+
+ systemId=Object(
+ schema=IUidBasedId,
+ title=_(u"System Id"),
+ description=_(u"Id of system where this EHR was created."),
+
+ )
+
+ ehrId=Object(
+ schema=IUidBasedId,
+ title=_(u"EHR ID"),
+ description=_(u"Id of this EHR."),
+
+ )
+
+ timeCreated=Object(
+ schema=IDvDateTime,
+ title=_(u"Created"),
+ description=_(u"Creation data/time"),
+
+ )
+
+ contributions=List(
+ title=_(u"Contributions"),
+ description=_(u"List of contributions causing changes to this EHR."),
+ value_type=Object(schema=IObjectRef),
+
+ )
+
+ ehrAccess=Object(
+ schema=IObjectRef,
+ title=_(u"EHR Access"),
+ description=_(u"A reference to the EHR Access object."),
+
+ )
+
+ ehrStatus=Object(
+ schema=IObjectRef,
+ title=_(u"EHR Status"),
+ description=_(u"A reference to the EHR Status object."),
+
+ )
+
+ directory=Object(
+ schema=IObjectRef,
+ title=_(u"Directory"),
+ description=_(u"Optional directory structure."),
+ required=False,
+ )
+
+ compositions=List(
+ title=_(u"Compositions"),
+ description=_(u"Master list of all compositions references."),
+ value_type=Object(schema=IObjectRef),
+
+ )
+
+
+
+class IVersionedEhrAccess(Interface):
+ """
+ Version container for EHR_ACCESS instance.
+ """
+
+
+
+class IEhrAccess(Interface):
+ """
+ EHR-wide access control object.
+ All access decisions to data in the EHR must be made in accordance with the policies and rules in this object.
+ """
+
+ settings = Object(
+ schema=IAccessControlSetting,
+ title=_(u"Settings"),
+ description=_(u"Access control settings for the EHR. Instance is a subtype of the AccessControlSetting."),
+ )
+
+ def scheme(self):
+ """The name of the access control scheme in use. Corresponds to the concrete instance of the settings attribute."""
+
+
+
+
+class IVersionedEhrStatus(Interface):
+ """
+ Version container for EHR_STATUS instance.
+ """
+
+
+class IEhrStatus(Interface):
+ """
+ Single object per EHR giving various EHR-wide information.
+ """
+
+ subject = Object (
+ schema=IPartySelf,
+ title=_(u"Subject"),
+ description=_(u"The subject of this EHR"),
+ required=True,
+ )
+
+ isQueryable = Bool (
+ title=_(u"Is queryable"),
+ description=_(u"True if this EHR should be included in population queries"),
+ )
+
+ isModifiable = Bool (
+ title=_(u"Is modifiable"),
+ description=_(u"True if this EHR is allowed to be written to."),
+ )
+
+ otherDetails = Object (
+ schema=IItemStructure,
+ title=_(u"Other details"),
+ description=_(u"Any other details of the EHR summary object, in the form of an archetyped Item_structure."),
+ )
+
+
+
+class IVersionedComposition(Interface):
+ """
+ Version-controlled composition abstraction.
+ """
+
+ def isPersistent():
+ """Indicates whether this composition set is persistent; derived from first version."""
=== added directory 'src/oship/openehr/rm/ehr/tests'
=== added file 'src/oship/openehr/rm/ehr/tests/__init__.py'
=== added file 'src/oship/openehr/rm/ehr/tests/ehraccess.txt'
--- src/oship/openehr/rm/ehr/tests/ehraccess.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/ehr/tests/ehraccess.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,32 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.ehr import EhrAccess
+>>> from oship.openehr.rm.ehr.interfaces import IEhrAccess
+>>> from oship.openehr.rm.datatypes.text import DvText
+>>> ehrAccessEntryName = DvText(u"EhrAccess", None, u"font-family:Arial", None, None, None)
+>>> ehrAccess = EhrAccess(u'an AccessControlSetting subclass', u'at0003', None, ehrAccessEntryName, None, None, None)
+>>> IEhrAccess.providedBy(ehrAccess)
+True
+>>> isinstance(ehrAccess,EhrAccess)
+True
+>>> ehrAccess2 = EhrAccess(u'an AccessControlSetting subclass', u'at0003', None, ehrAccessEntryName, None, None, None)
+>>> ehrAccess3 = EhrAccess(u'A different AccessControlSetting subclass', u'at0003', None, ehrAccessEntryName, None, None, None)
+>>> ehrAccess == ehrAccess2
+True
+>>> ehrAccess2 == ehrAccess
+True
+>>> ehrAccess != ehrAccess2
+False
+>>> ehrAccess2 != ehrAccess
+False
+>>> ehrAccess == ehrAccess3
+False
+>>> ehrAccess3 == ehrAccess
+False
+>>> ehrAccess != ehrAccess3
+True
+>>> ehrAccess3 != ehrAccess
+True
+>>> hash(ehrAccess) == hash(ehrAccess2)
+True
+>>>
=== added file 'src/oship/openehr/rm/ehr/tests/ehrstatus.txt'
--- src/oship/openehr/rm/ehr/tests/ehrstatus.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/ehr/tests/ehrstatus.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,46 @@
+:Test-Layer: unit
+
+>>> from oship.openehr.rm.ehr import EhrStatus
+>>> from oship.openehr.rm.ehr.interfaces import IEhrStatus
+>>> from oship.openehr.rm.common.generic import PartySelf
+>>> from oship.openehr.rm.datatypes.text import DvText
+>>> ehrStatusEntryName = DvText(u"EhrStatus", None, u"font-family:Arial", None, None, None)
+>>> otherDetails=None
+>>> subject=PartySelf(None)
+>>> ehrStatus = EhrStatus(subject,True,True,otherDetails,None,u'at0003',ehrStatusEntryName,None,None,None)
+>>> isinstance(ehrStatus.subject,PartySelf)
+True
+>>> ehrStatus.isQueryable
+True
+>>> ehrStatus.isModifiable
+True
+>>> ehrStatus.archetypeNodeId
+u'at0003'
+>>> ehrStatus.name.value
+u'EhrStatus'
+>>> IEhrStatus.providedBy(ehrStatus)
+True
+>>> isinstance(ehrStatus,EhrStatus)
+True
+
+>>> ehrStatus2 = EhrStatus(subject,True,True,otherDetails,None,u'at0003',ehrStatusEntryName,None,None,None)
+>>> ehrStatus3 = EhrStatus(subject,False,True,otherDetails,None,u'at0003',ehrStatusEntryName,None,None,None)
+>>> ehrStatus == ehrStatus2
+True
+>>> ehrStatus2 == ehrStatus
+True
+>>> ehrStatus != ehrStatus2
+False
+>>> ehrStatus2 != ehrStatus
+False
+>>> ehrStatus == ehrStatus3
+False
+>>> ehrStatus3 == ehrStatus
+False
+>>> ehrStatus != ehrStatus3
+True
+>>> ehrStatus3 != ehrStatus
+True
+>>> hash(ehrStatus) == hash(ehrStatus2)
+True
+>>>
=== added directory 'src/oship/openehr/rm/support'
=== added file 'src/oship/openehr/rm/support/__init__.py'
--- src/oship/openehr/rm/support/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/support/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,345 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+# Copyright (c) 2007, Timothy W. Cook and Contributors. All rights reserved.
+# Redistribution and use are governed by the MPL license.
+#
+# Use and/or redistribution of this file assumes you have read and accepted the
+# terms of the license.
+##############################################################################
+
+
+"""
+
+Support Information Model Rev.
+
+"""
+
+__author__ = u'Timothy Cook <timothywayne.cook@xxxxxxxxx>'
+__docformat__ = u'plaintext'
+__contributors__ = (u'Fabricio Ferracioli <fabricioferracioli@xxxxxxxxx>',
+ u'Sergio Miranda Freire <sergio@xxxxxxxxxxxxxxx>')
+
+
+import re
+from zope.interface import Interface
+from zope.schema import TextLine, Object
+from zope.i18nmessageid import MessageFactory
+
+import grok
+
+_ = MessageFactory('oship')
+
+class Smallest(object):
+ """Represents the smallest value
+
+ This type doesn't do much; it implements a pseudo-value that's smaller
+ than everything but itself.
+
+ >>> negInf = Smallest()
+ >>> smallest = Smallest()
+ >>> -264 < negInf
+ False
+ >>> -264 == negInf
+ False
+ >>> -264 > negInf
+ True
+ >>> negInf < negInf
+ False
+ >>> negInf == smallest
+ True
+ """
+
+ def __neg__(self):
+ """Returns the largest value
+
+ The opposite of negative infinity is infinity, the largest value.
+
+ >>> print -Smallest()
+ ~
+ """
+ return Largest()
+
+ def __cmp__(self, other):
+ """Compares this with another object
+
+ Always indicates that self is less than other, unless both are of
+ type Smallest, in which case they are equal.
+
+ >>> 0 < Smallest()
+ False
+ >>> -9999999 < Smallest()
+ False
+ >>> Smallest() < -9999999
+ True
+ >>> Smallest() < Smallest()
+ False
+ >>> Smallest() == Smallest()
+ True
+ """
+ if other.__class__ == self.__class__:
+ retval = 0
+ else:
+ retval = -1
+ return retval
+
+ def __str__(self):
+ """Returns a printable representation of this value
+
+ The string for the smallest number is -~, which means negative infinity.
+
+ >>> print Smallest()
+ -~
+ """
+ return "-~"
+
+ def __repr__(self):
+ """Returns an evaluable representation of the object
+
+ The representation of the smallest number is -Inf, which means
+ negative infinity.
+
+ >>> Smallest()
+ -Inf
+ """
+ return "-Inf"
+
+ def __hash__(self):
+ "Returns a value that can be used for generating hashes"
+ return 0x55555555
+
+
+class Largest(object):
+ """Class representing the universal largest value
+
+ This type doesn't do much; it implements a pseudo-value that's larger
+ than everything but itself.
+
+ >>> infinity = Largest()
+ >>> greatest = Largest()
+ >>> 6234 < infinity
+ True
+ >>> 6234 == infinity
+ False
+ >>> 6234 > infinity
+ False
+ >>> infinity > infinity
+ False
+ >>> infinity == greatest
+ True
+ """
+
+ def __neg__(self):
+ """Returns the smallest universal value
+
+ The opposite of infinity is negative infinity, the smallest value.
+
+ >>> print -Largest()
+ -~
+ """
+ return Smallest()
+
+ def __cmp__(self, other):
+ """Compares object with another object
+
+ Always indicates that self is greater than other, unless both are of
+ type Largest, in which case they are equal.
+
+ >>> 0 > Largest()
+ False
+ >>> Largest() < 9999999
+ False
+ >>> Largest() > 9999999
+ True
+ >>> Largest() < Largest()
+ False
+ >>> Largest() == Largest()
+ True
+ """
+ if other.__class__ == self.__class__:
+ retval = 0
+ else:
+ retval = 1
+ return retval
+
+ def __str__(self):
+ """Returns a string representation of the object
+
+ The largest number is displayed as ~ (it sort of looks like infinity...)
+
+ >>> print Largest()
+ ~
+ """
+ return "~"
+
+ def __repr__(self):
+ """Returns an evaluable expression representing this object
+
+ >>> Largest()
+ Inf
+ """
+ return "Inf"
+
+ def __hash__(self):
+ "Returns a value that can be used for generating hashes"
+ return -0x55555555
+
+
+class Interval(grok.Model):
+
+ def __init__(self, lower=Smallest(), upper=Largest(),
+ lower_included=False, upper_included=False, **kw):
+
+ """Initializes an interval
+
+ Parameters ========== - lower: The lower bound of an interval
+ (default Smallest()) - upper: The upper bound of an interval
+ (default Largest()) - lower_included: Boolean telling if the
+ lower value of interval are included (default True). -
+ upper_included: Boolean telling if the greater value of interval
+ are included (default True)
+
+ An Interval can represent an infinite set.
+
+ >>> r = Interval() # All values
+ >>> r.has(0)
+ True
+
+ An Interval can represent sets unbounded on an end.
+
+ >>> r = Interval(0,5)
+ >>> r.has(-1)
+ True
+ >>> r.has(3)
+ True
+ >>> r.has(5.1)
+ False
+
+ An Interval can represent a set of values up to, but not including a
+ value.
+
+ >>> r = Interval(25, 28, False)
+ >>> r.has(25)
+ False
+ >>> r.has(28)
+ True
+
+ An Interval can represent a set of values that have an inclusive
+ boundary.
+
+ >>> r = Interval(29, 216)
+
+ An Interval can represent a single value
+
+ >>> r = Interval(82, 82)
+ >>> r.has(82)
+ True
+
+ Intervals that are not normalized, gives an exception.
+
+ >>> r = Interval(4, 1)
+
+ Intervals can represent an empty set.
+
+ >>> r = Interval(5, 5, False, False)
+ """
+ if (lower is None or upper is None):
+ raise ValueError('lower and upper must not be None')
+
+ if (not isinstance(lower, Smallest) and not
+ isinstance(upper, Largest)):
+ if (type(lower) != type(upper)):
+ raise TypeError('lower and upper must be of the same type')
+ if (not callable(getattr(lower, '__cmp__'))
+ or not callable(getattr(upper, '__cmp__'))):
+ raise NotImplementedError('Classes are not comparable.'
+ ' Implement __cmp__ methods')
+
+ if (lower > upper):
+ raise ValueError('lower must be less than or equal to upper')
+
+ if (lower_included and isinstance(lower, Smallest)):
+ raise ValueError('lower_included implies lower greater than -Inf')
+
+ if(upper_included and isinstance(upper, Largest)):
+ raise ValueError('upper_included implies upper greater than Inf')
+
+ self.lower = lower
+ if (isinstance(lower, Smallest)):
+ self.lower_unbounded = True
+ else:
+ self.lower_unbounded = False
+ self.lower_included = lower_included
+
+ self.upper = upper
+ if (isinstance(upper, Largest)):
+ self.upper_unbounded = True
+ else:
+ self.upper_unbounded = False
+ self.upper_included = upper_included
+
+ def __hash__(self):
+ """
+ Returns a hashed value of the object
+ Intervals are to be considered immutable. Thus, a 32-bit hash can
+ be generated for them.
+ """
+ return hash((self.lower_unbounded, self.upper_unbounded, \
+ self.lower, self.upper))
+
+ def __repr__(self):
+ """
+ Returns an evaluable expression that can reproduce the object
+ """
+ return "Interval(lower=%s, upper=%s, lower_unbounded=%s, upper_unbounded=%s, \
+ lower_included=%s, upper_included=%s)" % (repr(self.lower), repr(self.upper), \
+ repr(self.lower_unbounded),repr(self.upper_unbounded), repr(self.lower_included), \
+ repr(self.upper_included))
+
+ def has(self, value):
+ """
+ Returns if a value is inside the interval
+ >>> interval = Interval(0,2)
+ >>> interval.has(4)
+ False
+ >>> interval.has(1.5)
+ True
+
+ """
+
+ if (value is None):
+ raise ValueError('value must not be None')
+
+ if (type(value) == type(self)):
+ raise TypeError('value must be of the same type as self')
+
+ #the value is between Smallest and Largest
+ if (isinstance(self.lower, Smallest) and isinstance(self.upper, Largest)):
+ return True
+ #Smallest is the value of self.lower and upper is finite,
+ #need to test the value of upper
+ elif (isinstance(self.lower, Smallest)):
+ if (value < self.upper):
+ return True
+ else:
+ #test for the upper closed interval
+ return self.upper_included and value == self.upper
+ #Largest is the value of self.upper and lower is finite,
+ #need to test the value of lower
+ elif (isinstance(self.upper, Largest)):
+ if (value > self.lower):
+ return True
+ else:
+ #test for the lower closed interval
+ return self.lower_included and value == self.lower
+ else:
+ #test for intervals that upper and lower values are finite
+ if (value > self.lower and value < self.upper):
+ return True
+ else:
+ #test for closed values
+ if (self.lower_included and value == self.lower):
+ return True
+ elif (self.upper_included and value == self.upper):
+ return True
+ else:
+ return False
=== added directory 'src/oship/openehr/rm/support/definition'
=== added file 'src/oship/openehr/rm/support/definition/__init__.py'
--- src/oship/openehr/rm/support/definition/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/support/definition/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+
+from interfaces import IBasicDefinitions, IOpenehrDefinitions
+
+import grok
+
+class BasicDefinitions(grok.Model):
+ """ Defines globally used constant values. """
+
+ grok.implements(IBasicDefinitions)
+
+ def __init__(self):
+ self.cr=u"\015"
+ self.lf=u"\012"
+
+class OpenehrDefinitions(BasicDefinitions):
+ """ Inheritance class to provide access to constants defined
+ in other packages."""
+
+ grok.implements(IOpenehrDefinitions)
=== added file 'src/oship/openehr/rm/support/definition/interfaces.py'
--- src/oship/openehr/rm/support/definition/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/support/definition/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,30 @@
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface
+from zope.schema import TextLine, Object
+from zope.i18nmessageid import MessageFactory
+
+_ = MessageFactory('oship')
+
+
+class IBasicDefinitions(Interface):
+ """ Defines globally used constant values. """
+
+ cr = TextLine(
+ title=_(u"CR"),
+ description=_(u"Carriage Return Character"),
+ readonly=True,
+ )
+
+ lf = TextLine(
+ title=_(u"LF"),
+ description=_(u"Line Feed Character"),
+ readonly=True,
+ )
+
+
+class IOpenehrDefinitions(Interface):
+ """ Inheritance class to provide access to constants defined
+ in other packages."""
+
+ pass
=== added directory 'src/oship/openehr/rm/support/definition/tests'
=== added file 'src/oship/openehr/rm/support/definition/tests/__init__.py'
=== added directory 'src/oship/openehr/rm/support/identification'
=== added file 'src/oship/openehr/rm/support/identification/__init__.py'
--- src/oship/openehr/rm/support/identification/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/support/identification/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,631 @@
+# -*- coding: utf-8 -*-
+
+import re
+import grok
+from persistent import Persistent
+
+from interfaces import *
+
+class InvalidUID(Exception):
+ pass
+
+class Uid(Persistent):
+
+ def __init__(self, value):
+ self.value = unicode(value)
+
+ def __eq__(self, other):
+ if not isinstance(other, self.__class__):
+ return False
+ return self.value == other.value
+
+
+class ISOOid(Uid):
+ u""" Model of ISO's Object Identifier (oid) as defined by the
+ standard ISO/IEC 8824 . Oids are formed from integers separated
+ by dots. Each non-leaf node in an Oid starting from the left
+ corresponds to an assigning authority, and identifies that
+ authority's namespace, inside which the remaining part of the
+ identifier is locally unique.
+ """
+
+ grok.implements(IUid)
+
+ def __init__(self, value):
+ # FIXME: Create a regular expression that matches a ISOOID
+ super(ISOOid,self).__init__(value)
+ numbers_parts = self.value.split(".")
+ for num in numbers_parts:
+ try:
+ int(num)
+ except ValueError,e:
+ raise InvalidUID("Invalid OID format.")
+
+
+class Uuid(Uid):
+ u""" Model of the DCE Universal Unique Identifier or UUID which
+ takes the form of hexadecimal integers separated by hyphens,
+ following the pattern 8-4-4-4-12 as defined by the Open Group, CDE
+ 1.1 Remote Procedure Call specification, Appendix A. Also known as
+ a GUID.
+ """
+
+ grok.implements(IUid)
+
+ def __init__(self, value):
+ if not re.match('\A([0-9a-fA-F]){8}'\
+ '-([0-9a-fA-F]){4}'\
+ '-([0-9a-fA-F]){4}'\
+ '-([0-9a-fA-F]){4}'\
+ '-([0-9a-fA-F]){12}\Z', value):
+ raise InvalidUID("Invalid UUID format.")
+ super(Uuid,self).__init__(value)
+
+
+class InternetId(Uid):
+ u""" Model of a reverse internet domain, as used to uniquely
+ identify an internet domain. In the form of a dot-separated string
+ in the reverse order of a domain name specified by IETF RFC1034
+ (http://www.ietf.org/rfc/rfc1034.txt).
+ """
+
+ grok.implements(IUid)
+
+ def __init__(self, value):
+# Regular Expression according to description found
+# in openEHR support module specification.
+ ietf_bnf_grammar= re.compile('\A[a-zA-Z]'\
+ '([a-zA-Z0-9-]*'\
+ '[a-zA-Z0-9])?'\
+ '(\.[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9]))+\Z')
+ if not ietf_bnf_grammar.match(value):
+ raise InvalidUID("Invalid Internet Domain.")
+ super(InternetId,self).__init__(value)
+
+
+class ObjectId(grok.Model):
+ u""" Ancestor (abstract) class of identifiers of informational
+ objects. Ids may be completely meaningless, in which case their
+ only job is to refer to something, or may carry some information
+ to do with the identified object. Object ids are used inside an
+ object to identify that object. To identify another object in
+ another service, use an OBJECT_REF, or else use a UID for local
+ objects identified by UID. If none of the subtypes is suitable,
+ direct instances of this class may be used. """
+
+ grok.implements(IObjectId)
+
+ def __init__(self, value):
+ self.value = unicode(value)
+
+ def __eq__(self, obj):
+ if obj is self:
+ return True
+ if isinstance(obj, ObjectId):
+ return obj.value == self.value
+ return False
+
+ def __hash__(self):
+ return hash(self.value)
+
+
+class UIDMatcher(object):
+
+ def __init__(self, value):
+ uid_factories = self.getUIDFactories()
+ self.uid_obj = None
+ for factory in uid_factories:
+ try:
+ self.uid_obj = factory(value)
+ except InvalidUID,e:
+ continue
+ if self.uid_obj: break
+ if self.uid_obj is None:
+ raise InvalidUID("There isn't a UID that match.")
+
+ def getUIDFactories(self):
+ return [Uuid, ISOOid, InternetId]
+
+ def createMatchedUid(self):
+ return self.uid_obj
+
+
+SEPARATOR = u"::"
+
+class UidBasedId(ObjectId):
+
+ grok.implements(IUidBasedId)
+
+ def __init__(self, uid, extension=None):
+ value = unicode("")
+ if IUid.providedBy(uid):
+ self._uid = uid
+ value = SEPARATOR.join([uid.value , extension])
+ else:
+ matcher = None
+ if extension is not None:
+ value = SEPARATOR.join([uid , extension])
+ matcher = UIDMatcher(uid)
+ else:
+ value = uid
+ parts = self._splitParts(uid)
+ matcher = UIDMatcher(parts[0])
+ self._uid = matcher.createMatchedUid()
+ super(UidBasedId, self).__init__(value)
+
+ def _splitParts(self, value):
+ seploc = value.find(SEPARATOR)
+ if seploc == 0:
+ raise InvalidUID("The string doesn't have a valid UID.")
+ elif seploc == -1:
+ return [value]
+ elif len(value) == (seploc+2):
+ raise InvalidUID("The string doesn't have a valid UID")
+ else:
+ root = value[:seploc]
+ seploc+= 2
+ extension = value[seploc:]
+ parts = [root, extension]
+ return parts
+
+ def root(self):
+ return self._uid
+
+ def extension(self):
+ parts = self._splitParts(self.value)
+ if len(parts) == 2:
+ return unicode(parts[1])
+ else:
+ return u""
+
+ def hasExtension(self):
+ if self.extension():
+ return True
+ return False
+
+
+class HierObjectId(UidBasedId):
+ u""" Concrete type corresponding to hierarchical identifiers of
+ the form defined by UidBasedId.
+ """
+
+
+class ObjectRef(grok.Model):
+ u""" Class describing a reference to another object, which may
+ exist locally or be maintained outside the current namespace,
+ e.g. in another service. Services are usually external,
+ e.g. available in a LAN (including on the same host) or the inter-
+ net via Corba, SOAP, or some other distributed protocol. However,
+ in small sys- tems they may be part of the same executable as the
+ data containing the Id.
+ """
+
+ grok.implements(IObjectRef)
+
+ def __init__(self, id_, nameSpace, type_):
+ self.id_=id_
+ self.nameSpace=nameSpace
+ self.type_=type_
+
+ def __eq__(self, obj):
+ if obj is self:
+ return True
+ if isinstance(obj, ObjectRef):
+ return obj.id_ == self.id_ and obj.nameSpace == self.nameSpace and obj.type_ == self.type_
+ return False
+
+ def __hash__(self):
+ result = 17
+ result += hash(self.id_)
+ result += hash(self.nameSpace)
+ result += hash(self.type_)
+ return result
+
+
+class AccessGroupRef(ObjectRef):
+ u""" Reference to access group in an access control service. """
+
+ grok.implements(IAccessGroupRef)
+
+ def __init__(self, id_, nameSpace, type_):
+ ObjectRef.__init__(self, id_, nameSpace, type_)
+
+
+class ArchetypeId(ObjectId):
+ grok.implements(IArchetypeId)
+
+ def __init__(self, value):
+ ObjectId.__init__(self, value)
+
+ self.AXIS_SEPARATOR = u'.'
+ self.SECTION_SEPARATOR = u'-'
+ self.NAME_PATTERN = r"[a-zA-Z][a-zA-Z0-9()_/%$#&]*"
+ self.VERSION_PATTERN = r"[a-zA-Z0-9]+"
+
+ # value is a unicode str of the full archetype ID from the ADL
+
+ self.value = value
+ tokens = value.split(self.AXIS_SEPARATOR)
+ if len(tokens) != 3:
+ raise ValueError, 'bad format, wrong number of sections'
+ self.__qualifiedRmEntity = tokens[0]
+
+ self.__domainConcept = tokens[1]
+ self.__version = tokens[2]
+ self.__validateVersionId(self.__version)
+
+ tokens = self.__qualifiedRmEntity.split(self.SECTION_SEPARATOR)
+ if len(tokens) != 3:
+ raise ValueError, 'bad format, wrong number of sections in ' + self.value
+ self.__rmOriginator = tokens[0]
+ self.__validateName(self.__rmOriginator, 'rm_originator')
+ self.__rmName = tokens[1]
+ self.__validateName(self.__rmName,'rm_name')
+ self.__rmEntity = tokens[2]
+ self.__validateName(self.__rmEntity, 'rm_entity')
+
+ tokens = self.__domainConcept.split(self.SECTION_SEPARATOR)
+ if len(tokens) < 1:
+ raise ValueError, 'bad format, too few sections for domainConcept in ' + self.value
+ self.__conceptName = tokens[0]
+ self.__validateName(self.__conceptName, 'concept_name')
+ if len(tokens) > 1:
+ self.__specialisation = tokens[-1]
+ self.__validateName(self.__specialisation, 'specialisation')
+ else: self.__specialisation = None
+
+ def __validateName(self, value, label):
+ match = re.compile(self.NAME_PATTERN).match(value)
+ if (match is None) or (match.end() < len(value)):
+ raise ValueError('wrong format of ' + label + ': ' + value)
+
+ def __validateVersionId(self, version):
+ match = re.compile(self.VERSION_PATTERN).match(version)
+ if (match is None) or (match.end() < len(version)):
+ raise ValueError('wrong format of versionId: ' + version)
+
+ def qualifiedRmEntity(self):
+ u""" Globally qualified reference model entity,
+ e.g. "openehr-composition-OBSERVATION".
+ """
+ return self.__qualifiedRmEntity
+
+ def domainConcept(self):
+ u""" Name of the concept represented by this archetype,
+ including specialisation,
+ e.g. "biochemistry_result-cholesterol".
+ """
+ return self.__domainConcept
+
+ def rmOriginator(self):
+ u""" Organisation originating the reference model on which
+ this archetype is based, e.g. "openehr", "cen", "hl7".
+ """
+ return self.__rmOriginator
+
+ def rmName(self):
+ u""" Name of the reference model, e.g. "rim","ehr_rm",
+ "en13606".
+ """
+ return self.__rmName
+
+ def rmEntity(self):
+ u""" Name of the ontological level within the reference model
+ to which this archetype is targeted, e.g. for openEHR,
+ "folder","composition", "section", "entry".
+ """
+ return self.__rmEntity
+
+ def specialisation(self):
+ u""" Name of specialisation of concept, if this archetype is a
+ specialisation of another archetype, e.g. "cholesterol".
+ """
+ return self.__specialisation
+
+ def versionId(self):
+ u""" Version of this archetype.
+ """
+ return self.__version
+
+
+class GenericId(ObjectId):
+ u""" Generic identifier type for identifiers whose format is
+ othterwise unknown to openEHR. Includes an attribute for naming
+ the identification scheme (which may well be local).
+ """
+
+ grok.implements(IGenericId)
+
+ def __init__(self, scheme, value):
+ self.scheme=scheme
+ ObjectId.__init__(self, value)
+
+ def __eq__(self, other):
+ if not isinstance(other, GenericId):
+ return False
+ if self.value != other.value:
+ return False
+ return self.scheme == other.scheme
+
+
+
+
+
+
+class LocatableRef(ObjectRef):
+ u""" Reference to a LOCATABLE instance inside the top-level
+ content structure inside a VERSION<T>; the path attribute is
+ applied to the object that VERSION.data points to.
+ """
+
+ grok.implements(ILocatableRef)
+
+ def __init__(self, id_, path, refId, refNameSpace, refType):
+ ObjectRef.__init__(self, refId, refNameSpace, refType)
+ self.id_=id_
+ self.path=path
+
+ def asUri(self):
+ u"""
+ A URI form of the reference, created by concatenating the following:
+ "ehr://" + id.value + "/" + path
+ """
+ return 'ehr://' + self.id_.value + "/" + self.path
+
+ def __eq__(self, other):
+ if not isinstance(other, LocatableRef):
+ return False
+ if self.id_ != other.id_:
+ return False
+ return self.path == other.path
+
+
+class ObjectVersionId(UidBasedId):
+ u""" Globally unique identifier for one version of a versioned
+ object; lexical form: object_id '::' creating_system_id '::'
+ version_tree_id
+
+ The string form of an OBJECT_VERSION_ID stored in its value
+ attribute consists of three segments separated by double colons
+ ("::"), i.e. (EBNF):
+
+ value: object_id '::' creating_system_id '::' version_tree_id
+ object_id: uid (see UID below) creating_system_id:
+
+ An example ObjectVersionId is as follows:
+ F7C5C7B7-75DB-4b39-9A1E-C0BA9BFDBDEC:
+ :87284370-2D4B-4e3d-A3F3-F303D2F4F34B::2
+ """
+
+ grok.implements(IObjectVersionId)
+
+
+ def __init__(self, value):
+ self.SIMPLE_UUID_PATTERN = r"([0-9a-fA-F])+(-([0-9a-fA-F])+)*"
+ self.SIMPLE_ISOOID_PATTERN = r"(\d)+(\.(\d)+)*"
+ self.SIMPLE_INTERNET_PATTERN = r"(\w)+(\.(\w)+)*"
+
+ UidBasedId.__init__(self, value)
+
+ # Steps for value checking:
+ # 1. Check if value contains any :: or starts with ::
+ doubleColons = value.find('::')
+ if doubleColons <= 0:
+ raise ValueError, 'bad format, missing objectId'
+
+ # 2. Check how many segments in the value
+ splits = value.split('::')
+ segments = len(splits)
+ if segments < 3:
+ raise ValueError, 'bad format, missing creatingSystemId or versionTreeId'
+ if segments > 4:
+ raise ValueError, 'bad format, too many segments or "::"'
+
+ # 3. Construct objects for each segment
+ # the patterns below are for sorting only, the correct syntax
+ # checking is handled by the UID sublcasses.
+ rootStr = splits[0]
+ matchUUID = re.compile(self.SIMPLE_UUID_PATTERN).match(rootStr)
+ matchISO = re.compile(self.SIMPLE_ISOOID_PATTERN).match(rootStr)
+ matchInternet = re.compile(self.SIMPLE_INTERNET_PATTERN).match(rootStr)
+ if (matchUUID is not None) and (matchUUID.start() == 0) and (matchUUID.end() == len(rootStr)):
+ self.__objectId = Uuid(rootStr)
+ elif (matchISO is not None) and (matchISO.start() == 0) and (matchISO.end() == len(rootStr)):
+ self.__objectId = IsoOid(rootStr)
+ elif (matchInternet is not None):
+ self.__objectId = InternetId(rootStr)
+ else:
+ raise ValueError('wrong format ' + rootStr)
+
+ if (segments == 4):
+ self.__creatingSystemId = HierObjectId(splits[1] +
+ '::' + splits[2])
+ self.__versionTreeId = VersionTreeId(splits[3])
+ else:
+ self.__creatingSystemId = HierObjectId(splits[1])
+ self.__versionTreeId = VersionTreeId(splits[2])
+
+ self.rootPart = self.objectId
+ self.extensionPart = self.__creatingSystemId.value + '::' + self.__versionTreeId.value
+
+ def objectId(self):
+ u""" Unique identifier for logical object of which this
+ identifier identifies one version; normally the object_id will
+ be the unique identifier of the version container containing
+ the version referred to by this OBJECT_VERSION_ID instance.
+ """
+ return self.__objectId
+
+ def versionTreeId(self):
+ u""" Tree identifier of this version with respect to other
+ versions in the same version tree, as either 1 or 3 part
+ dot-separated numbers, e.g. '1', '2.1.4'.
+ """
+ return self.__versionTreeId
+
+ def creatingSystemId(self):
+ u""" Identifier of the system that created the Version
+ corresponding to this Object version id.
+ """
+ return self.__creatingSystemId
+
+ def isBranch(self):
+ u"""
+ True if this version identifier represents a branch.
+ """
+ return self.__versionTreeId.isBranch()
+
+
+class PartyRef(ObjectRef):
+ u""" Identifier for parties in a demographic or identity
+ service. There are typically a number of subtypes of the PARTY
+ class, including PERSON, ORGANISATION, etc.
+
+ Abstract supertypes are allowed if the referenced object is of a
+ type not known by the current implementation of this class (in
+ other words, if the demographic model is changed by the addition
+ of a new PARTY or ACTOR subtypes, valid PartyRefs can still be
+ constructed to them).
+ """
+
+ grok.implements(IPartyRef)
+
+ def __init__(self, id_, nameSpace, type_):
+ ObjectRef.__init__(self, id_, nameSpace, type_)
+
+ def validateType(self):
+ u""" type_ is in
+ ["PERSON","ORGANISATION","GROUP","AGENT","ROLE","PARTY","ACTOR"]
+ """
+ return self.type_ in ['PERSON', 'ORGANISATION', 'GROUP', 'AGENT',
+ 'ROLE', 'PARTY', 'ACTOR']
+
+
+
+class TemplateId(ObjectId):
+ u""" Identifier for templates. Lexical form to be determined. """
+
+ grok.implements(ITemplateId)
+
+ def __init__(self, value):
+ self.value = value
+
+
+class TerminologyId(ObjectId):
+ u""" Identifier for terminologies such accessed via a terminology
+ query service. In this class, the value attribute identifies the
+ Terminology in the terminology service, e.g. "SNOMED-CT". A
+ terminology is assumed to be in a particular language, which must
+ be explicitly specified.
+
+ The value if the id attribute is the precise terminology id
+ identifier, including actual release (i.e. actual "version"),
+ local modifications etc; e.g. "ICPC2". Lexical form: name [ '('
+ version ')' ]
+ """
+
+ grok.implements(ITerminologyId)
+
+ def __init__(self, name):
+ self.value = name
+ parts = name.partition('(')
+ self.__name = parts[0]
+ self.__version = parts[2].rstrip(')')
+ ObjectId.__init__(self,name)
+
+ def name(self):
+ u""" Return the terminology id (which includes the "version"
+ in some cases). Distinct names correspond to distinct
+ (i.e. non-compatible) terminologies. Thus the names "ICD10AM"
+ and "ICD10" refer to distinct terminologies.
+ """
+ return self.__name
+
+ def versionId(self):
+ u""" Version of this terminology, if versioning supported,
+ else the empty string."""
+ return self.__version
+
+
+
+
+class VersionTreeId(grok.Model):
+ u"""
+ Version tree identifier for one version. Lexical form:
+ trunkVersion [ '.' branchNumber '.' branchVersion ]
+ """
+
+ grok.implements(IVersionTreeId)
+
+ PATTERN = r"[1-9](\d)*(\.(\d)+\.(\d)+)?"
+
+ def __init__(self, value):
+ self.__branchNumber = None
+ self.__branchVersion = None
+ match = re.compile(self.PATTERN).match(value)
+ if (match is None) or (match.start() != 0) or (match.end() != len(value)):
+ raise ValueError, 'wrong format'
+
+ branch = value.find('.')
+ if branch < 0: # no branch, just trunk
+ self.__trunkVersion = value
+ self.value = value
+ else:
+ entries = value.split(r".")
+ self.__validateValues(int(entries[0]), int(entries[1]),
+ int(entries[2]))
+ self.__trunkVersion = entries[0]
+ # never set branchNo or branchV to 0
+ if int(entries[1]) > 0:
+ self.__branchNumber = entries[1]
+ self.__branchVersion = entries[2]
+ self.value = value
+ else:
+ self.value = entries[0]
+
+ def __validateValues(self, trunk, branchNo, branchV):
+ if (trunk < 1) or (branchNo < 0) or (branchV < 0):
+ raise ValueError, 'version number smaller than 0'
+
+ # 0 for branchNo or branchV is special case,
+ # where both must be 0 to indicate no branch
+ if (branchNo == 0) or (branchV == 0):
+ if branchV != branchNo:
+ raise ValueError, 'breach of branch_validity'
+
+ def trunkVersion(self):
+ u""" Returns a string of the trunk version number; numbering
+ starts at 1.
+ """
+ return self.__trunkVersion
+
+ def branchNumber(self):
+ u"""
+ Number of branch from the trunk point; numbering starts at 1.
+ """
+ return self.__branchNumber
+
+ def branchVersion(self):
+ u"""
+ Number of branch from the trunk point; numbering starts at 1.
+ """
+ return self.__branchVersion
+
+ def isBranch(self):
+ u""" Returns True if this version identifier represents a
+ branch, i.e. has branchNumber and branchVersion parts.
+ """
+ return not self.__branchVersion is None
+
+ def isFirst(self):
+ u"""
+ True if this version identifier corresponds to the
+ first version, i.e. trunkVersion == "1"
+ """
+ return self.__trunkVersion == '1' and (not self.isBranch())
+
+ def __eq__(self, other):
+ if not isinstance(other, VersionTreeId):
+ return False
+ return self.value == other.value
+
=== added file 'src/oship/openehr/rm/support/identification/interfaces.py'
--- src/oship/openehr/rm/support/identification/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/support/identification/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,386 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+from zope.interface import Interface, invariant, Invalid, Attribute
+from zope.schema import TextLine, Object
+from zope.i18nmessageid import MessageFactory
+
+
+_ = MessageFactory('oship')
+
+class IUid(Interface):
+ u""" Abstract parent of classes representing unique identifiers
+ which identify information entities in a durable way. UIDs only
+ ever identify one IE in time or space and are never re-used.
+ """
+
+ value = Attribute("A single unicode string containing a valid UID")
+
+ @invariant
+ def valueExists(uid):
+ if uid.value == None or uid.value == '':
+ raise Invalid("The value attribute is not valid.")
+
+
+class IObjectId(Interface):
+ u""" Ancestor (abstract) class of identifiers of informational
+ objects. Ids may be completely meaningless, in which case their
+ only job is to refer to something, or may carry some information
+ to do with the identified object. Object ids are used inside an
+ object to identify that object. To identify another object in
+ another service, use an OBJECT_REF, or else use a UID for local
+ objects identified by UID. If none of the subtypes is suitable,
+ direct instances of this class may be used.
+ """
+
+ value = Attribute("A single unicode string containing a valid ID")
+
+ @invariant
+ def valueExists(id_obj):
+ if not (id_obj.value != None and not id_obj.value == ""):
+ raise Invalid("A value must exists.")
+
+
+class IUidBasedId(IObjectId):
+ u""" Abstract model of UID-based identifiers consisting of a root
+ part and an optional extension; lexical form: root '::' extension
+ """
+
+ def root():
+ u""" The identifier of the conceptual namespace in which the
+ object exists, within the identification scheme. Returns the
+ part to the left of the first '::' separator, if any, or else
+ the whole string.
+ """
+
+ def extension():
+ u""" Optional local identifier of the object within the
+ context of the root identifier. Returns the part to the right
+ of the first '::' separator if any, or else any empty String.
+ """
+
+ def hasExtension():
+ u""" True if extension is not None."""
+
+ @invariant
+ def rootValid(uid):
+ if uid.root() == None:
+ raise Invalid("Root method must return a valid UID object.")
+
+ @invariant
+ def extensionValidity(uid):
+ if uid.extension() is None:
+ raise Invalid("The extension method should"\
+ " return a extension from the String type")
+
+ @invariant
+ def hasExtensionValidity(uid):
+ def xor(exp1,exp2):
+ p = bool(exp1)
+ q = bool(exp2)
+ return p^q
+ if xor(uid.extension() is None, uid.hasExtension() == u''):
+ raise Invalid('The extension method expects a empty'\
+ ' string or a extension with characters.')
+
+
+class IObjectRef(Interface):
+ u""" Class describing a reference to another object, which may
+ exist locally or be maintained outside the current namespace,
+ e.g. in another service. Services are usually external,
+ e.g. available in a LAN (including on the same host) or the inter-
+ net via Corba, SOAP, or some other distributed protocol. However,
+ in small sys- tems they may be part of the same executable as the
+ data containing the Id.
+ """
+
+ id_ = Object(
+ schema=IObjectId,
+ title = _(u"Id"),
+ description = _(u"""Globally unique id of an object (of type ObjectId),
+ regardless of where it is stored."""),
+ required = True,
+ )
+
+ nameSpace = TextLine(
+ title = _(u"Namespace"),
+ description = _(u"""Namespace to which this identifier belongs in
+ the local system context (and possibly in any
+ other openEHR compliant environment) e.g.
+ "terminology", "demographic". These names
+ are not yet standardised. Legal values for the
+ namespace are
+ "local" | "unknown" | "[a-zA-
+ Z][a-zA-Z0-9_-:/&+?]*" """),
+ required = True,
+ )
+
+ type_ = TextLine(
+ title = _(u"Type"),
+ description = _(u"""Name of the class (concrete or abstract)
+ of object to which this identifier type
+ refers, e.g."PARTY", "PERSON", "GUIDELINE"
+ etc. These class names are from the relevant
+ reference model. The type name "ANY" can be
+ used to indicate that any type is accepted
+ (e.g. if the type is unknown)."""),
+ required = True,
+ )
+
+
+class IAccessGroupRef(Interface):
+ u""" Reference to access group in an access control service. """
+
+
+class IArchetypeId(Interface):
+ u""" Identifier for archetypes. Lexical form: rm_originator '-'
+ rm_name '-' rm_entity '.' concept_name { '-' specialisation }*
+ '.v' number
+
+ Archetype identifiers are "multi-axial", meaning that each
+ identifier instance denotes a single archetype within a
+ multi-dimensional space. In this case, the space is essentially a
+ versioned 3-dimensional space, with the dimensions being:
+
+ reference model entity, i.e. target of archetype domain concept
+ version
+
+ As with any multi-axial identifier, the underlying principle of an
+ archetype id is that all parts of the id must be able to be
+ considered immutable. This means that no variable characteristic
+ of an archetype (e.g. accrediting authority, which might change
+ due to later accreditation by another authority, or may be
+ multiple) can be included in its identifier. The syntax of an
+ ARCHETYPE_ID is as follows (EBNF):
+
+ archetype_id: qualified_rm_entity '.' domain_concept '.'
+ version_id qualified_rm_entity: rm_originator '-' rm_name '-'
+ rm_entity rm_originator: V_NAME rm_name: V_NAME rm_entity:
+ V_NAME domain_concept: concept_name { '-' specialisation }*
+ concept_name: V_NAME specialisation: V_NAME version_id: 'v'
+ V_NUMBER NUMBER: [0-9]* NAME: [a-z][a-z0-9()/%$#&]*
+
+ The field meanings are as follows: rm_originator: id of
+ organisation originating the reference model on which this
+ archetype is based; rm_name: id of the reference model on which
+ the archetype is based; rm_entity: ontological level in the
+ reference model; domain_concept: the domain concept name,
+ including any specialisations; version_id: numeric version
+ identifier;
+
+ Examples of archetype identifiers include:
+ openehr-composition-SECTION.physical_examination.v2
+ openehr-composition-SECTION.physical_examination-prenatal.v1
+ hl7-rim-act.progress_note.v1
+ openehr-composition-OBSERVATION.progress_note-naturopathy.v2
+
+ Archetypes can also be identified by other means, such as ISO oids.
+ """
+
+ def qualifiedRmEntity():
+ u""" Globally qualified reference model entity,
+ e.g. "openehr-composition-OBSERVATION".
+ """
+
+ def domainConcept():
+ u""" Name of the concept represented by this archetype,
+ including specialisation,
+ e.g. "biochemistry_result-cholesterol".
+ """
+
+ def rmOriginator():
+ u""" Organisation originating the reference model on which
+ this archetype is based, e.g. "openehr", "cen", "hl7".
+ """
+
+ def rmName():
+ u""" Name of the reference model, e.g. "rim","ehr_rm",
+ "en13606".
+ """
+
+ def rmEntity():
+ u""" Name of the ontological level within the reference model
+ to which this archetype is targeted, e.g. for openEHR,
+ "folder","composition", "section", "entry".
+ """
+
+ def specialization():
+ u""" Name of specialisation of concept, if this archetype is a
+ specialisation of another archetype, e.g. "cholesterol".
+ """
+
+ def versionId():
+ u"""
+ Version of this archetype.
+ """
+
+
+class IGenericId(Interface):
+ u""" Generic identifier type for identifiers whose format is
+ othterwise unknown to openEHR. Includes an attribute for naming
+ the identification scheme (which may well be local).
+ """
+
+ scheme = TextLine(
+ title = _(u"Scheme"),
+ description = _(u"Name of the scheme to which this identifier"
+ " conforms."),
+ required = True)
+
+
+class ILocatableRef(Interface):
+ u""" Reference to a LOCATABLE instance inside the top-level
+ content structure inside a VERSION<T>; the path attribute is
+ applied to the object that VERSION.data points to.
+ """
+
+ id_ = Object(
+ schema=IUidBasedId,
+ title = _(u'Id'),
+ description = _(u'Globally unique id of an object'
+ ' (of type UidBasedId), regardless of where'
+ ' it is stored.'),
+ required = True)
+
+ path = TextLine(
+ title = _(u"Path"),
+ description=_(u"""The path to an instance in question, as an
+ absolute path with respect to the object found at VERSION.data. An
+ empty path means that the object referred to by id being specified."""),
+ required = False)
+
+ def asUri():
+ u""" A URI form of the reference, created by concatenating the
+ following: "ehr://" + id.value + "/" + path
+ """
+
+
+class IObjectVersionId(Interface):
+ u""" Globally unique identifier for one version of a versioned
+ object; lexical form: object_id '::' creating_system_id '::'
+ version_tree_id
+
+ An example ObjectVersionId is as follows:
+ F7C5C7B7-75DB-4b39-9A1E-C0BA9BFDBDEC:
+ :87284370-2D4B-4e3d-A3F3-F303D2F4F34B::2
+ """
+
+ def objectId():
+ u""" Unique identifier for logical object of which this
+ identifier identifies one version; normally the object_id will
+ be the unique identifier of the version container containing
+ the version referred to by this OBJECT_VERSION_ID instance.
+ """
+
+ def versionTreeId():
+ u""" Tree identifier of this version with respect to other
+ versions in the same version tree, as either 1 or 3 part
+ dot-separated numbers, e.g. '1', '2.1.4'.
+ """
+
+ def creatingSystemId():
+ u""" Identifier of the system that created the Version
+ corresponding to this Object version id.
+ """
+
+ def isBranch():
+ u""" True if this version identifier represents a branch.
+ """
+
+class IPartyRef(Interface):
+ u""" Identifier for parties in a demographic or identity
+ service. There are typically a number of subtypes of the PARTY
+ class, including PERSON, ORGANISATION, etc.
+
+ Abstract supertypes are allowed if the referenced object is of a
+ type not known by the current implementation of this class (in
+ other words, if the demographic model is changed by the addition
+ of a new PARTY or ACTOR subtypes, valid PartyRefs can still be
+ constructed to them).
+ """
+
+ type_ = TextLine(
+ title = _(u"Type"),
+ description = _(u"""Name of the class (concrete or abstract)
+ of object to which this identifier type
+ refers, e.g."PARTY", "PERSON", "GUIDELINE"
+ etc. These class names are from the relevant
+ reference model. The type name "ANY" can be
+ used to indicate that any type is accepted
+ (e.g. if the type is unknown)."""),
+
+ #constraint = validateType
+ )
+
+
+class ITemplateId(Interface):
+ u""" Identifier for templates. Lexical form to be determined. """
+
+ value = TextLine(
+ title=_(u"Value"),
+ description=_(u"A single unicode string containing a valid ID"),
+
+ )
+
+
+class ITerminologyId(Interface):
+ u""" Identifier for terminologies such accessed via a terminology
+ query service. In this class, the value attribute identifies the
+ Terminology in the terminology service, e.g. "SNOMED-CT". A
+ terminology is assumed to be in a particular language, which must
+ be explicitly specified.
+
+ The value if the id attribute is the precise terminology id
+ identifier, including actual release (i.e. actual "version"),
+ local modifications etc; e.g. "ICPC2". Lexical form: name [ '('
+ version ')' ]
+ """
+
+ def name():
+ u""" Return the terminology id (which includes the "version"
+ in some cases). Distinct names correspond to distinct
+ (i.e. non-compatible) terminologies. Thus the names "ICD10AM"
+ and "ICD10" refer to distinct terminologies.
+ """
+
+ def versionId():
+ u""" Version of this terminology, if versioning supported,
+ else the empty string."""
+
+
+class IVersionTreeId(Interface):
+ u""" Version tree identifier for one version. Lexical form:
+ trunkVersion [ '.' branchNumber '.' branchVersion ]
+ """
+
+ value = TextLine(
+ title=_(u"Value"),
+ description=_(u"String form of this Version Tree identifier."),
+ )
+
+ def trunkVersion():
+ u"""
+ Returns a string of the trunk version number; numbering starts at 1.
+ """
+
+ def branchNumber():
+ u"""
+ Number of branch from the trunk point; numbering starts at 1.
+ """
+
+ def branchVersion():
+ u"""
+ Version of the branch; numbering starts at 1.
+ """
+
+ def isBranch():
+ u"""
+ Returns True if this version identifier represents a branch,
+ i.e. has branchNumber and branchVersion parts.
+ """
+
+ def isFirst():
+ u"""
+ True if this version identifier corresponds to the
+ first version, i.e. trunkVersion == "1"
+ """
=== added directory 'src/oship/openehr/rm/support/identification/tests'
=== added file 'src/oship/openehr/rm/support/identification/tests/__init__.py'
=== added file 'src/oship/openehr/rm/support/identification/tests/hierobjectid.txt'
--- src/oship/openehr/rm/support/identification/tests/hierobjectid.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/support/identification/tests/hierobjectid.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,123 @@
+:Test-Layer: unit
+
+HierObjectId Class
+==================
+
+HierObjectId is a object identifier that uses the available UID identifier
+types from OSHIP, consisted of a root part (the UID itself) and a extension
+part that from a identifier to a object.
+
+Every HierObjectId object follows the IUIDBasedId interface which defines
+four important members:
+
+* root method - it returns a UID object that match with the pattern.
+* extension method - returns the extension part in a unicode type.
+* hasExtension method - returns True if has a extension part, False otherwise.
+* value atrribute - It's the full identifier in unicode form.
+
+
+Let's create a object::
+
+>>> from oship.openehr.rm.support.identification import HierObjectId
+>>> id01 = HierObjectId(u'a8098c1a-f86e-11da-bd1a-00112444be1e')
+>>> id01.value
+u'a8098c1a-f86e-11da-bd1a-00112444be1e'
+>>> id01.root() #doctest: +ELLIPSIS
+<...Uuid object at ...>
+>>> id01.extension()
+u''
+>>> id01.hasExtension()
+False
+
+
+The object created above used the UUID format to create a Id.
+Let's another type of UID, now with a extension::
+
+>>> internetid_with_extension = HierObjectId(u'oship.org::12344535')
+>>> internetid_with_extension.value
+u'oship.org::12344535'
+>>> internetid_with_extension.root() #doctest: +ELLIPSIS
+<oship.openehr.rm.support.identification.InternetId object at ...>
+>>> internetid_with_extension.extension()
+u'12344535'
+>>> internetid_with_extension.hasExtension()
+True
+
+The **::** characters are used to separate the two parts of a UidBasedId,
+but it not allowed put it without a valid uid string ::
+
+>>> wrong_id = HierObjectId(u'::1231232')
+... # doctest: +ELLIPSIS
+Traceback (most recent call last):
+InvalidUID: ...
+
+The value attribute contains the full id in string format, but it must be in
+unicode form::
+
+>>> iso_oid = HierObjectId('1.3.5.7.9.24.68.1.1::test6753662')
+>>> iso_oid.value
+u'1.3.5.7.9.24.68.1.1::test6753662'
+
+A object also cannot be created with a empty string::
+
+>>> id_empty = HierObjectId('') #doctest: +ELLIPSIS
+Traceback (most recent call last):
+InvalidUID: ...
+
+It also cannot be created using the separator without include a extension
+part::
+
+>>> weird = HierObjectId(u'1.3.5.7.9.24.68.1.1::') #doctest: +ELLIPSIS
+Traceback (most recent call last):
+InvalidUID: ...
+
+The only acceptable UID are ``ISOOid``, ``Uuid``, ``InternetId``. If a uid
+string was passed that don't match with these patterns, will raise a
+exception::
+
+>>> weird_separator = HierObjectId(u"aaaabbccdd::123test") #doctest: +ELLIPSIS
+Traceback (most recent call last):
+InvalidUID: ...
+
+Using a UID object as argument
+------------------------------
+
+It is possible use a object that implements ``IUid`` Interface as a parameter::
+>>> from oship.openehr.rm.support.identification import ISOOid
+>>> other_iso_id = HierObjectId(ISOOid(u"1.3.5.7.9.24.68.1.1"),u'test6753662')
+>>> other_iso_id.value
+u'1.3.5.7.9.24.68.1.1::test6753662'
+>>> class MyUid(object):
+... pass
+>>> strange_uid = HierObjectId(MyUid()) # doctest : +ELLIPSIS
+Traceback (most recent call last):
+AttributeError: ...
+
+Comparison bewteen objects
+--------------------------
+
+If two objects are the same type and they have the same value attribute,
+it means they are the equals::
+
+>>> ok_id = HierObjectId(u"1.3.5.7.9.24.68.1.1",u"test6753662")
+>>> ok_id.value
+u'1.3.5.7.9.24.68.1.1::test6753662'
+>>> other_iso_id.value
+u'1.3.5.7.9.24.68.1.1::test6753662'
+>>> ok_id == other_iso_id
+True
+
+Validating Invariants
+---------------------
+
+The invariants can also checked using the zope.interface mechanism::
+
+>>> from oship.openehr.rm.support.identification import IUidBasedId
+>>> ok_id._uid = None
+>>> IUidBasedId.validateInvariants(ok_id)
+Traceback (most recent call last):
+Invalid: Root method must return a valid UID object.
+>>> other_iso_id.value = ''
+>>> IUidBasedId.validateInvariants(other_iso_id)
+Traceback (most recent call last):
+Invalid: A value must exists.
=== added file 'src/oship/openehr/rm/support/identification/tests/uidobject.txt'
--- src/oship/openehr/rm/support/identification/tests/uidobject.txt 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/support/identification/tests/uidobject.txt 2010-08-06 02:32:43 +0000
@@ -0,0 +1,124 @@
+:Test-Layer: unit
+
+UID Objects
+===========
+
+The ``identification`` package models informational identifiers, i.e.
+transparent identifiers understood by openEHR or related computational
+systems.
+UID objects in special are treated as primitive identifiers because
+they don't have a complex internal structure. The three subtypes from the
+``Uid`` superclass ``Uuid``, ``ISOOid`` and ``InternetId`` are common
+acceptable ways of uniquely identifying entities. They also are used as
+parts of other identifiers in openEHR.
+All Uid subtypes store identifiers as a string using the **value**
+attribute on each object. UID objects are never re-used
+and identify only one Information Entity in time or space.
+
+UUID Object
+-----------
+A UUID is an identifier that is unique across both space and time, with respect
+to the space of all UUIDs. A UUID can be used for multiple purposes, from taggin
+g objects with an extremely short lifetime, to reliably identifying very persist
+ent objects across a network.
+`The Model of the DCE Universal Unique Identifier`_ or UUID which takes the form of
+hexadecimal integers separated by hyphens, following the pattern 8-4-4-4-12
+characters::
+
+>>> from oship.openehr.rm.support.identification import Uuid
+>>> new_uuid = Uuid(u"1f4119ad-9463-4fd0-a8b3-fe9663f7e29b")
+>>> new_uuid.value
+u'1f4119ad-9463-4fd0-a8b3-fe9663f7e29b'
+
+It's only acceptable pass a string using the UUID format::
+
+>>> new_uuid = Uuid(u"1f4119ad-9463-4fd0-a8b36-TT9663f7e29b")#doctest: +ELLIPSIS
+Traceback (most recent call last):
+InvalidUID: Invalid UUID format.
+
+
+ISOOID Object
+-------------
+
+The ``ISOOid`` class allow create identifiers that match with the model of
+iso's object identifier as defined by the standard ISO/IEC 8824.
+OIDs are intended to be globally unique. They are formed by taking a unique
+numeric string (e.g. 1.3.5.7.9.24.68) and adding additional digits in a
+unique fashion (e.g. 1.3.5.7.9.24.68.1, 1.3.5.7.9.24.68.2, 1.3.5.7.9.24.68.1.1,
+etc.). An institution will acquire an arc (eg 1.3.5.7.9.24.68) and then extend
+the arc (called subarcs) as indicated above to create additional OIDâs and arcs.
+
+Let's create a ISOOid object:
+
+>>> from oship.openehr.rm.support.identification import ISOOid
+>>> new_isooid = ISOOid(u"1.3.5.7.9.24.68")
+>>> new_isooid.value
+u'1.3.5.7.9.24.68'
+
+It's only acceptable pass a string using the OID format::
+
+>>> new_isooid = ISOOid(u"1.3.5.7.a.b") #doctest: +ELLIPSIS
+Traceback (most recent call last):
+InvalidUID: Invalid OID format.
+
+
+InternetID Object
+-----------------
+
+The InternetId class allows use a reverse internet domain as a
+unique identifier. The pattern matched is the form of a dot-separated
+string in the reverse order of a domain name, specified by `IETF RFC 1034`_.
+
+
+
+>>> from oship.openehr.rm.support.identification import InternetId
+>>> new_internetid = InternetId(u"oship.org")
+>>> new_internetid.value
+u'oship.org'
+
+It's only acceptable pass a string using the Internet Domain format::
+
+>>> other_internetid = InternetId(u"""my text is huge and it has a domain: mydomain-1231""") #doctest: +ELLIPSIS
+Traceback (most recent call last):
+InvalidUID: Invalid Internet Domain.
+
+
+All UID subtypes convert any python string to unicode, because it's mandatory use it
+in order to maintain a interoperable coding, according to the openEHR
+specifications::
+
+>>> new_internetid = InternetId("oship.org")
+>>> new_internetid.value
+u'oship.org'
+>>> new_isooid = ISOOid("1.3.5.7.9.24.68")
+>>> new_isooid.value
+u'1.3.5.7.9.24.68'
+>>> new_uuid = Uuid("1f4119ad-9463-4fd0-a8b3-fe9663f7e29b")
+>>> new_uuid.value
+u'1f4119ad-9463-4fd0-a8b3-fe9663f7e29b'
+
+Using the invariant mechanism
+-----------------------------
+
+All classes that represent a UID must implement the IUid interface.
+It has a invariant expression that can be checked using the
+machinery provided by the zope.interface::
+
+>>> from oship.openehr.rm.support.identification.interfaces import IUid
+>>> IUid.validateInvariants(new_uuid)
+
+In the scenario above, the object was checked by invariant expression.
+Let's see what happened if it had a wrong value attribute::
+
+>>> new_uuid.value = ''
+>>> IUid.validateInvariants(new_uuid)
+Traceback (most recent call last):
+Invalid: The value attribute is not valid.
+>>> new_isooid.value = None
+>>> IUid.validateInvariants(new_isooid)
+Traceback (most recent call last):
+Invalid: The value attribute is not valid.
+
+.. _The Model of the DCE Universal Unique Identifier:
+ http://www.opengroup.org/onlinepubs/9629399/apdxa.htm
+.. _IETF RFC 1034: http://www.ietf.org/rfc/rfc1034.txt
=== added file 'src/oship/openehr/rm/support/interfaces.py'
--- src/oship/openehr/rm/support/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/support/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,4 @@
+from definition.interfaces import *
+from measurement.interfaces import *
+from terminology.interfaces import *
+from identification.interfaces import *
=== added directory 'src/oship/openehr/rm/support/measurement'
=== added file 'src/oship/openehr/rm/support/measurement/__init__.py'
--- src/oship/openehr/rm/support/measurement/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/support/measurement/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+
+import grok
+from interfaces import IMeasurementService
+
+
+class MeasurementService(grok.Model):
+ """Defines an object providing proxy access to a measurement
+ information service."""
+
+ grok.implements(IMeasurementService)
+
+ def isValidUnitsString(units):
+ u""" True if the units string 'units' is a valid string
+ according to the HL7 UCUM specification. units is not None
+ """
+ pass
+
+ def unitsEquivalent(units1, units2):
+ u""" True if two units strings correspond to the same measured
+ property. isValidUnitsString(units1) and
+ isValidUnitsString(units2)
+ """
+ pass
+
=== added file 'src/oship/openehr/rm/support/measurement/interfaces.py'
--- src/oship/openehr/rm/support/measurement/interfaces.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/support/measurement/interfaces.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,21 @@
+# -*- coding: UTF-8 -*-
+
+
+from zope.interface import Interface
+
+
+class IMeasurementService(Interface):
+ """Defines an object providing proxy access to a measurement
+ information service."""
+
+ def isValidUnitsString(units):
+ u""" True if the units string 'units' is a valid string
+ according to the HL7 UCUM specification. units is not None
+ """
+
+ def unitsEquivalent(units1, units2):
+ u""" True if two units strings correspond to the same measured
+ property. isValidUnitsString(units1) and
+ isValidUnitsString(units2)
+ """
+
=== added directory 'src/oship/openehr/rm/support/measurement/tests'
=== added file 'src/oship/openehr/rm/support/measurement/tests/__init__.py'
=== added directory 'src/oship/openehr/rm/support/terminology'
=== added file 'src/oship/openehr/rm/support/terminology/__init__.py'
--- src/oship/openehr/rm/support/terminology/__init__.py 1970-01-01 00:00:00 +0000
+++ src/oship/openehr/rm/support/terminology/__init__.py 2010-08-06 02:32:43 +0000
@@ -0,0 +1,198 @@
+# -*- coding: UTF-8 -*-
+
+import grok
+
+
+class CodeSetAccess(grok.Model):
+ u"""
+ Defines an object providing proxy access to a code_set.
+ """
+
+ def id(self,idStr):
+ u"""External identifier of this Code Set"""
+
+ def allCodes(self,codeSet):
+ u""" Return all codes known in this code set as CodePhrases"""
+
+ def hasLang(self,a_lang):
+ u""" True if code set knows about 'a_lang' """
+
+ def hasCode(self,a_code):
+ u""" True if code set knows about 'a_code' """
+
+ def idValid(self,idStr):
+ u""" True if id_ is not None and id_ != '' """
+
+
+class OpenehrCodeSetIdentifiers(object):
+ u"""
+ List of identifiers for code sets in the openEHR terminology.
+ """
+
+ CodeSetIdCharacterSets='character sets'
+ CodeSetIdCompressionAlgorithms='compression algorithms'
+ CodeSetIdCountries='countries'
+ CodeSetIdIntegrityCheckAlgorithms='integrity check algorithms'
+ CodeSetIdLanguages='languages'
+ CodeSetIdMediaTypes='media types'
+ CodeSetIdNormalStatuses='normal statuses'
+ values=(CodeSetIdCharacterSets, CodeSetIdCompressionAlgorithms,
+ CodeSetIdCountries, CodeSetIdIntegrityCheckAlgorithms,
+ CodeSetIdLanguages, CodeSetIdMediaTypes,
+ CodeSetIdNormalStatuses)
+
+
+def validCodeSetId(anId):
+ u"""
+ Boolean Validity function to test if an identifier is in
+ the tuple defined by class OpenehrCodeSetIdentifiers.
+ """
+ return anId in OpenehrCodeSetIdentifiers.values
+
+
+class OpenehrTerminologyGroupIdentifiers(object):
+ """
+ List of identifiers for groups in the openEHR terminology.
+ """
+ terminologyId='openehr'
+ groupIdAuditChangeType='audit change type'
+ groupIdAttestationReason='attestation reason'
+ groupIdCompositionCategory='composition category'
+ groupIdEventMathFunction='event math function'
+ groupIdIsmStates='instruction states'
+ groupIdIsmTransitions='instruction transitions'
+ groupIdNullFlavours='null flavours'
+ groupIdMeasurableProperties='property'
+ groupIdParticipationFunction='participation function'
+ groupIdParticipationMode='participation mode'
+ groupIdRelatedPartyRelationship='related party relationship'
+ groupIdSetting='setting'
+ groupIdTermMappingPurpose='term mapping purpose'
+ groupIdVersionLifecycleState='version lifecycle state'
+
+ values=(terminologyId, groupIdAuditChangeType, groupIdAttestationReason,
+ groupIdCompositionCategory, groupIdEventMathFunction,
+ groupIdIsmStates, groupIdIsmTransitions, groupIdNullFlavours,
+ groupIdMeasurableProperties, groupIdParticipationFunction,
+ groupIdParticipationMode, groupIdRelatedPartyRelationship,
+ groupIdSetting, groupIdTermMappingPurpose,
+ groupIdVersionLifecycleState)
+
+
+def validTerminologyGroupId(anId):
+ u""" Validity function to test if an identifier is in the tuple
+ defined by class OpenehrTerminologyGroupIdentifiers.
+ """
+ return anId in OpenehrTerminologyGroupIdentifiers.values
+
+
+class TerminologyAccess(grok.Model):
+ u"""
+ Defines an object providing proxy access to a terminology.
+ """
+
+ def id(self,idStr):
+ u"""ID of this code set"""
+ pass
+
+ def allCodes(self,codeSet):
+ u""" Return all codes known in this terminology """
+ pass
+
+ def codesForGroupId(self,group_id):
+ u"""
+ Return all codes under grouper 'group_id' from this terminology
+ """
+ pass
+
+ def hasCodeForGroupId(self,group_id, a_code):
+ u""" True if 'a_code' is known in group 'group_id' in the
+ openEHR terminology.
+ """
+ pass
+
+ def codesForGroupName(self,name, lang):
+ u""" Return all codes under grouper whose name in 'lang' is
+ 'name' from this terminology
+ """
+ pass
+
+ def rubricForCode(self,code, lang):
+ u""" Return all rubric of code 'code' in language 'lang'.
+ """
+ pass
+
+ def idExists(self):
+ u""" True if id_ is not None and id_ != '' """
+ pass
+
+
+class TerminologyService(grok.Model):
+ u"""
+ Defines an object providing proxy access to a terminology service.
+ """
+
+ def terminology(self,name):
+ u""" Return an interface to the terminology named
+ name. Allowable names include "openehr","centc251",any name
+ from are taken from the US NLM UMLS meta-data list at
+ http://www.nlm.nih.gov/research/umls/metaa1.html
+
+ name is not None and name is a valid TerminologyAccess.
+ """
+ pass
+
+ def codeSet(self,name):
+ u""" Return an interface to the code_set identified by the
+ external identifier name (e.g. "ISO_639-1").
+
+ name is not None and hasCodeSet == True.
+ """
+ pass
+
+ def codeSetForId(self,id_):
+ u""" Return an interface to the code_set identified internally
+ in openEHR by id.
+
+ id_ is not None and validCodeSetId(id_) == True
+ """
+ pass
+
+ def hasTerminology(self,name):
+ u""" True if terminology named name known by this
+ service. Allowable names include: "openehr","centc251",any
+ name from are taken from the US NLM UMLS meta-data list at
+ http://www.nlm.nih.gov/research/umls/metaa1.html
+
+ name is not None and name != ''
+ """
+ pass
+
+ def hasCodeSet(self,name):
+ u""" True if codeSet linked to internal name
+ (e.g. "languages") is available.
+
+ name is not None and name != ''
+ """
+ pass
+
+ def terminologyIdentifiers(self):
+ u""" Set (LIST) of all terminology identifiers known in the
+ terminology service. Values from the US NLM UMLS meta-data
+ list at http://www.nlm.nih.gov/research/umls/metaa1.html
+ """
+ pass
+
+ def codeSetIdentifiers(self):
+ u"""
+ Set of all code set identifiers known in the terminology service.
+ """
+ pass
+
+ def openehrCodeSets(self):
+ u""" Set of all code sets identifiers for which there is an
+ internal openEHR name; returned as a Hash of ids keyed by
+ internal name.
+ """
+ pass
+
=== added file 'src/oship/openehr/rm/support/terminology/interfaces.py'
=== added directory 'src/oship/openehr/rm/support/terminology/tests'
=== added file 'src/oship/openehr/rm/support/terminology/tests/__init__.py'
=== modified file 'src/oship/openehr/tests/extract.txt'
--- src/oship/openehr/tests/extract.txt 2010-07-28 21:58:43 +0000
+++ src/oship/openehr/tests/extract.txt 2010-08-06 02:32:43 +0000
@@ -1,12 +1,12 @@
:Test-Layer: unit
>>> from oship.openehr.extract import *
->>> from oship.rm.support.identification import TerminologyId, Uid, HierObjectId
->>> from oship.rm.datatypes.text import DvText, CodePhrase, TermMapping
->>> from oship.rm.datatypes.uri import DvUri
->>> from oship.rm.datatypes.quantity import DvAmount
->>> from oship.rm.datatypes.quantity.datetime import DvTime, DvDateTime
->>> from oship.rm.data_structures.item_structure.representation import Element
+>>> from oship.openehr.rm.support.identification import TerminologyId, Uid, HierObjectId
+>>> from oship.openehr.rm.datatypes.text import DvText, CodePhrase, TermMapping
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> from oship.openehr.rm.datatypes.quantity import DvAmount
+>>> from oship.openehr.rm.datatypes.quantity.datetime import DvTime, DvDateTime
+>>> from oship.openehr.rm.data_structures.item_structure.representation import Element
>>> tid1 = TerminologyId(u"SNOMED-CT(2003)")
=== modified file 'src/oship/openehr/tests/integration.txt'
--- src/oship/openehr/tests/integration.txt 2010-07-20 11:19:44 +0000
+++ src/oship/openehr/tests/integration.txt 2010-08-06 02:32:43 +0000
@@ -2,11 +2,11 @@
>>> import zope.schema
>>> from oship.openehr.integration import GenericEntry, IGenericEntry
->>> from oship.rm.data_structures.item_structure import ItemTree
->>> from oship.rm.data_structures.item_structure.representation import Element
->>> from oship.rm.datatypes.text import DvText, TermMapping, CodePhrase
->>> from oship.rm.datatypes.uri import DvUri
->>> from oship.rm.support.identification import TerminologyId
+>>> from oship.openehr.rm.data_structures.item_structure import ItemTree
+>>> from oship.openehr.rm.data_structures.item_structure.representation import Element
+>>> from oship.openehr.rm.datatypes.text import DvText, TermMapping, CodePhrase
+>>> from oship.openehr.rm.datatypes.uri import DvUri
+>>> from oship.openehr.rm.support.identification import TerminologyId
>>> tid = TerminologyId(u"SNOMED-CT(2003)")
>>> tid1 = TerminologyId(u"ISO_639-1")
>>> tid2 = TerminologyId(u"10646-1:1993")
=== removed directory 'src/oship/rm'
=== removed file 'src/oship/rm/__init__.py'
=== removed directory 'src/oship/rm/common'
=== removed file 'src/oship/rm/common/__init__.py'
--- src/oship/rm/common/__init__.py 2010-08-01 16:37:49 +0000
+++ src/oship/rm/common/__init__.py 1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-# This file just exists to make it's directory as a module.
=== removed directory 'src/oship/rm/common/archetyped'
=== removed file 'src/oship/rm/common/archetyped/__init__.py'
--- src/oship/rm/common/archetyped/__init__.py 2010-08-01 16:37:49 +0000
+++ src/oship/rm/common/archetyped/__init__.py 1970-01-01 00:00:00 +0000
@@ -1,245 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-
-import grok
-from interfaces import *
-
-
-class Pathable(grok.Model):
- """
- Abstract parent of all classes whose instances are reachable by paths, and
- which know how to locate child object by paths. The parent feature may be
- implemented as a function or attribute.
-
- The two attributes required for locatable in Grok is __parent__ and
- __name__. We inherit those from grok.Model.
-
- The functionality to get paths and find children is contained in the
- traversal mechanism. """
-
- grok.implements(IPathable)
-
-
-
- def pathOfItem(an_item):
- """
- The path to an item relative to the root of this archetyped structure.
-
- getPath is from the Traversal API.
- """
-
- def itemAtPath(a_path):
- """
- The item at a path (relative to this item);only valid for unique paths,
- i.e. paths that resolve to a single item. a_path is a string. Return
- a_path is not None and pathUnique(a_path)
-
- If the path is not unique or not found then a TraversalError is raised.
- """
-
- def itemsAtPath(a_path):
- """
- List of items corresponding to a non-unique path.
- a_path is a List
- Return a_path is not None and pathUnique(a_path)
- """
-
- def pathExists(a_path):
- """
- True if the path exists in the data with respect to the current item.
- Return a_path is not None and a_path != ''
- """
-
- def pathUnique(a_path):
- """
- True if the path corresponds to a single item in the data.
- Return a_path is not None and pathExists(a_path)
- """
-
-
-class Locatable(Pathable):
- """
- Root class of all information model classes that can be archetyped.
- """
-
- grok.implements(ILocatable)
-
- def __init__(self, uid, atnodeid, name, atdetails, fdraudit, links):
- self.uid=uid
- self.archetypeNodeId=atnodeid
- self.name=name
- self.archetypeDetails=atdetails
- self.feederAudit=fdraudit
- self.links=links
-
- def isArchetypeRoot(self):
- """True if this node is the root of an archetyped structure. At
- specification there's a requiment for archetypeDetails in all root
- points in data """
- return self.archetypeDetails is not None
-
- def concept():
- """
- Clinical concept of the archetype as a whole (= derived from the
- 'archetype_node_id' of the root node) isArchetypeRoot must be True.
- """
- if (self.isArchetypeRoot()):
- return DvText(self.archetypeDetails.archetypeId.conceptName())
- raise TypeError('Not root node')
-
- def nameValid():
- """ name is not None"""
- return self.name is not None
-
- def linksValid():
- """ links is not None and links != []"""
- if self.links is not None:
- return self.links != []
- return self.links is None
-
- def archetypedValid():
- """ isArchetypeRoot xor archetypeDetails = None """
- return xor(self.isArchetypeRoot(), self.archetypeDetails is None)
-
- def archetypeNodeIdValid():
- """ archetypeNodeId is not None and archetypeNodeId != '' """
- if(self.archetypeNodeId is not None):
- return self.archetypeNodeId != ''
- return self.archetypeNodeId is None
-
- def __eq__(self, obj):
- if self is obj:
- return True
- if isinstance(obj, Locatable):
- return obj.uid == self.uid and obj.archetypeNodeId == self.archetypeNodeId and obj.name == self.name and obj.archetypeDetails == self.archetypeDetails and obj.feederAudit == self.feederAudit and obj.links == self.links
- return False
-
- def __hash__(self):
- result = 17
- result += 31 * result + hash(self.uid)
- result += 31 * result + hash(self.archetypeNodeId)
- result += 31 * result + hash(self.name)
- result += 31 * result + hash(self.archetypeDetails)
- result += 31 * result + hash(self.feederAudit)
- result += 31 * result + hash(self.links)
- return result
-
-
-class Archetyped(grok.Model):
- """
- Archetypes act as the configuration basis for the particular structures of
- instances defined by the reference model. To enable archetypes to be used
- to create valid data, key classes in the reference model act as "root"
- points for archetyping; accordingly, these classes have the
- archetype_details attribute set. An instance of the class ARCHETYPED
- contains the relevant archetype identification information, allowing
- generating archetypes to be matched up with data instances """
-
- grok.implements(IArchetyped)
-
- def __init__(self, atid, tmplid, rmver):
- self.archetypeId=atid
- self.templateId=tmplid
- self.rmVersion=rmver
-
- def archetypeIdValid():
- """ archetypeId is not None """
-
- def rmVersionValid():
- """ rmVersion is not None and rmVersion != '' """
-
- def __eq__(self, obj):
- if obj is self:
- return True
- if isinstance(obj, Archetyped):
- return obj.archetypeId == self.archetypeId and obj.templateId == self.templateId and obj.rmVersion == self.rmVersion
- return False
-
- def __hash__(self):
- result = 17
- result = 31 * result + hash(self.archetypeId)
- result = 31 * result + hash(self.templateId)
- result = 31 * result + hash(self.rmVersion)
- return result
-
-
-class FeederAuditDetails(grok.Model):
- u"""
- Audit details for any system in a feeder system chain. Audit details here
- means the general notion of who/where/when the information item to which
- the audit is attached was created. None of the attributes is defined as
- mandatory, however, in different scenarios, various combinations of
- attributes will usually be mandatory. This can be controlled by specifying
- feeder audit details in legacy archetypes. """
-
- grok.implements(IFeederAuditDetails)
-
- def __init__(self, sysid, provider, location, time, subject, verid):
-
-
- self.systemId=sysid
- self.provider=provider
- self.location=location
- self.time=time
- self.subject=subject
- self.versionId=verid
-
- def systemIdValid():
- u"""systemId is not None and systemId != '' """
-
-
-class FeederAudit(Locatable):
- """
- Audit and other meta-data for systems in the feeder chain.
- """
-
- grok.implements(IFeederAudit)
-
- def __init__(self, orgsysaudit, orgsysids, fsaudit, fsauditids,
- orgcontent):
-
-
- self.originatingSystemAudit=orgsysaudit
- self.originatingSystemItemIds=orgsysids
- self.feederSystemAudit=fsaudit
- self.feederSystemItemIds=fsauditids
- self.originalContent=orgcontent
-
- def originatingSystemAuditValid():
- """ originatingSystemAudit is not None """
-
-
-class Link(Locatable):
- """
- The LINK type defines a logical relationship between two items, such as two
- ENTRYs or an ENTRY and a COMPOSITION. Links can be used across composi-
- tions, and across EHRs. Links can potentially be used between interior
- (i.e. non archetype root) nodes, although this probably should be prevented
- in archetypes. Multiple LINKs can be attached to the root object of any
- archetyped structure to give the effect of a 1->N link 1:1 and 1:N
- relationships between archetyped content elements (e.g. ENTRYs) can be
- expressed by using one, or more than one, respectively, DV_LINKs. Chains of
- links can be used to see "problem threads" or other logical groupings of
- items. Links should be between archetyped structures only, i.e. between
- objects representing complete domain concepts because relationships between
- sub-elements of whole concepts are not necessarily meaningful, and may be
- downright confusing. Sensible links only exist between whole ENTRYs,
- SECTIONs, COMPOSITIONs and so on. """
-
- grok.implements(ILink)
-
- def __init__(self, meaning, type_, target):
-
- self.meaning=meaning
- self.type_=type_
- self.target=target
-
- def meaningValid():
- """Return meaning is not None """
-
- def typeValid():
- """Return type is not None """
-
- def targetValid():
- """Return target is not None """
-
=== removed file 'src/oship/rm/common/archetyped/interfaces.py'
--- src/oship/rm/common/archetyped/interfaces.py 2010-08-01 16:37:49 +0000
+++ src/oship/rm/common/archetyped/interfaces.py 1970-01-01 00:00:00 +0000
@@ -1,436 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-
-from zope.interface import Interface
-from zope.schema import TextLine, Object, List, Set
-from zope.i18nmessageid import MessageFactory
-import grok
-
-from oship.rm.support.interfaces import IArchetypeId, ITemplateId, IUidBasedId
-from oship.rm.datatypes.basic import IDvIdentifier
-from oship.rm.datatypes.text.interfaces import IDvText
-from oship.rm.datatypes.quantity.datetime.interfaces import IDvDateTime
-from oship.rm.datatypes.encapsulated.interfaces import IDvEncapsulated
-from oship.rm.datatypes.uri.interfaces import IDvEhrUri
-from oship.rm.common.generic.interfaces import IPartyIdentified
-from oship.rm.common.generic.interfaces import IPartyProxy
-
-_ = MessageFactory('oship')
-
-
-class ILink(Interface):
- """
- The LINK type defines a logical relationship between two items, such as two
- ENTRYs or an ENTRY and a COMPOSITION. Links can be used across composi-
- tions, and across EHRs. Links can potentially be used between interior
- (i.e. non archetype root) nodes, although this probably should be prevented
- in archetypes. Multiple LINKs can be attached to the root object of any
- archetyped structure to give the effect of a 1->N link 1:1 and 1:N
- relationships between archetyped content elements (e.g. ENTRYs) can be
- expressed by using one, or more than one, respectively, DV_LINKs. Chains of
- links can be used to see "problem threads" or other logical groupings of
- items. Links should be between archetyped structures only, i.e. between
- objects representing complete domain concepts because relationships between
- sub-elements of whole concepts are not necessarily meaningful, and may be
- downright confusing. Sensible links only exist between whole ENTRYs,
- SECTIONs, COMPOSITIONs and so on. """
-
- meaning = Object(
- schema=IDvText,
- title=_(u"Meaning"),
- description=_(u"""Used to describe the relationship, usually in
- clinical terms, such as "in response to"
- (the relationship between test results and an order),
- "follow-up to" and so on. Such relationships can represent
- any clinically meaningful connection between pieces of
- information. Values for meaning include those described in
- Annex C, ENV 13606 pt 2 [11] under the categories of
- "generic", "documenting and
- reporting","organisational","clinical",
- "circumstancial", and "view management". """),
-
- )
-
- type_ = Object(
- schema=IDvText,
- title=_(u"Type"),
- description=_(u"""The type attribute is used to indicate a clinical or
- domain-level meaning for the kind of link, for example "problem" or
- "issue". If type values are designed appropriately, they can be used by
- the requestor of EHR extracts to categorise links which must be
- followed and which can be broken when the extract is created. """),
-
- )
-
- target = Object(
- schema=IDvEhrUri,
- title=_(u"Target"),
- description=_(u"""The logical "to" object in the link relation,
- as target: per the linguistic sense of the meaning
- attribute."""),
-
- )
-
- def meaningValid():
- """Return meaning is not None """
-
- def typeValid():
- """Return type is not None """
-
- def targetValid():
- """Return target is not None """
-
-
-
-class IFeederAuditDetails(Interface):
- u"""
- Audit details for any system in a feeder system chain. Audit details
- here means the general notion of who/where/when the information item to
- which the audit is attached was created. None of the attributes is defined
- as mandatory, however, in different scenarios, various combinations of
- attributes will usually be mandatory. This can be controlled by specifying
- feeder audit details in legacy archetypes. """
-
- systemId = TextLine(
- title=_(u'System Id'),
- description=_(u"""Identifier of the system which handled the
- information item."""),
- )
-
- provider = Object(
- schema=IPartyIdentified,
- title=_(u'Provider'),
- description=_(u"""Optional provider(s) who created, committed,
- forwarded or otherwise handled the item. Type ==
- PARTY_IDENTIFIED"""),
- required=False,
- )
-
- location = Object(
- schema=IPartyIdentified,
- title=_(u'Location'),
- description=_(u"""Identifier of the particular site/facility within an
- organisation which handled the item. For computability, this identifier
- needs to be e.g. a PKI identifier which can be included in the
- identifier list of the PARTY_IDENTIFIED object."""),
- required=False,
- )
-
- time = Object(
- schema=IDvDateTime,
- title=_(u'Time'),
- description=_(u"""Time of handling the item. For an originating time:
- DV_DATE_TIME system, this will be time of creation, for an intermediate
- feeder system, this will be a time of accession or other time of
- handling, where available."""),
- required=False,
- )
-
- subject = Object(
- schema=IPartyProxy,
- title=_(u'Subject'),
- description=_(u"""Identifiers for subject of the received information
- item."""),
- required=False,
- )
-
- versionId = TextLine(
- title=_(u'Version Id'),
- description=_(u"""Any identifier used in the system such as "interim",
- "final",
- or numeric versions if available."""),
- required=False,
- )
-
- def systemIdValid():
- u"""systemId is not None and systemId != '' """
-
-
-class IFeederAudit(Interface):
- """
- Audit and other meta-data for systems in the feeder chain.
- """
-
- originatingSystemAudit = Object(
- schema=IFeederAuditDetails,
- title=_(u"Originating System Audit"),
- description=_(u"""Any audit information for the information item from
- the originating system."""),
-
- )
-
- originatingSystemItemIds = List(
- value_type=Object(schema=IDvIdentifier),
- title=_(u"Originating System Item IDs"),
- description=_(u"""Identifiers used for the item in the originating
- system, e.g. filler and placer ids."""),
- required=False,
- )
-
-
- feederSystemAudit = Object(
- schema=IFeederAuditDetails,
- title=_(u"Feeder System Audit"),
- description=_(u"""Any audit information for the information item from
- the feeder system, if different from the originating system."""),
- required=False,
- )
-
- feederSystemItemIds = List(
- value_type=Object(schema=IDvIdentifier),
- title=_(u"Feeder System Item IDs"),
- description=_(u"""Identifiers used for the item in the feeder system,
- where the feeder system is distinct from the originating system. The
- List contents are restricted to type == DvIdentifiers"""),
- required=False,
- )
-
- originalContent=Object(
- schema=IDvEncapsulated,
- title=_(u"Original Content"),
- description=_(u""" """),
- required=False,
- )
-
- def originatingSystemAuditValid():
- """ originatingSystemAudit is not None """
-
-
-class IArchetyped(Interface):
- """
- Archetypes act as the configuration basis for the particular structures of
- instances defined by the reference model. To enable archetypes to be used
- to create valid data, key classes in the reference model act as "root"
- points for archetyping; accordingly, these classes have the
- archetype_details attribute set. An instance of the class ARCHETYPED
- contains the relevant archetype identification information, allowing
- generating archetypes to be matched up with data instances """
-
- archetypeId = Object(
- schema=IArchetypeId,
- title=_(u"Archetype ID"),
- description=_(u"Globally unique archetype identifier."),
- )
-
- templateId = Object(
- schema=ITemplateId,
- title=_(u"Template ID"),
- description=_(u"""Globally unique template identifier, if a template
- was active at this point in the structure. Normally, a template would
- only be used at the top of a top-level structure, but the possibility
- exists for templates at lower levels."""),
- required=False,
- )
-
- rmVersion = TextLine(
- title=_(u"RM Version"),
- description=_(u"""Version of the openEHR reference model used to create
- this object. Expressed in terms of the release version string, e.g.
- "1.0", "1.2.4". """),
- )
-
- def archetypeIdValid():
- """ archetypeId is not None """
-
- def rmVersionValid():
- """ rmVersion is not None and rmVersion != '' """
-
-
-class IPathable(Interface):
- """
- Abstract parent of all classes whose instances are reachable by paths, and
- which know how to locate child object by paths. The parent feature may be
- implemented as a function or attribute.
-
- The two attributes required for locatable in Grok is __parent__ and
- __name__. We inherit those from grok.Model.
-
- The functionality to get paths and find children is contained in the
- traversal mechanism. """
-
- def pathOfItem(an_item):
- """
- The path to an item relative to the root of this archetyped structure.
-
- getPath is from the Traversal API.
- """
-
- def itemAtPath(a_path):
- """
- The item at a path (relative to this item);only valid for unique paths,
- i.e. paths that resolve to a single item. a_path is a string. Return
- a_path is not None and pathUnique(a_path)
-
- If the path is not unique or not found then a TraversalError is raised.
- """
-
- def itemsAtPath(a_path):
- """
- List of items corresponding to a non-unique path.
- a_path is a List
- Return a_path is not None and pathUnique(a_path)
- """
-
- def pathExists(a_path):
- """
- True if the path exists in the data with respect to the current item.
- Return a_path is not None and a_path != ''
- """
-
- def pathUnique(a_path):
- """
- True if the path corresponds to a single item in the data.
- Return a_path is not None and pathExists(a_path)
- """
-
-
-class ILocatable(Interface):
- u"""
- Root class of all information model classes that can be archetyped.
- """
-
-
- uid = Object(
- schema=IUidBasedId,
- title=_(u"UID"),
- description=_(u"Optional globally unique object identifier for root"
- " points of archetyped structures. A UidBasedId "),
- required=False,
- )
-
-
- archetypeNodeId = TextLine(
- title=_(u"Node ID"),
- description=_(u"""Design-time archetype id of this node taken from its
- generating archetype; used to build archetype paths. Always in the form
- of an "at" code, e.g. "at0005". This value enables a "standardised"
- name for this node to be generated, by referring to the generating
- archetype local ontology. At an archetype root point, the value of this
- attribute is always the stringified form of the archetype_id found in
- the archetype_details object."""),
- required=True)
-
- name = Object(
- schema=IDvText,
- title=_(u"Name"),
- description=_(u"""DvText type - Runtime name of this fragment, used to
- build runtime paths. This is the term provided via a clinical
- application or batch process to name this EHR construct: its retention
- in the EHR faithfully preserves the original label by which this entry
- was known to end. """),
-
- )
-
-
- archetypeDetails = Object(
- schema=IArchetyped,
- title=_(u"Archetype Details"),
- description=_(u"Details of archetyping used on this node."),
- required=False,
- )
-
- feederAudit = Object(
- schema=IFeederAudit,
- title=_(u"Feeder Audit"),
- description=_(u"""Audit trail from non-openEHR system of original
- commit of information forming the content of this node, or
- from a conversion gateway which has synthesised this node."""),
- required=False,
- )
-
-
- links = Set(
- value_type=Object(schema=ILink),
- title=_(u"Links"),
- description=_(u"""Audit trail from non-openEHR system of original
- commit of information forming the content of this node,
- or from a conversion gateway which has synthesised this
- node."""),
- required=False,
- )
-
- def isArchetypeRoot():
- u"""True if this node is the root of an archetyped structure."""
-
- def concept():
- u"""
- Clinical concept of the archetype as a whole (= derived from the
- 'archetype_node_id' of the root node) isArchetypeRoot must be True.
- """
-
- def nameValid():
- u""" name is not None"""
-
- def linksValid():
- u""" links is not None and links != []"""
-
- def archetypedValid():
- u""" isArchetypeRoot xor archetypeDetails = None """
-
- def archetypeNodeIdValid():
- u""" archetypeNodeId is not None and archetypeNodeId != '' """
-
-
-class IFeederAuditDetails(Interface):
- u"""
- Audit details for any system in a feeder system chain. Audit details here
- means the general notion of who/where/when the information item to which
- the audit is attached was created. None of the attributes is defined as
- mandatory, however, in different scenarios, various combinations of
- attributes will usually be mandatory. This can be controlled by specifying
- feeder audit details in legacy archetypes. """
-
- systemId = TextLine(
- title=_(u'System Id'),
- description=_(u"""Identifier of the system which handled the
- information item."""),
- )
-
- provider = Object(
- schema=IPartyIdentified,
- title=_(u'Provider'),
- description=_(u"""Optional provider(s) who created, committed,
- forwarded or otherwise handled the item. Type ==
- PARTY_IDENTIFIED"""),
- required=False,
- )
-
- location = Object(
- schema=IPartyIdentified,
- title=_(u'Location'),
- description=_(u"""Identifier of the particular site/facility within an
- organisation which handled the item. For computability, this identifier
- needs to be e.g. a PKI identifier which can be included in the
- identifier list of the PARTY_IDENTIFIED object."""),
- required=False,
- )
-
- time = Object(
- schema=IDvDateTime,
- title=_(u'Time'),
- description=_(u"""Time of handling the item. For an originating time:
- DV_DATE_TIME system, this will be time of creation, for an intermediate
- feeder system, this will be a time of accession or other time of
- handling, where available."""),
- required=False,
- )
-
- subject = Object(
- schema=IPartyProxy,
- title=_(u'Subject'),
- description=_(u"""Identifiers for subject of the received information
- item."""),
- required=False,
- )
-
- versionId = TextLine(
- title=_(u'Version Id'),
- description=_(u"""Any identifier used in the system such as "interim",
- "final",
- or numeric versions if available."""),
- required=False,
- )
-
- def systemIdValid():
- u"""systemId is not None and systemId != '' """
-
=== removed directory 'src/oship/rm/common/archetyped/tests'
=== removed file 'src/oship/rm/common/archetyped/tests/__init__.py'
=== removed directory 'src/oship/rm/common/change_control'
=== removed file 'src/oship/rm/common/change_control/__init__.py'
--- src/oship/rm/common/change_control/__init__.py 2010-08-01 16:37:49 +0000
+++ src/oship/rm/common/change_control/__init__.py 1970-01-01 00:00:00 +0000
@@ -1,214 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-
-import grok
-
-from oship.rm.support.identification import HierObjectId
-from interfaces import *
-
-class Contribution(grok.Container):
- u"""
- Documents a contribution of one or more versions added to a
- change-controlled repository. """
-
- grok.implements(IContribution)
-
- def __init__(self, uid, versions, audit):
- self.uid=uid
- self.versions=versions
- self.audit=audit
-
-
-
-class Version(grok.Model):
- u"""
- Abstract model of one Version within a Version container, containing
- data, commit audit trail, and the identifier of its Contribution.
- """
-
- grok.implements(IVersion)
-
- def __init__(self, uid, preVid, data, lcstate, caudit, contr, sig):
- self.uid=uid
- self.precedingVersionId=preVid
- self.data=data
- self.lifecycleState=lcstate
- self.commitAudit=caudit
- self.signature=sig
-
- def ownerId(self):
- return HierObjectId(self.uid.objectId().value)
-
- def isBranch(self):
- return self.uid.versionTreeId().isBranch()
-
- def canonicalForm(self):
- raise NotImplementedError
-
-
-
-class OriginalVersion(Version):
- u"""
- A Version containing locally created content and optional attestations.
- """
-
- grok.implements(IOriginalVersion)
-
- def __init__(self, uid, previd,otherInputVersionUids,data,attestations,lifecycleState,caudit,contribution,sig):
- Version.__init__(self,uid,previd,data,lifecycleState,caudit,contribution,sig)
- self.otherInputVersionUids=otherInputVersionUids
- self.attestations=attestations
-
- def isMerged(self):
- """
- True if this Version was created from more than
- just the preceding (checked out) version.
- """
-
-
-
-class ImportedVersion(Version):
- u"""
- A Version containing locally created content and optional attestations.
- """
- grok.implements(IImportedVersion)
-
- def __init__(self, item):
- self.item = item
-
-
-
-class VersionedObject(grok.Container):
- u"""
- Version control abstraction, defining semantics for versioning one
- complex object.
- """
-
- grok.implements(IVersionedObject)
-
- def __init__(self, uid, ownerId, timeCreated):
- super(VersionedObject, self).__init__()
- self.uid=uid
- self.ownerId=ownerId
- self.timeCreated=timeCreated
-
- def allVersions():
- u"""Return a list of all versionsin this object. List <VERSION<T>>"""
-
- def allVersionIds():
- u"""Return a list of ids of all versions in this object.
- List <OBJECT_VERSION_ID>"""
-
- def versionCount(self):
- return len(self)
-
- def hasVersionId(an_id):
- u"""Return True if an_id exists. Require an_id is not None
- and an_id != '' """
-
- def isOriginalVersion(an_id):
- u"""True if version with an_id is an ORIGINAL_VERSION.
- Require an_id is not None and hasVersionId(an_id)"""
-
- def hasVersionAtTime(a_time):
- u"""Return True if a version for time; 'a_time' exists.
- Require isinstance(a_time, datetime)."""
-
- def versionWithId(an_id):
- u"""Return the version with id of 'an_id'.
- Require hasVersionId(an_id)"""
-
- def versionAtTime(a_time):
- u"""Return the version for time 'a_time'.
- Require hasVersionAtTime(a_time)."""
-
- def latestVersion():
- u"""Return the most recently added version (i.e. on trunk
- or any branch)."""
-
- def latestTrunkVersion():
- u"""Return the most recently added trunk version."""
-
- def trunkLifecycleState():
- u"""Return the lifecycle state from the latest trunk version.
- Useful for determining if the version container is logically deleted.
- """
-
- def revisionHistory():
- u"""History of all audits and attestations in this versioned
- repository."""
-
- def commitOriginalVersion(self,newVersionUid,precedingVersionUid,data,lifecycleState,commitAudit,contribution,signingKey):
- v = OriginalVersion(newVersionUid,precedingVersionUid,None,data,None,lifecycleState,commitAudit,contribution,signingKey)
- self[newVersionUid.value] = v
-
- def commitOriginalMergedVersion():
- u"""Add a new original merged version. This commit function adds a
- parameter containing the ids of other versions merged into the
- current one.
-
- (a_contribution: OBJECT_REF;a_new_version_uid, a_preceding_version_uid:
- OBJECT_VERSION_ID; an_audit: AUDIT_DETAILS; a_lifecycle_state:
- DV_CODED_TEXT; a_data: T; an_other_input_uids:Set<OBJECT_VERSION_ID>;
- signing_key: String)
-
- Require
- Contribution_valid: a_contribution /= Void
- New_version_valid: a_new_version_uid /= Void
- Preceding_version_id_valid:
- all_version_ids.has(a_preceding_version_uid)
- or else version_count = 0
- audit_valid: an_audit /= Void
- data_valid: a_version_data /= Void
- lifecycle_state_valid: a_lifecycle_state /= Void
- Merge_input_ids_valid: an_other_input_uids /= Void
- """
-
- def commitImportedVersion(a_contribution, an_audit, a_version):
- u"""Add a new imported version. Details of version id etc come from the
- ORIGINAL_VERSION being committed.
-
- (a_contribution: OBJECT_REF; an_audit: AUDIT_DETAILS;
- a_version: ORIGINAL_VERSION<T>)
-
- Require
- Contribution_valid: a_contribution /= Void
- audit_valid: an_audit /= Void
- Version_valid: a_version /= Void
- """
-
- def commitAttestation(an_attestation, a_ver_id, signing_key):
- u"""Add a new attestation to a specified original version. Attestations
- can only be added to Original versions.
-
- an_attestation: ATTESTATION; a_ver_id: OBJECT_VERSION_ID; signing_key:
- String)
-
- Require
- Attestation_valid: an_attestation /= Void
- Version_id_valid: has_version_id(a_ver_id) and
- is_original_version(a_ver_id) """
-
- def uidValid():
- u"""uid is not None"""
-
- def ownerIdValid():
- u"""owner_id is not None"""
-
- def timeCreatedValid():
- u"""timeCreated is not None"""
-
- def versionCountValid():
- u"""versionCount >= 0"""
-
- def allVersionIdsValid():
- u"""allVersionIds is not None and allVersionIds.count = versionCount"""
-
- def allVersionsValid():
- u"""allVersions is not None and allVersions.count = versionCount"""
-
- def latestVersionValid():
- u"""versionCount > 0 implies latestVersion is not None"""
-
- def revisionHistoryValid():
- u"""revisionHistory is not None"""
=== removed file 'src/oship/rm/common/change_control/interfaces.py'
--- src/oship/rm/common/change_control/interfaces.py 2010-08-01 16:37:49 +0000
+++ src/oship/rm/common/change_control/interfaces.py 1970-01-01 00:00:00 +0000
@@ -1,341 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-
-from zope.interface import Interface
-from zope.schema import TextLine, Object, Field, List, Set
-from zope.i18nmessageid import MessageFactory
-import grok
-
-from oship.rm.support.interfaces import (IUidBasedId,
- IObjectRef, IObjectVersionId)
-from oship.rm.datatypes.text.interfaces import IDvCodedText
-from oship.rm.datatypes.quantity.datetime.interfaces import IDvDateTime
-from oship.rm.common.generic.interfaces import IAuditDetails, IAttestation
-
-
-_ = MessageFactory('osh