最近公司跟西门子合作,开发他们需要的DR采集工作站的软件。接到一个需求是新的法规标准需要生成累计剂量报告的功能,需求描述是:“该系统的辐射剂量结构报告应包含IEC 61910-1:2014之5.1.2中要求(应)的数据元素;辐射剂量结构报告宜包含IEC 61910-1:2014之5.1.2中要求(宜)的数据元素。”
看到需求时不明所以,找来标准的条款看,如下图所示,英文的看不太明白。于是再找来对应的中文翻译版本来看,还是不知道这个报告应该长什么样。
后面再问西门子,要他们的CT设备生成的剂量报告来作参考,是一个DCM文件。用软件打开来看,跟dcm格式的图像还是不一样的,如下图。
这下终于有点眉目了,就要把标准里说的那个信息写到一个DCM文件里。接下来就是要研究用哪些DICOM标签来存放这些信息了。因为之前的软件能生成DCM格式的图像,知道一张图像里要用DICOM写入哪些数据,也用代码调用了哪些DCMTK函数可参考,于是信心大增。
用软件查看所有的DICOM标签,如下图。发现实在太多了,这么多要一个个写入,还要研究哪个标签要可以写入什么数据,标签要怎么嵌套。查了一下DICOM标准,看了一些标签的意思,如果要每个标签都自己写将会是很大的工作量。于在网上找看有没有实现类似报告的代码。还真找到了2个。链接如下:
Howto MammoCADSR - DCMTK - OFFIS DCMTK and DICOM ProjectsRedminehttps://support.dcmtk.org/redmine/projects/dcmtk/wiki/howto_mammocadsr#Howto-Create-a-Mammography-CAD-SR-DocumentDCMTK:使用dcmsr API创建示例结构化报告_C和C++技术博客-CSDN博客DCMTK:使用dcmsr API创建示例结构化报告使用dcmsr API创建示例结构化报告使用dcmsr API创建示例结构化报告#include "dcmtk/config/osconfig.h" #include "dcmtk/ofstd/ofconsol.h" #include "dcmtk/dcmsr/dsrdoc.h" #include "dcmtk/dcmsr/codes/ucum.h"#include "dcmtk/dcmdata/dctk.h" //
https://cplusplus.blog.csdn.net/article/details/116811257?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-6.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-6.no_search_link
其中第2个链接里的代码非常有用,后面就基于它来改的。后面还遇到2个问题,就是不能显示中文,另一个是怎么打开已生成的报告文件并追加新的内容。第一个问题是要把字符集设为DSRTypes::CS_UTF8,不能用例子里的DSRTypes::CS_Latin1。第2个问题就看代码吧。
#include <StdAfx.h>
#include "DoseStructuredReport.h"
// 写入剂量报告
void DoseStructuredReport::WriteDSRDocument(DoseStructuredReport& DoseInfo, CString sFilePath)
{
LOG_DEBUGGING("%s", sFilePath);
// 剂量报告已经存在,就打开它,往后追加
if (FileUtility::FileExists(sFilePath))
{
AppendDSRDocument(DoseInfo, sFilePath);
return;
}
DSRDocument* pDoseDocument = new DSRDocument();
if (pDoseDocument == NULL)
{
LOG_DEBUGGING("pDoseDocument == NULL");
return;
}
WriteDSRDocumentHeadInfo(pDoseDocument, DoseInfo);
WriteDSRDocumentAccumulatedDoseInfo(pDoseDocument, DoseInfo);
StoreDSRDocumentToDcmFile(pDoseDocument, sFilePath);
delete pDoseDocument;
pDoseDocument = NULL;
}
// 追加内容到已有的剂量报告里
void DoseStructuredReport::AppendDSRDocument(DoseStructuredReport& DoseInfo, CString sFilePath)
{
LOG_DEBUGGING("");
DSRDocument* pDoseDocument = new DSRDocument();
if (pDoseDocument == NULL)
{
LOG_DEBUGGING("pDoseDocument == NULL");
return;
}
ReadDSRDocumentDcmFile(pDoseDocument, sFilePath);
WriteDSRDocumentAccumulatedDoseInfo(pDoseDocument, DoseInfo, TRUE);
StoreDSRDocumentToDcmFile(pDoseDocument, sFilePath);
delete pDoseDocument;
pDoseDocument = NULL;
}
// 读取剂量报告DCM文件
BOOL DoseStructuredReport::ReadDSRDocumentDcmFile(DSRDocument* pDoseDocument, CString sFilePath)
{
LOG_DEBUGGING("");
ASSERT(pDoseDocument != NULL);
DcmFileFormat *pDcmFileFormat = new DcmFileFormat();
if (pDcmFileFormat == NULL)
{
LOG_DEBUGGING("pDcmFileFormat == NULL");
return FALSE;
}
if (pDcmFileFormat->loadFile(CT2A(sFilePath)).bad())
{
LOG_ERROR("加载文件失败");
return FALSE;
}
BOOL bRet = FALSE;
DcmDataset *pDcmDataset = pDcmFileFormat->getDataset();
if (pDcmDataset != NULL)
{
pDoseDocument->getCodingSchemeIdentification().addPrivateDcmtkCodingScheme();
OFCondition Condition = pDoseDocument->read(*pDcmDataset,
DSRTypes::RF_readDigitalSignatures | DSRTypes::RF_acceptUnknownRelationshipType
| DSRTypes::RF_ignoreRelationshipConstraints | DSRTypes::RF_ignoreContentItemErrors
| DSRTypes::RF_skipInvalidContentItems);
if (Condition.good())
{
//StoreDSRDocumentToDcmFile(pDoseDocument, sFilePath + "22");//测试用
bRet = TRUE;
}
else
{
LOG_DEBUGGING("ERROR: could not read pDcmDataset into SR document [%s]", Condition.text());
}
}
else
{
LOG_DEBUGGING("pDcmDataset == NULL");
}
delete pDcmFileFormat;
pDcmFileFormat = NULL;
return bRet;
}
// 把剂量报告保存到DCM文件中
BOOL DoseStructuredReport::StoreDSRDocumentToDcmFile(DSRDocument* pDoseDocument, CString sFilePath)
{
LOG_DEBUGGING("%s", sFilePath);
ASSERT(pDoseDocument != NULL);
DcmFileFormat *pDcmFileFormat = new DcmFileFormat();
if (pDcmFileFormat == NULL)
{
LOG_DEBUGGING("pDcmFileFormat == NULL");
return FALSE;
}
BOOL bRet = FALSE;
DcmDataset *pDcmDataset = pDcmFileFormat->getDataset();
if (pDcmDataset != NULL)
{
pDoseDocument->getCodingSchemeIdentification().addPrivateDcmtkCodingScheme();
if (pDoseDocument->write(*pDcmDataset).good())
{
//CString sSpecificCharacterSet;
//LANGID lid = GetSystemDefaultLangID();
是中文系统就改变语言字符集,不然显示中文乱码
//if (lid == 0x0804)
//{
// sSpecificCharacterSet = _T("GB18030");
// pDcmDataset->putAndInsertString(DCM_SpecificCharacterSet, CT2A(sSpecificCharacterSet));
//}
//else//case 0x0409
//{
// sSpecificCharacterSet = _T("ISO_IR 100");
//}
if (pDcmFileFormat->saveFile(CT2A(sFilePath), EXS_LittleEndianExplicit).good())
{
bRet = TRUE;
}
else
{
LOG_DEBUGGING("ERROR: could not save pDcmDataset to file");
}
}
else
{
LOG_DEBUGGING("ERROR: could not write SR document into pDcmDataset");
}
}
else
{
LOG_DEBUGGING("pDcmDataset == NULL");
}
delete pDcmFileFormat;
pDcmFileFormat = NULL;
return bRet;
}
// 写入剂量报告的头信息,从病人图像的DCM信息里获取
void DoseStructuredReport::WriteDSRDocumentHeadInfo(DSRDocument* pDoseDocument, DoseStructuredReport& DoseInfo)
{
LOG_DEBUGGING("");
ASSERT(pDoseDocument != NULL);
pDoseDocument->createNewDocument(DSRTypes::DT_XRayRadiationDoseSR);
// 默认字符集, 这里要设为UTF8不然没法显示中文, 不能设为CS_Latin1
pDoseDocument->setSpecificCharacterSetType(DSRTypes::CS_UTF8);
// Study Instance UID
pDoseDocument->createNewSeriesInStudy(ConvertCStringToUTF8(DoseInfo.StudyInstanceUid).c_str());
// 如果送诊医院为空就写入操作医生
if (DoseInfo.ReferringPhysiciansName.IsEmpty())
{
pDoseDocument->setReferringPhysicianName(ConvertCStringToUTF8(DoseInfo.OperatorsName).c_str());
}
else
{
pDoseDocument->setReferringPhysicianName(ConvertCStringToUTF8(DoseInfo.ReferringPhysiciansName).c_str());
}
//pDoseDocument->setSeriesDescription(DoseInfo.SeriesDescription).c_str());
pDoseDocument->setSeriesDescription("Radiation Dose Information");
// 如果检查描述为空,就写入检查部位
if (DoseInfo.StudyDescription.IsEmpty())
{
pDoseDocument->setStudyDescription(ConvertCStringToUTF8(DoseInfo.BodyPartExamined).c_str());
}
else
{
pDoseDocument->setStudyDescription(ConvertCStringToUTF8(DoseInfo.StudyDescription).c_str());
}
pDoseDocument->setManufacturer(ConvertCStringToUTF8(DoseInfo.Manufacturer).c_str());
pDoseDocument->setManufacturerModelName(ConvertCStringToUTF8(DoseInfo.ManufacturersModelName).c_str());
pDoseDocument->setDeviceSerialNumber(ConvertCStringToUTF8(DoseInfo.DeviceSerialNumber).c_str());
pDoseDocument->setSoftwareVersions(ConvertCStringToUTF8(DoseInfo.SoftwareVersions).c_str());
pDoseDocument->setPatientName(ConvertCStringToUTF8(DoseInfo.PatientName).c_str());
pDoseDocument->setPatientSex(ConvertCStringToUTF8(DoseInfo.PatientSex).c_str());
pDoseDocument->setPatientBirthDate(ConvertCStringToUTF8(DoseInfo.PatientBirthDate).c_str());
pDoseDocument->setPatientID(ConvertCStringToUTF8(DoseInfo.PatientID).c_str());
}
// 写入累计剂量信息
void DoseStructuredReport::WriteDSRDocumentAccumulatedDoseInfo(DSRDocument* pDoseDocument, DoseStructuredReport& DoseInfo, BOOL bIsAppend)
{
LOG_DEBUGGING("");
ASSERT(pDoseDocument != NULL);
OFString sPosition;
if (!bIsAppend)
{
pDoseDocument->getTree().addContentItem(DSRTypes::RT_isRoot, DSRTypes::VT_Container);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("DT.01", "DCM", "X-Ray Radiation Dose Report"));
// 观察员内容 Observation Context
pDoseDocument->getTree().addContentItem(DSRTypes::RT_hasObsContext, DSRTypes::VT_PName, DSRTypes::AM_belowCurrent);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("IHE.02", OFFIS_CODING_SCHEME_DESIGNATOR, "Person Observer's Role in this Procedure"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue("Irradiation Administering");
pDoseDocument->getTree().addContentItem(DSRTypes::RT_hasObsContext, DSRTypes::VT_Text);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("IHE.04", OFFIS_CODING_SCHEME_DESIGNATOR, "Device Observer Manufacturer"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue(ConvertCStringToUTF8(DoseInfo.Manufacturer).c_str());
pDoseDocument->getTree().addContentItem(DSRTypes::RT_hasObsContext, DSRTypes::VT_Text);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("IHE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "Recording Observer's Organization Name"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue(ConvertCStringToUTF8(DoseInfo.InstitutionName).c_str());
}
else
{
pDoseDocument->getTree().gotoRoot();
pDoseDocument->getTree().goDown();
size_t tt = pDoseDocument->getTree().gotoNode("1.3");
// 由于医院名称是中文,读取后再写入就丢掉了,这里要重新写入
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("IHE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "Recording Observer's Organization Name"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue(ConvertCStringToUTF8(DoseInfo.InstitutionName).c_str());
LOG_DEBUGGING("追加剂量报告: %d", tt);
}
LOG_DEBUGGING("NodeID=%d, Level=%d, Position=%s, sPosition=%s", pDoseDocument->getTree().getNodeID(),
pDoseDocument->getTree().getLevel(), pDoseDocument->getTree().getPosition(sPosition).c_str(), ConvertUTF8ToCString(sPosition.c_str()));
// 累积投射的X射线剂量
pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Container);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("SH.06", OFFIS_CODING_SCHEME_DESIGNATOR,
ConvertCStringToUTF8(StringUtility::Format("Accumulated X - Ray Dose Data (%s, %s)", DoseInfo.SeriesDate, DoseInfo.SeriesTime)).c_str()));
pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Text, DSRTypes::AM_belowCurrent);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("RE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "Dose (RP) Total"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue(ConvertCStringToUTF8(StringUtility::Format(_T("%.10f Gy"), DoseInfo.DoseTotal)).c_str());
pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Text);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("RE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "Dose Area Product Total"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue(ConvertCStringToUTF8(StringUtility::Format(_T("%.10f Gy.m2"), DoseInfo.DoseAreaProductTotal)).c_str());
pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Text);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("RE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "Distance Source to Reference Point"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue(ConvertCStringToUTF8(StringUtility::Format(_T("%d mm"), DoseInfo.DistanceSourceToReferencePoint)).c_str());
pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Text);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("RE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "Reference Point Definition"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue(ConvertCStringToUTF8(DoseInfo.ReferencePointDefinition).c_str());
pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Text);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("RE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "Total Number of Radiographic Frames"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue(ConvertCStringToUTF8(StringUtility::Format(_T("%d"), DoseInfo.TotalNumOfRadiographicFrames)).c_str());
pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Text);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("RE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "Total Fluoroscopy Time"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue(ConvertCStringToUTF8(StringUtility::Format(_T("%d s"), DoseInfo.TotalFluoroscopyTime)).c_str());
pDoseDocument->getTree().goUp();
// 辐照事件X射线数据
pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Container);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("SH.06", OFFIS_CODING_SCHEME_DESIGNATOR,
ConvertCStringToUTF8(StringUtility::Format("Irradiation Event X - Ray Data (%s, %s)", DoseInfo.SeriesDate, DoseInfo.SeriesTime)).c_str()));
// 采集协议,这里只写部位
pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Text, DSRTypes::AM_belowCurrent);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("RE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "Acquisition Protocol"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue(ConvertCStringToUTF8(DoseInfo.BodyPartExamined).c_str());
// 开始的日期和时间
pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Text);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("RE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "DateTime Started"));
pDoseDocument->getTree().getCurrentContentItem().setStringValue((ConvertCStringToUTF8(DoseInfo.SeriesDate + _T(" ") + DoseInfo.SeriesTime)).c_str());
// 辐照事件类型
pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Text);
pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("RE.05", OFFIS_CODING_SCHEME_DESIGNATOR, "Irradiation Event Type"));
CString IrradiationEventType;
IrradiationEventType.Format(_T("%s %s %s"),
(DoseInfo.IrradiationEventType & 0x01) == 0x01 ? "Radiography," : "",
(DoseInfo.IrradiationEventType & 0x02) == 0x02 ? "SerialRadiography," : "",
(DoseInfo.IrradiationEventType & 0x04) == 0x04 ? "Fluoroscopy" : "");
IrradiationEventType.TrimRight(_T(", "));
pDoseDocument->getTree().getCurrentContentItem().setStringValue(ConvertCStringToUTF8(IrradiationEventType).c_str());
LOG_DEBUGGING("NodeID=%d, Level=%d, Position=%s, sPosition=%s", pDoseDocument->getTree().getNodeID(),
pDoseDocument->getTree().getLevel(), pDoseDocument->getTree().getPosition(sPosition).c_str(), ConvertUTF8ToCString(sPosition.c_str()));
//pDoseDocument->getTree().addContentItem(DSRTypes::RT_contains, DSRTypes::VT_Image);
//pDoseDocument->getTree().getCurrentContentItem().setConceptName(DSRCodedEntryValue("IR.02", OFFIS_CODING_SCHEME_DESIGNATOR, "Acquired Image"));
//pDoseDocument->getTree().getCurrentContentItem().setImageReference(DSRImageReferenceValue(UID_SecondaryCaptureImageStorage, "1.3.12.2.1107.5.8.1.123456789.199507271803030521934"));
//pDoseDocument->getCurrentRequestedProcedureEvidence().addItem("1.3.12.2.1107.5.8.1.123456789.199507271803030520282", "1.3.12.2.1107.5.8.1.123456789.199507271803030521007", UID_SecondaryCaptureImageStorage, "1.3.12.2.1107.5.8.1.123456789.199507271803030521934");
//pDoseDocument->completeDocument();
}
// CString转为UTF8
std::string DoseStructuredReport::ConvertCStringToUTF8(CString strValue)
{
std::wstring wbuffer;
int length = 0;
#ifdef _UNICODE
wbuffer.assign(strValue.GetString(), strValue.GetLength());
#else
// 预转换ANSI到UNICODE, 获取转换后长度
length = ::MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, (LPCTSTR)strValue, -1, NULL, 0);
wbuffer.resize(length);
// 转换
MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)strValue, -1, (LPWSTR)(wbuffer.data()), wbuffer.length());
#endif
// 预转换UNICODE到UTF8, 获取转换后长度
length = WideCharToMultiByte(CP_UTF8, 0, wbuffer.data(), wbuffer.size(), NULL, 0, NULL, NULL);
// 转换UNICODE到UTF8, 获取转换后内容
std::string buffer;
buffer.resize(length);
WideCharToMultiByte(CP_UTF8, 0, wbuffer.c_str(), -1, (LPSTR)(buffer.data()), length, NULL, NULL);
return(buffer);
}
// UTF8转为CString
CString DoseStructuredReport::ConvertUTF8ToCString(std::string utf8str)
{
// 预转换,得到所需空间的大小
int nLen = ::MultiByteToWideChar(CP_UTF8, NULL, utf8str.data(), utf8str.size(), NULL, 0);
// UTF8转换为Unicode
std::wstring wbuffer;
wbuffer.resize(nLen);
::MultiByteToWideChar(CP_UTF8, NULL, utf8str.data(), utf8str.size(), (LPWSTR)(wbuffer.data()), wbuffer.length());
#ifdef UNICODE
return (CString(wbuffer.data(), wbuffer.length()));
#else
// Unicode转换为ANSI 得到转换后长度
nLen = WideCharToMultiByte(CP_ACP, 0, wbuffer.data(), wbuffer.length(), NULL, 0, NULL, NULL);
std::string ansistr;
ansistr.resize(nLen);
// unicode转成ansi
WideCharToMultiByte(CP_ACP, 0, (LPWSTR)(wbuffer.data()), wbuffer.length(),
(LPSTR)(ansistr.data()), ansistr.size(), NULL, NULL);
return (CString(ansistr.data(), ansistr.length()));
#endif
}
#pragma once
#include "dcmtk/config/osconfig.h"
#include "dcmtk/ofstd/ofconsol.h"
#include "dcmtk/dcmsr/dsrdoc.h"
#include "dcmtk/dcmdata/dctk.h"
#include <Entity/DcmInfo.h>
// 存储在报告里的一些剂量参数
class DoseStructuredReport : public CDcmImageInfo
{
public:
// 写入剂量报告
void WriteDSRDocument(DoseStructuredReport& DoseInfo, CString sFilePath);
private:
// 追加内容到已有的剂量报告里
void AppendDSRDocument(DoseStructuredReport& DoseInfo, CString sFilePath);
// 读取剂量报告DCM文件
BOOL ReadDSRDocumentDcmFile(DSRDocument* pDoseDocument, CString sFilePath);
// 把剂量报告保存到DCM文件中
BOOL StoreDSRDocumentToDcmFile(DSRDocument* pDoseDocument, CString sFilePath);
// 写入剂量报告的头信息,从病人图像的DCM信息里获取
void WriteDSRDocumentHeadInfo(DSRDocument* pDoseDocument, DoseStructuredReport& DoseInfo);
// 写入累计剂量信息
void WriteDSRDocumentAccumulatedDoseInfo(DSRDocument* pDoseDocument, DoseStructuredReport& DoseInfo, BOOL bIsAppend = FALSE);
// CString转为UTF8
std::string ConvertCStringToUTF8(CString strValue);
// UTF8转为CString
CString ConvertUTF8ToCString(std::string utf8str);
public:
// 累计剂量,单位:Gy
double DoseTotal = 0;
// 累计DAP,单位:Gy.m2
double DoseAreaProductTotal = 0;
// 射线源到基准点的距离,单位:mm
UINT DistanceSourceToReferencePoint = 850;
// 基准点定义,单位:cm
CString ReferencePointDefinition = _T("30cm above table");
// 辐照总帧数
UINT TotalNumOfRadiographicFrames = 0;
// 总透视时间,单位:s
UINT TotalFluoroscopyTime = 0;
// 辐照事件类型,包括3种及它们组合:Radiography,SerialRadiography,Fluoroscopy,
// bit0 = 1表示Radiography,bit1 = 1表示SerialRadiography,bit2 = 1表示Fluoroscopy
char IrradiationEventType = 0;
};