DICOM Medical Image processing: In-depth analysis of Orthanc SQLite, Understanding Wado & RESTful APIs

Source: Internet
Author: User
Tags sha1 sqlite database sqlite query uuid


background:


The previous blog post simply translated the CodeProject "using Orthanc Plugin SDK to develop Wado plugin" on the Orthanc website. It mentions that Orthanc supports fast queries from the 0.8.0 version, whereas the original Wado request needs to be positioned directly with the rest API in Orthanc. So why did the previous Orthanc have to step up to locate the instance of the Wado request? How is the new version improved? This blog post analyzes Orthanc's embedded SQLite database to analyze Orthanc's restful API mechanism and the implementation of Wado services.


Orthanc uuid and dicom UID:1) Orthanc Plugin SDK Simulation implementation Wado Server


The Locatestudy, locateseries, and Locateinstanc functions mentioned in the previous blog post are not directly querying the UID of each level (Studyuid, Seriesuid, Instanceuid) that the Wado request passed in. Instead, it is done internally by building an equivalent restful API. For example, the test DCM file is named TEST1.DCM, and its corresponding level three UID is:


studyuid=1.3.6.1.4.1.30071.6.176694098609799.4240639413125000,

seriesuid=1.3.6.1.4.1.30071.6.176694098609799.4240639413125000.1,

instanceuid (i.e. SOP Instance UID) =2.16.840.114421.81623.9430067258.9493139258, the normal Wado protocol requires a connection to:

http://localhost:8042/wado?requestType=WADO&studyUID=1.3.6.1.4.1.30071.6.176694098609799.4240639413125000 &

seriesuid=1.3.6.1.4.1.30071.6.176694098609799.4240639413125000.1&

objectuid=2.16.840.114421.81623.9430067258.9493139258


In the normal way, should be directly using the SQL statement in the specified database directly search Wado request in the three-level UID, and in the Orthanc Plugin SDK implementation of the Wado plug-in, is hierarchical, the detailed process is as follows:



study level : First, build the http://localhost:8042/studies request in the Locatestudy function, take advantage of the built-in rest The API service obtains the UUID of all studies in the current data (the transition relationship between the UUID and the Dicom uid is described later); second, each studyuuid in Locatestudy, constructs http://localhost:8042/ Studies/xxxx-xxxx-xxxx-xxxx, by contrast, returns the study["Maindicomtags" ["studyinstanceuid"] tag value in JSON data with Wado in Studyuid, Realize the function of positioning study;



Series level : Same as study, constructs http://localhost:8042/series to get all seriesuuid, then constructs http://localhost for each seriesuuid : 8042/series/xxxx-xxxx-xxxx-xxxx, comparing the return value of series["Maindicomtags" ["Seriesinstanceuid"] and seriesuid, to achieve the function of positioning series;



instance level : Constructs http://localhost:8042/instances to get all instanceuuid, then constructs http://localhost for each instanceuuid : 8042/instances/xxxx-xxxx-xxxx-xxxx compares the instance["Maindicomtags" ["Sopinstanceuid"] in the return value with Wado in the OBJECTUID request, The purpose of achieving the final positioning of the image.


2) Orthanc uuid and dicom UID


