changeset 5044:6fed78e13233

Refactored DicomMap to handle sequences when needed
author Alain Mazy <am@osimis.io>
date Tue, 28 Jun 2022 17:45:09 +0200
parents ec5c203a97ea
children a9ca92ecbbc2
files OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake OrthancFramework/Sources/DicomFormat/DicomMap.cpp OrthancFramework/Sources/DicomFormat/DicomMap.h OrthancFramework/Sources/DicomFormat/DicomSequencesMap.cpp OrthancFramework/Sources/DicomFormat/DicomSequencesMap.h OrthancFramework/Sources/DicomFormat/DicomValue.cpp OrthancFramework/Sources/DicomFormat/DicomValue.h OrthancFramework/Sources/DicomNetworking/Internals/FindScp.cpp OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp OrthancFramework/UnitTestsSources/DicomMapTests.cpp OrthancServer/Sources/Database/ResourcesContent.cpp OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp OrthancServer/Sources/Database/StatelessDatabaseOperations.h OrthancServer/Sources/ServerContext.cpp OrthancServer/Sources/ServerIndex.cpp OrthancServer/Sources/ServerIndex.h OrthancServer/UnitTestsSources/ServerIndexTests.cpp
diffstat 17 files changed, 405 insertions(+), 287 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake	Tue Jun 28 17:45:09 2022 +0200
@@ -197,7 +197,6 @@
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/DicomFormat/DicomInstanceHasher.cpp
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/DicomFormat/DicomIntegerPixelAccessor.cpp
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/DicomFormat/DicomMap.cpp
-    ${CMAKE_CURRENT_LIST_DIR}/../../Sources/DicomFormat/DicomSequencesMap.cpp
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/DicomFormat/DicomStreamReader.cpp
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/DicomFormat/DicomValue.cpp
     ${CMAKE_CURRENT_LIST_DIR}/../../Sources/DicomFormat/StreamBlockReader.cpp
--- a/OrthancFramework/Sources/DicomFormat/DicomMap.cpp	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomMap.cpp	Tue Jun 28 17:45:09 2022 +0200
@@ -359,6 +359,11 @@
     SetValueInternal(group, element, new DicomValue(str, isBinary));
   }
 
+  void DicomMap::SetValue(const DicomTag& tag, const Json::Value& value)
+  {
+    SetValueInternal(tag.GetGroup(), tag.GetElement(), new DicomValue(value));
+  }
+
   bool DicomMap::HasTag(uint16_t group, uint16_t element) const
   {
     return HasTag(DicomTag(group, element));
@@ -1328,7 +1333,7 @@
   }
 
   
-  void DicomMap::FromDicomAsJson(const Json::Value& dicomAsJson, bool append)
+  void DicomMap::FromDicomAsJson(const Json::Value& dicomAsJson, bool append, bool parseSequences)
   {
     if (dicomAsJson.type() != Json::objectValue)
     {
@@ -1371,6 +1376,18 @@
           SetValue(tag, value["Value"].asString(), false /* not binary */);
         }
       }
+      else if (value["Type"] == "Sequence" && parseSequences)
+      {
+        if (value["Value"].type() != Json::arrayValue)
+        {
+          printf("%s", dicomAsJson.toStyledString().c_str());
+          throw OrthancException(ErrorCode_CorruptedFile);
+        }
+        else
+        {
+          SetValue(tag, value["Value"]);
+        }
+      }
     }
   }
 
@@ -1435,21 +1452,18 @@
     return true;
   }
 
-#if ORTHANC_ENABLE_DCMTK == 1
-  void DicomMap::ExtractSequences(std::set<DicomTag>& sequences, const std::set<DicomTag>& tags)
+  void DicomMap::ExtractSequences(DicomMap& result) const
   {
-    sequences.clear();
+    result.Clear();
 
-    for (std::set<DicomTag>::const_iterator it = tags.begin(); it != tags.end(); ++it)
+    for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it)
     {
-      ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(*it);
-      if (vr == ValueRepresentation_Sequence)
+      if (it->second->IsSequence())
       {
-        sequences.insert(*it);
+        result.SetValue(it->first, it->second->GetSequenceContent());
       }
     }
   }
-#endif
 
   void DicomMap::Serialize(Json::Value& target) const
   {
@@ -1673,6 +1687,27 @@
   }
 
 
+  void DicomMap::RemoveSequences()
+  {
+    Content kept;
+
+    for (Content::iterator it = content_.begin(); it != content_.end(); ++it)
+    {
+      assert(it->second != NULL);
+
+      if (!it->second->IsSequence())
+      {
+        kept[it->first] = it->second;
+      }
+      else
+      {
+        delete it->second;
+      }
+    }
+
+    content_ = kept;
+  }
+
   void DicomMap::DumpMainDicomTags(Json::Value& target,
                                    ResourceType level) const
   {
--- a/OrthancFramework/Sources/DicomFormat/DicomMap.h	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomMap.h	Tue Jun 28 17:45:09 2022 +0200
@@ -94,6 +94,9 @@
                   const std::string& str,
                   bool isBinary);
 
+    void SetValue(const DicomTag& tag,
+                  const Json::Value& value);
+
     bool HasTag(uint16_t group, uint16_t element) const;
 
     bool HasTag(const DicomTag& tag) const;
@@ -124,6 +127,8 @@
 
     void ExtractTags(DicomMap& result, const std::set<DicomTag>& tags) const;
 
+    void ExtractSequences(DicomMap& result) const;
+
     static void SetupFindPatientTemplate(DicomMap& result);
 
     static void SetupFindStudyTemplate(DicomMap& result);
@@ -149,10 +154,6 @@
 
     static bool HasComputedTags(const std::set<DicomTag>& tags);
 
-#if ORTHANC_ENABLE_DCMTK == 1
-    static void ExtractSequences(std::set<DicomTag>& sequences, const std::set<DicomTag>& tags);
-#endif
-
     static const std::set<DicomTag>& GetMainDicomTags(ResourceType level);
 
     // returns a string uniquely identifying the list of main dicom tags for a level
