Mirth on Windows Server 2008 and SQL server 2008

If you are in HL7 business and have not looked at Mirth, you must. Kudos to the Mirth team, they have brought out a phenominal product. More I use it more I get amazed with its capabilities. In one of my recent project I had to install Mirth on a brand new Windows server 2008 running SQL Server 2008. I had not done this kind of implementation earlier and was skeptical as to how it will work. My previous installations on Windows and Linux boxes used MySQL as the internal datbase, this one was different, I had to use SQL Server 2008 for internal database. But it is quite simple, here are the steps:

1. Edit “C:\Program Files (x86)\Mirth\conf\mirth.properties”  and make sure the database property is set to sqlserver2005

database=sqlserver2005

2. Login to SQL Server management studio and create an database called “mirthdb”

3. Inside SQL Server Management Studio, execute the script  “C:\Program Files (x86)\Mirth\sqlserver2005-database.sql” which creates all the necessary tables within mirthdb database.

4. Create an account called “mirthdb” and grant necessary priviledges to this account for mirthdb database.

5.  Edit “C:\Program Files (x86)\Mirth\conf\sqlserver2005-SqlMapConfig.properties” and add the username and password for the SQL Server user created above.

Thats it, restart the Mirth servcie and login to Mirth. It is as simple as that.

How to parse multiple OBX segments in Mirth

Often there is a need to parse segments that occur multiple time in an HL7 message like OBX or Ali segments. For example, in an ADT message you will get height and weight in two OBX segments. How do you parse these multiple OBX segments and make the available to the channel map? I am going to show you how to parse multiple OBX segments in an ADT message and populate variables in to a channel map so they are accessible for further manipulation in the destination connector….

For brevity sake I am just going to showing the OBX segments that I am going to parse here instead of the whole message. The following two OBX segments are present in my message:

OBX|1|ST|HT^PATIENT HEIGHT||142.9

OBX|2|ST|WT^PATIENT WEIGHT||45.2

I want to create three variables, one to hold the height, one to hold the weight and one to hold the number of segments we parsed.

The first step is to create the channel. I am assuming here you already know how to create a channel. For my channel l have my source as a file reader and a database reader as the destination. I create a transformer for the destination. In the transformer, I paste my sample message in the template section and create a step with step being “Javascript”. Then I type the following script as my Java script:

var i=0;
for each (seg in msg..OBX)
{
       i++;
       var key = seg['OBX.3']['OBX.3.2'].toString()
       var obx_val = seg['OBX.5']['OBX.5.1'].toString() ;
       if(key.search(/HEIGHT/) != -1)channelMap.put(‘HEIGHT’, obx_val);
       if(key.search(/WEIGHT/) != -1)channelMap.put(‘WEIGHT’, obx_val);
}
channelMap.put(“obx_seg_count”, i);

 This script creates three variables, HEIGHT, WEIGHT and “obx_seg_count” that are now available to us in the destination for inserting in to a data base as follows.

 Assuming I have a table called ‘OBX’ and columns called ‘ht’ and ‘wt’, I insert the values in to the table as follows in the detonation tab….

expression = “insert into OBX (ht, wt ) values (‘” + $(‘HEIGHT’) + “‘ , ‘” + $(‘WEIGHT’) + “‘)”;
var result = dbConn.executeUpdate(expression);

