Tuesday, December 31, 2013

Using XSD 1.1 with HL7 as a Schematron replacement

Several years ago, I posted an article on IBM developerWorks about using OASIS CAM and David Webber's CAM Processor tooling to extend HL7 v3 schemas to better handle the extra conformance levels required by the HL7 RIM, particularly dealing with null flavors. At that time, CAM Processor was relatively new, and CAM is now reaching a very good level of maturity in the NIEM community; however, I suspect that HL7 specifications will always be more demanding than NIEM, in part due to the complexities of the RIM. The best alternative has always proven to be XSD 1.0 + ISO Schematron. At the time, I had considered using XSD 1.1, which provides assertions, but at the time, XSD 1.1 was still in development, and the CAM tooling just worked.

Recently however, it dawned on me that XSD 1.1 is now a W3C Recommend, and it has evolved, much like CAM, to include features that originated in Schematron. Actually these ideas didn't originate in Schematron, but that's another story.

As opposed to OASIS CAM, which really combines the core strengths from Examplotron and Schematron - using a reduced instance XML instead of a hierarchical grammar, and using XPath to define assertions - XSD 1.1 retains the hierarchical grammar, adding Schematron-like assertions to the extension/restriction process which is already built into XSD. So, to test data-type assertions on an element, you restrict the type definition for the element; to test conformance assertions on an element, you extend the type of the element to include any necessary assertions.

For example, in the HL7 RIM, an element can be Optional, Required or Mandatory - with an extra level, Populated, in some realms. For Optional, Required or Populated elements, a nullFlavor attribute is permitted in place of absent valued information, to describe why the information was absent. The phrase null flavor is confusing, but really it's just a reason why the information is absent. For Mandatory elements the nullFlavor attribute is forbidden.

In an existing XSD schema, you can determine which elements are Mandatory because they have minOccurs which is greater than 0, and isMandatory is true [ed. this has been edited]:
<xs:element name="processingCode" type="CS.CA"
   minOccurs="1" maxOccurs="1">
   <xs:annotation>
      <xs:appinfo>
         <mif:attribute name="processingCode"
             minimumMultiplicity="1" maximumMultiplicity="1"
             isMandatory="true" isImmutable="false">
            <mif:businessName name="D:Processing Code"/>
            <mif:annotations>
                <mif:appInfo>
                    <mif:mapping sourceName="Sample">
                        <mif:text>
                            <mif:p>[MSH-11.1]</mif:p>
                        </mif:text>
                    </mif:mapping>
                </mif:appInfo>
            </mif:annotations>
            <mif:type name="CS.CA"/>
            <mif:vocabulary>
                <mif:conceptDomain name="ProcessingID"/>
            </mif:vocabulary>
         </mif:attribute>
      </xs:appinfo>
   </xs:annotation>
</xs:element>
In order to add an assertion using the new features in XSD 1.1, we need to remove the type attribute from the element, and extend it as a complex type:
<xs:element name="processingCode" type="CS.CA"
   minOccurs="1" maxOccurs="1">
   <xs:annotation>
      <xs:appinfo>
         <mif:attribute name="processingCode"
             minimumMultiplicity="1" maximumMultiplicity="1"
             isMandatory="true" isImmutable="false">
            <mif:businessName name="D:Processing Code"/>
                    . . .
            <mif:type name="CS.CA"/>
            <mif:vocabulary>
                <mif:conceptDomain name="ProcessingID"/>
            </mif:vocabulary>
         </mif:attribute>
      </xs:appinfo>
   </xs:annotation>
   <xs:complexType>
      <xs:complexContent>
         <xs:extension base="CS.CA">
            <xs:assert test="not(@nullFlavor)"/>
         </xs:extension>
      </xs:complexContent>
   </xs:complexType>
</xs:element>
If additional assertions are required, they can be added to the same extension; however, in this case, the only assertion we require is to ensure that the Mandatory element does not have a null flavor when we validate an instance message. All that remains now is to change our XML editor so that it is using Xerces 2.11.0 or higher, which supports XSD 1.1, and when we validate a message, we will be alerted if there is a processingCode element which is null flavored.

Sunday, December 29, 2013

Wednesday, October 23, 2013

My New Policy for the Internet

I am drafting up my new policy for the internet. It consists of three ideas, nothing new, but possibly newly articulated as a haiku or something:

#thinkbeforeyoulink
#carebeforeyoushare
#waitbeforeyouhate