@@ -208,7 +209,8 @@
                      const DicomTag& tag) const;
 
     void FromDicomAsJson(const Json::Value& dicomAsJson, 
-                         bool append = false);
+                         bool append = false,
+                         bool parseSequences = false);
 
     void Merge(const DicomMap& other);
 
@@ -231,6 +233,8 @@
 
     void RemoveBinaryTags();
 
+    void RemoveSequences();
+
     void DumpMainDicomTags(Json::Value& target,
                            ResourceType level) const;
 
--- a/OrthancFramework/Sources/DicomFormat/DicomSequencesMap.cpp	Mon Jun 27 15:22:19 2022 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2022 Osimis S.A., Belgium
- * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "../PrecompiledHeaders.h"
-#include "DicomSequencesMap.h"
-#include "../Toolbox.h"
-
-namespace Orthanc
-{
-
-#if ORTHANC_ENABLE_DCMTK == 1
-
-  // copy all tags from Json (used to read from metadata)
-  void DicomSequencesMap::Deserialize(const Json::Value& serialized)
-  {
-    Json::Value::Members members = serialized.getMemberNames();
-    for (size_t i = 0; i < members.size(); i++)
-    {
-      DicomTag tag(0, 0);
-      if (DicomTag::ParseHexadecimal(tag, members[i].c_str()))
-      {
-        sequences_[tag] = serialized[members[i]];
-      }
-    }
-  }
-
-#endif
-
-  // serialize a subet of tags (used to store in the metadata)
-  void DicomSequencesMap::Serialize(Json::Value& target, const std::set<DicomTag>& tags) const
-  {
-    // add the sequences to "target"
-    for (std::map<DicomTag, Json::Value>::const_iterator it = sequences_.begin();
-          it != sequences_.end(); ++it)
-    {
-      if (tags.find(it->first) != tags.end())
-      {
-        target[it->first.Format()] = it->second;
-      }
-    }
-  }
-
-  // copy a subset of tags from Json
-  void DicomSequencesMap::FromDicomAsJson(const Json::Value& dicomAsJson, const std::set<DicomTag>& tags)
-  {
-    for (std::set<DicomTag>::const_iterator it = tags.begin();
-         it != tags.end(); ++it)
-    {
-      std::string tag = it->Format();
-      if (dicomAsJson.isMember(tag))
-      {
-        sequences_[*it] = dicomAsJson[tag];
-      }
-    }
-  }
-
-  void DicomSequencesMap::ToJson(Json::Value& target, DicomToJsonFormat format, const std::set<DicomTag>& tags) const
-  {
-    // add the sequences to "target"
-    for (std::map<DicomTag, Json::Value>::const_iterator it = sequences_.begin();
-          it != sequences_.end(); ++it)
-    {
-      Json::Value sequenceFullJson = Json::objectValue;
-      sequenceFullJson[it->first.Format()] = it->second;
-
-      Json::Value& requestedFormatJson = sequenceFullJson;
-      Json::Value convertedJson;
-
-      if (format != DicomToJsonFormat_Full)
-      {
-        Toolbox::SimplifyDicomAsJson(convertedJson, sequenceFullJson, format);
-        requestedFormatJson = convertedJson;
-      }
-      
-      Json::Value::Members keys = requestedFormatJson.getMemberNames();  
-      for (size_t i = 0; i < keys.size(); i++)  // there should always be only one member in this JSON
-      {
-        target[keys[i]] = requestedFormatJson[keys[i]];
-      }
-    }
-  }
-}
\ No newline at end of file
--- a/OrthancFramework/Sources/DicomFormat/DicomSequencesMap.h	Mon Jun 27 15:22:19 2022 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2022 Osimis S.A., Belgium
- * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../../OrthancFramework/Sources/DicomFormat/DicomTag.h"
-
-#include <json/value.h>
-#include <boost/noncopyable.hpp>
-
-#include <map>
-
-namespace Orthanc
-{
-  class DatabaseLookup;
-  class ParsedDicomFile;
-  struct ServerIndexChange;
-
-  /*
-   * contains a map of dicom sequences where:
-   * the key is a DicomTag
-   * the sequence is serialized in Json "full" format
-   */
-  struct DicomSequencesMap : public boost::noncopyable
-  {
-    std::map<DicomTag, Json::Value>     sequences_;
-
-    void Deserialize(const Json::Value& serialized);
-    void Serialize(Json::Value& target, const std::set<DicomTag>& tagsSubset) const;
-    void FromDicomAsJson(const Json::Value& dicomAsJson, const std::set<DicomTag>& tagsSubset);
-    void ToJson(Json::Value& target, DicomToJsonFormat format, const std::set<DicomTag>& tagsSubset) const;
-
-    size_t GetSize() const
-    {
-      return sequences_.size();
-    }
-  };
-}
--- a/OrthancFramework/Sources/DicomFormat/DicomValue.cpp	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomValue.cpp	Tue Jun 28 17:45:09 2022 +0200
@@ -40,7 +40,8 @@
 
   DicomValue::DicomValue(const DicomValue& other) :
     type_(other.type_),
-    content_(other.content_)
+    content_(other.content_),
+    sequenceJson_(other.sequenceJson_)
   {
   }
 
@@ -61,10 +62,15 @@
     content_.assign(data, size);
   }
     
+  DicomValue::DicomValue(const Json::Value& value) :
+    type_(Type_SequenceAsJson),
+    sequenceJson_(value)
+  {
+  }
   
   const std::string& DicomValue::GetContent() const
   {
-    if (type_ == Type_Null)
+    if (type_ == Type_Null || type_ == Type_SequenceAsJson)
     {
       throw OrthancException(ErrorCode_BadParameterType);
     }
@@ -74,6 +80,19 @@
     }
   }
 
+  const Json::Value& DicomValue::GetSequenceContent() const
+  {
+    if (type_ != Type_SequenceAsJson)
+    {
+      throw OrthancException(ErrorCode_BadParameterType);
+    }
+    else
+    {
+      return sequenceJson_;
+    }
+  }
+
+
   bool DicomValue::IsNull() const
   {
     return type_ == Type_Null;
@@ -84,6 +103,15 @@
     return type_ == Type_Binary;
   }
 
