Package Gnumed :: Package business :: Module gmDevices |
[frames] | no frames]

# Source Code for Module Gnumed.business.gmDevices

      1  # -*- coding: utf8 -*-
      2  #======================================================================
      3  # GNUmed Device handling
      4  #
      5  # @copyright: author
      6  #======================================================================
      7  __version__ = "$Revision: 1.4 $"
      8  __author__ = "Sebastian Hilbert"
      9  __license__ = 'GPL v2 or later (details at http://www.gnu.org)'
     10
     11
     12  import sys, logging
     13
     14
     15  if __name__ == '__main__':
     16          sys.path.insert(0, '../../')
     17
     18  _log = logging.getLogger('gm.dev')
     19  _log.info(__version__)
     20  #======================================================================
     21  # XML cardiac device description parsing
     22  #----------------------------------------------------------------------
     23
     24
     25  # since those methods appear in a top-level generic file (gmDevices.py)
     26  # they need more specific names because things like drivers for
     27  # urinalyzers, ecg, spiro, ... all conceptually belong into gmDevices.py
     28
     29
     30  # Devices holds a list of all cardiac devices in the xml
     31  # each list item holds a device context ( generator and one or more leads )
     32  ##Devices = []
     33  # DeviceParts is the device context and holds one or more device parts. Each list item
     34  # is a device part such as lead , generator which in turn can consist of
     35  # device parts such as mainboard or battery
     36  ##DeviceParts = []
     37
     38 -def extractDevices(DevicesTree=None):
     39          Devices = []
     40          # sort device list, first ICD, then pacemaker, then disconnected devices
     41          for Device in DevicesTree:
     42                  Devices.append(Device)
     43          return Devices
     44
     45 -def sortDevicesByTypeAndStatus(Devices=None):
     46          # todo: sort later, for now return like order gotten from XML
     47          return Devices
     48
     49 -def extractDeviceParts(Device=None,Type=None):
     50          DeviceParts = []
     51          for DevicePart in Device:
     52                  if DevicePart.get("type") == Type:
     53                          DeviceParts.append(DevicePart)
     54          return DeviceParts
     55
     56 -def sortLeadsByPosition(Leads=None):
     57          #skips sorting for now
     58          return Leads
     59
     60 -def extractActions(DevicePart=None,Type=None):
     61          Actions = []
     62          # get a list of all procedures for this DevicePart
     63          for tag in DevicePart.getchildren():
     64                  if tag.get("type") == Type:
     65                          Actions.append(tag)
     66          return Actions
     67
     68 -def extractTagData(start_node=None,SearchTag=None):
     69          #tag = None
     70          for tag in start_node.getchildren():
     71                  if tag.tag==SearchTag:
     72                          return tag.text
     73
     74 -def extractTagAttribute(start_node=None,SearchTag=None,Attribute=None):
     75          for tag in start_node.getchildren():
     76                  if tag.tag == SearchTag:
     77                          return tag.get(Attribute)
     78
     79 -def device_status_as_text(tree=None):
     80          DevicesDict = {}
     81          DevicePartSpecsDict = {}
     82          DevicesDisplayed = []
     83
     84          """ In this area GNUmed will place the status of all cardiac devices and device parts.
     85          There can be more than one device at a time\n\n
     86          It potentially looks like this\n
     87          ----------------------------------------------------------------------------------------------------------------\n
     88          Device: SJM Atlas DR (active)     Battery: 2.4V (MOL)      Implanted:  Feb 09 2008\n\n
     89          RA: Medtronic Sprint fidelis (active, flaky, replacement)             Implanted: Feb 09 2008\n
     90          Sensing: 2 (1.5) mV    Threshold: 0.7/0.5 (1/0.4) V/ms       Impedance: 800 (900) Ohm\n\n
     91          RV: Medtronic Sprint fidelis (active, flaky, replacement)             Implanted: Feb 09 2008\n
     92          Sensing: 7 (15) mV    Threshold: 0.7/0.5 (1/0.4) V/ms       Impedance: 800 (900) Ohm\n\n
     93          LV: Medtronic Sprint fidelis (active, flaky, Y-connector)             Implanted: Feb 09 2008\n
     94          Sensing: 7 ( ?) mV    Threshold: 1/1.5 (1/1) V/ms       Impedance: 800 (900) Ohm\n
     95          ----------------------------------------------------------------------------------------------------------------\n
     96          Device: Medtronic Relia SR (inactive)     Battery 2.1V (EOL)   Implanted: Jan 23 2000\n\n
     97          Device: Medtronic Kappa SR (explanted)     Battery 2.1V (EOL)   Explanted: Jan 23 2000 (Jan 23 1995)\n
     98          -----------------------------------------------------------------------------------------------------------------\n
     99          RA Lead: Medtronic ? (inactive, capped)             Implanted: Jan 23 2000\n
    100          RV Lead: Medtronic ? (explanted)                        Explanted: Feb 09 2008
    101          """
    102          """
    103          first search for devices, produce a list,
    104          sort in active devices first, ICD befor pacemaker before disconnted devices
    105          per convention a single generator or lead which is not connected is a self contained device
    106          there are virtual devices such as 'ICD' or 'pacemaker' which consist of parts such as leads and generator
    107          there are true devices such as inactive leads or non-explanted generators
    108          class will be 'lead' instead of type 'lead' for DeviceParts
    109          """
    110
    111          DevicesTree = tree.getroot()
    112          Devices = extractDevices(DevicesTree)
    113          DevicesSorted = sortDevicesByTypeAndStatus(Devices)
    114          #print 'Number of devices: %s' %len(Devices)
    115
    116          for Device in DevicesSorted:
    117                  DevicesDisplayed.append('-------------------------------------------------------------\n')
    118                  # check for class
    119                  DeviceClass=Device.get("class")
    120                  if DeviceClass == 'ICD':
    121                          # get generator xml node
    122                          Generator = extractDeviceParts(Device=Device,Type='generator')[0]
    123                          # get generator vendor, model, devicestate
    124                          vendor = extractTagData(start_node=Generator,SearchTag='vendor')
    125                          model = extractTagData(start_node=Generator,SearchTag='model')
    126                          devicestate = extractTagData(start_node=Generator,SearchTag='devicestate')
    127                          # get subpart battery
    128                          battery = extractDeviceParts(Device=Generator,Type='battery')[0]
    129                          action = extractActions(DevicePart=battery,Type='interrogation')[0]
    130                          battery_voltage = extractTagData(start_node=action,SearchTag='voltage')
    131                          battery_voltage_unit = extractTagAttribute(start_node=action,SearchTag='voltage',Attribute='unit')
    132                          battery_status = extractTagData(start_node=action,SearchTag='status')
    133                          implantation_date= extractTagData(start_node=Generator,SearchTag='doi')
    134                          line = _('Device(%s):') %DeviceClass + ' ' + vendor + ' ' + model + ' ' + '('+ devicestate + ')'+'   '+_('Battery:')+' '+battery_voltage+' '+battery_voltage_unit+'('+battery_status+')'+'  '+_('Implanted:')+' '+implantation_date+'\n\n'
    135                          # append each line to a list, later produce display string by parsing list
    136                          DevicesDisplayed.append(line)
    137                          #DevicesDisplayed.append('\n')
    138                          # now get the leads, RA then RV and last LV if they exist
    139                          # todo: think about four leads : pace/sense but on another thought they both simply show up as RV leads
    140                          Leads = extractDeviceParts(Device=Device,Type='lead')
    141                          LeadsSorted = sortLeadsByPosition(Leads)
    142                          for Lead in LeadsSorted:
    143                                  leadposition = extractTagData(start_node=Lead,SearchTag='leadposition')
    144                                  leadslot = extractTagData(start_node=Lead,SearchTag='leadslot')
    145                                  vendor = extractTagData(start_node=Lead,SearchTag='manufacturer')
    146                                  model = extractTagData(start_node=Lead,SearchTag='model')
    147                                  devicestate = extractTagData(start_node=Lead,SearchTag='devicestate')
    148                                  comment = extractTagData(start_node=Lead,SearchTag='comment')
    149                                  implantation_date = extractTagData(start_node=Lead,SearchTag='doi')
    150                                  line = '%s-lead in %s-position:' %(leadposition,leadslot) + ' ' + vendor + ' ' + model + ' ' + '(' + devicestate + ',' + comment + ')' + ' ' + 'Implanted:' + ' ' + implantation_date +'\n'
    151                                  DevicesDisplayed.append(line)
    152                                  #now get the newest interrogation
    153                                  action = extractActions(DevicePart=Lead,Type='interrogation')[0]
    154                                  action_date = extractTagData(start_node=action,SearchTag='dop')
    155                                  sensing = extractTagData(start_node=action,SearchTag='sensing')
    156                                  sensingunit = extractTagAttribute(start_node=action,SearchTag='sensing',Attribute='unit')
    157                                  threshold = extractTagData(start_node=action,SearchTag='thresholdvoltage')
    158                                  thresholdunit = extractTagAttribute(start_node=action,SearchTag='thresholdvoltage',Attribute='unit')
    159                                  impedance = extractTagData(start_node=action,SearchTag='impedance')
    160                                  impedanceunit = extractTagAttribute(start_node=action,SearchTag='impedance',Attribute='unit')
    161                                  line = _('last check:')+' '+action_date+' '+_('Sensing:')+' '+sensing+sensingunit+' '+_('Threshold')+' '+threshold+thresholdunit+' '+_('Impedance:')+' '+impedance+' '+impedanceunit+'\n\n'
    162                                  DevicesDisplayed.append(line)
    163
    164          return DevicesDisplayed
    165
    166  #======================================================================
    167  # main - unit testing
    168  #----------------------------------------------------------------------
    169  if __name__ == '__main__':
    170
    171          from lxml import etree
    172
    173          from Gnumed.pycommon import gmI18N
    174          gmI18N.activate_locale()
    175          gmI18N.install_domain()
    176
    177          if len(sys.argv) > 1 and sys.argv[1] == 'test':
    178
    179                  #----------------------------------------------------
    180 -                def test_parsing_cardio_dev_state():
    181                          # for now assume that the xml file provide the cardiac device context.
    182                          # that pretty much means logical connection of leads and generator is provided in the xml
    183                          print "parsing device status from XML file:", sys.argv[2]
    184                          xml_device_desc = etree.parse(sys.argv[2])
    185                          formatted_device_status = device_status_as_text(xml_device_desc)
    186                          for line in formatted_device_status:
    187                                  print line
    188                  #----------------------------------------------------
    189
    190                  test_parsing_cardio_dev_state()
    191
    192  #======================================================================
    193  # $Log: gmDevices.py,v $
    194  # Revision 1.4  2009-07-16 09:51:16  ncq
    195  # - cleanup and better naming
    196  #
    197  # Revision 1.3  2009/07/15 18:07:25  shilbert
    198  # - cleanup
    199  #
    200  # Revision 1.2  2009/07/15 12:09:59  ncq
    201  # - some cleanup
    202  #
    203  #
    204