And most likely, don't +1 anything. 

Wednesday, August 14, 2013

DB2-RDF

I still think this is really cool. NoSQL Graph support for DB2-RDF holds a lot of promise, particularly if it performs as well with large data sets as people are suggesting it does.

Summary:
1.  DB2-RDF support is officially called "NoSQL Graph Support". 
2.  The API extends the Jena API (Graph layer).  Developers familiar with Jena TDB will have the Model layer capabilities they are accustomed to.
3.  Although the DB2-RDF functionality is being released with DB2 LUW 10.1, it is also compatible with DB2 9.7.
4.  Full supports for SPARQL 1.0 and a subset of SPARQL 1.1.  Full SPARQL 1.1 support (which is still a W3C working draft) will be forthcoming.
5.  While RDBMS implementations of RDF graphs have typically been non-performant, that is not the case here*.  Some very impressive and innovative work has been put into optimization capabilities.  Out-of-the box performance is comparable with native triple stores, and read/write performance in the optimized schema has been seen to surpass these speeds.

Saturday, August 10, 2013

Angular Saxon Summer Update

My side project over the summer started with a premise: using Saxon-CE, the client-side port of the popular Saxon library, on a Firefox OS device. It didn't work on the Simulator, and I worked on some different Mobile Health work on PhoneGap and Android, and then one day, Saxon-CE just started working under both PhoneGap and Firefox OS. A new Simulator had come out, and the stars had aligned.

Firefox OS provides native support for Cross-Origin Resource Sharing (CORS) using XMLHttpResponse (XHR), as well as native support for JSON. I knew that I wanted to use XML, but I was finding JSON useful as well. About this time, I became involved with the Prescription Medication Information Exchange (PMIX) demo, which is part of David Webber's Open-XDX project, which is an extension of OASIS CAM. And it supports both JSON and XML endpoints. I had also been working with HL7 FHIR, which also supports REST, JSON and XML.