+  bool DicomValue::IsString() const
+  {
+    return type_ == Type_String;
+  }
+
+  bool DicomValue::IsSequence() const
+  {
+    return type_ == Type_SequenceAsJson;
+  }
 
   DicomValue* DicomValue::Clone() const
   {
@@ -107,8 +135,7 @@
 
   bool DicomValue::ParseInteger32(int32_t& result) const
   {
-    if (IsBinary() ||
-        IsNull())
+    if (!IsString())
     {
       return false;
     }
@@ -120,8 +147,7 @@
 
   bool DicomValue::ParseInteger64(int64_t& result) const
   {
-    if (IsBinary() ||
-        IsNull())
+    if (!IsString())
     {
       return false;
     }
@@ -133,8 +159,7 @@
 
   bool DicomValue::ParseUnsignedInteger32(uint32_t& result) const
   {
-    if (IsBinary() ||
-        IsNull())
+    if (!IsString())
     {
       return false;
     }
@@ -146,8 +171,7 @@
 
   bool DicomValue::ParseUnsignedInteger64(uint64_t& result) const
   {
-    if (IsBinary() ||
-        IsNull())
+    if (!IsString())
     {
       return false;
     }
@@ -159,8 +183,7 @@
 
   bool DicomValue::ParseFloat(float& result) const
   {
-    if (IsBinary() ||
-        IsNull())
+    if (!IsString())
     {
       return false;
     }
@@ -172,8 +195,7 @@
 
   bool DicomValue::ParseDouble(double& result) const
   {
-    if (IsBinary() ||
-        IsNull())
+    if (!IsString())
     {
       return false;
     }
@@ -185,8 +207,7 @@
 
   bool DicomValue::ParseFirstFloat(float& result) const
   {
-    if (IsBinary() ||
-        IsNull())
+    if (!IsString())
     {
       return false;
     }
@@ -200,8 +221,7 @@
   {
     uint64_t value;
 
-    if (IsBinary() ||
-        IsNull())
+    if (!IsString())
     {
       return false;
     }
@@ -223,6 +243,10 @@
     {
       return false;
     }
+    else if (IsSequence())
+    {
+      return false;
+    }
     else if (IsBinary() && !allowBinary)
     {
       return false;
@@ -263,6 +287,11 @@
         break;
       }
 
+      case Type_SequenceAsJson:
+      {
+        throw OrthancException(ErrorCode_NotImplemented);
+      }
+
       default:
         throw OrthancException(ErrorCode_InternalError);
     }
@@ -289,6 +318,10 @@
       const std::string base64 =SerializationToolbox::ReadString(source, KEY_CONTENT);
       Toolbox::DecodeBase64(content_, base64);
     }
+    else if (type == "Sequence")
+    {
+      throw OrthancException(ErrorCode_NotImplemented);
+    }
     else
     {
       throw OrthancException(ErrorCode_BadFileFormat);
--- a/OrthancFramework/Sources/DicomFormat/DicomValue.h	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancFramework/Sources/DicomFormat/DicomValue.h	Tue Jun 28 17:45:09 2022 +0200
@@ -43,11 +43,13 @@
     {
       Type_Null,
       Type_String,
-      Type_Binary
+      Type_Binary,
+      Type_SequenceAsJson
     };
 
     Type         type_;
     std::string  content_;
+    Json::Value  sequenceJson_;
 
     DicomValue(const DicomValue& other);
 
@@ -61,11 +63,19 @@
                size_t size,
                bool isBinary);
     
+    DicomValue(const Json::Value& value);
+    
     const std::string& GetContent() const;
 
+    const Json::Value& GetSequenceContent() const;
+
     bool IsNull() const;
 
     bool IsBinary() const;
+
+    bool IsString() const;
+
+    bool IsSequence() const;
     
     DicomValue* Clone() const;
 
--- a/OrthancFramework/Sources/DicomNetworking/Internals/FindScp.cpp	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancFramework/Sources/DicomNetworking/Internals/FindScp.cpp	Tue Jun 28 17:45:09 2022 +0200
@@ -275,6 +275,7 @@
               DicomMap input;
               std::set<DicomTag> ignoreTagLength;
               FromDcmtkBridge::ExtractDicomSummary(input, *requestIdentifiers, 0 /* don't truncate tags */, ignoreTagLength);
+              input.RemoveSequences();
 
               DicomMap filtered;
               FixFindQuery(filtered, input);
--- a/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp	Tue Jun 28 17:45:09 2022 +0200
@@ -564,6 +564,26 @@
                                 ConvertLeafElement(*element, DicomToJsonFlags_Default,
                                                    maxStringLength, encoding, hasCodeExtensions, ignoreTagLength));
       }
+      else
+      {
+        DcmSequenceOfItems* sequence = dynamic_cast<DcmSequenceOfItems*>(element);
+        
+        if (sequence)
+        {
+          Json::Value jsonSequence = Json::arrayValue;
+          for (unsigned long i = 0; i < sequence->card(); i++)
+          {
+            DcmItem* child = sequence->getItem(i);
+            Json::Value& v = jsonSequence.append(Json::objectValue);
+            DatasetToJson(v, *child, DicomToJsonFormat_Full, DicomToJsonFlags_Default, 
+                          maxStringLength, encoding, hasCodeExtensions,
+                          ignoreTagLength, 1);
+          }
+
+          target.SetValue(DicomTag(element->getTag().getGTag(), element->getTag().getETag()),
+                          jsonSequence);
+        }
+      }
     }
   }
 
@@ -1417,6 +1437,18 @@
           {
             result[tagName] = Json::nullValue;
           }
+          else if (it->second->IsSequence())
+          {
+            result[tagName] = Json::arrayValue;
+            const Json::Value& jsonSequence = it->second->GetSequenceContent();
+
+            for (Json::Value::ArrayIndex i = 0; i < jsonSequence.size(); ++i)
+            {
+              Json::Value target = Json::objectValue;
+              Toolbox::SimplifyDicomAsJson(target, jsonSequence[i], DicomToJsonFormat_Human);
+              result[tagName].append(target);
+            }
+          }
           else
           {
             // TODO IsBinary
@@ -1439,6 +1471,11 @@
             value["Type"] = "Null";
             value["Value"] = Json::nullValue;
           }
+          else if (it->second->IsSequence())
+          {
+            value["Type"] = "Sequence";
+            value["Value"] = it->second->GetSequenceContent();
+          }
           else
           {
             // TODO IsBinary
@@ -1458,6 +1495,18 @@
           {
             result[hex] = Json::nullValue;
           }
+          else if (it->second->IsSequence())
+          {
+            result[hex] = Json::arrayValue;
+            const Json::Value& jsonSequence = it->second->GetSequenceContent();
+
+            for (Json::Value::ArrayIndex i = 0; i < jsonSequence.size(); ++i)
+            {
+              Json::Value target = Json::objectValue;
+              Toolbox::SimplifyDicomAsJson(target, jsonSequence[i], DicomToJsonFormat_Short);
+              result[hex].append(target);
+            }
+          }
           else
           {
             // TODO IsBinary
--- a/OrthancFramework/UnitTestsSources/DicomMapTests.cpp	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancFramework/UnitTestsSources/DicomMapTests.cpp	Tue Jun 28 17:45:09 2022 +0200
@@ -167,26 +167,6 @@
 
 }
 
-TEST(DicomMap, ExtractSequences)
-{
-  std::set<DicomTag> allTags;
-  std::set<DicomTag> sequences;
-
-  // empty list
-  DicomMap::ExtractSequences(sequences, allTags);
-  ASSERT_EQ(0u, sequences.size());
-
-  // one tag, no sequence
-  allTags.insert(DICOM_TAG_PATIENT_NAME);
-  DicomMap::ExtractSequences(sequences, allTags);
-  ASSERT_EQ(0u, sequences.size());
-
-  // one sequence
-  allTags.insert(DICOM_TAG_REFERENCED_IMAGE_SEQUENCE);
-  DicomMap::ExtractSequences(sequences, allTags);
-  ASSERT_EQ(1u, sequences.size());
-  ASSERT_TRUE(sequences.find(DICOM_TAG_REFERENCED_IMAGE_SEQUENCE) != sequences.end());
-}
 
 TEST(DicomMap, Tags)
 {
@@ -642,6 +622,168 @@
 }
 
 
+TEST(DicomMap, FromDicomAsJsonAndSequences)
+{
+  DicomMap m;
+  std::string jsonFullString = "{"
+   "\"0008,1090\" : "
+   "{"
+      "\"Name\" : \"ManufacturerModelName\","
+      "\"Type\" : \"String\","
+      "\"Value\" : \"MyModel\""
+   "},"
+   "\"0008,1111\" : "
+   "{"
+      "\"Name\" : \"ReferencedPerformedProcedureStepSequence\","
+      "\"Type\" : \"Sequence\","
+      "\"Value\" : "
+      "["
+         "{"
+            "\"0008,1150\" : "
+            "{"
+               "\"Name\" : \"ReferencedSOPClassUID\","
+               "\"Type\" : \"String\","
+               "\"Value\" : \"1.2.4\""
+            "},"
+            "\"0008,1155\" : "
+            "{"
+               "\"Name\" : \"ReferencedSOPInstanceUID\","
+               "\"Type\" : \"String\","
+               "\"Value\" : \"1.2.3\""
+            "}"
+         "}"
+      "]"
+   "}}";
+
+  Json::Value parsedJson;
+  bool ret = Toolbox::ReadJson(parsedJson, jsonFullString);
+  
+  m.FromDicomAsJson(parsedJson, false /* append */, true /* parseSequences*/);
+  ASSERT_TRUE(ret);
+
+  ASSERT_TRUE(m.HasTag(DicomTag(0x0008, 0x1090)));
+  ASSERT_EQ("MyModel", m.GetValue(0x0008,0x1090).GetContent());
+
+  ASSERT_TRUE(m.HasTag(DicomTag(0x0008, 0x1111)));
+  const Json::Value& jsonSequence = m.GetValue(0x0008, 0x1111).GetSequenceContent();
+  ASSERT_EQ("ReferencedSOPClassUID", jsonSequence[0]["0008,1150"]["Name"].asString());
+
+  {// serialize to human dicomAsJson
+    Json::Value dicomAsJson = Json::objectValue;
+    FromDcmtkBridge::ToJson(dicomAsJson, m, DicomToJsonFormat_Human);
+    // printf("%s", dicomAsJson.toStyledString().c_str());
+
+    ASSERT_TRUE(dicomAsJson.isMember("ManufacturerModelName"));
+    ASSERT_TRUE(dicomAsJson.isMember("ReferencedPerformedProcedureStepSequence"));
+    ASSERT_TRUE(dicomAsJson["ReferencedPerformedProcedureStepSequence"][0].isMember("ReferencedSOPClassUID"));
+    ASSERT_EQ("1.2.4", dicomAsJson["ReferencedPerformedProcedureStepSequence"][0]["ReferencedSOPClassUID"].asString());
+  }
+
+  {// serialize to full dicomAsJson
+    Json::Value dicomAsJson = Json::objectValue;
+    FromDcmtkBridge::ToJson(dicomAsJson, m, DicomToJsonFormat_Full);
+    // printf("%s", dicomAsJson.toStyledString().c_str());
+
+    ASSERT_TRUE(dicomAsJson.isMember("0008,1090"));
+    ASSERT_TRUE(dicomAsJson.isMember("0008,1111"));
+    ASSERT_TRUE(dicomAsJson["0008,1111"]["Value"][0].isMember("0008,1150"));
+    ASSERT_EQ("1.2.4", dicomAsJson["0008,1111"]["Value"][0]["0008,1150"]["Value"].asString());
+    ASSERT_EQ("MyModel", dicomAsJson["0008,1090"]["Value"].asString());
+  }
+
+  {// serialize to short dicomAsJson
+    Json::Value dicomAsJson = Json::objectValue;
+    FromDcmtkBridge::ToJson(dicomAsJson, m, DicomToJsonFormat_Short);
+    // printf("%s", dicomAsJson.toStyledString().c_str());
+
+    ASSERT_TRUE(dicomAsJson.isMember("0008,1090"));
+    ASSERT_TRUE(dicomAsJson.isMember("0008,1111"));
+    ASSERT_TRUE(dicomAsJson["0008,1111"][0].isMember("0008,1150"));
+    ASSERT_EQ("1.2.4", dicomAsJson["0008,1111"][0]["0008,1150"].asString());
+    ASSERT_EQ("MyModel", dicomAsJson["0008,1090"].asString());
+  }
+
+  {// extract sequence
+    DicomMap sequencesOnly;
+    m.ExtractSequences(sequencesOnly);
+
+    ASSERT_EQ(1, sequencesOnly.GetSize());
+    ASSERT_TRUE(sequencesOnly.HasTag(0x0008, 0x1111));
+    ASSERT_TRUE(sequencesOnly.GetValue(0x0008, 0x1111).GetSequenceContent()[0].isMember("0008,1150"));
+
+    // copy sequence
+    DicomMap sequencesCopy;
+    sequencesCopy.SetValue(0x0008, 0x1111, sequencesOnly.GetValue(0x0008, 0x1111));
+
+    ASSERT_EQ(1, sequencesCopy.GetSize());
+    ASSERT_TRUE(sequencesCopy.HasTag(0x0008, 0x1111));
+    ASSERT_TRUE(sequencesCopy.GetValue(0x0008, 0x1111).GetSequenceContent()[0].isMember("0008,1150"));
+  }
+}
+
+TEST(DicomMap, ExtractSummary)
+{
+  Json::Value v = Json::objectValue;
+  v["PatientName"] = "Hello";
+  v["ReferencedSOPClassUID"] = "1.2.840.10008.5.1.4.1.1.4";
+
+  {
+    Json::Value a = Json::arrayValue;
+
+    {
+      Json::Value item = Json::objectValue;
+      item["ReferencedSOPClassUID"] = "1.2.840.10008.5.1.4.1.1.4";
+      item["ReferencedSOPInstanceUID"] = "1.2.840.113619.2.176.2025.1499492.7040.1171286241.719";
+      a.append(item);
+    }
+      
+    {
+      Json::Value item = Json::objectValue;
+      item["ReferencedSOPClassUID"] = "1.2.840.10008.5.1.4.1.1.4";  // ReferencedSOPClassUID
+      item["ReferencedSOPInstanceUID"] = "1.2.840.113619.2.176.2025.1499492.7040.1171286241.726";
+      a.append(item);
+    }
+      
+    v["ReferencedImageSequence"] = a;
+  }
+    
+  {
+    Json::Value a = Json::arrayValue;
+
+    {
+      Json::Value item = Json::objectValue;
+      item["StudyInstanceUID"] = "1.2.840.113704.1.111.7016.1342451220.40";
+
+      {
+        Json::Value b = Json::arrayValue;
+
+        {
+          Json::Value c = Json::objectValue;
+          c["CodeValue"] = "122403";
+          c["0008,103e"] = "WORLD";  // Series description
+          b.append(c);
+        }
+
+        item["PurposeOfReferenceCodeSequence"] = b;
+      }
+        
+      a.append(item);
+    }
+      
+    v["RelatedSeriesSequence"] = a;
+  }
+
+  std::unique_ptr<ParsedDicomFile> dicom(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, ""));
+
+  DicomMap summary;
+  std::set<DicomTag> ignoreTagLength;
+  dicom->ExtractDicomSummary(summary, ORTHANC_MAXIMUM_TAG_LENGTH, ignoreTagLength);
+
+  ASSERT_TRUE(summary.HasTag(0x0008, 0x1140));
+  ASSERT_EQ("1.2.840.10008.5.1.4.1.1.4", summary.GetValue(0x0008, 0x1140).GetSequenceContent()[0]["0008,1150"]["Value"].asString());
+}
+
+
 
 TEST(DicomWebJson, Multiplicity)
 {
--- a/OrthancServer/Sources/Database/ResourcesContent.cpp	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancServer/Sources/Database/ResourcesContent.cpp	Tue Jun 28 17:45:09 2022 +0200
@@ -28,6 +28,7 @@
 
 #include "../../../OrthancFramework/Sources/DicomFormat/DicomArray.h"
 #include "../../../OrthancFramework/Sources/OrthancException.h"
+#include "../../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
 
 #include <cassert>
 
@@ -45,8 +46,7 @@
       const DicomElement& element = flattened.GetElement(i);
       const DicomTag& tag = element.GetTag();
       const DicomValue& value = element.GetValue();
-      if (!value.IsNull() && 
-          !value.IsBinary())
+      if (value.IsString())
       {
         target.AddMainDicomTag(resource, tag, element.GetValue().GetContent());
       }
@@ -70,9 +70,7 @@
       assert(DicomMap::IsMainDicomTag(tags[i]));
         
       const DicomValue* value = map.TestAndGetValue(tags[i]);
-      if (value != NULL &&
-          !value->IsNull() &&
-          !value->IsBinary())
+      if (value != NULL && value->IsString())
       {
         std::string s = ServerToolbox::NormalizeIdentifier(value->GetContent());
         target.AddIdentifierTag(resource, tags[i], s);
@@ -133,7 +131,7 @@
         throw OrthancException(ErrorCode_InternalError);
     }
 
-    StoreMainDicomTagsInternal(*this, resource, tags);
+    StoreMainDicomTagsInternal(*this, resource, tags);  // saves only leaf tags, not sequences
   }
 
 
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp	Tue Jun 28 17:45:09 2022 +0200
@@ -881,7 +881,7 @@
               Toolbox::ReadJson(jsonMetadata, serializedSequences);
 
               assert(jsonMetadata["Version"].asInt() == 1);
-              target.sequences_.Deserialize(jsonMetadata["Sequences"]);
+              target.tags_.FromDicomAsJson(jsonMetadata["Sequences"], true /* append */, true /* parseSequences */);
             }
 
             // check if we have access to all requestedTags or if we must get tags from parents
@@ -2629,6 +2629,28 @@
   }
 
 
+  static void GetMainDicomSequenceMetadataContent(std::string& result,
+                                                  const DicomMap& dicomSummary,
+                                                  ResourceType level)
+  {
+    DicomMap levelSummary;
+    DicomMap levelSequences;
+
+    dicomSummary.ExtractResourceInformation(levelSummary, level);
+    levelSummary.ExtractSequences(levelSequences);
+
+    if (levelSequences.GetSize() > 0)
+    {
+      Json::Value jsonMetadata;
+      jsonMetadata["Version"] = 1;
+      jsonMetadata["Sequences"] = Json::objectValue;
+      FromDcmtkBridge::ToJson(jsonMetadata["Sequences"], levelSequences, DicomToJsonFormat_Full);
+
+      Toolbox::WriteFastJson(result, jsonMetadata);
+    }
+  }
+
+
   void StatelessDatabaseOperations::ReconstructInstance(const ParsedDicomFile& dicom)
   {
     class Operations : public IReadWriteOperations
@@ -2657,6 +2679,25 @@
         }
       }
       