The trick in this is the for each loop above. The expression in the parenthesis is simple XML E4X expression (see https://wso2.org/project/mashup/0.2/docs/e4xquickstart.html for more details). The other concept to grasp here is to note that the incoming message is available as ‘msg’ object and is just a XML object. Knowing this we can traverse the XML object with E4X and find the elements we are interested in which are OBX elements. The other concept to understand is the ‘maps’ in the Mirth. You need to populate the ‘channel map’ so those variable you create are available throughout your channel.

If you have unknown number of OBX segments in a message, like in a ORU message where you get a report, you can do two things, we can either loop through the way I did up here and concatenate each OBX segment to create on variable called ‘report’ with <cr> at the end and put that in to channel map. Or you could create several variables like following….

var i=0;
for each (seg in msg..OBX)
{
       i++;
       var key = “report_seg_”+I;
       var obx_val = seg['OBX.5']['OBX.5.1'].toString() ;

       channelMap.put(key, obx_val);
}
channelMap.put(“obx_seg_count”, i);

 

 

Hiring right to keep team performance high

Though processes and project management are key essentials for a project teams’ success, these are in no way an alternative to each individual’s personal efficiency. This becomes more important in Distributed Agile, where there are small teams and 2-3 weeks iterations. Hiring the right candidate in terms of aptitude, attitude and skills is becoming increasingly important, given the tough economic times and increasing customer expectations.

Interviewing skills is beyond this blog, though I believe in the celebrated fact that we should always look for aptitude while skills can be learnt. Having said that, it’s impossible to always hire good candidates within a few hours of technical evaluation. There are times when we end up hiring people we wished we didn’t hire. In the best interest of the team, the customer and even that employee, it’s good to get a replacement for three reasons –
a.    We cannot have a poor quality resource if we are faithful to our customer, as the customer is paying for him/her.
b.    Such resources are bad for the team’s motivation levels.
c.    This resource will eventually have to find something more worthwhile to do in life, the sooner the better.

It’s not considered a good HR practice to hire and fire employees, especially in India. I too am a big advocate of this concept. When we hire, it’s our moral and ethical responsibility to give ample opportunities to people we hire. We need to strike a balance between being faithful to the customer and the employee, and act sensitively as firing indiscriminately can create insecurity within the employees.

What generally happens is employers don’t openly give an honest feedback to the employees, and replace them at short notices without giving them an opportunity to improve. The best way is, as clichéd as it gets, open communication. Talk to the employee and put him/her on an improvement plan. Give him/her guidance, time and support. Talk to the customer and tell him/her that you’re looking for a replacement, in case this employee doesn’t work out. This is good for everyone – the employee, the customer and the organization.

Dynamically Changing MasterPage

Changing MasterPage Dynamically

In real-time we may come across scenario where depending on the particular group of users we need to show different layout, colors, themes, functionalities and so on. To achieve this there are various ways, maintain the settings for each user in table , maintain the cookies and so on.

 In .net the best way to achieve this is to change master page dynamically where the master pages will have different layout , different look and feel for different users.  This we can achieve by following below mentioned steps.

1.       All the WebPages will be inherited form System.UI.Web.Page base class

2.       In page directive we  have a property to set masterpage file

3.       Once we attach any master page to any child, first all the controls of the master page are instantiated, then child page controls are instantiated

4.       If we want to apply master page in code behind file ,the page’s master page property needs to be applied in Onpreinit method only.

5.       After instantiating controls, child page load will be called first, then the master page will be loaded.

To change master page dynamically we need to follow the below mentioned process/method

1.       Create one separate class file as public, which will inherits System.UI.Web.Page base class

2.       Override the Page base class method onPreinit(), in this method set the master page property of the page, give the name of the master page file which you want to apply

3.       At the end of the onPreinit() method call the base class onpreinit method

4.       Inherit the newly created class in all of your web pages.

5.       To provide the custom master page, we may use cookies, sessions or the values stored from database, it depends on how we want to manage the customization.

 

Illustration

Illustration

 

 

Merging Image and text in a single gridview cell

Neither you can add image in DataGridViewTextBoxColumn nor you can add text in DataGridViewImageColumn so merging text and image in the same cell in datagridview is bit tricky. To achieve this you can create your own control inheriting from “DataGridViewTextBoxColumn” and overriding paint method. Or you can track the grid view’s paint event and write the below functionality

Private Sub GridView1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles GridView1.Paint

Dim count As Integer = 0

Dim xCordinate As Integer = _

GridView1.GetColumnDisplayRectangle(GridView1.Columns(“column1”).Index, True).X + 11

1. For count = GridView1.FirstDisplayedScrollingRowIndex To (GridView1.FirstDisplayedScrollingRowIndex + 7)

2. If count < GridView1.Rows.Count Then

3. Dim rct As Rectangle = GridView1.GetRowDisplayRectangle(count, True)

4. Dim rct2 As New Rectangle(xCordinate, rct.Y, 26, 25)

5. e.Graphics.DrawImageUnscaledAndClipped(My.Resources.Image1, rct2)

End If

Next

End Sub

Here are the details of steps mentioned above

1. Looping thorough the rows which comes under visible area. Here in the sample code we have 8 rows visible at a time rest are coming under horizontal scroll. So we loop through only those rows starting from “FirstDisplayedScrollingRowIndex “ and paint cell with an added image.

3. Get the rectangle dimension of each row. This is to set the y coordinate of each image we are going to paint manually

4. Get the rectangle dimension of the area under which we want to paint the image.

Here the left coordinate of rct2 is set by taking the X coordinate of the DataGridViewTextBoxColumn under which we are going to paint the image and adding 11 pixels to accommodate the text.

Y coordinate is the Y coordinate of each row

Width and height of rct2 is the dimension of the image we are going to paint

5. “DrawImageUnscaledAndClipped” draws the image without scaling it and clipped by the rectangle passed as a second parameter

Splitting DICOM file in to HEADER and DATA

What is DICOM?

Digital Imaging and Communications in Medicine (DICOM) is a standard for storing, handling, printing, and transmitting information in medical imaging. DICOM internally defines network communications protocol that uses TCP/IP to communicate between systems. DICOM files can be exchanged between two systems that are capable of receiving image and patient data in DICOM format. Proposed by National Electrical Manufacturers Association (NEMA) (www.nema.org)

A DICOM file contains a header and the image data. The header stores information about the patient’s name, the type of scan, position and dimension of image and lots of other data. The image data part contains all the image information.

DICOM IMAGE HIERARCHY

DICOM IMAGE HIERARCHY

SPLITTING DICOM Image:

We can split the DICOM image in to header(Demographics) and data(Image) parts using java with the help of dcm4che API.

HEADER PART:

Ø First we have to open the DICOM image for reading using IOStream.

Ø Create a DICOM Object from the stream we opened for reading.

Ø Remove the Pixel Data from the DICOM Object. Now this DICOM Object only containing header information.

Ø Write the DICOM Object in to a separate file.

Splitting Header(Demographics) from DICOM file.

Splitting Header(Demographics) from DICOM file.

DATA PART:

Ø First we have to open the DICOM image for reading using streams.

Ø Create a DICOM Object from the stream we opened for reading.

Ø Read only Pixel Data from the DICOM Object and store in DICOM Element and write it in another file using byte array.

Extracting Image from DICOM file.

Extracting Image from DICOM file.

Tips to create an effective proposal

1.    While writing the proposal keep in mind who is the audience. Is it a technical person, an end user, a finance guy or maybe a combination? Tailor it to suit their needs. This basic rule holds good for any document for that matter, always keep in mind who will read it.

2.    A good introduction goes a long way in setting the tone of the proposal. The introduction should tell about the problem and the solution that your proposal intends to solve. It should also tell what to expect from the proposal.

3.    Important points in the proposal should be bulleted, highlighted, colored or whatever it takes to make them jump out of the pages. Don’t make it look like a credit card’s hidden terms and conditions.

4.    Keep it short. If the buyer has received ten proposals, probably she’ll pick up the shortest one first.

5.    Leave the finances for the later sections, if money is not your selling point. If you can convince you have understood and can solve a problem effectively, the buyer shouldn’t bother much about it.

6.    Your company’s profile should not appear in the first few pages. The buyer probably knows about that if she asked you to submit a proposal. It can be a part of the appendix at best.

7.    Do a spelling and grammar check. Do not submit a proposal without a table of content.

How to grow in an organization

I read a story in my high school English book written by a famous Indian author (I forgot the name) – There was an old blind man who used to work in a grocery store. He was very good at mathematics. He used to sit next to the shop owner. Whenever a customer bought goods from the shop, the owner would speak out the product list. The old man would quickly calculate the total amount payable with his impeccable strong hold on mathematics. He also had a good memory and knew the prices of all the products. One day when he came to the shop, he came to know that the owner had bought a new device called a calculator. The calculator could do all the maths and much faster! Slowly the old man became obsolete. The owner had not asked him to leave but he felt he was not doing much at the shop and became restless.

One day when he was sitting next to the owner as usual, with the owner doing all the maths on the calculator, the owner wanted to know the price of a product. The old man of course had this information handy through years of working in the shop. In fact he also knew how much quantity of that product was in the shop. From that day his role changed, he would advice the owner on inventory management, cost price and selling price of each product.

A few days later on being asked by someone what was he still doing in the shop, when the owner now had the calculator, the old man said that he had been promoted to be a manager!

The morale of the story is simple. To grow in an organization, make yourself replaceable. Grow your fellow employees to take your place. Growing your team should be the higher objective, and you’ll see that your own growth was a natural consequence.

A practical approach to project effort estimate

It’s called an estimate because it’s bound to change as the development progresses, and as both the partners (the customer and the service provider) get a better understanding of the project. The use of the word partners takes significant importance since mutual trust and understanding is necessary for a project to be successful. At CircleSource we follow a simple two step process –

a.    The sales team, which includes a technical specialist, estimates based on the available product overview and provides ball park figures to the customer. These are typically an order of magnitude estimates, e.g. 6 to 8 person months or $10,000-15,000. This estimate includes a list of features to be developed, development methodology, deliverables and time lines.
b.    During the first 2-3 weeks, CircleSource puts its best efforts at gathering business objectives and requirement of the product. A Software Requirement Specification or wireframes or screen mock-ups are created during this time. Based on this, we provide revised estimates to the customer which becomes the point of reference to the overall project cost and time. This is also the time when we provide business and technology suggestions, based on our experience, to improve the product. Both the sales team and the project lead are involved in this stage.

With the advent of Agile, where the entire product development is broken down into 2-3 weeks iterations, it has become easy to provide a realistic view of the project timelines to the customer. We provide iteration based releases to get continual suggestions and changes from the customer. However, a basic pre-requisite of Agile is that whenever the requirements change, the iteration plan needs to be revised and communicated to the customer. We have to act as trusted advisors to the customers, consult them on the feature addition versus time and cost balance, and keep them updated on a daily basis on the progress. Since the basic nature of estimates is dynamic, prompt and effective communication is the key for success.

Process Training during Induction

It is a celebrated fact that software development is no longer an art but a science where results can be predicted to a high degree of accuracy, thanks to the processes or quality management system of an organization. The QMS of any organization is an integral part of its DNA, which predicts and maintains consistency of quality in the projects.

Each organization has its own unique set of processes and tools. At CircleSource we have created our own Software Development Methodology customized to suit the kind of product development we undertake in our organization. This is a simple one page document, figuratively explaining the various phases and associated deliverables. We use two main tools – SVN for version control and Trac for project management. We have customized both these tools to our needs. Besides, we have many other documented processes e.g. Release Management, Roll out of the application on the production server,  Pre Release Checks.
The key is the dissemination of this information to the employees on a continual basis. It takes extreme importance for new joinees who have to be quickly taken under the wings of CircleSource’ QMS. We provide training to all new employees on our tools and processes, and strive to do this within a week of their inception. No employee can be part of a live project unless he/she has undergone these trainings. This initiative, which is a combined effort of the HR/Quality Team/Engineering Team of CircleSource, ensures that our team adheres to processes and  delivers value  from day one of the project!