So at that point, I had a rudimentary XSLT view which ran as an application on Firefox OS, backed by Open-XDX. Not very useful, considering that Firefox OS devices had not at this point begun shipping commercially (they still haven't). So I turned my focus back to PhoneGap for Android. Without native support for CORS XHR, I needed JQuery and Backbone, and I started down that path; however, this didn't allow me to share code between PhoneGap and Firefox OS, since JQuery and Backbone were over-powered for what I wanted to accomplish.

Then I watched the AngularJS demo video. I had worked with Thymeleaf on the server-side, and the idea of attribute driven directives in the HTML seemed very natural. It is. I have no doubt that these directives will soon find their way into native support in browsers. Try it. It's practical magic, and it works. Better than JQuery, I feel, once you get used to it.

As I worked with these technologies, I started to have a feeling, and I am starting to see that it is more or less accurate: with planning, a common code base can be used with PhoneGap and Native Browser Mobile like ChromeOS and Firefox OS, using a Dependency Injection framework like AngularJS with a templating framework like Saxon-CE. More than this, Angular and JSON shine on PhoneGap, where you are contending with an existing VM, and Saxon-CE runs really slow; on Firefox OS, with native JavaScript, AngularJS is harder to work with and less necessary, and Saxon-CE performs well.

#AngularSaxon #AngularSummer

Tuesday, August 06, 2013

New Glue: Using Angular and CSS pseudo elements

My overall plan for Rhizome is to auto-schema-generate Views - partial HTML5 ng-includes - which I have bundled up as ordered lists, combined with CSS3 pseudo elements to inject in application labels, positioning of elements and so forth. The idea is that a change to the underlying schemas should require regeneration of the Views, but not of the application.

<ol id="prescriptions">
    <li ng-repeat="prescription in pmix.response.prescriptions">
        <div class="pmpPrescription">
            <span class="pmpPrescriptionNumberText" ng-bind="prescription['pmp:PrescriptionNumberText']"></span>
            <span class="pmpDrugRefillNumberCount" ng-bind="prescription['pmp:DrugRefillNumberCount']"></span>
            <span class="pmpPrescriptionFilledDate" ng-bind="prescription['pmp:PrescriptionFilledDate']['nc:Date']"></span>
        </div>

        <div ng-repeat="prescriptionDrug in prescription['pmp:PrescriptionDrug']">
            <div class="pmpPrescriptionDrug">
                <span ng-bind="prescriptionDrug['pmp:DrugProductNameText']"></span>
                <span ng-bind="prescriptionDrug['pmp:DrugStrengthText']"></span>
                <span ng-bind="prescriptionDrug['pmp:DrugUnitOfMeasureText']"></span>
            </div> 
        </div>
    </li>

</ol>

And then the corresponding stylesheet looks like:

/* Prescription resource labels: */
.pmpPrescription::before {

   content: "Prescription #: ";        
   font-weight: bold;
}
 

.pmpPrescriptionDrug::before { 
   content: "Prescription Drug: ";
   font-weight: bold; 
}

.pmpDrugRefillNumberCount::before { 

   content: "("; 
}
 

.pmpDrugRefillNumberCount::after { 
   content: " refills)"; 
} 

And the resulting screen looks like:

Prescription #:  RX-12453 (3 refills)
Prescription Drug: Hydrocet LOW 5MG

Resource-based Mobile Links:

http://www.dfki.de/~sonntag/ubicomm10.pdf
http://www.goodreads.com/book/show/16674717-the-agile-architecture-revolution
http://sharedservices.lnwprogram.org/sites/default/files/XJC_-_Art_of_the_Possible.pdf 

Monday, August 05, 2013

Strategy: Turning Theory into Practice

I have been reading The Strategy Book, by Max McKeown. This is a very short review because I haven't read the book fully yet, and because no approach to business strategy can be evaluated immediately. It takes time to implement business strategy, and it takes longer to evaluate success.\

On thing that strikes me, and perhaps this is because I am a consultant and implementer, not a business person, is that the strategy approach described is very active - "Strategy in Action" - which makes sense. But my personal strategy is very passive, or rather, responsive. It's not a right/wrong thing, but relates more to what you are trying to accomplish.

So when I read "Position, Intention, Direction", I can't disagree that these things are an important part of strategy. And then these criteria are described in terms of Objective, Context, Challenge and Success. This is fine-grained, but my own personal strategy, as I have described, is intentionally responsive:

Vision - what is the message you are creating or are hearing?
Precision - is your description of the problem-space accurate?
Concision - have you removed all the noise from your message?
Decision - can you act upon your vision?

So these are responsive criteria, with the last cutting over into active territory. Decision is where you cut over from "-ision" to "-ition".

Tuesday, July 30, 2013

Rhizome Business Value

Rhizome is a resource-based mobile demo I am building. It was originally intended for an HL7 FHIR connectathon to build out a security layer, and since developed into a companion to the PMIX Open-XDX API demo on VerifyXML.org, demonstrating using mobile JSON and XML.

Rhizome stands for "Resource-based Health Information Zone for the Mobile Enterprise"... the name is intended to be tongue in cheek, and the "R" could stand for REST, "E" for Exchange... but there is a buried meaning here as well: a rhizome like ginger or bamboo is diageotropic, meaning that it grows laterally; and the Rhizome application by design supports concepts like cross-jurisdictional exchange because it is resource- and scheme-based. It goes lateral.

In order to succeed in the enterprise, mobile exchange needs to be built on resource-based open web standards, which support making cross-jurisdictional data exchange work. This doesn't mean that the comprehensive approach taken by HL7 v3 is wrong, but we also need to support less complicated protocols like JSON and REST, using an agile approach towards content creation, consumption, collaboration and curation. Examples of this are projects like GreenCDA, HL7 FHIR and Open-XDX. Rhizome is an example of this also.

French literary theorists Gilles Deleuze and Felix Guattari introduce their A Thousand Plateaus by outlining the concept of the rhizome (quoted from A Thousand Plateaus):
  • 1 and 2: Principles of connection and heterogeneity: any point of a rhizome can be connected to any other, and must be
  • 3. Principle of multiplicity: only when the multiple is effectively treated as a substantive, "multiplicity" that it ceases to have any relation to the One
  • 4. Principle of asignifying rupture: a rhizome may be broken, but it will start up again on one of its old lines, or on new lines
  • 5 and 6: Principle of cartography and decalcomania: a rhizome is not amenable to any structural or generative model; it is a "map and not a tracing"

Structure within Angular

I am finding more useful resources for AngularJS, including Christopher Hiller's Developing an AngularJS Edge (Bleeding Edge). What I am going to do here is describe the structure I have come to after a lot of refactoring in my Rhizome application, using AngularJS and Saxon-CE. It's not perfect,  but I do want to document it at this point. I'm using PhoneGap, so this all resides in assets/www:

lib/shared - contains the JavaScript files for AngularJS and Saxon-CE
lib/rhizome/css - contains rhizome.css, references to Gaia css
lib/rhizome/js - contains Controllers.js, PresentationServices.js
res/views/html - contains pmixRequest.html, pmixResponse.html
res/views/xslt - contains PMPPrescriptionReport-application.xslt, other stylesheets

The stylesheets still need some work - I started out building a pure Gaia application for Firefox OS, before porting into PhoneGap for Android, but I have retained some of the Gaia look and feel. I am also considering leveraging AngularUI/Bootstrap for this purpose.

All of my controllers are in a single file, and align nicely with my views. The Presentation Services contains my rendering service and Business Services is currently empty. I am sure I will require some business logic eventually. My main AngularJS module is declared in a script tag near the bottom of my index.html page, and called at the top in the html element.

As far as my views are concerned, I have a pair of partial HTML forms which align with the PMIX Request and Response interactions, and a separate include file for the header, to reduce clutter. I may actually rename the controllers PMIXRequestCtrl and PMIXResponseCtrl, to make it obvious that is what they are. I'm used to HL7, where interactions have well-defined interactions. I like the alignment between controller and partial HTML view.

For the Saxon-CE piece, I have a  separate set of template views. I'm not as happy with these, but they serve a purpose. In the long run, both the HTML and XSLT views should be largely generated from the PMIX CAM schema. I have put these in the res directory because they are resources.

My approach is resource-based, whereas the PMIX data is really not. Three resources are represented in the PMIX payload: Patient, Prescription Report and Prescription. These are clipped out of the response message and then bound to the model scope in pmixResponse.html. This would be cleaner and more RESTful if the PMIX schema was broken into more granular interactions, but that's okay.

Monday, July 29, 2013

JSON vs. XML: Holy Wars and Container Elements

I've been working on a demo based on David Webber's CAM/Open-XDX demo for Prescription Medication Checking (PMIX). Open-XDX offers an easy way to set up a schema-based REST API for XML and JSON. I am building a mobile app with PhoneGap, AngularJS and Saxon-CE.

Originally, my demo mobile application used Saxon-CE with a bit of JQuery to coordinate Ajax calls. I soon replaced JQuery with AngularJS because I wanted a chance to use this framework, and because I liked the name "AngularSaxon". Meanwhile, I was also figuring out a way to embed a Firefox OS build within an Android PhoneGap build.

It soon became apparent that Angular, at 80K, could perform many tasks faster than Saxon-CE, at 800K, and since I had both JSON and XML available, I started shifting my focus, to allow a time trial between the two wire formats. One thing I discovered is that, whereas XSLT can handle something like:

   <Prescription id="1">...</Prescription> 
   <Prescription id="2">...</Prescription> 

...in the specific case where there is only one element, in JSON, this surfaces as the difference between an Array and an Object, which results in problems using Angular's ng-repeat directive. I was able to create a workaround in my JavaScript objects, as detailed below.

I had already created an Angular Service to handle rendering in both XSLT, using Saxon-CE, and in JSON. This Rendering Service already contained an exposed copy of the data returned from an API call, triggering an Angular Controller when the data is ready. I added the following method to the Rendering Service to insert an absent Array for a container element:

   renderingService.fixJSONContainer = 
      function(parentNode, childName) {
         if (parentNode !== undefined) {
            var childNode = parentNode[childName]
            if (!Array.isArray(childNode)) {
                parentNode[childName] = new Array(childNode)       
            }
            return parentNode[childName]
        }
        return []
    }


This helper method is available to the Response Controller, since it has already been Dependency Injected. In the Response Controller, I made the following changes to the render method for JSON:

   $scope.$on('renderJSON', function() {
    $scope.fixJSONContainers(renderingService.data)            

    $scope.pmix.resp.prescReport = renderingService.data[...]
    $scope.pmix.response.prescriptions =
       $scope.pmix.resp.prescReport['pmp:Prescription']
  });
         

  $scope.fixJSONContainers = function(data) {
     var prescriptionArray = 

        renderingService.fixJSONContainer(data[...], 
        'pmp:Prescription')
     for (prescriptionNode in prescriptionArray) {
        prescriptionDrugArray = renderingService.fixJSONContainer(

           prescriptionArray[prescriptionNode], 
           'pmp:PrescriptionDrug')
     }
  }


The local method fixJSONContainers is specific to my schema, and requires intimate knowledge of the schema; where for instance, the CAM elements have makeRepeatable. Other than that, this solution is generic. In my HTML View, Angular handles the data-binding using ng-repeat directives:
 
   <ol id="prescriptions">
      <li ng-repeat="prescription in pmix.response.prescriptions">
      <h3> Prescription #:
         {{prescription['pmp:PrescriptionNumberText']}}
         ({{prescription['pmp:DrugRefillNumberCount']}})</h3>
      <div ng-repeat="prescriptionDrug in 
          prescription['pmp:PrescriptionDrug']">
          <div> Prescription: 
              {{prescriptionDrug['pmp:DrugProductNameText']}}
              - {{prescriptionDrug['pmp:DrugStrengthText']}}
              - {{prescriptionDrug['pmp:DrugUnitOfMeasureText']}}
          </div>
       </div>
    </li>
 </ol> 
 
Once the changes have been made to the underlying Services and Controllers, the HTML View is very tight and concise, which is part of the magic of Angular. Autowired data-binding takes care of the rest.

Sunday, July 28, 2013

Open Mobile Web

It turns out AngularJS and it's companion UI framework bundles JavaScript support for Bootstrap, which is fantastic. All you need to do is include AngularJS, AngularUI, and the Bootstrap CSS, and you can say goodbye to JQuery for good, and start building Adaptive Design for the Mobile Web.

I really feel this piece has been lacking; I am very pleased with being able to nestle a Firefox OS app within a PhoneGap app, boosted by Angular. With the addition of Bootstrap, you really can have it all.

What is important here, though, is that all of these approaches intend to make themselves obsolete, leaving behind the promise of Firefox OS... Rich Internet Applications built on Open Web standards (HTML5, CSS), rather than Mono or Flash. In time, the best features of these frameworks will be built into the mobile browser.

Much as I love JavaScript and XSLT, there has to be a better way. I'm really starting to believe that a thin layer of Controller glue and maintainable AngularJS Services is this better way. This is a great time to be a mobile developer.

On the server-side, a resource-based Open Data REST API, Secured Mobile approach should allow us to build mobile applications that mash up resources across jurisdictions, securely and meaningfully.

Mobile Web and Mobile Exchange. This will be exciting.

Monday, July 15, 2013

JavaScript: The Cake and Eating it Too

In my previous post, I started to talk about some of the things I appreciate about Angular, and many of these things, I also like about technologies like Thymeleaf as a JSP replacement, Scala as a Java/Spring replacement, PhoneGap as a native mobile replacement... the list goes on, but what all of these have in common is that (with the exception of Scala, and I will get to that eventually) they leverage and enable the potential of HTML5 by using HTML5 as template and view, a purpose for which it is well suited. In short, these technologies are all  replacements for approaches that are harder to work with, and all come with a self awareness that their purpose is to make themselves obsolete as more standardized functionality comes built in the browser and server alike.

This makes me very happy, of course, because I am excited about the lightweight native mobile web approach promised by Firefox OS and other browser based platforms for the web and mobile. Why is this exciting? Because the developer community for native apps built in HTML5, CSS and JavaScript with a decent framework is huge. I would hazard a guess that Angular JavaScript could be taught in schools very easily, and deployed onto mobile devices, shared with other students using github... it's a good time to be exploring new technologies.

My own personal preference is a sort of best of breed client layer formed by layering Angular JS and then Saxon CE over Cordova (PhoneGap), which I have been referring to as "SaxonCord", although the more I use the functionality built into Angular, the less I rely on Saxon CE as a client layer. For some things, like SVG manipulation or working with XML messaging standards like HL7 CDA or NIEM, Saxon CE is a rockstar; however, these standards are becoming more open, and in doing so, have started to embrace JSON, at which point the autowired data binding Angular provides is really all you need to inject data into a page. I have used client-side Inversion of Control frameworks in Adobe Flex; Angular is just plain easier.

Sunday, July 14, 2013

JavaScript: The New Glue

I don't work for Google: but let's talk about AngularJS.


Specifically, I have been working with the JavaScript framework AngularJS recently. When the web was very young, it served static pages, for which HTML was appropriate because browsers facilitated looking at a page and then looking at the underlying markup; learning by view source was viral. Then the web started getting more dynamic, and technologies like JavaScript were introduced to allow for greater interactivity, but they never lost their reputation as "glue code".

Static webpages are a thing of the past. A mature JavaScript framework like AngularJS enables the browser to behave dynamically without hiding a lot of functionality in controllers; this means that the HTML code should still be easily understood at the level of view source. This is what I mean when I refer to the New Glue. JavaScript has evolved beyond "glue code": the real magic is in the autowired data binding provided by the underlying framework

This is nothing new, of course, but I do think it's important to note that use of a framework should allow you to do simple dynamic web pages without a lot of code; CSS can provide some of this as well. If you find yourself writing a lot of controller code for a dynamic webpage or mobile application, ask yourself if you really need this level complexity, or are you coding around the automagic?

The level of investment in a JavaScript framework is very low. Using a best of breed combination of Backbone, Marionette, JQuery, Underscore and so forth can be used to create great results, but requires a reference implementation, and some extra glue to coordinate between different libraries. With a framework, all you need to do to get started is to reference the minimized script from a remote server, and build from there. This really leaves no excuse not to get started exploring frameworks like AngularJS now, and share your work.

#AngularSummer

Saturday, July 13, 2013

JavaScript: the Good, the Bad and the Ugly

I recently read Michael Fogus's Functional JavaScript (O'Reilly). I've always enjoyed JavaScript as a language for it's balance of simplicity and complexity. It's a very flexible language, a bit of a hot mess, lipstick on a pig in places; and I still appreciate Crockford's book, The Good Parts, but really, in much the same way I am expecting a move away from libraries like JQuery and approaches that masquerade object-oriented principles in JS, I think that there is a lot to be said for gaining an appreciation for pure declarative JavaScript, which Underscore really facilitates.