The above implementation is not very cumbersome ah, haha. Fortunately, the official Plugin SDK explains that blog post gives the latest version of the positioning method, the specific implementation can be found in my last blog post (http://blog.csdn.net/zssureqh/article/details/41836885). So why does Orthanc need such a tedious positioning image at first? Here we first briefly analyze how the Orthanc internal is to mark the uniqueness of the file, the subsequent chapters detailed analysis before the Orthanc simulation Wado service why so cumbersome.



In the Orthanc source code there is such a class dicominstancehasher (defined in DicomInstanceHasher.h, implemented in DicomInstanceHasher.cpp), as described in its comments:





/** 
* This class implements the hashing mechanism that is used to 
* convert DICOM unique identifiers to Orthanc identifiers. Any 
* Orthanc identifier for a DICOM resource corresponds to the SHA-1 
* hash of the DICOM identifiers.
* \note SHA-1 hash is used because it is less sensitive to 
* collision attacks than MD5. <a 
* href="http://en.wikipedia.org/wiki/SHA-256#Comparison_of_SHA_functions">[Reference]</a> 
**/





From the description we can know Orthanc internal use SHA1 (Baidu Encyclopedia: Wikipedia:) algorithm to calculate the DCM file unique identification, the specific calculation process is:



Patientid corresponding UUID: That is, enter "Patientid" directly into the SHA1 calculation function to obtain the SHA1 value



Studyuid corresponding UUID: Enter "patientid+" in the SHA1 calculation function | +studyuid ", Get SHA1 value



Seriesuid corresponding UUID: Enter "patientid+" in the SHA1 calculation function | +studyuid+ "|" +seriesuid ", Get SHA1 value



Instanceuid corresponding UUID: Enter "patientid+" in the SHA1 calculation function | +studyuid+ "|" +seriesuid+ "|" +instanceuid ", Get SHA1 value



This is the transition between the orthancuuid and the Dicom uid, and the next section explains the database and gives a real-world example.


Orthanc SQLite Introduction:1) Orthanc SQLite Database list Description:


Orthanc uses the SQLite embedded database, the operation of the database in the project code integration, so in the use of the process can not feel the management of the database, which also supports the Orthanc flagship lightweight, convenient, networking advantages. The following is a brief introduction to the logic of the Orthanc sqlite data table:



The default storage location for SQLite database files is:C:\Orthanc\OrthancStoragef\index(its true suffix is db3). Using the SQLite visualizer to open the index file, you can see the following tables:






The approximate purpose of the tables can be inferred from the name of the table: for example, Attachedfiles is the record of adding files, changes may be modified (delete, anonymity, etc.), Dicomidentifiers is the Dicom file identifier (UID at each level), Exportedresources may be an export or upload operation, globalproperties should be a global attribute, Maindicomtags should be a JSON-formatted data Orthanc returned to rest API operations, metadata is the data body, The resources should be a file body tag (Patientrecyclingorder is temporarily unclear, see below for an analysis).


2) Orthanc main data Operation class Introduction:


Orthanc source code has the Databasewrapper class, which has the following comments:





/** 
* This class manages an instance of the Orthanc SQLite database. It 
* translates low-level requests into SQL statements. Mutual 
* exclusion MUST be implemented at a higher level. 
**/





This class is Orthanc Operation SQLite Database encapsulation class, specifically related to the SQLite database underlying operations are done by Databasewrapper. In contrast to the table in index seen in the previous section, the main functions of the Databasewrapper class are categorized as follows:


Data Sheet Databasewrapper operation function
Attachedfiles AddAttachment
DeleteAttachment
Lookupattachment
Listavailableattachments
Resources Createresource
Deleteresource
getResourceType
Getresourcecount
Lookupresource
Metadata Deletemetadata
Getallmetadata
GetMetaData
Getmetadataasinteger
Lookupmetadata
Setmetadata


You'll also see a number of functions that get each table field, such as Getpublicid, Getchildrenpublicid, and so on.


Orthanc in the SQLite instance test:


After a rough understanding of the basic structure of the SQLite database in Orthanc, take a look at the example test. As described in blog post (http://blog.csdn.net/zssureqh/article/details/41836885), there are several ways to add data to Orthanc, command-line tools, REST APIs, and Web pages. Below we test real data uploads for Orthanc's own explorer and DCMTK Toolkit Storescu.exe.


SQLite Data Write logic instance test1) Drag & Drop test in Explorer:


First open the Orthanc browsing interface: Http://localhost:8042/app/explorer.html#upload






Drag any image into the browser and click "Start the Upload" until the green ' done ' appears, indicating that the upload was successful.









The database changes as follows:





2) Storescu.exe test:


The above uses Orthanc embedded Explorer to successfully upload and write to the database. This time using Storescu.exe, the Orthanc as Dicom server to view the data write, write instructions as follows:



storescu.exe-d localhost 4242-aet zssure-aec orthanc c:\test2.dcm



After completion, the database changes as follows:





sqlite query logic test:


There are two ways to complete the addition of data to the Orthanc embedded SQLite database (and the rest API Third Way, see the previous blog: because the principle and the same as in the Explorer is not described separately), and observed the real changes in the database, But the exact field meaning may not be clear at the moment, so let's use the rest API to read the database and try to analyze what it means.


1) Patients:


Curl Http://localhost:8042/patients






The returned results are shown by comparing the database changes observed in the previous section to the following: The two patient UUID returned are recorded in rows 4th and 8 of the publicID column in the Resources table, and their corresponding internalid are 44 and 48 respectively. So we can infer that the resources should be the records of our uploaded files, the following to verify our conjecture.



According to the previous section of the analysis, the publicid should be the UUID corresponding to the Dicom uid, which is the SHA1 computed value. Open the online computing SHA1 website: http://www.seacha.com/tools/sha1.html. Follow the previous section to analyze the level UID of the input test1.dcm, and the results are as follows:






We can see that the first four records in the resources table are stored in Instanceuuid, Seriesuuid, Studyuuid, and Patientuuid, respectively, by level depth, and these uuid are calculated from the dicom level UID SHA1. If you are interested, you can verify the following four records, naturally the same meaning. So far we have figured out the significance of the resources table, which is the UUID used to store dicom images.


2) Studies:


Curl Http://localhost:8042/studies



Returns the result as,






The third record of each group in the resources table of the above analysis, that is, 43 and 47 rows in the table.


3) Series:


Curl Http://localhost:8042/series



Returns the result as,






The second bar of each group of records in the resources table, with rows 42 and 46 in the table.


4) Instances:


Curl Http://localhost:8042/instances



Returns the result as,






The first bar of each group of records in the resources table, with rows 41 and 45 in the table.


5) View each patient content:


Curl Http://localhost:8042/patients/64d6f8a0-ea0ffdb2-a14d1488-4fa7879c-2d9758d8






Comparing the analysis of the previous database, it is found that most of the fields can see the corresponding values directly in the database, as shown in:





6) View specific instance content


Because viewing the study and series levels is similar to viewing the patient level, you can look directly at the query results for the specific instance (that is, the Dicom file) and enter the instructions:



Curl http://localhost:8042/instances/064123d1-803dde30-f81071dc-cb2aad3b-bd246b7b






The above results can be found directly in the database, as shown in:






So far we have seen the familiar "SOP Instance UID", originally stored in the Dicomidentifiers table.



From the above several instances of the test we also roughly guess the Orthanc sqlite database in the role of the tables, the Resources table is the use of SHA1 to calculate the UUID uniquely identify our DCM file The Dicomidentifiers table records the Dicom UID of the corresponding DCM files, presumably this is also necessary to locate the file in the Wado protocol; The Maindicomtags table stores the main types of tags that correspond to the DCM files, including the group number, Element number, and the range data. The association between the tables is done through the internalid in the Resources table, and Internalid is the primary key (PK) for most tables.



Here This article can be finished, has reached the analysis of the purpose of Orthanc SQLite, but it is not clear to see the rest API and Wado difference. To this end, but also in order to better understand the operation of Orthanc, and then add a section, through a single-step debugging to deeply analyze the implementation mechanism of ORTHANC, to achieve in-depth analysis of the realm.


Orthanc SQLite Summary:





A short translation of the Plugin SDK development documentation from the Orthanc official was given in the previous blog post, which was noted before the 0.8.0 release, Orthanc is using the built-in restful API to simulate the implementation of Wado services, It is not a direct response to a Wado request sent by the browser. The previous article has described how to compile and install the official WadoPlugin.dll, here in the analysis of SQLite based on a single-step debugging way to see how early Orthanc is the use of RESTful API to simulate the implementation of Wado services.


RESTful API emulation Wado


The official website gives the use of built-in RESTful API simulation Wado code in the WadoPlugin.cpp Wado function, the most important of which is locatestudy, locateseries and locateinstance three positioning functions. is a single-step debug result at the Locatestudy level:






As you can see inside the Locatestudy function, The first is to use the Getallpublicid function in the DatabaseWrapper.cpp to extract all the publicid from the resources table of the SQLite database, as we analyzed above, each uploaded file has a unique UUID format of publicid.



Then, within the Locatestudy function, all the publicid that were previously returned are iterated through and the resource is positioned for each of the/studies/{publicid}. The function used is Lookupresource (also in DatabaseWrapper.cpp). As you can see from the Resources table, the function queries out the Internalid and resourcetype two fields according to publicID. View the type resourcetype definition of the Lookupresource function parameter type: The second column field in the Resources table stores the publicid corresponding resource level, which is divided into patient (=1) according to the DICOM3.0 standard. Study (=2), Series (=3), Instance (=4) level four, as defined in Enumeration.h:





Enum Resourcetype{resource
enum ResourceType
{
ResourceType_Patient = 1,
ResourceType_Study = 2,
ResourceType_Series = 3,
ResourceType_Instance = 4
};
type_patient = 1,resourcetype_study = 2,resourcetype_series = 3,resourcetype_instance = 4};





The following directly post debugging:





















You can see the approximate database retrieval process in response to Wado requests in Orthanc, starting with querying all publicid in the Resources table (because the initial query cannot take advantage of the Studyid/seriesid/in the Wado request Objectid calculates any valid UUID), then constructs a URI in the form of/studies/{id}, using the RESTful API mechanism query to assemble the publicid at each level, The relationship between its levels is indicated by the ParentID field in the table resources, and the uniqueness is determined by the primary key Internalid. This is the main reason why the RESTful API query database has been launched several times, and after all levels publicid and internalid are obtained, it is from the Dicomidentifiers table, The Maindicomtags table and the metadata table extract the Dicom file key information operation; it is natural to return the resulting image of the query to the browser side (which can be returned in dicom format or JPEG thumbnail).



Note: the type recorded in table metadata is defined by the Enumerations.h file, as follows:





enum MetadataType
{
MetadataType_Instance_IndexInSeries = 1,
MetadataType_Instance_ReceptionDate = 2,
MetadataType_Instance_RemoteAet = 3,
MetadataType_Series_ExpectedNumberOfInstances = 4,
MetadataType_ModifiedFrom = 5,
MetadataType_AnonymizedFrom = 6,
MetadataType_LastUpdate = 7,
// Make sure that the value "65535" can be stored into this enumeration
MetadataType_StartUser = 1024,
MetadataType_EndUser = 65535
};





It can be found that there are remoteaet types, so speculation may be related to DICOM protocol, used to record the AE Title on the upload side, verified by the input instruction as follows:



directive:storescu.exe-d localhost 4242-aet zssure-aec orthanc c:\Slice_0010.dcm



Test results:





Direct implementation of Wado


After analyzing the original Wadoplugin query method with low efficiency, we follow the same way to step through debugging to see the new Orthanc pluginsdk query process. Specific as follows:












The above series shows that the new Orthanc Plugin SDK can easily read the publicid of the specified instance from the SQLite database in three steps (that is, the UUID above); Instanceuuid Post-construction/instances/{id } type of restful API URI to get the file information directly from the Orthanc database. This improves efficiency by reducing the number of times the database is queried. Careful analysis can be found that the original PLUGINSDK need to query multiple databases because Orthanc in the Dicom file and related information at different levels to classify the information stored, so the extraction needs to be positioned separately and then the query results are combined. Also open the Orthanc storage directory can be found for each DCM file Orthanc with a publicid two-level directory to store: the first level directory is the MD5 value of the first 2 bytes of the file, the second level is the last two bytes. As shown in the following:









At this point can clearly understand the Orthanc underlying SQLite database structure and related operations, in order to be compatible with the RESTful API and DICOM3.0 standards, the logical design of the database is very subtle, follow-up can be further studied.





Follow-up column blog introduction


Fo-dicom build a simple dicom server server


[email  Protected]

time: 2014-12-10 span>


Dicom medical Image processing: In-depth anatomy of Orthanc SQLite, Understanding Wado & RESTful APIs

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.