Replacing existing instances on dicom store instead of discarding new data?

Hi,

(solved with the last paragraph, thank you for writing such a neat piece of software)

I'm currently trying to start using Orthanc in my organization to replace a large non-dicom image store. I'm really looking forward to being able to use something with a good REST API and the first-run experience of Orthanc was excellent.

I noticed that when I store dicom images that have a UID that already exists in the database, the transfer is successful, but the updated file is ignored [1] (this came up because I'm refining the dicom files generated from my existing image data)

I wanted to configure Orthanc to overwrite existing files when a changed version is sent via Dicom, but could not figure out a way to achieve that. [3]

While figuring out what to ask I've discovered that the HTTP API is awesome and returns everything I need here. So I'll use HTTP instead of `dcmstore` to import my files [2] That also seems like a better solution to my problem, because Dicom nodes should probably not be able to overwrite existing instances in the archive anyway.

Thank you for reading,
Levin Alexander

[1]

$ img2dcm -k "(0010,0010)"="A" -k "(0010,0020)"="test" a.jpg a.dcm
$ dcmsend -v localhost 4242 a.dcm

# change some properties of the dicom file while keeping UIDs unchanged
$ dcmodify -i "(0010,0010)"="B" a.dcm
$ dcmsend -v localhost 4242 a.dcm

# here the updated file is ignored, but dcmsend returns success.
# the server log shows: "I1103 17:08:58.260460 ServerContext.cpp:264] Already stored"
# but for the client there doesn't seem to be a way to detect if the updated file was accepted or not

$ curl -s "http://orthanc:orthanc@localhost:8042/patients/a94a8fe5-ccb19ba6-1c4c0873-d391e987-982fbbd3?expand" | jq .MainDicomTags.PatientName
#=> "A"

[2]

$ curl http://orthanc:orthanc@localhost:8042/instances --data-binary @a.dcm
{
   "ID" : "32ce9e54-e25d1a96-854dc296-525fb450-09e55f67",
   "Path" : "/instances/32ce9e54-e25d1a96-854dc296-525fb450-09e55f67",
   "Status" : "AlreadyStored"
}
$ curl http://orthanc:orthanc@localhost:8042/instances/32ce9e54-e25d1a96-854dc296-525fb450-09e55f67 -XDELETE
{
   "RemainingAncestor" : {
      "ID" : "a94a8fe5-ccb19ba6-1c4c0873-d391e987-982fbbd3",
      "Path" : "/patients/a94a8fe5-ccb19ba6-1c4c0873-d391e987-982fbbd3",
      "Type" : "Patient"
   }
}
$ curl http://orthanc:orthanc@localhost:8042/instances --data-binary @a.dcm
{
   "ID" : "32ce9e54-e25d1a96-854dc296-525fb450-09e55f67",
   "Path" : "/instances/32ce9e54-e25d1a96-854dc296-525fb450-09e55f67",
   "Status" : "Success"
}

[3]

I thought it might be possible to write a Lua script that deletes the existing instance before writing the new, changed one. However I got stuck very quickly.

While the `OnStoredInstance` callback is called when uploading files that are "Already stored", the uploaded dicom data is deleted at the point the function is called (afaict) and only the original instance data is accessible.

In `ReceivedInstanceFilter` I get the updated dicom data, but at this point I don't see a way to determine the instanceId from that. (also, that callback does not sound like it would be appropriate to delete instances from the database there)

What is sending the repeat files? Does it know the Dicom files are repeated?

Either way I would write this logic external to Orthanc, python would be my choice, call tools/lookup to get the OrthancID (which will be empty if there is no instance in Orthanc) then delete the instance via rest (possibly download it first for safety if you require it) then send the new instance.
I guess you could use the DicomWeb plugin to skip the first step, I don’t.

Chico Venancio
CEO VM TECH
(98)8800-2743

Hi,

What is sending the repeat files? Does it know the Dicom files are repeated?

My importer script does that.

I have a large repository of images that I am slowly converting to DICOM and sending to Orthanc. When I update my converter script to fix import bugs or generate better files I want to replace older ones in Orthanc with those new ones. (keeping UIDs the same so that I don’t end up with duplicates)

Either way I would write this logic external to Orthanc, python would be my choice,

Yeah, looks like this is the best solution. Going to import with the rest API and delete existing instances when I encounter duplicates.

call tools/lookup to get the OrthancID (which will be empty if there is no instance in Orthanc) then delete the instance via rest (possibly download it first for safety if you require it) then send the new instance.
I guess you could use the DicomWeb plugin to skip the first step, I don’t.

I don’t even need to check with /tools/lookup before uploading because when I upload via HTTP, the API response tells me if what was just uploaded was a duplicate or not (“Status” : “AlreadyStored”). :slight_smile:

Thank you.

–Levin Alexander