I do think that in the future, picking an enabling framework like Ember or Angular will pay dividends, as a lot of functionality like Http/REST/JSON support becomes native and standardized in the browser. On mobile devices, look and feel may be prescribed by an open but proprietary set of styles and widgets. A good framework should enable the user experience, while supporting it transparently with good MV* pattern support for data binding. I really like Learning JavaScript Design Patterns by Addy Osmani, which explores the standard Java design patterns like Singleton, Modules and Observers, and then goes into the different Model View patterns in depth.

Once you take away a lot of the fiddly bits, JavaScript starts to look more like it's original intent - sophisticated and somewhat magical glue that holds together your required controllers. I like Angular because it takes a fundamental design approach that your HTML becomes your View, and contains the hooks that become your Model. With the Model View View-Model pattern, if you are building a lot of complicated controllers, it's possible that what you really need is more auto-wiring and dependency injection - the glue makes it magical.

For a small application, building functional JavaScript with a minimum of additional library support is liberating. For a larger application, picking a mature framework is a good way to go. In the middle, a consolidated platform built out of best of breed libraries may be a good solution, but I would still go with a mature framework. As a development manager, I am always looking for good resources both to help developers make the move from Java development or client-side development using JQuery or ActionScript, to using an appropriate framework or collection of libraries.