+      static void SetMainDicomSequenceMetadata(ReadWriteTransaction& transaction,
+                                               int64_t instance,
+                                               const DicomMap& dicomSummary,
+                                               ResourceType level)
+      {
+        std::string serialized;
+        GetMainDicomSequenceMetadataContent(serialized, dicomSummary, level);
+
+        if (!serialized.empty())
+        {
+          ReplaceMetadata(transaction, instance, MetadataType_MainDicomSequences, serialized);
+        }
+        else
+        {
+          transaction.DeleteMetadata(instance, MetadataType_MainDicomSequences);
+        }
+        
+      }
+
     public:
       explicit Operations(const ParsedDicomFile& dicom)
       {
@@ -2704,6 +2745,11 @@
           ReplaceMetadata(transaction, study, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Study));        // New in Orthanc 1.11.0
           ReplaceMetadata(transaction, series, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Series));      // New in Orthanc 1.11.0
           ReplaceMetadata(transaction, instance, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Instance));  // New in Orthanc 1.11.0
+        
+          SetMainDicomSequenceMetadata(transaction, patient, summary_, ResourceType_Patient);
+          SetMainDicomSequenceMetadata(transaction, study, summary_, ResourceType_Study);
+          SetMainDicomSequenceMetadata(transaction, series, summary_, ResourceType_Series);
+          SetMainDicomSequenceMetadata(transaction, instance, summary_, ResourceType_Instance);
         }
 
         if (hasTransferSyntax_)
