DICOM C_MOVE с "CompositeNetworkFunctions" для gdcm
Я пытаюсь получить DICOMS с сервера, используя gposcm CompositeNetworkFunctions. Мой тестовый сервер настроен с использованием "Orthanc".
Когда я запускаю запрос Move, я получаю:
terminate called after throwing an instance of 'gdcm::Exception'
what (): /home/myname/Builds/GDCM/Source/Source/Common/gdcmException.h:74 ():
Когда я ловлю это исключение, я обнаруживаю, что это "необработанное исключение", больше никакой информации. Поэтому вместо того, чтобы ловить его, я запускаю программу, используя gdb. Вот что я получаю:
0x00007ffff3e4dcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 0x00007ffff3e4dcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007ffff3e510d8 in __GI_abort () at abort.c:89
#2 0x00007ffff44526b5 in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff4450836 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff4450863 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff4450aa2 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x0000000000781772 in std::istream& gdcm::DataSet::ReadWithLength<gdcm::ExplicitDataElement, gdcm::SwapperNoOp>(std::istream&, gdcm::VL&) ()
#7 0x00000000007cd268 in gdcm::network::PresentationDataValue::ConcatenatePDVBlobsAsExplicit(std::vector<gdcm::network::PresentationDataValue, std::allocator<gdcm::network::PresentationDataValue> > const&) ()
#8 0x00000000007d6af1 in gdcm::network::ULConnectionManager::RunEventLoop(gdcm::network::ULEvent&, gdcm::network::ULConnection*, gdcm::network::ULConnectionCallback*, bool const&) ()
#9 0x00000000007d5190 in gdcm::network::ULConnectionManager::RunMoveEventLoop(gdcm::network::ULEvent&, gdcm::network::ULConnectionCallback*) ()
#10 0x00000000007d4acf in gdcm::network::ULConnectionManager::SendMove(gdcm::BaseRootQuery const*, gdcm::network::ULConnectionCallback*) ()
#11 0x00000000007c1750 in gdcm::CompositeNetworkFunctions::CMove(char const*, unsigned short, gdcm::BaseRootQuery const*, unsigned short, char const*, char const*, char const*) ()
#12 0x0000000000666c5c in PACSCMove::run (this=0x25a9dd0) at /home/myname/Projects/Hiwi/Source/src/PACSCMove.cpp:67
#13 0x00007ffff4798384 in ?? () from /home/myname/Qt/5.4/gcc_64/lib/libQt5Core.so.5
#14 0x00007ffff70fa182 in start_thread (arg=0x7fffd8cf5700) at pthread_create.c:312
#15 0x00007ffff3f1147d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
Вот мой код:
mQuery.InitializeDataSet( mQueryLevel );
setSearchParameter( gdcm::Tag( 0x20, 0x000d ), studyUID.toStdString() ); // Study UID
setSearchParameter( gdcm::Tag( 0x20, 0x000e ), seriesUID.toStdString() ); // Series UID
std::cout << "New Move Query: " << mQuery.ValidateQuery(true) << std::endl;
mQuery.WriteQuery("MoveQuery.dcm");
bool res = gdcm::CompositeNetworkFunctions::CMove(
"localhost", 4242,
&mQuery,
11110,
"IMHOTEP",
NULL,
"/home/myname/TestPatient" );
mQueryLevel - это gdcm::eSeries
Интересно то, что благодаря написанному файлу запросов "MoveQuery.dcm" я могу загрузить файл без проблем, используя Movecu:
movescu -v -p -aet IMHOTEP -od /home/myname/TestPatient/ --port 11110 localhost 4242 MoveQuery.dcm
Я пробовал:
- Различные значения для AET и CALL
- Относительные и абсолютные пути
- Разные порты (хотя это не должно быть - мой вызов movcu использует одни и те же порты, в конце концов!)
- mQuery в настоящее время имеет тип gdcm::MovePatientRootQuery, но я пробовал MoveStudyRootQuery, FindPatientRootQuery, FindStudyRootQuery
- Погружаясь в код GDCM, следуя трассировке стека - но я недостаточно понимаю, что происходит
- Добавление значения "PatientID" к запросу также или только предоставление "SeriesUID" (тот же результат)
С PatientID, также добавленным к запросу, вот содержимое MoveQuery.dcm:
$ dcmdump MoveQuery.dcm
# Dicom-File-Format
# Dicom-Meta-Information-Header
# Used TransferSyntax: Unknown Transfer Syntax
# Dicom-Data-Set
# Used TransferSyntax: Little Endian Implicit
(0008,0052) CS [SERIES] # 6, 1 QueryRetrieveLevel
(0010,0020) LO [4589301] # 8, 1 PatientID
(0020,000d) UI [1.2.840.113619.2.55.1.1762893669.2104.1060778173.267] # 52, 1 StudyInstanceUID
(0020,000e) UI [1.2.840.113619.2.55.1.1762893669.2104.1060778173.271] # 52, 1 SeriesInstanceUID
1 ответ
Сервис C-GET не исключен в стандарте DICOM. C-GET использует то же соединение для извлечения изображения из SCP, но C-MOVE использует параллельное соединение, где сервер переключает свою роль на SCU (клиент) и пытается подключиться для перемещения целевого AE (конечный сервер). В этом случае для обработки входящего соединения на вашей стороне должен быть прослушиватель DICOM (SCP).
Я думаю, вы говорите, что Calling AE Title (реквестер службы C-Move) - это "IMHOTEP", и у вас должен быть прослушиватель DICOM, прослушивающий порт "11110". Вы запрашиваете у удаленного AE "ORTHANC" (называемый AE) переместить серию в C-Move Destination AE (это должен быть ваш боковой слушатель DICOM (SCP), который называется "IMHOTEP").