All of these books provide a lot of good code samples, but it is also worth noting that the current generation of libraries and frameworks, like Underscore, Backbone, Ember and Angular are terse enough that  you can refer to the underlying source, and also provide excellent references and quick starts for new developers. There is a lot of competition in this space, and good documentation and sample code often separates the Good from the Bad and the Ugly.  

Saturday, June 22, 2013

Jekyll/Prose.io

so, healthcare.gov: github/Jekyll/prose.io, and this is the Agile NoCMS approach now, replacing drupal as a shortest path content for anything solution? Weird, wild stuff.

Thursday, June 20, 2013

Time to talk about Single Page Applications again?

The phrase Single Page Application is possibly link-bait. It has certainly drawn more comments than any other post I have made, although many of them are in languages with which I am not familiar, discussing products and services about which the less said the better.

Back in 2009, if I referred to a Single Page Application, I was most likely talking about TiddlyWiki, and that has changed now due to the ever-expanding field of mobile development and popularity of HTML5; so that now, if I refer to a Single Page Application, I am more likely referring to a mobile application shell which uses client-side business logic and asynchronous REST to provide a rich user experience. A modern SPA will use a combination of MVW libraries and frameworks like Backbone, Marionette, AngularJS or Ember; wheras TiddlyWiki used a lot of well written sophisticated JavaScript.