@@ -2852,7 +2898,6 @@
 
   StoreStatus StatelessDatabaseOperations::Store(std::map<MetadataType, std::string>& instanceMetadata,
                                                  const DicomMap& dicomSummary,
-                                                 const DicomSequencesMap& sequencesToStore,
                                                  const Attachments& attachments,
                                                  const MetadataMap& metadata,
                                                  const DicomInstanceOrigin& origin,
@@ -2871,7 +2916,6 @@
       StoreStatus                          storeStatus_;
       std::map<MetadataType, std::string>& instanceMetadata_;
       const DicomMap&                      dicomSummary_;
-      const DicomSequencesMap&             sequencesToStore_;
       const Attachments&                   attachments_;
       const MetadataMap&                   metadata_;
       const DicomInstanceOrigin&           origin_;
@@ -2904,32 +2948,17 @@
       }
 
       static void SetMainDicomSequenceMetadata(ResourcesContent& content,
-                                               int64_t resource,
-                                               const DicomSequencesMap& sequencesToStore,  // all sequences for all levels !
-                                               ResourceType level)
+                                                int64_t resource,
+                                                const DicomMap& dicomSummary,
+                                                ResourceType level)
       {
-        if (sequencesToStore.GetSize() > 0)
+        std::string serialized;
+        GetMainDicomSequenceMetadataContent(serialized, dicomSummary, level);
+
+        if (!serialized.empty())
         {
-          const std::set<DicomTag>& levelTags = DicomMap::GetMainDicomTags(level);
-          std::set<DicomTag> levelSequences;
-          DicomMap::ExtractSequences(levelSequences, levelTags);
-
-          if (levelSequences.size() == 0)
-          {
-            return;
-          }
-
-          Json::Value jsonMetadata;
-          jsonMetadata["Version"] = 1;
-          jsonMetadata["Sequences"] = Json::objectValue;
-          sequencesToStore.Serialize(jsonMetadata["Sequences"], levelSequences);
-
-          std::string serialized;
-          Toolbox::WriteFastJson(serialized, jsonMetadata);
-
           content.AddMetadata(resource, MetadataType_MainDicomSequences, serialized);
         }
-
       }
       
       static bool ComputeExpectedNumberOfInstances(int64_t& target,
@@ -2989,7 +3018,6 @@
     public:
       Operations(std::map<MetadataType, std::string>& instanceMetadata,
                  const DicomMap& dicomSummary,
-                 const DicomSequencesMap& sequencesToStore,
                  const Attachments& attachments,
                  const MetadataMap& metadata,
                  const DicomInstanceOrigin& origin,
@@ -3004,7 +3032,6 @@
         storeStatus_(StoreStatus_Failure),
         instanceMetadata_(instanceMetadata),
         dicomSummary_(dicomSummary),
-        sequencesToStore_(sequencesToStore),
         attachments_(attachments),
         metadata_(metadata),
         origin_(origin),
@@ -3155,27 +3182,27 @@
 
             content.AddResource(instanceId, ResourceType_Instance, dicomSummary_);
             SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Instance));  // New in Orthanc 1.11.0
