Mercurial > hg > orthanc
changeset 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 | e8d30585b909 |
children | |
files | OrthancServer/OrthancFindRequestHandler.cpp |
diffstat | 1 files changed, 116 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancServer/OrthancFindRequestHandler.cpp Mon Jun 15 17:21:48 2020 +0200 +++ b/OrthancServer/OrthancFindRequestHandler.cpp Tue Jun 30 17:20:22 2020 +0200 @@ -382,37 +382,134 @@ assert(dicomAsJson != NULL); const Json::Value& source = (*dicomAsJson) [tag->Format()]; - if (source.type() == Json::objectValue && + // the options below were introduced during an investigation with Zeiss Cirrus software + // in order to reproduce exactly the same "weird" answers as a Zeiss server. + // Of course, this code should not remain as is. The Zeiss Cirrus Patch + // shall be implemented in a "lua callback" that would modify the response before it is sent. + // Note that, during these investigations, DefaultEncoding was set to "Utf8" and + // this line was modified in dimse.cc (DCMTK): + // E_EncodingType sequenceType_encoding = EET_UndefinedLength; // g_dimse_send_sequenceType_encoding; + // and the following dictionnary was declared: + // "Dictionary" : { + // "0407,10a1" : ["SQ", "OCT Cube Sequence", 1,1,"99CZM_CapeCod_OctGeneral" ], + // "0407,1005" : ["SQ", "OCT Cube Sequence2", 1, 1, "99CZM_CapeCod_OctGeneral" ], + // "0407,0010" : ["LO", "OCT Cube Sequence3", 1, 1, "99CZM_CapeCod_OctGeneral" ], + // "0407,1001" : ["US", "Undefined Private Tag 1001", 1, 1, "99CZM_CapeCod_OctGeneral" ], + // "0407,1002" : ["US", "Undefined Private Tag 1002", 1, 1, "99CZM_CapeCod_OctGeneral" ], + // "0407,1003" : ["US", "Undefined Private Tag 1003", 1, 1, "99CZM_CapeCod_OctGeneral" ], + // "0405,1001" : ["SH", "PatternType", 1, 1, "99CZM_CapeCod_OctSettings" ], + // "0405,101a" : ["FL", "SignalStrength", 1, 1, "99CZM_CapeCod_OctSettings" ] + // } + bool addEmptySequences = false; // this could go into a "Manufacturer" option + bool zeissCirrusMinimumPatch = true; // investigations we tried and that are necessary for Cirrus to accept the response + if (zeissCirrusMinimumPatch) + { + addEmptySequences = true; + } + 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) + + if ((source.type() == Json::objectValue && source.isMember("Type") && source.isMember("Value") && source["Type"].asString() == "Sequence" && - source["Value"].type() == Json::arrayValue) + source["Value"].type() == Json::arrayValue) || + (addEmptySequences && source.type() == Json::nullValue)) { Json::Value content = Json::arrayValue; + bool replace = true; - for (Json::Value::ArrayIndex i = 0; i < source["Value"].size(); i++) - { - Json::Value item; - ServerToolbox::SimplifyTags(item, source["Value"][i], DicomToJsonFormat_Short); - content.append(item); - } - - if (tag->IsPrivate()) + if (source.type() == Json::objectValue) { - std::map<uint16_t, std::string>::const_iterator found = privateCreators.find(tag->GetGroup()); - - if (found != privateCreators.end()) + for (Json::Value::ArrayIndex i = 0; i < source["Value"].size(); i++) { - dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, found->second.c_str()); - } - else - { - dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, defaultPrivateCreator); + Json::Value item; + ServerToolbox::SimplifyTags(item, source["Value"][i], DicomToJsonFormat_Short); + content.append(item); } } else { - dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, "" /* no private creator */); + LOG(INFO) << "inserting empty sequence for " << tag->Format(); + + DcmDataset& dataset = *dicom.GetDcmtkObject().getDataset(); + + { + std::unique_ptr<DcmSequenceOfItems> sequence; + + if (zeissCirrusMinimumPatch && tag->GetGroup() == 1031 && tag->GetElement() == 4257) + { + sequence.reset(new DcmSequenceOfItems(DcmTag(tag->GetGroup(), tag->GetElement(), "99CZM_CapeCod_OctGeneral"))); + + LOG(INFO) << "inserting first 4 empty elements into " << tag->Format(); + std::unique_ptr<DcmItem> item(new DcmItem(DcmTag(0xfffe, 0xe000))); + bool ok = false; + ok = item->putAndInsertString(DcmTag(0x0407, 0x0010), "99CZM_CapeCod_OctGeneral").good(); + ok = item->insertEmptyElement(DcmTag(0x0407, 0x1001, "99CZM_CapeCod_OctGeneral")).good(); + ok = item->insertEmptyElement(DcmTag(0x0407, 0x1002, "99CZM_CapeCod_OctGeneral")).good(); + ok = item->insertEmptyElement(DcmTag(0x0407, 0x1003, "99CZM_CapeCod_OctGeneral")).good(); + ok = sequence->insert(item.release(), false, false).good(); + // LOG(INFO) << ok; + } + else + { + sequence.reset(new DcmSequenceOfItems(DcmTagKey(tag->GetGroup(), tag->GetElement()))); + std::unique_ptr<DcmItem> item; + if (zeissCirrusMaximumPatch) + { + item.reset(new DcmItem(DcmTag(0xfffe, 0xe000))); + } + else + { + item.reset(new DcmItem); + } + bool ok = sequence->insert(item.release(), false, false).good(); + // LOG(INFO) << ok; + } + + bool ok3 = dataset.insert(sequence.release(), false, false).good(); + replace = false; + // LOG(INFO) << ok3; + } + } + + if (zeissCirrusMaximumPatch && tag->GetGroup() == 1031 && tag->GetElement() == 4257 && content.size() > 0 && content[0].size() >= 4) + { + LOG(INFO) << "keeping only the first elements from " << tag->Format(); + Json::Value cloneContent = Json::Value(); + + Json::Value::Members members = content[0].getMemberNames(); + for (size_t i = 0; i < members.size(); i++) + { + const std::string& member = members[i]; + cloneContent[0][member] = content[0][member]; + Json::Value& v = cloneContent[0][member]; + if (i == 3) + { + break; + } + } + content = cloneContent; + } + + if (replace) + { + if (tag->IsPrivate()) + { + std::map<uint16_t, std::string>::const_iterator found = privateCreators.find(tag->GetGroup()); + + if (found != privateCreators.end()) + { + dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, found->second.c_str()); + } + else + { + dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, defaultPrivateCreator); + } + } + else + { + dicom.Replace(*tag, content, false, DicomReplaceMode_InsertIfAbsent, "" /* no private creator */); + } } } }