My own experiments with Saxon-CE and JQuery in PhoneGap have been very enjoyable, in which case all of your business and presentation logic are bundled into XSLT2 stylesheets, with a very thin layer of Ajax, which really constitutes another framework. In this case, when you take PhoneGap away and replace it with a native web OS (Firefox OS), you are left with a very thin framework for SPA.

To return to the subject of my previous post, if I was to create a "book" as a single page application (and not just use EPub3), this is the sort of framework I would target, for exactly my previous reasons. So from that point of view, I'm very pleased with the way technology is currently evolving.

Tuesday, June 18, 2013

of words she's made up

speaking

of
words

she's made

up


and

waking
through

dreams

she's

breathing
alive

singing
through
songs

she's
sung

Tuesday, June 11, 2013

-ision

I'm going to get into this once, and then hope it takes on a life of its own. I believe it is important to put this down in words; how not to suck at things. Precision, concision, vision, decision. This is like asking "is this measurable, is this actionable?" But this is easier, I have found.

Precision
When you describe a thing, are you accurate? Are your facts correct?

Concision
Have you used ten words where five are required? Is your argument more complete when you say less?

Vision
Do you have a clear and compelling message?

Decision
Are you able to act on the information available?

Tuesday, May 07, 2013

TermInfo Discussion at HL7 WGM Atlanta 2013 (SIM&A)



