-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sr update aim #197
base: master
Are you sure you want to change the base?
Sr update aim #197
Conversation
I also have a question I am not sure who is the best person to ask @JamesAPetts, is that you? |
This is very timely and we should put our heads together on this. There has been a lot of SR activity also in python for highdicom and also for pathology annotations and AI results, so we should be sure to develop good conventions for interoperability and consistency. @hackermd @CPBridge @seandoyle @fedorov @dclunie maybe we should have a larger group discussion meeting? @igoroctaviano can you also help review this? |
@emelalkim could you share some representative image series with the accompanying SRs that demonstrate the capabilities of your implementation? |
@fedorov I put the sample data set I am using and the draft DICOM SR here. I also put some screenshots. I am going to add some tests after I get a more mature conversion. (FYI, we are working on adding radelements so the AIM file has some made up entities for the codes, please ignore them) |
@emelalkim I took a look at your sample, which looks pretty good. Wrt. TID 1500 compliance: Content item 1.5.1.4 CONTAINS: CODE: (G-C0E3,SRT,"Finding Site") = (RID58,RadLex,"liver") should have a "HAS CONCEPT MOD" relationship with its parent (125007,DCM,"Measurement Group"), not "CONTAINS" http://dicom.nema.org/medical/dicom/current/output/chtml/part16/chapter_A.html#para_67e2ac2d-62c4-47d1-851c-975e33b49fed You are identifying the time point in a non-standard place with a non-standard code:
Wrt. codes: If you are going to use RADLEX or RADELEMENT, please use the standard all-capitalized coding scheme designators, rather than the lower case ones used now: dciodvfy reports: Warning - Unrecognized defined term for value 1 of attribute Also, it would be better to use SCT rather than SRT codes, since the former are deprecated. E.g., instead of (G-A185,SRT,"Long Axis"), use (103339001,SCT,"Long Axis") which is why dciodvfy reports: Warning - Coding Scheme Designator is deprecated - attribute = See http://dicom.nema.org/medical/dicom/current/output/chtml/part16/chapter_8.html#sect_8.1 You will probably not be convinced, but in DICOM we prefer to use SCT codes for anatomy, rather than RadLex, i.e., (10200004, SCT, "Liver") rather than (RID58,RADLEX,"liver") For the finding, you might consider (108369006, SCT, "Tumor") instead of (RECIST_v2,99EPAD,"Tumor assessment"). For specifying it is a target lesion, you might consider (112016, DCM, "Baseline Category") = (112074, DCM, "Target Lesion at Baseline") (see the pattern at http://dicom.nema.org/medical/dicom/current/output/chtml/part16/sect_TID_4102.html#para_929b7c79-ee18-49b2-9eb1-7b7452354fac] For enhancing lesions, DICOM SEGs use (C113842, NCIt, "Enhancing Lesion") rather than (RID6055,RADLEX,"Enhancing") http://ncit.nci.nih.gov/ncitbrowser/ConceptReport.jsp?dictionary=NCI_Thesaurus&code=C113842 For the lesion "status", for the presence or absence of things, DICOM SR templates usually use the generic SNOMED CT codes, e.g., (52101004, SCT, "Present"); see http://dicom.nema.org/medical/dicom/current/output/chtml/part16/sect_CID_241.html |
Thank you very much @dclunie! This is very helpful. I appreciate you taking the time to go through it.
|
Yes, agreed, it would be great if you can update the coding in dcmjs. Great to see progress on this @emelalkim and thank you @dclunie for your help. |
I have just one comments. "Tracking Identifier" is populated to what looks like a mapping to the application-specific tool used to do the annotation. I believe the intent for "Tracking identifier" is to be a human-readable identifier of the finding to facilitate tracking of the finding over time. |
Will do @pieper |
Thanks @fedorov, I'll put the annotation name. I just wanted to have @JamesAPetts's opinion first to see if it will mess up cornerstone as it seems to be doing some checks. I don't understand that part. I didn't hear back yet. If I don't hear back in a couple of days. I'll change it and try to see if it will mess up loading in cornerstone |
If it does - we should revisit this as part of the IDC work. I don't think it should! |
ok. I'll proceed with adding annotation name then. Thanks |
@fedorov - I don't want to hijack this thread - but I was wondering if the "Tracking Identifier" was meant to be immutable? Here's my use case: in the lumbar spine SR that I'm making I create both a tracking identifier and a tracking uid for labeling each lumbar spine disc (there is also a separate SNOMED code for the disc). But a user can shift the vertebral labels up and down if they disagree with the original labeling. I was planning in this case to change the "Tracking Identifier" but not the uid. We want to use the uid to track the changes that the user made. An alternative would be to just use a tracking identifier of 'disc1', 'disc2' and make them immutable. This would avoid the problem of the user changing labels with the result being that they were inconsistent. |
Yes, the current implementation uses a tracking identifier as a key to map the measurement group to its cornerstone annotation tool-type equivalent. In this issue: OHIF/Viewers#1215 we are discussing new alternatives of doing this because storing vendor-specific names in tracking identifiers seems too brittle and we should use a smart matching strategy or something along those lines e.g. bidirectional measurement properties matched? (e.g. match created based on Clunie's planner annotations paper) then assign the correct vendor tool type. Example of planar annotation stowed using OHIF:
where the first bit of the string identifies a vendor, the second bit is the version, and the last bit the vendor annotation tool type. This string should be interpreted and given to MeasurementService in order to map the SR content to its corresponding annotation format using a mapper implemented by the vendor and registered in OHIF. This is not done currently since this service is still in progress, so what's happening is that inside OHIF the SR is interpreted directly and parsed into annotations. More about this service here: https://github.com/dannyrb/Viewers/blob/f99a6699107c932fb067168ef13ea787d00855c8/docs/latest/services/data/measurements.md The measurement service + mappings ideal + ideal way of storing things is still an open discussion. Your incremental changes don't seem to affect our STOWRS/SR logic for cornerstone annotations. |
@igoroctaviano, that doesn't sound like it is going to work if you receive annotations in DICOM SR from another application that doesn't follow your magic convention for how to fill in Tracking Identifier. You should map based on the form of the annotation and allow the Tracking Identifier to be whatever it needs to be for the use case per local procedures (e.g., in a previous life, we required these to follow a certain convention per SOP, such as NT002 for non-target lesion #2, to match entries in our clinical database management system, and not to be constrained by the image annotation tool). |
@seandoyle, nothing should be immutable in the workflow (as opposed to a single serialized instance of an SR) - errors happen, so when a user-mislabeled lesion needs to be renamed (e.g., NT001 to NT002), it might (or might not) be appropriate to keep the same UID, depending on the workflow and local convention (e.g., what needs to happen when a new/updated SR with the corrected information is saved and ingested by the downstream systems that use the information, e.g., RECIST calculations). In your intervertebral disk labeling use case, I might ask the questions: "what does the user want to see?" to which the answer would seem to be "L2/3" not "disc A" or similar, corrected on a subsequent occasion or not, and "does it matter if the UID changes" to which the answer is "it depends", on the impact on the downstream workflow, e.g, are there post-processing measurements/decisions indexed by that UID stored separately, such as "thickness", that should remain associated with that annotation even if its human-readable identifier has changed, or those that should not, such as semantic information such as (67459009, SCT, "Intervertebral disc, L2-L3") Note that in tracking corrections like this, DICOM SR has a predecessor reference mechanism that can be used to determine the head (most recent) "version" to be used (and thence to suppress earlier versions from use), if changes need to be tracked. |
Exactly, that's is the current OHIF approach which at the time was done just as a POC to demo stowrs I guess. This map you mentioned is what I meant in the last comment I think it's not so easy to come with solid matchers for all tools but we can start with simple ones and then incrementing them as we go. I'll try working on at least one e2e example using measurement service + matching criteria + no tracking identifier and then we can get the ball rolling |
Hi @igoroctaviano and @dclunie, |
Also @dclunie,
|
…dentifier from AIM
…he default value according to DICOM standard
I'm pretty sure nobody has done that yet. What I would do is look at the structure of the QIN-HEADNECK data I linked above and just copy it into a new dataset object for conversion to part10. Then as far as I know the best way to test it would be to load it into Slicer's dicom database with the QuantitativeReporting extension installed. If everything is referenced the same as the QIN-HEADNECK conventions then doubleclicking the SR should offer to load the SEG and the referenced images as well. I have done that before for SEG from OHIF, and SR from CrowdsCure, but not SR that references SEG. |
…RT (David Clunie's recommendation)
@pieper @emelalkim the classes in dcmjs.sr.templates should support that in principle. These are pretty much a 1-1 translation of the |
As we work on this can we add some tests for the sr code just to show how all the pieces should fit together? |
…ng the tracking identifier and tracking unique identifier from the report and adding it to the tool
Hey @emelalkim, I was rereading the issue and I think I missed this comment. As Danny said here, I think that's the case for related measurements that are linked by UID? (and span measurement groups)? some measurements will explicitly map to a POINT or POLYLINE, while others are implied or derived from neighboring info. Maybe @dclunie can shed some light on it? Regarding the "in-progress" adapters code I mentioned earlier, just figured that it's not related to freehand or rect (me and my big mouth), it's just a very early adapters code which is basically what we have in dcmjs but scattered. Feel free to implement the freehand and rect adapters, I'll be happy to help to bring people to validate what you have in mind since this is something that's gonna be needed in OHIF as we add freehand and rect SR support. I can even try to reach out to @JamesAPetts or other team members that worked with the adapters before if needed. |
Hi @igoroctaviano, do you mean the tracking Unique Identifier? So if there are more than one ROI in one SR, they would have different tracking unique identifiers. |
That's right. 👍 |
Note that tracking UID is optional. |
Here is an example in the standard of using the same Tracking Unique Identifier in two different Measurement Groups to indicate that different kinds of measurements apply to the same finding. The example uses a SEG reference to define the ROI but the same approach would apply if one used a closed POLYLINE to define a contour around the lesion instead, since it may still be necessary to use separate Measurement Groups if one is defining an Area or Volume, and the other linear distance measurements. http://dicom.nema.org/medical/dicom/current/output/chtml/part17/sect_RRR.5.html Note also that for the bi-dimensional measurements, each of the two perpendicular lines is (a) encoded separately and (b) labelled with a specific code (long vs. short axis). See also the discussion in: |
You would still need to compare the contours point-by-point, no matter whether they have the same UID or not, since I believe the semantics of the UID is to define the finding, not the ROI. So if you have the same finding annotated twice using potentially different contours (I don't think it is forbidden to have this done twice within the same session), I think the expected behavior is that they will have the same UID. |
??? Compare what with what for what purpose? The ROI only needs to be defined once, and the measurements associated with it. If one is comparing across time points (same lesion, different size/shape), then one can check the relevant entries identifying the time point explicitly or the date time the (set of) entries were made. |
David, I was thinking about a scenario where a planar ROI corresponding to the same finding can be present in two different measurement groups within the same SR instance. In this case the findings would have the same tracking UID, but the actual contours may or may not be the same. If the contour points are the same, it would probably be more desirable not to render the same ROI twice. Did I clarify my point? |
@dclunie, @fedorov Here is a sample screenshot of an SR with one ROI with multiple measurement groups. I'll put the DICOM in the releases later today |
I see.
But WTF would that actually "mean", and how would any app present that to the user?
They might be the same "lesion" but they would be different ROIs, and would certainly need different codes describing what they are.
They should probably have different Tracking IDs and UIDs.
E.g. Lesion 1 outlined/segmented on bone window versus Lesion 1 on soft tissue window perhaps (which give very different outlines and sizes).
We could add more IDs/UIDs for ROIs versus actual things (like lesions) for this kind if complex use case, but that might be too much for applications to handle.
PS. You realize that for the linear measurements with endpoints that they are already in different Measurement Groups than the ROI outline or SEG reference, so they need a common identifier ... there are no replicated outlines to "match".
On July 1, 2021 12:53:40 PM EDT, Andrey Fedorov ***@***.***> wrote:
David, I was thinking about a scenario where a planar ROI corresponding to the same finding can be present in two different measurement groups within the same SR instance. In this case the findings would have the same tracking UID, but the actual contours may or may not be the same. If the contour points are the same, it would probably be more desirable not to render the same ROI twice. Did I clarify my point?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#197 (comment)> , or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABBLYVNEQQUN6B2HBMIMNADTVSMRJANCNFSM42PM5RQQ> . <https://github.com/notifications/beacon/ABBLYVNVKA5NYURXTQSNLP3TVSMRJA5CNFSM42PM5RQ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOGP75AAI.gif>
|
That's not a good way to do it @emelalkim, you should define the planar ROI coordinates once, and have multiple measurement children. |
@dclunie I did it like that using the work we did during the XSLT transformation as a reference. here is a sample
|
@emelalkim, the TID 1410 approach is much preferred; the shape is important, and one should avoid depending on assumptions. |
ok. Any objections @igoroctaviano @fedorov @pieper |
No objections from me. I agree it sounds much cleaner to avoid having the points defined twice. |
All I recommend is that someone who is currently working on OHIF test these changes with tracking mode in OHIF v3, for which our original (rather bare bones) implemenation was built for. Tagging @swederik, who has a closer connection to OHIF than I currently, who can get someone to look at this. Otherwise this all looks pretty good, and I'm glad these parts of the library are progressing :) |
Hi @emelalkim , |
I have been working on AIM to DICOM SR conversion.
I am using the Cornerstone adapters because we are using Cornerstone and Cornerstone tools for our frontend
I have found some missing features and started adding them
We worked with David Clunie on AIM DICOM-SR harmonization efforts and I am using that as a reference
Currently I have added
I still have more to implement but I wanted to put this here and ask your opinion/comments
Appreciate any input
Also Steve said Igor is taking over DICOM SR, what is his github handle? I'd like to ask his opinion too