comparison OrthancServer/OrthancFindRequestHandler.cpp @ 4095:642b0947af84 zeiss-cirrus-investigations

temporarily modified the FindRequestHandler such that ZeissCirrus accepts the response from Orthanc. Work to be cleaned
author Alain Mazy <alain@mazy.be>
date Tue, 30 Jun 2020 17:20:22 +0200
parents c6e82885f570
children
comparison
equal deleted inserted replaced
4073:e8d30585b909 4095:642b0947af84
380 tag != sequencesToReturn.end(); ++tag) 380 tag != sequencesToReturn.end(); ++tag)
381 { 381 {
382 assert(dicomAsJson != NULL); 382 assert(dicomAsJson != NULL);
383 const Json::Value& source = (*dicomAsJson) [tag->Format()]; 383 const Json::Value& source = (*dicomAsJson) [tag->Format()];
384 384
385 if (source.type() == Json::objectValue && 385 // the options below were introduced during an investigation with Zeiss Cirrus software
386 // in order to reproduce exactly the same "weird" answers as a Zeiss server.
387 // Of course, this code should not remain as is. The Zeiss Cirrus Patch
388 // shall be implemented in a "lua callback" that would modify the response before it is sent.
389 // Note that, during these investigations, DefaultEncoding was set to "Utf8" and
390 // this line was modified in dimse.cc (DCMTK):
391 // E_EncodingType sequenceType_encoding = EET_UndefinedLength; // g_dimse_send_sequenceType_encoding;
392 // and the following dictionnary was declared:
393 // "Dictionary" : {
394 // "0407,10a1" : ["SQ", "OCT Cube Sequence", 1,1,"99CZM_CapeCod_OctGeneral" ],
395 // "0407,1005" : ["SQ", "OCT Cube Sequence2", 1, 1, "99CZM_CapeCod_OctGeneral" ],
396 // "0407,0010" : ["LO", "OCT Cube Sequence3", 1, 1, "99CZM_CapeCod_OctGeneral" ],
397 // "0407,1001" : ["US", "Undefined Private Tag 1001", 1, 1, "99CZM_CapeCod_OctGeneral" ],
398 // "0407,1002" : ["US", "Undefined Private Tag 1002", 1, 1, "99CZM_CapeCod_OctGeneral" ],
399 // "0407,1003" : ["US", "Undefined Private Tag 1003", 1, 1, "99CZM_CapeCod_OctGeneral" ],
400 // "0405,1001" : ["SH", "PatternType", 1, 1, "99CZM_CapeCod_OctSettings" ],
401 // "0405,101a" : ["FL", "SignalStrength", 1, 1, "99CZM_CapeCod_OctSettings" ]
402 // }
403 bool addEmptySequences = false; // this could go into a "Manufacturer" option
404 bool zeissCirrusMinimumPatch = true; // investigations we tried and that are necessary for Cirrus to accept the response
405 if (zeissCirrusMinimumPatch)
406 {
407 addEmptySequences = true;
408 }
409 bool zeissCirrusMaximumPatch = false; // investigations we tried but that finally do not seem necessary for Cirrus to accept the response (but that are required to get the same response as the Zeiss Server)
410
411 if ((source.type() == Json::objectValue &&
386 source.isMember("Type") && 412 source.isMember("Type") &&
387 source.isMember("Value") && 413 source.isMember("Value") &&
388 source["Type"].asString() == "Sequence" && 414 source["Type"].asString() == "Sequence" &&
389 source["Value"].type() == Json::arrayValue) 415 source["Value"].type() == Json::arrayValue) ||
416 (addEmptySequences && source.type() == Json::nullValue))
390 { 417 {
391 Json::Value content = Json::arrayValue; 418 Json::Value content = Json::arrayValue;
392 419 bool replace = true;
393 for (Json::Value::ArrayIndex i = 0; i < source["Value"].size(); i++) 420
421 if (source.type() == Json::objectValue)
394 { 422 {
395 Json::Value item; 423 for (Json::Value::ArrayIndex i = 0; i < source["Value"].size(); i++)
396 ServerToolbox::SimplifyTags(item, source["Value"][i], DicomToJsonFormat_Short);
397 content.append(item);
398 }
399
400 if (tag->IsPrivate())
401 {
402 std::map<uint16_t, std::string>::const_iterator found = privateCreators.find(tag->GetGroup());
403
404 if (found != privateCreators.end())
405 { 424 {
406 dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, found->second.c_str()); 425 Json::Value item;
407 } 426 ServerToolbox::SimplifyTags(item, source["Value"][i], DicomToJsonFormat_Short);
408 else 427 content.append(item);
409 {
410 dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, defaultPrivateCreator);
411 } 428 }
412 } 429 }
413 else 430 else
414 { 431 {
415 dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, "" /* no private creator */); 432 LOG(INFO) << "inserting empty sequence for " << tag->Format();
433
434 DcmDataset& dataset = *dicom.GetDcmtkObject().getDataset();
435
436 {
437 std::unique_ptr<DcmSequenceOfItems> sequence;
438
439 if (zeissCirrusMinimumPatch && tag->GetGroup() == 1031 && tag->GetElement() == 4257)
440 {
441 sequence.reset(new DcmSequenceOfItems(DcmTag(tag->GetGroup(), tag->GetElement(), "99CZM_CapeCod_OctGeneral")));
442
443 LOG(INFO) << "inserting first 4 empty elements into " << tag->Format();
444 std::unique_ptr<DcmItem> item(new DcmItem(DcmTag(0xfffe, 0xe000)));
445 bool ok = false;
446 ok = item->putAndInsertString(DcmTag(0x0407, 0x0010), "99CZM_CapeCod_OctGeneral").good();
447 ok = item->insertEmptyElement(DcmTag(0x0407, 0x1001, "99CZM_CapeCod_OctGeneral")).good();
448 ok = item->insertEmptyElement(DcmTag(0x0407, 0x1002, "99CZM_CapeCod_OctGeneral")).good();
449 ok = item->insertEmptyElement(DcmTag(0x0407, 0x1003, "99CZM_CapeCod_OctGeneral")).good();
450 ok = sequence->insert(item.release(), false, false).good();
451 // LOG(INFO) << ok;
452 }
453 else
454 {
455 sequence.reset(new DcmSequenceOfItems(DcmTagKey(tag->GetGroup(), tag->GetElement())));
456 std::unique_ptr<DcmItem> item;
457 if (zeissCirrusMaximumPatch)
458 {
459 item.reset(new DcmItem(DcmTag(0xfffe, 0xe000)));
460 }
461 else
462 {
463 item.reset(new DcmItem);
464 }
465 bool ok = sequence->insert(item.release(), false, false).good();
466 // LOG(INFO) << ok;
467 }
468
469 bool ok3 = dataset.insert(sequence.release(), false, false).good();
470 replace = false;
471 // LOG(INFO) << ok3;
472 }
473 }
474
475 if (zeissCirrusMaximumPatch && tag->GetGroup() == 1031 && tag->GetElement() == 4257 && content.size() > 0 && content[0].size() >= 4)
476 {
477 LOG(INFO) << "keeping only the first elements from " << tag->Format();
478 Json::Value cloneContent = Json::Value();
479
480 Json::Value::Members members = content[0].getMemberNames();
481 for (size_t i = 0; i < members.size(); i++)
482 {
483 const std::string& member = members[i];
484 cloneContent[0][member] = content[0][member];
485 Json::Value& v = cloneContent[0][member];
486 if (i == 3)
487 {
488 break;
489 }
490 }
491 content = cloneContent;
492 }
493
494 if (replace)
495 {
496 if (tag->IsPrivate())
497 {
498 std::map<uint16_t, std::string>::const_iterator found = privateCreators.find(tag->GetGroup());
499
500 if (found != privateCreators.end())
501 {
502 dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, found->second.c_str());
503 }
504 else
505 {
506 dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, defaultPrivateCreator);
507 }
508 }
509 else
510 {
511 dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, "" /* no private creator */);
512 }
416 } 513 }
417 } 514 }
418 } 515 }
419 516
420 answers.Add(dicom); 517 answers.Add(dicom);