Okay, HL7's RIMBAA Working Group hasn't changed their name to SIM&A yet ("Simba"), but it looks like that is the name that is going to stick to reflect the group's broadened scope.

One issue that this and other working groups are determined to put to bed is that of negation, particularly with TermInfo vocabulary sets like SNOMED CT. The problem is that not all vocabulary sets support negation implicitly, by providing vocabulary terms that are already negated. SNOMED CT does. The big question then is, should you always use the implied negation in the vocabulary set if it is available; or should you sometimes, or never use it.

The alternative, for HL7 v3 at least, is to use a negation indicator, messaged as a negationInd attribute on the element in question... so this is effectively metadata, and the problem with metadata is that there is no guarantee that the receiver interprets it correctly, if at all. For many use cases, this probably doesn't matter much, but for clinical diagnosis and decision making, for allergies, for drug interactions, and even in the context of non-health applications like Corrections and Defense, Person-of-Interest queries need to properly take into account null flavours and negations; so there is a strong Public Health and Public Safety aspect to this discussion as well.

So it is an important concept, and people need to reach agreement on the correct way to do this; however, this issue goes back a number of years, so I'm curious to see where it goes. My own thoughts are that a better way to do this from the start would have been to use a tri-state negation indicator, which indicates "positive", "requires negation", or "implictly negated"... but it's too late for that now, and it always has been.

Here are the details from the RIMBAA forum (via Rob Hausum, MD, Hausum Consulting):
The TermInfo negation discussion at the Atlanta WGM will be held in Q1 Tuesday (tomorrow).  Following a brief introduction, we intend to devote the remainder of the quarter to this topic.  We would like to come away from the quarter with a concrete plan to create and provide guidance on this important topic.  That may involve a focused TermInfo ballot on negation, but the specific form and scope is still open for discussion.

For those who aren't in Atlanta, we expect to have remote participation capability via GoToMeeting (details below).  Please join the discussion, or, if you are unable to attend either in person or remotely, feel free to pass along any comments/questions/concerns.

Rob

GTM details:

1.  Please join my meeting.

2.  Use your microphone and speakers (VoIP) - a headset is recommended.
Or, call in using your telephone.

Denmark: +45 (0) 69 91 89 33
Australia: +61 2 8355 1031
Austria: +43 (0) 7 2088 1033
Belgium: +32 (0) 28 08 4342
Canada: +1 (647) 497-9371
Finland: +358 (0) 942 41 5770
France: +33 (0) 182 880 159
Germany: +49 (0) 811 8899 6925
Ireland: +353 (0) 19 030 050
Italy: +39 0 693 38 75 50
Netherlands: +31 (0) 208 080 208
New Zealand: +64 (0) 9 925 0481
Norway: +47 21 54 82 21
Spain: +34 911 82 9890
Sweden: +46 (0) 852 500 179
Switzerland: +41 (0) 435 0167 65
United Kingdom: +44 (0) 207 151 1806
United States: +1 (213) 493-0619

Access Code: 912-947-024
Audio PIN: Shown after joining the meeting

Meeting ID: 912-947-024

GoToMeeting®
Online Meetings Made Easy®

