This is Info file appman.info, produced by Makeinfo-1.64 from the input file appman.texi. This text describes the concepts, operation, and maintenance of the ProtoGen/HL7 interface to HP's clinical information system CareVue as well as the ASTM to HL7 converter for the acid base laboratory Radiometer ABL 500 and 600 series. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation. Copyright (C) 1996 Gunther Schadow  File: appman.info, Node: Units, Next: Hosts, Prev: LOINC, Up: Databases The Code for Units of Measure ============================= When measurements are communicated any expression that does specify only the value and not the unit of the measure is incomplete and therefore meaningless, even though this incomplete communication is quite common especially in the medical field. By stating that the blood glucose level of a patient measures "80", some experienced health care professional will probably know that we are talking of "80 mg/dl", but the statement is nevertheless incomplete. Experienced human mind is capable of filling in informational gaps, however, computers cannot do so and it is therefore essential to the correct report of measurements to take care of the units. Since units are algebraic terms it is pretty useless for a unit code to only list "all" possible ("defined") such terms of a code of units. It is just as bad to allow any string of characters to count as a unit. A unit has a special semantic meaning that can be expressed in numerical terms quite easily, compared with the difficulties in building a semantic system of other medical terms. Each unit is expressed as a coefficient and a vector of basic units. Thus, it is possible to define algebraic operations on units, like multiplication, division and exponentiation with an integer number. Units can be easily compared for commensurability and measures can be converted to other commensurable units: if the vector of base units is the same, the units are commensurable (of same dimension) and the conversion is simply done by multiplying the value of the measurement with the quotient of the coefficient parts of the respective units. The Vector of Basic Measures ---------------------------- The base unit vector tries to enclose any measured phenomena while seeking minimality. The elements of the base unit vector are integer numbers which denote the exponent under which the corresponding basic measure counts to the derived measure. Consider a simple base vector [L, T] that is made up only of length (L) and time (T), at least the following measures can be expressed: Measure Vector ------------- ------- 1 [ 0, 0] length [ 1, 0] area [ 2, 0] volume [ 3, 0] time [ 0, 1] velocity [ 1,-1] acceleration [ 1,-2] fluid current [ 3,-1] ... ... The operations on these classes of vectors are: Addition and subtraction, which means multiplication resp. division of measures; and multiplication of a vector with a scalar (integer) n which means the n-th potence of the measure. The example below shows the calculation of the acceleration vector: acceleration = length / time ^ 2 = [ 1, 0] - [ 0, 1] * 2 = [ 1, 0] - [ 0, 2] = [ 1,-2] Minimality is the reason why the concept of SI base units had to be left almost completely. SI base units are the following: Measure Unit ----------------------------- ------- ----------- length m meter mass kg kilogram time s second electric current A Amp`ere thermodynamic temperature K Kelvin amount of substance mol mole luminous intensity cd candela While there are no problems with length, time and temperature, it is certainly not useful to have a prefix `kilo' in a base unit as it is the case with mass. The reason for this is consistency with the rules of prefixing: If we would accept kg as a base unit, we had to allow 1kkg = 1Mg and 1mkg = 1g which is certainly not correct. Thus I decided to use the Gram (g) as the base unit for mass. It might be just for my personal taste that I use the charge as the base unit of electrical phenomena instead of currency: it is the electron resp. the elementary *charge* that all electrical phenomena are based on. Since the amount of substance represents just the number of particles, it is in fact a dimensionless measure (see `The Feynman Lectures on Physics p.39-10'). The mole will therefore be defined later as a pseudo-unit equal to Avogadro's number. Finally, I am not yet finished with luminous intensity and I am thinking about dropping it as a base unit. Since the luminous phenomenon is either just another electromagnetic phenomenon or it belongs into the sensory physiology just like the intensity of sound. Since I'm not yet aware of the implications of the candela as a base unit, I'll leave it untouched for the time being. The following table shows the basic measures as I will use them here: Measure Unit ----------------------------- ------- ----------- length m meter time s second mass g gram electrical charge C Coulomb thermodynamic temperature K Kelvin luminous intensity cd candela angle circ Circle As can be seen, I admitted the angle to the list of basic measures. Otherwise I see no way how to be aware of the incommensurability of steradian and radian (1sr = 1rad^2). The angle is measured in whole circles, thus 360deg = 1circ is true. * Menu: * units.tab:: The Table of Units * unitmgr:: Managing the Database of Units  File: appman.info, Node: units.tab, Next: unitmgr, Prev: Units, Up: Units The Table of Units ------------------ Description ........... The table of units defines new units in terms of previously defined units. A term of units is expressed according to the ISO standard 2955 using the following operators: `.' multiplication `/' division The exponentiation is expressed by writing an (integer) number directly behind the units symbol, e.g. a cubic meter is expressed as `m2'. Negative exponents are allowed by writing a `-' in front of the number. The use of parentheses to overcome left to right association is not allowed. Thus, the Newton is defined as `kg/m/s2'. Note that because there are no parentheses and operators strictly associate left to right, `kg/m.s2' is not a correct representation for the Newton. Using negative exponents `kg.m-1.s-2' is again the Newton. Parentheses in units are a part of the unit symbol itself. Thus, `m(H2O)' is an allowed unit symbol that can be defined distinct from `m(Hg)' and the base unit of length `m'. The following basic units are predefined: SYMBOL BASE UNIT VECTOR M E -------- ---------------------- -- -- m [ 1, 0, 0, 0, 0, 0, 0] 1 0 s [ 0, 1, 0, 0, 0, 0, 0] 1 0 g [ 0, 0, 1, 0, 0, 0, 0] 1 0 c [ 0, 0, 0, 1, 0, 0, 0] 1 0 k [ 0, 0, 0, 0, 1, 0, 0] 1 0 cd [ 0, 0, 0, 0, 0, 1, 0] 1 0 circ [ 0, 0, 0, 0, 0, 0, 1] 1 0 1 [ 0, 0, 0, 0, 0, 0, 0] 1 0 10* [ 0, 0, 0, 0, 0, 0, 0] 1 1 In the above table the attribute `M' is the mantissa and `E' is the exponent of logarithmical representation of the coefficient to the base 10. A unit symbol may be prepended by a prefix symbol. However, it is important that the combination of prefix and unit does not interfere with another combination of a prefix and a unit. The symbols are interpreted case insensitive according to ISO 2955. This is the reason, why the symbols for prefices as well as for the units slightly differ from the normal SI symbols. The following prefices may be used: `ex' exa 10^18 `pe' peta 10^15 `t' tera 10^12 `g' giga 10^9 `ma' mega 10^6 `k' kilo 10^3 `h' hecto 10^2 `da' deka 2, 1 `d' deci 10^-1 `c' centi 10^-2 `m' milli 10^-3 `u' micro 10^-6 `n' nano 10^-9 `p' pico 10^-12 `f' femto 10^-15 `a' atto 10^-18 Beside the proportional conversions, i.e. those where conversion is performed simply by multiplication with a conversion coefficient, a limited set of non-proportional conversions is supported. This is used for logarithmic units like *pH* or *db* as well as for conversions of temperature scales of Celsius, Kelvin and Fahrenheit. Proportional conversions are defined as NEW_UNIT = NUMBER KNOWN_UNIT while non-proportional conversions are defined as NEW_UNIT = FUNCTION_NAME(NUMBER KNOWN_UNIT) where FUNCTION_NAME must be a name known at compile time. Working with functions is a bit tricky and limits the applicability of the unit in conversions. Therefore the general rule is to avoid functions where possible. If not avoidable define new functions as follows: 1. define a pair of functions in the C++ source `cnv_func_tab.cc' and recompile/relink 2. edit the table of units 3. run through `unitmgr' to remake the database Functions are applied as follows: If the table states: foo = foo_f(12.3 bar) a given foo (F) is converted to bar (B) as: B = foo_from(F) * ( 12.3 bar ) and if a bar (B) is given, we get the foo (F) by: F = foo_to(B / ( 12.3 bar )) Comment lines starting with a number sign (`#') are allowed as well as blank lines. Examples ........ The following is the current contents of the file `units.tab'. # Pseudo Units, i.e. those whose dimension is 1 % = 1 10*-2 # percent # Angle rad = 1.5915494309189533577 10*-1.circ # radian sr = 4.0528473456935108578 10*-1.circ+2 # steradian deg = 2.7777777777777777778 10*-3.circ # degree (angular) mnt = 1.6666666666666666667 10*-2.deg # angular minute # Space l = 1 dm3 # liter # Time hr = 3.6 10*3.s # hour min = 6 10*1.s # minute d = 8.64 10*4.s # day ann = 3.1536 10*7.s # year hz = 1 /s # Herz # Mechanics n = 1 kg.m/s2 # Newton p = 9.80665 g.m/s2 # pond j = 1 n.m # Joule cal = 4.1868 j # calorie w = 1 j/s # Watt pal = 1 n/m2 # Pascal bar = 1 10*5.pal # bar m(h2o) = 9.806650 kpal # meter of water column m(hg) = 133.3220 kpal # meter of mercury column # Temperature cel = cel_f(1 k) # degree Celsius degf = degf_f(0.5555555555555555556 k) # degree Fahrenheit # Electromagnetism a = 1 c/s # Ampere v = 1 j/c # Volt ohm = 1 v/a # Ohm sie = 1 a/v # Siemens f = 1 c/v # Farad wb = 1 v.s # Weber (magnetic flux) t = 1 wb/m2 # Tesla (magnetic inductance) hy = 1 wb/a # Henry (inductance) # Nuclear/Atomic/Molecular/Chemical mol = 6.022137 10*23 # mole -- Avogadro's number val = 6.022137 10*23 # val -- equivalents eq = 6.022137 10*23 # equivalents ph = ph_f(1 mol/l) # pH e = 1.6021892 10*-19.c # elementary charge ev = 1.602177 10*-19.j # electronvolt u = 1.6605655 10*-24.g # atomic mass unit bq = 1 1/s # Bequerel (activity) gy = 1 j/s # Gray (energy dose) # Biological/Biochemical/Medical Units sv(a) = 0.04 gy # Sievert (alpha rays) sv(b) = 1 gy # Sievert (beta rays) sv(g) = 1 gy # Sievert (gamma rays) sv(x) = 1 gy # Sievert (X-rays) sv(n) = 0.2 gy # Sievert (neutrons) sv(p) = 0.1 gy # Sievert (protons) tot = 1 1 # particles total count cfu = 1 1 # colony forming units ppm = 1 10*-6 # parts per million ppb = 1 10*-9 # parts per billion iu = 1 1 # international units kat = 1 mol/s # katal # Photometric Units lm = 1 cd/sr # lumen (luminous flux) lx = 1 lm/m2 # lux # Levels bel = f_ln(1 1) # bel db(spl) = f_20_lg(2 10*-5.pal) # decibel sound pressure db(v) = f_20_lg(1 v) # decibel volts db(mv) = f_20_lg(1 mv) # decibel millivolts db(uv) = f_20_lg(1 uv) # decibel mycrovolts db(w) = f_10_lg(1 w) # decibel watts db(kw) = f_10_lg(1 kw) # decibel kilowatts Files ..... `/usr/hl7/etc/units.tab' the source text of the units database `/usr/hl7/lib/codes/units.db' the compiled, hashed file of the units database See Also ........ *Note unitmgr::  File: appman.info, Node: unitmgr, Prev: units.tab, Up: Units Managing the Database of Units ------------------------------ Synopsis ........ unitmgr FILE Description ........... The `uinitmgr' program is the "manager" of the database of units and does nothing else than to create a new database `/usr/hl7/lib/codes/units.db' and inserts the definition found in the definition FILE. All previous contents in the database is lost. Examples ........ unitmgr /usr/hl7/etc/units.tab Environment ........... `PG_CODELIB' The location of the external code databases for LOINC, LabEventInfo and units. This is rarely used, since everyone uses the names compiled into the programs. Files ..... `/usr/hl7/etc/units.tab' the source text of the units database `/usr/hl7/lib/codes/units.db' the compiled, hashed file of the units database `./units.log' the run logfile Bugs .... Writing errors to the logfile is not useful since this is a program that is normally invoked manually by an operator. Diagnostics ........... See the file `./units.log' for error messages See Also ........ *Note units.tab::.  File: appman.info, Node: Hosts, Prev: Units, Up: Databases Users and Hosts =============== * Menu: * hl7hosts:: Access Control for Networked ProtoGen Applications * carevuehost:: Configuring the CareVue Host  File: appman.info, Node: hl7hosts, Next: carevuehost, Prev: Hosts, Up: Hosts Access Control for Networked ProtoGen Applications -------------------------------------------------- Description ........... As soon as HL7 communication involves networks, security is an issue. We do not want everybody in the world to admit or discharge patients, nor do we allow any site in our institution to send any type of a message. In order to control access to the TCP/IP networked HL7 services, a special access control list is used that allows to specify access to services depending on: 1. remote host address 2. connection id token (exchanged in the ILLP, see *Note ILLP::) 3. sending application 4. sending facility 5. receiving application 6. receiving facility 7. list of allowed or forbidden message/evet types The `hl7hosts' file is a simple table where each line represents one access control entry that specifies the above attributes. Fields are separated by blank characters. Comment lines starting with a number sign (`#') are allowed as well as blank lines. Lines that start with a blank character (i.e. space or tab) are continuations of the preceding line. Asterisks (`*') allow any value to match the respective attribute. Lists of message types are specified using the `MESSAGE^EVENT' notation each entry of the list separated by blanks. The first entry of the list may have a `+' or `-' prepended specifying the sense of the list: a `+' means that the list specifies allowed messages while the `-' means that all message except those specified are allowed. No sign implies `+' and an empty list at all means all message types. Examples ........ # host cid SenApp SenFac RecApp RecFac Messages #-------- --- -------- -------- --------- -------- ----------------- localhost * TEST_APP TEST_FAC * * NMD localhost * * * * * uks3p * * * NSERVER ANAE +NMD ORU uks3p * * * CVGATEWAY 060_IOP uks3p * * * * * +NMD ACK ADT^A01 ADT^A02 ADT^A03 ORU * * * * HL7TEST * Files ..... `/usr/hl7/etc/hl7hosts' the file described here `/usr/hl7/lib/ANYmsg/ANYmsg.conf' the list of configured message types that are handled at all See Also ........ *Note cvgateway::.  File: appman.info, Node: carevuehost, Prev: hl7hosts, Up: Hosts Configuring the CareVue Host ---------------------------- Description ........... There are certain preparations necessary in order to run the CareVue interface application correctly that are summarized here: 1. Edit the file `/usr/hl7/etc/carevuehost' to contain one line of text, specifying the host which is to be connected for access to CareVue's tools and databases. 2. Edit the file `/usr/hl7/etc/carevue' to contain one line of text, specifying the login name and the host which is to be connected for access to CareVue's tools and databases. Use the notation of a simple ARPA domain e-mail address, e.g. `LOGIN@HOST'. 3. Edit the file `/usr/hl7/etc/admin' to contain one line of text, specifying the e-mail address of an administrator who will receive error and warning reports by mail. 4. Make sure the user who runs the ProtoGen interface programs may log into the CareVue account specified in the file `/usr/hl7/etc/carevue'. You might need an `.rhosts' entry in the home directory of that account. 5. Copy the file `new_wt_ht_bsa' to the home directory of the CareVue account and make it executable. This can be used to test the functionality of the account, by copying with rcp(1). rcp new_wt_ht_bsa `cat /usr/hl7/etc/carevue`: 6. Configure the `/usr/hl7/etc/hl7hosts' file to match the minimal set of users of the HL7 services. 7. Configure the FSISERVER and FSICLIENT of the CareVue system using the following dbload script: INSERT AsyncLinkCfg EntityId = ASNYC_ENTITY WITH VALUES type = "ASYNC", flowCtrlEnabled = NULL, maxRcvMsgQSize = NULL, devicepath = "/dev/fsiad", primaryStation = "TRUE", binaryMode = "FALSE", bccType = "LRC", crcFormat = "HEX", baudRate = "9600", stopBits = "1", dataBits = "8", blocksize = 1024, responseTimeout = 0, receiveTimeout = 0, grossTimeout = 0, bidRespTimeout = 0, bidRetries = 60, blockRetries = 3, blockNumEnabled = "FALSE", bidACKN = "FALSE", blockACKN = "FALSE"; INSERT HL7ProtoCfg | INSERT HL7ProtoCfg EntityId = ADT_ENTITY | EntityId = CLI_ENTITY WITH VALUES | WITH VALUES type = "HL7", | type = "HL7", applServiceCode = "ADT", | applServiceCode = "CLI", localApplEndPoint = NULL, | localApplEndPoint = NULL, localApplSystemId = NULL, | localApplSystemId = NULL, version = NULL, | version = NULL, remoteAppl = NULL, | remoteAppl = NULL, remoteFacility = NULL, | remoteFacility = NULL, inhibitACK = "FALSE", | inhibitACK = "FALSE", responseTimeout = 60, | responseTimeout = 60, retries = 60, | retries = 60, retryDelay = 60, | retryDelay = 60, nmdXmtEnabled = "FALSE", | nmdXmtEnabled = "FALSE", nmdRcvExpected = "FALSE", | nmdRcvExpected = "FALSE", nmdPeriod = 0, | nmdPeriod = 0, xmtNmdForSystem = "FALSE", | xmtNmdForSystem = "FALSE", maxZdmFields = 15; | maxZdmFields = 15; INSERT FsiConfig EntityId = C958E1:1 WITH VALUES linkProtocol = ASYNC_ENTITY, applProtocols[0] = ADT_ENTITY, applProtocols[1] = CLI_ENTITY; 8. If you are going to use ADT application configure the ZDM segment as described in *Note ADT::. 9. If you are going to use CLI results reporting configure the file `LabEventInfo.tab' and issue the following commands: LabEventInfoMgr -c LabEventInfo.tab LabEventInfoMgr -M > LabEventMap.idb Use an editor in order to prepend the three lines of idb commands to the file `LabEventMap.idb' and remove the invalid INSERT statements for the ADT observations as described in *Note LabEventInfoMgr::. 10. Activate the changes made to the CareVue system 11. Set up the services to be started by init(8) in the background using `/etc/ttys' or `/etc/inittab'. `/etc/ttys': # 1. CareVue FSI Interface carevuefsi "/usr/hl7/bin/llpdrv -yaIt /dev/cuaa0 -i discard%localhost -i" unknow n on # 2. CareVue HL7 Gateway 060_IOP "/usr/hl7/bin/cvgateway carevuehl7 carevuefsi localhost" unknown on # 3. Serial lines to the ABL625 ttyd1 "/usr/hl7/bin/radioshell 6 -" unknown on # 3. Serial lines to the ABL300 ttyd2 "/usr/hl7/bin/radioshell 3 -" unknown on 12. Ensure that the service names of the services you used above in the file `/etc/services' are defined in accordance with other remote hosts that will use these services. `/etc/services': carevuehl7 99999/tcp carevuefsi 99998/tcp 13. Set up the ProtoGen user's crontab(5) to perform regular jobs like `hl7tocv'. */1 * * * * hl7tocv batch See Also ........ `rcp(1)', `init(8)', `ttys(5)', `cron(8)', `crontab(1)', `crontab(5)'.