DicomEdit

320 views
Skip to first unread message

Ben Wagner

unread,
Mar 22, 2013, 4:29:35 PM3/22/13
to xnat_di...@googlegroups.com
Hey DicomEdit Wizards,

  Couple of questions,

1) Is there a way to test a DicomEdit "script" on a dicom in the command line?  How?

2) Can I store a store part of a reqular expression into a variable?  For example, with  the string "abc_def_ghi" can I get the "def" out using a regular expression? A short example would be nice.

Thanks,
Ben

Archie, Kevin

unread,
Mar 24, 2013, 3:13:26 AM3/24/13
to <xnat_discussion@googlegroups.com>, dicombrow...@googlegroups.com
Ben,

1. DicomRemap (in the .tgz distribution of DicomBuilder) is a command-line program that applies DicomEdit scripts. (Documented, sort of, here: http://nrg.wustl.edu/software/dicom-browser/instructions/command-line-interface)

2. Yes, with the caveat that variable scope is complicated. (Or, rather, simple but unintuitive.)

   second_part := match["abc_def_ghi", "(\\w{3})_(\\w{3})_(\\w{3})", 2]

You probably want to use a tag as the first argument in that expression -- I just used a string literal for testing.

Because all DicomEdit variables have global (really, per applicator object lifetime) scope, that variable value initialization happens once, evaluating any tag values from whatever file the engine happens to read first -- so you couldn't use this to extract anything from individual files. You could use match to get values from individual files, so long as you use the resulting value directly rather than initializing a variable with it, say:

(0010,0020) := match[(0010,0020), "(\\w{3}_(\\w{3})_(\\w{3})", 2]

or you could pass the result of match to something like format if you wanted something more complicated.

  - Kevin


--
You received this message because you are subscribed to the Google Groups "xnat_discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to xnat_discussi...@googlegroups.com.
To post to this group, send email to xnat_di...@googlegroups.com.
Visit this group at http://groups.google.com/group/xnat_discussion?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 




The material in this message is private and may contain Protected Healthcare Information (PHI). If you are not the intended recipient, be advised that any unauthorized use, disclosure, copying or the taking of any action in reliance on the contents of this information is strictly prohibited. If you have received this email in error, please immediately notify the sender via telephone or return mail.

Archie, Kevin

unread,
Mar 24, 2013, 3:16:26 AM3/24/13
to <xnat_discussion@googlegroups.com>, dicombrow...@googlegroups.com
On Mar 24, 2013, at 2:13 AM, Archie, Kevin wrote:

1. DicomRemap (in the .tgz distribution of DicomBuilder)

That would be DicomBrowser. I can't even guess what my fingers were trying to do there.

Ben Wagner

unread,
Mar 24, 2013, 7:42:43 AM3/24/13
to xnat_di...@googlegroups.com, arc...@mir.wustl.edu, dicombrow...@googlegroups.com
Hi Kevin,
Thanks for the detailed answers!

Ben
> xnat_discussi...@googlegroups.com<mailto:xnat_discussi...@googlegroups.com>.
> To post to this group, send email to
> xnat_di...@googlegroups.com<mailto:xnat_di...@googlegroups.com>.

Ben Wagner

unread,
Mar 26, 2013, 11:26:52 AM3/26/13
to xnat_di...@googlegroups.com, arc...@mir.wustl.edu, dicombrow...@googlegroups.com
Hi Kevin,
Nearly done.  This is the script I've got so far:

subject := match[(0010,4000),"Project: (.*); Subject: (.*); Session: (.*)",2]
session := match[(0010,4000),"Project: (.*); Subject: (.*); Session: (.*)",3]
//(0038,4000) [VisitCommets] is our project variable since we cannot use a variable in the pattern matching below
(0038,4000) := match[(0010,4000),"Project: (.*); Subject: (.*); Session: (.*)",1]
(0010,0010) ~ "KIDS.*" : (0038,4000) := "KIDS"
(0010,0010) ~ "kids.*" : (0038,4000) := "KIDS"
(0010,0010) ~ "AADHS.*" : (0038,4000) := "AADHS"
(0010,0010) ~ "aadhs.*" : (0038,4000) := "AADHS"
(0010,4000) := format["Project: {0}; Subject: {1}; Session: {2}",(0038,4000),subject,session]

2 things...

First.  I tried to use the pattern matching and assign the KIDS/AADHS strings.  I received the following error, so used the empty (0038,4000) field.  Not ideal, so if there is a better way, I'd like to know.

line 5:25 no viable alternative at input 'project'
org/nrg/dcm/edit/EditDCMTreeParser.g: node from line 0:0 no viable alternative at input '(0010,0010) ~ "kids.*" : (0038,4000) := "KIDS"'

Second.  The above script works in DicomRemap, but when placed in the Annonymization tab in XNAT 1.6.1 it doesn't work.  The problem appears to be the last line.  The error in application logs is below.  Any ideas?

Thanks,
Ben

2013-03-26 11:07:39,784 [pool-1-thread-8] ERROR org.nrg.dcm.CStoreService - C-STORE operation failed
org.nrg.action.ServerException: java.io.IOException: java.lang.NullPointerException
        at org.nrg.xnat.archive.GradualDicomImporter.call(GradualDicomImporter.java:431)
        at org.nrg.dcm.CStoreService.doCStore(CStoreService.java:231)
        at org.nrg.dcm.CStoreService.cstore(CStoreService.java:194)
        at org.dcm4che2.net.DicomServiceRegistry.process(DicomServiceRegistry.java:238)
        at org.dcm4che2.net.NetworkApplicationEntity.perform(NetworkApplicationEntity.java:1158)
        at org.dcm4che2.net.Association.onDimseRQ(Association.java:979)
        at org.dcm4che2.net.PDUDecoder.decodeDIMSE(PDUDecoder.java:530)
        at org.dcm4che2.net.Association.onPDataTF(Association.java:956)
        at org.dcm4che2.net.State$Sta6.receivedPDataTF(State.java:239)
        at org.dcm4che2.net.Association.receivedPDataTF(Association.java:952)
        at org.dcm4che2.net.PDUDecoder.nextPDU(PDUDecoder.java:231)
        at org.dcm4che2.net.Association.run(Association.java:851)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
        at java.lang.Thread.run(Thread.java:722)
Caused by: java.io.IOException: java.lang.NullPointerException
        at org.nrg.dcm.Anonymize.anonymize(Anonymize.java:474)
        at org.nrg.dcm.Anonymize.anonymize(Anonymize.java:207)
        at org.nrg.xnat.archive.GradualDicomImporter.call(GradualDicomImporter.java:400)
        ... 14 more
Caused by: java.lang.NullPointerException
        at java.util.regex.Matcher.getTextLength(Matcher.java:1234)
        at java.util.regex.Matcher.reset(Matcher.java:308)
        at java.util.regex.Matcher.<init>(Matcher.java:228)
        at java.util.regex.Pattern.matcher(Pattern.java:1088)
        at org.nrg.dcm.edit.fn.Match.evaluate(Match.java:76)
        at org.nrg.dcm.edit.fn.Match.access$000(Match.java:26)
        at org.nrg.dcm.edit.fn.Match$1.on(Match.java:70)
        at org.nrg.dcm.edit.Assignment.toString(Assignment.java:112)
        at java.lang.String.valueOf(String.java:2854)
        at java.lang.StringBuilder.append(StringBuilder.java:128)
        at org.nrg.dcm.edit.Statement.toString(Statement.java:55)
        at java.lang.String.valueOf(String.java:2854)
        at java.lang.StringBuilder.append(StringBuilder.java:128)
        at java.util.AbstractCollection.toString(AbstractCollection.java:450)
        at java.lang.String.valueOf(String.java:2854)
        at java.lang.StringBuffer.append(StringBuffer.java:232)
        at org.slf4j.helpers.MessageFormatter.deeplyAppendParameter(MessageFormatter.java:237)
        at org.slf4j.helpers.MessageFormatter.arrayFormat(MessageFormatter.java:196)
        at org.slf4j.helpers.MessageFormatter.format(MessageFormatter.java:111)
        at org.slf4j.impl.JCLLoggerAdapter.trace(JCLLoggerAdapter.java:88)
        at org.nrg.dcm.edit.ScriptApplicator.<init>(ScriptApplicator.java:104)
        at org.nrg.dcm.edit.ScriptApplicator.<init>(ScriptApplicator.java:119)
        at org.nrg.dcm.Anonymize$AnonymizeHelper.call(Anonymize.java:356)
        at org.nrg.dcm.Anonymize$AnonymizeHelper.call(Anonymize.java:324)
        at org.nrg.dcm.WorkOnCopyOp.run(WorkOnCopyOp.java:51)
        at org.nrg.transaction.Run.runTransaction(Run.java:8)
        at org.nrg.dcm.Anonymize.anonymize(Anonymize.java:470)
        ... 16 more
2013-03-26 11:07:39,785 [pool-1-thread-8] INFO  org.dcm4che2.net.PDUEncoder - XNAT(1534) << 1:C-STORE-RSP[pcid=105, status=a700H
        error=java.io.IOException: java.lang.NullPointerException
        cuid=1.2.840.10008.5.1.4.1.1.4/MR Image Storage
        iuid=1.3.12.2.1107.5.99.2.3938.30000012110518243557800001231]
2013-03-26 11:07:39,785 [pool-1-thread-8] DEBUG org.dcm4che2.net.PDUEncoder - Command:
(0000,0002) UI #26 [1.2.840.10008.5.1.4.1.1.4] Affected SOP Class UID
(0000,0100) US #2 [32769] Command Field
(0000,0120) US #2 [1] Message ID Being Responded To
(0000,0800) US #2 [257] Data Set Type
(0000,0900) US #2 [42752] Status
(0000,0902) LO #52 [java.io.IOException: java.lang.NullPointerException] Error Comment
(0000,1000) UI #56 [1.3.12.2.1107.5.99.2.3938.30000012110518243557800001231] Affected SOP Instance U

Archie, Kevin

unread,
Mar 26, 2013, 11:58:58 AM3/26/13
to Ben Wagner, xnat_di...@googlegroups.com, dicombrow...@googlegroups.com

Ben,

 

As you’ve determined, variable initializations can’t be conditional. (Let me think about that for a bit – it might be okay to relax that condition, I just want to make sure that it wouldn’t break something else.)

 

Also, all values are evaluated on the pre-modification values – and since there is no 38,4000 in your original object, the 38,4000 in your format call is null (which is why the NPE gets thrown).

 

So, some things for me to do:

 

1.       Fix the NPE – that script should have completed, although it wouldn’t have done what you wanted anyway

2.       Make it possible to assign variables in conditional statements, or come up with a convincing reason not to, and

3.       Put an updated jar in our maven repo.

 

I’ll try to fit that in by the end of the week.

 

In the meantime, you could kludge the script into working by manual substitution:

 

subject := match[(0010,4000),"Project: (.*); Subject: (.*); Session: (.*)",2]
session := match[(0010,4000),"Project: (.*); Subject: (.*); Session: (.*)",3]

(0010,0010) ~ "(?i)kids.*" : (0010,4000) := format["Project: KIDS; Subject: {0}; Session: {1}”,subject,session]

(0010,0010) ~ "(?i)aadhs.*" : (0010,4000) := format["Project: AADHS; Subject: {0}; Session: {1}”,subject,session]

 

-         Kevin

Ben Wagner

unread,
Mar 26, 2013, 12:30:44 PM3/26/13
to xnat_di...@googlegroups.com, Ben Wagner, dicombrow...@googlegroups.com
I don't find your kludge kludgy at all.  I'm happy just using it.  Wish I'd have thought of it....  Got to test it, but if it works its great!

So, unless you just have nothing to do (ha!), don't worry about updating the codebase for me.

Thanks!
Ben

Ben Wagner

unread,
Mar 26, 2013, 2:02:39 PM3/26/13
to xnat_di...@googlegroups.com
Kevin,

Bugger, its so close.  I'm still getting a Null pointer error.  Appears that subject/session are not being passed nicely to format.  This works:


subject := match[(0010,4000),"Project: (.*); Subject: (.*); Session: (.*)",2]
session := match[(0010,4000),"Project: (.*); Subject: (.*); Session: (.*)",3]
x := "hi"
y := "there"
(0010,0010) ~ "(?i)aadhs.*" : (0010,4000) := format["Project: AADHS; Subject: {0}; Session: {1}",x,y]
//(0010,0010) ~ "(?i)aadhs.*" : (0010,4000) := format["Project: AADHS; Subject: {0}; Session: {1}",subject,session]

But the commented line does not.  Again, this  happens in XNAT, but not in DicomRemap.

Ben

Archie, Kevin

unread,
Mar 26, 2013, 3:41:03 PM3/26/13
to <xnat_discussion@googlegroups.com>, dicombrow...@googlegroups.com
Hm. I'm suspicious of those matches, wondering if they're getting an unexpected result somehow.

This might be easier to debug if DicomRemap and XNAT were using more similar versions of DicomEdit. Try this build:


and add:

echo subject
echo session

...to see what DicomEdit 3.0.x does with the script.

  - Kevin

--
You received this message because you are subscribed to the Google Groups "xnat_discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to xnat_discussi...@googlegroups.com.
To post to this group, send email to xnat_di...@googlegroups.com.

the...@wagners.homeip.net

unread,
Mar 26, 2013, 4:22:38 PM3/26/13
to xnat_di...@googlegroups.com, dicombrow...@googlegroups.com
Yeah, that behaves differently. Its asking for values for session and
subject.

Ben
> org.dcm4che2.net<http://org.dcm4che2.net>.DicomServiceRegistry.process(DicomServiceRegistry.java:238)
> at
> org.dcm4che2.net<http://org.dcm4che2.net>.NetworkApplicationEntity.perform(NetworkApplicationEntity.java:1158)
> xnat_discussi...@googlegroups.com<mailto:xnat_discussi...@googlegroups.com>.
> To post to this group, send email to
> xnat_di...@googlegroups.com<mailto:xnat_di...@googlegroups.com>.

Archie, Kevin

unread,
Mar 26, 2013, 4:27:13 PM3/26/13
to <xnat_discussion@googlegroups.com>, dicombrow...@googlegroups.com
You should just be able to hit return to get the initialized values (the ones that come from the match statements). Those initialized values will appear in the prompts, in square brackets.

- Kevin

On Mar 26, 2013, at 3:22 PM, <the...@wagners.homeip.net>
wrote:

Ben Wagner

unread,
Mar 27, 2013, 10:47:02 AM3/27/13
to xnat_di...@googlegroups.com
I'm able to get the expected session/subject.  There are no values in brackets appearing, though.

Ben
Reply all
Reply to author
Forward
0 new messages