Thursday, May 02, 2013

Loose boats and gliders

loose boats and gliders
children floating
away over rocks
under supervision still
throwing stones at the
waves over time
here they come; there they go
turn and they play
face down the ocean
now overconfident
perhaps, tiny creatures
intertidal safety zones
safe in untidy interzones
carrying with them
nets and shrimp
pockets and stones

Friday, April 05, 2013

Great interview with John Resig, discussing jQuery, Khan Academy, and the ubiquity of Selectors API.

http://net.tutsplus.com/articles/where-in-the-world-is-john-resig/

Sunday, March 24, 2013

My Review of JavaScript Enlightenment

Originally submitted at O'Reilly

From Library User to JavaScript Developer


Absolutely essential reading

By Piers Hollott from Victoria, BC on 3/24/2013

 

5out of 5

Pros: Helpful examples, Well-written

Best Uses: Intermediate, Expert

Describe Yourself: Developer

If you work with JavaScript, maybe you love it, maybe you hate it. Cody's book is a constant reminder for me why I love working with JavaScript. It's a unique language, and this is a unique book. As soon as I finished, I went back to the beginning and started again.

(legalese)

Thursday, March 21, 2013

I mean, it's almost with sadness that I am uninstalling Opera, but something happened a while back, and all political arguments aside, I'm just as happy with Firefox. You see, I really liked Opera Unite, which embedded a web server inside the Opera browser. All sorts of potential in that idea, although realistically, this allows you to operate an intermittent file server. For testing purposes, however, it meant I didn't need to run a separate web server. Anyway, water under the bridge, Opera is no longer supporting this feature.

At a time when people appear to be switching back to Firefox from Chrome because newer builds of Chrome are apparently slower... I might start running the Aurora stable nightly builds of Firefox. I have a love/hate relationship with Firefox. At the moment, because Firefox is providing the only decent SVG support for mobile devices, I love it again, even though the only mobile device I have is Android, and I like Chrome for Android a lot. I just have no room for Opera.

Thursday, March 07, 2013

Firefox OS and Mobile Health

I have to say, I am very excited about Mozilla's Firefox OS, formerly Boot to Gecko, a Mobile OS built on web standards like HTML5, CSS and JavaScript, powered by a small Linux kernel. The OS is going to target less expensive phones, without requiring the power that Android or iOS do. If you were thinking PhoneGap, a Firefox OS app is much simpler than that. Why am I embedding in WebKit when I can boot to Gecko?

So the downside will be market penetration. In Canada or the States, or the UK. In Brazil, in Mexico, in eastern Europe, these phones could hit a sweet spot and build a strong developer community.

And this is why I'm excited. The real strength of mobile health is not going to be iPhone apps for American Doctors; it's going to be useful tools for areas that aren't already serviced by Epic or Meditech... In LMIC countries, a suite of mobile medical tools, and particularly one you might modify or extend yourself, that will be invaluable.

The developer phones are cool and orange as well.


Wednesday, February 13, 2013

Android FaceDetection

How could a book application interact with facial detection?

If Harry Potter has taught me anything, it is that any book can conceal a rotten core of evil, or a path to enlightenment. And yes, your typical book will not communicate by talking, or bleeding...
On the other hand, I've been experimenting with the FaceDetection capabilities which Android ICS introduced. A front facing camera can take a snapshot, say, each time you advance a page while you are reading. FaceDetection can do several things; for instance, count faces, track eyes and mouthes to see who is smiling, and register when a reader is new.

So the book can recognize the audience, as a proxy for the author. Consider this: as you are reading a book, it could refuse to go to the next page until you shared the text with another set of eyes. Perhaps more useful, a book app could track progress for a number of readers, based on their faces.
Wheels within wheels - well we're at it, the more I work with Firefox OS and Gaia, the more I want to use it as a platform to build a more interactive ePub reader, leveraging the Web Activity model. See below. Think books which can talk to each other using Web Activity sharing.

The thing is, FacialDetection may be easily fooled by a photograph... Might not be as secure as exchanging secure tokens, but once an application has authenticated that token, it can remain authenticated until the status of the detected face or faces changes, based on periodic snapshots.

Once authenticated with a single face, an app could drop authentication when this face goes away or a face is added. As long as your face is associated with a secure token, and your face does not change, this should be satisfactory to maintain authentication.

What are some ways a book app could interact differently if it could recognize its audience?

Tom Riddle me this.