/** * Returns a new descriptor eqiuvalent to this+D. Remember, composition is not commutative for all * attributes, and may not exist for some. To compose, remember to call * {@linkDescriptor#isComposable() isComposable} first and try both <code>A.compose (B)</code> and * <code>B.compose (A)</code>. * * @param D The Descriptor to compose with this Descriptor. * @param scope The attribute scope and mapping. * @return A new Descriptor that is equivalent to the composition of this and the argument D. * @throws BadDataException if the compose semantics are not correct. * @throws UncomposableException this instance of the descriptor cannot be composed. Check * isComposable! */ public Descriptor compose(Descriptor D, EvaluationParameters.ScopeRules scope) throws BadDataException, UncomposableException { DescAggregate temp = (DescAggregate) this.clone(); // Unify Descriptions and Spans temp.span = temp.span.union(D.getFrameSpan()); if (D.getClass().equals(DescSingle.class)) { if (idList.contains(D.getID())) throw new BadDataException("Attempting to compose the same descriptor multiple times"); else temp.idList.add(D.getID()); } else { // First, check to see if there are any dup ID numbers Iterator iterA = idList.iterator(); Iterator iterB = ((TreeSet) D.getID()).iterator(); Comparable A = (Comparable) iterA.next(); Comparable B = (Comparable) iterB.next(); /// difference will be negative iff A < B, and positive iff A > B. // I wish java had operator overloading. I really do. double difference = A.compareTo(B); while (iterA.hasNext() && iterB.hasNext() && (difference != 0)) { while ((difference < 0) && (iterA.hasNext() && iterB.hasNext())) { A = (Comparable) iterA.next(); difference = A.compareTo(B); } while ((difference > 0) && (iterA.hasNext() && iterB.hasNext())) { B = (Comparable) iterB.next(); difference = A.compareTo(B); } } if (difference == 0) // If there was a dup ID num, return 0 throw new BadDataException("Attempting to compose the same descriptor multiple times"); temp.idList.addAll(((DescAggregate) D).idList); } // Unify Attributes String errMsg = null; for (Iterator iter = scope.getInScopeAttributesFor(temp); iter.hasNext(); ) { String currAttrName = (String) iter.next(); int i = temp.getAttributeIndex(currAttrName, scope.getMap()); try { temp.attributes[i] = Attribute.compose( this.span, this.getAttribute(currAttrName, scope.getMap()), D.span, D.getAttribute(currAttrName, scope.getMap())); } catch (UncomposableException ux) { if (errMsg == null) { errMsg = ux.getMessage(); } else { errMsg += "\n" + ux.getMessage(); } } } if (errMsg != null) System.err.println(errMsg + "\n fix your .epf"); return temp; }
/** * Read a DICOM dataset and write an XML representation of it to the standard output, or vice * versa. * * @param arg either one filename of the file containing the DICOM dataset, or a direction * argument (toDICOM or toXML, case insensitive) and an input filename */ public static void main(String arg[]) { try { boolean bad = true; boolean toXML = true; String filename = null; if (arg.length == 1) { bad = false; toXML = true; filename = arg[0]; } else if (arg.length == 2) { filename = arg[1]; if (arg[0].toLowerCase(java.util.Locale.US).equals("toxml")) { bad = false; toXML = true; } else if (arg[0].toLowerCase(java.util.Locale.US).equals("todicom") || arg[0].toLowerCase(java.util.Locale.US).equals("todcm")) { bad = false; toXML = false; } } if (bad) { System.err.println( "usage: XMLRepresentationOfDicomObjectFactory [toDICOM|toXML] inputfile"); } else { if (toXML) { AttributeList list = new AttributeList(); // System.err.println("reading list"); list.read(filename, null, true, true); // System.err.println("making document"); Document document = new XMLRepresentationOfDicomObjectFactory().getDocument(list); // System.err.println(toString(document)); write(System.out, document); } else { // long startReadTime = System.currentTimeMillis(); AttributeList list = new XMLRepresentationOfDicomObjectFactory().getAttributeList(filename); // System.err.println("AttributeList.main(): read XML and create DICOM AttributeList - // done in "+(System.currentTimeMillis()-startReadTime)+" ms"); String sourceApplicationEntityTitle = Attribute.getSingleStringValueOrEmptyString( list, TagFromName.SourceApplicationEntityTitle); list.removeMetaInformationHeaderAttributes(); FileMetaInformation.addFileMetaInformation( list, TransferSyntax.ExplicitVRLittleEndian, sourceApplicationEntityTitle); list.write( System.out, TransferSyntax.ExplicitVRLittleEndian, true /*useMeta*/, true /*useBufferedStream*/); } } } catch (Exception e) { e.printStackTrace(System.err); } }
/** * @param list * @param document * @param parent */ void addAttributesFromListToNode(AttributeList list, Document document, Node parent) { DicomDictionary dictionary = list.getDictionary(); Iterator i = list.values().iterator(); while (i.hasNext()) { Attribute attribute = (Attribute) i.next(); AttributeTag tag = attribute.getTag(); String elementName = dictionary.getNameFromTag(tag); if (elementName == null) { elementName = makeElementNameFromHexadecimalGroupElementValues(tag); } Node node = document.createElement(elementName); parent.appendChild(node); { Attr attr = document.createAttribute("group"); attr.setValue(HexDump.shortToPaddedHexString(tag.getGroup())); node.getAttributes().setNamedItem(attr); } { Attr attr = document.createAttribute("element"); attr.setValue(HexDump.shortToPaddedHexString(tag.getElement())); node.getAttributes().setNamedItem(attr); } { Attr attr = document.createAttribute("vr"); attr.setValue(ValueRepresentation.getAsString(attribute.getVR())); node.getAttributes().setNamedItem(attr); } if (attribute instanceof SequenceAttribute) { int count = 0; Iterator si = ((SequenceAttribute) attribute).iterator(); while (si.hasNext()) { SequenceItem item = (SequenceItem) si.next(); Node itemNode = document.createElement("Item"); Attr numberAttr = document.createAttribute("number"); numberAttr.setValue(Integer.toString(++count)); itemNode.getAttributes().setNamedItem(numberAttr); node.appendChild(itemNode); addAttributesFromListToNode(item.getAttributeList(), document, itemNode); } } else { // Attr attr = document.createAttribute("value"); // attr.setValue(attribute.getDelimitedStringValuesOrEmptyString()); // node.getAttributes().setNamedItem(attr); // node.appendChild(document.createTextNode(attribute.getDelimitedStringValuesOrEmptyString())); String values[] = null; try { values = attribute.getStringValues(); } catch (DicomException e) { // e.printStackTrace(System.err); } if (values != null) { for (int j = 0; j < values.length; ++j) { Node valueNode = document.createElement("value"); Attr numberAttr = document.createAttribute("number"); numberAttr.setValue(Integer.toString(j + 1)); valueNode.getAttributes().setNamedItem(numberAttr); valueNode.appendChild(document.createTextNode(values[j])); node.appendChild(valueNode); } } } } }
/** * @param list * @param parent * @exception NumberFormatException * @exception DicomException */ void addAttributesFromNodeToList(AttributeList list, Node parent) throws NumberFormatException, DicomException { if (parent != null) { Node node = parent.getFirstChild(); while (node != null) { String elementName = node.getNodeName(); NamedNodeMap attributes = node.getAttributes(); if (attributes != null) { Node vrNode = attributes.getNamedItem("vr"); Node groupNode = attributes.getNamedItem("group"); Node elementNode = attributes.getNamedItem("element"); if (vrNode != null && groupNode != null && elementNode != null) { String vrString = vrNode.getNodeValue(); String groupString = groupNode.getNodeValue(); String elementString = elementNode.getNodeValue(); if (vrString != null && groupString != null && elementString != null) { byte[] vr = vrString.getBytes(); int group = Integer.parseInt(groupString, 16); int element = Integer.parseInt(elementString, 16); AttributeTag tag = new AttributeTag(group, element); if ((group % 2 == 0 && element == 0) || (group == 0x0008 && element == 0x0001) || (group == 0xfffc && element == 0xfffc)) { // System.err.println("ignoring group length or length to end or dataset trailing // padding "+tag); } else { if (vrString.equals("SQ")) { SequenceAttribute a = new SequenceAttribute(tag); // System.err.println("Created "+a); if (node.hasChildNodes()) { Node childNode = node.getFirstChild(); while (childNode != null) { String childNodeName = childNode.getNodeName(); // System.err.println("childNodeName = "+childNodeName); if (childNodeName != null && childNodeName.equals("Item")) { // should check item number, but ignore for now :( // System.err.println("Adding item to sequence"); AttributeList itemList = new AttributeList(); addAttributesFromNodeToList(itemList, childNode); a.addItem(itemList); } // else may be a #text element in between childNode = childNode.getNextSibling(); } } // System.err.println("Sequence Attribute is "+a); list.put(tag, a); } else { Attribute a = AttributeFactory.newAttribute(tag, vr); // System.err.println("Created "+a); if (node.hasChildNodes()) { Node childNode = node.getFirstChild(); while (childNode != null) { String childNodeName = childNode.getNodeName(); // System.err.println("childNodeName = "+childNodeName); if (childNodeName != null && childNodeName.equals("value")) { // should check value number, but ignore for now :( String value = childNode.getTextContent(); // System.err.println("Value value = "+value); if (value != null) { value = StringUtilities.removeLeadingOrTrailingWhitespaceOrISOControl( value); // just in case a.addValue(value); } } // else may be a #text element in between childNode = childNode.getNextSibling(); } } // System.err.println("Attribute is "+a); list.put(tag, a); } } } } } node = node.getNextSibling(); } } }