Greetings!
tldr; - How to politely bulk upload with the project level anonymisation or how to fix the CR (DX) upload in general?
The story:
I'm looking for a way to upload a lot (~18K images) of strongly de-identified data to my private XNAT. These are Kaggle competition data (
https://www.kaggle.com/competitions/vinbigdata-chest-xray-abnormalities-detection/data). The problem is that those dcm files do not have the Modality tag set, but only the SOPClassUID one (1.2.840.10008.5.1.4.1.1.1 and 1.2.840.10008.5.1.4.1.1.1.1).
First problem I've encountered was the prearchive ERROR:
Almost fresh dockerized XNAT setup, with default site-wide anonymisation turned on.
Bulk upload with autogenerated subject id and session label.
XNAT Desktop Client error log:
Type Message Date/Time Details
error Session upload failed (with status code: 500 - ""). 2022-05-15 12:57:59 FAILED: Unable to archive FN450_undefined_1: org.xml.sax.SAXParseException; systemId: file:///data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1.xml; lineNumber: 1; columnNumber: 1; Premature end of file. You can get technical details here. Please continue your visit at our home page.
success Series uploaded 1.2.826.0.1.3680043.2.1143.5315754475745396317638352422706470748. 2022-05-15 12:57:58 undefined
application.log:
2022-05-15 10:57:59,154 [http-nio-8080-exec-8] ERROR org.nrg.session.SessionBuilder - Unable to write session XML for /data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1
java.lang.NullPointerException: null
2022-05-15 10:57:59,274 [http-nio-8080-exec-8] ERROR org.nrg.session.SessionBuilder - /data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1 must contain exactly one session
org.nrg.session.SessionBuilder$NoUniqueSessionException: No session found
at org.nrg.session.SessionBuilder.writeSession(SessionBuilder.java:210)
at org.nrg.session.SessionBuilder.run(SessionBuilder.java:249)
at org.nrg.xnat.archive.XNATSessionBuilder.buildPetSession(XNATSessionBuilder.java:227)
at org.nrg.xnat.archive.XNATSessionBuilder.call(XNATSessionBuilder.java:174)
at org.nrg.xnat.helpers.prearchive.PrearcUtils.buildSession(PrearcUtils.java:808)
at org.nrg.xnat.helpers.prearchive.PrearcUtils.buildSession(PrearcUtils.java:771)
at org.nrg.xnat.helpers.prearchive.PrearcDatabase$13.extSync(PrearcDatabase.java:1035)
at org.nrg.xnat.helpers.prearchive.PrearcDatabase$13.extSync(PrearcDatabase.java:1033)
at org.nrg.xnat.helpers.prearchive.PrearcDatabase$LockAndSync.run(PrearcDatabase.java:1596)
at org.nrg.xnat.helpers.prearchive.PrearcDatabase.buildSession(PrearcDatabase.java:1047)
at org.nrg.xnat.helpers.prearchive.PrearcDatabase.buildSession(PrearcDatabase.java:1015)
at org.nrg.xnat.restlet.resources.prearchive.PrearcSessionResource.postActionCommit(PrearcSessionResource.java:402)
at org.nrg.xnat.restlet.resources.prearchive.PrearcSessionResource.handlePost(PrearcSessionResource.java:267)
at org.restlet.Finder.handle(Finder.java:357)
...
dicom.log:
2022-05-15 10:57:59,059 [http-nio-8080-exec-8] INFO org.nrg.dcm.xnat.DICOMSessionBuilder - Building session for 1.2.826.0.1.3680043.2.1143.3781799682068820516421578260039507767
2022-05-15 10:57:59,086 [http-nio-8080-exec-8] WARN org.nrg.dcm.xnat.DICOMSessionBuilder - Session builder not implemented for SOP class(es) [1.2.840.10008.5.1.4.1.1.1.1] or modality(ies) [null], trying default session builder factory
2022-05-15 10:57:59,090 [http-nio-8080-exec-8] INFO org.nrg.dcm.xnat.DefaultXnatImagesessiondataBeanFactory - Did not find a DICOM session type but did find scan type "dxScanData" for SOP class UIDs, returning generic session bean: [1.2.840.10008.5.1.4.1.1.1.1]
2022-05-15 10:57:59,152 [http-nio-8080-exec-8] INFO org.nrg.dcm.xnat.DICOMSessionBuilder - Warnings occurred in processing /data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1; see org.nrg.sl4fj.PrintWriterLogger(/data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1/dcmtoxnat.log)
jms.log:
2022-05-15 10:57:59,437 [DefaultMessageListenerContainer-6] ERROR org.nrg.xnat.services.messaging.prearchive.PrearchiveOperationRequestListener - An error occurred processing a request from user admin to perform Archive operation on prearchive session at: /prearchive/projects/COVID/20220515_105754243/FN450_undefined_1
java.lang.IllegalStateException: org.xml.sax.SAXParseException; systemId: file:///data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1.xml; lineNumber: 1; columnNumber: 1; Premature end of file.
at org.nrg.xnat.helpers.prearchive.PrearcDatabase._archive(PrearcDatabase.java:949)
at org.nrg.xnat.helpers.prearchive.PrearcDatabase.archive(PrearcDatabase.java:935)
at org.nrg.xnat.helpers.prearchive.handlers.PrearchiveArchiveHandler.commitSessionToArchive(PrearchiveArchiveHandler.java:61)
at org.nrg.xnat.helpers.prearchive.handlers.PrearchiveArchiveHandler.execute(PrearchiveArchiveHandler.java:47)
at org.nrg.xnat.services.messaging.prearchive.PrearchiveOperationRequestListener.onRequest(PrearchiveOperationRequestListener.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:180)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:112)
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:104)
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:69)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:719)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:679)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:649)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:317)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:255)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1167)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1159)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1056)
at java.lang.Thread.run(Thread.java:750)
Caused by: org.xml.sax.SAXParseException: Premature end of file.
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1238)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:642)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:326)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:274)
at org.nrg.framework.services.SerializerService.parse(SerializerService.java:419)
at org.nrg.framework.services.SerializerService.parse(SerializerService.java:378)
at org.nrg.xft.schema.Wrappers.XMLWrapper.SAXReader.parse(SAXReader.java:136)
at org.nrg.xnat.turbine.utils.XNATSessionPopulater.populate(XNATSessionPopulater.java:56)
at org.nrg.xnat.archive.PrearcSessionArchiver.<init>(PrearcSessionArchiver.java:142)
at org.nrg.xnat.helpers.prearchive.PrearcDatabase._archive(PrearcDatabase.java:946)
... 21 common frames omitted
prearchive.log:
2022-05-15 10:57:59,304 [http-nio-8080-exec-8] ERROR org.nrg.xnat.helpers.prearchive.PrearcUtils - /data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1.xml is empty.
received.log:
2022-05-15 10:57:58,775 - admin:/data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1/SCANS/1_2_826_0_1_3680043_2_1143_5315754475745396317638352422706470748/DICOM/1.2.826.0.1.3680043.2.1143.3781799682068820516421578260039507767-no-value-for-SeriesNumber-no-value-for-InstanceNumber-1ebynrv.dcm
restlet.log:
2022-05-15 10:57:59,870 [http-nio-8080-exec-8] ERROR org.nrg.xnat.restlet.resources.prearchive.PrearcSessionResource -
org.nrg.action.ServerException: FAILED: Unable to archive FN450_undefined_1: org.xml.sax.SAXParseException; systemId: file:///data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1.xml; lineNumber: 1; columnNumber: 1; Premature end of file.
at org.nrg.xnat.archive.QueueBasedImageCommit.call(QueueBasedImageCommit.java:169)
at org.nrg.xnat.restlet.resources.prearchive.PrearcSessionResource.postActionCommit(PrearcSessionResource.java:414)
at org.nrg.xnat.restlet.resources.prearchive.PrearcSessionResource.handlePost(PrearcSessionResource.java:267)
at org.restlet.Finder.handle(Finder.java:357)
...
<prearchive>/COVID/20220515_105754243/FN450_undefined_1/dcmtoxnat.log:
session attribute date has no value
session attribute time has no value
session attribute scanner/model has no value
session attribute study_id has no value
session attribute dcmPatientWeight has no value
session attribute modality has no value
session attribute dcmPatientBirthDate has no value
session attribute scanner/manufacturer has no value
session attribute dcmAccessionNumber has no value
session attribute acquisition_site has no value
session attribute fields/field has no value
session attribute operator has no value
This leads also to the "archive pending" status in the project's prearchive.
Rebuilding gives next logs:
application.log:
2022-05-15 12:08:42,446 [DefaultMessageListenerContainer-10] ERROR org.nrg.session.SessionBuilder - Unable to write session XML for /data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1
java.lang.NullPointerException: null
2022-05-15 12:08:42,563 [DefaultMessageListenerContainer-10] ERROR org.nrg.session.SessionBuilder - /data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1 must contain exactly one session
org.nrg.session.SessionBuilder$NoUniqueSessionException: No session found
at org.nrg.session.SessionBuilder.writeSession(SessionBuilder.java:210)
at org.nrg.session.SessionBuilder.run(SessionBuilder.java:249)
...
dicom.log:
2022-05-15 12:08:42,361 [DefaultMessageListenerContainer-10] INFO org.nrg.dcm.xnat.DICOMSessionBuilder - Building session for 1.2.826.0.1.3680043.2.1143.3781799682068820516421578260039507767
2022-05-15 12:08:42,375 [DefaultMessageListenerContainer-10] WARN org.nrg.dcm.xnat.DICOMSessionBuilder - Session builder not implemented for SOP class(es) [1.2.840.10008.5.1.4.1.1.1.1] or modality(ies) [null], trying default session builder factory
2022-05-15 12:08:42,379 [DefaultMessageListenerContainer-10] INFO org.nrg.dcm.xnat.DefaultXnatImagesessiondataBeanFactory - Did not find a DICOM session type but did find scan type "dxScanData" for SOP class UIDs, returning generic session bean: [1.2.840.10008.5.1.4.1.1.1.1]
2022-05-15 12:08:42,444 [DefaultMessageListenerContainer-10] INFO org.nrg.dcm.xnat.DICOMSessionBuilder - Warnings occurred in processing /data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1; see org.nrg.sl4fj.PrintWriterLogger(/data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1/dcmtoxnat.log)
prearchive.log:
2022-05-15 12:08:42,635 [DefaultMessageListenerContainer-10] ERROR org.nrg.xnat.helpers.prearchive.PrearcUtils - /data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1.xml is empty.
turbine.log:
2022-05-15 12:08:46,505 [http-nio-8080-exec-4] ERROR org.nrg.xdat.turbine.modules.screens.SecureScreen -
org.xml.sax.SAXParseException: Premature end of file.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
...
xdat.log:
2022-05-15 12:08:42,168 [DefaultMessageListenerContainer-10] ERROR org.nrg.xnat.archive.XNATSessionBuilder - Couldn't parse previous session xml /data/xnat/prearchive/COVID/20220515_105754243/FN450_undefined_1.xml, no resources will be copied into the rebuilt version
org.xml.sax.SAXParseException: Premature end of file.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
...
After I found this thread, I started creating a plugin. During it, reading logs carefully brought an idea to use the anonymisation as a workaround.
Setting the Modality tag in the anonymisation script for the project does the job for the time-being:
(0008,0060) := "CR"
The dcm file gets uploaded and lands into the subject's CR experiment.
But after enabling it I'm getting the "Project anonymisation script contains variables. Only single session upload is available." message in the XNAT Desktop Client. Is there any polite way to bulk upload with the project level anonymization? Currently I'm turning it off before selecting the project in the Client and later turning it on right before clicking the "Finish and Upload" button.
Another thing, when i'm trying to be more specific in the tag setting:
// Set Modality based on SOPClassUID.
(0008,0016) = "1.2.840.10008.5.1.4.1.1.1.1" ? (0008,0060) := "DX"
(0008,0016) = "1.2.840.10008.5.1.4.1.1.1" ? (0008,0060) := "CR"
it reverts me back to the previous state of not being able to upload the dcm at all - errors from the above are back again.
Best regards,
Ihor