-            SetMainDicomSequenceMetadata(content, instanceId, sequencesToStore_, ResourceType_Instance);   // new in Orthanc 1.11.1
+            SetMainDicomSequenceMetadata(content, instanceId, dicomSummary_, ResourceType_Instance);   // new in Orthanc 1.11.1
 
             if (status.isNewSeries_)
             {
               content.AddResource(status.seriesId_, ResourceType_Series, dicomSummary_);
               content.AddMetadata(status.seriesId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Series));  // New in Orthanc 1.11.0
-              SetMainDicomSequenceMetadata(content, status.seriesId_, sequencesToStore_, ResourceType_Series);   // new in Orthanc 1.11.1
+              SetMainDicomSequenceMetadata(content, status.seriesId_, dicomSummary_, ResourceType_Series);   // new in Orthanc 1.11.1
             }
 
             if (status.isNewStudy_)
             {
               content.AddResource(status.studyId_, ResourceType_Study, dicomSummary_);
               content.AddMetadata(status.studyId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Study));  // New in Orthanc 1.11.0
-              SetMainDicomSequenceMetadata(content, status.studyId_, sequencesToStore_, ResourceType_Study);   // new in Orthanc 1.11.1
+              SetMainDicomSequenceMetadata(content, status.studyId_, dicomSummary_, ResourceType_Study);   // new in Orthanc 1.11.1
             }
 
             if (status.isNewPatient_)
             {
               content.AddResource(status.patientId_, ResourceType_Patient, dicomSummary_);
               content.AddMetadata(status.patientId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Patient));  // New in Orthanc 1.11.0
