Implementing an External Preprocessor for MIRC Clinical Trials
The article is intended for software developers working on clinical trials which require the imposition of special rules on the types of objects which are accepted into the trial. To fully understand this article, you may wish to reference the RSNA MIRC Source Code and Implementing an External Database Interface for MIRC Clinical Trials.
1 The ObjectProcessor
The ObjectProcessor is a component of a MIRC Storage Service. It processes files which are received from DICOM and HTTP sources and either creates or updates MIRCdocuments to reference them. The processing can include:
- External preprocessing.
- Queuing for export to DICOM or HTTP destinations.
- Queuing for processing by an external database interface.
This article describes how to develop a preprocessor and connect it to the ObjectProcessor. A preprocessor is a Java class to which the ObjectProcessor passes an object encapsulating a file. The preprocessor returns a result indicating whether the object is acceptable. If it is acceptable, the Object processor continues processing the file. If it is not, the ObjectProcessor quarantines it. The ObjectProcessor dynamically loads the preprocessor's class, obtaining the name of the class from the Storage Service’s trial/trial.xml configuration file. This file is typically configured by the trial administrator through the Admin Service.
2 The Object Classes
MIRC provides four classes to encapsulate files of various types. See The MIRC Object Classes for details. The classes are:
3 The PreprocessorAdapter Class
The PreprocessorAdapter class, org.rsna.mircsite.util.PreprocessorAdapter, is a base class for building an external preprocessor. To be recognized and loaded by the ObjectProcessor, an external preprocessor class must be an extension of PreprocessorAdapter.
All the methods of the PreprocessorAdapter class return an integer status value. Static values for the statuses are defined in the class. There are two values:
- STATUS_OK means that the object meets the external criteria for inclusion in the study.
- STATUS_REJECT means that the object is to be excluded from the study, in which case the ObjectProcessor will quarantine it.
All the methods of the PreprocessorAdapter class return the value STATUS_OK.
4 Extending the PreprocessorAdapter Class
To implement a useful preprocessor, you must extend the PreprocessorAdapter class. Since the PreprocessorAdapter class implements dummy methods returning STATUS_OK, your class that extends PreprocessorAdapter only has to override the methods that apply to your application. If, for example, you only care about XML objects, you can just override the process(XmlObject xmlObject) method and let PreprocessorAdapter supply the other process() methods, thus ignoring objects of other types.
If you want to reject objects of certain types, you must override the process() method for that type and return STATUS_REJECT.
The preprocessor can be also be used to modify objects before any further processing takes place. The various object classes provide access to the data and you can programmatically do anything you want with it (it's great to be king).
If you want to log information to the Tomcat/logs/stdout.log directory, the PreprocessorAdapter class provides a static org.apache.log4j.Logger object called logger. The MIRC site typically runs at the logging level WARN, so unless you change that, you should make calls like:
If you want to log information that will be visible through the Show Log button on the admin page, you can use the static methods in the org.rsna.mircsite.log.Log class. Remember, however, that the Log class only maintains a circular buffer of the past 200 entries, so if you make many calls, you may be removing log entries made by other objects.
5 Connecting Your Preprocessor Class to MIRC
After building your preprocessor and producing a jar file for it, you have to install it and configure it. The preprocessor is part of a Storage Service, and each storage service can have its own (possibly different) external preprocessor. Therefore, the interface is installed and configured at the level of the Storage Service.
The preprocessor jar file must be installed in the Tomcat/webapps/[storageservice]/WEB-INF/lib directory, where [storageservice] is the name of the storage service for the clinical trial. Do not place the jar file in the Tomcat/shared/lib directory. Doing so will cause the class not to load.
The MIRCsite-installer program always deletes the Tomcat/webapps/[storageservice]/WEB-INF/lib directory during an upgrade to prevent old libraries from contaminating a new release. This has the unfortunate effect of deleting the database interface jar file. You must therefore be careful to restore the preprocessor jar file after an upgrade.
5.2 Configuring MIRC for Your Preprocessor Class
The Admin Service provides a web interface for setting the configuration parameters. The interface is accessed by clicking the Update Configuration button in the DICOM Service column on the admin page. In the Preprocessor section of the resulting page, there are two parameters:
- Enabled determines whether objects are preprocessed.
- Preprocessor class name specifies the fully qualified name of the class. If this field is empty, the system will operate as if preprocessing is disabled.
5.3 Operational Note
When a file is received, the PreprocessorAdapter attempts to figure out the type of file by parsing it. It first tries to parse the file based on the extension of its filename. If that fails, it tries all the untried classes in the order:
If none of the objects can be instantiated, a FileObject is created for the file. If the file is a binary object that is neither a DICOM file nor a zip file, the attempt to instantiate the XmlObject will cause the Xerces parser to encounter a fatal, but not serious, error, which it logs to the console stream where it can be seen in the log viewer or by accessing the Tomcat/logs/stdout.log file. The error is not serious because although the Xerces parser fails, it is reinstantiated whenever it is needed, so there is no effect on the operation of the system. This error will never occur in trials which produce only DICOM, zip, or XML files.