⚠️ これは 非公式の翻訳サイトです。DCMTK / OFFIS とは無関係です。正確な情報は 原文(https://support.dcmtk.org/docs/mod_dcmsr.html) を参照してください。

dcmsr: 構造化レポートのライブラリとユーティリティアプリ

このモジュールには、DICOM 構造化レポート(SR)文書の読み込み・書き込み・作成・変更・アクセス・印刷・描画を行うクラスが含まれます。対応する SOP クラスの一覧は DSRTypes::E_DocumentType を参照してください。

主なインターフェースクラスは次のとおりです。

SR テンプレートを実装する際に役立つクラスを、さらにいくつか挙げます。

現在、次の 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;