Forum Replies Created
-
AuthorReplies
-
Good Luck Jim. I enjoyed chatting with you over the last 15 years.
Jim,
What version of Cloverleaf are you using? I am comparing the screen shots to mine install of 5.7. I’ll be upgrading soon, before I have to get https working.
We’ve moved away from smat files. We save off trace files that we access via Slunk. Implementing Splunk is alittle like loading the data to a SQL database for folks to access. Splunk allows for freezing older data that can still be retrieved. Using Splunk allows coworkers to simply access a url to search data going into or out of Cloverleaf, greating simplifying testing efforts and freeing up my time.
I’ve worked on Corepoint interface engines and Rhapsody interface engines where data logging is nicely built in and there are great search capabilities accross interfaces.
Here is our proc to save off trace files. We put this in the Inbound or Outbound TPS proc. We pass the directory/file as an argument.
proc save_message_to_file { args } {
keylget args MODE mode ;# Fetch mode
switch -exact — $mode {
start {
# Perform special init functions
# N.B.: may or may not be a MSGID key
}
run {
# ‘run’ mode always has a MSGID; fetch and process it
keylget args MSGID mh
keylget args ARGS uarg
set SAVEFILE [ open [ keylget uarg SAVEFILE] a ]
puts $SAVEFILE [msgget $mh]
close $SAVEFILE
return “{CONTINUE $mh}”
}
shutdown {
# Doing some clean-up work
}
default {
error “Unknown mode ‘$mode’ in just_print_message”
}
}
}
I like your idea of using the AND alert. I use an alternate alert file for holidays. I’d like to experiment with your idea and would appreciate getting a copy of your Tcl and holiday file.
Thanks
Keith, you are always doing interesting cool stuff.
March 16, 2012 at 11:19 pm in reply to: Is there a size limit to temporary variables inside Xlate? #76218Chris,
Thanks so much for your assistance.
I made the change to the outbound variant, even though I was convinced it had to do with the temporary variable. Lo and Behold it worked. I knew I was exceeding 5000 characters (used Word’s character count function) and that I would have to change the variant to accomodate that, but I was fixated on the temporary variable being a issue also. So now I am mystified by how changing the outbound variant changed the behavior of an internal temporary variable. I will have to repeat all my steps to confrm it really did or prove I simply wasn’t looking at it right.
Thanks again.
March 16, 2012 at 10:03 pm in reply to: Is there a size limit to temporary variables inside Xlate? #76216Chris, I did check the size of the field in my outbound variant:
00573 Observation Value
I do not see how to set it to -1 via the queue tool. Would I have to edit the format definition under $HCIROOT? I am running QDX 5.7.
March 16, 2012 at 9:58 pm in reply to: Is there a size limit to temporary variables inside Xlate? #76215The outbound variant is not my restriction. it is the temporary variable I have defined to use during my translation.
I am looping through OBX segments, concatenating all OBX.5’s into one temporary variable so that I can write it out to one outbound OBX. When I put in echos in my TCL fragment and I can see that the temp variable, @secondOBX, truncates the accumulating OBX.5 text. I have coded up a preprocessing script using grm-code and will test that soon. I am concerned that this is a TCL issue and the temporary variable won’t hold the number of characters I need – 5000.
Here is my Translation:
prologue
xlt_infile: hl7 2.6 hie ORU_R01
who: spcekp
date: March 16, 2012 1:24:02 PM MST
xlt_outfile: hl7 2.6 hie ORU_R01
type: xlt
version: 7.0
end_prologue
{ { OP COMMENT }
{ COMMENT {****************************** GENERAL INFORMATION ************************************} }
}
{ { OP COMMENT }
{ COMMENT {Epic ORU_R01 results to Epic.} }
}
{ { OP COMMENT }
{ COMMENT {Author: Lucy Maupin Date: 02/03/11} }
}
{ { OP COMMENT }
{ COMMENT {PREPROCESSING PROC: remove_amper} }
}
{ { OP COMMENT }
{ COMMENT {*************************************** Modifications ************************************************} }
}
{ { OP COMMENT }
{ COMMENT {Date Modifier Requester Task ID Change Detail} }
}
{ { OP COMMENT }
{ COMMENT {08/30/2011 Connie Kraska
Deb Ingraham Initial Install.} }
}
{ { OP COMMENT }
{ COMMENT {02/07/2011 Connie Kraska Greg Wikstrom Addendums need to append after the report on OBX 2} }
}
{ { OP COMMENT }
{ COMMENT {02/24/2012 Connie Kraska Ric Guzman Changed logic so that the impression component } }
}
{ { OP COMMENT }
{ COMMENT { of an addendum presents first in OBX(0). Had to use} }
}
{ { OP COMMENT }
{ COMMENT { OBX.3 in logic which forces use of preprocessing proc} }
}
{ { OP COMMENT }
{ COMMENT { remove_amper; which replaces & with ‘and’.} }
}
{ { OP COMMENT }
{ COMMENT {03/24/2012 Connie Kraska Ric Guzman Added Addendum literal to OBX(0)
} }
}
{ { OP COMMENT }
{ COMMENT { when ever there is a ADT.1 segment.
} }
}
{ { OP BULKCOPY }
{ ERR 0 }
}
{ { OP COMMENT }
{ COMMENT {Sending Application.} }
}
{ { OP COPY }
{ ERR 0 }
{ IN =EPIC }
{ OUT 0(0).MSH.00003 }
}
{ { OP COMMENT }
{ COMMENT {Sending Facility.} }
}
{ { OP COPY }
{ ERR 0 }
{ IN =TMC }
{ OUT 0(0).MSH.00004 }
}
{ { OP COMMENT }
{ COMMENT {Receiving Application} }
}
{ { OP COPY }
{ ERR 0 }
{ IN =HIE }
{ OUT 0(0).MSH(0).00005(0) }
}
{ { OP COMMENT }
{ COMMENT {Recieving Facility.} }
}
{ { OP COPY }
{ ERR 0 }
{ IN =Axolotl }
{ OUT 0(0).MSH(0).00006(0) }
}
{ { OP COMMENT }
{ COMMENT {Set up temporary variables for holding data as loop through OBXs} }
}
{ { OP COPY }
{ ERR 0 }
{ IN {=\.br\} }
{ OUT @firstOBX }
}
{ { OP COPY }
{ ERR 0 }
{ IN {=\.br\} }
{ OUT @secondOBX }
}
{ { OP COPY }
{ ERR 0 }
{ IN =N }
{ OUT @addendumflag }
}
{ { OP COMMENT }
{ COMMENT {Loop through OBXs and retrieve text} }
}
{ { OP ITERATE }
{ BASIS 1(0).1(0).1(0).OBX }
{ VAR %f1 }
{ TYPE segment }
{ BODY {
{ { OP COMMENT }
{ COMMENT {1) Retrieve Impression text (IMP.2)which will go in first OBX } }
}
{ { OP COMMENT }
{ COMMENT {2) Retrieve Addendum Impression text (ADT.1 )} }
}
{ { OP COMMENT }
{ COMMENT { both of which which will go in first OBX } }
}
{ { OP CALL }
{ ERR 0 }
{ IN {@firstOBX 1(0).1(0).1(0).OBX(%f1).#3(0) 1(0).1(0).1(0).OBX(%f1).#4(0) 1(0).1(0).1(0).OBX(%f1).#5(0)} }
{ OUT {@firstOBX @addendumflag} }
{ TCL {
set textin [lindex $xlateInVals 0]
set observ_id [lindex $xlateInVals 1]
set observ_subid [lindex $xlateInVals 2]
set observ_text [lindex $xlateInVals 3]
set cr \.br\
set firstOBX $textin$cr$observ_text
#echo “OBX0 $firstOBX”
# building the first OBX with ADT.1’s and IMP.2’s
if { ([cequal $observ_id “andADT”]) && ([cequal $observ_subid “1”]) } {
xpmstore $xlateId [lindex $xlateOutList 0] d -c $firstOBX
xpmstore $xlateId [lindex $xlateOutList 1] d -c “Y”
} elseif {([cequal $observ_id “andIMP”]) && ([cequal $observ_subid “2”]) } {
xpmstore $xlateId [lindex $xlateOutList 0] d -c $firstOBX
}
}}
}
{ { OP COMMENT }
{ COMMENT {4) Retrieve report text (IMP.!2, ADT.!1, all GDT) which will go in second OBX} }
}
{ { OP CALL }
{ ERR 0 }
{ IN {@secondOBX 1(0).1(0).1(0).OBX(%f1).#3(0) 1(0).1(0).1(0).OBX(%f1).#4(0) 1(0).1(0).1(0).OBX(%f1).#5(0)} }
{ OUT @secondOBX }
{ TCL {
set textin [lindex $xlateInVals 0]
set observ_id [lindex $xlateInVals 1]
set observ_subid [lindex $xlateInVals 2]
set observ_text [lindex $xlateInVals 3]
#echo “ID $observ_id SUBID $observ_subid TEXT $observ_text”
set cr \.br\
set secondOBX $textin$cr$observ_text
# building the second OBX with all GDT, ADT not 1, and IMP not 2
if { ([cequal $observ_id “andGDT”] ) ||
(([cequal $observ_id “andADT”] && ![cequal $observ_subid “1”]) ||
([cequal $observ_id “andIMP”] && ![cequal $observ_subid “2”])) } {
#echo “ID $observ_id SUBID $observ_subid TEXT $observ_text”
xpmstore $xlateId [lindex $xlateOutList 0] d -c $secondOBX
#echo “OBX1 – $secondOBX”
}
}}
}
}}
}
{ { OP COMMENT }
{ COMMENT {Clear OBXs} }
}
{ { OP ITERATE }
{ BASIS 1(0).1(0).1(0).OBX }
{ VAR %f1 }
{ TYPE segment }
{ BODY {
{ { OP PATHCOPY }
{ ERR 0 }
{ IN @null }
{ OUT 1(0).1(0).1(0).OBX(%f1) }
{ DFLT @null }
}
}}
}
{ { OP COMMENT }
{ COMMENT {Build impression OBX (0) concatenating Addendum impression and Impression text} }
}
{ { OP CALL }
{ ERR 0 }
{ IN {@firstOBX @addendumflag} }
{ OUT {1(0).1(0).1(0).OBX(0).#1(0) 1(0).1(0).1(0).OBX(0).#2(0) {1(0).1(0).1(0).OBX(0).#3(0).[0].[0]} 1(0).1(0).1(0).OBX(0.#4(0) 1(0).1(0).1(0).OBX(0).#5(0) {1(0).1(0).1(0).OBX(0).#3(0).[0].[1]}} }
{ TCL {
# build the OBX containing the impression
set textin [lindex $xlateInVals 0]
set addflag [lindex $xlateInVals 1]
set cr \.br\
set addlit “— ADDENDUM —“
if { [cequal $addflag “Y”]} {
echo ” found addendum (ADT.1)”
set firstOBX $addlit$cr$textin
} else {
set firstOBX $textin
}
xpmstore $xlateId [lindex $xlateOutList 0] d -c “1”
xpmstore $xlateId [lindex $xlateOutList 1] d -c “FT”
xpmstore $xlateId [lindex $xlateOutList 2] d -c “&IMP”
xpmstore $xlateId [lindex $xlateOutList 3] d -c “1”
xpmstore $xlateId [lindex $xlateOutList 4] d -c $firstOBX
xpmstore $xlateId [lindex $xlateOutList 5] d -c “”
}}
}
{ { OP COMMENT }
{ COMMENT {Build report OBX (1) concatenating Addendum text and report text} }
}
{ { OP CALL }
{ ERR 0 }
{ IN {@secondOBX @addendum} }
{ OUT {1(0).1(0).1(0).OBX(1).#1(0) 1(0).1(0).1(0).OBX(1).#2(0) {1(0).1(0).1(0).OBX(1).#3(0).[0].[0]} 1(0).1(0).1(0).OBX(1).#4(0) 1(0).1(0).1(0).OBX(1).#5(0) {1(0).1(0).1(0).OBX(1).#3(0).[0].[1]}} }
{ TCL {
# build the OBX containing the impression
set report [lindex $xlateInVals 0]
set addendum [lindex $xlateInVals 1]
set cr \.br\
#echo “REPORT – $report”
# if the “addendum” variable contains more than .br
# concatenate it infront of the report variable
if {[string length $addendum] > 5} {
#echo ” found addendum”
set textout $addendum$cr$report
} else {
set textout $report
}
xpmstore $xlateId [lindex $xlateOutList 0] d -c “2”
xpmstore $xlateId [lindex $xlateOutList 1] d -c “FT”
xpmstore $xlateId [lindex $xlateOutList 2] d -c “&GDT”
xpmstore $xlateId [lindex $xlateOutList 3] d -c “2”
xpmstore $xlateId [lindex $xlateOutList 4] d -c $textout
xpmstore $xlateId [lindex $xlateOutList 5] d -c “”
}}
}
{ { OP COMMENT }
{ COMMENT {Populate result status, producers id, and responsible observer for both OBX segs} }
}
{ { OP COPY }
{ ERR 0 }
{ IN {1(0).1(0).1(0).OBX(0).#11(0) 1(0).1(0).1(0).OBX(0).#15(0) 1(0).1(0).1(0).OBX(0).#16(0)} }
{ OUT {1(0).1(0).1(0).OBX(0).#11(0) 1(0).1(0).1(0).OBX(0).#15(0) 1(0).1(0).1(0).OBX(0).#16(0)} }
}
{ { OP COPY }
{ ERR 0 }
{ IN {1(0).1(0).1(0).OBX(0).#11(0) 1(0).1(0).1(0).OBX(0).#15(0) 1(0).1(0).1(0).OBX(0).#16(0)} }
{ OUT {1(0).1(0).1(0).OBX(1).#11(0) 1(0).1(0).1(0).OBX(1).#15(0) 1(0).1(0).1(0).OBX(1).#16(0)} }
}
Jim, Lucy and I did not look up the exact release but sent the email based on memory. If there is only one release then that is what we did.
We are here in Tucson. We were on 3.8 and went to 5.8, RL2. We have more java issues now. We get heap dumps and have to cycle the java client often. We don’t know why. I can’t find in the documentation were to tune the java memory usage. We also found we had to modify a few variants, making some segments optional, which we did not have to do with 3.8.
All told we found the upgrade process to be simple and it went smoothly. We did have an issue making sure the server and client .jar files matched but supported helped there. Make sure you apply the rev.
We too are in a VM environment hosted by an IBM P6. We have to have this configuration in order to fail over to our disaster recovery site. Our storage is EMC’s Clarion.
We have also are experiencing the issue of java core dumps and heap dumps on 5.7 Rev 2. We have to stop and start the client nearly daily. It’s a big hassle. Are ulimits on AIX 6.1 are generous. We also do not think this is really a memory issue but rather processes that do not shut down. Occassionally we get the error “too many files open”.
We would like to know if there is a fix out there. Charlie?
I grep the NetConfig for the proc or I edit it and do a search. Hi Mike, Charlie knows more than me so he will probably solve your problem. But I did want to send you a preprocessing proc we used years ago to determine how to route an order to either Lab or Radiology. The incoming layout was FRL from an old clinical orders system, CCS. This may be an antiquated way of doing this but you might get it to work:
######################################################################
# Name: CCS_orders_OMFALOIE_routing
# Purpose: This procedure parses the incoming CCS OMFALOIE
# (which is the order modification/additional criteria)
# It examines the ordering_dept field to determine
# whether the order is meant for FlexiRad or FlexiLab.
# Once this has been done it chooses the appropriate
# translation and destination thread.
# UPoC type: tps
# Args: tps keyedlist containing the following keys:
# MODE run mode (“start”, “run” or “time”)
# MSGID message handle
# ARGS user-supplied arguments:
#
#
# Returns: tps disposition list:
#
#
########### CHANGE HISTORY ############################################
# Date Task Pgmr Description
# 01/11/01 4471 CEK Modified code to process RESP orderes
#######################################################################
proc CCS_orders_OMFALOIE_routing { args } {
keylget args MODE mode ;# Fetch mode
set dispList {} ;# Nothing to return
set DatList [datlist]
switch -exact — $mode {
start {
# Perform special init functions
# N.B.: there may or may not be a MSGID key in args
}
run {
# ‘run’ mode always has a MSGID; fetch and process it
keylget args MSGID mh
set GRMin [grmcreate -msg $mh frl CCS.order.OMFALOIE.frl]
set OrderingDept [datget [grmfetch $GRMin ordering_dept] VALUE]
if { [cequal $OrderingDept XRAY] || [cequal $OrderingDept PROC] } {
keylset detail
PREPROCS.ARGS {}
PREPROCS.PROCS {}
DEST flexirad_out
POSTPROCS.ARGS {}
POSTPROCS.PROCS {}
TYPE xlate
XLATE CCS.orders.OMFALOIE.to.FlexiRad.ORM_O01.xlt
lappend xrayRouting $detail
msgrouteset $mh $xrayRouting
lappend dispList “CONTINUE $mh”
} elseif { [cequal $OrderingDept LAB] } {
keylset detail
PREPROCS.ARGS {}
PREPROCS.PROCS {}
DEST flexilab_out
POSTPROCS.ARGS {}
POSTPROCS.PROCS {}
TYPE xlate
XLATE CCS.orders.OMFALOIE.to.FlexiLab.ORM_O01.xlt
lappend labRouting $detail
msgrouteset $mh $labRouting
lappend dispList “CONTINUE $mh”
} elseif { [cequal $OrderingDept RESP] } {
keylset detail
PREPROCS.ARGS {}
PREPROCS.PROCS {}
DEST clinivision_out
POSTPROCS.ARGS {}
POSTPROCS.PROCS {}
TYPE xlate
XLATE CCS.orders.OMFALOIE.to.Clinivision.ORM_O01.xlt
lappend respRouting $detail
msgrouteset $mh $respRouting
lappend dispList “CONTINUE $mh”
} else {
lappend dispList “KILL $mh”
error “CCS Order Mod sent for unknown destination -[set OrderingDept]-“
}
hcidatlistreset $DatList
grmdestroy $GRMin
}
time {
# Timer-based processing
# N.B.: there may or may not be a MSGID key in args
}
shutdown {
# Doing some clean-up work
}
default {
error “Unknown mode ‘$mode’ in CCS_orders_routing”
}
}
return $dispList
Ryan, we just upgraded to 5.7 also. We found the inforcement of variant rules seems to have tightened up. We got around some of these issue by making the offending segment optional. other times I had to go back and look at the standard variant and build groupings there were never there before. But try optional – that often seemed to do the trick for us. And we write tons of Tcl here, also. -
AuthorReplies