dcmsr: 構造化レポートのライブラリとユーティリティアプリ
このモジュールには、DICOM 構造化レポート(SR)文書の読み込み・書き込み・作成・変更・アクセス・印刷・描画を行うクラスが含まれます。対応する SOP クラスの一覧は DSRTypes::E_DocumentType を参照してください。
主なインターフェースクラスは次のとおりです。
- DSRDocument
- DSRDocumentTree
- DSRDocumentSubTree
- DSRDocumentTreeNode
- DSRContentItem
- DSRCodedEntryValue
SR テンプレートを実装する際に役立つクラスを、さらにいくつか挙げます。
現在、次の SR テンプレートが実装されています(詳細は注記を参照)。
- TID300_Measurement
- TID1001_ObservationContext
- TID1204_LanguageOfContentItemAndDescendants
- TID1411_VolumetricROIMeasurements
- TID1419_ROIMeasurements_Measurement
- TID1500_MeasurementReport
- TID1501_MeasurementGroup
- TID1600_ImageLibrary
- TID4019_AlgorithmIdentification
ツール
このモジュールには次のコマンドラインツールが含まれます。
- dsr2html: DICOM SR ファイルとデータセットを HTML/XHTML に描画
- dsr2xml: DICOM SR ファイルとデータセットを XML に変換
- dsrdump: DICOM SR ファイルとデータセットをダンプ
- xml2dsr: XML 文書を DICOM SR ファイルに変換
使用例
次の例は、DICOM 構造化レポートを読み込み、その内容を HTML 形式で描画する方法を示します。
DcmFileFormat fileformat;
OFCondition status = fileformat.loadFile("test.dcm");
if (status.good())
{
DSRDocument document;
status = document.read(*fileformat.getDataset());
if (status.good())
{
status = document.renderHTML(cout);
if (status.bad())
cerr << "Error: cannot render SR document (" << status.text() << ")" << endl;
} else
cerr << "Error: cannot read SR document (" << status.text() << ")" << endl;
} else
cerr << "Error: cannot load DICOM file (" << status.text() << ")" << endl;
次の例は、DICOM 構造化レポートを作成してファイルに保存する方法を示します(詳細は mkreport のソースファイルを参照してください)。
DSRDocument document;
document.setPatientName("Doe^John");
/ ... /
DSRDocumentTree &tree = document.getTree();
tree.addContentItem(DSRTypes::RT_isRoot, DSRTypes::VT_Container);
tree.getCurrentContentItem().setConceptName(DSRCodedEntryValue(/ some code /));
tree.addChildContentItem(DSRTypes::RT_hasObsContext, DSRTypes::VT_Code, CODE_DCM_ObserverType);
tree.getCurrentContentItem().setCodeValue(CODE_DCM_Person);
/ ... /
DcmFileFormat fileformat;
OFCondition status = document.write(*fileformat.getDataset())
if (status.good())
{
status = fileformat.saveFile("test.dcm", EXS_LittleEndianExplicit);
if (status.bad())
cerr << "Error: cannot save DICOM file (" << status.text() << ")" << endl;
} else
cerr << "Error: cannot write SR document (" << status.text() << ")" << endl;
また、次の例のように、文書ツリーの多くのプロパティには直接アクセスして変更することもできます。
DSRDocument document(DSRTypes::DT_KeyObjectSelectionDocument);
/ ... /
DSRDocumentTree &tree = document.getTree();
tree.addContentItem(DSRTypes::RT_isRoot, DSRTypes::VT_Container);
DSRCodedEntryValue *codePtr = tree.getCurrentContentItem().getConceptNamePtr();
if (codePtr != NULL)
codePtr->setCode("113000", "DCM", "Of Interest");
/ ... /
tree.addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Image);
DSRImageReferenceValue *imagePtr = tree.getCurrentContentItem().getImageReferencePtr();
if (imagePtr != NULL)
{
imagePtr->setValue(DSRImageReferenceValue(UID_UltrasoundMultiframeImageStorage, / image UID /));
imagePtr->setPresentationState(DSRCompositeReferenceValue(UID_GrayscaleSoftcopyPresentationStateStorage, / GSPS UID /));
imagePtr->getFrameList().addItem(2);
imagePtr->getFrameList().addItem(5);
}
/ ... /
さらに、新しく作成した DSRDocumentTreeNode インスタンスへのポインタを受け取る、専用の DSRDocumentTree::addContentItem() および DSRDocumentTree::addChildContentItem() メソッドもあります。
文書ツリーを走査して特定の条件を満たすコンテンツアイテムを探す方法はいくつかあります。ここではそのうちの2つを示します。
DSRDocument document;
/ ... /
DSRDocumentTree &tree = document.getTree();
/ #1: search for content items with a certain concept name /
if (tree.gotoNamedNode(CODE_DCM_ProcedureReported))
{
do {
const DSRDocumentTreeNode *node = tree.getNode();
/ and check for expected value type /
if ((node != NULL) && (node->getValueType() == DSRTypes::VT_Code))
{
/ do something useful with the CODE content item /
}
} while (tree.gotoNextNamedNode(CODE_DCM_ProcedureReported, OFFalse /searchIntoSub/));
}
/ #2: search for content items using a more complex filter /
DSRDocumentTreeNodeAndFilter filter;
filter.addFilter(new DSRDocumentTreeNodeValueTypeFilter(DSRTypes::VT_Code));
filter.addFilter(new DSRDocumentTreeNodeRelationshipTypeFilter(DSRTypes::RT_hasConceptMod));
filter.addFilter(new DSRDocumentTreeNodeHasChildrenFilter());
if (tree.gotoMatchingNode(filter))
{
/ found first "has concept mod CODE" content item that has children /
}
最後の例は、SR テンプレートの扱い方を示します。たとえば TID 1500(Measurement Report)に基づく DICOM 構造化レポートを作成する場合です。
TID1500_MeasurementReport report(CMR_CID7021::ImagingMeasurementReport);
report.setLanguage(CID5000_Language::English);
report.getObservationContext().addPersonObserver("Doe^Jane", "Some Organization");
/ ... /
CMR_TID1411_in_TID1500 &volumetric = report.getVolumetricROIMeasurements();
volumetric.setActivitySession("1");
volumetric.setTrackingIdentifier("aorta reference region");
/ ... /
CMR_TID1419_in_TID1411_in_TID1500 &measurement = volumetric.getMeasurement();
measurement.createNewMeasurement(CMR_CID7469::Volume, CMR_TID1419_in_TID1411_in_TID1500::MeasurementValue("15", CMR_CID7181::CubicMillimeter));
measurement.setDerivation(CMR_CID7464::StandardDeviation);
/ ... /
DSRDocument document;
document.setPatientName("Last Name^First Name");
/ ... /
if (document.setTreeFromRootTemplate(report).good())
document.print(cout, DSRTypes::PF_printTemplateIdentification);
else
cerr << "Error: cannot set template content as document tree" << endl;