There is not much to say about this week. I spent most of the time making minor changes to try and get the work finished up. Next week I will be doing more minor changes and preparing for the final presentation.
This week I finished up the first pass of the “Choose Concept By Hierarchy” page. Next step is to get it in front of some people and see what they would like modified. I will spend some time going through and adding some comments and maybe more organization to my code for the next week and preparing for the final presentation the week after that. Here are some screen shots of the work I have done as a first pass on the hierarchy page:
This week has been spent working more on the hierarchies page using angularjs. AngularJs has a much higher learning curve than learning something like lucene but if you pay your dues and really try to understand how to use it then it is a very powerful tool.
I think we are finally coming close to the final stretch and I am going to meet my personal goal of getting a nice tool for viewing the Snomed CT terms in a hierarchy. I think this kind of tool has a lot of potential for being very useful if added on to in the future and so this has been the most important accomplishment for me. I still have some work to do but I feel more confident now that it will all be done in the end.
Here is some more information on AngularJs:
Here is an exert from the docs.angularjs.org/guide/ website that I find to be one of the most powerful tools in using AngularJs. It is about the directives:
“Directives are a way to teach HTML new tricks. During DOM compilation directives are matched against the HTML and executed. This allows directives to register behavior, or transform the DOM.
Angular comes with a built in set of directives which are useful for building web applications but can be extended such that HTML can be turned into a declarative domain specific language (DSL).”
I do all of my service calls with factories and they usually are making an ajax call to my fragment controller:
“While Angular offers several useful services, for any nontrivial application you’ll find it useful to write your own custom services. To do this you begin by registering a service factory function with a module either via the
Module#factory api or directly via the
$provide api inside of module config function.
All Angular services participate in dependency injection (DI) by registering themselves with Angular’s DI system (injector) under a
name (id) as well as by declaring dependencies which need to be provided for the factory function of the registered service. The ability to swap dependencies for mocks/stubs/dummies in tests allows for services to be highly testable.” (http://docs.angularjs.org/guide/dev_guide.services.creating_services)
One of the last important pieces is the Controller:
Use controllers to:
- Set up the initial state of a scope object.
- Add behavior to the scope object.” (http://docs.angularjs.org/guide/dev_guide.mvc.understanding_controller)
As you can see with these key pieces AngularJs makes it easy to write code following MVC.
I will say the only way to learn AngularJs is to just try and keep working at it. I could not find any tutorials that could get all the way into advanced use. It is a lot of trial and error.
This week I have started to learn about and use AngularJS.
I will be using AngularJS in one of the final phases of the project to build a widget for a hierarchy based concept search. So here are the thoughts on the widget:
The search widget will search through the concepts with a typical ajax auto complete. Selecting a concept will 1) set the value of the auto complete to be the selected concept, 2) if the concept has a mapping to SNOMED CT, then show the SNOMED hierarchy around that concept in the tree below. In the tree, each item is a SNOMED CT ConceptReferenceTerm. Some of these have OpenMRS Concepts mapped to them. If they do, we should visually highlight it, and also display the preferred name of that Concept. We will Show one level of parents and children. If you click on a parent or child, it should redraw the tree for that term. (I.E. the user can traverse up or down by one step by clicking a row). Also, if the term you clicked on has one or more Concepts attached to it (query the API for concepts with a mapping SAME-AS SNOMED CT 123456), then visually highlight this row, and also show the OpenMRS Concepts using thier preferred names. These concept names should actually be links/buttons that set the search box above (and its form field) to that concept. Implement it all as a fragment called “chooseConceptByHierarchy”, that requires a “formFieldName” parameter, and ultimately sets a hidden input (with that form field name) to the conceptId of the chosen concept.
Once this is finished we should be pretty much done with all functionality for the project and it will just be time to clean up and make sure all the final touches are done.
Lucene is an open-source Java full-text search library. It makes it easy to add search functionality to an application or website. After some studying about the best way to handle the work I started last week I found that this is the best tool to use for going through the SNOMED CT files.
The files were made to be put straight into a database. Because we do not plan on doing that, indexing seems to be the next best thing. Basically what Lucene gave me is the ability to take the files and index them so that I could easily search for the information I needed for my reference terms and cut down the time it was taking to process the information in the SNOMED files. So for each line in the file I split it on the tab delimiters and told lucene what each column is so that I could search on the data contained in that column. So for instance in the sct2_Relationship_Full_INT_20130131 it has sourceId and destinationId I need to search on. So, I put that into a StringField:
doc.add(new StringField(“sourceId”, fileFields, Field.Store.YES));
doc.add(new StringField(“destinationId”, fileFields, Field.Store.YES));
This makes it so that I can tell it I want to find termId “1234” in the sourceId field.
What the structure looks like:
Index –> Document1, Document2, etc… –>Field1, Field2, etc…
Lucene was not hard to learn to use. But it is only an API all of the hard part of indexing is done but it is up to the user to figure out how to parse the file data into Lucene and how you want to get the data out which has to do with how you put the data into the Documents.
Lucene managed to cut the search processing time and made it more than 10 times faster.
This week I have been working on the following:
a dashboard-style page where you (1) indicate where on your filesystem the snomed files are, (2) have a series of buttons for the different tasks, like “add names to all my SNOMED terms” and “import ancestors for all my SNOMED terms”.
I have mostly been working on the ancestors and parents which will be what we need for the hierarchy. So I have about 38000 terms in the database and I am traversing through a file with 4,000,000 records to find the ancestors. I think the best way to handle this will be to use a HashMap with byte offsets so that it will not take too long for the process. I have made the skeleton of the work and I am just tweaking it to make sure it is as fast as possible. But I do not see any issues with getting the work done.