diff --git a/weasis-core/src/main/java/org/weasis/core/ui/model/layer/LayerType.java b/weasis-core/src/main/java/org/weasis/core/ui/model/layer/LayerType.java index 7b947a375..18ec72ba1 100755 --- a/weasis-core/src/main/java/org/weasis/core/ui/model/layer/LayerType.java +++ b/weasis-core/src/main/java/org/weasis/core/ui/model/layer/LayerType.java @@ -82,6 +82,8 @@ public enum LayerType { Boolean.TRUE, Boolean.TRUE), + DICOM_SEG(95, "DICOM SEG", Boolean.TRUE, Boolean.TRUE, Boolean.FALSE, Boolean.FALSE), // NON-NLS + DICOM_SR(100, "DICOM SR", Boolean.TRUE, Boolean.TRUE, Boolean.FALSE, Boolean.TRUE), // NON-NLS DICOM_RT(110, "DICOM RT", Boolean.TRUE, Boolean.TRUE, Boolean.FALSE, Boolean.FALSE), // NON-NLS diff --git a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/AbstractKOSpecialElement.java b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/AbstractKOSpecialElement.java index 80cbd2e24..33116de6a 100755 --- a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/AbstractKOSpecialElement.java +++ b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/AbstractKOSpecialElement.java @@ -19,6 +19,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.stream.Collectors; import org.dcm4che3.data.Attributes; import org.dcm4che3.data.Tag; @@ -29,7 +31,7 @@ import org.weasis.dicom.codec.macro.SOPInstanceReferenceAndMAC; import org.weasis.dicom.codec.macro.SeriesAndInstanceReference; -public class AbstractKOSpecialElement extends DicomSpecialElement { +public class AbstractKOSpecialElement extends HiddenSpecialElement { public static class Reference { private final String studyInstanceUID; @@ -499,4 +501,89 @@ private static int[] removeFrames(int[] arr1, List frameList) { } return result.stream().mapToInt(i -> i).toArray(); } + + /** + * @param seriesUID the Series Instance UID + * @param specialElements the list of DicomSpecialElement + * @return the KOSpecialElement collection for the given parameters, if the referenced seriesUID + * is null all the KOSpecialElement from specialElements collection are returned. In any case + * all the KOSpecialElement that are writable will be added to the returned collection + * whatever is the seriesUID. These KO are part of the new created one's by users of the + * application + */ + public static Collection getKoSpecialElements( + Collection specialElements, String seriesUID) { + + if (specialElements == null) { + return Collections.emptySet(); + } + + SortedSet koElementSet = null; + for (KOSpecialElement koElement : specialElements) { + Set referencedSeriesInstanceUIDSet = koElement.getReferencedSeriesInstanceUIDSet(); + if (seriesUID == null + || referencedSeriesInstanceUIDSet.contains(seriesUID) + || koElement.getMediaReader().isEditableDicom()) { + + if (koElementSet == null) { + koElementSet = new TreeSet<>(ORDER_BY_DATE); + } + koElementSet.add(koElement); + } + } + return koElementSet == null ? Collections.emptySet() : koElementSet; + } + + public static Collection getRejectionKoSpecialElements( + Collection specialElements, String seriesUID) { + + if (specialElements == null) { + return Collections.emptySet(); + } + + SortedSet sortedSet = null; + for (RejectedKOSpecialElement element : specialElements) { + Set referencedSeriesInstanceUIDSet = element.getReferencedSeriesInstanceUIDSet(); + + if (seriesUID == null + || referencedSeriesInstanceUIDSet.contains(seriesUID) + || element.getMediaReader().isEditableDicom()) { + + if (sortedSet == null) { + sortedSet = new TreeSet<>(ORDER_BY_DATE); + } + sortedSet.add(element); + } + } + return sortedSet == null ? Collections.emptySet() : sortedSet; + } + + public static RejectedKOSpecialElement getRejectionKoSpecialElement( + Collection specialElements, + String seriesUID, + String sopUID, + Integer dicomFrameNumber) { + + if (specialElements == null) { + return null; + } + List koList = null; + + for (RejectedKOSpecialElement koElement : specialElements) { + if (isSopuidInReferencedSeriesSequence( + koElement.getReferencedSOPInstanceUIDObject(seriesUID), sopUID, dicomFrameNumber)) { + if (koList == null) { + koList = new ArrayList<>(); + } + koList.add(koElement); + } + } + + if (koList != null && !koList.isEmpty()) { + // return the most recent Rejection Object + koList.sort(ORDER_BY_DATE); + return koList.getFirst(); + } + return null; + } } diff --git a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomMediaIO.java b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomMediaIO.java index 9673ac5ed..42215db42 100755 --- a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomMediaIO.java +++ b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomMediaIO.java @@ -24,6 +24,7 @@ import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import org.dcm4che3.data.Attributes; import org.dcm4che3.data.BulkData; @@ -83,6 +84,7 @@ public class DicomMediaIO implements DcmMediaReader { public static final String SERIES_MIMETYPE = "series/dicom"; // NON-NLS public static final String SERIES_PR_MIMETYPE = "pr/dicom"; // NON-NLS public static final String SERIES_KO_MIMETYPE = "ko/dicom"; // NON-NLS + public static final String SERIES_SEG_MIMETYPE = "seg/dicom"; // NON-NLS public static final String SERIES_ENCAP_DOC_MIMETYPE = "encap/dicom"; // NON-NLS public static final String UNREADABLE = "unreadable/dicom"; // NON-NLS @@ -186,13 +188,12 @@ public class DicomMediaIO implements DcmMediaReader { } public static final Map DCM_ELEMENT_FACTORIES = - new HashMap<>(); + new ConcurrentHashMap<>(); static { - /* - * DICOM PR and KO are not displayed with a special viewer but are transversally managed objects. So they are - * not registered from a viewer. - */ + // The hidden type factories are not displayed with a special viewer but are transversally + // managed objects. + DCM_ELEMENT_FACTORIES.put( "PR", new DicomSpecialElementFactory() { @@ -207,11 +208,17 @@ public String[] getModalities() { return new String[] {"PR"}; } + @Override + public boolean isHidden() { + return true; + } + @Override public DicomSpecialElement buildDicomSpecialElement(DicomMediaIO mediaIO) { return new PRSpecialElement(mediaIO); } }); + DCM_ELEMENT_FACTORIES.put( "KO", new DicomSpecialElementFactory() { @@ -226,6 +233,11 @@ public String[] getModalities() { return new String[] {"KO"}; } + @Override + public boolean isHidden() { + return true; + } + @Override public DicomSpecialElement buildDicomSpecialElement(DicomMediaIO mediaIO) { if (RejectedKOSpecialElement.isRejectionKOS(mediaIO)) { @@ -234,6 +246,31 @@ public DicomSpecialElement buildDicomSpecialElement(DicomMediaIO mediaIO) { return new KOSpecialElement(mediaIO); } }); + + DCM_ELEMENT_FACTORIES.put( + "SEG", + new DicomSpecialElementFactory() { + + @Override + public String getSeriesMimeType() { + return SERIES_SEG_MIMETYPE; + } + + @Override + public String[] getModalities() { + return new String[] {"SEG"}; + } + + @Override + public boolean isHidden() { + return true; + } + + @Override + public DicomSpecialElement buildDicomSpecialElement(DicomMediaIO mediaIO) { + return new SegSpecialElement(mediaIO); + } + }); } private static final SoftHashMap HEADER_CACHE = @@ -325,7 +362,7 @@ public synchronized boolean isReadableDicom() { return false; } - if (tags.size() == 0) { + if (tags.isEmpty()) { try { DicomMetaData md = readMetaData(); Attributes fmi = md.getFileMetaInformation(); @@ -347,7 +384,11 @@ public synchronized boolean isReadableDicom() { // MPEG4 AVC/H.264 BD 1.2.840.10008.1.2.4.103 mimeType = SERIES_VIDEO_MIMETYPE; } else { - mimeType = IMAGE_MIMETYPE; + if ("1.2.840.10008.5.1.4.1.1.66.4".equals(mediaStorageSOPClassUID)) { + mimeType = SERIES_SEG_MIMETYPE; // Do not display SEG images + } else { + mimeType = IMAGE_MIMETYPE; + } } } else { boolean special = setDicomSpecialType(header); @@ -423,7 +464,7 @@ public Iterator> getTagEntrySetIterator() { } private void writeInstanceTags(DicomMetaData md) { - if (tags.size() > 0 || md == null || md.getDicomObject() == null) { + if (!tags.isEmpty() || md == null || md.getDicomObject() == null) { return; } Attributes fmi = md.getFileMetaInformation(); @@ -698,8 +739,9 @@ public synchronized MediaElement[] getMediaElement() { } else if (SERIES_ENCAP_DOC_MIMETYPE.equals(mimeType)) { image = new MediaElement[] {new DicomEncapDocElement(this, null)}; } else { + DicomSpecialElementFactory factory = getDicomSpecialElementFactory(); if (numberOfFrame > 0) { - image = new MediaElement[numberOfFrame]; + image = new MediaElement[factory == null ? numberOfFrame : numberOfFrame + 1]; for (int i = 0; i < image.length; i++) { image[i] = new DicomImageElement(this, i); } @@ -712,18 +754,15 @@ public synchronized MediaElement[] getMediaElement() { image[i].setTag(TagD.get(Tag.InstanceNumber), nb); } } - } else { - String modality = TagD.getTagValue(this, Tag.Modality, String.class); - if (modality != null) { - DicomSpecialElementFactory factory = DCM_ELEMENT_FACTORIES.get(modality); - if (factory != null) { - image = new MediaElement[1]; - image[0] = factory.buildDicomSpecialElement(this); - } + if (factory != null) { + image[numberOfFrame] = factory.buildDicomSpecialElement(this); } - if (image == null) { + } else { + if (factory == null) { // Corrupted image => should have one frame image = new MediaElement[0]; + } else { + image = new MediaElement[] {factory.buildDicomSpecialElement(this)}; } } } @@ -731,6 +770,14 @@ public synchronized MediaElement[] getMediaElement() { return image; } + private DicomSpecialElementFactory getDicomSpecialElementFactory() { + String modality = TagD.getTagValue(this, Tag.Modality, String.class); + if (modality != null) { + return DCM_ELEMENT_FACTORIES.get(modality); + } + return null; + } + @Override public MediaSeries getMediaSeries() { Series series = null; @@ -880,4 +927,14 @@ private synchronized DicomMetaData readMetaData() throws IOException { reader.dispose(); } } + + public static boolean isHiddenModality(String modality) { + if (modality != null) { + DicomSpecialElementFactory factory = DCM_ELEMENT_FACTORIES.get(modality); + if (factory != null) { + return factory.isHidden(); + } + } + return false; + } } diff --git a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSeries.java b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSeries.java index 20dc343ef..af9c93aff 100755 --- a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSeries.java +++ b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSeries.java @@ -9,6 +9,7 @@ */ package org.weasis.dicom.codec; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -51,6 +52,50 @@ public DicomSeries(String subseriesInstanceUID, List c, TagVi SortSeriesStack.instanceNumber); } + public static List getHiddenElementsFromSeries(Class clazz, String... seriesUID) { + if (clazz != null && clazz.isAssignableFrom(clazz)) { + List list = new ArrayList<>(); + for (String uid : seriesUID) { + if (StringUtil.hasText(uid)) { + List hiddenElements = + HiddenSeriesManager.getInstance().series2Elements.get(uid); + if (hiddenElements != null) { + for (HiddenSpecialElement el : hiddenElements) { + if (clazz.isInstance(el)) { + list.add((E) el); + } + } + } + } + } + return list; + } + return Collections.emptyList(); + } + + public static List getHiddenElementsFromPatient(String patientPseudoUID, Class clazz) { + if (StringUtil.hasText(patientPseudoUID) && clazz != null && clazz.isAssignableFrom(clazz)) { + List patients = + HiddenSeriesManager.getInstance().patient2Series.get(patientPseudoUID); + if (patients != null) { + List list = new ArrayList<>(); + for (String seriesUID : patients) { + List hiddenElements = + HiddenSeriesManager.getInstance().series2Elements.get(seriesUID); + if (hiddenElements != null) { + for (HiddenSpecialElement el : hiddenElements) { + if (clazz.isInstance(el)) { + list.add((E) el); + } + } + } + } + return list; + } + } + return Collections.emptyList(); + } + public boolean[] getImageInMemoryList() { boolean[] list; synchronized (this) { @@ -149,6 +194,25 @@ public String getMimeType() { @Override public void dispose() { stopPreloading(this); + String seriesUID = (String) getTagValue(getTagID()); + String modality = TagD.getTagValue(this, Tag.Modality, String.class); + if (DicomMediaIO.isHiddenModality(modality)) { + List removed = + HiddenSeriesManager.getInstance().series2Elements.remove(seriesUID); + if (removed != null && !removed.isEmpty()) { + String patientPseudoUID = (String) removed.getFirst().getTagValue(TagW.PatientPseudoUID); + if (patientPseudoUID != null) { + List list = + HiddenSeriesManager.getInstance().patient2Series.get(patientPseudoUID); + if (list != null) { + list.remove(seriesUID); + if (list.isEmpty()) { + HiddenSeriesManager.getInstance().patient2Series.remove(patientPseudoUID); + } + } + } + } + } super.dispose(); } @@ -228,11 +292,10 @@ public boolean hasMediaContains(TagW tag, Object val) { } } if (medias.isEmpty()) { - List seriesSpecialElementList = - (List) getTagValue(TagW.DicomSpecialElementList); - if (seriesSpecialElementList != null) { - for (DicomSpecialElement seriesSpecialElement : seriesSpecialElementList) { - Object val2 = seriesSpecialElement.getTagValue(tag); + List list = getAllDicomSpecialElement(); + if (list != null) { + for (DicomSpecialElement specialElement : list) { + Object val2 = specialElement.getTagValue(tag); if (val.equals(val2)) { return true; } @@ -243,12 +306,28 @@ public boolean hasMediaContains(TagW tag, Object val) { return false; } + public List getAllDicomSpecialElement() { + List specialElements = + (List) getTagValue(TagW.DicomSpecialElementList); + if (specialElements != null) { + return specialElements; + } + + String seriesUID = (String) getTagValue(getTagID()); + List list = + HiddenSeriesManager.getInstance().series2Elements.get(seriesUID); + if (list != null && !list.isEmpty()) { + return new ArrayList<>(list); + } + return Collections.emptyList(); + } + @Override public DicomSpecialElement getFirstSpecialElement() { List specialElements = (List) getTagValue(TagW.DicomSpecialElementList); if (specialElements != null && !specialElements.isEmpty()) { - return specialElements.get(0); + return specialElements.getFirst(); } return null; } diff --git a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSpecialElement.java b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSpecialElement.java index 7c598327f..03898a3ab 100755 --- a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSpecialElement.java +++ b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSpecialElement.java @@ -12,14 +12,8 @@ import java.io.File; import java.io.IOException; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; import org.dcm4che3.data.Attributes; import org.dcm4che3.data.Tag; import org.dcm4che3.data.UID; @@ -49,14 +43,9 @@ public int compare(DicomSpecialElement arg0, DicomSpecialElement arg1) { @Override public int compare(DicomSpecialElement m1, DicomSpecialElement m2) { - - // Note : Dicom Standard PS3.3 - Table C.17.6-1 KEY OBJECT DOCUMENT SERIES MODULE - // ATTRIBUTES - // // SeriesDate stands for "Date the Series started" and is optional parameter, don't use - // this to compare - // and prefer "Content Date And Time" Tags (date and time the document content creation - // started) + // this to compare and prefer "Content Date And Time" Tags (date and time the document + // content creation started) LocalDateTime date1 = TagD.dateTime(Tag.ContentDate, Tag.ContentTime, m1); LocalDateTime date2 = TagD.dateTime(Tag.ContentDate, Tag.ContentTime, m2); @@ -201,125 +190,6 @@ public static boolean isSopuidInReferencedSeriesSequence( return true; } } - return false; } - - /** - * @param seriesUID the Series Instance UID - * @param specialElements the list of DicomSpecialElement - * @return the KOSpecialElement collection for the given parameters, if the referenced seriesUID - * is null all the KOSpecialElement from specialElements collection are returned. In any case - * all the KOSpecialElement that are writable will be added to the returned collection - * whatever is the seriesUID. These KO are part of the new created one's by users of the - * application - */ - public static Collection getKoSpecialElements( - Collection specialElements, String seriesUID) { - - if (specialElements == null) { - return Collections.emptySet(); - } - - SortedSet koElementSet = null; - - for (DicomSpecialElement element : specialElements) { - - if (element instanceof KOSpecialElement koElement) { - Set referencedSeriesInstanceUIDSet = koElement.getReferencedSeriesInstanceUIDSet(); - - if (seriesUID == null - || referencedSeriesInstanceUIDSet.contains(seriesUID) - || koElement.getMediaReader().isEditableDicom()) { - - if (koElementSet == null) { - koElementSet = new TreeSet<>(ORDER_BY_DATE); - } - koElementSet.add(koElement); - } - } - } - return koElementSet == null ? Collections.emptySet() : koElementSet; - } - - public static Collection getRejectionKoSpecialElements( - Collection specialElements, String seriesUID) { - - if (specialElements == null) { - return Collections.emptySet(); - } - - SortedSet koElementSet = null; - - for (DicomSpecialElement element : specialElements) { - - if (element instanceof RejectedKOSpecialElement koElement) { - Set referencedSeriesInstanceUIDSet = koElement.getReferencedSeriesInstanceUIDSet(); - - if (seriesUID == null - || referencedSeriesInstanceUIDSet.contains(seriesUID) - || koElement.getMediaReader().isEditableDicom()) { - - if (koElementSet == null) { - koElementSet = new TreeSet<>(ORDER_BY_DATE); - } - koElementSet.add(koElement); - } - } - } - return koElementSet == null ? Collections.emptySet() : koElementSet; - } - - public static RejectedKOSpecialElement getRejectionKoSpecialElement( - Collection specialElements, - String seriesUID, - String sopUID, - Integer dicomFrameNumber) { - - if (specialElements == null) { - return null; - } - List koList = null; - - for (DicomSpecialElement element : specialElements) { - if (element instanceof RejectedKOSpecialElement koElement - && isSopuidInReferencedSeriesSequence( - koElement.getReferencedSOPInstanceUIDObject(seriesUID), sopUID, dicomFrameNumber)) { - if (koList == null) { - koList = new ArrayList<>(); - } - koList.add(koElement); - } - } - - if (koList != null) { - // return the most recent Rejection Object - koList.sort(ORDER_BY_DATE); - return koList.get(0); - } - return null; - } - - public static List getPRSpecialElements( - Collection specialElements, DicomImageElement img) { - - if (specialElements == null) { - return Collections.emptyList(); - } - List prList = null; - - for (DicomSpecialElement element : specialElements) { - if (element instanceof PRSpecialElement prElement - && PresentationStateReader.isImageApplicable(prElement, img)) { - if (prList == null) { - prList = new ArrayList<>(); - } - prList.add(prElement); - } - } - if (prList != null) { - prList.sort(ORDER_BY_DATE); - } - return prList == null ? Collections.emptyList() : prList; - } } diff --git a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSpecialElementFactory.java b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSpecialElementFactory.java index 384e25613..80407e8c5 100755 --- a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSpecialElementFactory.java +++ b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/DicomSpecialElementFactory.java @@ -15,5 +15,9 @@ public interface DicomSpecialElementFactory { String[] getModalities(); + default boolean isHidden() { + return false; + } + DicomSpecialElement buildDicomSpecialElement(DicomMediaIO mediaIO); } diff --git a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/HiddenSeriesManager.java b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/HiddenSeriesManager.java new file mode 100644 index 000000000..60cbdfcd7 --- /dev/null +++ b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/HiddenSeriesManager.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Weasis Team and other contributors. + * + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License 2.0 which is available at https://www.eclipse.org/legal/epl-2.0, or the Apache + * License, Version 2.0 which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ +package org.weasis.dicom.codec; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class HiddenSeriesManager { + private static final HiddenSeriesManager instance = new HiddenSeriesManager(); + public final Map> series2Elements = new ConcurrentHashMap<>(); + public final Map> patient2Series = new ConcurrentHashMap<>(); + public final Map> reference2Series = new ConcurrentHashMap<>(); + + public static HiddenSeriesManager getInstance() { + return instance; + } +} diff --git a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/HiddenSpecialElement.java b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/HiddenSpecialElement.java new file mode 100644 index 000000000..2a0556816 --- /dev/null +++ b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/HiddenSpecialElement.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Weasis Team and other contributors. + * + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License 2.0 which is available at https://www.eclipse.org/legal/epl-2.0, or the Apache + * License, Version 2.0 which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ +package org.weasis.dicom.codec; + +public class HiddenSpecialElement extends DicomSpecialElement { + + public HiddenSpecialElement(DicomMediaIO mediaIO) { + super(mediaIO); + } +} diff --git a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/PRSpecialElement.java b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/PRSpecialElement.java index 75be3b381..b3628254a 100755 --- a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/PRSpecialElement.java +++ b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/PRSpecialElement.java @@ -9,12 +9,16 @@ */ package org.weasis.dicom.codec; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; import org.dcm4che3.data.Attributes; import org.dcm4che3.data.Tag; import org.dcm4che3.img.data.PrDicomObject; import org.weasis.core.api.media.data.TagW; -public class PRSpecialElement extends DicomSpecialElement { +public class PRSpecialElement extends HiddenSpecialElement { public PRSpecialElement(DicomMediaIO mediaIO) { super(mediaIO); @@ -47,4 +51,26 @@ protected void initLabel() { public PrDicomObject getPrDicomObject() { return (PrDicomObject) getTagValue(TagW.PrDicomObject); } + + public static List getPRSpecialElements( + Collection specialElements, DicomImageElement img) { + + if (specialElements == null) { + return Collections.emptyList(); + } + List prList = null; + + for (PRSpecialElement prElement : specialElements) { + if (PresentationStateReader.isImageApplicable(prElement, img)) { + if (prList == null) { + prList = new ArrayList<>(); + } + prList.add(prElement); + } + } + if (prList != null) { + prList.sort(ORDER_BY_DATE); + } + return prList == null ? Collections.emptyList() : prList; + } } diff --git a/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/SegSpecialElement.java b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/SegSpecialElement.java new file mode 100644 index 000000000..900a2773d --- /dev/null +++ b/weasis-dicom/weasis-dicom-codec/src/main/java/org/weasis/dicom/codec/SegSpecialElement.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021 Weasis Team and other contributors. + * + * This program and the accompanying materials are made available under the terms of the Eclipse + * Public License 2.0 which is available at https://www.eclipse.org/legal/epl-2.0, or the Apache + * License, Version 2.0 which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + */ +package org.weasis.dicom.codec; + +import org.dcm4che3.data.Attributes; +import org.dcm4che3.data.Tag; + +public class SegSpecialElement extends HiddenSpecialElement { + + public SegSpecialElement(DicomMediaIO mediaIO) { + super(mediaIO); + } + + @Override + protected void initLabel() { + StringBuilder buf = new StringBuilder(); + Integer val = TagD.getTagValue(this, Tag.InstanceNumber, Integer.class); + if (val != null) { + buf.append("["); + buf.append(val); + buf.append("] "); + } + Attributes dicom = ((DicomMediaIO) mediaIO).getDicomObject(); + String item = dicom.getString(Tag.ContentLabel); + if (item != null) { + buf.append(item); + } + item = dicom.getString(Tag.ContentDescription); + if (item != null) { + buf.append(" - "); + buf.append(item); + } + label = buf.toString(); + } + + public void initContours(DicomSeries series) {} +} diff --git a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/CheckTreeModel.java b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/CheckTreeModel.java index 6c8d16b44..ac6758364 100755 --- a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/CheckTreeModel.java +++ b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/CheckTreeModel.java @@ -88,30 +88,25 @@ public List getDefaultSelectedPaths() { private static void buildSeries(DefaultMutableTreeNode studyNode, Series series) { DefaultMutableTreeNode seriesNode = new ToolTipTreeNode(series, true); - List specialElements = - (List) series.getTagValue(TagW.DicomSpecialElementList); - if (specialElements != null) { - for (DicomSpecialElement specialElement : specialElements) { - seriesNode.add( - new DefaultMutableTreeNode(specialElement, false) { - @Override - public String toString() { - DicomSpecialElement d = (DicomSpecialElement) getUserObject(); - StringBuilder buf = new StringBuilder(); - boolean newElement = - LangUtil.getNULLtoFalse((Boolean) d.getTagValue(TagW.ObjectToSave)); - if (newElement) { - buf.append(GuiUtils.HTML_COLOR_START); - buf.append(IconColor.ACTIONS_YELLOW.getHtmlCode()); - buf.append("'>NEW "); // NON-NLS + if (series instanceof DicomSeries dicomSeries) { + List specialElements = dicomSeries.getAllDicomSpecialElement(); + if (specialElements != null) { + for (DicomSpecialElement specialElement : specialElements) { + seriesNode.add( + new DefaultMutableTreeNode(specialElement, false) { + @Override + public String toString() { + DicomSpecialElement d = (DicomSpecialElement) getUserObject(); + StringBuilder buf = new StringBuilder(); + boolean newElement = initToolTipText(d, buf); + buf.append(d.getShortLabel()); + if (newElement) { + buf.append(GuiUtils.HTML_END); + } + return buf.toString(); } - buf.append(d.getShortLabel()); - if (newElement) { - buf.append(GuiUtils.HTML_END); - } - return buf.toString(); - } - }); + }); + } } } @@ -201,6 +196,17 @@ public static DefaultTreeModel buildModel(DicomModel dicomModel) { return new DefaultTreeModel(rootNode, false); } + private static boolean initToolTipText(TagReadable tagReadable, StringBuilder buf) { + boolean newElement = + LangUtil.getNULLtoFalse((Boolean) tagReadable.getTagValue(TagW.ObjectToSave)); + if (newElement) { + buf.append(GuiUtils.HTML_COLOR_START); + buf.append(IconColor.ACTIONS_YELLOW.getHtmlCode()); + buf.append("'>NEW "); // NON-NLS + } + return newElement; + } + static class ToolTipTreeNode extends DefaultMutableTreeNode { public ToolTipTreeNode(TagReadable userObject, boolean allowsChildren) { @@ -215,12 +221,7 @@ public String getToolTipText() { public String toString() { MediaSeries s = (MediaSeries) getUserObject(); StringBuilder buf = new StringBuilder(); - boolean newElement = LangUtil.getNULLtoFalse((Boolean) s.getTagValue(TagW.ObjectToSave)); - if (newElement) { - buf.append(GuiUtils.HTML_COLOR_START); - buf.append(IconColor.ACTIONS_YELLOW.getHtmlCode()); - buf.append("'>NEW "); // NON-NLS - } + boolean newElement = initToolTipText(s, buf); buildSeriesEntry(s, buf); int child = getChildCount(); if (newElement) { diff --git a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/DicomExplorer.java b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/DicomExplorer.java index 07c6f3479..ad5acb74f 100755 --- a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/DicomExplorer.java +++ b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/DicomExplorer.java @@ -871,10 +871,10 @@ protected JPanel getMainPanel() { selectedPatient == null ? null : selectedPatient.patient; if (patient != null && e.getSource() instanceof JButton button) { List list = - DicomModel.getSpecialElements(patient, KOSpecialElement.class); + DicomModel.getHiddenSpecialElements(patient, KOSpecialElement.class); if (!list.isEmpty()) { if (list.size() == 1) { - model.openRelatedSeries(list.get(0), patient); + model.openRelatedSeries(list.getFirst(), patient); } else { list.sort(DicomSpecialElement.ORDER_BY_DATE); JPopupMenu popupMenu = new JPopupMenu(); @@ -954,7 +954,7 @@ public void selectPatient(MediaSeriesGroup patient) { } studyCombobox.addItemListener(studyItemListener); selectStudy(); - koOpen.setVisible(DicomModel.hasSpecialElements(patient, KOSpecialElement.class)); + koOpen.setVisible(DicomModel.hasHiddenSpecialElements(patient, KOSpecialElement.class)); // Send message for selecting related plug-ins window model.firePropertyChange( new ObservableEvent(ObservableEvent.BasicAction.SELECT, model, null, patient)); @@ -1074,7 +1074,7 @@ public void dispose() { } private void addDicomSeries(Series series) { - if (DicomModel.isSpecialModality(series)) { + if (DicomModel.isHiddenModality(series)) { // Up to now nothing has to be done in the explorer view about specialModality return; } @@ -1212,7 +1212,7 @@ else if (ObservableEvent.BasicAction.UPDATE_PARENT.equals(action)) { MediaSeriesGroup study = model.getParent(dcm, DicomModel.study); StudyPane studyPane = getStudyPane(study); if (studyPane != null) { - if (!DicomModel.isSpecialModality(dcm)) { + if (!DicomModel.isHiddenModality(dcm)) { SeriesPane pane = getSeriesPane(dcm); if (pane != null) { pane.updateText(); @@ -1233,7 +1233,8 @@ else if (ObservableEvent.BasicAction.UPDATE.equals(action)) { } else if (newVal instanceof KOSpecialElement) { MediaSeriesGroupNode patient = getSelectedPatient(); if (patient != null) { - koOpen.setVisible(DicomModel.hasSpecialElements(patient, KOSpecialElement.class)); + koOpen.setVisible( + DicomModel.hasHiddenSpecialElements(patient, KOSpecialElement.class)); } } } else if (ObservableEvent.BasicAction.LOADING_START.equals(action)) { @@ -1247,7 +1248,7 @@ else if (ObservableEvent.BasicAction.UPDATE.equals(action)) { } MediaSeriesGroupNode patient = getSelectedPatient(); if (patient != null) { - koOpen.setVisible(DicomModel.hasSpecialElements(patient, KOSpecialElement.class)); + koOpen.setVisible(DicomModel.hasHiddenSpecialElements(patient, KOSpecialElement.class)); } } } else if (evt.getSource() instanceof SeriesViewer diff --git a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/DicomModel.java b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/DicomModel.java index cfef1ffd1..976b2613f 100755 --- a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/DicomModel.java +++ b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/DicomModel.java @@ -50,6 +50,7 @@ import org.weasis.core.api.media.data.Codec; import org.weasis.core.api.media.data.MediaElement; import org.weasis.core.api.media.data.MediaSeries; +import org.weasis.core.api.media.data.MediaSeries.MEDIA_POSITION; import org.weasis.core.api.media.data.MediaSeriesGroup; import org.weasis.core.api.media.data.MediaSeriesGroupNode; import org.weasis.core.api.media.data.Series; @@ -64,6 +65,7 @@ import org.weasis.core.ui.editor.ViewerPluginBuilder; import org.weasis.core.util.LangUtil; import org.weasis.core.util.StringUtil; +import org.weasis.dicom.codec.AbstractKOSpecialElement; import org.weasis.dicom.codec.DicomEncapDocElement; import org.weasis.dicom.codec.DicomImageElement; import org.weasis.dicom.codec.DicomMediaIO; @@ -71,9 +73,12 @@ import org.weasis.dicom.codec.DicomSpecialElement; import org.weasis.dicom.codec.DicomVideoElement; import org.weasis.dicom.codec.FilesExtractor; +import org.weasis.dicom.codec.HiddenSeriesManager; +import org.weasis.dicom.codec.HiddenSpecialElement; import org.weasis.dicom.codec.KOSpecialElement; import org.weasis.dicom.codec.PRSpecialElement; import org.weasis.dicom.codec.RejectedKOSpecialElement; +import org.weasis.dicom.codec.SegSpecialElement; import org.weasis.dicom.codec.SortSeriesStack; import org.weasis.dicom.codec.TagD; import org.weasis.dicom.codec.TagD.Level; @@ -397,12 +402,12 @@ public void mergeSeries(List> seriesList) { } } - public void removeSpecialElement(DicomSpecialElement dicomSpecialElement) { - if (dicomSpecialElement == null) { + public void removeHiddenSpecialElement(HiddenSpecialElement element) { + if (element == null) { return; } - String patientPseudoUID = (String) dicomSpecialElement.getTagValue(TagW.PatientPseudoUID); + String patientPseudoUID = (String) element.getTagValue(TagW.PatientPseudoUID); MediaSeriesGroup patientGroup = getHierarchyNode(MediaSeriesGroupNode.rootNode, patientPseudoUID); @@ -410,35 +415,30 @@ public void removeSpecialElement(DicomSpecialElement dicomSpecialElement) { return; } - String studyUID = TagD.getTagValue(dicomSpecialElement, Tag.StudyInstanceUID, String.class); + String studyUID = TagD.getTagValue(element, Tag.StudyInstanceUID, String.class); MediaSeriesGroup studyGroup = getHierarchyNode(patientGroup, studyUID); if (studyGroup == null) { return; } - String seriesUID = TagD.getTagValue(dicomSpecialElement, Tag.SeriesInstanceUID, String.class); + String seriesUID = TagD.getTagValue(element, Tag.SeriesInstanceUID, String.class); Series dicomSeries = (Series) getHierarchyNode(studyGroup, seriesUID); if (dicomSeries == null) { return; } - if (isSpecialModality(dicomSeries)) { - List specialElementList = - (List) dicomSeries.getTagValue(TagW.DicomSpecialElementList); - - List patientSpecialElementList = - (List) patientGroup.getTagValue(TagW.DicomSpecialElementList); - - if (specialElementList == null || patientSpecialElementList == null) { + if (isHiddenModality(dicomSeries)) { + List specialElementList = + HiddenSeriesManager.getInstance().series2Elements.get(seriesUID); + if (specialElementList == null) { return; } - specialElementList.remove(dicomSpecialElement); - - if (patientSpecialElementList.remove(dicomSpecialElement)) { + if (specialElementList.remove(element)) { + // TDOO update the hidden series firePropertyChange( - new ObservableEvent( - ObservableEvent.BasicAction.UPDATE, this, null, dicomSpecialElement)); + new ObservableEvent(ObservableEvent.BasicAction.UPDATE, this, null, element)); + element.dispose(); } if (specialElementList.isEmpty()) { @@ -517,62 +517,20 @@ public void removePatient(MediaSeriesGroup patientGroup) { group.dispose(); } } - - List sps = - (List) patientGroup.getTagValue(TagW.DicomSpecialElementList); - if (sps != null) { - for (DicomSpecialElement d : sps) { - d.dispose(); - } - } removeHierarchyNode(MediaSeriesGroupNode.rootNode, patientGroup); LOGGER.info("Remove Patient: {}", patientGroup); } } - /** - * DicomSpecialElement are added at patientGroupLevel since StudyInstanceUID and SeriesInstanceUID - * are not relevant with the CurrentRequestedProcedureEvidenceSequence which can reference any - * SOPInstance of any Study and Series of the Patient - * - * @param series the series value - */ - public void addSpecialModality(Series series) { - - List seriesSpecialElementList = - (List) series.getTagValue(TagW.DicomSpecialElementList); - if (seriesSpecialElementList == null || seriesSpecialElementList.isEmpty()) { - return; - } - - MediaSeriesGroup patientGroup = getParent(series, DicomModel.patient); - - if (patientGroup == null) { - return; - } - - List patientSpecialElementList = - (List) patientGroup.getTagValue(TagW.DicomSpecialElementList); - - if (patientSpecialElementList == null) { - patientSpecialElementList = new CopyOnWriteArrayList<>(); - patientGroup.setTag(TagW.DicomSpecialElementList, patientSpecialElementList); - } - for (DicomSpecialElement seriesSpecialElement : seriesSpecialElementList) { - if (!patientSpecialElementList.contains(seriesSpecialElement)) { - patientSpecialElementList.add(seriesSpecialElement); - } - } - } - - public static boolean isSpecialModality(MediaSeries series) { + public static boolean isHiddenModality(MediaSeries series) { String modality = (series == null) ? null : TagD.getTagValue(series, Tag.Modality, String.class); - return ("PR".equals(modality) || "KO".equals(modality)); // NON-NLS + return DicomMediaIO.isHiddenModality(modality); } - public static Collection getEditableKoSpecialElements(MediaSeriesGroup group) { - List list = getSpecialElements(group, KOSpecialElement.class); + public static Collection getEditableKoSpecialElements( + MediaSeriesGroup patient) { + List list = getHiddenSpecialElements(patient, KOSpecialElement.class); if (!list.isEmpty()) { for (int i = list.size() - 1; i >= 0; i--) { KOSpecialElement koElement = list.get(i); @@ -587,77 +545,122 @@ public static Collection getEditableKoSpecialElements(MediaSer public static Collection getKoSpecialElements( MediaSeries dicomSeries) { - // Get all DicomSpecialElement at patient level - List specialElementList = getSpecialElements(dicomSeries); + String patientPseudoUID = getPatientPseudoUID(dicomSeries); + List specialElementList = + DicomSeries.getHiddenElementsFromPatient(patientPseudoUID, KOSpecialElement.class); String referencedSeriesInstanceUID = TagD.getTagValue(dicomSeries, Tag.SeriesInstanceUID, String.class); - return DicomSpecialElement.getKoSpecialElements( + return AbstractKOSpecialElement.getKoSpecialElements( specialElementList, referencedSeriesInstanceUID); } public static Collection getRejectionKoSpecialElements( MediaSeries dicomSeries) { - // Get all DicomSpecialElement at patient level - List specialElementList = getSpecialElements(dicomSeries); + String patientPseudoUID = getPatientPseudoUID(dicomSeries); + List specialElementList = + DicomSeries.getHiddenElementsFromPatient(patientPseudoUID, RejectedKOSpecialElement.class); String referencedSeriesInstanceUID = TagD.getTagValue(dicomSeries, Tag.SeriesInstanceUID, String.class); - return DicomSpecialElement.getRejectionKoSpecialElements( + return AbstractKOSpecialElement.getRejectionKoSpecialElements( specialElementList, referencedSeriesInstanceUID); } + public static String getPatientPseudoUID(MediaSeries dicomSeries) { + if (dicomSeries == null) { + return null; + } + DicomImageElement img = dicomSeries.getMedia(MEDIA_POSITION.FIRST, null, null); + if (img == null) { + return null; + } + return (String) img.getTagValue(TagW.PatientPseudoUID); + } + public static RejectedKOSpecialElement getRejectionKoSpecialElement( MediaSeries dicomSeries, String sopUID, Integer dicomFrameNumber) { - // Get all DicomSpecialElement at patient level - List specialElementList = getSpecialElements(dicomSeries); + String patientPseudoUID = getPatientPseudoUID(dicomSeries); + List specialElementList = + DicomSeries.getHiddenElementsFromPatient(patientPseudoUID, RejectedKOSpecialElement.class); String referencedSeriesInstanceUID = TagD.getTagValue(dicomSeries, Tag.SeriesInstanceUID, String.class); - return DicomSpecialElement.getRejectionKoSpecialElement( + return AbstractKOSpecialElement.getRejectionKoSpecialElement( specialElementList, referencedSeriesInstanceUID, sopUID, dicomFrameNumber); } public static List getPrSpecialElements( MediaSeries dicomSeries, DicomImageElement img) { - // Get all DicomSpecialElement at patient level - List specialElementList = getSpecialElements(dicomSeries); + String patientPseudoUID = getPatientPseudoUID(dicomSeries); + List specialElementList = + DicomSeries.getHiddenElementsFromPatient(patientPseudoUID, PRSpecialElement.class); if (!specialElementList.isEmpty()) { String referencedSeriesInstanceUID = TagD.getTagValue(dicomSeries, Tag.SeriesInstanceUID, String.class); String seriesUID = TagD.getTagValue(img, Tag.SeriesInstanceUID, String.class); if (Objects.equals(seriesUID, referencedSeriesInstanceUID)) { - return DicomSpecialElement.getPRSpecialElements(specialElementList, img); + return PRSpecialElement.getPRSpecialElements(specialElementList, img); } } return Collections.emptyList(); } - public static List getSpecialElements( - MediaSeries dicomSeries) { - if (dicomSeries == null) { - return Collections.emptyList(); + public static boolean hasHiddenSpecialElements(MediaSeriesGroup patient, Class clazz) { + if (patient != null && clazz != null && clazz.isAssignableFrom(clazz)) { + String patientPseudoUID = (String) patient.getTagValue(TagW.PatientPseudoUID); + List patients = + HiddenSeriesManager.getInstance().patient2Series.get(patientPseudoUID); + if (patients != null) { + for (String seriesUID : patients) { + List hiddenElements = + HiddenSeriesManager.getInstance().series2Elements.get(seriesUID); + if (hiddenElements != null) { + for (HiddenSpecialElement el : hiddenElements) { + if (clazz.isInstance(el)) { + return true; + } + } + } + } + } } + return false; + } - List list = null; - DataExplorerModel model = (DataExplorerModel) dicomSeries.getTagValue(TagW.ExplorerModel); - - if (model instanceof DicomModel dicomModel) { - MediaSeriesGroup patientGroup = dicomModel.getParent(dicomSeries, DicomModel.patient); - if (patientGroup != null) { - list = (List) patientGroup.getTagValue(TagW.DicomSpecialElementList); + public static List getHiddenSpecialElements(MediaSeriesGroup patient, Class clazz) { + if (patient != null && clazz != null && clazz.isAssignableFrom(clazz)) { + String patientPseudoUID = (String) patient.getTagValue(TagW.PatientPseudoUID); + if (patientPseudoUID != null) { + List patients = + HiddenSeriesManager.getInstance().patient2Series.get(patientPseudoUID); + if (patients != null) { + List list = new ArrayList<>(); + for (String seriesUID : patients) { + List hiddenElements = + HiddenSeriesManager.getInstance().series2Elements.get(seriesUID); + if (hiddenElements != null) { + for (HiddenSpecialElement el : hiddenElements) { + if (clazz.isInstance(el)) { + list.add((E) el); + } + } + } + } + return list; + } } } - return list == null ? Collections.emptyList() : list; + return Collections.emptyList(); } - public static List getSpecialElements(MediaSeriesGroup group, Class clazz) { - if (group != null && clazz != null && clazz.isAssignableFrom(clazz)) { - List kos = - (List) group.getTagValue(TagW.DicomSpecialElementList); - if (kos != null) { + public static List getSpecialElements(MediaSeriesGroup series, Class clazz) { + if (series != null && clazz != null && clazz.isAssignableFrom(clazz)) { + List elements = + (List) series.getTagValue(TagW.DicomSpecialElementList); + if (elements != null) { List list = new ArrayList<>(); - for (DicomSpecialElement el : kos) { + for (DicomSpecialElement el : elements) { if (clazz.isInstance(el)) { list.add((E) el); } @@ -683,22 +686,6 @@ public static E getFirstSpecialElement(MediaSeriesGroup group, Class claz return null; } - public static boolean hasSpecialElements( - MediaSeriesGroup group, Class clazz) { - if (group != null && clazz != null) { - List kos = - (List) group.getTagValue(TagW.DicomSpecialElementList); - if (kos != null) { - for (DicomSpecialElement el : kos) { - if (clazz.isInstance(el)) { - return true; - } - } - } - } - return false; - } - public void openRelatedSeries(KOSpecialElement koSpecialElement, MediaSeriesGroup patient) { if (koSpecialElement != null && patient != null) { SeriesViewerFactory plugin = @@ -851,6 +838,9 @@ private void rebuildSeries(DicomMediaIO dicomReader, MediaElement media) { public boolean applySplittingRules(Series original, MediaElement media) { if (media != null && media.getMediaReader() instanceof DicomMediaIO dicomReader) { String seriesUID = TagD.getTagValue(original, Tag.SeriesInstanceUID, String.class); + if (seriesUID == null) { + throw new IllegalArgumentException("Series UID cannot be null"); + } if (!seriesUID.equals(TagD.getTagValue(dicomReader, Tag.SeriesInstanceUID))) { rebuildSeries(dicomReader, media); return true; @@ -880,37 +870,62 @@ public boolean applySplittingRules(Series original, MediaElement media) { return true; } if (media instanceof DicomSpecialElement specialElement) { - List specialElementList = - (List) initialSeries.getTagValue(TagW.DicomSpecialElementList); - String rMime = dicomReader.getMimeType(); - if (specialElementList == null) { - specialElementList = new CopyOnWriteArrayList<>(); - initialSeries.setTag(TagW.DicomSpecialElementList, specialElementList); - if ("rt/dicom".equals(rMime)) { // NON-NLS - MediaSeriesGroup st = getParent(initialSeries, DicomModel.study); - if (st != null - && !LangUtil.getNULLtoFalse((Boolean) st.getTagValue(TagW.StudyDicomRT))) { - st.setTag(TagW.StudyDicomRT, Boolean.TRUE); - for (MediaSeriesGroup s : getChildren(st)) { - String modality = TagD.getTagValue(s, Tag.Modality, String.class); - if ("CT".equals(modality)) { - // Force to update the Plugin Tools of the selected Viewer - firePropertyChange( - new ObservableEvent(BasicAction.UPDATE_TOOLS, this, null, this)); - break; + if (specialElement instanceof HiddenSpecialElement hiddenSpecialElement) { + if (hiddenSpecialElement instanceof SegSpecialElement segSpecialElement) { + segSpecialElement.initContours(initialSeries); + } + synchronized (this) { + Map> mapSeries = + HiddenSeriesManager.getInstance().series2Elements; + List hiddenElements = + mapSeries.computeIfAbsent(seriesUID, k -> new CopyOnWriteArrayList<>()); + if (!hiddenElements.contains(hiddenSpecialElement)) { + hiddenElements.add(hiddenSpecialElement); + } + + String patientPseudoUID = + (String) hiddenSpecialElement.getTagValue(TagW.PatientPseudoUID); + if (patientPseudoUID != null) { + List patients = + HiddenSeriesManager.getInstance() + .patient2Series + .computeIfAbsent(patientPseudoUID, k -> new CopyOnWriteArrayList<>()); + if (!patients.contains(seriesUID)) { + patients.add(seriesUID); + } + } + } + } else { + List specialElementList = + (List) initialSeries.getTagValue(TagW.DicomSpecialElementList); + String rMime = dicomReader.getMimeType(); + if (specialElementList == null) { + specialElementList = new CopyOnWriteArrayList<>(); + initialSeries.setTag(TagW.DicomSpecialElementList, specialElementList); + if ("rt/dicom".equals(rMime)) { // NON-NLS + MediaSeriesGroup st = getParent(initialSeries, DicomModel.study); + if (st != null + && !LangUtil.getNULLtoFalse((Boolean) st.getTagValue(TagW.StudyDicomRT))) { + st.setTag(TagW.StudyDicomRT, Boolean.TRUE); + for (MediaSeriesGroup s : getChildren(st)) { + String modality = TagD.getTagValue(s, Tag.Modality, String.class); + if ("CT".equals(modality)) { + // Force to update the Plugin Tools of the selected Viewer + firePropertyChange( + new ObservableEvent(BasicAction.UPDATE_TOOLS, this, null, this)); + break; + } } } } + } else if ("sr/dicom".equals(rMime) || "wf/dicom".equals(rMime)) { // NON-NLS + // Split SR series to have only one object by series + Series s = splitSeries(dicomReader, initialSeries); + specialElementList = new CopyOnWriteArrayList<>(); + s.setTag(TagW.DicomSpecialElementList, specialElementList); } - } else if ("sr/dicom".equals(rMime) || "wf/dicom".equals(rMime)) { // NON-NLS - // Split SR series to have only one object by series - Series s = splitSeries(dicomReader, initialSeries); - specialElementList = new CopyOnWriteArrayList<>(); - specialElementList.add(specialElement); - s.setTag(TagW.DicomSpecialElementList, specialElementList); - return false; + specialElementList.add((specialElement)); } - specialElementList.add((specialElement)); return false; } diff --git a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/LoadDicom.java b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/LoadDicom.java index 8312ac83a..9b5c6d46f 100755 --- a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/LoadDicom.java +++ b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/LoadDicom.java @@ -25,7 +25,7 @@ import org.weasis.core.api.media.data.TagW; import org.weasis.core.api.media.data.Thumbnail; import org.weasis.dicom.codec.DicomMediaIO; -import org.weasis.dicom.codec.DicomSpecialElement; +import org.weasis.dicom.codec.HiddenSpecialElement; import org.weasis.dicom.codec.TagD; import org.weasis.dicom.codec.TagD.Level; import org.weasis.dicom.explorer.HangingProtocols.OpeningViewer; @@ -143,13 +143,11 @@ protected SeriesThumbnail buildDicomStructure(DicomMediaIO dicomReader) { } } - if (DicomModel.isSpecialModality(dicomSeries)) { - dicomModel.addSpecialModality(dicomSeries); + if (DicomModel.isHiddenModality(dicomSeries) && medias != null) { Arrays.stream(medias) - .filter(DicomSpecialElement.class::isInstance) - .map(DicomSpecialElement.class::cast) - .findFirst() - .ifPresent( + .filter(HiddenSpecialElement.class::isInstance) + .map(HiddenSpecialElement.class::cast) + .forEach( d -> dicomModel.firePropertyChange( new ObservableEvent( @@ -193,13 +191,11 @@ protected SeriesThumbnail buildDicomStructure(DicomMediaIO dicomReader) { } } - if (DicomModel.isSpecialModality(dicomSeries)) { - dicomModel.addSpecialModality(dicomSeries); + if (DicomModel.isHiddenModality(dicomSeries)) { Arrays.stream(medias) - .filter(DicomSpecialElement.class::isInstance) - .map(DicomSpecialElement.class::cast) - .findFirst() - .ifPresent( + .filter(HiddenSpecialElement.class::isInstance) + .map(HiddenSpecialElement.class::cast) + .forEach( d -> dicomModel.firePropertyChange( new ObservableEvent( diff --git a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/mf/DicomModelQueryResult.java b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/mf/DicomModelQueryResult.java index ee6510d8a..1a8644961 100755 --- a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/mf/DicomModelQueryResult.java +++ b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/mf/DicomModelQueryResult.java @@ -92,7 +92,7 @@ private void init(DicomModel model, MediaSeriesGroup... patientGroups) { continue; } - if (DicomModel.isSpecialModality((MediaSeries) series)) { + if (DicomModel.isHiddenModality((MediaSeries) series)) { String seriesInstanceUID = TagD.getTagValue(series, Tag.SeriesInstanceUID, String.class); for (DicomSpecialElement spel : dcmSpecElements) { diff --git a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/wado/LoadSeries.java b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/wado/LoadSeries.java index 072453e9f..ffae2d399 100755 --- a/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/wado/LoadSeries.java +++ b/weasis-dicom/weasis-dicom-explorer/src/main/java/org/weasis/dicom/explorer/wado/LoadSeries.java @@ -79,7 +79,8 @@ import org.weasis.core.util.StreamIOException; import org.weasis.core.util.StringUtil; import org.weasis.dicom.codec.DicomMediaIO; -import org.weasis.dicom.codec.DicomSpecialElement; +import org.weasis.dicom.codec.HiddenSeriesManager; +import org.weasis.dicom.codec.HiddenSpecialElement; import org.weasis.dicom.codec.TagD; import org.weasis.dicom.codec.TagD.Level; import org.weasis.dicom.codec.TransferSyntax; @@ -333,15 +334,13 @@ protected void done() { } } - if (DicomModel.isSpecialModality(dicomSeries)) { - dicomModel.addSpecialModality(dicomSeries); - List list = - (List) dicomSeries.getTagValue(TagW.DicomSpecialElementList); + if (DicomModel.isHiddenModality(dicomSeries)) { + List list = + HiddenSeriesManager.getInstance().series2Elements.get(seriesUID); if (list != null) { list.stream() .filter(Objects::nonNull) - .findFirst() - .ifPresent( + .forEach( d -> dicomModel.firePropertyChange( new ObservableEvent( diff --git a/weasis-dicom/weasis-dicom-rt/src/main/java/org/weasis/dicom/rt/RtSet.java b/weasis-dicom/weasis-dicom-rt/src/main/java/org/weasis/dicom/rt/RtSet.java index 4abb43fc3..fc4c6901c 100755 --- a/weasis-dicom/weasis-dicom-rt/src/main/java/org/weasis/dicom/rt/RtSet.java +++ b/weasis-dicom/weasis-dicom-rt/src/main/java/org/weasis/dicom/rt/RtSet.java @@ -802,13 +802,8 @@ private void initIsoDoses(Plan plan) { int k = 0; for (Point point : matOfPoint.toList()) { - double[] coordinates = new double[2]; - - coordinates[0] = dose.getDoseMmLUT().getKey()[(int) point.x]; - coordinates[1] = dose.getDoseMmLUT().getValue()[(int) point.y]; - - newContour[k] = coordinates[0]; - newContour[k + 1] = coordinates[1]; + newContour[k] = dose.getDoseMmLUT().getKey()[(int) point.x]; + newContour[k + 1] = dose.getDoseMmLUT().getValue()[(int) point.y]; newContour[k + 2] = z.getValue(); k += 3; } diff --git a/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/KeyObjectToolBar.java b/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/KeyObjectToolBar.java index 9890ac056..571aad7e7 100755 --- a/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/KeyObjectToolBar.java +++ b/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/KeyObjectToolBar.java @@ -229,7 +229,7 @@ private void editKo( DicomModel dicomModel = (DicomModel) selectedDicomSeries.getTagValue(TagW.ExplorerModel); if (dicomModel != null) { - dicomModel.removeSpecialElement(list.getSelectedValue()); + dicomModel.removeHiddenSpecialElement(list.getSelectedValue()); if (selectedView2d instanceof View2d view2d) { boolean needToRepaint = view2d.updateKOSelectedState(selectedView2d.getImage()); if (needToRepaint) { diff --git a/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/PRManager.java b/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/PRManager.java index 6262ed2e0..904f4b867 100755 --- a/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/PRManager.java +++ b/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/PRManager.java @@ -511,7 +511,7 @@ public static ViewButton buildPrSelection( } if (!ActionState.NoneLabel.NONE_SERIES.equals(oldPR)) { // Set the previous selected value, otherwise set the more recent PR by default - view.setPresentationState(!prList.contains(oldPR) ? prList.get(0) : oldPR, true); + view.setPresentationState(!prList.contains(oldPR) ? prList.getFirst() : oldPR, true); } int offset = series.size(null) > 1 ? 2 : 1; diff --git a/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/View2dContainer.java b/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/View2dContainer.java index 9275ddd2e..56f019166 100755 --- a/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/View2dContainer.java +++ b/weasis-dicom/weasis-dicom-viewer2d/src/main/java/org/weasis/dicom/viewer2d/View2dContainer.java @@ -442,6 +442,14 @@ public JMenu fillSelectedPluginMenu(JMenu menuRoot) { return menuRoot; } + @Override + public void addSeries(MediaSeries sequence) { + if (DicomModel.isHiddenModality(sequence)) { + return; + } + super.addSeries(sequence); + } + protected MediaSeries getFirstSeries() { for (ViewCanvas v : getImagePanels()) { if (v.getSeries() != null) {