-              SetMainDicomSequenceMetadata(content, status.patientId_, sequencesToStore_, ResourceType_Patient);   // new in Orthanc 1.11.1
+              SetMainDicomSequenceMetadata(content, status.patientId_, dicomSummary_, ResourceType_Patient);   // new in Orthanc 1.11.1
             }
 
             // Attach the auto-computed metadata for the patient/study/series levels
@@ -3320,7 +3347,7 @@
     };
 
 
-    Operations operations(instanceMetadata, dicomSummary, sequencesToStore, attachments, metadata, origin,
+    Operations operations(instanceMetadata, dicomSummary, attachments, metadata, origin,
                           overwrite, hasTransferSyntax, transferSyntax, hasPixelDataOffset,
                           pixelDataOffset, maximumStorageSize, maximumPatients, isReconstruct);
     Apply(operations);
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.h	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.h	Tue Jun 28 17:45:09 2022 +0200
@@ -23,7 +23,6 @@
 #pragma once
 
 #include "../../../OrthancFramework/Sources/DicomFormat/DicomMap.h"
-#include "../../../OrthancFramework/Sources/DicomFormat/DicomSequencesMap.h"
 
 #include "IDatabaseWrapper.h"
 #include "../DicomInstanceOrigin.h"
@@ -41,8 +40,7 @@
   struct ExpandedResource : public boost::noncopyable
   {
     std::string                         id_;
-    DicomMap                            tags_;          // all tags from DB (only leaf tags, not sequences !)
-    DicomSequencesMap                   sequences_;     // the requested sequences (from MainDicomTags or RequestedTags)
+    DicomMap                            tags_;          // all main tags and main sequences from DB
     std::string                         mainDicomTagsSignature_;
     std::string                         parentId_;
     std::list<std::string>              childrenIds_;
@@ -652,7 +650,6 @@
 
     StoreStatus Store(std::map<MetadataType, std::string>& instanceMetadata,
                       const DicomMap& dicomSummary,
-                      const DicomSequencesMap& sequencesToStore,
                       const Attachments& attachments,
                       const MetadataMap& metadata,
                       const DicomInstanceOrigin& origin,
--- a/OrthancServer/Sources/ServerContext.cpp	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancServer/Sources/ServerContext.cpp	Tue Jun 28 17:45:09 2022 +0200
@@ -526,12 +526,9 @@
     bool hasTransferSyntax = dicom.LookupTransferSyntax(transferSyntax);
     
     DicomMap summary;
-    dicom.GetSummary(summary);   // -> this includes only the leaf nodes
+    dicom.GetSummary(summary);   // -> from Orthanc 1.11.1, this includes the leaf nodes and sequences
 
     std::set<DicomTag> allMainDicomTags = DicomMap::GetAllMainDicomTags();
-    std::set<DicomTag> mainDicomSequences;
-    DicomMap::ExtractSequences(mainDicomSequences, allMainDicomTags);
-    DicomSequencesMap sequencesToStore;
 
     try
     {
@@ -541,10 +538,8 @@
       DicomInstanceHasher hasher(summary);
       resultPublicId = hasher.HashInstance();
 
-      Json::Value dicomAsJson;    // -> this includes the sequences
-
-      dicom.GetDicomAsJson(dicomAsJson, mainDicomSequences /*ignoreTagLength*/);  // make sure that sequences that we wish to store in DB are not 'cropped'
-      sequencesToStore.FromDicomAsJson(dicomAsJson, mainDicomSequences);
+      Json::Value dicomAsJson;
+      dicom.GetDicomAsJson(dicomAsJson, allMainDicomTags);  // don't crop any main dicom tags
 
       Json::Value simplifiedTags;
       Toolbox::SimplifyDicomAsJson(simplifiedTags, dicomAsJson, DicomToJsonFormat_Human);
@@ -623,7 +618,7 @@
       typedef std::map<MetadataType, std::string>  InstanceMetadata;
       InstanceMetadata  instanceMetadata;
       result.SetStatus(index_.Store(
-        instanceMetadata, summary, sequencesToStore, attachments, dicom.GetMetadata(), dicom.GetOrigin(), overwrite,
+        instanceMetadata, summary, attachments, dicom.GetMetadata(), dicom.GetOrigin(), overwrite,
         hasTransferSyntax, transferSyntax, hasPixelDataOffset, pixelDataOffset, isReconstruct));
 
       // Only keep the metadata for the "instance" level
@@ -1901,8 +1896,14 @@
   const std::string& ServerContext::GetDeidentifiedContent(const DicomElement &element) const
   {
     static const std::string redactedContent = "*** POTENTIAL PHI ***";
+    static const std::string emptyContent = "";
 
     const DicomTag& tag = element.GetTag();
+    if (element.GetValue().IsSequence())
+    {
+      return emptyContent;
+    }
+    
     if (deidentifyLogs_ &&
         !element.GetValue().GetContent().empty() &&
         logsDeidentifierRules_.IsAlteredTag(tag))
@@ -2083,13 +2084,6 @@
     target[MAIN_DICOM_TAGS] = Json::objectValue;
     FromDcmtkBridge::ToJson(target[MAIN_DICOM_TAGS], mainDicomTags, format);
     
-    {// add the main DICOM sequences to the main dicom tags
-      const std::set<DicomTag>& mainDicomTags = DicomMap::GetMainDicomTags(resource.type_);
-      std::set<DicomTag> mainDicomSequences;
-      DicomMap::ExtractSequences(mainDicomSequences, mainDicomTags);
-      resource.sequences_.ToJson(target[MAIN_DICOM_TAGS], format, mainDicomSequences);
-    }
-
     if (resource.type_ == ResourceType_Study)
     {
       DicomMap patientMainDicomTags;
@@ -2109,12 +2103,6 @@
       target[REQUESTED_TAGS] = Json::objectValue;
       FromDcmtkBridge::ToJson(target[REQUESTED_TAGS], tags, format);
 
-      {// add the requested sequences to the requested tags
-        std::set<DicomTag> requestedDicomSequences;
-        DicomMap::ExtractSequences(requestedDicomSequences, requestedTags);
-        resource.sequences_.ToJson(target[REQUESTED_TAGS], format, requestedDicomSequences);
-      }
-
     }
 
   }
@@ -2426,9 +2414,6 @@
       // possibly merge missing requested tags from dicom-as-json
       if (!resource.missingRequestedTags_.empty() && !DicomMap::HasOnlyComputedTags(resource.missingRequestedTags_))
       {
-        std::set<DicomTag> missingSequences;
-        DicomMap::ExtractSequences(missingSequences, resource.missingRequestedTags_);
-
         OrthancConfiguration::ReaderLock lock;
         if (lock.GetConfiguration().IsWarningEnabled(Warnings_001_TagsBeingReadFromStorage))
         {
@@ -2474,13 +2459,11 @@
   
           Json::Value tmpDicomAsJson;
           ReadDicomAsJson(tmpDicomAsJson, instanceId_, resource.missingRequestedTags_ /* ignoreTagLength */);  // read all tags from DICOM and avoid cropping requested tags
-          tagsFromJson.FromDicomAsJson(tmpDicomAsJson);
-          resource.sequences_.FromDicomAsJson(tmpDicomAsJson, missingSequences);
+          tagsFromJson.FromDicomAsJson(tmpDicomAsJson, false /* append */, true /* parseSequences*/);
         }
         else
         {
-          tagsFromJson.FromDicomAsJson(*dicomAsJson);
-          resource.sequences_.FromDicomAsJson(*dicomAsJson, missingSequences);
+          tagsFromJson.FromDicomAsJson(*dicomAsJson, false /* append */, true /* parseSequences*/);
         }
 
         resource.tags_.Merge(tagsFromJson);
--- a/OrthancServer/Sources/ServerIndex.cpp	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancServer/Sources/ServerIndex.cpp	Tue Jun 28 17:45:09 2022 +0200
@@ -511,7 +511,6 @@
 
   StoreStatus ServerIndex::Store(std::map<MetadataType, std::string>& instanceMetadata,
                                  const DicomMap& dicomSummary,
-                                 const DicomSequencesMap& sequencesToStore,
                                  const ServerIndex::Attachments& attachments,
                                  const ServerIndex::MetadataMap& metadata,
                                  const DicomInstanceOrigin& origin,
@@ -532,7 +531,7 @@
     }
 
     return StatelessDatabaseOperations::Store(
-      instanceMetadata, dicomSummary, sequencesToStore, attachments, metadata, origin, overwrite, hasTransferSyntax,
+      instanceMetadata, dicomSummary, attachments, metadata, origin, overwrite, hasTransferSyntax,
       transferSyntax, hasPixelDataOffset, pixelDataOffset, maximumStorageSize, maximumPatients, isReconstruct);
   }
 
--- a/OrthancServer/Sources/ServerIndex.h	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancServer/Sources/ServerIndex.h	Tue Jun 28 17:45:09 2022 +0200
@@ -77,7 +77,6 @@
 
     StoreStatus Store(std::map<MetadataType, std::string>& instanceMetadata,
                       const DicomMap& dicomSummary,
-                      const DicomSequencesMap& sequencesToStore,
                       const Attachments& attachments,
                       const MetadataMap& metadata,
                       const DicomInstanceOrigin& origin,
--- a/OrthancServer/UnitTestsSources/ServerIndexTests.cpp	Mon Jun 27 15:22:19 2022 +0200
+++ b/OrthancServer/UnitTestsSources/ServerIndexTests.cpp	Tue Jun 28 17:45:09 2022 +0200
@@ -732,14 +732,13 @@
 
     {
       DicomMap summary;
-      DicomSequencesMap sequences;
       OrthancConfiguration::DefaultExtractDicomSummary(summary, toStore->GetParsedDicomFile());
       toStore->SetOrigin(DicomInstanceOrigin::FromPlugins());
 
       DicomTransferSyntax transferSyntax;
       bool hasTransferSyntax = dicom.LookupTransferSyntax(transferSyntax);
       ASSERT_EQ(StoreStatus_Success, index.Store(
-                  instanceMetadata, summary, sequences, attachments, toStore->GetMetadata(),
+                  instanceMetadata, summary, attachments, toStore->GetMetadata(),
                   toStore->GetOrigin(), false /* don't overwrite */,
                   hasTransferSyntax, transferSyntax, true /* pixel data offset */, 42, false));
     }